Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/sys/contrib/alpine-hal/eth/al_hal_eth_kr.c
48255 views
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
1032