The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/contrib/alpine-hal/eth/al_hal_eth_kr.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    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 }

Cache object: 40dd82e7842f4daaacd731ce90e294b9


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.