1 /*- 2 ******************************************************************************* 3 Copyright (C) 2015 Annapurna Labs Ltd. 4 5 This file may be licensed under the terms of the Annapurna Labs Commercial 6 License Agreement. 7 8 Alternatively, this file can be distributed under the terms of the GNU General 9 Public License V2 as published by the Free Software Foundation and can be 10 found at http://www.gnu.org/licenses/gpl-2.0.html 11 12 Alternatively, redistribution and use in source and binary forms, with or 13 without modification, are permitted provided that the following conditions are 14 met: 15 16 * Redistributions of source code must retain the above copyright notice, 17 this list of conditions and the following disclaimer. 18 19 * Redistributions in binary form must reproduce the above copyright 20 notice, this list of conditions and the following disclaimer in 21 the documentation and/or other materials provided with the 22 distribution. 23 24 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 25 ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 26 WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 27 DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR 28 ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 29 (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 30 LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON 31 ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 32 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 33 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 34 35 *******************************************************************************/ 36 /** 37 * Ethernet 38 * @{ 39 * @file al_hal_eth_kr.c 40 * 41 * @brief KR HAL driver for main functions (auto-neg, Link Training) 42 * 43 */ 44 45 #include "al_hal_eth_kr.h" 46 #include "al_hal_eth_mac_regs.h" 47 #include "al_hal_an_lt_wrapper_regs.h" 48 49 enum al_eth_lt_unit_rev { 50 AL_ETH_LT_UNIT_REV_1 = 0, 51 AL_ETH_LT_UNIT_REV_2, 52 53 AL_ETH_LT_UNIT_REV_MAX 54 }; 55 56 enum al_eth_an_lt_regs_ids { 57 AL_ETH_KR_AN_CONTROL = 0, 58 AL_ETH_KR_AN_STATUS, 59 AL_ETH_KR_AN_ADV0, 60 AL_ETH_KR_AN_ADV1, 61 AL_ETH_KR_AN_ADV2, 62 AL_ETH_KR_AN_REM_ADV0, 63 AL_ETH_KR_AN_REM_ADV1, 64 AL_ETH_KR_AN_REM_ADV2, 65 AL_ETH_KR_PMD_CONTROL, 66 AL_ETH_KR_PMD_STATUS, 67 AL_ETH_KR_PMD_LP_COEF_UP, 68 AL_ETH_KR_PMD_LP_STATUS_REPORT, 69 AL_ETH_KR_PMD_LD_COEF_UP, 70 AL_ETH_KR_PMD_LD_STATUS_REPORT, 71 AL_ETH_KR_AN_XNP_ADV0, 72 AL_ETH_KR_AN_XNP_ADV1, 73 AL_ETH_KR_AN_XNP_ADV2, 74 AL_ETH_KR_AN_REM_XNP_ADV0, 75 AL_ETH_KR_AN_REM_XNP_ADV1, 76 AL_ETH_KR_AN_REM_XNP_ADV2, 77 }; 78 79 static uint32_t al_eth_an_lt_regs_addr[][AL_ETH_LT_UNIT_REV_MAX] = { 80 [AL_ETH_KR_AN_CONTROL] = {0 , 0x0}, 81 [AL_ETH_KR_AN_STATUS] = {1 , 0x4}, 82 [AL_ETH_KR_AN_ADV0] = {16 , 0x8}, 83 [AL_ETH_KR_AN_ADV1] = {17 , 0xc}, 84 [AL_ETH_KR_AN_ADV2] = {18 , 0x10}, 85 [AL_ETH_KR_AN_REM_ADV0] = {19 , 0x14}, 86 [AL_ETH_KR_AN_REM_ADV1] = {20 , 0x18}, 87 [AL_ETH_KR_AN_REM_ADV2] = {21 , 0x1c}, 88 [AL_ETH_KR_PMD_CONTROL] = {150, 0x400}, 89 [AL_ETH_KR_PMD_STATUS] = {151, 0x404}, 90 [AL_ETH_KR_PMD_LP_COEF_UP] = {152, 0x408}, 91 [AL_ETH_KR_PMD_LP_STATUS_REPORT] = {153, 0x40c}, 92 [AL_ETH_KR_PMD_LD_COEF_UP] = {154, 0x410}, 93 [AL_ETH_KR_PMD_LD_STATUS_REPORT] = {155, 0x414}, 94 [AL_ETH_KR_AN_XNP_ADV0] = {22 , 0x24}, 95 [AL_ETH_KR_AN_XNP_ADV1] = {23 , 0x28}, 96 [AL_ETH_KR_AN_XNP_ADV2] = {24 , 0x2c}, 97 [AL_ETH_KR_AN_REM_XNP_ADV0] = {25 , 0x30}, 98 [AL_ETH_KR_AN_REM_XNP_ADV1] = {26 , 0x34}, 99 [AL_ETH_KR_AN_REM_XNP_ADV2] = {27 , 0x38}, 100 }; 101 102 103 /* 104 * AN(Auto Negotiation) registers 105 * (read / write indirect with al_eth_an_reg_read/write) 106 */ 107 #define AL_ETH_KR_AN_CONTROL_RESTART AL_BIT(9) 108 #define AL_ETH_KR_AN_CONTROL_ENABLE AL_BIT(12) 109 #define AL_ETH_KR_AN_CONTROL_NP_ENABLE AL_BIT(13) 110 111 #define AL_ETH_KR_AN_STATUS_COMPLETED AL_BIT(5) 112 #define AL_ETH_KR_AN_STATUS_BASE_PAGE_RECEIVED AL_BIT(6) 113 #define AL_ETH_KR_AN_STATUS_CHECK_MASK 0xFF0A 114 #define AL_ETH_KR_AN_STATUS_CHECK_NO_ERROR 0x0008 115 116 /* AN advertising registers parsing */ 117 /* register 1 */ 118 #define AL_ETH_KR_AN_ADV1_SEL_FIELD_MASK 0x001f 119 #define AL_ETH_KR_AN_ADV1_SEL_FIELD_SHIFT 0 120 #define AL_ETH_KR_AN_ADV1_ECHOED_NONCE_MASK 0x03e0 121 #define AL_ETH_KR_AN_ADV1_ECHOED_NONCE_SHIFT 5 122 #define AL_ETH_KR_AN_ADV1_CAPABILITY_MASK 0x1c00 123 #define AL_ETH_KR_AN_ADV1_CAPABILITY_SHIFT 10 124 #define AL_ETH_KR_AN_ADV1_REM_FAULT_MASK 0x2000 125 #define AL_ETH_KR_AN_ADV1_REM_FAULT_SHIFT 13 126 #define AL_ETH_KR_AN_ADV1_ACK_MASK 0x4000 127 #define AL_ETH_KR_AN_ADV1_ACK_SHIFT 14 128 #define AL_ETH_KR_AN_ADV1_NEXT_PAGE_MASK 0x8000 129 #define AL_ETH_KR_AN_ADV1_NEXT_PAGE_SHIFT 15 130 /* register 2 */ 131 #define AL_ETH_KR_AN_ADV2_TX_NONCE_MASK 0x001f 132 #define AL_ETH_KR_AN_ADV2_TX_NONCE_SHIFT 0 133 #define AL_ETH_KR_AN_ADV2_TECH_MASK 0xffe0 134 #define AL_ETH_KR_AN_ADV2_TECH_SHIFT 5 135 /* register 3 */ 136 /* TECH field in the third register is extended to the field in the second 137 * register and it is currently reserved (should be always 0) */ 138 #define AL_ETH_KR_AN_ADV3_TECH_MASK 0x1fff 139 #define AL_ETH_KR_AN_ADV3_TECH_SHIFT 0 140 #define AL_ETH_KR_AN_ADV3_FEC_MASK 0xc000 141 #define AL_ETH_KR_AN_ADV3_FEC_SHIFT 14 142 143 /* Next Page Fields */ 144 /* register 1 */ 145 #define AL_ETH_KR_AN_NP_ADV1_DATA1_MASK 0x07ff 146 #define AL_ETH_KR_AN_NP_ADV1_DATA1_SHIFT 0 147 #define AL_ETH_KR_AN_NP_ADV1_TOGGLE_MASK 0x0800 148 #define AL_ETH_KR_AN_NP_ADV1_TOGGLE_SHIFT 11 149 #define AL_ETH_KR_AN_NP_ADV1_ACK2_MASK 0x1000 150 #define AL_ETH_KR_AN_NP_ADV1_ACK2_SHIFT 12 151 #define AL_ETH_KR_AN_NP_ADV1_MSG_PAGE_MASK 0x2000 152 #define AL_ETH_KR_AN_NP_ADV1_MSG_PAGE_SHIFT 13 153 #define AL_ETH_KR_AN_NP_ADV1_NP_MASK 0x8000 154 #define AL_ETH_KR_AN_NP_ADV1_NP_SHIFT 15 155 156 /* 157 * LT(Link Training) registers 158 * (read / write indirect with al_eth_pma_reg_read/write) 159 */ 160 #define AL_ETH_KR_PMD_CONTROL_RESTART 0 161 #define AL_ETH_KR_PMD_CONTROL_ENABLE 1 162 163 #define AL_ETH_KR_PMD_STATUS_RECEIVER_COMPLETED_SHIFT 0 164 #define AL_ETH_KR_PMD_STATUS_RECEIVER_FRAME_LOCK_SHIFT 1 165 #define AL_ETH_KR_PMD_STATUS_RECEIVER_START_UP_PROTO_PROG_SHIFT 2 166 #define AL_ETH_KR_PMD_STATUS_FAILURE_SHIFT 3 167 168 #define AL_ETH_KR_PMD_LP_COEF_UP_MINUS_MASK 0x0003 169 #define AL_ETH_KR_PMD_LP_COEF_UP_MINUS_SHIFT 0 170 #define AL_ETH_KR_PMD_LP_COEF_UP_ZERO_MASK 0x000C 171 #define AL_ETH_KR_PMD_LP_COEF_UP_ZERO_SHIFT 2 172 #define AL_ETH_KR_PMD_LP_COEF_UP_PLUS_MASK 0x0030 173 #define AL_ETH_KR_PMD_LP_COEF_UP_PLUS_SHIFT 4 174 #define AL_ETH_KR_PMD_LP_COEF_UP_INITIALIZE_SHIFT 12 175 #define AL_ETH_KR_PMD_LP_COEF_UP_PRESET_SHIFT 13 176 177 #define AL_ETH_KR_PMD_LP_STATUS_REPORT_MINUS_MASK 0x0003 178 #define AL_ETH_KR_PMD_LP_STATUS_REPORT_MINUS_SHIFT 0 179 #define AL_ETH_KR_PMD_LP_STATUS_REPORT_ZERO_MASK 0x000C 180 #define AL_ETH_KR_PMD_LP_STATUS_REPORT_ZERO_SHIFT 2 181 #define AL_ETH_KR_PMD_LP_STATUS_REPORT_PLUS_MASK 0x0030 182 #define AL_ETH_KR_PMD_LP_STATUS_REPORT_PLUS_SHIFT 4 183 #define AL_ETH_KR_PMD_LP_STATUS_RECEIVER_READY_SHIFT 15 184 185 #define AL_ETH_KR_PMD_LD_COEF_UP_MINUS_MASK 0x0003 186 #define AL_ETH_KR_PMD_LD_COEF_UP_MINUS_SHIFT 0 187 #define AL_ETH_KR_PMD_LD_COEF_UP_ZERO_MASK 0x000C 188 #define AL_ETH_KR_PMD_LD_COEF_UP_ZERO_SHIFT 2 189 #define AL_ETH_KR_PMD_LD_COEF_UP_PLUS_MASK 0x0030 190 #define AL_ETH_KR_PMD_LD_COEF_UP_PLUS_SHIFT 4 191 #define AL_ETH_KR_PMD_LD_COEF_UP_INITIALIZE_SHIFT 12 192 #define AL_ETH_KR_PMD_LD_COEF_UP_PRESET_SHIFT 13 193 194 #define AL_ETH_KR_PMD_LD_STATUS_REPORT_MINUS_MASK 0x0003 195 #define AL_ETH_KR_PMD_LD_STATUS_REPORT_MINUS_SHIFT 0 196 #define AL_ETH_KR_PMD_LD_STATUS_REPORT_ZERO_MASK 0x000C 197 #define AL_ETH_KR_PMD_LD_STATUS_REPORT_ZERO_SHIFT 2 198 #define AL_ETH_KR_PMD_LD_STATUS_REPORT_PLUS_MASK 0x0030 199 #define AL_ETH_KR_PMD_LD_STATUS_REPORT_PLUS_SHIFT 4 200 #define AL_ETH_KR_PMD_LD_STATUS_REPORT_RECEIVER_READY_SHIFT 15 201 202 203 enum al_eth_an_lt_regs { 204 AL_ETH_AN_REGS, 205 AL_ETH_LT_REGS, 206 }; 207 208 static uint16_t al_eth_an_lt_reg_read( 209 struct al_hal_eth_adapter *adapter, 210 enum al_eth_an_lt_regs_ids reg_id, 211 enum al_eth_an_lt_regs an_lt, 212 enum al_eth_an_lt_lane lane) 213 { 214 uint32_t val; 215 uint16_t reg_addr; 216 217 if (adapter->rev_id < AL_ETH_REV_ID_3) { 218 al_assert(lane == AL_ETH_AN__LT_LANE_0); 219 220 reg_addr = al_eth_an_lt_regs_addr[reg_id][AL_ETH_LT_UNIT_REV_1]; 221 if (an_lt == AL_ETH_AN_REGS) { 222 al_reg_write32(&adapter->mac_regs_base->kr.an_addr, reg_addr); 223 val = al_reg_read32(&adapter->mac_regs_base->kr.an_data); 224 } else { 225 al_reg_write32(&adapter->mac_regs_base->kr.pma_addr, reg_addr); 226 val = al_reg_read32(&adapter->mac_regs_base->kr.pma_data); 227 } 228 } else { 229 struct al_an_lt_wrapper_regs *regs = NULL; 230 231 reg_addr = al_eth_an_lt_regs_addr[reg_id][AL_ETH_LT_UNIT_REV_2]; 232 233 switch (lane) { 234 case AL_ETH_AN__LT_LANE_0: 235 al_reg_write32(&adapter->mac_regs_base->gen_v3.an_lt_0_addr, 236 (uintptr_t)®s->an_lt[adapter->curr_lt_unit].addr); 237 al_reg_write32(&adapter->mac_regs_base->gen_v3.an_lt_0_data, 238 reg_addr); 239 240 al_reg_write32(&adapter->mac_regs_base->gen_v3.an_lt_0_addr, 241 (uintptr_t)®s->an_lt[adapter->curr_lt_unit].data); 242 val = al_reg_read32(&adapter->mac_regs_base->gen_v3.an_lt_0_data); 243 break; 244 case AL_ETH_AN__LT_LANE_1: 245 al_reg_write32(&adapter->mac_regs_base->gen_v3.an_lt_1_addr, 246 (uintptr_t)®s->an_lt[adapter->curr_lt_unit].addr); 247 al_reg_write32(&adapter->mac_regs_base->gen_v3.an_lt_1_data, 248 reg_addr); 249 250 al_reg_write32(&adapter->mac_regs_base->gen_v3.an_lt_1_addr, 251 (uintptr_t)®s->an_lt[adapter->curr_lt_unit].data); 252 val = al_reg_read32(&adapter->mac_regs_base->gen_v3.an_lt_1_data); 253 break; 254 case AL_ETH_AN__LT_LANE_2: 255 al_reg_write32(&adapter->mac_regs_base->gen_v3.an_lt_2_addr, 256 (uintptr_t)®s->an_lt[adapter->curr_lt_unit].addr); 257 al_reg_write32(&adapter->mac_regs_base->gen_v3.an_lt_2_data, 258 reg_addr); 259 260 al_reg_write32(&adapter->mac_regs_base->gen_v3.an_lt_2_addr, 261 (uintptr_t)®s->an_lt[adapter->curr_lt_unit].data); 262 val = al_reg_read32(&adapter->mac_regs_base->gen_v3.an_lt_2_data); 263 break; 264 case AL_ETH_AN__LT_LANE_3: 265 al_reg_write32(&adapter->mac_regs_base->gen_v3.an_lt_3_addr, 266 (uintptr_t)®s->an_lt[adapter->curr_lt_unit].addr); 267 al_reg_write32(&adapter->mac_regs_base->gen_v3.an_lt_3_data, 268 reg_addr); 269 270 al_reg_write32(&adapter->mac_regs_base->gen_v3.an_lt_3_addr, 271 (uintptr_t)®s->an_lt[adapter->curr_lt_unit].data); 272 val = al_reg_read32(&adapter->mac_regs_base->gen_v3.an_lt_3_data); 273 break; 274 default: 275 al_err("%s: Unknown Lane %d\n", __func__, lane); 276 return 0; 277 } 278 } 279 280 281 al_dbg("[%s]: %s - (%s) lane %d, reg %d, val 0x%x", adapter->name, __func__, 282 (an_lt == AL_ETH_AN_REGS) ? "AN" : "LT", lane, reg_addr, val); 283 284 return (uint16_t)val; 285 } 286 287 static void al_eth_an_lt_reg_write( 288 struct al_hal_eth_adapter *adapter, 289 enum al_eth_an_lt_regs_ids reg_id, 290 enum al_eth_an_lt_regs an_lt, 291 enum al_eth_an_lt_lane lane, 292 uint16_t val) 293 { 294 uint16_t reg_addr; 295 296 if (adapter->rev_id < AL_ETH_REV_ID_3) { 297 reg_addr = al_eth_an_lt_regs_addr[reg_id][AL_ETH_LT_UNIT_REV_1]; 298 if (an_lt == AL_ETH_AN_REGS) { 299 al_reg_write32(&adapter->mac_regs_base->kr.an_addr, reg_addr); 300 al_reg_write32(&adapter->mac_regs_base->kr.an_data, val); 301 } else { 302 al_reg_write32(&adapter->mac_regs_base->kr.pma_addr, reg_addr); 303 al_reg_write32(&adapter->mac_regs_base->kr.pma_data, val); 304 } 305 } else { 306 struct al_an_lt_wrapper_regs *regs = NULL; 307 308 reg_addr = al_eth_an_lt_regs_addr[reg_id][AL_ETH_LT_UNIT_REV_2]; 309 310 switch (lane) { 311 case AL_ETH_AN__LT_LANE_0: 312 al_reg_write32(&adapter->mac_regs_base->gen_v3.an_lt_0_addr, 313 (uintptr_t)®s->an_lt[adapter->curr_lt_unit].addr); 314 al_reg_write32(&adapter->mac_regs_base->gen_v3.an_lt_0_data, 315 reg_addr); 316 317 al_reg_write32(&adapter->mac_regs_base->gen_v3.an_lt_0_addr, 318 (uintptr_t)®s->an_lt[adapter->curr_lt_unit].data); 319 al_reg_write32(&adapter->mac_regs_base->gen_v3.an_lt_0_data, 320 val); 321 break; 322 case AL_ETH_AN__LT_LANE_1: 323 al_reg_write32(&adapter->mac_regs_base->gen_v3.an_lt_1_addr, 324 (uintptr_t)®s->an_lt[adapter->curr_lt_unit].addr); 325 al_reg_write32(&adapter->mac_regs_base->gen_v3.an_lt_1_data, 326 reg_addr); 327 328 al_reg_write32(&adapter->mac_regs_base->gen_v3.an_lt_1_addr, 329 (uintptr_t)®s->an_lt[adapter->curr_lt_unit].data); 330 al_reg_write32(&adapter->mac_regs_base->gen_v3.an_lt_1_data, 331 val); 332 break; 333 case AL_ETH_AN__LT_LANE_2: 334 al_reg_write32(&adapter->mac_regs_base->gen_v3.an_lt_2_addr, 335 (uintptr_t)®s->an_lt[adapter->curr_lt_unit].addr); 336 al_reg_write32(&adapter->mac_regs_base->gen_v3.an_lt_2_data, 337 reg_addr); 338 339 al_reg_write32(&adapter->mac_regs_base->gen_v3.an_lt_2_addr, 340 (uintptr_t)®s->an_lt[adapter->curr_lt_unit].data); 341 al_reg_write32(&adapter->mac_regs_base->gen_v3.an_lt_2_data, 342 val); 343 break; 344 case AL_ETH_AN__LT_LANE_3: 345 al_reg_write32(&adapter->mac_regs_base->gen_v3.an_lt_3_addr, 346 (uintptr_t)®s->an_lt[adapter->curr_lt_unit].addr); 347 al_reg_write32(&adapter->mac_regs_base->gen_v3.an_lt_3_data, 348 reg_addr); 349 350 al_reg_write32(&adapter->mac_regs_base->gen_v3.an_lt_3_addr, 351 (uintptr_t)®s->an_lt[adapter->curr_lt_unit].data); 352 al_reg_write32(&adapter->mac_regs_base->gen_v3.an_lt_3_data, 353 val); 354 break; 355 default: 356 al_err("%s: Unknown Lane %d\n", __func__, lane); 357 return; 358 } 359 } 360 361 362 al_dbg("[%s]: %s - (%s) lane %d, reg %d, val 0x%x", adapter->name, __func__, 363 (an_lt == AL_ETH_AN_REGS) ? "AN" : "LT", lane, reg_addr, val); 364 } 365 366 static void al_eth_an_lt_unit_config(struct al_hal_eth_adapter *adapter) 367 { 368 struct al_an_lt_wrapper_regs *regs = NULL; 369 uint32_t cfg_lane_0 = (AN_LT_WRAPPER_GEN_CFG_BYPASS_RX | AN_LT_WRAPPER_GEN_CFG_BYPASS_TX); 370 uint32_t cfg_lane_1 = (AN_LT_WRAPPER_GEN_CFG_BYPASS_RX | AN_LT_WRAPPER_GEN_CFG_BYPASS_TX); 371 uint32_t cfg_lane_2 = (AN_LT_WRAPPER_GEN_CFG_BYPASS_RX | AN_LT_WRAPPER_GEN_CFG_BYPASS_TX); 372 uint32_t cfg_lane_3 = (AN_LT_WRAPPER_GEN_CFG_BYPASS_RX | AN_LT_WRAPPER_GEN_CFG_BYPASS_TX); 373 374 switch (adapter->mac_mode) { 375 case AL_ETH_MAC_MODE_10GbE_Serial: 376 cfg_lane_0 = 0; 377 AL_REG_FIELD_SET(cfg_lane_0, 378 AN_LT_WRAPPER_GEN_CFG_AN_LT_SEL_RX_MASK, 379 AN_LT_WRAPPER_GEN_CFG_AN_LT_SEL_RX_SHIFT, 380 AL_ETH_AN_LT_UNIT_20_BIT); 381 AL_REG_FIELD_SET(cfg_lane_0, 382 AN_LT_WRAPPER_GEN_CFG_AN_LT_SEL_TX_MASK, 383 AN_LT_WRAPPER_GEN_CFG_AN_LT_SEL_TX_SHIFT, 384 AL_ETH_AN_LT_UNIT_20_BIT); 385 386 adapter->curr_lt_unit = AL_ETH_AN_LT_UNIT_20_BIT; 387 388 break; 389 case AL_ETH_MAC_MODE_KR_LL_25G: 390 cfg_lane_0 = 0; 391 AL_REG_FIELD_SET(cfg_lane_0, 392 AN_LT_WRAPPER_GEN_CFG_AN_LT_SEL_RX_MASK, 393 AN_LT_WRAPPER_GEN_CFG_AN_LT_SEL_RX_SHIFT, 394 AL_ETH_AN_LT_UNIT_32_BIT); 395 AL_REG_FIELD_SET(cfg_lane_0, 396 AN_LT_WRAPPER_GEN_CFG_AN_LT_SEL_TX_MASK, 397 AN_LT_WRAPPER_GEN_CFG_AN_LT_SEL_TX_SHIFT, 398 AL_ETH_AN_LT_UNIT_32_BIT); 399 400 adapter->curr_lt_unit = AL_ETH_AN_LT_UNIT_32_BIT; 401 402 break; 403 case AL_ETH_MAC_MODE_XLG_LL_40G: 404 cfg_lane_0 = 0; 405 AL_REG_FIELD_SET(cfg_lane_0, 406 AN_LT_WRAPPER_GEN_CFG_AN_LT_SEL_RX_MASK, 407 AN_LT_WRAPPER_GEN_CFG_AN_LT_SEL_RX_SHIFT, 408 AL_ETH_AN_LT_UNIT_16_BIT); 409 AL_REG_FIELD_SET(cfg_lane_0, 410 AN_LT_WRAPPER_GEN_CFG_AN_LT_SEL_TX_MASK, 411 AN_LT_WRAPPER_GEN_CFG_AN_LT_SEL_TX_SHIFT, 412 AL_ETH_AN_LT_UNIT_16_BIT); 413 414 cfg_lane_1 = 0; 415 AL_REG_FIELD_SET(cfg_lane_1, 416 AN_LT_WRAPPER_GEN_CFG_AN_LT_SEL_RX_MASK, 417 AN_LT_WRAPPER_GEN_CFG_AN_LT_SEL_RX_SHIFT, 418 AL_ETH_AN_LT_UNIT_16_BIT); 419 AL_REG_FIELD_SET(cfg_lane_1, 420 AN_LT_WRAPPER_GEN_CFG_AN_LT_SEL_TX_MASK, 421 AN_LT_WRAPPER_GEN_CFG_AN_LT_SEL_TX_SHIFT, 422 AL_ETH_AN_LT_UNIT_16_BIT); 423 424 cfg_lane_2 = 0; 425 AL_REG_FIELD_SET(cfg_lane_2, 426 AN_LT_WRAPPER_GEN_CFG_AN_LT_SEL_RX_MASK, 427 AN_LT_WRAPPER_GEN_CFG_AN_LT_SEL_RX_SHIFT, 428 AL_ETH_AN_LT_UNIT_16_BIT); 429 AL_REG_FIELD_SET(cfg_lane_2, 430 AN_LT_WRAPPER_GEN_CFG_AN_LT_SEL_TX_MASK, 431 AN_LT_WRAPPER_GEN_CFG_AN_LT_SEL_TX_SHIFT, 432 AL_ETH_AN_LT_UNIT_16_BIT); 433 434 cfg_lane_3 = 0; 435 AL_REG_FIELD_SET(cfg_lane_3, 436 AN_LT_WRAPPER_GEN_CFG_AN_LT_SEL_RX_MASK, 437 AN_LT_WRAPPER_GEN_CFG_AN_LT_SEL_RX_SHIFT, 438 AL_ETH_AN_LT_UNIT_16_BIT); 439 AL_REG_FIELD_SET(cfg_lane_3, 440 AN_LT_WRAPPER_GEN_CFG_AN_LT_SEL_TX_MASK, 441 AN_LT_WRAPPER_GEN_CFG_AN_LT_SEL_TX_SHIFT, 442 AL_ETH_AN_LT_UNIT_16_BIT); 443 444 adapter->curr_lt_unit = AL_ETH_AN_LT_UNIT_16_BIT; 445 446 break; 447 case AL_ETH_MAC_MODE_XLG_LL_50G: 448 cfg_lane_0 = 0; 449 AL_REG_FIELD_SET(cfg_lane_0, 450 AN_LT_WRAPPER_GEN_CFG_AN_LT_SEL_RX_MASK, 451 AN_LT_WRAPPER_GEN_CFG_AN_LT_SEL_RX_SHIFT, 452 AL_ETH_AN_LT_UNIT_32_BIT); 453 AL_REG_FIELD_SET(cfg_lane_0, 454 AN_LT_WRAPPER_GEN_CFG_AN_LT_SEL_TX_MASK, 455 AN_LT_WRAPPER_GEN_CFG_AN_LT_SEL_TX_SHIFT, 456 AL_ETH_AN_LT_UNIT_32_BIT); 457 458 cfg_lane_1 = 0; 459 AL_REG_FIELD_SET(cfg_lane_1, 460 AN_LT_WRAPPER_GEN_CFG_AN_LT_SEL_RX_MASK, 461 AN_LT_WRAPPER_GEN_CFG_AN_LT_SEL_RX_SHIFT, 462 AL_ETH_AN_LT_UNIT_32_BIT); 463 AL_REG_FIELD_SET(cfg_lane_1, 464 AN_LT_WRAPPER_GEN_CFG_AN_LT_SEL_TX_MASK, 465 AN_LT_WRAPPER_GEN_CFG_AN_LT_SEL_TX_SHIFT, 466 AL_ETH_AN_LT_UNIT_32_BIT); 467 468 adapter->curr_lt_unit = AL_ETH_AN_LT_UNIT_32_BIT; 469 470 break; 471 default: 472 al_err("%s: Unknown mac_mode\n", __func__); 473 return; 474 } 475 476 al_reg_write32(&adapter->mac_regs_base->gen_v3.an_lt_0_addr, 477 (uintptr_t)®s->gen.cfg); 478 al_reg_write32(&adapter->mac_regs_base->gen_v3.an_lt_0_data, 479 cfg_lane_0); 480 481 al_reg_write32(&adapter->mac_regs_base->gen_v3.an_lt_1_addr, 482 (uintptr_t)®s->gen.cfg); 483 al_reg_write32(&adapter->mac_regs_base->gen_v3.an_lt_1_data, 484 cfg_lane_1); 485 486 al_reg_write32(&adapter->mac_regs_base->gen_v3.an_lt_2_addr, 487 (uintptr_t)®s->gen.cfg); 488 al_reg_write32(&adapter->mac_regs_base->gen_v3.an_lt_2_data, 489 cfg_lane_2); 490 491 al_reg_write32(&adapter->mac_regs_base->gen_v3.an_lt_3_addr, 492 (uintptr_t)®s->gen.cfg); 493 al_reg_write32(&adapter->mac_regs_base->gen_v3.an_lt_3_data, 494 cfg_lane_3); 495 } 496 497 void al_eth_lp_coeff_up_get( 498 struct al_hal_eth_adapter *adapter, 499 enum al_eth_an_lt_lane lane, 500 struct al_eth_kr_coef_up_data *lpcoeff) 501 { 502 uint16_t reg; 503 504 reg = al_eth_an_lt_reg_read(adapter, AL_ETH_KR_PMD_LP_COEF_UP, AL_ETH_LT_REGS, lane); 505 506 lpcoeff->preset = 507 (AL_REG_BIT_GET( 508 reg, AL_ETH_KR_PMD_LP_COEF_UP_PRESET_SHIFT) != 0); 509 510 lpcoeff->initialize = 511 (AL_REG_BIT_GET( 512 reg, AL_ETH_KR_PMD_LP_COEF_UP_INITIALIZE_SHIFT) != 0); 513 514 lpcoeff->c_minus = AL_REG_FIELD_GET(reg, 515 AL_ETH_KR_PMD_LP_COEF_UP_MINUS_MASK, 516 AL_ETH_KR_PMD_LP_COEF_UP_MINUS_SHIFT); 517 518 lpcoeff->c_zero = AL_REG_FIELD_GET(reg, 519 AL_ETH_KR_PMD_LP_COEF_UP_ZERO_MASK, 520 AL_ETH_KR_PMD_LP_COEF_UP_ZERO_SHIFT); 521 522 lpcoeff->c_plus = AL_REG_FIELD_GET(reg, 523 AL_ETH_KR_PMD_LP_COEF_UP_PLUS_MASK, 524 AL_ETH_KR_PMD_LP_COEF_UP_PLUS_SHIFT); 525 } 526 527 void al_eth_lp_status_report_get( 528 struct al_hal_eth_adapter *adapter, 529 enum al_eth_an_lt_lane lane, 530 struct al_eth_kr_status_report_data *status) 531 { 532 uint16_t reg; 533 534 reg = al_eth_an_lt_reg_read(adapter, AL_ETH_KR_PMD_LP_STATUS_REPORT, AL_ETH_LT_REGS, lane); 535 536 status->c_minus = AL_REG_FIELD_GET(reg, 537 AL_ETH_KR_PMD_LP_STATUS_REPORT_MINUS_MASK, 538 AL_ETH_KR_PMD_LP_STATUS_REPORT_MINUS_SHIFT); 539 540 status->c_zero = AL_REG_FIELD_GET(reg, 541 AL_ETH_KR_PMD_LP_STATUS_REPORT_ZERO_MASK, 542 AL_ETH_KR_PMD_LP_STATUS_REPORT_ZERO_SHIFT); 543 544 status->c_plus = AL_REG_FIELD_GET(reg, 545 AL_ETH_KR_PMD_LP_STATUS_REPORT_PLUS_MASK, 546 AL_ETH_KR_PMD_LP_STATUS_REPORT_PLUS_SHIFT); 547 548 status->receiver_ready = 549 (AL_REG_BIT_GET( 550 reg, AL_ETH_KR_PMD_LP_STATUS_RECEIVER_READY_SHIFT) != 0); 551 552 } 553 554 void al_eth_ld_coeff_up_set( 555 struct al_hal_eth_adapter *adapter, 556 enum al_eth_an_lt_lane lane, 557 struct al_eth_kr_coef_up_data *ldcoeff) 558 { 559 uint16_t reg = 0; 560 561 if (ldcoeff->preset) 562 AL_REG_BIT_SET(reg, AL_ETH_KR_PMD_LD_COEF_UP_PRESET_SHIFT); 563 564 if (ldcoeff->initialize) 565 AL_REG_BIT_SET(reg, AL_ETH_KR_PMD_LD_COEF_UP_INITIALIZE_SHIFT); 566 567 AL_REG_FIELD_SET(reg, 568 AL_ETH_KR_PMD_LD_COEF_UP_MINUS_MASK, 569 AL_ETH_KR_PMD_LD_COEF_UP_MINUS_SHIFT, 570 ldcoeff->c_minus); 571 572 AL_REG_FIELD_SET(reg, 573 AL_ETH_KR_PMD_LD_COEF_UP_ZERO_MASK, 574 AL_ETH_KR_PMD_LD_COEF_UP_ZERO_SHIFT, 575 ldcoeff->c_zero); 576 577 AL_REG_FIELD_SET(reg, 578 AL_ETH_KR_PMD_LD_COEF_UP_PLUS_MASK, 579 AL_ETH_KR_PMD_LD_COEF_UP_PLUS_SHIFT, 580 ldcoeff->c_plus); 581 582 al_eth_an_lt_reg_write(adapter, AL_ETH_KR_PMD_LD_COEF_UP, AL_ETH_LT_REGS, lane, reg); 583 } 584 585 void al_eth_ld_status_report_set( 586 struct al_hal_eth_adapter *adapter, 587 enum al_eth_an_lt_lane lane, 588 struct al_eth_kr_status_report_data *status) 589 { 590 uint16_t reg = 0; 591 592 AL_REG_FIELD_SET(reg, 593 AL_ETH_KR_PMD_LD_STATUS_REPORT_MINUS_MASK, 594 AL_ETH_KR_PMD_LD_STATUS_REPORT_MINUS_SHIFT, 595 status->c_minus); 596 597 AL_REG_FIELD_SET(reg, 598 AL_ETH_KR_PMD_LD_STATUS_REPORT_ZERO_MASK, 599 AL_ETH_KR_PMD_LD_STATUS_REPORT_ZERO_SHIFT, 600 status->c_zero); 601 602 AL_REG_FIELD_SET(reg, 603 AL_ETH_KR_PMD_LD_STATUS_REPORT_PLUS_MASK, 604 AL_ETH_KR_PMD_LD_STATUS_REPORT_PLUS_SHIFT, 605 status->c_plus); 606 607 if (status->receiver_ready) 608 AL_REG_BIT_SET(reg, 609 AL_ETH_KR_PMD_LD_STATUS_REPORT_RECEIVER_READY_SHIFT); 610 611 al_eth_an_lt_reg_write(adapter, AL_ETH_KR_PMD_LD_STATUS_REPORT, AL_ETH_LT_REGS, lane, reg); 612 } 613 614 al_bool al_eth_kr_receiver_frame_lock_get(struct al_hal_eth_adapter *adapter, 615 enum al_eth_an_lt_lane lane) 616 { 617 uint16_t reg; 618 619 reg = al_eth_an_lt_reg_read(adapter, AL_ETH_KR_PMD_STATUS, AL_ETH_LT_REGS, lane); 620 621 return (AL_REG_BIT_GET(reg, 622 AL_ETH_KR_PMD_STATUS_RECEIVER_FRAME_LOCK_SHIFT) != 0); 623 } 624 625 al_bool al_eth_kr_startup_proto_prog_get(struct al_hal_eth_adapter *adapter, 626 enum al_eth_an_lt_lane lane) 627 { 628 uint16_t reg; 629 630 reg = al_eth_an_lt_reg_read(adapter, AL_ETH_KR_PMD_STATUS, AL_ETH_LT_REGS, lane); 631 632 return (AL_REG_BIT_GET( 633 reg, AL_ETH_KR_PMD_STATUS_RECEIVER_START_UP_PROTO_PROG_SHIFT) != 0); 634 } 635 636 al_bool al_eth_kr_training_status_fail_get(struct al_hal_eth_adapter *adapter, 637 enum al_eth_an_lt_lane lane) 638 { 639 uint16_t reg; 640 641 reg = al_eth_an_lt_reg_read(adapter, AL_ETH_KR_PMD_STATUS, AL_ETH_LT_REGS, lane); 642 643 return (AL_REG_BIT_GET(reg, AL_ETH_KR_PMD_STATUS_FAILURE_SHIFT) != 0); 644 } 645 646 void al_eth_receiver_ready_set(struct al_hal_eth_adapter *adapter, 647 enum al_eth_an_lt_lane lane) 648 { 649 al_eth_an_lt_reg_write(adapter, AL_ETH_KR_PMD_STATUS, AL_ETH_LT_REGS, lane, 1); 650 } 651 652 /*************************** auto negotiation *********************************/ 653 static int al_eth_kr_an_validate_adv(struct al_hal_eth_adapter *adapter, 654 struct al_eth_an_adv *an_adv) 655 { 656 al_assert(adapter); 657 658 if (an_adv == NULL) 659 return 0; 660 661 if (an_adv->selector_field != 1) { 662 al_err("[%s]: %s failed on selector_field (%d)\n", 663 adapter->name, __func__, an_adv->selector_field); 664 return -EINVAL; 665 } 666 667 if (an_adv->capability & AL_BIT(2)) { 668 al_err("[%s]: %s failed on capability bit 2 (%d)\n", 669 adapter->name, __func__, an_adv->capability); 670 return -EINVAL; 671 } 672 673 if (an_adv->remote_fault) { 674 al_err("[%s]: %s failed on remote_fault (%d)\n", 675 adapter->name, __func__, an_adv->remote_fault); 676 return -EINVAL; 677 } 678 679 if (an_adv->acknowledge) { 680 al_err("[%s]: %s failed on acknowledge (%d)\n", 681 adapter->name, __func__, an_adv->acknowledge); 682 return -EINVAL; 683 } 684 685 return 0; 686 } 687 688 static int al_eth_kr_an_write_adv(struct al_hal_eth_adapter *adapter, 689 struct al_eth_an_adv *an_adv) 690 { 691 uint16_t reg; 692 693 if(an_adv == NULL) 694 return 0; 695 696 reg = 0; 697 AL_REG_FIELD_SET(reg, AL_ETH_KR_AN_ADV1_SEL_FIELD_MASK, 698 AL_ETH_KR_AN_ADV1_SEL_FIELD_SHIFT, 699 an_adv->selector_field); 700 701 AL_REG_FIELD_SET(reg, AL_ETH_KR_AN_ADV1_ECHOED_NONCE_MASK, 702 AL_ETH_KR_AN_ADV1_ECHOED_NONCE_SHIFT, 703 an_adv->echoed_nonce); 704 705 AL_REG_FIELD_SET(reg, AL_ETH_KR_AN_ADV1_CAPABILITY_MASK, 706 AL_ETH_KR_AN_ADV1_CAPABILITY_SHIFT, 707 an_adv->capability); 708 709 AL_REG_BIT_VAL_SET(reg, AL_ETH_KR_AN_ADV1_REM_FAULT_SHIFT, 710 an_adv->remote_fault); 711 712 AL_REG_BIT_VAL_SET(reg, AL_ETH_KR_AN_ADV1_ACK_SHIFT, 713 an_adv->acknowledge); 714 715 AL_REG_BIT_VAL_SET(reg, AL_ETH_KR_AN_ADV1_NEXT_PAGE_SHIFT, 716 an_adv->next_page); 717 718 al_eth_an_lt_reg_write(adapter, AL_ETH_KR_AN_ADV0, AL_ETH_AN_REGS, 719 AL_ETH_AN__LT_LANE_0, reg); 720 721 reg = 0; 722 AL_REG_FIELD_SET(reg, AL_ETH_KR_AN_ADV2_TX_NONCE_MASK, 723 AL_ETH_KR_AN_ADV2_TX_NONCE_SHIFT, 724 an_adv->transmitted_nonce); 725 726 AL_REG_FIELD_SET(reg, AL_ETH_KR_AN_ADV2_TECH_MASK, 727 AL_ETH_KR_AN_ADV2_TECH_SHIFT, 728 an_adv->technology); 729 730 al_eth_an_lt_reg_write(adapter, AL_ETH_KR_AN_ADV1, AL_ETH_AN_REGS, 731 AL_ETH_AN__LT_LANE_0, reg); 732 733 reg = 0; 734 AL_REG_FIELD_SET(reg, AL_ETH_KR_AN_ADV3_TECH_MASK, 735 AL_ETH_KR_AN_ADV3_TECH_SHIFT, 736 an_adv->technology >> 11); 737 738 AL_REG_FIELD_SET(reg, AL_ETH_KR_AN_ADV3_FEC_MASK, 739 AL_ETH_KR_AN_ADV3_FEC_SHIFT, 740 an_adv->fec_capability); 741 742 al_eth_an_lt_reg_write(adapter, AL_ETH_KR_AN_ADV2, AL_ETH_AN_REGS, 743 AL_ETH_AN__LT_LANE_0, reg); 744 745 return 0; 746 } 747 748 void al_eth_kr_an_read_adv(struct al_hal_eth_adapter *adapter, 749 struct al_eth_an_adv *an_adv) 750 { 751 int16_t reg; 752 753 al_assert(an_adv != NULL); 754 755 756 reg = al_eth_an_lt_reg_read(adapter, AL_ETH_KR_AN_REM_ADV0, 757 AL_ETH_AN_REGS, AL_ETH_AN__LT_LANE_0); 758 759 an_adv->selector_field = AL_REG_FIELD_GET(reg, 760 AL_ETH_KR_AN_ADV1_SEL_FIELD_MASK, 761 AL_ETH_KR_AN_ADV1_SEL_FIELD_SHIFT); 762 763 an_adv->echoed_nonce = AL_REG_FIELD_GET(reg, 764 AL_ETH_KR_AN_ADV1_ECHOED_NONCE_MASK, 765 AL_ETH_KR_AN_ADV1_ECHOED_NONCE_SHIFT); 766 767 an_adv->capability = AL_REG_FIELD_GET(reg, 768 AL_ETH_KR_AN_ADV1_CAPABILITY_MASK, 769 AL_ETH_KR_AN_ADV1_CAPABILITY_SHIFT); 770 771 an_adv->remote_fault = AL_REG_BIT_GET(reg, 772 AL_ETH_KR_AN_ADV1_REM_FAULT_SHIFT); 773 774 an_adv->acknowledge = AL_REG_BIT_GET(reg, 775 AL_ETH_KR_AN_ADV1_ACK_SHIFT); 776 777 an_adv->next_page = AL_REG_BIT_GET(reg, 778 AL_ETH_KR_AN_ADV1_NEXT_PAGE_SHIFT); 779 780 781 reg = al_eth_an_lt_reg_read(adapter, AL_ETH_KR_AN_REM_ADV1, 782 AL_ETH_AN_REGS, AL_ETH_AN__LT_LANE_0); 783 784 an_adv->transmitted_nonce = AL_REG_FIELD_GET(reg, 785 AL_ETH_KR_AN_ADV2_TX_NONCE_MASK, 786 AL_ETH_KR_AN_ADV2_TX_NONCE_SHIFT); 787 788 an_adv->technology = AL_REG_FIELD_GET(reg, 789 AL_ETH_KR_AN_ADV2_TECH_MASK, 790 AL_ETH_KR_AN_ADV2_TECH_SHIFT); 791 792 793 reg = al_eth_an_lt_reg_read(adapter, AL_ETH_KR_AN_REM_ADV2, 794 AL_ETH_AN_REGS, AL_ETH_AN__LT_LANE_0); 795 796 an_adv->technology |= (AL_REG_FIELD_GET(reg, 797 AL_ETH_KR_AN_ADV3_TECH_MASK, 798 AL_ETH_KR_AN_ADV3_TECH_SHIFT) << 11); 799 800 an_adv->fec_capability = AL_REG_FIELD_GET(reg, 801 AL_ETH_KR_AN_ADV3_FEC_MASK, 802 AL_ETH_KR_AN_ADV3_FEC_SHIFT); 803 } 804 805 int al_eth_kr_next_page_read(struct al_hal_eth_adapter *adapter, 806 struct al_eth_an_np *np) 807 { 808 uint16_t reg; 809 810 reg = al_eth_an_lt_reg_read(adapter, 811 AL_ETH_KR_AN_REM_XNP_ADV0, 812 AL_ETH_AN_REGS, 813 AL_ETH_AN__LT_LANE_0); 814 815 np->unformatted_code_field = AL_REG_FIELD_GET(reg, AL_ETH_KR_AN_NP_ADV1_DATA1_MASK, 816 AL_ETH_KR_AN_NP_ADV1_DATA1_SHIFT); 817 818 np->toggle = AL_REG_FIELD_GET(reg, AL_ETH_KR_AN_NP_ADV1_TOGGLE_MASK, 819 AL_ETH_KR_AN_NP_ADV1_TOGGLE_SHIFT); 820 821 np->ack2 = AL_REG_FIELD_GET(reg, AL_ETH_KR_AN_NP_ADV1_ACK2_MASK, 822 AL_ETH_KR_AN_NP_ADV1_ACK2_SHIFT); 823 824 np->msg_page = AL_REG_FIELD_GET(reg, AL_ETH_KR_AN_NP_ADV1_MSG_PAGE_MASK, 825 AL_ETH_KR_AN_NP_ADV1_MSG_PAGE_SHIFT); 826 827 np->next_page = AL_REG_FIELD_GET(reg, AL_ETH_KR_AN_NP_ADV1_NP_MASK, 828 AL_ETH_KR_AN_NP_ADV1_NP_SHIFT); 829 830 np->unformatted_code_field1 = al_eth_an_lt_reg_read(adapter, 831 AL_ETH_KR_AN_REM_XNP_ADV1, 832 AL_ETH_AN_REGS, 833 AL_ETH_AN__LT_LANE_0); 834 np->unformatted_code_field2 = al_eth_an_lt_reg_read(adapter, 835 AL_ETH_KR_AN_REM_XNP_ADV2, 836 AL_ETH_AN_REGS, 837 AL_ETH_AN__LT_LANE_0); 838 839 return 0; 840 } 841 842 int al_eth_kr_next_page_write(struct al_hal_eth_adapter *adapter, 843 struct al_eth_an_np *np) 844 { 845 uint16_t reg = 0; 846 847 AL_REG_FIELD_SET(reg, AL_ETH_KR_AN_NP_ADV1_DATA1_MASK, 848 AL_ETH_KR_AN_NP_ADV1_DATA1_SHIFT, 849 np->unformatted_code_field); 850 AL_REG_FIELD_SET(reg, AL_ETH_KR_AN_NP_ADV1_TOGGLE_MASK, 851 AL_ETH_KR_AN_NP_ADV1_TOGGLE_SHIFT, 852 np->toggle); 853 AL_REG_FIELD_SET(reg, AL_ETH_KR_AN_NP_ADV1_ACK2_MASK, 854 AL_ETH_KR_AN_NP_ADV1_ACK2_SHIFT, 855 np->ack2); 856 AL_REG_FIELD_SET(reg, AL_ETH_KR_AN_NP_ADV1_MSG_PAGE_MASK, 857 AL_ETH_KR_AN_NP_ADV1_MSG_PAGE_SHIFT, 858 np->msg_page); 859 AL_REG_FIELD_SET(reg, AL_ETH_KR_AN_NP_ADV1_NP_MASK, 860 AL_ETH_KR_AN_NP_ADV1_NP_SHIFT, 861 np->next_page); 862 863 al_eth_an_lt_reg_write(adapter, AL_ETH_KR_AN_XNP_ADV0, AL_ETH_AN_REGS, 864 AL_ETH_AN__LT_LANE_0, reg); 865 866 al_eth_an_lt_reg_write(adapter, AL_ETH_KR_AN_XNP_ADV1, AL_ETH_AN_REGS, 867 AL_ETH_AN__LT_LANE_0, np->unformatted_code_field1); 868 al_eth_an_lt_reg_write(adapter, AL_ETH_KR_AN_XNP_ADV2, AL_ETH_AN_REGS, 869 AL_ETH_AN__LT_LANE_0, np->unformatted_code_field2); 870 871 return 0; 872 } 873 874 int al_eth_kr_an_init(struct al_hal_eth_adapter *adapter, 875 struct al_eth_an_adv *an_adv) 876 { 877 int rc; 878 879 if (adapter->rev_id > AL_ETH_REV_ID_2) 880 al_eth_an_lt_unit_config(adapter); 881 882 rc = al_eth_kr_an_validate_adv(adapter, an_adv); 883 if (rc) 884 return rc; 885 886 rc = al_eth_kr_an_write_adv(adapter, an_adv); 887 if (rc) 888 return rc; 889 890 /* clear status */ 891 al_eth_an_lt_reg_read(adapter, AL_ETH_KR_AN_STATUS, AL_ETH_AN_REGS, AL_ETH_AN__LT_LANE_0); 892 893 al_dbg("[%s]: autonegotiation initialized successfully", adapter->name); 894 return 0; 895 } 896 897 int al_eth_kr_an_start(struct al_hal_eth_adapter *adapter, 898 enum al_eth_an_lt_lane lane, 899 al_bool next_page_enable, 900 al_bool lt_enable) 901 { 902 uint16_t control = AL_ETH_KR_AN_CONTROL_ENABLE | AL_ETH_KR_AN_CONTROL_RESTART; 903 904 al_dbg("Eth [%s]: enable autonegotiation. lt_en %s", 905 adapter->name, (lt_enable == AL_TRUE) ? "yes" : "no"); 906 907 al_eth_an_lt_reg_write(adapter, AL_ETH_KR_PMD_CONTROL, AL_ETH_LT_REGS, 908 lane, AL_BIT(AL_ETH_KR_PMD_CONTROL_RESTART)); 909 910 if (next_page_enable == AL_TRUE) 911 control |= AL_ETH_KR_AN_CONTROL_NP_ENABLE; 912 913 al_eth_an_lt_reg_write(adapter, AL_ETH_KR_AN_CONTROL, AL_ETH_AN_REGS, 914 lane, control); 915 916 if (lt_enable == AL_TRUE) { 917 al_eth_kr_lt_initialize(adapter, lane); 918 } 919 920 return 0; 921 } 922 923 void al_eth_kr_an_stop(struct al_hal_eth_adapter *adapter) 924 { 925 al_eth_an_lt_reg_write(adapter, AL_ETH_KR_AN_CONTROL, AL_ETH_AN_REGS, 926 AL_ETH_AN__LT_LANE_0, 0); 927 } 928 929 void al_eth_kr_an_status_check(struct al_hal_eth_adapter *adapter, 930 al_bool *page_received, 931 al_bool *an_completed, 932 al_bool *error) 933 { 934 uint16_t reg; 935 936 reg = al_eth_an_lt_reg_read(adapter, AL_ETH_KR_AN_STATUS, 937 AL_ETH_AN_REGS, AL_ETH_AN__LT_LANE_0); 938 939 if ((reg & AL_ETH_KR_AN_STATUS_CHECK_MASK) != 940 AL_ETH_KR_AN_STATUS_CHECK_NO_ERROR) { 941 al_err("[%s]: %s AN_STATUS (0x%x) indicated error\n", 942 adapter->name, __func__, reg); 943 944 *error = AL_TRUE; 945 } 946 947 if (reg & AL_ETH_KR_AN_STATUS_BASE_PAGE_RECEIVED) 948 *page_received = AL_TRUE; 949 else 950 *page_received = AL_FALSE; 951 952 if (reg & AL_ETH_KR_AN_STATUS_COMPLETED) 953 *an_completed = AL_TRUE; 954 else 955 *an_completed = AL_FALSE; 956 } 957 958 959 /****************************** KR Link Training *****************************/ 960 void al_eth_kr_lt_restart(struct al_hal_eth_adapter *adapter, 961 enum al_eth_an_lt_lane lane) 962 { 963 al_dbg("[%s]: KR LT Restart Link Training.\n", adapter->name); 964 965 al_eth_an_lt_reg_write(adapter, AL_ETH_KR_PMD_CONTROL, AL_ETH_LT_REGS, 966 lane, (AL_BIT(AL_ETH_KR_PMD_CONTROL_ENABLE) | 967 AL_BIT(AL_ETH_KR_PMD_CONTROL_RESTART))); 968 } 969 970 void al_eth_kr_lt_stop(struct al_hal_eth_adapter *adapter, 971 enum al_eth_an_lt_lane lane) 972 { 973 al_dbg("[%s]: KR LT Stop Link Training.\n", adapter->name); 974 975 al_eth_an_lt_reg_write(adapter, AL_ETH_KR_PMD_CONTROL, AL_ETH_LT_REGS, 976 lane, AL_BIT(AL_ETH_KR_PMD_CONTROL_RESTART)); 977 } 978 979 void al_eth_kr_lt_initialize(struct al_hal_eth_adapter *adapter, 980 enum al_eth_an_lt_lane lane) 981 { 982 al_dbg("[%s]: KR LT Initialize.\n", adapter->name); 983 984 /* Reset LT state machine */ 985 al_eth_kr_lt_stop(adapter, lane); 986 987 /* clear receiver status */ 988 al_eth_an_lt_reg_write(adapter, AL_ETH_KR_PMD_STATUS, AL_ETH_LT_REGS, lane, 0); 989 990 /* Coefficient Update to all zero (no command, hold) */ 991 al_eth_an_lt_reg_write(adapter, AL_ETH_KR_PMD_LD_COEF_UP, AL_ETH_LT_REGS, lane, 0); 992 /* Coefficient Status to all zero (not_updated) */ 993 al_eth_an_lt_reg_write(adapter, AL_ETH_KR_PMD_LD_STATUS_REPORT, AL_ETH_LT_REGS, lane, 0); 994 995 /* start */ 996 al_eth_kr_lt_restart(adapter, lane); 997 } 998 999 al_bool al_eth_kr_lt_frame_lock_wait(struct al_hal_eth_adapter *adapter, 1000 enum al_eth_an_lt_lane lane, 1001 uint32_t timeout) 1002 { 1003 uint32_t loop; 1004 uint16_t reg = 0; 1005 1006 for (loop = 0; loop < timeout; loop++) { 1007 reg = al_eth_an_lt_reg_read(adapter, AL_ETH_KR_PMD_STATUS, AL_ETH_LT_REGS, lane); 1008 1009 if (AL_REG_BIT_GET(reg, AL_ETH_KR_PMD_STATUS_FAILURE_SHIFT)) { 1010 al_info("[%s]: Failed on Training Failure." 1011 " loops %d PMD STATUS 0x%04x\n", 1012 adapter->name, loop, reg); 1013 1014 return AL_FALSE; 1015 } 1016 if (AL_REG_BIT_GET(reg, 1017 AL_ETH_KR_PMD_STATUS_RECEIVER_FRAME_LOCK_SHIFT)) { 1018 al_dbg("[%s]: Frame lock received." 1019 " loops %d PMD STATUS 0x%04x\n", 1020 adapter->name, loop, reg); 1021 1022 return AL_TRUE; 1023 } 1024 al_udelay(1); 1025 } 1026 al_info("[%s]: Failed on timeout. PMD STATUS 0x%04x\n", 1027 adapter->name, reg); 1028 1029 return AL_FALSE; 1030 } 1031