xref: /freebsd/sys/contrib/alpine-hal/eth/al_hal_eth_kr.c (revision d9f0ce31900a48d1a2bfc1c8c86f79d1e831451a)
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)&regs->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)&regs->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)&regs->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)&regs->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)&regs->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)&regs->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)&regs->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)&regs->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)&regs->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)&regs->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)&regs->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)&regs->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)&regs->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)&regs->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)&regs->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)&regs->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)&regs->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)&regs->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)&regs->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)&regs->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