Path: blob/main/sys/contrib/alpine-hal/eth/al_hal_eth_kr.c
48255 views
/*-1*******************************************************************************2Copyright (C) 2015 Annapurna Labs Ltd.34This file may be licensed under the terms of the Annapurna Labs Commercial5License Agreement.67Alternatively, this file can be distributed under the terms of the GNU General8Public License V2 as published by the Free Software Foundation and can be9found at http://www.gnu.org/licenses/gpl-2.0.html1011Alternatively, redistribution and use in source and binary forms, with or12without modification, are permitted provided that the following conditions are13met:1415* Redistributions of source code must retain the above copyright notice,16this list of conditions and the following disclaimer.1718* Redistributions in binary form must reproduce the above copyright19notice, this list of conditions and the following disclaimer in20the documentation and/or other materials provided with the21distribution.2223THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND24ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED25WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE26DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR27ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES28(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;29LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON30ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT31(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS32SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.3334*******************************************************************************/35/**36* Ethernet37* @{38* @file al_hal_eth_kr.c39*40* @brief KR HAL driver for main functions (auto-neg, Link Training)41*42*/4344#include "al_hal_eth_kr.h"45#include "al_hal_eth_mac_regs.h"46#include "al_hal_an_lt_wrapper_regs.h"4748enum al_eth_lt_unit_rev {49AL_ETH_LT_UNIT_REV_1 = 0,50AL_ETH_LT_UNIT_REV_2,5152AL_ETH_LT_UNIT_REV_MAX53};5455enum al_eth_an_lt_regs_ids {56AL_ETH_KR_AN_CONTROL = 0,57AL_ETH_KR_AN_STATUS,58AL_ETH_KR_AN_ADV0,59AL_ETH_KR_AN_ADV1,60AL_ETH_KR_AN_ADV2,61AL_ETH_KR_AN_REM_ADV0,62AL_ETH_KR_AN_REM_ADV1,63AL_ETH_KR_AN_REM_ADV2,64AL_ETH_KR_PMD_CONTROL,65AL_ETH_KR_PMD_STATUS,66AL_ETH_KR_PMD_LP_COEF_UP,67AL_ETH_KR_PMD_LP_STATUS_REPORT,68AL_ETH_KR_PMD_LD_COEF_UP,69AL_ETH_KR_PMD_LD_STATUS_REPORT,70AL_ETH_KR_AN_XNP_ADV0,71AL_ETH_KR_AN_XNP_ADV1,72AL_ETH_KR_AN_XNP_ADV2,73AL_ETH_KR_AN_REM_XNP_ADV0,74AL_ETH_KR_AN_REM_XNP_ADV1,75AL_ETH_KR_AN_REM_XNP_ADV2,76};7778static uint32_t al_eth_an_lt_regs_addr[][AL_ETH_LT_UNIT_REV_MAX] = {79[AL_ETH_KR_AN_CONTROL] = {0 , 0x0},80[AL_ETH_KR_AN_STATUS] = {1 , 0x4},81[AL_ETH_KR_AN_ADV0] = {16 , 0x8},82[AL_ETH_KR_AN_ADV1] = {17 , 0xc},83[AL_ETH_KR_AN_ADV2] = {18 , 0x10},84[AL_ETH_KR_AN_REM_ADV0] = {19 , 0x14},85[AL_ETH_KR_AN_REM_ADV1] = {20 , 0x18},86[AL_ETH_KR_AN_REM_ADV2] = {21 , 0x1c},87[AL_ETH_KR_PMD_CONTROL] = {150, 0x400},88[AL_ETH_KR_PMD_STATUS] = {151, 0x404},89[AL_ETH_KR_PMD_LP_COEF_UP] = {152, 0x408},90[AL_ETH_KR_PMD_LP_STATUS_REPORT] = {153, 0x40c},91[AL_ETH_KR_PMD_LD_COEF_UP] = {154, 0x410},92[AL_ETH_KR_PMD_LD_STATUS_REPORT] = {155, 0x414},93[AL_ETH_KR_AN_XNP_ADV0] = {22 , 0x24},94[AL_ETH_KR_AN_XNP_ADV1] = {23 , 0x28},95[AL_ETH_KR_AN_XNP_ADV2] = {24 , 0x2c},96[AL_ETH_KR_AN_REM_XNP_ADV0] = {25 , 0x30},97[AL_ETH_KR_AN_REM_XNP_ADV1] = {26 , 0x34},98[AL_ETH_KR_AN_REM_XNP_ADV2] = {27 , 0x38},99};100101102/*103* AN(Auto Negotiation) registers104* (read / write indirect with al_eth_an_reg_read/write)105*/106#define AL_ETH_KR_AN_CONTROL_RESTART AL_BIT(9)107#define AL_ETH_KR_AN_CONTROL_ENABLE AL_BIT(12)108#define AL_ETH_KR_AN_CONTROL_NP_ENABLE AL_BIT(13)109110#define AL_ETH_KR_AN_STATUS_COMPLETED AL_BIT(5)111#define AL_ETH_KR_AN_STATUS_BASE_PAGE_RECEIVED AL_BIT(6)112#define AL_ETH_KR_AN_STATUS_CHECK_MASK 0xFF0A113#define AL_ETH_KR_AN_STATUS_CHECK_NO_ERROR 0x0008114115/* AN advertising registers parsing */116/* register 1 */117#define AL_ETH_KR_AN_ADV1_SEL_FIELD_MASK 0x001f118#define AL_ETH_KR_AN_ADV1_SEL_FIELD_SHIFT 0119#define AL_ETH_KR_AN_ADV1_ECHOED_NONCE_MASK 0x03e0120#define AL_ETH_KR_AN_ADV1_ECHOED_NONCE_SHIFT 5121#define AL_ETH_KR_AN_ADV1_CAPABILITY_MASK 0x1c00122#define AL_ETH_KR_AN_ADV1_CAPABILITY_SHIFT 10123#define AL_ETH_KR_AN_ADV1_REM_FAULT_MASK 0x2000124#define AL_ETH_KR_AN_ADV1_REM_FAULT_SHIFT 13125#define AL_ETH_KR_AN_ADV1_ACK_MASK 0x4000126#define AL_ETH_KR_AN_ADV1_ACK_SHIFT 14127#define AL_ETH_KR_AN_ADV1_NEXT_PAGE_MASK 0x8000128#define AL_ETH_KR_AN_ADV1_NEXT_PAGE_SHIFT 15129/* register 2 */130#define AL_ETH_KR_AN_ADV2_TX_NONCE_MASK 0x001f131#define AL_ETH_KR_AN_ADV2_TX_NONCE_SHIFT 0132#define AL_ETH_KR_AN_ADV2_TECH_MASK 0xffe0133#define AL_ETH_KR_AN_ADV2_TECH_SHIFT 5134/* register 3 */135/* TECH field in the third register is extended to the field in the second136* register and it is currently reserved (should be always 0) */137#define AL_ETH_KR_AN_ADV3_TECH_MASK 0x1fff138#define AL_ETH_KR_AN_ADV3_TECH_SHIFT 0139#define AL_ETH_KR_AN_ADV3_FEC_MASK 0xc000140#define AL_ETH_KR_AN_ADV3_FEC_SHIFT 14141142/* Next Page Fields */143/* register 1 */144#define AL_ETH_KR_AN_NP_ADV1_DATA1_MASK 0x07ff145#define AL_ETH_KR_AN_NP_ADV1_DATA1_SHIFT 0146#define AL_ETH_KR_AN_NP_ADV1_TOGGLE_MASK 0x0800147#define AL_ETH_KR_AN_NP_ADV1_TOGGLE_SHIFT 11148#define AL_ETH_KR_AN_NP_ADV1_ACK2_MASK 0x1000149#define AL_ETH_KR_AN_NP_ADV1_ACK2_SHIFT 12150#define AL_ETH_KR_AN_NP_ADV1_MSG_PAGE_MASK 0x2000151#define AL_ETH_KR_AN_NP_ADV1_MSG_PAGE_SHIFT 13152#define AL_ETH_KR_AN_NP_ADV1_NP_MASK 0x8000153#define AL_ETH_KR_AN_NP_ADV1_NP_SHIFT 15154155/*156* LT(Link Training) registers157* (read / write indirect with al_eth_pma_reg_read/write)158*/159#define AL_ETH_KR_PMD_CONTROL_RESTART 0160#define AL_ETH_KR_PMD_CONTROL_ENABLE 1161162#define AL_ETH_KR_PMD_STATUS_RECEIVER_COMPLETED_SHIFT 0163#define AL_ETH_KR_PMD_STATUS_RECEIVER_FRAME_LOCK_SHIFT 1164#define AL_ETH_KR_PMD_STATUS_RECEIVER_START_UP_PROTO_PROG_SHIFT 2165#define AL_ETH_KR_PMD_STATUS_FAILURE_SHIFT 3166167#define AL_ETH_KR_PMD_LP_COEF_UP_MINUS_MASK 0x0003168#define AL_ETH_KR_PMD_LP_COEF_UP_MINUS_SHIFT 0169#define AL_ETH_KR_PMD_LP_COEF_UP_ZERO_MASK 0x000C170#define AL_ETH_KR_PMD_LP_COEF_UP_ZERO_SHIFT 2171#define AL_ETH_KR_PMD_LP_COEF_UP_PLUS_MASK 0x0030172#define AL_ETH_KR_PMD_LP_COEF_UP_PLUS_SHIFT 4173#define AL_ETH_KR_PMD_LP_COEF_UP_INITIALIZE_SHIFT 12174#define AL_ETH_KR_PMD_LP_COEF_UP_PRESET_SHIFT 13175176#define AL_ETH_KR_PMD_LP_STATUS_REPORT_MINUS_MASK 0x0003177#define AL_ETH_KR_PMD_LP_STATUS_REPORT_MINUS_SHIFT 0178#define AL_ETH_KR_PMD_LP_STATUS_REPORT_ZERO_MASK 0x000C179#define AL_ETH_KR_PMD_LP_STATUS_REPORT_ZERO_SHIFT 2180#define AL_ETH_KR_PMD_LP_STATUS_REPORT_PLUS_MASK 0x0030181#define AL_ETH_KR_PMD_LP_STATUS_REPORT_PLUS_SHIFT 4182#define AL_ETH_KR_PMD_LP_STATUS_RECEIVER_READY_SHIFT 15183184#define AL_ETH_KR_PMD_LD_COEF_UP_MINUS_MASK 0x0003185#define AL_ETH_KR_PMD_LD_COEF_UP_MINUS_SHIFT 0186#define AL_ETH_KR_PMD_LD_COEF_UP_ZERO_MASK 0x000C187#define AL_ETH_KR_PMD_LD_COEF_UP_ZERO_SHIFT 2188#define AL_ETH_KR_PMD_LD_COEF_UP_PLUS_MASK 0x0030189#define AL_ETH_KR_PMD_LD_COEF_UP_PLUS_SHIFT 4190#define AL_ETH_KR_PMD_LD_COEF_UP_INITIALIZE_SHIFT 12191#define AL_ETH_KR_PMD_LD_COEF_UP_PRESET_SHIFT 13192193#define AL_ETH_KR_PMD_LD_STATUS_REPORT_MINUS_MASK 0x0003194#define AL_ETH_KR_PMD_LD_STATUS_REPORT_MINUS_SHIFT 0195#define AL_ETH_KR_PMD_LD_STATUS_REPORT_ZERO_MASK 0x000C196#define AL_ETH_KR_PMD_LD_STATUS_REPORT_ZERO_SHIFT 2197#define AL_ETH_KR_PMD_LD_STATUS_REPORT_PLUS_MASK 0x0030198#define AL_ETH_KR_PMD_LD_STATUS_REPORT_PLUS_SHIFT 4199#define AL_ETH_KR_PMD_LD_STATUS_REPORT_RECEIVER_READY_SHIFT 15200201202enum al_eth_an_lt_regs {203AL_ETH_AN_REGS,204AL_ETH_LT_REGS,205};206207static uint16_t al_eth_an_lt_reg_read(208struct al_hal_eth_adapter *adapter,209enum al_eth_an_lt_regs_ids reg_id,210enum al_eth_an_lt_regs an_lt,211enum al_eth_an_lt_lane lane)212{213uint32_t val;214uint16_t reg_addr;215216if (adapter->rev_id < AL_ETH_REV_ID_3) {217al_assert(lane == AL_ETH_AN__LT_LANE_0);218219reg_addr = al_eth_an_lt_regs_addr[reg_id][AL_ETH_LT_UNIT_REV_1];220if (an_lt == AL_ETH_AN_REGS) {221al_reg_write32(&adapter->mac_regs_base->kr.an_addr, reg_addr);222val = al_reg_read32(&adapter->mac_regs_base->kr.an_data);223} else {224al_reg_write32(&adapter->mac_regs_base->kr.pma_addr, reg_addr);225val = al_reg_read32(&adapter->mac_regs_base->kr.pma_data);226}227} else {228struct al_an_lt_wrapper_regs *regs = NULL;229230reg_addr = al_eth_an_lt_regs_addr[reg_id][AL_ETH_LT_UNIT_REV_2];231232switch (lane) {233case AL_ETH_AN__LT_LANE_0:234al_reg_write32(&adapter->mac_regs_base->gen_v3.an_lt_0_addr,235(uintptr_t)®s->an_lt[adapter->curr_lt_unit].addr);236al_reg_write32(&adapter->mac_regs_base->gen_v3.an_lt_0_data,237reg_addr);238239al_reg_write32(&adapter->mac_regs_base->gen_v3.an_lt_0_addr,240(uintptr_t)®s->an_lt[adapter->curr_lt_unit].data);241val = al_reg_read32(&adapter->mac_regs_base->gen_v3.an_lt_0_data);242break;243case AL_ETH_AN__LT_LANE_1:244al_reg_write32(&adapter->mac_regs_base->gen_v3.an_lt_1_addr,245(uintptr_t)®s->an_lt[adapter->curr_lt_unit].addr);246al_reg_write32(&adapter->mac_regs_base->gen_v3.an_lt_1_data,247reg_addr);248249al_reg_write32(&adapter->mac_regs_base->gen_v3.an_lt_1_addr,250(uintptr_t)®s->an_lt[adapter->curr_lt_unit].data);251val = al_reg_read32(&adapter->mac_regs_base->gen_v3.an_lt_1_data);252break;253case AL_ETH_AN__LT_LANE_2:254al_reg_write32(&adapter->mac_regs_base->gen_v3.an_lt_2_addr,255(uintptr_t)®s->an_lt[adapter->curr_lt_unit].addr);256al_reg_write32(&adapter->mac_regs_base->gen_v3.an_lt_2_data,257reg_addr);258259al_reg_write32(&adapter->mac_regs_base->gen_v3.an_lt_2_addr,260(uintptr_t)®s->an_lt[adapter->curr_lt_unit].data);261val = al_reg_read32(&adapter->mac_regs_base->gen_v3.an_lt_2_data);262break;263case AL_ETH_AN__LT_LANE_3:264al_reg_write32(&adapter->mac_regs_base->gen_v3.an_lt_3_addr,265(uintptr_t)®s->an_lt[adapter->curr_lt_unit].addr);266al_reg_write32(&adapter->mac_regs_base->gen_v3.an_lt_3_data,267reg_addr);268269al_reg_write32(&adapter->mac_regs_base->gen_v3.an_lt_3_addr,270(uintptr_t)®s->an_lt[adapter->curr_lt_unit].data);271val = al_reg_read32(&adapter->mac_regs_base->gen_v3.an_lt_3_data);272break;273default:274al_err("%s: Unknown Lane %d\n", __func__, lane);275return 0;276}277}278279280al_dbg("[%s]: %s - (%s) lane %d, reg %d, val 0x%x", adapter->name, __func__,281(an_lt == AL_ETH_AN_REGS) ? "AN" : "LT", lane, reg_addr, val);282283return (uint16_t)val;284}285286static void al_eth_an_lt_reg_write(287struct al_hal_eth_adapter *adapter,288enum al_eth_an_lt_regs_ids reg_id,289enum al_eth_an_lt_regs an_lt,290enum al_eth_an_lt_lane lane,291uint16_t val)292{293uint16_t reg_addr;294295if (adapter->rev_id < AL_ETH_REV_ID_3) {296reg_addr = al_eth_an_lt_regs_addr[reg_id][AL_ETH_LT_UNIT_REV_1];297if (an_lt == AL_ETH_AN_REGS) {298al_reg_write32(&adapter->mac_regs_base->kr.an_addr, reg_addr);299al_reg_write32(&adapter->mac_regs_base->kr.an_data, val);300} else {301al_reg_write32(&adapter->mac_regs_base->kr.pma_addr, reg_addr);302al_reg_write32(&adapter->mac_regs_base->kr.pma_data, val);303}304} else {305struct al_an_lt_wrapper_regs *regs = NULL;306307reg_addr = al_eth_an_lt_regs_addr[reg_id][AL_ETH_LT_UNIT_REV_2];308309switch (lane) {310case AL_ETH_AN__LT_LANE_0:311al_reg_write32(&adapter->mac_regs_base->gen_v3.an_lt_0_addr,312(uintptr_t)®s->an_lt[adapter->curr_lt_unit].addr);313al_reg_write32(&adapter->mac_regs_base->gen_v3.an_lt_0_data,314reg_addr);315316al_reg_write32(&adapter->mac_regs_base->gen_v3.an_lt_0_addr,317(uintptr_t)®s->an_lt[adapter->curr_lt_unit].data);318al_reg_write32(&adapter->mac_regs_base->gen_v3.an_lt_0_data,319val);320break;321case AL_ETH_AN__LT_LANE_1:322al_reg_write32(&adapter->mac_regs_base->gen_v3.an_lt_1_addr,323(uintptr_t)®s->an_lt[adapter->curr_lt_unit].addr);324al_reg_write32(&adapter->mac_regs_base->gen_v3.an_lt_1_data,325reg_addr);326327al_reg_write32(&adapter->mac_regs_base->gen_v3.an_lt_1_addr,328(uintptr_t)®s->an_lt[adapter->curr_lt_unit].data);329al_reg_write32(&adapter->mac_regs_base->gen_v3.an_lt_1_data,330val);331break;332case AL_ETH_AN__LT_LANE_2:333al_reg_write32(&adapter->mac_regs_base->gen_v3.an_lt_2_addr,334(uintptr_t)®s->an_lt[adapter->curr_lt_unit].addr);335al_reg_write32(&adapter->mac_regs_base->gen_v3.an_lt_2_data,336reg_addr);337338al_reg_write32(&adapter->mac_regs_base->gen_v3.an_lt_2_addr,339(uintptr_t)®s->an_lt[adapter->curr_lt_unit].data);340al_reg_write32(&adapter->mac_regs_base->gen_v3.an_lt_2_data,341val);342break;343case AL_ETH_AN__LT_LANE_3:344al_reg_write32(&adapter->mac_regs_base->gen_v3.an_lt_3_addr,345(uintptr_t)®s->an_lt[adapter->curr_lt_unit].addr);346al_reg_write32(&adapter->mac_regs_base->gen_v3.an_lt_3_data,347reg_addr);348349al_reg_write32(&adapter->mac_regs_base->gen_v3.an_lt_3_addr,350(uintptr_t)®s->an_lt[adapter->curr_lt_unit].data);351al_reg_write32(&adapter->mac_regs_base->gen_v3.an_lt_3_data,352val);353break;354default:355al_err("%s: Unknown Lane %d\n", __func__, lane);356return;357}358}359360361al_dbg("[%s]: %s - (%s) lane %d, reg %d, val 0x%x", adapter->name, __func__,362(an_lt == AL_ETH_AN_REGS) ? "AN" : "LT", lane, reg_addr, val);363}364365static void al_eth_an_lt_unit_config(struct al_hal_eth_adapter *adapter)366{367struct al_an_lt_wrapper_regs *regs = NULL;368uint32_t cfg_lane_0 = (AN_LT_WRAPPER_GEN_CFG_BYPASS_RX | AN_LT_WRAPPER_GEN_CFG_BYPASS_TX);369uint32_t cfg_lane_1 = (AN_LT_WRAPPER_GEN_CFG_BYPASS_RX | AN_LT_WRAPPER_GEN_CFG_BYPASS_TX);370uint32_t cfg_lane_2 = (AN_LT_WRAPPER_GEN_CFG_BYPASS_RX | AN_LT_WRAPPER_GEN_CFG_BYPASS_TX);371uint32_t cfg_lane_3 = (AN_LT_WRAPPER_GEN_CFG_BYPASS_RX | AN_LT_WRAPPER_GEN_CFG_BYPASS_TX);372373switch (adapter->mac_mode) {374case AL_ETH_MAC_MODE_10GbE_Serial:375cfg_lane_0 = 0;376AL_REG_FIELD_SET(cfg_lane_0,377AN_LT_WRAPPER_GEN_CFG_AN_LT_SEL_RX_MASK,378AN_LT_WRAPPER_GEN_CFG_AN_LT_SEL_RX_SHIFT,379AL_ETH_AN_LT_UNIT_20_BIT);380AL_REG_FIELD_SET(cfg_lane_0,381AN_LT_WRAPPER_GEN_CFG_AN_LT_SEL_TX_MASK,382AN_LT_WRAPPER_GEN_CFG_AN_LT_SEL_TX_SHIFT,383AL_ETH_AN_LT_UNIT_20_BIT);384385adapter->curr_lt_unit = AL_ETH_AN_LT_UNIT_20_BIT;386387break;388case AL_ETH_MAC_MODE_KR_LL_25G:389cfg_lane_0 = 0;390AL_REG_FIELD_SET(cfg_lane_0,391AN_LT_WRAPPER_GEN_CFG_AN_LT_SEL_RX_MASK,392AN_LT_WRAPPER_GEN_CFG_AN_LT_SEL_RX_SHIFT,393AL_ETH_AN_LT_UNIT_32_BIT);394AL_REG_FIELD_SET(cfg_lane_0,395AN_LT_WRAPPER_GEN_CFG_AN_LT_SEL_TX_MASK,396AN_LT_WRAPPER_GEN_CFG_AN_LT_SEL_TX_SHIFT,397AL_ETH_AN_LT_UNIT_32_BIT);398399adapter->curr_lt_unit = AL_ETH_AN_LT_UNIT_32_BIT;400401break;402case AL_ETH_MAC_MODE_XLG_LL_40G:403cfg_lane_0 = 0;404AL_REG_FIELD_SET(cfg_lane_0,405AN_LT_WRAPPER_GEN_CFG_AN_LT_SEL_RX_MASK,406AN_LT_WRAPPER_GEN_CFG_AN_LT_SEL_RX_SHIFT,407AL_ETH_AN_LT_UNIT_16_BIT);408AL_REG_FIELD_SET(cfg_lane_0,409AN_LT_WRAPPER_GEN_CFG_AN_LT_SEL_TX_MASK,410AN_LT_WRAPPER_GEN_CFG_AN_LT_SEL_TX_SHIFT,411AL_ETH_AN_LT_UNIT_16_BIT);412413cfg_lane_1 = 0;414AL_REG_FIELD_SET(cfg_lane_1,415AN_LT_WRAPPER_GEN_CFG_AN_LT_SEL_RX_MASK,416AN_LT_WRAPPER_GEN_CFG_AN_LT_SEL_RX_SHIFT,417AL_ETH_AN_LT_UNIT_16_BIT);418AL_REG_FIELD_SET(cfg_lane_1,419AN_LT_WRAPPER_GEN_CFG_AN_LT_SEL_TX_MASK,420AN_LT_WRAPPER_GEN_CFG_AN_LT_SEL_TX_SHIFT,421AL_ETH_AN_LT_UNIT_16_BIT);422423cfg_lane_2 = 0;424AL_REG_FIELD_SET(cfg_lane_2,425AN_LT_WRAPPER_GEN_CFG_AN_LT_SEL_RX_MASK,426AN_LT_WRAPPER_GEN_CFG_AN_LT_SEL_RX_SHIFT,427AL_ETH_AN_LT_UNIT_16_BIT);428AL_REG_FIELD_SET(cfg_lane_2,429AN_LT_WRAPPER_GEN_CFG_AN_LT_SEL_TX_MASK,430AN_LT_WRAPPER_GEN_CFG_AN_LT_SEL_TX_SHIFT,431AL_ETH_AN_LT_UNIT_16_BIT);432433cfg_lane_3 = 0;434AL_REG_FIELD_SET(cfg_lane_3,435AN_LT_WRAPPER_GEN_CFG_AN_LT_SEL_RX_MASK,436AN_LT_WRAPPER_GEN_CFG_AN_LT_SEL_RX_SHIFT,437AL_ETH_AN_LT_UNIT_16_BIT);438AL_REG_FIELD_SET(cfg_lane_3,439AN_LT_WRAPPER_GEN_CFG_AN_LT_SEL_TX_MASK,440AN_LT_WRAPPER_GEN_CFG_AN_LT_SEL_TX_SHIFT,441AL_ETH_AN_LT_UNIT_16_BIT);442443adapter->curr_lt_unit = AL_ETH_AN_LT_UNIT_16_BIT;444445break;446case AL_ETH_MAC_MODE_XLG_LL_50G:447cfg_lane_0 = 0;448AL_REG_FIELD_SET(cfg_lane_0,449AN_LT_WRAPPER_GEN_CFG_AN_LT_SEL_RX_MASK,450AN_LT_WRAPPER_GEN_CFG_AN_LT_SEL_RX_SHIFT,451AL_ETH_AN_LT_UNIT_32_BIT);452AL_REG_FIELD_SET(cfg_lane_0,453AN_LT_WRAPPER_GEN_CFG_AN_LT_SEL_TX_MASK,454AN_LT_WRAPPER_GEN_CFG_AN_LT_SEL_TX_SHIFT,455AL_ETH_AN_LT_UNIT_32_BIT);456457cfg_lane_1 = 0;458AL_REG_FIELD_SET(cfg_lane_1,459AN_LT_WRAPPER_GEN_CFG_AN_LT_SEL_RX_MASK,460AN_LT_WRAPPER_GEN_CFG_AN_LT_SEL_RX_SHIFT,461AL_ETH_AN_LT_UNIT_32_BIT);462AL_REG_FIELD_SET(cfg_lane_1,463AN_LT_WRAPPER_GEN_CFG_AN_LT_SEL_TX_MASK,464AN_LT_WRAPPER_GEN_CFG_AN_LT_SEL_TX_SHIFT,465AL_ETH_AN_LT_UNIT_32_BIT);466467adapter->curr_lt_unit = AL_ETH_AN_LT_UNIT_32_BIT;468469break;470default:471al_err("%s: Unknown mac_mode\n", __func__);472return;473}474475al_reg_write32(&adapter->mac_regs_base->gen_v3.an_lt_0_addr,476(uintptr_t)®s->gen.cfg);477al_reg_write32(&adapter->mac_regs_base->gen_v3.an_lt_0_data,478cfg_lane_0);479480al_reg_write32(&adapter->mac_regs_base->gen_v3.an_lt_1_addr,481(uintptr_t)®s->gen.cfg);482al_reg_write32(&adapter->mac_regs_base->gen_v3.an_lt_1_data,483cfg_lane_1);484485al_reg_write32(&adapter->mac_regs_base->gen_v3.an_lt_2_addr,486(uintptr_t)®s->gen.cfg);487al_reg_write32(&adapter->mac_regs_base->gen_v3.an_lt_2_data,488cfg_lane_2);489490al_reg_write32(&adapter->mac_regs_base->gen_v3.an_lt_3_addr,491(uintptr_t)®s->gen.cfg);492al_reg_write32(&adapter->mac_regs_base->gen_v3.an_lt_3_data,493cfg_lane_3);494}495496void al_eth_lp_coeff_up_get(497struct al_hal_eth_adapter *adapter,498enum al_eth_an_lt_lane lane,499struct al_eth_kr_coef_up_data *lpcoeff)500{501uint16_t reg;502503reg = al_eth_an_lt_reg_read(adapter, AL_ETH_KR_PMD_LP_COEF_UP, AL_ETH_LT_REGS, lane);504505lpcoeff->preset =506(AL_REG_BIT_GET(507reg, AL_ETH_KR_PMD_LP_COEF_UP_PRESET_SHIFT) != 0);508509lpcoeff->initialize =510(AL_REG_BIT_GET(511reg, AL_ETH_KR_PMD_LP_COEF_UP_INITIALIZE_SHIFT) != 0);512513lpcoeff->c_minus = AL_REG_FIELD_GET(reg,514AL_ETH_KR_PMD_LP_COEF_UP_MINUS_MASK,515AL_ETH_KR_PMD_LP_COEF_UP_MINUS_SHIFT);516517lpcoeff->c_zero = AL_REG_FIELD_GET(reg,518AL_ETH_KR_PMD_LP_COEF_UP_ZERO_MASK,519AL_ETH_KR_PMD_LP_COEF_UP_ZERO_SHIFT);520521lpcoeff->c_plus = AL_REG_FIELD_GET(reg,522AL_ETH_KR_PMD_LP_COEF_UP_PLUS_MASK,523AL_ETH_KR_PMD_LP_COEF_UP_PLUS_SHIFT);524}525526void al_eth_lp_status_report_get(527struct al_hal_eth_adapter *adapter,528enum al_eth_an_lt_lane lane,529struct al_eth_kr_status_report_data *status)530{531uint16_t reg;532533reg = al_eth_an_lt_reg_read(adapter, AL_ETH_KR_PMD_LP_STATUS_REPORT, AL_ETH_LT_REGS, lane);534535status->c_minus = AL_REG_FIELD_GET(reg,536AL_ETH_KR_PMD_LP_STATUS_REPORT_MINUS_MASK,537AL_ETH_KR_PMD_LP_STATUS_REPORT_MINUS_SHIFT);538539status->c_zero = AL_REG_FIELD_GET(reg,540AL_ETH_KR_PMD_LP_STATUS_REPORT_ZERO_MASK,541AL_ETH_KR_PMD_LP_STATUS_REPORT_ZERO_SHIFT);542543status->c_plus = AL_REG_FIELD_GET(reg,544AL_ETH_KR_PMD_LP_STATUS_REPORT_PLUS_MASK,545AL_ETH_KR_PMD_LP_STATUS_REPORT_PLUS_SHIFT);546547status->receiver_ready =548(AL_REG_BIT_GET(549reg, AL_ETH_KR_PMD_LP_STATUS_RECEIVER_READY_SHIFT) != 0);550551}552553void al_eth_ld_coeff_up_set(554struct al_hal_eth_adapter *adapter,555enum al_eth_an_lt_lane lane,556struct al_eth_kr_coef_up_data *ldcoeff)557{558uint16_t reg = 0;559560if (ldcoeff->preset)561AL_REG_BIT_SET(reg, AL_ETH_KR_PMD_LD_COEF_UP_PRESET_SHIFT);562563if (ldcoeff->initialize)564AL_REG_BIT_SET(reg, AL_ETH_KR_PMD_LD_COEF_UP_INITIALIZE_SHIFT);565566AL_REG_FIELD_SET(reg,567AL_ETH_KR_PMD_LD_COEF_UP_MINUS_MASK,568AL_ETH_KR_PMD_LD_COEF_UP_MINUS_SHIFT,569ldcoeff->c_minus);570571AL_REG_FIELD_SET(reg,572AL_ETH_KR_PMD_LD_COEF_UP_ZERO_MASK,573AL_ETH_KR_PMD_LD_COEF_UP_ZERO_SHIFT,574ldcoeff->c_zero);575576AL_REG_FIELD_SET(reg,577AL_ETH_KR_PMD_LD_COEF_UP_PLUS_MASK,578AL_ETH_KR_PMD_LD_COEF_UP_PLUS_SHIFT,579ldcoeff->c_plus);580581al_eth_an_lt_reg_write(adapter, AL_ETH_KR_PMD_LD_COEF_UP, AL_ETH_LT_REGS, lane, reg);582}583584void al_eth_ld_status_report_set(585struct al_hal_eth_adapter *adapter,586enum al_eth_an_lt_lane lane,587struct al_eth_kr_status_report_data *status)588{589uint16_t reg = 0;590591AL_REG_FIELD_SET(reg,592AL_ETH_KR_PMD_LD_STATUS_REPORT_MINUS_MASK,593AL_ETH_KR_PMD_LD_STATUS_REPORT_MINUS_SHIFT,594status->c_minus);595596AL_REG_FIELD_SET(reg,597AL_ETH_KR_PMD_LD_STATUS_REPORT_ZERO_MASK,598AL_ETH_KR_PMD_LD_STATUS_REPORT_ZERO_SHIFT,599status->c_zero);600601AL_REG_FIELD_SET(reg,602AL_ETH_KR_PMD_LD_STATUS_REPORT_PLUS_MASK,603AL_ETH_KR_PMD_LD_STATUS_REPORT_PLUS_SHIFT,604status->c_plus);605606if (status->receiver_ready)607AL_REG_BIT_SET(reg,608AL_ETH_KR_PMD_LD_STATUS_REPORT_RECEIVER_READY_SHIFT);609610al_eth_an_lt_reg_write(adapter, AL_ETH_KR_PMD_LD_STATUS_REPORT, AL_ETH_LT_REGS, lane, reg);611}612613al_bool al_eth_kr_receiver_frame_lock_get(struct al_hal_eth_adapter *adapter,614enum al_eth_an_lt_lane lane)615{616uint16_t reg;617618reg = al_eth_an_lt_reg_read(adapter, AL_ETH_KR_PMD_STATUS, AL_ETH_LT_REGS, lane);619620return (AL_REG_BIT_GET(reg,621AL_ETH_KR_PMD_STATUS_RECEIVER_FRAME_LOCK_SHIFT) != 0);622}623624al_bool al_eth_kr_startup_proto_prog_get(struct al_hal_eth_adapter *adapter,625enum al_eth_an_lt_lane lane)626{627uint16_t reg;628629reg = al_eth_an_lt_reg_read(adapter, AL_ETH_KR_PMD_STATUS, AL_ETH_LT_REGS, lane);630631return (AL_REG_BIT_GET(632reg, AL_ETH_KR_PMD_STATUS_RECEIVER_START_UP_PROTO_PROG_SHIFT) != 0);633}634635al_bool al_eth_kr_training_status_fail_get(struct al_hal_eth_adapter *adapter,636enum al_eth_an_lt_lane lane)637{638uint16_t reg;639640reg = al_eth_an_lt_reg_read(adapter, AL_ETH_KR_PMD_STATUS, AL_ETH_LT_REGS, lane);641642return (AL_REG_BIT_GET(reg, AL_ETH_KR_PMD_STATUS_FAILURE_SHIFT) != 0);643}644645void al_eth_receiver_ready_set(struct al_hal_eth_adapter *adapter,646enum al_eth_an_lt_lane lane)647{648al_eth_an_lt_reg_write(adapter, AL_ETH_KR_PMD_STATUS, AL_ETH_LT_REGS, lane, 1);649}650651/*************************** auto negotiation *********************************/652static int al_eth_kr_an_validate_adv(struct al_hal_eth_adapter *adapter,653struct al_eth_an_adv *an_adv)654{655al_assert(adapter);656657if (an_adv == NULL)658return 0;659660if (an_adv->selector_field != 1) {661al_err("[%s]: %s failed on selector_field (%d)\n",662adapter->name, __func__, an_adv->selector_field);663return -EINVAL;664}665666if (an_adv->capability & AL_BIT(2)) {667al_err("[%s]: %s failed on capability bit 2 (%d)\n",668adapter->name, __func__, an_adv->capability);669return -EINVAL;670}671672if (an_adv->remote_fault) {673al_err("[%s]: %s failed on remote_fault (%d)\n",674adapter->name, __func__, an_adv->remote_fault);675return -EINVAL;676}677678if (an_adv->acknowledge) {679al_err("[%s]: %s failed on acknowledge (%d)\n",680adapter->name, __func__, an_adv->acknowledge);681return -EINVAL;682}683684return 0;685}686687static int al_eth_kr_an_write_adv(struct al_hal_eth_adapter *adapter,688struct al_eth_an_adv *an_adv)689{690uint16_t reg;691692if(an_adv == NULL)693return 0;694695reg = 0;696AL_REG_FIELD_SET(reg, AL_ETH_KR_AN_ADV1_SEL_FIELD_MASK,697AL_ETH_KR_AN_ADV1_SEL_FIELD_SHIFT,698an_adv->selector_field);699700AL_REG_FIELD_SET(reg, AL_ETH_KR_AN_ADV1_ECHOED_NONCE_MASK,701AL_ETH_KR_AN_ADV1_ECHOED_NONCE_SHIFT,702an_adv->echoed_nonce);703704AL_REG_FIELD_SET(reg, AL_ETH_KR_AN_ADV1_CAPABILITY_MASK,705AL_ETH_KR_AN_ADV1_CAPABILITY_SHIFT,706an_adv->capability);707708AL_REG_BIT_VAL_SET(reg, AL_ETH_KR_AN_ADV1_REM_FAULT_SHIFT,709an_adv->remote_fault);710711AL_REG_BIT_VAL_SET(reg, AL_ETH_KR_AN_ADV1_ACK_SHIFT,712an_adv->acknowledge);713714AL_REG_BIT_VAL_SET(reg, AL_ETH_KR_AN_ADV1_NEXT_PAGE_SHIFT,715an_adv->next_page);716717al_eth_an_lt_reg_write(adapter, AL_ETH_KR_AN_ADV0, AL_ETH_AN_REGS,718AL_ETH_AN__LT_LANE_0, reg);719720reg = 0;721AL_REG_FIELD_SET(reg, AL_ETH_KR_AN_ADV2_TX_NONCE_MASK,722AL_ETH_KR_AN_ADV2_TX_NONCE_SHIFT,723an_adv->transmitted_nonce);724725AL_REG_FIELD_SET(reg, AL_ETH_KR_AN_ADV2_TECH_MASK,726AL_ETH_KR_AN_ADV2_TECH_SHIFT,727an_adv->technology);728729al_eth_an_lt_reg_write(adapter, AL_ETH_KR_AN_ADV1, AL_ETH_AN_REGS,730AL_ETH_AN__LT_LANE_0, reg);731732reg = 0;733AL_REG_FIELD_SET(reg, AL_ETH_KR_AN_ADV3_TECH_MASK,734AL_ETH_KR_AN_ADV3_TECH_SHIFT,735an_adv->technology >> 11);736737AL_REG_FIELD_SET(reg, AL_ETH_KR_AN_ADV3_FEC_MASK,738AL_ETH_KR_AN_ADV3_FEC_SHIFT,739an_adv->fec_capability);740741al_eth_an_lt_reg_write(adapter, AL_ETH_KR_AN_ADV2, AL_ETH_AN_REGS,742AL_ETH_AN__LT_LANE_0, reg);743744return 0;745}746747void al_eth_kr_an_read_adv(struct al_hal_eth_adapter *adapter,748struct al_eth_an_adv *an_adv)749{750int16_t reg;751752al_assert(an_adv != NULL);753754755reg = al_eth_an_lt_reg_read(adapter, AL_ETH_KR_AN_REM_ADV0,756AL_ETH_AN_REGS, AL_ETH_AN__LT_LANE_0);757758an_adv->selector_field = AL_REG_FIELD_GET(reg,759AL_ETH_KR_AN_ADV1_SEL_FIELD_MASK,760AL_ETH_KR_AN_ADV1_SEL_FIELD_SHIFT);761762an_adv->echoed_nonce = AL_REG_FIELD_GET(reg,763AL_ETH_KR_AN_ADV1_ECHOED_NONCE_MASK,764AL_ETH_KR_AN_ADV1_ECHOED_NONCE_SHIFT);765766an_adv->capability = AL_REG_FIELD_GET(reg,767AL_ETH_KR_AN_ADV1_CAPABILITY_MASK,768AL_ETH_KR_AN_ADV1_CAPABILITY_SHIFT);769770an_adv->remote_fault = AL_REG_BIT_GET(reg,771AL_ETH_KR_AN_ADV1_REM_FAULT_SHIFT);772773an_adv->acknowledge = AL_REG_BIT_GET(reg,774AL_ETH_KR_AN_ADV1_ACK_SHIFT);775776an_adv->next_page = AL_REG_BIT_GET(reg,777AL_ETH_KR_AN_ADV1_NEXT_PAGE_SHIFT);778779780reg = al_eth_an_lt_reg_read(adapter, AL_ETH_KR_AN_REM_ADV1,781AL_ETH_AN_REGS, AL_ETH_AN__LT_LANE_0);782783an_adv->transmitted_nonce = AL_REG_FIELD_GET(reg,784AL_ETH_KR_AN_ADV2_TX_NONCE_MASK,785AL_ETH_KR_AN_ADV2_TX_NONCE_SHIFT);786787an_adv->technology = AL_REG_FIELD_GET(reg,788AL_ETH_KR_AN_ADV2_TECH_MASK,789AL_ETH_KR_AN_ADV2_TECH_SHIFT);790791792reg = al_eth_an_lt_reg_read(adapter, AL_ETH_KR_AN_REM_ADV2,793AL_ETH_AN_REGS, AL_ETH_AN__LT_LANE_0);794795an_adv->technology |= (AL_REG_FIELD_GET(reg,796AL_ETH_KR_AN_ADV3_TECH_MASK,797AL_ETH_KR_AN_ADV3_TECH_SHIFT) << 11);798799an_adv->fec_capability = AL_REG_FIELD_GET(reg,800AL_ETH_KR_AN_ADV3_FEC_MASK,801AL_ETH_KR_AN_ADV3_FEC_SHIFT);802}803804int al_eth_kr_next_page_read(struct al_hal_eth_adapter *adapter,805struct al_eth_an_np *np)806{807uint16_t reg;808809reg = al_eth_an_lt_reg_read(adapter,810AL_ETH_KR_AN_REM_XNP_ADV0,811AL_ETH_AN_REGS,812AL_ETH_AN__LT_LANE_0);813814np->unformatted_code_field = AL_REG_FIELD_GET(reg, AL_ETH_KR_AN_NP_ADV1_DATA1_MASK,815AL_ETH_KR_AN_NP_ADV1_DATA1_SHIFT);816817np->toggle = AL_REG_FIELD_GET(reg, AL_ETH_KR_AN_NP_ADV1_TOGGLE_MASK,818AL_ETH_KR_AN_NP_ADV1_TOGGLE_SHIFT);819820np->ack2 = AL_REG_FIELD_GET(reg, AL_ETH_KR_AN_NP_ADV1_ACK2_MASK,821AL_ETH_KR_AN_NP_ADV1_ACK2_SHIFT);822823np->msg_page = AL_REG_FIELD_GET(reg, AL_ETH_KR_AN_NP_ADV1_MSG_PAGE_MASK,824AL_ETH_KR_AN_NP_ADV1_MSG_PAGE_SHIFT);825826np->next_page = AL_REG_FIELD_GET(reg, AL_ETH_KR_AN_NP_ADV1_NP_MASK,827AL_ETH_KR_AN_NP_ADV1_NP_SHIFT);828829np->unformatted_code_field1 = al_eth_an_lt_reg_read(adapter,830AL_ETH_KR_AN_REM_XNP_ADV1,831AL_ETH_AN_REGS,832AL_ETH_AN__LT_LANE_0);833np->unformatted_code_field2 = al_eth_an_lt_reg_read(adapter,834AL_ETH_KR_AN_REM_XNP_ADV2,835AL_ETH_AN_REGS,836AL_ETH_AN__LT_LANE_0);837838return 0;839}840841int al_eth_kr_next_page_write(struct al_hal_eth_adapter *adapter,842struct al_eth_an_np *np)843{844uint16_t reg = 0;845846AL_REG_FIELD_SET(reg, AL_ETH_KR_AN_NP_ADV1_DATA1_MASK,847AL_ETH_KR_AN_NP_ADV1_DATA1_SHIFT,848np->unformatted_code_field);849AL_REG_FIELD_SET(reg, AL_ETH_KR_AN_NP_ADV1_TOGGLE_MASK,850AL_ETH_KR_AN_NP_ADV1_TOGGLE_SHIFT,851np->toggle);852AL_REG_FIELD_SET(reg, AL_ETH_KR_AN_NP_ADV1_ACK2_MASK,853AL_ETH_KR_AN_NP_ADV1_ACK2_SHIFT,854np->ack2);855AL_REG_FIELD_SET(reg, AL_ETH_KR_AN_NP_ADV1_MSG_PAGE_MASK,856AL_ETH_KR_AN_NP_ADV1_MSG_PAGE_SHIFT,857np->msg_page);858AL_REG_FIELD_SET(reg, AL_ETH_KR_AN_NP_ADV1_NP_MASK,859AL_ETH_KR_AN_NP_ADV1_NP_SHIFT,860np->next_page);861862al_eth_an_lt_reg_write(adapter, AL_ETH_KR_AN_XNP_ADV0, AL_ETH_AN_REGS,863AL_ETH_AN__LT_LANE_0, reg);864865al_eth_an_lt_reg_write(adapter, AL_ETH_KR_AN_XNP_ADV1, AL_ETH_AN_REGS,866AL_ETH_AN__LT_LANE_0, np->unformatted_code_field1);867al_eth_an_lt_reg_write(adapter, AL_ETH_KR_AN_XNP_ADV2, AL_ETH_AN_REGS,868AL_ETH_AN__LT_LANE_0, np->unformatted_code_field2);869870return 0;871}872873int al_eth_kr_an_init(struct al_hal_eth_adapter *adapter,874struct al_eth_an_adv *an_adv)875{876int rc;877878if (adapter->rev_id > AL_ETH_REV_ID_2)879al_eth_an_lt_unit_config(adapter);880881rc = al_eth_kr_an_validate_adv(adapter, an_adv);882if (rc)883return rc;884885rc = al_eth_kr_an_write_adv(adapter, an_adv);886if (rc)887return rc;888889/* clear status */890al_eth_an_lt_reg_read(adapter, AL_ETH_KR_AN_STATUS, AL_ETH_AN_REGS, AL_ETH_AN__LT_LANE_0);891892al_dbg("[%s]: autonegotiation initialized successfully", adapter->name);893return 0;894}895896int al_eth_kr_an_start(struct al_hal_eth_adapter *adapter,897enum al_eth_an_lt_lane lane,898al_bool next_page_enable,899al_bool lt_enable)900{901uint16_t control = AL_ETH_KR_AN_CONTROL_ENABLE | AL_ETH_KR_AN_CONTROL_RESTART;902903al_dbg("Eth [%s]: enable autonegotiation. lt_en %s",904adapter->name, (lt_enable == AL_TRUE) ? "yes" : "no");905906al_eth_an_lt_reg_write(adapter, AL_ETH_KR_PMD_CONTROL, AL_ETH_LT_REGS,907lane, AL_BIT(AL_ETH_KR_PMD_CONTROL_RESTART));908909if (next_page_enable == AL_TRUE)910control |= AL_ETH_KR_AN_CONTROL_NP_ENABLE;911912al_eth_an_lt_reg_write(adapter, AL_ETH_KR_AN_CONTROL, AL_ETH_AN_REGS,913lane, control);914915if (lt_enable == AL_TRUE) {916al_eth_kr_lt_initialize(adapter, lane);917}918919return 0;920}921922void al_eth_kr_an_stop(struct al_hal_eth_adapter *adapter)923{924al_eth_an_lt_reg_write(adapter, AL_ETH_KR_AN_CONTROL, AL_ETH_AN_REGS,925AL_ETH_AN__LT_LANE_0, 0);926}927928void al_eth_kr_an_status_check(struct al_hal_eth_adapter *adapter,929al_bool *page_received,930al_bool *an_completed,931al_bool *error)932{933uint16_t reg;934935reg = al_eth_an_lt_reg_read(adapter, AL_ETH_KR_AN_STATUS,936AL_ETH_AN_REGS, AL_ETH_AN__LT_LANE_0);937938if ((reg & AL_ETH_KR_AN_STATUS_CHECK_MASK) !=939AL_ETH_KR_AN_STATUS_CHECK_NO_ERROR) {940al_err("[%s]: %s AN_STATUS (0x%x) indicated error\n",941adapter->name, __func__, reg);942943*error = AL_TRUE;944}945946if (reg & AL_ETH_KR_AN_STATUS_BASE_PAGE_RECEIVED)947*page_received = AL_TRUE;948else949*page_received = AL_FALSE;950951if (reg & AL_ETH_KR_AN_STATUS_COMPLETED)952*an_completed = AL_TRUE;953else954*an_completed = AL_FALSE;955}956957958/****************************** KR Link Training *****************************/959void al_eth_kr_lt_restart(struct al_hal_eth_adapter *adapter,960enum al_eth_an_lt_lane lane)961{962al_dbg("[%s]: KR LT Restart Link Training.\n", adapter->name);963964al_eth_an_lt_reg_write(adapter, AL_ETH_KR_PMD_CONTROL, AL_ETH_LT_REGS,965lane, (AL_BIT(AL_ETH_KR_PMD_CONTROL_ENABLE) |966AL_BIT(AL_ETH_KR_PMD_CONTROL_RESTART)));967}968969void al_eth_kr_lt_stop(struct al_hal_eth_adapter *adapter,970enum al_eth_an_lt_lane lane)971{972al_dbg("[%s]: KR LT Stop Link Training.\n", adapter->name);973974al_eth_an_lt_reg_write(adapter, AL_ETH_KR_PMD_CONTROL, AL_ETH_LT_REGS,975lane, AL_BIT(AL_ETH_KR_PMD_CONTROL_RESTART));976}977978void al_eth_kr_lt_initialize(struct al_hal_eth_adapter *adapter,979enum al_eth_an_lt_lane lane)980{981al_dbg("[%s]: KR LT Initialize.\n", adapter->name);982983/* Reset LT state machine */984al_eth_kr_lt_stop(adapter, lane);985986/* clear receiver status */987al_eth_an_lt_reg_write(adapter, AL_ETH_KR_PMD_STATUS, AL_ETH_LT_REGS, lane, 0);988989/* Coefficient Update to all zero (no command, hold) */990al_eth_an_lt_reg_write(adapter, AL_ETH_KR_PMD_LD_COEF_UP, AL_ETH_LT_REGS, lane, 0);991/* Coefficient Status to all zero (not_updated) */992al_eth_an_lt_reg_write(adapter, AL_ETH_KR_PMD_LD_STATUS_REPORT, AL_ETH_LT_REGS, lane, 0);993994/* start */995al_eth_kr_lt_restart(adapter, lane);996}997998al_bool al_eth_kr_lt_frame_lock_wait(struct al_hal_eth_adapter *adapter,999enum al_eth_an_lt_lane lane,1000uint32_t timeout)1001{1002uint32_t loop;1003uint16_t reg = 0;10041005for (loop = 0; loop < timeout; loop++) {1006reg = al_eth_an_lt_reg_read(adapter, AL_ETH_KR_PMD_STATUS, AL_ETH_LT_REGS, lane);10071008if (AL_REG_BIT_GET(reg, AL_ETH_KR_PMD_STATUS_FAILURE_SHIFT)) {1009al_info("[%s]: Failed on Training Failure."1010" loops %d PMD STATUS 0x%04x\n",1011adapter->name, loop, reg);10121013return AL_FALSE;1014}1015if (AL_REG_BIT_GET(reg,1016AL_ETH_KR_PMD_STATUS_RECEIVER_FRAME_LOCK_SHIFT)) {1017al_dbg("[%s]: Frame lock received."1018" loops %d PMD STATUS 0x%04x\n",1019adapter->name, loop, reg);10201021return AL_TRUE;1022}1023al_udelay(1);1024}1025al_info("[%s]: Failed on timeout. PMD STATUS 0x%04x\n",1026adapter->name, reg);10271028return AL_FALSE;1029}103010311032