2 *******************************************************************************
3 Copyright (C) 2015 Annapurna Labs Ltd.
5 This file may be licensed under the terms of the Annapurna Labs Commercial
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
12 Alternatively, redistribution and use in source and binary forms, with or
13 without modification, are permitted provided that the following conditions are
16 * Redistributions of source code must retain the above copyright notice,
17 this list of conditions and the following disclaimer.
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
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.
35 *******************************************************************************/
39 * @file al_hal_eth_kr.c
41 * @brief KR HAL driver for main functions (auto-neg, Link Training)
45 #include "al_hal_eth_kr.h"
46 #include "al_hal_eth_mac_regs.h"
47 #include "al_hal_an_lt_wrapper_regs.h"
49 enum al_eth_lt_unit_rev {
50 AL_ETH_LT_UNIT_REV_1 = 0,
53 AL_ETH_LT_UNIT_REV_MAX
56 enum al_eth_an_lt_regs_ids {
57 AL_ETH_KR_AN_CONTROL = 0,
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,
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,
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},
104 * AN(Auto Negotiation) registers
105 * (read / write indirect with al_eth_an_reg_read/write)
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)
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
116 /* AN advertising registers parsing */
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
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
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
143 /* Next Page Fields */
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
157 * LT(Link Training) registers
158 * (read / write indirect with al_eth_pma_reg_read/write)
160 #define AL_ETH_KR_PMD_CONTROL_RESTART 0
161 #define AL_ETH_KR_PMD_CONTROL_ENABLE 1
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
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
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
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
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
203 enum al_eth_an_lt_regs {
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)
217 if (adapter->rev_id < AL_ETH_REV_ID_3) {
218 al_assert(lane == AL_ETH_AN__LT_LANE_0);
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);
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);
229 struct al_an_lt_wrapper_regs *regs = NULL;
231 reg_addr = al_eth_an_lt_regs_addr[reg_id][AL_ETH_LT_UNIT_REV_2];
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,
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);
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,
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);
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,
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);
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,
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);
275 al_err("%s: Unknown Lane %d\n", __func__, lane);
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);
284 return (uint16_t)val;
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,
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);
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);
306 struct al_an_lt_wrapper_regs *regs = NULL;
308 reg_addr = al_eth_an_lt_regs_addr[reg_id][AL_ETH_LT_UNIT_REV_2];
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,
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,
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,
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,
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,
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,
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,
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,
356 al_err("%s: Unknown Lane %d\n", __func__, lane);
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);
366 static void al_eth_an_lt_unit_config(struct al_hal_eth_adapter *adapter)
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);
374 switch (adapter->mac_mode) {
375 case AL_ETH_MAC_MODE_10GbE_Serial:
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);
386 adapter->curr_lt_unit = AL_ETH_AN_LT_UNIT_20_BIT;
389 case AL_ETH_MAC_MODE_KR_LL_25G:
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);
400 adapter->curr_lt_unit = AL_ETH_AN_LT_UNIT_32_BIT;
403 case AL_ETH_MAC_MODE_XLG_LL_40G:
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);
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);
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);
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);
444 adapter->curr_lt_unit = AL_ETH_AN_LT_UNIT_16_BIT;
447 case AL_ETH_MAC_MODE_XLG_LL_50G:
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);
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);
468 adapter->curr_lt_unit = AL_ETH_AN_LT_UNIT_32_BIT;
472 al_err("%s: Unknown mac_mode\n", __func__);
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,
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,
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,
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,
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)
504 reg = al_eth_an_lt_reg_read(adapter, AL_ETH_KR_PMD_LP_COEF_UP, AL_ETH_LT_REGS, lane);
508 reg, AL_ETH_KR_PMD_LP_COEF_UP_PRESET_SHIFT) != 0);
510 lpcoeff->initialize =
512 reg, AL_ETH_KR_PMD_LP_COEF_UP_INITIALIZE_SHIFT) != 0);
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);
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);
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);
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)
534 reg = al_eth_an_lt_reg_read(adapter, AL_ETH_KR_PMD_LP_STATUS_REPORT, AL_ETH_LT_REGS, lane);
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);
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);
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);
548 status->receiver_ready =
550 reg, AL_ETH_KR_PMD_LP_STATUS_RECEIVER_READY_SHIFT) != 0);
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)
562 AL_REG_BIT_SET(reg, AL_ETH_KR_PMD_LD_COEF_UP_PRESET_SHIFT);
564 if (ldcoeff->initialize)
565 AL_REG_BIT_SET(reg, AL_ETH_KR_PMD_LD_COEF_UP_INITIALIZE_SHIFT);
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,
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,
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,
582 al_eth_an_lt_reg_write(adapter, AL_ETH_KR_PMD_LD_COEF_UP, AL_ETH_LT_REGS, lane, reg);
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)
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,
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,
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,
607 if (status->receiver_ready)
609 AL_ETH_KR_PMD_LD_STATUS_REPORT_RECEIVER_READY_SHIFT);
611 al_eth_an_lt_reg_write(adapter, AL_ETH_KR_PMD_LD_STATUS_REPORT, AL_ETH_LT_REGS, lane, reg);
614 al_bool al_eth_kr_receiver_frame_lock_get(struct al_hal_eth_adapter *adapter,
615 enum al_eth_an_lt_lane lane)
619 reg = al_eth_an_lt_reg_read(adapter, AL_ETH_KR_PMD_STATUS, AL_ETH_LT_REGS, lane);
621 return (AL_REG_BIT_GET(reg,
622 AL_ETH_KR_PMD_STATUS_RECEIVER_FRAME_LOCK_SHIFT) != 0);
625 al_bool al_eth_kr_startup_proto_prog_get(struct al_hal_eth_adapter *adapter,
626 enum al_eth_an_lt_lane lane)
630 reg = al_eth_an_lt_reg_read(adapter, AL_ETH_KR_PMD_STATUS, AL_ETH_LT_REGS, lane);
632 return (AL_REG_BIT_GET(
633 reg, AL_ETH_KR_PMD_STATUS_RECEIVER_START_UP_PROTO_PROG_SHIFT) != 0);
636 al_bool al_eth_kr_training_status_fail_get(struct al_hal_eth_adapter *adapter,
637 enum al_eth_an_lt_lane lane)
641 reg = al_eth_an_lt_reg_read(adapter, AL_ETH_KR_PMD_STATUS, AL_ETH_LT_REGS, lane);
643 return (AL_REG_BIT_GET(reg, AL_ETH_KR_PMD_STATUS_FAILURE_SHIFT) != 0);
646 void al_eth_receiver_ready_set(struct al_hal_eth_adapter *adapter,
647 enum al_eth_an_lt_lane lane)
649 al_eth_an_lt_reg_write(adapter, AL_ETH_KR_PMD_STATUS, AL_ETH_LT_REGS, lane, 1);
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)
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);
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);
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);
679 if (an_adv->acknowledge) {
680 al_err("[%s]: %s failed on acknowledge (%d)\n",
681 adapter->name, __func__, an_adv->acknowledge);
688 static int al_eth_kr_an_write_adv(struct al_hal_eth_adapter *adapter,
689 struct al_eth_an_adv *an_adv)
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);
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);
705 AL_REG_FIELD_SET(reg, AL_ETH_KR_AN_ADV1_CAPABILITY_MASK,
706 AL_ETH_KR_AN_ADV1_CAPABILITY_SHIFT,
709 AL_REG_BIT_VAL_SET(reg, AL_ETH_KR_AN_ADV1_REM_FAULT_SHIFT,
710 an_adv->remote_fault);
712 AL_REG_BIT_VAL_SET(reg, AL_ETH_KR_AN_ADV1_ACK_SHIFT,
713 an_adv->acknowledge);
715 AL_REG_BIT_VAL_SET(reg, AL_ETH_KR_AN_ADV1_NEXT_PAGE_SHIFT,
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);
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);
726 AL_REG_FIELD_SET(reg, AL_ETH_KR_AN_ADV2_TECH_MASK,
727 AL_ETH_KR_AN_ADV2_TECH_SHIFT,
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);
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);
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);
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);
748 void al_eth_kr_an_read_adv(struct al_hal_eth_adapter *adapter,
749 struct al_eth_an_adv *an_adv)
753 al_assert(an_adv != NULL);
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);
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);
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);
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);
771 an_adv->remote_fault = AL_REG_BIT_GET(reg,
772 AL_ETH_KR_AN_ADV1_REM_FAULT_SHIFT);
774 an_adv->acknowledge = AL_REG_BIT_GET(reg,
775 AL_ETH_KR_AN_ADV1_ACK_SHIFT);
777 an_adv->next_page = AL_REG_BIT_GET(reg,
778 AL_ETH_KR_AN_ADV1_NEXT_PAGE_SHIFT);
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);
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);
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);
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);
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);
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);
805 int al_eth_kr_next_page_read(struct al_hal_eth_adapter *adapter,
806 struct al_eth_an_np *np)
810 reg = al_eth_an_lt_reg_read(adapter,
811 AL_ETH_KR_AN_REM_XNP_ADV0,
813 AL_ETH_AN__LT_LANE_0);
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);
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);
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);
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);
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);
830 np->unformatted_code_field1 = al_eth_an_lt_reg_read(adapter,
831 AL_ETH_KR_AN_REM_XNP_ADV1,
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,
837 AL_ETH_AN__LT_LANE_0);
842 int al_eth_kr_next_page_write(struct al_hal_eth_adapter *adapter,
843 struct al_eth_an_np *np)
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,
853 AL_REG_FIELD_SET(reg, AL_ETH_KR_AN_NP_ADV1_ACK2_MASK,
854 AL_ETH_KR_AN_NP_ADV1_ACK2_SHIFT,
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,
859 AL_REG_FIELD_SET(reg, AL_ETH_KR_AN_NP_ADV1_NP_MASK,
860 AL_ETH_KR_AN_NP_ADV1_NP_SHIFT,
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);
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);
874 int al_eth_kr_an_init(struct al_hal_eth_adapter *adapter,
875 struct al_eth_an_adv *an_adv)
879 if (adapter->rev_id > AL_ETH_REV_ID_2)
880 al_eth_an_lt_unit_config(adapter);
882 rc = al_eth_kr_an_validate_adv(adapter, an_adv);
886 rc = al_eth_kr_an_write_adv(adapter, an_adv);
891 al_eth_an_lt_reg_read(adapter, AL_ETH_KR_AN_STATUS, AL_ETH_AN_REGS, AL_ETH_AN__LT_LANE_0);
893 al_dbg("[%s]: autonegotiation initialized successfully", adapter->name);
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,
902 uint16_t control = AL_ETH_KR_AN_CONTROL_ENABLE | AL_ETH_KR_AN_CONTROL_RESTART;
904 al_dbg("Eth [%s]: enable autonegotiation. lt_en %s",
905 adapter->name, (lt_enable == AL_TRUE) ? "yes" : "no");
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));
910 if (next_page_enable == AL_TRUE)
911 control |= AL_ETH_KR_AN_CONTROL_NP_ENABLE;
913 al_eth_an_lt_reg_write(adapter, AL_ETH_KR_AN_CONTROL, AL_ETH_AN_REGS,
916 if (lt_enable == AL_TRUE) {
917 al_eth_kr_lt_initialize(adapter, lane);
923 void al_eth_kr_an_stop(struct al_hal_eth_adapter *adapter)
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);
929 void al_eth_kr_an_status_check(struct al_hal_eth_adapter *adapter,
930 al_bool *page_received,
931 al_bool *an_completed,
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);
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);
947 if (reg & AL_ETH_KR_AN_STATUS_BASE_PAGE_RECEIVED)
948 *page_received = AL_TRUE;
950 *page_received = AL_FALSE;
952 if (reg & AL_ETH_KR_AN_STATUS_COMPLETED)
953 *an_completed = AL_TRUE;
955 *an_completed = AL_FALSE;
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)
963 al_dbg("[%s]: KR LT Restart Link Training.\n", adapter->name);
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)));
970 void al_eth_kr_lt_stop(struct al_hal_eth_adapter *adapter,
971 enum al_eth_an_lt_lane lane)
973 al_dbg("[%s]: KR LT Stop Link Training.\n", adapter->name);
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));
979 void al_eth_kr_lt_initialize(struct al_hal_eth_adapter *adapter,
980 enum al_eth_an_lt_lane lane)
982 al_dbg("[%s]: KR LT Initialize.\n", adapter->name);
984 /* Reset LT state machine */
985 al_eth_kr_lt_stop(adapter, lane);
987 /* clear receiver status */
988 al_eth_an_lt_reg_write(adapter, AL_ETH_KR_PMD_STATUS, AL_ETH_LT_REGS, lane, 0);
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);
996 al_eth_kr_lt_restart(adapter, lane);
999 al_bool al_eth_kr_lt_frame_lock_wait(struct al_hal_eth_adapter *adapter,
1000 enum al_eth_an_lt_lane lane,
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);
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);
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);
1026 al_info("[%s]: Failed on timeout. PMD STATUS 0x%04x\n",
1027 adapter->name, reg);