From 3098c7f4883d83f28e887bc376250a6d2806ab20 Mon Sep 17 00:00:00 2001 From: Zbigniew Bodek Date: Tue, 26 Jan 2016 14:45:25 +0000 Subject: [PATCH 1/2] Update alpine-hal/dist/ accordingly after r294828 alpine-hal/dist was omitted in the previous commit. Files added here. HAL version: 2.7 Obtained from: Semihalf Sponsored by: Annapurna Labs --- al_hal_iofic.c | 291 ++ al_hal_serdes.c | 3228 +++++++++++++++++++ al_hal_serdes.h | 1125 +++++++ al_hal_serdes_internal_regs.h | 750 +++++ al_hal_serdes_regs.h | 495 +++ al_hal_udma.h | 672 ++++ al_hal_udma_config.c | 1373 ++++++++ al_hal_udma_config.h | 755 +++++ al_hal_udma_debug.c | 497 +++ al_hal_udma_debug.h | 134 + al_hal_udma_iofic.c | 151 + al_hal_udma_iofic.h | 614 ++++ al_hal_udma_iofic_regs.h | 66 + al_hal_udma_main.c | 618 ++++ al_hal_udma_regs.h | 104 + al_hal_udma_regs_gen.h | 414 +++ al_hal_udma_regs_m2s.h | 1159 +++++++ al_hal_udma_regs_s2m.h | 998 ++++++ eth/al_hal_an_lt_wrapper_regs.h | 264 ++ eth/al_hal_eth.h | 2381 ++++++++++++++ eth/al_hal_eth_alu.h | 95 + eth/al_hal_eth_ec_regs.h | 3362 ++++++++++++++++++++ eth/al_hal_eth_kr.c | 1030 ++++++ eth/al_hal_eth_kr.h | 372 +++ eth/al_hal_eth_mac_regs.h | 1809 +++++++++++ eth/al_hal_eth_main.c | 5260 +++++++++++++++++++++++++++++++ 26 files changed, 28017 insertions(+) create mode 100644 al_hal_iofic.c create mode 100644 al_hal_serdes.c create mode 100644 al_hal_serdes.h create mode 100644 al_hal_serdes_internal_regs.h create mode 100644 al_hal_serdes_regs.h create mode 100644 al_hal_udma.h create mode 100644 al_hal_udma_config.c create mode 100644 al_hal_udma_config.h create mode 100644 al_hal_udma_debug.c create mode 100644 al_hal_udma_debug.h create mode 100644 al_hal_udma_iofic.c create mode 100644 al_hal_udma_iofic.h create mode 100644 al_hal_udma_iofic_regs.h create mode 100644 al_hal_udma_main.c create mode 100644 al_hal_udma_regs.h create mode 100644 al_hal_udma_regs_gen.h create mode 100644 al_hal_udma_regs_m2s.h create mode 100644 al_hal_udma_regs_s2m.h create mode 100644 eth/al_hal_an_lt_wrapper_regs.h create mode 100644 eth/al_hal_eth.h create mode 100644 eth/al_hal_eth_alu.h create mode 100644 eth/al_hal_eth_ec_regs.h create mode 100644 eth/al_hal_eth_kr.c create mode 100644 eth/al_hal_eth_kr.h create mode 100644 eth/al_hal_eth_mac_regs.h create mode 100644 eth/al_hal_eth_main.c diff --git a/al_hal_iofic.c b/al_hal_iofic.c new file mode 100644 index 00000000000..28467f2e3b8 --- /dev/null +++ b/al_hal_iofic.c @@ -0,0 +1,291 @@ +/*- +******************************************************************************* +Copyright (C) 2015 Annapurna Labs Ltd. + +This file may be licensed under the terms of the Annapurna Labs Commercial +License Agreement. + +Alternatively, this file can be distributed under the terms of the GNU General +Public License V2 as published by the Free Software Foundation and can be +found at http://www.gnu.org/licenses/gpl-2.0.html + +Alternatively, redistribution and use in source and binary forms, with or +without modification, are permitted provided that the following conditions are +met: + + * Redistributions of source code must retain the above copyright notice, +this list of conditions and the following disclaimer. + + * Redistributions in binary form must reproduce the above copyright +notice, this list of conditions and the following disclaimer in +the documentation and/or other materials provided with the +distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +*******************************************************************************/ + +/** + * @{ + * @file al_hal_iofic.c + * + * @brief interrupt controller hal + * + */ + +#include "al_hal_iofic.h" +#include "al_hal_iofic_regs.h" + +/* + * configure the interrupt registers, interrupts will are kept masked + */ +int al_iofic_config(void __iomem *regs_base, int group, uint32_t flags) +{ + struct al_iofic_regs __iomem *regs = (struct al_iofic_regs __iomem *)(regs_base); + + al_assert(regs_base); + al_assert(group < AL_IOFIC_MAX_GROUPS); + + al_reg_write32(®s->ctrl[group].int_control_grp, flags); + + return 0; +} + +/* + * configure the moderation timer resolution for a given group + */ +int al_iofic_moder_res_config(void __iomem *regs_base, int group, + uint8_t resolution) + +{ + struct al_iofic_regs __iomem *regs = (struct al_iofic_regs __iomem *)(regs_base); + uint32_t reg; + + al_assert(regs_base); + al_assert(group < AL_IOFIC_MAX_GROUPS); + + reg = al_reg_read32(®s->ctrl[group].int_control_grp); + AL_REG_FIELD_SET(reg, + INT_CONTROL_GRP_MOD_RES_MASK, + INT_CONTROL_GRP_MOD_RES_SHIFT, + resolution); + al_reg_write32(®s->ctrl[group].int_control_grp, reg); + + return 0; +} + +/* + * configure the moderation timer interval for a given legacy interrupt group + */ +int al_iofic_legacy_moder_interval_config(void __iomem *regs_base, int group, + uint8_t interval) +{ + struct al_iofic_regs __iomem *regs = (struct al_iofic_regs __iomem *)(regs_base); + uint32_t reg; + + al_assert(regs_base); + al_assert(group < AL_IOFIC_MAX_GROUPS); + + reg = al_reg_read32(®s->ctrl[group].int_control_grp); + AL_REG_FIELD_SET(reg, + INT_CONTROL_GRP_MOD_INTV_MASK, + INT_CONTROL_GRP_MOD_INTV_SHIFT, + interval); + al_reg_write32(®s->ctrl[group].int_control_grp, reg); + + return 0; +} + + +/* + * configure the moderation timer interval for a given msix vector. + */ +int al_iofic_msix_moder_interval_config(void __iomem *regs_base, int group, + uint8_t vector, uint8_t interval) +{ + struct al_iofic_regs __iomem *regs = (struct al_iofic_regs __iomem *)(regs_base); + uint32_t reg; + + al_assert(regs_base); + al_assert(group < AL_IOFIC_MAX_GROUPS); + + reg = al_reg_read32(®s->grp_int_mod[group][vector].grp_int_mod_reg); + AL_REG_FIELD_SET(reg, + INT_MOD_INTV_MASK, + INT_MOD_INTV_SHIFT, + interval); + al_reg_write32(®s->grp_int_mod[group][vector].grp_int_mod_reg, reg); + + return 0; +} + +/* + * configure the vmid attributes for a given msix vector. + */ +int al_iofic_msix_vmid_attributes_config(void __iomem *regs_base, int group, + uint8_t vector, uint32_t vmid, uint8_t vmid_en) +{ + struct al_iofic_regs __iomem *regs = (struct al_iofic_regs __iomem *)(regs_base); + uint32_t reg = 0; + + al_assert(regs_base); + al_assert(group < AL_IOFIC_MAX_GROUPS); + + AL_REG_FIELD_SET(reg, + INT_MSIX_VMID_MASK, + INT_MSIX_VMID_SHIFT, + vmid); + AL_REG_BIT_VAL_SET(reg, + INT_MSIX_VMID_EN_SHIFT, + vmid_en); + + al_reg_write32(®s->grp_int_mod[group][vector].grp_int_vmid_reg, reg); + + return 0; +} + +/* + * return the offset of the unmask register for a given group + */ +uint32_t __iomem * al_iofic_unmask_offset_get(void __iomem *regs_base, int group) +{ + struct al_iofic_regs __iomem *regs = (struct al_iofic_regs __iomem *)(regs_base); + + al_assert(regs_base); + al_assert(group < AL_IOFIC_MAX_GROUPS); + + return ®s->ctrl[group].int_mask_clear_grp; +} + + +/* + * unmask specific interrupts for a given group + */ +void al_iofic_unmask(void __iomem *regs_base, int group, uint32_t mask) +{ + struct al_iofic_regs __iomem *regs = (struct al_iofic_regs __iomem *)(regs_base); + + al_assert(regs_base); + al_assert(group < AL_IOFIC_MAX_GROUPS); + + /* + * use the mask clear register, no need to read the mask register + * itself. write 0 to unmask, 1 has no effect + */ + al_reg_write32_relaxed(®s->ctrl[group].int_mask_clear_grp, ~mask); +} + +/* + * mask specific interrupts for a given group + */ +void al_iofic_mask(void __iomem *regs_base, int group, uint32_t mask) +{ + struct al_iofic_regs __iomem *regs = (struct al_iofic_regs __iomem *)(regs_base); + uint32_t reg; + + al_assert(regs_base); + al_assert(group < AL_IOFIC_MAX_GROUPS); + + reg = al_reg_read32(®s->ctrl[group].int_mask_grp); + + al_reg_write32(®s->ctrl[group].int_mask_grp, reg | mask); +} + +/* + * read the mask for a given group + */ +uint32_t al_iofic_read_mask(void __iomem *regs_base, int group) +{ + struct al_iofic_regs __iomem *regs = (struct al_iofic_regs __iomem *)(regs_base); + + al_assert(regs_base); + al_assert(group < AL_IOFIC_MAX_GROUPS); + + return al_reg_read32(®s->ctrl[group].int_mask_grp); +} + +/* + * read interrupt cause register for a given group + */ +uint32_t al_iofic_read_cause(void __iomem *regs_base, int group) +{ + struct al_iofic_regs __iomem *regs = (struct al_iofic_regs __iomem *)(regs_base); + + al_assert(regs_base); + al_assert(group < AL_IOFIC_MAX_GROUPS); + + return al_reg_read32(®s->ctrl[group].int_cause_grp); +} + +/* + * clear bits in the interrupt cause register for a given group + */ +void al_iofic_clear_cause(void __iomem *regs_base, int group, uint32_t mask) +{ + struct al_iofic_regs __iomem *regs = (struct al_iofic_regs __iomem *)(regs_base); + + al_assert(regs_base); + al_assert(group < AL_IOFIC_MAX_GROUPS); + + /* inverse mask, writing 1 has no effect */ + al_reg_write32(®s->ctrl[group].int_cause_grp, ~mask); +} + +/* + * Set the cause register for a given group + */ +void al_iofic_set_cause(void __iomem *regs_base, int group, uint32_t mask) +{ + struct al_iofic_regs __iomem *regs = (struct al_iofic_regs __iomem *)(regs_base); + + al_assert(regs_base); + al_assert(group < AL_IOFIC_MAX_GROUPS); + + al_reg_write32(®s->ctrl[group].int_cause_set_grp, mask); +} + + +/* + * unmask specific interrupts from aborting the udma a given group + */ +void al_iofic_abort_mask(void __iomem *regs_base, int group, uint32_t mask) +{ + struct al_iofic_regs __iomem *regs = (struct al_iofic_regs __iomem *)(regs_base); + + al_assert(regs_base); + al_assert(group < AL_IOFIC_MAX_GROUPS); + + al_reg_write32(®s->ctrl[group].int_abort_msk_grp, mask); + +} + +/* + * trigger all interrupts that are waiting for moderation timers to expire + */ +void al_iofic_interrupt_moderation_reset(void __iomem *regs_base, int group) +{ + struct al_iofic_regs __iomem *regs = (struct al_iofic_regs __iomem *)(regs_base); + uint32_t reg = 0; + + al_assert(regs_base); + al_assert(group < AL_IOFIC_MAX_GROUPS); + + al_assert(regs_base); + al_assert(group < AL_IOFIC_MAX_GROUPS); + + reg = al_reg_read32(®s->ctrl[group].int_control_grp); + reg |= INT_CONTROL_GRP_MOD_RST; + + al_reg_write32(®s->ctrl[group].int_control_grp, reg); +} + +/** @} end of interrupt controller group */ diff --git a/al_hal_serdes.c b/al_hal_serdes.c new file mode 100644 index 00000000000..bb34d13c765 --- /dev/null +++ b/al_hal_serdes.c @@ -0,0 +1,3228 @@ +/*- +******************************************************************************* +Copyright (C) 2015 Annapurna Labs Ltd. + +This file may be licensed under the terms of the Annapurna Labs Commercial +License Agreement. + +Alternatively, this file can be distributed under the terms of the GNU General +Public License V2 as published by the Free Software Foundation and can be +found at http://www.gnu.org/licenses/gpl-2.0.html + +Alternatively, redistribution and use in source and binary forms, with or +without modification, are permitted provided that the following conditions are +met: + + * Redistributions of source code must retain the above copyright notice, +this list of conditions and the following disclaimer. + + * Redistributions in binary form must reproduce the above copyright +notice, this list of conditions and the following disclaimer in +the documentation and/or other materials provided with the +distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +*******************************************************************************/ + +#include "al_hal_serdes.h" +#include "al_hal_serdes_regs.h" +#include "al_hal_serdes_internal_regs.h" + +#define SRDS_CORE_REG_ADDR(page, type, offset)\ + (((page) << 13) | ((type) << 12) | (offset)) + +/* Link Training configuration */ +#define AL_SERDES_TX_DEEMPH_SUM_MAX 0x1b + +/* c configurations */ +#define AL_SERDES_TX_DEEMPH_C_ZERO_MAX_VAL 0x1b +#define AL_SERDES_TX_DEEMPH_C_ZERO_MIN_VAL 0 +#define AL_SERDES_TX_DEEMPH_C_ZERO_PRESET AL_SERDES_TX_DEEMPH_C_ZERO_MAX_VAL + +/* c(+1) configurations */ +#define AL_SERDES_TX_DEEMPH_C_PLUS_MAX_VAL 0x9 +#define AL_SERDES_TX_DEEMPH_C_PLUS_MIN_VAL 0 +#define AL_SERDES_TX_DEEMPH_C_PLUS_PRESET AL_SERDES_TX_DEEMPH_C_PLUS_MIN_VAL + +/* c(-1) configurations */ +#define AL_SERDES_TX_DEEMPH_C_MINUS_MAX_VAL 0x6 +#define AL_SERDES_TX_DEEMPH_C_MINUS_MIN_VAL 0 +#define AL_SERDES_TX_DEEMPH_C_MINUS_PRESET AL_SERDES_TX_DEEMPH_C_MINUS_MIN_VAL + +/* Rx equal total delay = MDELAY * TRIES */ +#define AL_SERDES_RX_EQUAL_MDELAY 10 +#define AL_SERDES_RX_EQUAL_TRIES 50 + +/* Rx eye calculation delay = MDELAY * TRIES */ +#define AL_SERDES_RX_EYE_CAL_MDELAY 50 +#define AL_SERDES_RX_EYE_CAL_TRIES 70 + + +/** + * Prototypes for _lane_ compatibility + */ +int al_serdes_lane_read( + struct al_serdes_obj *obj, + enum al_serdes_group grp, + enum al_serdes_lane lane, + enum al_serdes_reg_type type, + uint16_t offset, + uint8_t *data); + +int al_serdes_lane_write( + struct al_serdes_obj *obj, + enum al_serdes_group grp, + enum al_serdes_lane lane, + enum al_serdes_reg_type type, + uint16_t offset, + uint8_t data); + + +/** + * SERDES core reg/lane read + */ +static inline uint8_t al_serdes_grp_reg_read( + struct al_serdes_group_info *grp_info, + enum al_serdes_reg_page page, + enum al_serdes_reg_type type, + uint16_t offset); + +static inline uint8_t al_serdes_grp_lane_read( + struct al_serdes_group_info *grp_info, + enum al_serdes_lane page, + enum al_serdes_reg_type type, + uint16_t offset); + +/** + * SERDES core reg/lane write + */ +static inline void al_serdes_grp_reg_write( + struct al_serdes_group_info *grp_info, + enum al_serdes_reg_page page, + enum al_serdes_reg_type type, + uint16_t offset, + uint8_t data); + +static inline void al_serdes_grp_lane_write( + struct al_serdes_group_info *grp_info, + enum al_serdes_lane lane, + enum al_serdes_reg_type type, + uint16_t offset, + uint8_t data); + +/** + * SERDES core masked reg/lane write + */ +static inline void al_serdes_grp_reg_masked_write( + struct al_serdes_group_info *grp_info, + enum al_serdes_reg_page page, + enum al_serdes_reg_type type, + uint16_t offset, + uint8_t mask, + uint8_t data); + +/** + * Lane Rx rate change software flow disable + */ +static void _al_serdes_lane_rx_rate_change_sw_flow_dis( + struct al_serdes_group_info *grp_info, + enum al_serdes_lane lane); + +/** + * Group Rx rate change software flow enable if all conditions met + */ +static void al_serdes_group_rx_rate_change_sw_flow_dis( + struct al_serdes_group_info *grp_info); + +/** + * Lane Rx rate change software flow enable if all conditions met + */ +static void _al_serdes_lane_rx_rate_change_sw_flow_en_cond( + struct al_serdes_group_info *grp_info, + enum al_serdes_lane lane); + +/** + * Group Rx rate change software flow enable if all conditions met + */ +static void al_serdes_group_rx_rate_change_sw_flow_en_cond( + struct al_serdes_group_info *grp_info); + + +static inline void al_serdes_grp_lane_masked_write( + struct al_serdes_group_info *grp_info, + enum al_serdes_lane lane, + enum al_serdes_reg_type type, + uint16_t offset, + uint8_t mask, + uint8_t data); + +/******************************************************************************/ +/******************************************************************************/ +int al_serdes_handle_init( + void __iomem *serdes_regs_base, + struct al_serdes_obj *obj) +{ + int i; + + al_dbg( + "%s(%p, %p)\n", + __func__, + serdes_regs_base, + obj); + + al_assert(serdes_regs_base); + + for (i = 0; i < AL_SRDS_NUM_GROUPS; i++) { + obj->grp_info[i].pobj = obj; + + obj->grp_info[i].regs_base = + &((struct al_serdes_regs *)serdes_regs_base)[i]; + } + + return 0; +} + +/******************************************************************************/ +/******************************************************************************/ +int al_serdes_reg_read( + struct al_serdes_obj *obj, + enum al_serdes_group grp, + enum al_serdes_reg_page page, + enum al_serdes_reg_type type, + uint16_t offset, + uint8_t *data) +{ + int status = 0; + + al_dbg( + "%s(%p, %d, %d, %d, %u)\n", + __func__, + obj, + grp, + page, + type, + offset); + + al_assert(obj); + al_assert(data); + al_assert(((int)grp) >= AL_SRDS_GRP_A); + al_assert(((int)grp) <= AL_SRDS_GRP_D); + al_assert(((int)page) >= AL_SRDS_REG_PAGE_0_LANE_0); + al_assert(((int)page) <= AL_SRDS_REG_PAGE_4_COMMON); + al_assert(((int)type) >= AL_SRDS_REG_TYPE_PMA); + al_assert(((int)type) <= AL_SRDS_REG_TYPE_PCS); + + *data = al_serdes_grp_reg_read( + &obj->grp_info[grp], + page, + type, + offset); + + al_dbg( + "%s: return(%u)\n", + __func__, + *data); + + return status; +} + +int al_serdes_lane_read( + struct al_serdes_obj *obj, + enum al_serdes_group grp, + enum al_serdes_lane lane, + enum al_serdes_reg_type type, + uint16_t offset, + uint8_t *data) +{ + return al_serdes_reg_read(obj, grp, (enum al_serdes_reg_page)lane, type, + offset, data); +} +/******************************************************************************/ +/******************************************************************************/ +int al_serdes_reg_write( + struct al_serdes_obj *obj, + enum al_serdes_group grp, + enum al_serdes_reg_page page, + enum al_serdes_reg_type type, + uint16_t offset, + uint8_t data) +{ + int status = 0; + + al_dbg( + "%s(%p, %d, %d, %d, %u, %u)\n", + __func__, + obj, + grp, + page, + type, + offset, + data); + + al_assert(obj); + al_assert(((int)grp) >= AL_SRDS_GRP_A); + al_assert(((int)grp) <= AL_SRDS_GRP_D); + al_assert(((int)page) >= AL_SRDS_REG_PAGE_0_LANE_0); + al_assert(((int)page) <= AL_SRDS_REG_PAGE_0123_LANES_0123); + al_assert(((int)type) >= AL_SRDS_REG_TYPE_PMA); + al_assert(((int)type) <= AL_SRDS_REG_TYPE_PCS); + + al_serdes_grp_reg_write( + &obj->grp_info[grp], + page, + type, + offset, + data); + + return status; +} + +int al_serdes_lane_write( + struct al_serdes_obj *obj, + enum al_serdes_group grp, + enum al_serdes_lane lane, + enum al_serdes_reg_type type, + uint16_t offset, + uint8_t data) +{ + return al_serdes_reg_write(obj, grp, (enum al_serdes_reg_page)lane, + type, offset, data); +} +/******************************************************************************/ +/******************************************************************************/ +#if (SERDES_IREG_FLD_PCSRX_DATAWIDTH_REG_NUM != SERDES_IREG_FLD_PCSTX_DATAWIDTH_REG_NUM) +#error "Wrong assumption!" +#endif +#if (SERDES_IREG_FLD_PCSRX_DIVRATE_REG_NUM != SERDES_IREG_FLD_PCSTX_DIVRATE_REG_NUM) +#error "Wrong assumption!" +#endif +#if (SERDES_IREG_FLD_CMNPCIEGEN3_LOCWREN_REG_NUM != SERDES_IREG_FLD_CMNPCS_LOCWREN_REG_NUM) +#error "Wrong assumption!" +#endif +#if (SERDES_IREG_FLD_CMNPCIEGEN3_LOCWREN_REG_NUM != SERDES_IREG_FLD_CMNPCSBIST_LOCWREN_REG_NUM) +#error "Wrong assumption!" +#endif +#if (SERDES_IREG_FLD_CMNPCIEGEN3_LOCWREN_REG_NUM != SERDES_IREG_FLD_CMNPCSPSTATE_LOCWREN_REG_NUM) +#error "Wrong assumption!" +#endif +#if (SERDES_IREG_FLD_LANEPCSPSTATE_LOCWREN_REG_NUM != SERDES_IREG_FLD_LB_LOCWREN_REG_NUM) +#error "Wrong assumption!" +#endif +#if (SERDES_IREG_FLD_LANEPCSPSTATE_LOCWREN_REG_NUM != SERDES_IREG_FLD_PCSRX_LOCWREN_REG_NUM) +#error "Wrong assumption!" +#endif +#if (SERDES_IREG_FLD_LANEPCSPSTATE_LOCWREN_REG_NUM != SERDES_IREG_FLD_PCSRXBIST_LOCWREN_REG_NUM) +#error "Wrong assumption!" +#endif +#if (SERDES_IREG_FLD_LANEPCSPSTATE_LOCWREN_REG_NUM != SERDES_IREG_FLD_PCSRXEQ_LOCWREN_REG_NUM) +#error "Wrong assumption!" +#endif +#if (SERDES_IREG_FLD_LANEPCSPSTATE_LOCWREN_REG_NUM != SERDES_IREG_FLD_PCSTX_LOCWREN_REG_NUM) +#error "Wrong assumption!" +#endif +void al_serdes_bist_overrides_enable( + struct al_serdes_obj *obj, + enum al_serdes_group grp, + enum al_serdes_rate rate) +{ + struct al_serdes_group_info *grp_info = &obj->grp_info[grp]; + int i; + + uint8_t rx_rate_val; + uint8_t tx_rate_val; + + switch (rate) { + case AL_SRDS_RATE_1_8: + rx_rate_val = SERDES_IREG_FLD_PCSRX_DIVRATE_VAL_1_8; + tx_rate_val = SERDES_IREG_FLD_PCSTX_DIVRATE_VAL_1_8; + break; + case AL_SRDS_RATE_1_4: + rx_rate_val = SERDES_IREG_FLD_PCSRX_DIVRATE_VAL_1_4; + tx_rate_val = SERDES_IREG_FLD_PCSTX_DIVRATE_VAL_1_4; + break; + case AL_SRDS_RATE_1_2: + rx_rate_val = SERDES_IREG_FLD_PCSRX_DIVRATE_VAL_1_2; + tx_rate_val = SERDES_IREG_FLD_PCSTX_DIVRATE_VAL_1_2; + break; + case AL_SRDS_RATE_FULL: + rx_rate_val = SERDES_IREG_FLD_PCSRX_DIVRATE_VAL_1_1; + tx_rate_val = SERDES_IREG_FLD_PCSTX_DIVRATE_VAL_1_1; + break; + default: + al_err("%s: invalid rate (%d)\n", __func__, rate); + al_assert(0); + rx_rate_val = SERDES_IREG_FLD_PCSRX_DIVRATE_VAL_1_1; + tx_rate_val = SERDES_IREG_FLD_PCSTX_DIVRATE_VAL_1_1; + } + + for (i = 0; i < AL_SRDS_NUM_LANES; i++) { + al_serdes_grp_reg_masked_write( + grp_info, + (enum al_serdes_reg_page)i, + AL_SRDS_REG_TYPE_PMA, + SERDES_IREG_FLD_PCSRX_DATAWIDTH_REG_NUM, + SERDES_IREG_FLD_PCSRX_DATAWIDTH_MASK | + SERDES_IREG_FLD_PCSTX_DATAWIDTH_MASK, + SERDES_IREG_FLD_PCSRX_DATAWIDTH_VAL_20 | + SERDES_IREG_FLD_PCSTX_DATAWIDTH_VAL_20); + + al_serdes_grp_reg_masked_write( + grp_info, + (enum al_serdes_reg_page)i, + AL_SRDS_REG_TYPE_PMA, + SERDES_IREG_FLD_PCSRX_DIVRATE_REG_NUM, + SERDES_IREG_FLD_PCSRX_DIVRATE_MASK | + SERDES_IREG_FLD_PCSTX_DIVRATE_MASK, + rx_rate_val | tx_rate_val); + } + + al_serdes_grp_reg_masked_write( + grp_info, + AL_SRDS_REG_PAGE_4_COMMON, + AL_SRDS_REG_TYPE_PMA, + SERDES_IREG_FLD_CMNPCIEGEN3_LOCWREN_REG_NUM, + SERDES_IREG_FLD_CMNPCIEGEN3_LOCWREN | + SERDES_IREG_FLD_CMNPCS_LOCWREN | + SERDES_IREG_FLD_CMNPCSBIST_LOCWREN | + SERDES_IREG_FLD_CMNPCSPSTATE_LOCWREN, + 0); + + al_serdes_grp_reg_masked_write( + grp_info, + AL_SRDS_REG_PAGE_4_COMMON, + AL_SRDS_REG_TYPE_PMA, + SERDES_IREG_FLD_CMNPCIEGEN3_LOCWREN_REG_NUM, + SERDES_IREG_FLD_CMNPCIEGEN3_LOCWREN | + SERDES_IREG_FLD_CMNPCS_LOCWREN | + SERDES_IREG_FLD_CMNPCSBIST_LOCWREN | + SERDES_IREG_FLD_CMNPCSPSTATE_LOCWREN, + 0); + + al_serdes_grp_reg_masked_write( + grp_info, + AL_SRDS_REG_PAGE_4_COMMON, + AL_SRDS_REG_TYPE_PMA, + SERDES_IREG_FLD_PCS_LOCWREN_REG_NUM, + SERDES_IREG_FLD_PCS_LOCWREN, + 0); + + al_serdes_grp_reg_masked_write( + grp_info, + AL_SRDS_REG_PAGE_4_COMMON, + AL_SRDS_REG_TYPE_PMA, + SERDES_IREG_FLD_CMNPCS_TXENABLE_REG_NUM, + SERDES_IREG_FLD_CMNPCS_TXENABLE, + SERDES_IREG_FLD_CMNPCS_TXENABLE); + + for (i = 0; i < AL_SRDS_NUM_LANES; i++) { + al_serdes_grp_reg_masked_write( + grp_info, + (enum al_serdes_reg_page)i, + AL_SRDS_REG_TYPE_PMA, + SERDES_IREG_FLD_LANEPCSPSTATE_LOCWREN_REG_NUM, + SERDES_IREG_FLD_LANEPCSPSTATE_LOCWREN | + SERDES_IREG_FLD_LB_LOCWREN | + SERDES_IREG_FLD_PCSRX_LOCWREN | + SERDES_IREG_FLD_PCSRXBIST_LOCWREN | + SERDES_IREG_FLD_PCSRXEQ_LOCWREN | + SERDES_IREG_FLD_PCSTX_LOCWREN, + 0); + + al_serdes_grp_reg_masked_write( + grp_info, + (enum al_serdes_reg_page)i, + AL_SRDS_REG_TYPE_PMA, + SERDES_IREG_FLD_PCSTXBIST_LOCWREN_REG_NUM, + SERDES_IREG_FLD_PCSTXBIST_LOCWREN, + 0); + + al_serdes_grp_reg_masked_write( + grp_info, + (enum al_serdes_reg_page)i, + AL_SRDS_REG_TYPE_PMA, + SERDES_IREG_FLD_TX_DRV_OVERRIDE_EN_REG_NUM, + SERDES_IREG_FLD_TX_DRV_OVERRIDE_EN, + 0); + + al_serdes_grp_reg_masked_write( + grp_info, + (enum al_serdes_reg_page)i, + AL_SRDS_REG_TYPE_PMA, + SERDES_IREG_FLD_RXLOCK2REF_OVREN_REG_NUM, + SERDES_IREG_FLD_RXLOCK2REF_OVREN, + SERDES_IREG_FLD_RXLOCK2REF_OVREN); + } +} + +/******************************************************************************/ +/******************************************************************************/ +void al_serdes_bist_overrides_disable( + struct al_serdes_obj *obj, + enum al_serdes_group grp) +{ + struct al_serdes_group_info *grp_info = &obj->grp_info[grp]; + int i; + + al_serdes_grp_reg_masked_write( + grp_info, + AL_SRDS_REG_PAGE_4_COMMON, + AL_SRDS_REG_TYPE_PMA, + SERDES_IREG_FLD_CMNPCIEGEN3_LOCWREN_REG_NUM, + SERDES_IREG_FLD_CMNPCSBIST_LOCWREN, + SERDES_IREG_FLD_CMNPCSBIST_LOCWREN); + + for (i = 0; i < AL_SRDS_NUM_LANES; i++) { + al_serdes_grp_reg_masked_write( + grp_info, + (enum al_serdes_reg_page)i, + AL_SRDS_REG_TYPE_PMA, + SERDES_IREG_FLD_LANEPCSPSTATE_LOCWREN_REG_NUM, + SERDES_IREG_FLD_LB_LOCWREN | + SERDES_IREG_FLD_PCSRXBIST_LOCWREN, + SERDES_IREG_FLD_LB_LOCWREN | + SERDES_IREG_FLD_PCSRXBIST_LOCWREN); + + al_serdes_grp_reg_masked_write( + grp_info, + (enum al_serdes_reg_page)i, + AL_SRDS_REG_TYPE_PMA, + SERDES_IREG_FLD_PCSTXBIST_LOCWREN_REG_NUM, + SERDES_IREG_FLD_PCSTXBIST_LOCWREN, + SERDES_IREG_FLD_PCSTXBIST_LOCWREN); + } +} + +/******************************************************************************/ +/******************************************************************************/ +void al_serdes_rx_rate_change( + struct al_serdes_obj *obj, + enum al_serdes_group grp, + enum al_serdes_rate rate) +{ + struct al_serdes_group_info *grp_info = &obj->grp_info[grp]; + int i; + + uint8_t rx_rate_val; + + switch (rate) { + case AL_SRDS_RATE_1_8: + rx_rate_val = SERDES_IREG_FLD_PCSRX_DIVRATE_VAL_1_8; + break; + case AL_SRDS_RATE_1_4: + rx_rate_val = SERDES_IREG_FLD_PCSRX_DIVRATE_VAL_1_4; + break; + case AL_SRDS_RATE_1_2: + rx_rate_val = SERDES_IREG_FLD_PCSRX_DIVRATE_VAL_1_2; + break; + case AL_SRDS_RATE_FULL: + rx_rate_val = SERDES_IREG_FLD_PCSRX_DIVRATE_VAL_1_1; + break; + default: + al_err("%s: invalid rate (%d)\n", __func__, rate); + rx_rate_val = SERDES_IREG_FLD_PCSRX_DIVRATE_VAL_1_1; + break; + } + + for (i = 0; i < AL_SRDS_NUM_LANES; i++) { + al_serdes_grp_reg_masked_write( + grp_info, + (enum al_serdes_reg_page)i, + AL_SRDS_REG_TYPE_PMA, + SERDES_IREG_FLD_PCSRX_DIVRATE_REG_NUM, + SERDES_IREG_FLD_PCSRX_DIVRATE_MASK, + rx_rate_val); + } +} + +/******************************************************************************/ +/******************************************************************************/ +void al_serdes_group_pm_set( + struct al_serdes_obj *obj, + enum al_serdes_group grp, + enum al_serdes_pm pm) +{ + struct al_serdes_group_info *grp_info = &obj->grp_info[grp]; + + uint8_t pm_val; + + switch (pm) { + case AL_SRDS_PM_PD: + pm_val = SERDES_IREG_FLD_CMNPCSPSTATE_SYNTH_VAL_PD; + break; + case AL_SRDS_PM_P2: + pm_val = SERDES_IREG_FLD_CMNPCSPSTATE_SYNTH_VAL_P2; + break; + case AL_SRDS_PM_P1: + pm_val = SERDES_IREG_FLD_CMNPCSPSTATE_SYNTH_VAL_P1; + break; + case AL_SRDS_PM_P0S: + pm_val = SERDES_IREG_FLD_CMNPCSPSTATE_SYNTH_VAL_P0S; + break; + case AL_SRDS_PM_P0: + pm_val = SERDES_IREG_FLD_CMNPCSPSTATE_SYNTH_VAL_P0; + break; + default: + al_err("%s: invalid power mode (%d)\n", __func__, pm); + al_assert(0); + pm_val = SERDES_IREG_FLD_CMNPCSPSTATE_SYNTH_VAL_P0; + } + + if (pm == AL_SRDS_PM_PD) + al_serdes_group_rx_rate_change_sw_flow_dis(grp_info); + + al_serdes_grp_reg_masked_write( + grp_info, + AL_SRDS_REG_PAGE_4_COMMON, + AL_SRDS_REG_TYPE_PMA, + SERDES_IREG_FLD_CMNPCSPSTATE_SYNTH_REG_NUM, + SERDES_IREG_FLD_CMNPCSPSTATE_SYNTH_MASK, + pm_val); + + if (pm != AL_SRDS_PM_PD) + al_serdes_group_rx_rate_change_sw_flow_en_cond(grp_info); +} + +/******************************************************************************/ +/******************************************************************************/ +void al_serdes_lane_rx_rate_change_sw_flow_en( + struct al_serdes_obj *obj, + enum al_serdes_group grp, + enum al_serdes_lane lane) +{ + al_serdes_lane_write(obj, grp, lane, AL_SRDS_REG_TYPE_PMA, 201, 0xfc); + al_serdes_lane_write(obj, grp, lane, AL_SRDS_REG_TYPE_PMA, 202, 0xff); + al_serdes_lane_write(obj, grp, lane, AL_SRDS_REG_TYPE_PMA, 203, 0xff); + al_serdes_lane_write(obj, grp, lane, AL_SRDS_REG_TYPE_PMA, 204, 0xff); + al_serdes_lane_write(obj, grp, lane, AL_SRDS_REG_TYPE_PMA, 205, 0x7f); + al_serdes_lane_write(obj, grp, lane, AL_SRDS_REG_TYPE_PMA, 205, 0xff); +} + +/******************************************************************************/ +/******************************************************************************/ +void al_serdes_lane_rx_rate_change_sw_flow_dis( + struct al_serdes_obj *obj, + enum al_serdes_group grp, + enum al_serdes_lane lane) +{ + al_serdes_lane_write(obj, grp, lane, AL_SRDS_REG_TYPE_PMA, 205, 0x7f); +} + +/******************************************************************************/ +/******************************************************************************/ +void al_serdes_lane_pcie_rate_override_enable_set( + struct al_serdes_obj *obj, + enum al_serdes_group grp, + enum al_serdes_lane lane, + al_bool en) +{ + struct al_serdes_group_info *grp_info = &obj->grp_info[grp]; + + al_serdes_grp_reg_masked_write( + grp_info, + (enum al_serdes_reg_page)lane, + AL_SRDS_REG_TYPE_PCS, + SERDES_IREG_FLD_PCS_VPCSIF_OVR_RATE_ENA_REG_NUM, + SERDES_IREG_FLD_PCS_VPCSIF_OVR_RATE_ENA, + en ? SERDES_IREG_FLD_PCS_VPCSIF_OVR_RATE_ENA : 0); +} + +/******************************************************************************/ +/******************************************************************************/ +al_bool al_serdes_lane_pcie_rate_override_is_enabled( + struct al_serdes_obj *obj, + enum al_serdes_group grp, + enum al_serdes_lane lane) +{ + struct al_serdes_group_info *grp_info = &obj->grp_info[grp]; + + return (al_serdes_grp_lane_read( + grp_info, + lane, + AL_SRDS_REG_TYPE_PCS, + SERDES_IREG_FLD_PCS_VPCSIF_OVR_RATE_ENA_REG_NUM) & + SERDES_IREG_FLD_PCS_VPCSIF_OVR_RATE_ENA) ? AL_TRUE : AL_FALSE; +} + +/******************************************************************************/ +/******************************************************************************/ +enum al_serdes_pcie_rate al_serdes_lane_pcie_rate_get( + struct al_serdes_obj *obj, + enum al_serdes_group grp, + enum al_serdes_lane lane) +{ + struct al_serdes_group_info *grp_info = &obj->grp_info[grp]; + + return (al_serdes_grp_reg_read( + grp_info, + (enum al_serdes_reg_page)lane, + AL_SRDS_REG_TYPE_PCS, + SERDES_IREG_FLD_PCS_VPCSIF_OVR_RATE_REG_NUM) & + SERDES_IREG_FLD_PCS_VPCSIF_OVR_RATE_MASK) >> + SERDES_IREG_FLD_PCS_VPCSIF_OVR_RATE_SHIFT; +} + +/******************************************************************************/ +/******************************************************************************/ +void al_serdes_lane_pcie_rate_set( + struct al_serdes_obj *obj, + enum al_serdes_group grp, + enum al_serdes_lane lane, + enum al_serdes_pcie_rate rate) +{ + struct al_serdes_group_info *grp_info = &obj->grp_info[grp]; + + al_serdes_grp_reg_masked_write( + grp_info, + (enum al_serdes_reg_page)lane, + AL_SRDS_REG_TYPE_PCS, + SERDES_IREG_FLD_PCS_VPCSIF_OVR_RATE_REG_NUM, + SERDES_IREG_FLD_PCS_VPCSIF_OVR_RATE_MASK, + rate << SERDES_IREG_FLD_PCS_VPCSIF_OVR_RATE_SHIFT); +} + +/******************************************************************************/ +/******************************************************************************/ +void al_serdes_lane_pm_set( + struct al_serdes_obj *obj, + enum al_serdes_group grp, + enum al_serdes_lane lane, + enum al_serdes_pm rx_pm, + enum al_serdes_pm tx_pm) +{ + struct al_serdes_group_info *grp_info = &obj->grp_info[grp]; + + uint8_t rx_pm_val; + uint8_t tx_pm_val; + + switch (rx_pm) { + case AL_SRDS_PM_PD: + rx_pm_val = SERDES_IREG_FLD_LANEPCSPSTATE_RX_VAL_PD; + break; + case AL_SRDS_PM_P2: + rx_pm_val = SERDES_IREG_FLD_LANEPCSPSTATE_RX_VAL_P2; + break; + case AL_SRDS_PM_P1: + rx_pm_val = SERDES_IREG_FLD_LANEPCSPSTATE_RX_VAL_P1; + break; + case AL_SRDS_PM_P0S: + rx_pm_val = SERDES_IREG_FLD_LANEPCSPSTATE_RX_VAL_P0S; + break; + case AL_SRDS_PM_P0: + rx_pm_val = SERDES_IREG_FLD_LANEPCSPSTATE_RX_VAL_P0; + break; + default: + al_err("%s: invalid rx power mode (%d)\n", __func__, rx_pm); + al_assert(0); + rx_pm_val = SERDES_IREG_FLD_LANEPCSPSTATE_RX_VAL_P0; + } + + switch (tx_pm) { + case AL_SRDS_PM_PD: + tx_pm_val = SERDES_IREG_FLD_LANEPCSPSTATE_TX_VAL_PD; + break; + case AL_SRDS_PM_P2: + tx_pm_val = SERDES_IREG_FLD_LANEPCSPSTATE_TX_VAL_P2; + break; + case AL_SRDS_PM_P1: + tx_pm_val = SERDES_IREG_FLD_LANEPCSPSTATE_TX_VAL_P1; + break; + case AL_SRDS_PM_P0S: + tx_pm_val = SERDES_IREG_FLD_LANEPCSPSTATE_TX_VAL_P0S; + break; + case AL_SRDS_PM_P0: + tx_pm_val = SERDES_IREG_FLD_LANEPCSPSTATE_TX_VAL_P0; + break; + default: + al_err("%s: invalid tx power mode (%d)\n", __func__, tx_pm); + al_assert(0); + tx_pm_val = SERDES_IREG_FLD_LANEPCSPSTATE_TX_VAL_P0; + } + + if (rx_pm == AL_SRDS_PM_PD) + _al_serdes_lane_rx_rate_change_sw_flow_dis(grp_info, lane); + + al_serdes_grp_reg_masked_write( + grp_info, + (enum al_serdes_reg_page)lane, + AL_SRDS_REG_TYPE_PMA, + SERDES_IREG_FLD_LANEPCSPSTATE_RX_REG_NUM, + SERDES_IREG_FLD_LANEPCSPSTATE_RX_MASK, + rx_pm_val); + + al_serdes_grp_reg_masked_write( + grp_info, + (enum al_serdes_reg_page)lane, + AL_SRDS_REG_TYPE_PMA, + SERDES_IREG_FLD_LANEPCSPSTATE_TX_REG_NUM, + SERDES_IREG_FLD_LANEPCSPSTATE_TX_MASK, + tx_pm_val); + + if (rx_pm != AL_SRDS_PM_PD) + _al_serdes_lane_rx_rate_change_sw_flow_en_cond(grp_info, lane); +} + +/******************************************************************************/ +/******************************************************************************/ +void al_serdes_pma_hard_reset_group( + struct al_serdes_obj *obj, + enum al_serdes_group grp, + al_bool enable) +{ + struct al_serdes_group_info *grp_info = &obj->grp_info[grp]; + + if (enable) + al_serdes_group_rx_rate_change_sw_flow_dis(grp_info); + + /* Enable Hard Reset Override */ + al_serdes_grp_reg_masked_write( + grp_info, + AL_SRDS_REG_PAGE_4_COMMON, + AL_SRDS_REG_TYPE_PMA, + SERDES_IREG_FLD_CMNCTLPOR_HARDRSTBYPASSEN_SYNTH_REG_NUM, + SERDES_IREG_FLD_CMNCTLPOR_HARDRSTBYPASSEN_SYNTH_MASK, + SERDES_IREG_FLD_CMNCTLPOR_HARDRSTBYPASSEN_SYNTH_VAL_REGS); + + /* Assert/Deassert Hard Reset Override */ + al_serdes_grp_reg_masked_write( + grp_info, + AL_SRDS_REG_PAGE_4_COMMON, + AL_SRDS_REG_TYPE_PMA, + SERDES_IREG_FLD_CMNCTLPOR_HARDRSTBYPASS_SYNTH_REG_NUM, + SERDES_IREG_FLD_CMNCTLPOR_HARDRSTBYPASS_SYNTH_MASK, + enable ? + SERDES_IREG_FLD_CMNCTLPOR_HARDRSTBYPASS_SYNTH_VAL_ASSERT : + SERDES_IREG_FLD_CMNCTLPOR_HARDRSTBYPASS_SYNTH_VAL_DEASSERT); + + if (!enable) + al_serdes_group_rx_rate_change_sw_flow_en_cond(grp_info); +} + +/******************************************************************************/ +/******************************************************************************/ +void al_serdes_pma_hard_reset_lane( + struct al_serdes_obj *obj, + enum al_serdes_group grp, + enum al_serdes_lane lane, + al_bool enable) +{ + struct al_serdes_group_info *grp_info = &obj->grp_info[grp]; + + if (enable) + _al_serdes_lane_rx_rate_change_sw_flow_dis(grp_info, lane); + + /* Enable Hard Reset Override */ + al_serdes_grp_reg_masked_write( + grp_info, + (enum al_serdes_reg_page)lane, + AL_SRDS_REG_TYPE_PMA, + SERDES_IREG_FLD_CMNCTLPOR_HARDRSTBYPASSEN_REG_NUM, + SERDES_IREG_FLD_CMNCTLPOR_HARDRSTBYPASSEN_MASK, + SERDES_IREG_FLD_CMNCTLPOR_HARDRSTBYPASSEN_VAL_REGS); + + /* Assert/Deassert Hard Reset Override */ + al_serdes_grp_reg_masked_write( + grp_info, + (enum al_serdes_reg_page)lane, + AL_SRDS_REG_TYPE_PMA, + SERDES_IREG_FLD_CMNCTLPOR_HARDRSTBYPASS_REG_NUM, + SERDES_IREG_FLD_CMNCTLPOR_HARDRSTBYPASS_MASK, + enable ? + SERDES_IREG_FLD_CMNCTLPOR_HARDRSTBYPASS_VAL_ASSERT : + SERDES_IREG_FLD_CMNCTLPOR_HARDRSTBYPASS_VAL_DEASSERT); + + if (!enable) + _al_serdes_lane_rx_rate_change_sw_flow_en_cond(grp_info, lane); +} + +/******************************************************************************/ +/******************************************************************************/ +#if (SERDES_IREG_FLD_LB_RX2TXUNTIMEDEN_REG_NUM !=\ + SERDES_IREG_FLD_LB_TX2RXBUFTIMEDEN_REG_NUM) ||\ + (SERDES_IREG_FLD_LB_TX2RXBUFTIMEDEN_REG_NUM !=\ + SERDES_IREG_FLD_LB_TX2RXIOTIMEDEN_REG_NUM) ||\ + (SERDES_IREG_FLD_LB_TX2RXIOTIMEDEN_REG_NUM !=\ + SERDES_IREG_FLD_LB_PARRX2TXTIMEDEN_REG_NUM) ||\ + (SERDES_IREG_FLD_LB_PARRX2TXTIMEDEN_REG_NUM !=\ + SERDES_IREG_FLD_LB_CDRCLK2TXEN_REG_NUM) +#error Wrong assumption +#endif + +void al_serdes_loopback_control( + struct al_serdes_obj *obj, + enum al_serdes_group grp, + enum al_serdes_lane lane, + enum al_serdes_lb_mode mode) +{ + struct al_serdes_group_info *grp_info = &obj->grp_info[grp]; + uint8_t val = 0; + + switch (mode) { + case AL_SRDS_LB_MODE_OFF: + break; + case AL_SRDS_LB_MODE_PMA_IO_UN_TIMED_RX_TO_TX: + val = SERDES_IREG_FLD_LB_RX2TXUNTIMEDEN; + break; + case AL_SRDS_LB_MODE_PMA_INTERNALLY_BUFFERED_SERIAL_TX_TO_RX: + val = SERDES_IREG_FLD_LB_TX2RXBUFTIMEDEN; + break; + case AL_SRDS_LB_MODE_PMA_SERIAL_TX_IO_TO_RX_IO: + val = SERDES_IREG_FLD_LB_TX2RXIOTIMEDEN; + break; + case AL_SRDS_LB_MODE_PMA_PARALLEL_RX_TO_TX: + val = SERDES_IREG_FLD_LB_PARRX2TXTIMEDEN | + SERDES_IREG_FLD_LB_CDRCLK2TXEN; + break; + default: + al_err("%s: invalid mode (%d)\n", __func__, mode); + al_assert(0); + } + + al_serdes_grp_reg_masked_write( + grp_info, + (enum al_serdes_reg_page)lane, + AL_SRDS_REG_TYPE_PMA, + SERDES_IREG_FLD_LB_RX2TXUNTIMEDEN_REG_NUM, + SERDES_IREG_FLD_LB_RX2TXUNTIMEDEN | + SERDES_IREG_FLD_LB_TX2RXBUFTIMEDEN | + SERDES_IREG_FLD_LB_TX2RXIOTIMEDEN | + SERDES_IREG_FLD_LB_PARRX2TXTIMEDEN | + SERDES_IREG_FLD_LB_CDRCLK2TXEN, + val); +} + +/******************************************************************************/ +/******************************************************************************/ +void al_serdes_bist_pattern_select( + struct al_serdes_obj *obj, + enum al_serdes_group grp, + enum al_serdes_bist_pattern pattern, + uint8_t *user_data) +{ + struct al_serdes_group_info *grp_info = &obj->grp_info[grp]; + uint8_t val = 0; + + switch (pattern) { + case AL_SRDS_BIST_PATTERN_USER: + al_assert(user_data); + val = SERDES_IREG_FLD_CMNPCSBIST_MODESEL_VAL_USER; + break; + case AL_SRDS_BIST_PATTERN_PRBS7: + val = SERDES_IREG_FLD_CMNPCSBIST_MODESEL_VAL_PRBS7; + break; + case AL_SRDS_BIST_PATTERN_PRBS23: + val = SERDES_IREG_FLD_CMNPCSBIST_MODESEL_VAL_PRBS23; + break; + case AL_SRDS_BIST_PATTERN_PRBS31: + val = SERDES_IREG_FLD_CMNPCSBIST_MODESEL_VAL_PRBS31; + break; + case AL_SRDS_BIST_PATTERN_CLK1010: + val = SERDES_IREG_FLD_CMNPCSBIST_MODESEL_VAL_CLK1010; + break; + default: + al_err("%s: invalid pattern (%d)\n", __func__, pattern); + al_assert(0); + } + + if (pattern == AL_SRDS_BIST_PATTERN_USER) { + int i; + + for (i = 0; i < SERDES_IREG_FLD_TX_BIST_PAT_NUM_BYTES; i++) + al_serdes_grp_reg_write( + grp_info, + AL_SRDS_REG_PAGE_4_COMMON, + AL_SRDS_REG_TYPE_PMA, + SERDES_IREG_FLD_TX_BIST_PAT_REG_NUM(i), + user_data[i]); + } + + al_serdes_grp_reg_masked_write( + grp_info, + AL_SRDS_REG_PAGE_4_COMMON, + AL_SRDS_REG_TYPE_PMA, + SERDES_IREG_FLD_CMNPCSBIST_MODESEL_REG_NUM, + SERDES_IREG_FLD_CMNPCSBIST_MODESEL_MASK, + val); +} + +/******************************************************************************/ +/******************************************************************************/ +void al_serdes_bist_tx_enable( + struct al_serdes_obj *obj, + enum al_serdes_group grp, + enum al_serdes_lane lane, + al_bool enable) +{ + struct al_serdes_group_info *grp_info = &obj->grp_info[grp]; + + al_serdes_grp_reg_masked_write( + grp_info, + (enum al_serdes_reg_page)lane, + AL_SRDS_REG_TYPE_PMA, + SERDES_IREG_FLD_PCSTXBIST_EN_REG_NUM, + SERDES_IREG_FLD_PCSTXBIST_EN, + enable ? SERDES_IREG_FLD_PCSTXBIST_EN : 0); +} + +/******************************************************************************/ +/******************************************************************************/ +void al_serdes_bist_tx_err_inject( + struct al_serdes_obj *obj, + enum al_serdes_group grp) +{ + struct al_serdes_group_info *grp_info = &obj->grp_info[grp]; + + al_serdes_grp_reg_masked_write( + grp_info, + AL_SRDS_REG_PAGE_4_COMMON, + AL_SRDS_REG_TYPE_PMA, + SERDES_IREG_FLD_TXBIST_BITERROR_EN_REG_NUM, + SERDES_IREG_FLD_TXBIST_BITERROR_EN, + SERDES_IREG_FLD_TXBIST_BITERROR_EN); + + al_serdes_grp_reg_masked_write( + grp_info, + AL_SRDS_REG_PAGE_4_COMMON, + AL_SRDS_REG_TYPE_PMA, + SERDES_IREG_FLD_TXBIST_BITERROR_EN_REG_NUM, + SERDES_IREG_FLD_TXBIST_BITERROR_EN, + 0); +} + +/******************************************************************************/ +/******************************************************************************/ +void al_serdes_bist_rx_enable( + struct al_serdes_obj *obj, + enum al_serdes_group grp, + enum al_serdes_lane lane, + al_bool enable) +{ + struct al_serdes_group_info *grp_info = &obj->grp_info[grp]; + + al_serdes_grp_reg_masked_write( + grp_info, + (enum al_serdes_reg_page)lane, + AL_SRDS_REG_TYPE_PMA, + SERDES_IREG_FLD_PCSRXBIST_EN_REG_NUM, + SERDES_IREG_FLD_PCSRXBIST_EN, + enable ? SERDES_IREG_FLD_PCSRXBIST_EN : 0); +} + +/******************************************************************************/ +/******************************************************************************/ +#if (SERDES_IREG_FLD_RXBIST_ERRCOUNT_OVERFLOW_REG_NUM !=\ + SERDES_IREG_FLD_RXBIST_RXLOCKED_REG_NUM) +#error Wrong assumption +#endif + +void al_serdes_bist_rx_status( + struct al_serdes_obj *obj, + enum al_serdes_group grp, + enum al_serdes_lane lane, + al_bool *is_locked, + al_bool *err_cnt_overflow, + uint16_t *err_cnt) +{ + struct al_serdes_group_info *grp_info = &obj->grp_info[grp]; + uint8_t status_reg_val; + uint16_t err_cnt_msb_reg_val; + uint16_t err_cnt_lsb_reg_val; + + status_reg_val = al_serdes_grp_reg_read( + grp_info, + (enum al_serdes_reg_page)lane, + AL_SRDS_REG_TYPE_PMA, + SERDES_IREG_FLD_RXBIST_RXLOCKED_REG_NUM); + + err_cnt_msb_reg_val = al_serdes_grp_reg_read( + grp_info, + (enum al_serdes_reg_page)lane, + AL_SRDS_REG_TYPE_PMA, + SERDES_IREG_FLD_RXBIST_ERRCOUNT_MSB_REG_NUM); + + err_cnt_lsb_reg_val = al_serdes_grp_reg_read( + grp_info, + (enum al_serdes_reg_page)lane, + AL_SRDS_REG_TYPE_PMA, + SERDES_IREG_FLD_RXBIST_ERRCOUNT_LSB_REG_NUM); + + *is_locked = + (status_reg_val & SERDES_IREG_FLD_RXBIST_RXLOCKED) ? + AL_TRUE : AL_FALSE; + + *err_cnt_overflow = + (status_reg_val & SERDES_IREG_FLD_RXBIST_ERRCOUNT_OVERFLOW) ? + AL_TRUE : AL_FALSE; + + *err_cnt = (err_cnt_msb_reg_val << 8) + err_cnt_lsb_reg_val; +} + +/******************************************************************************/ +/******************************************************************************/ +static inline uint8_t al_serdes_grp_reg_read( + struct al_serdes_group_info *grp_info, + enum al_serdes_reg_page page, + enum al_serdes_reg_type type, + uint16_t offset) +{ + al_reg_write32( + &grp_info->regs_base->gen.reg_addr, + SRDS_CORE_REG_ADDR(page, type, offset)); + + return al_reg_read32(&grp_info->regs_base->gen.reg_data); +} + +static inline uint8_t al_serdes_grp_lane_read( + struct al_serdes_group_info *grp_info, + enum al_serdes_lane page, + enum al_serdes_reg_type type, + uint16_t offset) +{ + return al_serdes_grp_reg_read(grp_info, (enum al_serdes_reg_page)page, + type, offset); +} + +/******************************************************************************/ +/******************************************************************************/ +static inline void al_serdes_grp_reg_write( + struct al_serdes_group_info *grp_info, + enum al_serdes_reg_page page, + enum al_serdes_reg_type type, + uint16_t offset, + uint8_t data) +{ + al_reg_write32( + &grp_info->regs_base->gen.reg_addr, + SRDS_CORE_REG_ADDR(page, type, offset)); + + al_reg_write32(&grp_info->regs_base->gen.reg_data, data); +} + + +static inline void al_serdes_grp_lane_write( + struct al_serdes_group_info *grp_info, + enum al_serdes_lane lane, + enum al_serdes_reg_type type, + uint16_t offset, + uint8_t data) +{ + al_serdes_grp_reg_write(grp_info, (enum al_serdes_reg_page)lane, + type, offset, data); +} + +/******************************************************************************/ +/******************************************************************************/ +static inline void al_serdes_ns_delay(int cnt) +{ + al_udelay((cnt + 999) / 1000); +} + +/******************************************************************************/ +/******************************************************************************/ +static inline void al_serdes_grp_reg_masked_write( + struct al_serdes_group_info *grp_info, + enum al_serdes_reg_page page, + enum al_serdes_reg_type type, + uint16_t offset, + uint8_t mask, + uint8_t data) +{ + uint8_t val; + enum al_serdes_reg_page start_page = page; + enum al_serdes_reg_page end_page = page; + enum al_serdes_reg_page iter_page; + + if (page == AL_SRDS_REG_PAGE_0123_LANES_0123) { + start_page = AL_SRDS_REG_PAGE_0_LANE_0; + end_page = AL_SRDS_REG_PAGE_3_LANE_3; + } + + for(iter_page = start_page; iter_page <= end_page; ++iter_page) { + val = al_serdes_grp_reg_read(grp_info, iter_page, type, offset); + val &= ~mask; + val |= data; + al_serdes_grp_reg_write(grp_info, iter_page, type, offset, val); + } +} + +static inline void al_serdes_grp_lane_masked_write( + struct al_serdes_group_info *grp_info, + enum al_serdes_lane lane, + enum al_serdes_reg_type type, + uint16_t offset, + uint8_t mask, + uint8_t data) +{ + al_serdes_grp_reg_masked_write(grp_info, (enum al_serdes_reg_page)lane, + type, offset, mask, data); +} + +/******************************************************************************/ +/******************************************************************************/ +static void _al_serdes_lane_rx_rate_change_sw_flow_dis( + struct al_serdes_group_info *grp_info, + enum al_serdes_lane lane) +{ + al_bool lane_sw_flow_enabled; + + al_assert(lane != AL_SRDS_LANES_0123); + + lane_sw_flow_enabled = + (al_serdes_grp_reg_read(grp_info, (enum al_serdes_reg_page)lane, + AL_SRDS_REG_TYPE_PMA, 201) == 0xfc) && + (al_serdes_grp_reg_read(grp_info, (enum al_serdes_reg_page)lane, + AL_SRDS_REG_TYPE_PMA, 202) == 0xff) && + (al_serdes_grp_reg_read(grp_info, (enum al_serdes_reg_page)lane, + AL_SRDS_REG_TYPE_PMA, 203) == 0xff) && + (al_serdes_grp_reg_read(grp_info, (enum al_serdes_reg_page)lane, + AL_SRDS_REG_TYPE_PMA, 204) == 0xff) && + (al_serdes_grp_reg_read(grp_info, (enum al_serdes_reg_page)lane, + AL_SRDS_REG_TYPE_PMA, 205) == 0xff); + + /** + * Disable the Rx rate change software flow by clearing bit 7 of lane PMA register 205 + * (RSTPDOVR_RX_OVREN) + */ + if (lane_sw_flow_enabled) { + al_dbg("%s(%d): actually disabling\n", __func__, lane); + al_serdes_grp_reg_masked_write(grp_info, (enum al_serdes_reg_page)lane, + AL_SRDS_REG_TYPE_PMA, 205, 0x80, 0x00); + } +} + +/******************************************************************************/ +/******************************************************************************/ +static void al_serdes_group_rx_rate_change_sw_flow_dis( + struct al_serdes_group_info *grp_info) +{ + int lane; + + for (lane = AL_SRDS_LANE_0; lane < AL_SRDS_NUM_LANES; lane++) + _al_serdes_lane_rx_rate_change_sw_flow_dis(grp_info, lane); +} + +/******************************************************************************/ +/******************************************************************************/ +static void _al_serdes_lane_rx_rate_change_sw_flow_en_cond( + struct al_serdes_group_info *grp_info, + enum al_serdes_lane lane) +{ + al_bool lane_sw_flow_almost_enabled; + al_bool group_reset_enabled; + al_bool lane_reset_enabled; + al_bool group_pd_enabled; + al_bool lane_pd_enabled; + + al_assert(lane != AL_SRDS_LANES_0123); + + lane_sw_flow_almost_enabled = + (al_serdes_grp_reg_read(grp_info, (enum al_serdes_reg_page)lane, + AL_SRDS_REG_TYPE_PMA, 201) == 0xfc) && + (al_serdes_grp_reg_read(grp_info, (enum al_serdes_reg_page)lane, + AL_SRDS_REG_TYPE_PMA, 202) == 0xff) && + (al_serdes_grp_reg_read(grp_info, (enum al_serdes_reg_page)lane, + AL_SRDS_REG_TYPE_PMA, 203) == 0xff) && + (al_serdes_grp_reg_read(grp_info, (enum al_serdes_reg_page)lane, + AL_SRDS_REG_TYPE_PMA, 204) == 0xff) && + (al_serdes_grp_reg_read(grp_info, (enum al_serdes_reg_page)lane, + AL_SRDS_REG_TYPE_PMA, 205) == 0x7f); + + group_reset_enabled = + ((al_serdes_grp_reg_read( + grp_info, AL_SRDS_REG_PAGE_4_COMMON, AL_SRDS_REG_TYPE_PMA, + SERDES_IREG_FLD_CMNCTLPOR_HARDRSTBYPASSEN_SYNTH_REG_NUM) & + SERDES_IREG_FLD_CMNCTLPOR_HARDRSTBYPASSEN_SYNTH_MASK) == + SERDES_IREG_FLD_CMNCTLPOR_HARDRSTBYPASSEN_SYNTH_VAL_REGS) && + ((al_serdes_grp_reg_read( + grp_info, AL_SRDS_REG_PAGE_4_COMMON, AL_SRDS_REG_TYPE_PMA, + SERDES_IREG_FLD_CMNCTLPOR_HARDRSTBYPASS_SYNTH_REG_NUM) & + SERDES_IREG_FLD_CMNCTLPOR_HARDRSTBYPASS_SYNTH_MASK) == + SERDES_IREG_FLD_CMNCTLPOR_HARDRSTBYPASS_SYNTH_VAL_ASSERT); + + lane_reset_enabled = + ((al_serdes_grp_reg_read( + grp_info, (enum al_serdes_reg_page)lane, AL_SRDS_REG_TYPE_PMA, + SERDES_IREG_FLD_CMNCTLPOR_HARDRSTBYPASSEN_REG_NUM) & + SERDES_IREG_FLD_CMNCTLPOR_HARDRSTBYPASSEN_MASK) == + SERDES_IREG_FLD_CMNCTLPOR_HARDRSTBYPASSEN_VAL_REGS) && + ((al_serdes_grp_reg_read( + grp_info, (enum al_serdes_reg_page)lane, AL_SRDS_REG_TYPE_PMA, + SERDES_IREG_FLD_CMNCTLPOR_HARDRSTBYPASS_REG_NUM) & + SERDES_IREG_FLD_CMNCTLPOR_HARDRSTBYPASS_MASK) == + SERDES_IREG_FLD_CMNCTLPOR_HARDRSTBYPASS_VAL_ASSERT); + + group_pd_enabled = + (al_serdes_grp_reg_read( + grp_info, AL_SRDS_REG_PAGE_4_COMMON, AL_SRDS_REG_TYPE_PMA, + SERDES_IREG_FLD_CMNPCSPSTATE_SYNTH_REG_NUM) & + SERDES_IREG_FLD_CMNPCSPSTATE_SYNTH_MASK) == + SERDES_IREG_FLD_CMNPCSPSTATE_SYNTH_VAL_PD; + + lane_pd_enabled = + (al_serdes_grp_reg_read( + grp_info, (enum al_serdes_reg_page)lane, AL_SRDS_REG_TYPE_PMA, + SERDES_IREG_FLD_LANEPCSPSTATE_RX_REG_NUM) & + SERDES_IREG_FLD_LANEPCSPSTATE_RX_MASK) == + SERDES_IREG_FLD_LANEPCSPSTATE_RX_VAL_PD; + + /** + * Enable the Rx rate change software flow by setting bit 7 of lane PMA register 205 + * (RSTPDOVR_RX_OVREN) + */ + if (lane_sw_flow_almost_enabled && !group_reset_enabled && !lane_reset_enabled && + !group_pd_enabled && !lane_pd_enabled) { + al_dbg("%s(%d): actually enabling\n", __func__, lane); + + al_serdes_ns_delay(500); + al_serdes_grp_reg_masked_write(grp_info, (enum al_serdes_reg_page)lane, + AL_SRDS_REG_TYPE_PMA, 205, 0x80, 0x80); + } +} + +/******************************************************************************/ +/******************************************************************************/ +static void al_serdes_group_rx_rate_change_sw_flow_en_cond( + struct al_serdes_group_info *grp_info) +{ + int lane; + + for (lane = AL_SRDS_LANE_0; lane < AL_SRDS_NUM_LANES; lane++) + _al_serdes_lane_rx_rate_change_sw_flow_en_cond(grp_info, lane); +} + +/******************************************************************************/ +/******************************************************************************/ +int al_serdes_eye_measure_run( + struct al_serdes_obj *obj, + enum al_serdes_group grp, + enum al_serdes_lane lane, + uint32_t timeout, + unsigned int *value) +{ + uint32_t reg = 0; + uint32_t i; + struct serdes_lane *lane_regs; + + lane_regs = &obj->grp_info[grp].regs_base->lane[lane]; + + al_reg_write32(&lane_regs->ictl_multi_rxeq, + SERDES_LANE_ICTL_MULTI_RXEQ_START_L_A); + + for (i = 0 ; i < timeout ; i++) { + reg = al_reg_read32(&lane_regs->octl_multi); + + if (reg & SERDES_LANE_OCTL_MULTI_RXEQ_DONE_L_A) + break; + + al_msleep(10); + } + + if (i == timeout) { + al_err("%s: measure eye failed on timeout\n", __func__); + return -ETIMEDOUT; + } + + *value = al_reg_read32(&lane_regs->odat_multi_rxeq); + + al_reg_write32(&lane_regs->ictl_multi_rxeq, 0); + + return 0; +} + +/******************************************************************************/ +/******************************************************************************/ +int al_serdes_eye_diag_sample( + struct al_serdes_obj *obj, + enum al_serdes_group grp, + enum al_serdes_lane lane, + unsigned int x, + int y, + unsigned int timeout, + unsigned int *value) +{ + enum al_serdes_reg_page page = (enum al_serdes_reg_page)lane; + struct al_serdes_group_info *grp_info; + uint32_t i; + uint8_t sample_count_orig_msb; + uint8_t sample_count_orig_lsb; + + al_assert(obj); + al_assert(((int)grp) >= AL_SRDS_GRP_A); + al_assert(((int)grp) <= AL_SRDS_GRP_D); + al_assert(((int)page) >= AL_SRDS_REG_PAGE_0_LANE_0); + al_assert(((int)page) <= AL_SRDS_REG_PAGE_0123_LANES_0123); + + grp_info = &obj->grp_info[grp]; + + /* Obtain sample count by reading RXCALROAMEYEMEAS_COUNT */ + sample_count_orig_msb = al_serdes_grp_reg_read(grp_info, + AL_SRDS_REG_PAGE_4_COMMON, AL_SRDS_REG_TYPE_PMA, + SERDES_IREG_FLD_EYE_DIAG_SAMPLE_CNT_MSB_REG_NUM); + sample_count_orig_lsb = al_serdes_grp_reg_read(grp_info, + AL_SRDS_REG_PAGE_4_COMMON, AL_SRDS_REG_TYPE_PMA, + SERDES_IREG_FLD_EYE_DIAG_SAMPLE_CNT_LSB_REG_NUM); + + /* Set sample count to ~100000 samples */ + al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON, + AL_SRDS_REG_TYPE_PMA, + SERDES_IREG_FLD_EYE_DIAG_SAMPLE_CNT_MSB_REG_NUM, 0x13); + al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON, + AL_SRDS_REG_TYPE_PMA, + SERDES_IREG_FLD_EYE_DIAG_SAMPLE_CNT_LSB_REG_NUM, 0x88); + + /* BER Contour Overwrite */ + al_serdes_grp_reg_masked_write(grp_info, page, AL_SRDS_REG_TYPE_PMA, + SERDES_IREG_FLD_RXCALROAMEYEMEASIN_LOCWREN_REG_NUM, + SERDES_IREG_FLD_RXCALROAMEYEMEASIN_LOCWREN, + 0); + al_serdes_grp_reg_masked_write(grp_info, page, AL_SRDS_REG_TYPE_PMA, + SERDES_IREG_FLD_RXCALROAMXADJUST_LOCWREN_REG_NUM, + SERDES_IREG_FLD_RXCALROAMXADJUST_LOCWREN, + 0); + al_serdes_grp_reg_masked_write(grp_info, page, AL_SRDS_REG_TYPE_PMA, + SERDES_IREG_FLD_RXCALROAMYADJUST_LOCWREN_REG_NUM, + SERDES_IREG_FLD_RXCALROAMYADJUST_LOCWREN, + 0); + + /* RXROAM_XORBITSEL = 0x1 or 0x0 */ + al_serdes_grp_reg_masked_write(grp_info, page, AL_SRDS_REG_TYPE_PMA, + SERDES_IREG_FLD_RXROAM_XORBITSEL_REG_NUM, + SERDES_IREG_FLD_RXROAM_XORBITSEL, + SERDES_IREG_FLD_RXROAM_XORBITSEL_2ND); + + /* Set X */ + al_serdes_grp_reg_write(grp_info, page, AL_SRDS_REG_TYPE_PMA, + SERDES_IREG_FLD_RXCALROAMXADJUST_REG_NUM, x); + + /* Set Y */ + al_serdes_grp_reg_write(grp_info, page, AL_SRDS_REG_TYPE_PMA, + SERDES_IREG_FLD_RXCALROAMYADJUST_REG_NUM, + y < 32 ? 31 - y : y + 1); + + /* Start Measurement by setting RXCALROAMEYEMEASIN_CYCLEEN = 0x1 */ + al_serdes_grp_reg_masked_write(grp_info, page, AL_SRDS_REG_TYPE_PMA, + SERDES_IREG_FLD_RXCALROAMEYEMEASIN_CYCLEEN_REG_NUM, + SERDES_IREG_FLD_RXCALROAMEYEMEASIN_CYCLEEN_START, + SERDES_IREG_FLD_RXCALROAMEYEMEASIN_CYCLEEN_START); + + /* Check RXCALROAMEYEMEASDONE Signal (Polling Until 0x1) */ + for (i = 0 ; i < timeout ; i++) { + if (al_serdes_grp_reg_read(grp_info, page, AL_SRDS_REG_TYPE_PMA, + SERDES_IREG_FLD_RXCALROAMEYEMEASDONE_REG_NUM) & + SERDES_IREG_FLD_RXCALROAMEYEMEASDONE) + break; + al_udelay(1); + } + if (i == timeout) { + al_err("%s: eye diagram sampling timed out!\n", __func__); + return -ETIMEDOUT; + } + + /* Stop Measurement by setting RXCALROAMEYEMEASIN_CYCLEEN = 0x0 */ + al_serdes_grp_reg_masked_write(grp_info, page, AL_SRDS_REG_TYPE_PMA, + SERDES_IREG_FLD_RXCALROAMEYEMEASIN_CYCLEEN_REG_NUM, + SERDES_IREG_FLD_RXCALROAMEYEMEASIN_CYCLEEN_START, + 0); + + /* Obtain Error Counts by reading RXCALROAMEYEMEAS_ACC */ + *value = ((unsigned int)al_serdes_grp_reg_read(grp_info, page, + AL_SRDS_REG_TYPE_PMA, + SERDES_IREG_FLD_RXCALROAMEYEMEAS_ACC_MSB_REG_NUM)) << 8 | + al_serdes_grp_reg_read(grp_info, page, AL_SRDS_REG_TYPE_PMA, + SERDES_IREG_FLD_RXCALROAMEYEMEAS_ACC_LSB_REG_NUM); + + /* BER Contour Overwrite */ + al_serdes_grp_reg_masked_write(grp_info, page, AL_SRDS_REG_TYPE_PMA, + SERDES_IREG_FLD_RXCALROAMEYEMEASIN_LOCWREN_REG_NUM, + SERDES_IREG_FLD_RXCALROAMEYEMEASIN_LOCWREN, + SERDES_IREG_FLD_RXCALROAMEYEMEASIN_LOCWREN); + al_serdes_grp_reg_masked_write(grp_info, page, AL_SRDS_REG_TYPE_PMA, + SERDES_IREG_FLD_RXCALROAMXADJUST_LOCWREN_REG_NUM, + SERDES_IREG_FLD_RXCALROAMXADJUST_LOCWREN, + SERDES_IREG_FLD_RXCALROAMXADJUST_LOCWREN); + al_serdes_grp_reg_masked_write(grp_info, page, AL_SRDS_REG_TYPE_PMA, + SERDES_IREG_FLD_RXCALROAMYADJUST_LOCWREN_REG_NUM, + SERDES_IREG_FLD_RXCALROAMYADJUST_LOCWREN, + SERDES_IREG_FLD_RXCALROAMYADJUST_LOCWREN); + + /* Restore sample count */ + al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON, + AL_SRDS_REG_TYPE_PMA, + SERDES_IREG_FLD_EYE_DIAG_SAMPLE_CNT_MSB_REG_NUM, + sample_count_orig_msb); + al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON, + AL_SRDS_REG_TYPE_PMA, + SERDES_IREG_FLD_EYE_DIAG_SAMPLE_CNT_LSB_REG_NUM, + sample_count_orig_lsb); + + return 0; +} + +/******************************************************************************/ +/******************************************************************************/ +static void al_serdes_tx_deemph_set( + struct al_serdes_obj *obj, + enum al_serdes_group grp, + enum al_serdes_lane lane, + uint32_t c_zero, + uint32_t c_plus_1, + uint32_t c_minus_1) +{ + al_serdes_grp_lane_masked_write( + &obj->grp_info[grp], + lane, + AL_SRDS_REG_TYPE_PMA, + SERDES_IREG_TX_DRV_1_REG_NUM, + SERDES_IREG_TX_DRV_1_LEVN_MASK, + ((c_zero + c_plus_1 + c_minus_1) + << SERDES_IREG_TX_DRV_1_LEVN_SHIFT)); + + al_serdes_grp_lane_masked_write( + &obj->grp_info[grp], + lane, + AL_SRDS_REG_TYPE_PMA, + SERDES_IREG_TX_DRV_2_REG_NUM, + SERDES_IREG_TX_DRV_2_LEVNM1_MASK, + (c_plus_1 << SERDES_IREG_TX_DRV_2_LEVNM1_SHIFT)); + + al_serdes_grp_lane_masked_write( + &obj->grp_info[grp], + lane, + AL_SRDS_REG_TYPE_PMA, + SERDES_IREG_TX_DRV_3_REG_NUM, + SERDES_IREG_TX_DRV_3_LEVNP1_MASK, + (c_minus_1 << SERDES_IREG_TX_DRV_3_LEVNP1_SHIFT)); +} + +static void al_serdes_tx_deemph_get( + struct al_serdes_obj *obj, + enum al_serdes_group grp, + enum al_serdes_lane lane, + uint32_t *c_zero, + uint32_t *c_plus_1, + uint32_t *c_minus_1) +{ + uint32_t reg = 0; + + reg = al_serdes_grp_lane_read( + &obj->grp_info[grp], + lane, + AL_SRDS_REG_TYPE_PMA, + SERDES_IREG_TX_DRV_2_REG_NUM); + + *c_plus_1 = ((reg & SERDES_IREG_TX_DRV_2_LEVNM1_MASK) >> + SERDES_IREG_TX_DRV_2_LEVNM1_SHIFT); + + reg = al_serdes_grp_lane_read( + &obj->grp_info[grp], + lane, + AL_SRDS_REG_TYPE_PMA, + SERDES_IREG_TX_DRV_3_REG_NUM); + + *c_minus_1 = ((reg & SERDES_IREG_TX_DRV_3_LEVNP1_MASK) >> + SERDES_IREG_TX_DRV_3_LEVNP1_SHIFT); + + reg = al_serdes_grp_lane_read( + &obj->grp_info[grp], + lane, + AL_SRDS_REG_TYPE_PMA, + SERDES_IREG_TX_DRV_1_REG_NUM); + + *c_zero = (((reg & SERDES_IREG_TX_DRV_1_LEVN_MASK) >> + SERDES_IREG_TX_DRV_1_LEVN_SHIFT) - *c_plus_1 - *c_minus_1); +} + +al_bool al_serdes_tx_deemph_inc( + struct al_serdes_obj *obj, + enum al_serdes_group grp, + enum al_serdes_lane lane, + enum al_serdes_tx_deemph_param param) +{ + al_bool ret = AL_TRUE; + uint32_t c0; + uint32_t c1; + uint32_t c_1; + + al_serdes_tx_deemph_get(obj, grp, lane, &c0, &c1, &c_1); + + al_dbg("%s: current txdeemph: c0 = 0x%x c1 = 0x%x c-1 = 0x%x\n", + __func__, c0, c1, c_1); + + switch (param) { + case AL_SERDES_TX_DEEMP_C_ZERO: + + if (c0 == AL_SERDES_TX_DEEMPH_C_ZERO_MAX_VAL) + return AL_FALSE; + + c0++; + + break; + case AL_SERDES_TX_DEEMP_C_PLUS: + + if (c1 == AL_SERDES_TX_DEEMPH_C_PLUS_MAX_VAL) + return AL_FALSE; + + c1++; + + break; + case AL_SERDES_TX_DEEMP_C_MINUS: + + if (c_1 == AL_SERDES_TX_DEEMPH_C_MINUS_MAX_VAL) + return AL_FALSE; + + c_1++; + + break; + } + + if ((c0 + c1 + c_1) > AL_SERDES_TX_DEEMPH_SUM_MAX) { + al_dbg("%s: sum of all tx de-emphasis over the max limit\n", + __func__); + + return AL_FALSE; + } + + al_dbg("%s: new txdeemph: c0 = 0x%x c1 = 0x%x c-1 = 0x%x\n", + __func__, c0, c1, c_1); + + al_serdes_tx_deemph_set(obj, grp, lane, c0, c1, c_1); + + return ret; +} + +al_bool al_serdes_tx_deemph_dec( + struct al_serdes_obj *obj, + enum al_serdes_group grp, + enum al_serdes_lane lane, + enum al_serdes_tx_deemph_param param) +{ + al_bool ret = AL_TRUE; + uint32_t c0; + uint32_t c1; + uint32_t c_1; + + al_serdes_tx_deemph_get(obj, grp, lane, &c0, &c1, &c_1); + + al_dbg("%s: current txdeemph: c0 = 0x%x c1 = 0x%x c-1 = 0x%x\n", + __func__, c0, c1, c_1); + + switch (param) { + case AL_SERDES_TX_DEEMP_C_ZERO: + + if (c0 == AL_SERDES_TX_DEEMPH_C_ZERO_MIN_VAL) + return AL_FALSE; + + c0--; + + break; + case AL_SERDES_TX_DEEMP_C_PLUS: + + if (c1 == AL_SERDES_TX_DEEMPH_C_PLUS_MIN_VAL) + return AL_FALSE; + + c1--; + + break; + case AL_SERDES_TX_DEEMP_C_MINUS: + + if (c_1 == AL_SERDES_TX_DEEMPH_C_MINUS_MIN_VAL) + return AL_FALSE; + + c_1--; + + break; + } + + al_dbg("%s: new txdeemph: c0 = 0x%x c1 = 0x%x c-1 = 0x%x\n", + __func__, c0, c1, c_1); + + al_serdes_tx_deemph_set(obj, grp, lane, c0, c1, c_1); + + return ret; +} + +void al_serdes_tx_deemph_preset( + struct al_serdes_obj *obj, + enum al_serdes_group grp, + enum al_serdes_lane lane) +{ + uint32_t c0; + uint32_t c1; + uint32_t c_1; + + c0 = AL_SERDES_TX_DEEMPH_C_ZERO_PRESET; + + c1 = AL_SERDES_TX_DEEMPH_C_PLUS_PRESET; + + c_1 = AL_SERDES_TX_DEEMPH_C_MINUS_PRESET; + + al_dbg("preset: new txdeemph: c0 = 0x%x c1 = 0x%x c-1 = 0x%x\n", + c0, c1, c_1); + + al_serdes_tx_deemph_set(obj, grp, lane, c0, c1, c_1); +} + +al_bool al_serdes_signal_is_detected( + struct al_serdes_obj *obj, + enum al_serdes_group grp, + enum al_serdes_lane lane) +{ + uint32_t reg = 0; + + reg = al_serdes_grp_lane_read( + &obj->grp_info[grp], + lane, + AL_SRDS_REG_TYPE_PMA, + SERDES_IREG_FLD_RXRANDET_REG_NUM); + + return ((reg & SERDES_IREG_FLD_RXRANDET_STAT) ? AL_TRUE : AL_FALSE); +} + +void al_serdes_tx_advanced_params_set(struct al_serdes_obj *obj, + enum al_serdes_group grp, + enum al_serdes_lane lane, + struct al_serdes_adv_tx_params *params) +{ + uint8_t reg = 0; + + if(!params->override) { + al_serdes_grp_lane_masked_write(&obj->grp_info[grp], + lane, + AL_SRDS_REG_TYPE_PMA, + SERDES_IREG_FLD_TX_DRV_OVERRIDE_EN_REG_NUM, + SERDES_IREG_FLD_TX_DRV_OVERRIDE_EN, + SERDES_IREG_FLD_TX_DRV_OVERRIDE_EN); + + return; + } + + al_serdes_grp_lane_masked_write(&obj->grp_info[grp], + lane, + AL_SRDS_REG_TYPE_PMA, + SERDES_IREG_FLD_TX_DRV_OVERRIDE_EN_REG_NUM, + SERDES_IREG_FLD_TX_DRV_OVERRIDE_EN, + 0); + + AL_REG_FIELD_SET(reg, + SERDES_IREG_TX_DRV_1_HLEV_MASK, + SERDES_IREG_TX_DRV_1_HLEV_SHIFT, + params->amp); + + AL_REG_FIELD_SET(reg, + SERDES_IREG_TX_DRV_1_LEVN_MASK, + SERDES_IREG_TX_DRV_1_LEVN_SHIFT, + params->total_driver_units); + + al_serdes_grp_lane_write(&obj->grp_info[grp], + lane, + AL_SRDS_REG_TYPE_PMA, + SERDES_IREG_TX_DRV_1_REG_NUM, + reg); + + reg = 0; + AL_REG_FIELD_SET(reg, + SERDES_IREG_TX_DRV_2_LEVNM1_MASK, + SERDES_IREG_TX_DRV_2_LEVNM1_SHIFT, + params->c_plus_1); + + AL_REG_FIELD_SET(reg, + SERDES_IREG_TX_DRV_2_LEVNM2_MASK, + SERDES_IREG_TX_DRV_2_LEVNM2_SHIFT, + params->c_plus_2); + + al_serdes_grp_lane_write(&obj->grp_info[grp], + lane, + AL_SRDS_REG_TYPE_PMA, + SERDES_IREG_TX_DRV_2_REG_NUM, + reg); + + reg = 0; + AL_REG_FIELD_SET(reg, + SERDES_IREG_TX_DRV_3_LEVNP1_MASK, + SERDES_IREG_TX_DRV_3_LEVNP1_SHIFT, + params->c_minus_1); + + AL_REG_FIELD_SET(reg, + SERDES_IREG_TX_DRV_3_SLEW_MASK, + SERDES_IREG_TX_DRV_3_SLEW_SHIFT, + params->slew_rate); + + al_serdes_grp_lane_write(&obj->grp_info[grp], + lane, + AL_SRDS_REG_TYPE_PMA, + SERDES_IREG_TX_DRV_3_REG_NUM, + reg); + +} + +void al_serdes_tx_advanced_params_get(struct al_serdes_obj *obj, + enum al_serdes_group grp, + enum al_serdes_lane lane, + struct al_serdes_adv_tx_params *tx_params) +{ + uint8_t reg_val = 0; + + al_serdes_lane_read(obj, grp, lane, AL_SRDS_REG_TYPE_PMA, + SERDES_IREG_TX_DRV_1_REG_NUM, + ®_val); + tx_params->amp = (reg_val & SERDES_IREG_TX_DRV_1_HLEV_MASK) >> + SERDES_IREG_TX_DRV_1_HLEV_SHIFT; + tx_params->total_driver_units = (reg_val & + SERDES_IREG_TX_DRV_1_LEVN_MASK) >> + SERDES_IREG_TX_DRV_1_LEVN_SHIFT; + + al_serdes_lane_read(obj, grp, lane, AL_SRDS_REG_TYPE_PMA, + SERDES_IREG_TX_DRV_2_REG_NUM, + ®_val); + tx_params->c_plus_1 = (reg_val & SERDES_IREG_TX_DRV_2_LEVNM1_MASK) >> + SERDES_IREG_TX_DRV_2_LEVNM1_SHIFT; + tx_params->c_plus_2 = (reg_val & SERDES_IREG_TX_DRV_2_LEVNM2_MASK) >> + SERDES_IREG_TX_DRV_2_LEVNM2_SHIFT; + + al_serdes_lane_read(obj, grp, lane, AL_SRDS_REG_TYPE_PMA, + SERDES_IREG_TX_DRV_3_REG_NUM, + ®_val); + tx_params->c_minus_1 = (reg_val & SERDES_IREG_TX_DRV_3_LEVNP1_MASK) >> + SERDES_IREG_TX_DRV_3_LEVNP1_SHIFT; + tx_params->slew_rate = (reg_val & SERDES_IREG_TX_DRV_3_SLEW_MASK) >> + SERDES_IREG_TX_DRV_3_SLEW_SHIFT; + + al_serdes_lane_read(obj, grp, lane, AL_SRDS_REG_TYPE_PMA, + SERDES_IREG_FLD_TX_DRV_OVERRIDE_EN_REG_NUM, + ®_val); + tx_params->override = ((reg_val & SERDES_IREG_FLD_TX_DRV_OVERRIDE_EN) == 0); +} + + +void al_serdes_rx_advanced_params_set(struct al_serdes_obj *obj, + enum al_serdes_group grp, + enum al_serdes_lane lane, + struct al_serdes_adv_rx_params *params) +{ + uint8_t reg = 0; + + if(!params->override) { + al_serdes_grp_lane_masked_write(&obj->grp_info[grp], + lane, + AL_SRDS_REG_TYPE_PMA, + SERDES_IREG_FLD_RX_DRV_OVERRIDE_EN_REG_NUM, + SERDES_IREG_FLD_RX_DRV_OVERRIDE_EN, + SERDES_IREG_FLD_RX_DRV_OVERRIDE_EN); + + return; + } + + al_serdes_grp_lane_masked_write(&obj->grp_info[grp], + lane, + AL_SRDS_REG_TYPE_PMA, + SERDES_IREG_FLD_RX_DRV_OVERRIDE_EN_REG_NUM, + SERDES_IREG_FLD_RX_DRV_OVERRIDE_EN, + 0); + + AL_REG_FIELD_SET(reg, + SERDES_IREG_RX_CALEQ_1_DCGAIN_MASK, + SERDES_IREG_RX_CALEQ_1_DCGAIN_SHIFT, + params->dcgain); + + AL_REG_FIELD_SET(reg, + SERDES_IREG_RX_CALEQ_1_DFEPSTAP3DB_MASK, + SERDES_IREG_RX_CALEQ_1_DFEPSTAP3DB_SHIFT, + params->dfe_3db_freq); + + al_serdes_grp_lane_write(&obj->grp_info[grp], + lane, + AL_SRDS_REG_TYPE_PMA, + SERDES_IREG_RX_CALEQ_1_REG_NUM, + reg); + + reg = 0; + AL_REG_FIELD_SET(reg, + SERDES_IREG_RX_CALEQ_2_DFEPSTAPGAIN_MASK, + SERDES_IREG_RX_CALEQ_2_DFEPSTAPGAIN_SHIFT, + params->dfe_gain); + + AL_REG_FIELD_SET(reg, + SERDES_IREG_RX_CALEQ_2_DFETAP1GAIN_MASK, + SERDES_IREG_RX_CALEQ_2_DFETAP1GAIN_SHIFT, + params->dfe_first_tap_ctrl); + + al_serdes_grp_lane_write(&obj->grp_info[grp], + lane, + AL_SRDS_REG_TYPE_PMA, + SERDES_IREG_RX_CALEQ_2_REG_NUM, + reg); + + reg = 0; + AL_REG_FIELD_SET(reg, + SERDES_IREG_RX_CALEQ_3_DFETAP2GAIN_MASK, + SERDES_IREG_RX_CALEQ_3_DFETAP2GAIN_SHIFT, + params->dfe_secound_tap_ctrl); + + AL_REG_FIELD_SET(reg, + SERDES_IREG_RX_CALEQ_3_DFETAP3GAIN_MASK, + SERDES_IREG_RX_CALEQ_3_DFETAP3GAIN_SHIFT, + params->dfe_third_tap_ctrl); + + al_serdes_grp_lane_write(&obj->grp_info[grp], + lane, + AL_SRDS_REG_TYPE_PMA, + SERDES_IREG_RX_CALEQ_3_REG_NUM, + reg); + + reg = 0; + AL_REG_FIELD_SET(reg, + SERDES_IREG_RX_CALEQ_4_DFETAP4GAIN_MASK, + SERDES_IREG_RX_CALEQ_4_DFETAP4GAIN_SHIFT, + params->dfe_fourth_tap_ctrl); + + AL_REG_FIELD_SET(reg, + SERDES_IREG_RX_CALEQ_4_LOFREQAGCGAIN_MASK, + SERDES_IREG_RX_CALEQ_4_LOFREQAGCGAIN_SHIFT, + params->low_freq_agc_gain); + + al_serdes_grp_lane_write(&obj->grp_info[grp], + lane, + AL_SRDS_REG_TYPE_PMA, + SERDES_IREG_RX_CALEQ_4_REG_NUM, + reg); + + reg = 0; + AL_REG_FIELD_SET(reg, + SERDES_IREG_RX_CALEQ_5_PRECAL_CODE_SEL_MASK, + SERDES_IREG_RX_CALEQ_5_PRECAL_CODE_SEL_SHIFT, + params->precal_code_sel); + + AL_REG_FIELD_SET(reg, + SERDES_IREG_RX_CALEQ_5_HIFREQAGCCAP_MASK, + SERDES_IREG_RX_CALEQ_5_HIFREQAGCCAP_SHIFT, + params->high_freq_agc_boost); + + al_serdes_grp_lane_write(&obj->grp_info[grp], + lane, + AL_SRDS_REG_TYPE_PMA, + SERDES_IREG_RX_CALEQ_5_REG_NUM, + reg); +} + +static inline void al_serdes_common_cfg_eth(struct al_serdes_group_info *grp_info) +{ + al_serdes_grp_reg_masked_write( + grp_info, + AL_SRDS_REG_PAGE_4_COMMON, + AL_SRDS_REG_TYPE_PMA, + SERDES_IREG_FLD_RXEQ_LOOKUP_CODE_EN_REG_NUM, + SERDES_IREG_FLD_RXEQ_LOOKUP_CODE_EN_MASK, + (0x1 << SERDES_IREG_FLD_RXEQ_LOOKUP_CODE_EN_SHIFT)); + + al_serdes_grp_reg_masked_write( + grp_info, + AL_SRDS_REG_PAGE_4_COMMON, + AL_SRDS_REG_TYPE_PMA, + SERDES_IREG_FLD_RXEQ_LOOKUP_LASTCODE_REG_NUM, + SERDES_IREG_FLD_RXEQ_LOOKUP_LASTCODE_MASK, + (0 << SERDES_IREG_FLD_RXEQ_LOOKUP_LASTCODE_SHIFT)); + + al_serdes_grp_reg_masked_write( + grp_info, + AL_SRDS_REG_PAGE_4_COMMON, + AL_SRDS_REG_TYPE_PMA, + SERDES_IREG_FLD_RXEQ_COARSE_RUN1_MASK_REG_NUM, + SERDES_IREG_FLD_RXEQ_COARSE_RUN1_MASK_MASK, + (0x2 << SERDES_IREG_FLD_RXEQ_COARSE_RUN1_MASK_SHIFT)); + + al_serdes_grp_reg_masked_write( + grp_info, + AL_SRDS_REG_PAGE_4_COMMON, + AL_SRDS_REG_TYPE_PMA, + SERDES_IREG_FLD_RXEQ_COARSE_RUN2_MASK_REG_NUM, + SERDES_IREG_FLD_RXEQ_COARSE_RUN2_MASK_MASK, + (0 << SERDES_IREG_FLD_RXEQ_COARSE_RUN2_MASK_SHIFT)); + + al_serdes_grp_reg_masked_write( + grp_info, + AL_SRDS_REG_PAGE_4_COMMON, + AL_SRDS_REG_TYPE_PMA, + SERDES_IREG_FLD_RXEQ_COARSE_STEP_REG_NUM, + SERDES_IREG_FLD_RXEQ_COARSE_STEP_MASK, + (0x1 << SERDES_IREG_FLD_RXEQ_COARSE_STEP_SHIFT)); + + al_serdes_grp_reg_masked_write( + grp_info, + AL_SRDS_REG_PAGE_4_COMMON, + AL_SRDS_REG_TYPE_PMA, + SERDES_IREG_FLD_RXEQ_COARSE_ITER_NUM_REG_NUM, + SERDES_IREG_FLD_RXEQ_COARSE_ITER_NUM_MASK, + (0x1 << SERDES_IREG_FLD_RXEQ_COARSE_ITER_NUM_SHIFT)); + + al_serdes_grp_reg_masked_write( + grp_info, + AL_SRDS_REG_PAGE_4_COMMON, + AL_SRDS_REG_TYPE_PMA, + SERDES_IREG_FLD_RXEQ_FINE_RUN1_MASK_REG_NUM, + SERDES_IREG_FLD_RXEQ_FINE_RUN1_MASK_MASK, + (0xf0 << SERDES_IREG_FLD_RXEQ_FINE_RUN1_MASK_SHIFT)); + + al_serdes_grp_reg_masked_write( + grp_info, + AL_SRDS_REG_PAGE_4_COMMON, + AL_SRDS_REG_TYPE_PMA, + SERDES_IREG_FLD_RXEQ_FINE_RUN2_MASK_REG_NUM, + SERDES_IREG_FLD_RXEQ_FINE_RUN2_MASK_MASK, + (0 << SERDES_IREG_FLD_RXEQ_FINE_RUN2_MASK_SHIFT)); + + al_serdes_grp_reg_masked_write( + grp_info, + AL_SRDS_REG_PAGE_4_COMMON, + AL_SRDS_REG_TYPE_PMA, + SERDES_IREG_FLD_RXEQ_FINE_STEP_REG_NUM, + SERDES_IREG_FLD_RXEQ_FINE_STEP_MASK, + (1 << SERDES_IREG_FLD_RXEQ_FINE_STEP_SHIFT)); + + al_serdes_grp_reg_masked_write( + grp_info, + AL_SRDS_REG_PAGE_4_COMMON, + AL_SRDS_REG_TYPE_PMA, + SERDES_IREG_FLD_RXEQ_FINE_ITER_NUM_REG_NUM, + SERDES_IREG_FLD_RXEQ_FINE_ITER_NUM_MASK, + (0x8 << SERDES_IREG_FLD_RXEQ_FINE_ITER_NUM_SHIFT)); + + al_serdes_grp_reg_masked_write( + grp_info, + AL_SRDS_REG_PAGE_4_COMMON, + AL_SRDS_REG_TYPE_PMA, + SERDES_IREG_FLD_RXCALEYEDIAGFSM_BERTHRESHOLD1_REG_NUM, + SERDES_IREG_FLD_RXCALEYEDIAGFSM_BERTHRESHOLD1_MASK, + (0 << SERDES_IREG_FLD_RXCALEYEDIAGFSM_BERTHRESHOLD1_SHIFT)); + + al_serdes_grp_reg_masked_write( + grp_info, + AL_SRDS_REG_PAGE_4_COMMON, + AL_SRDS_REG_TYPE_PMA, + SERDES_IREG_FLD_RXCALEYEDIAGFSM_BERTHRESHOLD2_REG_NUM, + SERDES_IREG_FLD_RXCALEYEDIAGFSM_BERTHRESHOLD2_MASK, + (0x64 << SERDES_IREG_FLD_RXCALEYEDIAGFSM_BERTHRESHOLD2_SHIFT)); + + al_serdes_grp_reg_masked_write( + grp_info, + AL_SRDS_REG_PAGE_4_COMMON, + AL_SRDS_REG_TYPE_PMA, + SERDES_IREG_FLD_RXCALEYEDIAGFSM_XVALCOARSE_REG_NUM, + SERDES_IREG_FLD_RXCALEYEDIAGFSM_XVALCOARSE_MASK, + (0x3 << SERDES_IREG_FLD_RXCALEYEDIAGFSM_XVALCOARSE_SHIFT)); + + al_serdes_grp_reg_masked_write( + grp_info, + AL_SRDS_REG_PAGE_4_COMMON, + AL_SRDS_REG_TYPE_PMA, + SERDES_IREG_FLD_RXCALEYEDIAGFSM_XVALFINE_REG_NUM, + SERDES_IREG_FLD_RXCALEYEDIAGFSM_XVALFINE_MASK, + (0x1 << SERDES_IREG_FLD_RXCALEYEDIAGFSM_XVALFINE_SHIFT)); + + al_serdes_grp_reg_masked_write( + grp_info, + AL_SRDS_REG_PAGE_4_COMMON, + AL_SRDS_REG_TYPE_PMA, + SERDES_IREG_FLD_RXCALEYEDIAGFSM_YVALCOARSE_REG_NUM, + SERDES_IREG_FLD_RXCALEYEDIAGFSM_YVALCOARSE_MASK, + (3 << SERDES_IREG_FLD_RXCALEYEDIAGFSM_YVALCOARSE_SHIFT)); + + al_serdes_grp_reg_masked_write( + grp_info, + AL_SRDS_REG_PAGE_4_COMMON, + AL_SRDS_REG_TYPE_PMA, + SERDES_IREG_FLD_RXCALEYEDIAGFSM_YVALFINE_REG_NUM, + SERDES_IREG_FLD_RXCALEYEDIAGFSM_YVALFINE_MASK, + (1 << SERDES_IREG_FLD_RXCALEYEDIAGFSM_YVALFINE_SHIFT)); + + al_serdes_grp_reg_masked_write( + grp_info, + AL_SRDS_REG_PAGE_4_COMMON, + AL_SRDS_REG_TYPE_PMA, + SERDES_IREG_FLD_EYE_DIAG_SAMPLE_CNT_MSB_REG_NUM, + SERDES_IREG_FLD_EYE_DIAG_SAMPLE_CNT_MSB_MASK, + (0xc << SERDES_IREG_FLD_EYE_DIAG_SAMPLE_CNT_MSB_SHIFT)); + + al_serdes_grp_reg_masked_write( + grp_info, + AL_SRDS_REG_PAGE_4_COMMON, + AL_SRDS_REG_TYPE_PMA, + SERDES_IREG_FLD_EYE_DIAG_SAMPLE_CNT_LSB_REG_NUM, + SERDES_IREG_FLD_EYE_DIAG_SAMPLE_CNT_LSB_MASK, + (0xcc << SERDES_IREG_FLD_EYE_DIAG_SAMPLE_CNT_LSB_SHIFT)); +} + +struct al_serdes_mode_rx_tx_inv_state { + al_bool restore; + uint32_t pipe_rst; + uint32_t ipd_multi[AL_SRDS_NUM_LANES]; + uint8_t inv_value[AL_SRDS_NUM_LANES]; +}; + +static void al_serdes_mode_rx_tx_inv_state_save( + struct al_serdes_group_info *grp_info, + struct al_serdes_mode_rx_tx_inv_state *state) +{ + if (al_reg_read32(&grp_info->regs_base->gen.irst) & SERDES_GEN_IRST_POR_B_A) { + int i; + + state->restore = AL_TRUE; + state->pipe_rst = al_reg_read32(&grp_info->regs_base->gen.irst); + + for (i = 0; i < AL_SRDS_NUM_LANES; i++) { + state->inv_value[i] = al_serdes_grp_reg_read( + grp_info, + i, + AL_SRDS_REG_TYPE_PMA, + SERDES_IREG_FLD_POLARITY_RX_REG_NUM); + state->ipd_multi[i] = + al_reg_read32(&grp_info->regs_base->lane[i].ipd_multi); + } + } else { + state->restore = AL_FALSE; + } +} + +static void al_serdes_mode_rx_tx_inv_state_restore( + struct al_serdes_group_info *grp_info, + struct al_serdes_mode_rx_tx_inv_state *state) +{ + if (state->restore) { + int i; + + for (i = 0; i < AL_SRDS_NUM_LANES; i++) { + al_serdes_grp_reg_write( + grp_info, + i, + AL_SRDS_REG_TYPE_PMA, + SERDES_IREG_FLD_POLARITY_RX_REG_NUM, + state->inv_value[i]); + al_reg_write32( + &grp_info->regs_base->lane[i].ipd_multi, state->ipd_multi[i]); + al_reg_write32_masked( + &grp_info->regs_base->gen.irst, + (SERDES_GEN_IRST_PIPE_RST_L0_B_A_SEL >> i) | + (SERDES_GEN_IRST_PIPE_RST_L0_B_A >> i), + state->pipe_rst); + } + } +} + +void al_serdes_mode_set_sgmii( + struct al_serdes_obj *obj, + enum al_serdes_group grp) +{ + struct al_serdes_group_info *grp_info; + struct al_serdes_mode_rx_tx_inv_state rx_tx_inv_state; + + al_assert(obj); + al_assert(((int)grp) >= AL_SRDS_GRP_A); + al_assert(((int)grp) <= AL_SRDS_GRP_D); + + grp_info = &obj->grp_info[grp]; + + al_serdes_mode_rx_tx_inv_state_save(grp_info, &rx_tx_inv_state); + + al_reg_write32(&grp_info->regs_base->gen.irst, 0x000000); + al_reg_write32(&grp_info->regs_base->lane[0].ictl_multi, 0x10110010); + al_reg_write32(&grp_info->regs_base->lane[1].ictl_multi, 0x10110010); + al_reg_write32(&grp_info->regs_base->lane[2].ictl_multi, 0x10110010); + al_reg_write32(&grp_info->regs_base->lane[3].ictl_multi, 0x10110010); + al_reg_write32(&grp_info->regs_base->gen.ipd_multi_synth , 0x0001); + al_reg_write32(&grp_info->regs_base->lane[0].ipd_multi, 0x0003); + al_reg_write32(&grp_info->regs_base->lane[1].ipd_multi, 0x0003); + al_reg_write32(&grp_info->regs_base->lane[2].ipd_multi, 0x0003); + al_reg_write32(&grp_info->regs_base->lane[3].ipd_multi, 0x0003); + al_reg_write32(&grp_info->regs_base->gen.ictl_pcs , 0); + al_reg_write32(&grp_info->regs_base->gen.irst, 0x001000); + al_serdes_ns_delay(800); + al_reg_write32(&grp_info->regs_base->gen.irst, 0x000000); + al_serdes_ns_delay(500); + al_reg_write32(&grp_info->regs_base->gen.irst, 0x001000); + al_serdes_ns_delay(500); + + al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_0123_LANES_0123, + AL_SRDS_REG_TYPE_PMA, 101, 183); + al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_0123_LANES_0123, + AL_SRDS_REG_TYPE_PMA, 102, 183); + al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_0123_LANES_0123, + AL_SRDS_REG_TYPE_PMA, 103, 12); + al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_0123_LANES_0123, + AL_SRDS_REG_TYPE_PMA, 104, 12); + al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_0123_LANES_0123, + AL_SRDS_REG_TYPE_PMA, 105, 26); + al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_0123_LANES_0123, + AL_SRDS_REG_TYPE_PMA, 106, 26); + al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_0123_LANES_0123, + AL_SRDS_REG_TYPE_PMA, 107, 2); + al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_0123_LANES_0123, + AL_SRDS_REG_TYPE_PMA, 108, 2); + al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_0123_LANES_0123, + AL_SRDS_REG_TYPE_PMA, 109, 17); + al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_0123_LANES_0123, + AL_SRDS_REG_TYPE_PMA, 110, 13); + al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON, + AL_SRDS_REG_TYPE_PMA, 101, 153); + al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON, + AL_SRDS_REG_TYPE_PMA, 102, 0); + al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON, + AL_SRDS_REG_TYPE_PMA, 103, 108); + al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON, + AL_SRDS_REG_TYPE_PMA, 104, 183); + al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON, + AL_SRDS_REG_TYPE_PMA, 105, 183); + al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON, + AL_SRDS_REG_TYPE_PMA, 106, 12); + al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON, + AL_SRDS_REG_TYPE_PMA, 107, 12); + al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON, + AL_SRDS_REG_TYPE_PMA, 108, 26); + al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON, + AL_SRDS_REG_TYPE_PMA, 109, 26); + al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON, + AL_SRDS_REG_TYPE_PMA, 110, 7); + al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON, + AL_SRDS_REG_TYPE_PMA, 111, 12); + al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON, + AL_SRDS_REG_TYPE_PMA, 112, 8); + al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON, + AL_SRDS_REG_TYPE_PMA, 113, 0); + al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON, + AL_SRDS_REG_TYPE_PMA, 114, 8); + al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON, + AL_SRDS_REG_TYPE_PMA, 115, 0); + al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON, + AL_SRDS_REG_TYPE_PMA, 116, 255); + al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON, + AL_SRDS_REG_TYPE_PMA, 117, 179); + al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON, + AL_SRDS_REG_TYPE_PMA, 118, 246); + al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON, + AL_SRDS_REG_TYPE_PMA, 119, 208); + al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON, + AL_SRDS_REG_TYPE_PMA, 120, 239); + al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON, + AL_SRDS_REG_TYPE_PMA, 121, 251); + al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON, + AL_SRDS_REG_TYPE_PMA, 122, 255); + al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON, + AL_SRDS_REG_TYPE_PMA, 123, 255); + al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON, + AL_SRDS_REG_TYPE_PMA, 124, 255); + al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON, + AL_SRDS_REG_TYPE_PMA, 125, 255); + al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON, + AL_SRDS_REG_TYPE_PMA, 126, 255); + al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON, + AL_SRDS_REG_TYPE_PMA, 127, 211); + al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON, + AL_SRDS_REG_TYPE_PMA, 128, 211); + al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON, + AL_SRDS_REG_TYPE_PMA, 129, 226); + al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON, + AL_SRDS_REG_TYPE_PMA, 130, 239); + al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON, + AL_SRDS_REG_TYPE_PMA, 131, 251); + al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON, + AL_SRDS_REG_TYPE_PMA, 132, 251); + al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON, + AL_SRDS_REG_TYPE_PMA, 133, 255); + al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON, + AL_SRDS_REG_TYPE_PMA, 134, 239); + al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON, + AL_SRDS_REG_TYPE_PMA, 135, 255); + al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON, + AL_SRDS_REG_TYPE_PMA, 136, 255); + al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON, + AL_SRDS_REG_TYPE_PMA, 137, 211); + al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON, + AL_SRDS_REG_TYPE_PMA, 138, 211); + al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON, + AL_SRDS_REG_TYPE_PMA, 139, 226); + al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON, + AL_SRDS_REG_TYPE_PMA, 140, 239); + al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON, + AL_SRDS_REG_TYPE_PMA, 141, 251); + al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON, + AL_SRDS_REG_TYPE_PMA, 142, 251); + al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON, + AL_SRDS_REG_TYPE_PMA, 143, 255); + al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON, + AL_SRDS_REG_TYPE_PMA, 144, 239); + al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON, + AL_SRDS_REG_TYPE_PMA, 145, 255); + al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON, + AL_SRDS_REG_TYPE_PMA, 146, 255); + al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON, + AL_SRDS_REG_TYPE_PMA, 147, 251); + al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON, + AL_SRDS_REG_TYPE_PMA, 148, 255); + al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON, + AL_SRDS_REG_TYPE_PMA, 149, 63); + al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON, + AL_SRDS_REG_TYPE_PMA, 150, 0); + al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON, + AL_SRDS_REG_TYPE_PMA, 151, 100); + al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON, + AL_SRDS_REG_TYPE_PMA, 152, 0); + al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON, + AL_SRDS_REG_TYPE_PMA, 153, 4); + al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON, + AL_SRDS_REG_TYPE_PMA, 154, 2); + al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON, + AL_SRDS_REG_TYPE_PMA, 155, 5); + al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON, + AL_SRDS_REG_TYPE_PMA, 156, 5); + al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON, + AL_SRDS_REG_TYPE_PMA, 157, 4); + al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON, + AL_SRDS_REG_TYPE_PMA, 158, 0); + al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON, + AL_SRDS_REG_TYPE_PMA, 159, 0); + al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON, + AL_SRDS_REG_TYPE_PMA, 160, 8); + al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON, + AL_SRDS_REG_TYPE_PMA, 161, 4); + al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON, + AL_SRDS_REG_TYPE_PMA, 162, 0); + al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON, + AL_SRDS_REG_TYPE_PMA, 163, 0); + al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON, + AL_SRDS_REG_TYPE_PMA, 164, 4); + al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_0_LANE_0, + AL_SRDS_REG_TYPE_PMA, 7, 0); + al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_1_LANE_1, + AL_SRDS_REG_TYPE_PMA, 7, 0); + al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_2_LANE_2, + AL_SRDS_REG_TYPE_PMA, 7, 0); + al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_3_LANE_3, + AL_SRDS_REG_TYPE_PMA, 7, 0); + al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON, + AL_SRDS_REG_TYPE_PMA, 13, 16); + al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON, + AL_SRDS_REG_TYPE_PMA, 48, 0); + al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON, + AL_SRDS_REG_TYPE_PMA, 49, 0); + al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON, + AL_SRDS_REG_TYPE_PMA, 54, 0); + al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON, + AL_SRDS_REG_TYPE_PMA, 55, 180); + al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON, + AL_SRDS_REG_TYPE_PMA, 93, 2); + al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON, + AL_SRDS_REG_TYPE_PMA, 165, 3); + al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_0123_LANES_0123, + AL_SRDS_REG_TYPE_PMA, 41, 6); + al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON, + AL_SRDS_REG_TYPE_PMA, 354, 3); + al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON, + AL_SRDS_REG_TYPE_PMA, 355, 58); + al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON, + AL_SRDS_REG_TYPE_PMA, 356, 9); + al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON, + AL_SRDS_REG_TYPE_PMA, 357, 3); + al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON, + AL_SRDS_REG_TYPE_PMA, 358, 62); + al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON, + AL_SRDS_REG_TYPE_PMA, 359, 12); + al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_0123_LANES_0123, + AL_SRDS_REG_TYPE_PMA, 701, 0); + al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_0123_LANES_0123, + AL_SRDS_REG_TYPE_PMA, 87, 0x1f); + + al_serdes_common_cfg_eth(grp_info); + + al_serdes_mode_rx_tx_inv_state_restore(grp_info, &rx_tx_inv_state); + + al_reg_write32(&grp_info->regs_base->gen.irst, 0x0011F0); + al_serdes_ns_delay(500); +} + +void al_serdes_mode_set_kr( + struct al_serdes_obj *obj, + enum al_serdes_group grp) +{ + struct al_serdes_group_info *grp_info; + struct al_serdes_mode_rx_tx_inv_state rx_tx_inv_state; + + al_assert(obj); + al_assert(((int)grp) >= AL_SRDS_GRP_A); + al_assert(((int)grp) <= AL_SRDS_GRP_D); + + grp_info = &obj->grp_info[grp]; + + al_serdes_mode_rx_tx_inv_state_save(grp_info, &rx_tx_inv_state); + + al_reg_write32(&grp_info->regs_base->gen.irst, 0x000000); + al_reg_write32(&grp_info->regs_base->lane[0].ictl_multi, 0x30330030); + al_reg_write32(&grp_info->regs_base->lane[1].ictl_multi, 0x30330030); + al_reg_write32(&grp_info->regs_base->lane[2].ictl_multi, 0x30330030); + al_reg_write32(&grp_info->regs_base->lane[3].ictl_multi, 0x30330030); + al_reg_write32(&grp_info->regs_base->gen.ipd_multi_synth , 0x0001); + al_reg_write32(&grp_info->regs_base->lane[0].ipd_multi, 0x0003); + al_reg_write32(&grp_info->regs_base->lane[1].ipd_multi, 0x0003); + al_reg_write32(&grp_info->regs_base->lane[2].ipd_multi, 0x0003); + al_reg_write32(&grp_info->regs_base->lane[3].ipd_multi, 0x0003); + al_reg_write32(&grp_info->regs_base->gen.ictl_pcs , 0); + al_reg_write32(&grp_info->regs_base->gen.irst, 0x001000); + al_serdes_ns_delay(800); + al_reg_write32(&grp_info->regs_base->gen.irst, 0x000000); + al_serdes_ns_delay(500); + al_reg_write32(&grp_info->regs_base->gen.irst, 0x001000); + al_serdes_ns_delay(500); + + al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_0123_LANES_0123, + AL_SRDS_REG_TYPE_PMA, 101, 189); + al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_0123_LANES_0123, + AL_SRDS_REG_TYPE_PMA, 102, 189); + al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_0123_LANES_0123, + AL_SRDS_REG_TYPE_PMA, 103, 6); + al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_0123_LANES_0123, + AL_SRDS_REG_TYPE_PMA, 104, 6); + al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_0123_LANES_0123, + AL_SRDS_REG_TYPE_PMA, 105, 27); + al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_0123_LANES_0123, + AL_SRDS_REG_TYPE_PMA, 106, 27); + al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_0123_LANES_0123, + AL_SRDS_REG_TYPE_PMA, 107, 1); + al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_0123_LANES_0123, + AL_SRDS_REG_TYPE_PMA, 108, 1); + al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_0123_LANES_0123, + AL_SRDS_REG_TYPE_PMA, 109, 119); + al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_0123_LANES_0123, + AL_SRDS_REG_TYPE_PMA, 110, 5); + al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON, + AL_SRDS_REG_TYPE_PMA, 101, 170); + al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON, + AL_SRDS_REG_TYPE_PMA, 102, 0); + al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON, + AL_SRDS_REG_TYPE_PMA, 103, 108); + al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON, + AL_SRDS_REG_TYPE_PMA, 104, 189); + al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON, + AL_SRDS_REG_TYPE_PMA, 105, 189); + al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON, + AL_SRDS_REG_TYPE_PMA, 106, 6); + al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON, + AL_SRDS_REG_TYPE_PMA, 107, 6); + al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON, + AL_SRDS_REG_TYPE_PMA, 108, 27); + al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON, + AL_SRDS_REG_TYPE_PMA, 109, 27); + al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON, + AL_SRDS_REG_TYPE_PMA, 110, 7); + al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON, + AL_SRDS_REG_TYPE_PMA, 111, 12); + al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON, + AL_SRDS_REG_TYPE_PMA, 112, 16); + al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON, + AL_SRDS_REG_TYPE_PMA, 113, 0); + al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON, + AL_SRDS_REG_TYPE_PMA, 114, 16); + al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON, + AL_SRDS_REG_TYPE_PMA, 115, 0); + al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON, + AL_SRDS_REG_TYPE_PMA, 116, 255); + al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON, + AL_SRDS_REG_TYPE_PMA, 117, 179); + al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON, + AL_SRDS_REG_TYPE_PMA, 118, 246); + al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON, + AL_SRDS_REG_TYPE_PMA, 119, 208); + al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON, + AL_SRDS_REG_TYPE_PMA, 120, 239); + al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON, + AL_SRDS_REG_TYPE_PMA, 121, 251); + al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON, + AL_SRDS_REG_TYPE_PMA, 122, 255); + al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON, + AL_SRDS_REG_TYPE_PMA, 123, 255); + al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON, + AL_SRDS_REG_TYPE_PMA, 124, 255); + al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON, + AL_SRDS_REG_TYPE_PMA, 125, 255); + al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON, + AL_SRDS_REG_TYPE_PMA, 126, 255); + al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON, + AL_SRDS_REG_TYPE_PMA, 127, 211); + al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON, + AL_SRDS_REG_TYPE_PMA, 128, 211); + al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON, + AL_SRDS_REG_TYPE_PMA, 129, 226); + al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON, + AL_SRDS_REG_TYPE_PMA, 130, 239); + al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON, + AL_SRDS_REG_TYPE_PMA, 131, 251); + al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON, + AL_SRDS_REG_TYPE_PMA, 132, 251); + al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON, + AL_SRDS_REG_TYPE_PMA, 133, 255); + al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON, + AL_SRDS_REG_TYPE_PMA, 134, 239); + al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON, + AL_SRDS_REG_TYPE_PMA, 135, 255); + al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON, + AL_SRDS_REG_TYPE_PMA, 136, 255); + al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON, + AL_SRDS_REG_TYPE_PMA, 137, 211); + al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON, + AL_SRDS_REG_TYPE_PMA, 138, 211); + al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON, + AL_SRDS_REG_TYPE_PMA, 139, 226); + al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON, + AL_SRDS_REG_TYPE_PMA, 140, 239); + al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON, + AL_SRDS_REG_TYPE_PMA, 141, 251); + al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON, + AL_SRDS_REG_TYPE_PMA, 142, 251); + al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON, + AL_SRDS_REG_TYPE_PMA, 143, 255); + al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON, + AL_SRDS_REG_TYPE_PMA, 144, 239); + al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON, + AL_SRDS_REG_TYPE_PMA, 145, 255); + al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON, + AL_SRDS_REG_TYPE_PMA, 146, 255); + al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON, + AL_SRDS_REG_TYPE_PMA, 147, 251); + al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON, + AL_SRDS_REG_TYPE_PMA, 148, 255); + al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON, + AL_SRDS_REG_TYPE_PMA, 149, 63); + al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON, + AL_SRDS_REG_TYPE_PMA, 150, 0); + al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON, + AL_SRDS_REG_TYPE_PMA, 151, 50); + al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON, + AL_SRDS_REG_TYPE_PMA, 152, 17); + al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON, + AL_SRDS_REG_TYPE_PMA, 153, 2); + al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON, + AL_SRDS_REG_TYPE_PMA, 154, 1); + al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON, + AL_SRDS_REG_TYPE_PMA, 155, 0); + al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON, + AL_SRDS_REG_TYPE_PMA, 156, 0); + al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON, + AL_SRDS_REG_TYPE_PMA, 157, 4); + al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON, + AL_SRDS_REG_TYPE_PMA, 158, 0); + al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON, + AL_SRDS_REG_TYPE_PMA, 159, 0); + al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON, + AL_SRDS_REG_TYPE_PMA, 160, 8); + al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON, + AL_SRDS_REG_TYPE_PMA, 161, 4); + al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON, + AL_SRDS_REG_TYPE_PMA, 162, 0); + al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON, + AL_SRDS_REG_TYPE_PMA, 163, 0); + al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON, + AL_SRDS_REG_TYPE_PMA, 164, 4); + al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_0_LANE_0, + AL_SRDS_REG_TYPE_PMA, 7, 0); + al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_1_LANE_1, + AL_SRDS_REG_TYPE_PMA, 7, 0); + al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_2_LANE_2, + AL_SRDS_REG_TYPE_PMA, 7, 0); + al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_3_LANE_3, + AL_SRDS_REG_TYPE_PMA, 7, 0); + al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON, + AL_SRDS_REG_TYPE_PMA, 13, 16); + al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON, + AL_SRDS_REG_TYPE_PMA, 48, 0); + al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON, + AL_SRDS_REG_TYPE_PMA, 49, 0); + al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON, + AL_SRDS_REG_TYPE_PMA, 54, 0); + al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON, + AL_SRDS_REG_TYPE_PMA, 55, 149); /*Was 182*/ + al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON, + AL_SRDS_REG_TYPE_PMA, 93, 2); + al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON, + AL_SRDS_REG_TYPE_PMA, 165, 3); + al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_0123_LANES_0123, + AL_SRDS_REG_TYPE_PMA, 41, 6); + al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON, + AL_SRDS_REG_TYPE_PMA, 354, 3); + al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON, + AL_SRDS_REG_TYPE_PMA, 355, 58); + al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON, + AL_SRDS_REG_TYPE_PMA, 356, 9); + al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON, + AL_SRDS_REG_TYPE_PMA, 357, 3); + al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON, + AL_SRDS_REG_TYPE_PMA, 358, 62); + al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON, + AL_SRDS_REG_TYPE_PMA, 359, 12); + al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_0123_LANES_0123, + AL_SRDS_REG_TYPE_PMA, 701, 0); + al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_0123_LANES_0123, + AL_SRDS_REG_TYPE_PMA, 87, 0x1f); + + al_serdes_common_cfg_eth(grp_info); + + al_serdes_mode_rx_tx_inv_state_restore(grp_info, &rx_tx_inv_state); + + al_reg_write32(&grp_info->regs_base->gen.irst, 0x0011F0); + al_serdes_ns_delay(500); +} + +void al_serdes_rx_advanced_params_get(struct al_serdes_obj *obj, + enum al_serdes_group grp, + enum al_serdes_lane lane, + struct al_serdes_adv_rx_params* rx_params) +{ + uint8_t temp_val; + + al_serdes_lane_read( + obj, grp, lane, AL_SRDS_REG_TYPE_PMA, + SERDES_IREG_RX_CALEQ_1_REG_NUM, + &temp_val); + rx_params->dcgain = (temp_val & SERDES_IREG_RX_CALEQ_1_DCGAIN_MASK) >> + SERDES_IREG_RX_CALEQ_1_DCGAIN_SHIFT; + rx_params->dfe_3db_freq = (temp_val & + SERDES_IREG_RX_CALEQ_1_DFEPSTAP3DB_MASK) >> + SERDES_IREG_RX_CALEQ_1_DFEPSTAP3DB_SHIFT; + + al_serdes_lane_read( + obj, grp, lane, AL_SRDS_REG_TYPE_PMA, + SERDES_IREG_RX_CALEQ_2_REG_NUM, + &temp_val); + rx_params->dfe_gain = (temp_val & + SERDES_IREG_RX_CALEQ_2_DFEPSTAPGAIN_MASK) >> + SERDES_IREG_RX_CALEQ_2_DFEPSTAPGAIN_SHIFT; + rx_params->dfe_first_tap_ctrl = (temp_val & + SERDES_IREG_RX_CALEQ_2_DFETAP1GAIN_MASK) >> + SERDES_IREG_RX_CALEQ_2_DFETAP1GAIN_SHIFT; + + al_serdes_lane_read( + obj, grp, lane, AL_SRDS_REG_TYPE_PMA, + SERDES_IREG_RX_CALEQ_3_REG_NUM, + &temp_val); + rx_params->dfe_secound_tap_ctrl = (temp_val & + SERDES_IREG_RX_CALEQ_3_DFETAP2GAIN_MASK) >> + SERDES_IREG_RX_CALEQ_3_DFETAP2GAIN_SHIFT; + rx_params->dfe_third_tap_ctrl = (temp_val & + SERDES_IREG_RX_CALEQ_3_DFETAP3GAIN_MASK) >> + SERDES_IREG_RX_CALEQ_3_DFETAP3GAIN_SHIFT; + + al_serdes_lane_read( + obj, grp, lane, AL_SRDS_REG_TYPE_PMA, + SERDES_IREG_RX_CALEQ_4_REG_NUM, + &temp_val); + rx_params->dfe_fourth_tap_ctrl = (temp_val & + SERDES_IREG_RX_CALEQ_4_DFETAP4GAIN_MASK) >> + SERDES_IREG_RX_CALEQ_4_DFETAP4GAIN_SHIFT; + rx_params->low_freq_agc_gain = (temp_val & + SERDES_IREG_RX_CALEQ_4_LOFREQAGCGAIN_MASK) >> + SERDES_IREG_RX_CALEQ_4_LOFREQAGCGAIN_SHIFT; + + al_serdes_lane_read( + obj, grp, lane, AL_SRDS_REG_TYPE_PMA, + SERDES_IREG_RX_CALEQ_5_REG_NUM, + &temp_val); + rx_params->precal_code_sel = (temp_val & + SERDES_IREG_RX_CALEQ_5_PRECAL_CODE_SEL_MASK) >> + SERDES_IREG_RX_CALEQ_5_PRECAL_CODE_SEL_SHIFT; + rx_params->high_freq_agc_boost = (temp_val & + SERDES_IREG_RX_CALEQ_5_HIFREQAGCCAP_MASK) >> + SERDES_IREG_RX_CALEQ_5_HIFREQAGCCAP_SHIFT; + + al_serdes_lane_read(obj, grp, lane, AL_SRDS_REG_TYPE_PMA, + SERDES_IREG_FLD_RX_DRV_OVERRIDE_EN_REG_NUM, + &temp_val); + rx_params->override = ((temp_val & SERDES_IREG_FLD_RX_DRV_OVERRIDE_EN) == 0); +} + +#if ( SERDES_IREG_FLD_RXCALEYEDIAGFSMIN_LOCWREN_REG_NUM != \ + SERDES_IREG_FLD_RXCALROAMEYEMEASIN_LOCWREN_REG_NUM || \ + SERDES_IREG_FLD_RXCALEYEDIAGFSMIN_LOCWREN_REG_NUM != \ + SERDES_IREG_FLD_RXCALROAMXADJUST_LOCWREN_REG_NUM) +#error Wrong assumption +#endif +int al_serdes_rx_equalization( + struct al_serdes_obj *obj, + enum al_serdes_group grp, + enum al_serdes_lane lane) +{ + uint8_t serdes_ireg_fld_rxcalroamyadjust_locwren_val; + uint8_t serdes_ireg_fld_rxroam_xorbitsel_val; + uint8_t serdes_ireg_fld_pcsrxeq_locwren_val; + uint8_t serdes_ireg_fld_rxcal_locwren_val; + uint8_t temp_val; + uint8_t done; + + int test_score; + int i; + + /* + * Make sure Roam Eye mechanism is not overridden + * Lane SERDES_IREG_FLD_RXCALEYEDIAGFSMIN_LOCWREN = 1, + * so Rx 4-Point Eye process is not overridden + * Lane SERDES_IREG_FLD_RXCALROAMEYEMEASIN_LOCWREN = 1, + * so Eye Roam latch is not overridden + * Lane SERDES_IREG_FLD_RXCALROAMXADJUST_LOCWREN = 1, + * so Eye Roam latch 'X adjust' is not overridden + * Lane SERDES_IREG_FLD_RXCALROAMYADJUST_LOCWREN = 1, + * so Eye Roam latch 'Y adjust' is not overridden + * Lane SERDES_IREG_FLD_RXROAM_XORBITSEL = 0/1, + * so Eye Roamlatch works on the right Eye position (XORBITSEL) + * For most cases 0 is needed, but sometimes 1 is needed. + * I couldn't sort out why is this so the code uses a global + * XORBITSELmode variable, set by the user (GUI). Default is 0. + * control must be internal. At the end we restore original setting + */ + + /* save current values for restoring them later in the end */ + al_serdes_lane_read( + obj, grp, lane, AL_SRDS_REG_TYPE_PMA, + SERDES_IREG_FLD_RXCAL_LOCWREN_REG_NUM, + &serdes_ireg_fld_rxcal_locwren_val); + + al_serdes_lane_read( + obj, grp, lane, AL_SRDS_REG_TYPE_PMA, + SERDES_IREG_FLD_RXCALROAMYADJUST_LOCWREN_REG_NUM, + &serdes_ireg_fld_rxcalroamyadjust_locwren_val ); + al_serdes_lane_read( + obj, grp, lane, AL_SRDS_REG_TYPE_PMA, + SERDES_IREG_FLD_RXROAM_XORBITSEL_REG_NUM, + &serdes_ireg_fld_rxroam_xorbitsel_val ); + al_serdes_lane_read( + obj, grp, lane, AL_SRDS_REG_TYPE_PMA, + SERDES_IREG_FLD_PCSRXEQ_LOCWREN_REG_NUM, + &serdes_ireg_fld_pcsrxeq_locwren_val ); + + /* + * Set Bits: + * SERDES_IREG_FLD_RXCALEYEDIAGFSMIN_LOCWREN + * SERDES_IREG_FLD_RXCALROAMEYEMEASIN_LOCWREN + * SERDES_IREG_FLD_RXCALROAMXADJUST_LOCWREN + * to return 4pt-RxEye and EyeRoam Latch to internal logic + * + * clear bit SERDES_IREG_FLD_RX_DRV_OVERRIDE_EN + * AGC/DFE controlled via PMA registers + */ + temp_val = serdes_ireg_fld_rxcal_locwren_val; + temp_val |= SERDES_IREG_FLD_RXCALEYEDIAGFSMIN_LOCWREN; + temp_val |= SERDES_IREG_FLD_RXCALROAMEYEMEASIN_LOCWREN; + temp_val |= SERDES_IREG_FLD_RXCALROAMXADJUST_LOCWREN; + temp_val |= SERDES_IREG_FLD_RX_DRV_OVERRIDE_EN; + + al_serdes_lane_write( + obj, grp, lane, AL_SRDS_REG_TYPE_PMA, + SERDES_IREG_FLD_RXCAL_LOCWREN_REG_NUM, + temp_val ); + + /* + * Set bit SERDES_IREG_FLD_RXCALROAMYADJUST_LOCWREN + * to return EyeRoam Latch Y to internal logic + */ + temp_val = serdes_ireg_fld_rxcalroamyadjust_locwren_val | + SERDES_IREG_FLD_RXCALROAMYADJUST_LOCWREN; + al_serdes_lane_write( + obj, grp, lane, AL_SRDS_REG_TYPE_PMA, + SERDES_IREG_FLD_RXCALROAMYADJUST_LOCWREN_REG_NUM, + temp_val ); + + /* + * Clear Bit: SERDES_IREG_FLD_RXROAM_XORBITSEL + * so XORBITSEL=0, needed for the Eye mapping. + */ + temp_val = serdes_ireg_fld_rxroam_xorbitsel_val & + ~SERDES_IREG_FLD_RXROAM_XORBITSEL; + al_serdes_lane_write( + obj, grp, lane, AL_SRDS_REG_TYPE_PMA, + SERDES_IREG_FLD_RXROAM_XORBITSEL_REG_NUM, + temp_val ); + + /* + * Take Control from int.pin over RxEQ process. + * Clear Bit SERDES_IREG_FLD_PCSRXEQ_LOCWREN + * to override RxEQ via PMA + */ + temp_val = serdes_ireg_fld_pcsrxeq_locwren_val & + ~SERDES_IREG_FLD_PCSRXEQ_LOCWREN; + al_serdes_lane_write( + obj, grp, lane, AL_SRDS_REG_TYPE_PMA, + SERDES_IREG_FLD_PCSRXEQ_LOCWREN_REG_NUM, + temp_val ); + + + /* + * Start/Stop RxEQ Cal is via PCSRXEQ_START: 1=START. 0=STOP. + * Clear Bit SERDES_IREG_FLD_PCSRXEQ_START + * to start fresh from Stop + */ + al_serdes_lane_read( + obj, grp, lane, AL_SRDS_REG_TYPE_PMA, + SERDES_IREG_FLD_PCSRXEQ_START_REG_NUM, + &temp_val ); + temp_val &= ~SERDES_IREG_FLD_PCSRXEQ_START; + al_serdes_lane_write( + obj, grp, lane, AL_SRDS_REG_TYPE_PMA, + SERDES_IREG_FLD_PCSRXEQ_START_REG_NUM, + temp_val ); + + /* Set Bit SERDES_IREG_FLD_PCSRXEQ_START + * to begin Rx Eq Cal */ + temp_val |= SERDES_IREG_FLD_PCSRXEQ_START; + al_serdes_lane_write( + obj, grp, lane, AL_SRDS_REG_TYPE_PMA, + SERDES_IREG_FLD_PCSRXEQ_START_REG_NUM, + temp_val ); + + /* Poll on RxEq Cal completion. SERDES_IREG_FLD_RXEQ_DONE. 1=Done. */ + for( i = 0; i < AL_SERDES_RX_EQUAL_TRIES; ++i ) { + al_serdes_lane_read( + obj, grp, lane, AL_SRDS_REG_TYPE_PMA, + SERDES_IREG_FLD_RXCALROAMEYEMEASDONE_REG_NUM, + &done ); + done &= SERDES_IREG_FLD_RXEQ_DONE; + + /* Check if RxEQ Cal is done */ + if (done) + break; + al_msleep(AL_SERDES_RX_EQUAL_MDELAY); + } + + if (!done) { + al_err("%s: Timeout!\n", __func__); + return -1; + } + + /* Stop the RxEQ process. */ + temp_val &= ~SERDES_IREG_FLD_PCSRXEQ_START; + al_serdes_lane_write( + obj, grp, lane, AL_SRDS_REG_TYPE_PMA, + SERDES_IREG_FLD_PCSRXEQ_START_REG_NUM, + temp_val ); + /* Get score */ + al_serdes_lane_read( + obj, grp, lane, AL_SRDS_REG_TYPE_PMA, + SERDES_IREG_RXEQ_BEST_EYE_MSB_VAL_REG_NUM, + &temp_val ); + test_score = (int)( (temp_val & 0xFF) << 6 ); + al_serdes_lane_read( + obj, grp, lane, AL_SRDS_REG_TYPE_PMA, + SERDES_IREG_RXEQ_BEST_EYE_LSB_VAL_REG_NUM, + &temp_val ); + test_score += (int)(temp_val & SERDES_IREG_RXEQ_BEST_EYE_LSB_VAL_MASK); + + /* Restore start values */ + al_serdes_lane_write( + obj, grp, lane, AL_SRDS_REG_TYPE_PMA, + SERDES_IREG_FLD_RXCAL_LOCWREN_REG_NUM, + serdes_ireg_fld_rxcal_locwren_val); + al_serdes_lane_write( + obj, grp, lane, AL_SRDS_REG_TYPE_PMA, + SERDES_IREG_FLD_RXCALROAMYADJUST_LOCWREN_REG_NUM, + serdes_ireg_fld_rxcalroamyadjust_locwren_val ); + al_serdes_lane_write( + obj, grp, lane, AL_SRDS_REG_TYPE_PMA, + SERDES_IREG_FLD_RXROAM_XORBITSEL_REG_NUM, + serdes_ireg_fld_rxroam_xorbitsel_val ); + al_serdes_lane_write( + obj, grp, lane, AL_SRDS_REG_TYPE_PMA, + SERDES_IREG_FLD_PCSRXEQ_LOCWREN_REG_NUM, + serdes_ireg_fld_pcsrxeq_locwren_val ); + + return test_score; +} + +#if ( SERDES_IREG_FLD_RXCAL_LOCWREN_REG_NUM != \ + SERDES_IREG_FLD_RXCALROAMEYEMEASIN_LOCWREN_REG_NUM || \ + SERDES_IREG_FLD_RXCAL_LOCWREN_REG_NUM != \ + SERDES_IREG_FLD_RXCALROAMXADJUST_LOCWREN_REG_NUM || \ + SERDES_IREG_FLD_RXCAL_LOCWREN_REG_NUM != \ + SERDES_IREG_FLD_RXCALEYEDIAGFSMIN_LOCWREN_REG_NUM) +#error Wrong assumption +#endif +int al_serdes_calc_eye_size( + struct al_serdes_obj *obj, + enum al_serdes_group grp, + enum al_serdes_lane lane, + int* width, + int* height) +{ + uint8_t rxcaleyediagfsm_x_y_valweight_val; + uint8_t rxcaleyediagfsm_xvalcoarse_val; + uint8_t rxcaleyediagfsm_xvalfine_val; + uint8_t rxcaleyediagfsm_yvalcoarse_val; + uint8_t rxcaleyediagfsm_yvalfine_val; + uint8_t rxlock2ref_locwren_val; + uint8_t rxcal_locwren_val; + uint8_t rxcalroamyadjust_locwren_val; + uint8_t rxlock2ref_ovren_val; + + int i; + uint8_t status; + uint8_t reg_value; + + /* Save Registers */ + al_serdes_lane_read(obj, grp, lane, AL_SRDS_REG_TYPE_PMA, + SERDES_IREG_FLD_RXLOCK2REF_LOCWREN_REG_NUM, + &rxlock2ref_locwren_val); + al_serdes_lane_read(obj, grp, lane, AL_SRDS_REG_TYPE_PMA, + SERDES_IREG_FLD_RXCAL_LOCWREN_REG_NUM, + &rxcal_locwren_val); + al_serdes_lane_read(obj, grp, lane, AL_SRDS_REG_TYPE_PMA, + SERDES_IREG_FLD_RXCALROAMYADJUST_LOCWREN_REG_NUM, + &rxcalroamyadjust_locwren_val); + al_serdes_lane_read(obj, grp, lane, AL_SRDS_REG_TYPE_PMA, + SERDES_IREG_FLD_RXLOCK2REF_OVREN_REG_NUM, + &rxlock2ref_ovren_val); + + al_serdes_reg_read(obj, grp, AL_SRDS_REG_PAGE_4_COMMON, + AL_SRDS_REG_TYPE_PMA, + SERDES_IREG_FLD_RXCALEYEDIAGFSM_X_Y_VALWEIGHT_REG_NUM, + &rxcaleyediagfsm_x_y_valweight_val); + al_serdes_reg_read(obj, grp, AL_SRDS_REG_PAGE_4_COMMON, + AL_SRDS_REG_TYPE_PMA, + SERDES_IREG_FLD_RXCALEYEDIAGFSM_XVALCOARSE_REG_NUM, + &rxcaleyediagfsm_xvalcoarse_val); + al_serdes_reg_read(obj, grp, AL_SRDS_REG_PAGE_4_COMMON, + AL_SRDS_REG_TYPE_PMA, + SERDES_IREG_FLD_RXCALEYEDIAGFSM_XVALFINE_REG_NUM, + &rxcaleyediagfsm_xvalfine_val); + al_serdes_reg_read(obj, grp, AL_SRDS_REG_PAGE_4_COMMON, + AL_SRDS_REG_TYPE_PMA, + SERDES_IREG_FLD_RXCALEYEDIAGFSM_YVALCOARSE_REG_NUM, + &rxcaleyediagfsm_yvalcoarse_val); + al_serdes_reg_read(obj, grp, AL_SRDS_REG_PAGE_4_COMMON, + AL_SRDS_REG_TYPE_PMA, + SERDES_IREG_FLD_RXCALEYEDIAGFSM_YVALFINE_REG_NUM, + &rxcaleyediagfsm_yvalfine_val); + + /* + * Clear Bit: + * SERDES_IREG_FLD_RXCALEYEDIAGFSMIN_LOCWREN + * to override RxEQ via PMA + * Set Bits: + * SERDES_IREG_FLD_RXCALROAMEYEMEASIN_LOCWREN, + * SERDES_IREG_FLD_RXCALROAMXADJUST_LOCWREN + * to keep Eye Diag Roam controlled internally + */ + al_serdes_grp_lane_masked_write(&obj->grp_info[grp], + lane, + AL_SRDS_REG_TYPE_PMA, + SERDES_IREG_FLD_RXCAL_LOCWREN_REG_NUM, + SERDES_IREG_FLD_RXCALEYEDIAGFSMIN_LOCWREN | + SERDES_IREG_FLD_RXCALROAMEYEMEASIN_LOCWREN | + SERDES_IREG_FLD_RXCALROAMXADJUST_LOCWREN, + SERDES_IREG_FLD_RXCALROAMEYEMEASIN_LOCWREN | + SERDES_IREG_FLD_RXCALROAMXADJUST_LOCWREN); + /* + * Set Bit: + * SERDES_IREG_FLD_RXCALROAMYADJUST_LOCWREN + * to keep Eye Diag Roam controlled internally + */ + al_serdes_grp_lane_masked_write(&obj->grp_info[grp], + lane, + AL_SRDS_REG_TYPE_PMA, + SERDES_IREG_FLD_RXCALROAMYADJUST_LOCWREN_REG_NUM, + SERDES_IREG_FLD_RXCALROAMYADJUST_LOCWREN, + SERDES_IREG_FLD_RXCALROAMYADJUST_LOCWREN); + + /* + * Clear Bit: + * SERDES_IREG_FLD_RXROAM_XORBITSEL, + * so XORBITSEL=0, needed for the Eye mapping + * Set Bit: + * SERDES_IREG_FLD_RXLOCK2REF_OVREN, + * so RXLOCK2REF_OVREN=1, keeping lock to data, preventing data hit + */ + al_serdes_grp_lane_masked_write(&obj->grp_info[grp], + lane, + AL_SRDS_REG_TYPE_PMA, + SERDES_IREG_FLD_RXROAM_XORBITSEL_REG_NUM, + SERDES_IREG_FLD_RXLOCK2REF_OVREN | + SERDES_IREG_FLD_RXROAM_XORBITSEL, + SERDES_IREG_FLD_RXLOCK2REF_OVREN); + + + /* + * Clear Bit: + * SERDES_IREG_FLD_RXLOCK2REF_LOCWREN, + * so RXLOCK2REF_LOCWREN=0, to override control + */ + al_serdes_grp_lane_masked_write(&obj->grp_info[grp], + lane, + AL_SRDS_REG_TYPE_PMA, + SERDES_IREG_FLD_RXLOCK2REF_LOCWREN_REG_NUM, + SERDES_IREG_FLD_RXLOCK2REF_LOCWREN, + 0); + + /* Width Calculation */ + + /* Return Value = 0*Y + 1*X */ + al_serdes_reg_write(obj, grp, AL_SRDS_REG_PAGE_4_COMMON, + AL_SRDS_REG_TYPE_PMA, + SERDES_IREG_FLD_RXCALEYEDIAGFSM_X_Y_VALWEIGHT_REG_NUM, + 0x01); + /* X coarse scan step = 3 */ + al_serdes_reg_write(obj, grp, AL_SRDS_REG_PAGE_4_COMMON, + AL_SRDS_REG_TYPE_PMA, + SERDES_IREG_FLD_RXCALEYEDIAGFSM_XVALCOARSE_REG_NUM, + 0x03); + /* X fine scan step = 1 */ + al_serdes_reg_write(obj, grp, AL_SRDS_REG_PAGE_4_COMMON, + AL_SRDS_REG_TYPE_PMA, + SERDES_IREG_FLD_RXCALEYEDIAGFSM_XVALFINE_REG_NUM, + 0x01); + /* Y coarse scan step = 0 */ + al_serdes_reg_write(obj, grp, AL_SRDS_REG_PAGE_4_COMMON, + AL_SRDS_REG_TYPE_PMA, + SERDES_IREG_FLD_RXCALEYEDIAGFSM_YVALCOARSE_REG_NUM, + 0x00); + /* Y fine scan step = 0 */ + al_serdes_reg_write(obj, grp, AL_SRDS_REG_PAGE_4_COMMON, + AL_SRDS_REG_TYPE_PMA, + SERDES_IREG_FLD_RXCALEYEDIAGFSM_YVALFINE_REG_NUM, + 0x00); + + /* + * Set Bit: + * SERDES_IREG_FLD_RXCALEYEDIAGFSMIN_START, + * to start Eye measurement + */ + al_serdes_grp_lane_masked_write(&obj->grp_info[grp], + lane, + AL_SRDS_REG_TYPE_PMA, + SERDES_IREG_FLD_RXCALEYEDIAGFSMIN_START_REG_NUM, + SERDES_IREG_FLD_RXCALEYEDIAGFSMIN_START, + SERDES_IREG_FLD_RXCALEYEDIAGFSMIN_START); + + for( i = 0; i < AL_SERDES_RX_EYE_CAL_TRIES; ++i ) { + /* Check if RxEQ Cal is done */ + al_serdes_lane_read( + obj, grp, lane, AL_SRDS_REG_TYPE_PMA, + SERDES_IREG_FLD_RXCALEYEDIAGFSM_DONE_REG_NUM, + &status ); + if (status & SERDES_IREG_FLD_RXCALEYEDIAGFSM_DONE) + break; + al_msleep(AL_SERDES_RX_EYE_CAL_MDELAY); + } + + if (status & SERDES_IREG_FLD_RXCALEYEDIAGFSM_ERR) { + al_err("%s: eye measure error!\n", __func__); + return -1; + } + + if (!(status & SERDES_IREG_FLD_RXCALEYEDIAGFSM_DONE)) { + al_err("%s: eye measure timeout!\n", __func__); + return -1; + } + + /* Read Eye Opening Metrics, Bits: + * SERDES_IREG_FLD_RXCALEYEDIAGFSM_EYESUM_LSB, + * SERDES_IREG_FLD_RXCALEYEDIAGFSM_EYESUM_LSB + */ + al_serdes_lane_read( + obj, grp, lane, AL_SRDS_REG_TYPE_PMA, + SERDES_IREG_FLD_RXCALEYEDIAGFSM_EYESUM_MSB_REG_NUM, + ®_value ); + *width = reg_value << 6; + al_serdes_lane_read( + obj, grp, lane, AL_SRDS_REG_TYPE_PMA, + SERDES_IREG_FLD_RXCALEYEDIAGFSM_EYESUM_LSB_REG_NUM, + ®_value ); + *width =+ reg_value & SERDES_IREG_FLD_RXCALEYEDIAGFSM_EYESUM_LSB_MAKE; + + /* + * Clear Bit: + * SERDES_IREG_FLD_RXCALEYEDIAGFSMIN_START, + * to stop Eye measurement + */ + al_serdes_grp_lane_masked_write(&obj->grp_info[grp], + lane, + AL_SRDS_REG_TYPE_PMA, + SERDES_IREG_FLD_RXCALEYEDIAGFSMIN_START_REG_NUM, + SERDES_IREG_FLD_RXCALEYEDIAGFSMIN_START, + 0); + + /* Height Calculation */ + + /* Return Value = 1*Y + 0*X */ + al_serdes_reg_write(obj, grp, AL_SRDS_REG_PAGE_4_COMMON, + AL_SRDS_REG_TYPE_PMA, + SERDES_IREG_FLD_RXCALEYEDIAGFSM_X_Y_VALWEIGHT_REG_NUM, + 0x10); + /* X coarse scan step = 0 */ + al_serdes_reg_write(obj, grp, AL_SRDS_REG_PAGE_4_COMMON, + AL_SRDS_REG_TYPE_PMA, + SERDES_IREG_FLD_RXCALEYEDIAGFSM_XVALCOARSE_REG_NUM, + 0x00); + /* X fine scan step = 0 */ + al_serdes_reg_write(obj, grp, AL_SRDS_REG_PAGE_4_COMMON, + AL_SRDS_REG_TYPE_PMA, + SERDES_IREG_FLD_RXCALEYEDIAGFSM_XVALFINE_REG_NUM, + 0x00); + /* Y coarse scan step = 3 */ + al_serdes_reg_write(obj, grp, AL_SRDS_REG_PAGE_4_COMMON, + AL_SRDS_REG_TYPE_PMA, + SERDES_IREG_FLD_RXCALEYEDIAGFSM_YVALCOARSE_REG_NUM, + 0x03); + /* Y fine scan step = 1 */ + al_serdes_reg_write(obj, grp, AL_SRDS_REG_PAGE_4_COMMON, + AL_SRDS_REG_TYPE_PMA, + SERDES_IREG_FLD_RXCALEYEDIAGFSM_YVALFINE_REG_NUM, + 0x01); + + /* + * Set Bit: + * SERDES_IREG_FLD_RXCALEYEDIAGFSMIN_START, + * to start Eye measurement + */ + al_serdes_grp_lane_masked_write(&obj->grp_info[grp], + lane, + AL_SRDS_REG_TYPE_PMA, + SERDES_IREG_FLD_RXCALEYEDIAGFSMIN_START_REG_NUM, + SERDES_IREG_FLD_RXCALEYEDIAGFSMIN_START, + SERDES_IREG_FLD_RXCALEYEDIAGFSMIN_START); + + for( i = 0; i < AL_SERDES_RX_EYE_CAL_TRIES; ++i ) { + /* Check if RxEQ Cal is done */ + al_serdes_lane_read( + obj, grp, lane, AL_SRDS_REG_TYPE_PMA, + SERDES_IREG_FLD_RXCALEYEDIAGFSM_DONE_REG_NUM, + &status ); + if (status & SERDES_IREG_FLD_RXCALEYEDIAGFSM_DONE) + break; + al_msleep(AL_SERDES_RX_EYE_CAL_MDELAY); + } + + if (status & SERDES_IREG_FLD_RXCALEYEDIAGFSM_ERR) { + al_err("%s: eye measure error!\n", __func__); + return -1; + } + + if (!(status & SERDES_IREG_FLD_RXCALEYEDIAGFSM_DONE)) { + al_err("%s: eye measure timeout!\n", __func__); + return -1; + } + + /* Read Eye Opening Metrics, Bits: + * SERDES_IREG_FLD_RXCALEYEDIAGFSM_EYESUM_LSB, + * SERDES_IREG_FLD_RXCALEYEDIAGFSM_EYESUM_LSB + */ + al_serdes_lane_read( + obj, grp, lane, AL_SRDS_REG_TYPE_PMA, + SERDES_IREG_FLD_RXCALEYEDIAGFSM_EYESUM_MSB_REG_NUM, + ®_value ); + *height = reg_value << 6; + al_serdes_lane_read( + obj, grp, lane, AL_SRDS_REG_TYPE_PMA, + SERDES_IREG_FLD_RXCALEYEDIAGFSM_EYESUM_LSB_REG_NUM, + ®_value ); + *height =+ reg_value & SERDES_IREG_FLD_RXCALEYEDIAGFSM_EYESUM_LSB_MAKE; + + /* + * Clear Bit: + * SERDES_IREG_FLD_RXCALEYEDIAGFSMIN_START, + * to stop Eye measurement + */ + al_serdes_grp_lane_masked_write(&obj->grp_info[grp], + lane, + AL_SRDS_REG_TYPE_PMA, + SERDES_IREG_FLD_RXCALEYEDIAGFSMIN_START_REG_NUM, + SERDES_IREG_FLD_RXCALEYEDIAGFSMIN_START, + 0); + + /* Restore Registers */ + al_serdes_reg_write(obj, grp, AL_SRDS_REG_PAGE_4_COMMON, + AL_SRDS_REG_TYPE_PMA, + SERDES_IREG_FLD_RXCALEYEDIAGFSM_X_Y_VALWEIGHT_REG_NUM, + rxcaleyediagfsm_x_y_valweight_val); + al_serdes_reg_write(obj, grp, AL_SRDS_REG_PAGE_4_COMMON, + AL_SRDS_REG_TYPE_PMA, + SERDES_IREG_FLD_RXCALEYEDIAGFSM_XVALCOARSE_REG_NUM, + rxcaleyediagfsm_xvalcoarse_val); + al_serdes_reg_write(obj, grp, AL_SRDS_REG_PAGE_4_COMMON, + AL_SRDS_REG_TYPE_PMA, + SERDES_IREG_FLD_RXCALEYEDIAGFSM_XVALFINE_REG_NUM, + rxcaleyediagfsm_xvalfine_val); + al_serdes_reg_write(obj, grp, AL_SRDS_REG_PAGE_4_COMMON, + AL_SRDS_REG_TYPE_PMA, + SERDES_IREG_FLD_RXCALEYEDIAGFSM_YVALCOARSE_REG_NUM, + rxcaleyediagfsm_yvalcoarse_val); + al_serdes_reg_write(obj, grp, AL_SRDS_REG_PAGE_4_COMMON, + AL_SRDS_REG_TYPE_PMA, + SERDES_IREG_FLD_RXCALEYEDIAGFSM_YVALFINE_REG_NUM, + rxcaleyediagfsm_yvalfine_val); + + al_serdes_lane_write(obj, grp, lane, AL_SRDS_REG_TYPE_PMA, + SERDES_IREG_FLD_RXLOCK2REF_LOCWREN_REG_NUM, + rxlock2ref_locwren_val); + al_serdes_lane_write(obj, grp, lane, AL_SRDS_REG_TYPE_PMA, + SERDES_IREG_FLD_RXCAL_LOCWREN_REG_NUM, + rxcal_locwren_val); + al_serdes_lane_write(obj, grp, lane, AL_SRDS_REG_TYPE_PMA, + SERDES_IREG_FLD_RXCALROAMYADJUST_LOCWREN_REG_NUM, + rxcalroamyadjust_locwren_val); + al_serdes_lane_write(obj, grp, lane, AL_SRDS_REG_TYPE_PMA, + SERDES_IREG_FLD_RXLOCK2REF_OVREN_REG_NUM, + rxlock2ref_ovren_val); + return 0; +} + +void al_serdes_sris_config( + struct al_serdes_obj *obj, + enum al_serdes_group grp, + struct al_serdes_sris_params *params) +{ + struct al_serdes_group_info *grp_info = &obj->grp_info[grp]; + + al_serdes_reg_write(obj, grp, AL_SRDS_REG_PAGE_4_COMMON, AL_SRDS_REG_TYPE_PMA, + SERDES_IREG_FLD_PPMDRIFTCOUNT1_REG_NUM, + (params->ppm_drift_count & AL_FIELD_MASK(7, 0)) >> 0); + al_serdes_reg_write(obj, grp, AL_SRDS_REG_PAGE_4_COMMON, AL_SRDS_REG_TYPE_PMA, + SERDES_IREG_FLD_PPMDRIFTCOUNT2_REG_NUM, + (params->ppm_drift_count & AL_FIELD_MASK(15, 8)) >> 8); + + al_serdes_reg_write(obj, grp, AL_SRDS_REG_PAGE_4_COMMON, AL_SRDS_REG_TYPE_PMA, + SERDES_IREG_FLD_PPMDRIFTMAX1_REG_NUM, + (params->ppm_drift_max & AL_FIELD_MASK(7, 0)) >> 0); + al_serdes_reg_write(obj, grp, AL_SRDS_REG_PAGE_4_COMMON, AL_SRDS_REG_TYPE_PMA, + SERDES_IREG_FLD_PPMDRIFTMAX2_REG_NUM, + (params->ppm_drift_max & AL_FIELD_MASK(15, 8)) >> 8); + + al_serdes_reg_write(obj, grp, AL_SRDS_REG_PAGE_4_COMMON, AL_SRDS_REG_TYPE_PMA, + SERDES_IREG_FLD_SYNTHPPMDRIFTMAX1_REG_NUM, + (params->synth_ppm_drift_max & AL_FIELD_MASK(7, 0)) >> 0); + al_serdes_reg_write(obj, grp, AL_SRDS_REG_PAGE_4_COMMON, AL_SRDS_REG_TYPE_PMA, + SERDES_IREG_FLD_SYNTHPPMDRIFTMAX2_REG_NUM, + (params->synth_ppm_drift_max & AL_FIELD_MASK(15, 8)) >> 8); + + al_serdes_grp_reg_masked_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON, AL_SRDS_REG_TYPE_PCS, + SERDES_IREG_FLD_PCS_EBUF_FULL_D2R1_REG_NUM, + SERDES_IREG_FLD_PCS_EBUF_FULL_D2R1_REG_MASK, + (params->full_d2r1) + << SERDES_IREG_FLD_PCS_EBUF_FULL_D2R1_REG_SHIFT); + + al_serdes_grp_reg_masked_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON, AL_SRDS_REG_TYPE_PCS, + SERDES_IREG_FLD_PCS_EBUF_FULL_PCIE_G3_REG_NUM, + SERDES_IREG_FLD_PCS_EBUF_FULL_PCIE_G3_REG_MASK, + (params->full_pcie_g3) + << SERDES_IREG_FLD_PCS_EBUF_FULL_PCIE_G3_REG_SHIFT); + + al_serdes_grp_reg_masked_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON, AL_SRDS_REG_TYPE_PCS, + SERDES_IREG_FLD_PCS_EBUF_RD_THRESHOLD_D2R1_REG_NUM, + SERDES_IREG_FLD_PCS_EBUF_RD_THRESHOLD_D2R1_REG_MASK, + (params->rd_threshold_d2r1) + << SERDES_IREG_FLD_PCS_EBUF_RD_THRESHOLD_D2R1_REG_SHIFT); + + al_serdes_grp_reg_masked_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON, AL_SRDS_REG_TYPE_PCS, + SERDES_IREG_FLD_PCS_EBUF_RD_THRESHOLD_PCIE_G3_REG_NUM, + SERDES_IREG_FLD_PCS_EBUF_RD_THRESHOLD_PCIE_G3_REG_MASK, + (params->rd_threshold_pcie_g3) + << SERDES_IREG_FLD_PCS_EBUF_RD_THRESHOLD_PCIE_G3_REG_SHIFT); +} diff --git a/al_hal_serdes.h b/al_hal_serdes.h new file mode 100644 index 00000000000..37aec839b2f --- /dev/null +++ b/al_hal_serdes.h @@ -0,0 +1,1125 @@ +/*- +******************************************************************************* +Copyright (C) 2015 Annapurna Labs Ltd. + +This file may be licensed under the terms of the Annapurna Labs Commercial +License Agreement. + +Alternatively, this file can be distributed under the terms of the GNU General +Public License V2 as published by the Free Software Foundation and can be +found at http://www.gnu.org/licenses/gpl-2.0.html + +Alternatively, redistribution and use in source and binary forms, with or +without modification, are permitted provided that the following conditions are +met: + + * Redistributions of source code must retain the above copyright notice, +this list of conditions and the following disclaimer. + + * Redistributions in binary form must reproduce the above copyright +notice, this list of conditions and the following disclaimer in +the documentation and/or other materials provided with the +distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +*******************************************************************************/ + +/** + * @defgroup group_serdes_api API + * SerDes HAL driver API + * @ingroup group_serdes SerDes + * @{ + * + * @file al_hal_serdes.h + * + * @brief Header file for the SerDes HAL driver + * + */ + +#ifndef __AL_HAL_SERDES_H__ +#define __AL_HAL_SERDES_H__ + +#include "al_hal_common.h" + +/* *INDENT-OFF* */ +#ifdef __cplusplus +extern "C" { +#endif +/* *INDENT-ON* */ + +struct al_serdes_obj; + +enum al_serdes_group { + AL_SRDS_GRP_A = 0, + AL_SRDS_GRP_B, + AL_SRDS_GRP_C, + AL_SRDS_GRP_D, + + AL_SRDS_NUM_GROUPS, +}; + +struct al_serdes_group_info { + /* + * Group parent object - filled automatically by al_serdes_handle_init + */ + struct al_serdes_obj *pobj; + + /* + * Group specific register base - filled automatically by + * al_sedres_handle_init + */ + struct al_serdes_regs __iomem *regs_base; +}; + +struct al_serdes_obj { + struct al_serdes_group_info grp_info[AL_SRDS_NUM_GROUPS]; +}; + +enum al_serdes_reg_page { + AL_SRDS_REG_PAGE_0_LANE_0 = 0, + AL_SRDS_REG_PAGE_1_LANE_1, + AL_SRDS_REG_PAGE_2_LANE_2, + AL_SRDS_REG_PAGE_3_LANE_3, + AL_SRDS_REG_PAGE_4_COMMON, + AL_SRDS_REG_PAGE_0123_LANES_0123 = 7, +}; + +enum al_serdes_reg_type { + AL_SRDS_REG_TYPE_PMA = 0, + AL_SRDS_REG_TYPE_PCS, +}; + +enum al_serdes_lane { + AL_SRDS_LANE_0 = AL_SRDS_REG_PAGE_0_LANE_0, + AL_SRDS_LANE_1 = AL_SRDS_REG_PAGE_1_LANE_1, + AL_SRDS_LANE_2 = AL_SRDS_REG_PAGE_2_LANE_2, + AL_SRDS_LANE_3 = AL_SRDS_REG_PAGE_3_LANE_3, + + AL_SRDS_NUM_LANES, + AL_SRDS_LANES_0123 = AL_SRDS_REG_PAGE_0123_LANES_0123, +}; + +/** Serdes loopback mode */ +enum al_serdes_lb_mode { + /** No loopback */ + AL_SRDS_LB_MODE_OFF, + + /** + * Transmits the untimed, partial equalized RX signal out the transmit + * IO pins. + * No clock used (untimed) + */ + AL_SRDS_LB_MODE_PMA_IO_UN_TIMED_RX_TO_TX, + + /** + * Loops back the TX serializer output into the CDR. + * CDR recovered bit clock used (without attenuation) + */ + AL_SRDS_LB_MODE_PMA_INTERNALLY_BUFFERED_SERIAL_TX_TO_RX, + + /** + * Loops back the TX driver IO signal to the RX IO pins + * CDR recovered bit clock used (only through IO) + */ + AL_SRDS_LB_MODE_PMA_SERIAL_TX_IO_TO_RX_IO, + + /** + * Parallel loopback from the PMA receive lane data ports, to the + * transmit lane data ports + * CDR recovered bit clock used + */ + AL_SRDS_LB_MODE_PMA_PARALLEL_RX_TO_TX, + + /** Loops received data after elastic buffer to transmit path */ + AL_SRDS_LB_MODE_PCS_PIPE, + + /** Loops TX data (to PMA) to RX path (instead of PMA data) */ + AL_SRDS_LB_MODE_PCS_NEAR_END, + + /** Loops receive data prior to interface block to transmit path */ + AL_SRDS_LB_MODE_PCS_FAR_END, +}; + +/** Serdes BIST pattern */ +enum al_serdes_bist_pattern { + AL_SRDS_BIST_PATTERN_USER, + AL_SRDS_BIST_PATTERN_PRBS7, + AL_SRDS_BIST_PATTERN_PRBS23, + AL_SRDS_BIST_PATTERN_PRBS31, + AL_SRDS_BIST_PATTERN_CLK1010, +}; + +/** SerDes group rate */ +enum al_serdes_rate { + AL_SRDS_RATE_1_8, + AL_SRDS_RATE_1_4, + AL_SRDS_RATE_1_2, + AL_SRDS_RATE_FULL, +}; + +/** SerDes power mode */ +enum al_serdes_pm { + AL_SRDS_PM_PD, + AL_SRDS_PM_P2, + AL_SRDS_PM_P1, + AL_SRDS_PM_P0S, + AL_SRDS_PM_P0, +}; + +/** SerDes PCIe Rate - values are important for proper behavior */ +enum al_serdes_pcie_rate { + AL_SRDS_PCIE_RATE_GEN1 = 0, + AL_SRDS_PCIE_RATE_GEN2, + AL_SRDS_PCIE_RATE_GEN3, +}; + +/** + * Initializes a SERDES object + * + * @param serdes_regs_base + * The SERDES register file base pointer + * + * @param obj + * An allocated, non initialized object context + * + * + * @return 0 if no error found. + * + */ +int al_serdes_handle_init( + void __iomem *serdes_regs_base, + struct al_serdes_obj *obj); + +/** + * SERDES register read + * + * Reads a SERDES register + * + * @param obj + * The object context + * + * @param grp + * The SERDES group + * + * @param page + * The SERDES register page within the group + * + * @param type + * The SERDES register type (PMA /PCS) + * + * @param offset + * The SERDES register offset (0 - 4095) + * + * @param data + * The read data + * + * + * @return 0 if no error found. + * + */ +int al_serdes_reg_read( + struct al_serdes_obj *obj, + enum al_serdes_group grp, + enum al_serdes_reg_page page, + enum al_serdes_reg_type type, + uint16_t offset, + uint8_t *data); + +/** + * SERDES register write + * + * Writes a SERDES register + * + * @param obj + * The object context + * + * @param grp + * The SERDES group + * + * @param page + * The SERDES register page within the group + * + * @param type + * The SERDES register type (PMA /PCS) + * + * @param offset + * The SERDES register offset (0 - 4095) + * + * @param data + * The data to write + * + * + * @return 0 if no error found. + * + */ +int al_serdes_reg_write( + struct al_serdes_obj *obj, + enum al_serdes_group grp, + enum al_serdes_reg_page page, + enum al_serdes_reg_type type, + uint16_t offset, + uint8_t data); + +/** + * Enable BIST required overrides + * + * @param obj + * The object context + * @param grp + * The SERDES group + * @param rate + * The required speed rate + */ +void al_serdes_bist_overrides_enable( + struct al_serdes_obj *obj, + enum al_serdes_group grp, + enum al_serdes_rate rate); + +/** + * Disable BIST required overrides + * + * @param obj + * The object context + * @param grp + * The SERDES group + * @param rate + * The required speed rate + */ +void al_serdes_bist_overrides_disable( + struct al_serdes_obj *obj, + enum al_serdes_group grp); + +/** + * Rx rate change + * + * @param obj + * The object context + * @param grp + * The SERDES group + * @param rate + * The Rx required rate + */ +void al_serdes_rx_rate_change( + struct al_serdes_obj *obj, + enum al_serdes_group grp, + enum al_serdes_rate rate); + +/** + * SERDES lane Rx rate change software flow enable + * + * @param obj + * The object context + * @param grp + * The SERDES group + * @param lane + * The SERDES lane within the group + */ +void al_serdes_lane_rx_rate_change_sw_flow_en( + struct al_serdes_obj *obj, + enum al_serdes_group grp, + enum al_serdes_lane lane); + +/** + * SERDES lane Rx rate change software flow disable + * + * @param obj + * The object context + * @param grp + * The SERDES group + * @param lane + * The SERDES lane within the group + */ +void al_serdes_lane_rx_rate_change_sw_flow_dis( + struct al_serdes_obj *obj, + enum al_serdes_group grp, + enum al_serdes_lane lane); + +/** + * PCIe lane rate override check + * + * @param obj + * The object context + * @param grp + * The SERDES group + * @param lane + * The SERDES lane within the group + * @returns AL_TRUE if the override is enabled + */ +al_bool al_serdes_lane_pcie_rate_override_is_enabled( + struct al_serdes_obj *obj, + enum al_serdes_group grp, + enum al_serdes_lane lane); + +/** + * PCIe lane rate override control + * + * @param obj + * The object context + * @param grp + * The SERDES group + * @param lane + * The SERDES lane within the group + * @param en + * Enable/disable + */ +void al_serdes_lane_pcie_rate_override_enable_set( + struct al_serdes_obj *obj, + enum al_serdes_group grp, + enum al_serdes_lane lane, + al_bool en); + +/** + * PCIe lane rate get + * + * @param obj + * The object context + * @param grp + * The SERDES group + * @param lane + * The SERDES lane within the group + */ +enum al_serdes_pcie_rate al_serdes_lane_pcie_rate_get( + struct al_serdes_obj *obj, + enum al_serdes_group grp, + enum al_serdes_lane lane); + +/** + * PCIe lane rate set + * + * @param obj + * The object context + * @param grp + * The SERDES group + * @param lane + * The SERDES lane within the group + * @param rate + * The required rate + */ +void al_serdes_lane_pcie_rate_set( + struct al_serdes_obj *obj, + enum al_serdes_group grp, + enum al_serdes_lane lane, + enum al_serdes_pcie_rate rate); + +/** + * SERDES group power mode control + * + * @param obj + * The object context + * @param grp + * The SERDES group + * @param pm + * The required power mode + */ +void al_serdes_group_pm_set( + struct al_serdes_obj *obj, + enum al_serdes_group grp, + enum al_serdes_pm pm); + +/** + * SERDES lane power mode control + * + * @param obj + * The object context + * @param grp + * The SERDES group + * @param lane + * The SERDES lane within the group + * @param rx_pm + * The required RX power mode + * @param tx_pm + * The required TX power mode + */ +void al_serdes_lane_pm_set( + struct al_serdes_obj *obj, + enum al_serdes_group grp, + enum al_serdes_lane lane, + enum al_serdes_pm rx_pm, + enum al_serdes_pm tx_pm); + +/** + * SERDES group PMA hard reset + * + * Controls Serdes group PMA hard reset + * + * @param obj + * The object context + * + * @param grp + * The SERDES group + * + * @param enable + * Enable/disable hard reset + */ +void al_serdes_pma_hard_reset_group( + struct al_serdes_obj *obj, + enum al_serdes_group grp, + al_bool enable); + +/** + * SERDES lane PMA hard reset + * + * Controls Serdes lane PMA hard reset + * + * @param obj + * The object context + * + * @param grp + * The SERDES group + * + * @param lane + * The SERDES lane within the group + * + * @param enable + * Enable/disable hard reset + */ +void al_serdes_pma_hard_reset_lane( + struct al_serdes_obj *obj, + enum al_serdes_group grp, + enum al_serdes_lane lane, + al_bool enable); + +/** + * SERDES loopback control + * + * Controls the loopback + * + * @param obj + * The object context + * + * @param grp + * The SERDES group + * + * @param lane + * The SERDES lane within the group + * + * @param mode + * The requested loopback mode + * + */ +void al_serdes_loopback_control( + struct al_serdes_obj *obj, + enum al_serdes_group grp, + enum al_serdes_lane lane, + enum al_serdes_lb_mode mode); + +/** + * SERDES BIST pattern selection + * + * Selects the BIST pattern to be used + * + * @param obj + * The object context + * + * @param grp + * The SERDES group + * + * @param pattern + * The pattern to set + * + * @param user_data + * The pattern user data (when pattern == AL_SRDS_BIST_PATTERN_USER) + * 80 bits (8 bytes array) + * + */ +void al_serdes_bist_pattern_select( + struct al_serdes_obj *obj, + enum al_serdes_group grp, + enum al_serdes_bist_pattern pattern, + uint8_t *user_data); + +/** + * SERDES BIST TX Enable + * + * Enables/disables TX BIST per lane + * + * @param obj + * The object context + * + * @param grp + * The SERDES group + * + * @param lane + * The SERDES lane within the group + * + * @param enable + * Enable or disable TX BIST + */ +void al_serdes_bist_tx_enable( + struct al_serdes_obj *obj, + enum al_serdes_group grp, + enum al_serdes_lane lane, + al_bool enable); + +/** + * SERDES BIST TX single bit error injection + * + * Injects single bit error during a TX BIST + * + * @param obj + * The object context + * + * @param grp + * The SERDES group + */ +void al_serdes_bist_tx_err_inject( + struct al_serdes_obj *obj, + enum al_serdes_group grp); + +/** + * SERDES BIST RX Enable + * + * Enables/disables RX BIST per lane + * + * @param obj + * The object context + * + * @param grp + * The SERDES group + * + * @param lane + * The SERDES lane within the group + * + * @param enable + * Enable or disable TX BIST + */ +void al_serdes_bist_rx_enable( + struct al_serdes_obj *obj, + enum al_serdes_group grp, + enum al_serdes_lane lane, + al_bool enable); + +/** + * SERDES BIST RX status + * + * Checks the RX BIST status for a specific SERDES lane + * + * @param obj + * The object context + * + * @param grp + * The SERDES group + * + * @param lane + * The SERDES lane within the group + * + * @param is_locked + * An indication whether RX BIST is locked + * + * @param err_cnt_overflow + * An indication whether error count overflow occured + * + * @param err_cnt + * Current bit error count + */ +void al_serdes_bist_rx_status( + struct al_serdes_obj *obj, + enum al_serdes_group grp, + enum al_serdes_lane lane, + al_bool *is_locked, + al_bool *err_cnt_overflow, + uint16_t *err_cnt); + +/** + * SERDES Digital Test Bus + * + * Samples the digital test bus of a specific SERDES lane + * + * @param obj + * The object context + * + * @param grp + * The SERDES group + * + * @param lane + * The SERDES lane within the group + * + * @param sel + * The selected sampling group (0 - 31) + * + * @param sampled_data + * The sampled data (5 bytes array) + * + * + * @return 0 if no error found. + * + */ +int al_serdes_digital_test_bus( + struct al_serdes_obj *obj, + enum al_serdes_group grp, + enum al_serdes_lane lane, + uint8_t sel, + uint8_t *sampled_data); + + +/* KR link training */ +/** + * Set the tx de-emphasis to preset values + * + * @param obj The object context + * + * @param grp The SERDES group + * + * @param lane The SERDES lane within the group + * + */ +void al_serdes_tx_deemph_preset( + struct al_serdes_obj *obj, + enum al_serdes_group grp, + enum al_serdes_lane lane); + +/** + * Tx de-emphasis parameters + */ +enum al_serdes_tx_deemph_param { + AL_SERDES_TX_DEEMP_C_ZERO, /*< c(0) */ + AL_SERDES_TX_DEEMP_C_PLUS, /*< c(1) */ + AL_SERDES_TX_DEEMP_C_MINUS, /*< c(-1) */ +}; + +/** + * Increase tx de-emphasis param. + * + * @param obj The object context + * + * @param grp The SERDES group + * + * @param lane The SERDES lane within the group + * + * @param param which tx de-emphasis to change + * + * @return false in case max is reached. true otherwise. + */ +al_bool al_serdes_tx_deemph_inc( + struct al_serdes_obj *obj, + enum al_serdes_group grp, + enum al_serdes_lane lane, + enum al_serdes_tx_deemph_param param); + +/** + * Decrease tx de-emphasis param. + * + * @param obj The object context + * + * @param grp The SERDES group + * + * @param lane The SERDES lane within the group + * + * @param param which tx de-emphasis to change + * + * @return false in case min is reached. true otherwise. + */ +al_bool al_serdes_tx_deemph_dec( + struct al_serdes_obj *obj, + enum al_serdes_group grp, + enum al_serdes_lane lane, + enum al_serdes_tx_deemph_param param); + +/** + * run Rx eye measurement. + * + * @param obj The object context + * + * @param grp The SERDES group + * + * @param lane The SERDES lane within the group + * + * @param timeout timeout in uSec + * + * @param value Rx eye measurement value + * (0 - completely closed eye, 0xffff - completely open eye). + * + * @return 0 if no error found. + */ +int al_serdes_eye_measure_run( + struct al_serdes_obj *obj, + enum al_serdes_group grp, + enum al_serdes_lane lane, + uint32_t timeout, + unsigned int *value); + +/** + * Eye diagram single sampling + * + * @param obj The object context + * + * @param grp The SERDES group + * + * @param lane The SERDES lane within the group + * + * @param x Sampling X position (0 - 63 --> -1.00 UI ... 1.00 UI) + * + * @param y Sampling Y position (0 - 62 --> 500mV ... -500mV) + * + * @param timeout timeout in uSec + * + * @param value Eye diagram sample value (BER - 0x0000 - 0xffff) + * + * @return 0 if no error found. + */ +int al_serdes_eye_diag_sample( + struct al_serdes_obj *obj, + enum al_serdes_group grp, + enum al_serdes_lane lane, + unsigned int x, + int y, + unsigned int timeout, + unsigned int *value); + +/** + * Check if signal is detected + * + * @param obj The object context + * + * @param grp The SERDES group + * + * @param lane The SERDES lane within the group + * + * @return true if signal is detected. false otherwise. + */ +al_bool al_serdes_signal_is_detected( + struct al_serdes_obj *obj, + enum al_serdes_group grp, + enum al_serdes_lane lane); + + +struct al_serdes_adv_tx_params { + /* + * select the input values location. + * When set to true the values will be taken from the internal registers + * that will be override with the next following parameters. + * When set to false the values will be taken from external pins (the + * other parameters in this case is not needed) + */ + al_bool override; + /* + * Transmit Amplitude control signal. Used to define the full-scale + * maximum swing of the driver. + * 000 - Not Supported + * 001 - 952mVdiff-pkpk + * 010 - 1024mVdiff-pkpk + * 011 - 1094mVdiff-pkpk + * 100 - 1163mVdiff-pkpk + * 101 - 1227mVdiff-pkpk + * 110 - 1283mVdiff-pkpk + * 111 - 1331mVdiff-pkpk + */ + uint8_t amp; + /* Defines the total number of driver units allocated in the driver */ + uint8_t total_driver_units; + /* Defines the total number of driver units allocated to the + * first post-cursor (C+1) tap. */ + uint8_t c_plus_1; + /* Defines the total number of driver units allocated to the + * second post-cursor (C+2) tap. */ + uint8_t c_plus_2; + /* Defines the total number of driver units allocated to the + * first pre-cursor (C-1) tap. */ + uint8_t c_minus_1; + /* TX driver Slew Rate control: + * 00 - 31ps + * 01 - 33ps + * 10 - 68ps + * 11 - 170ps + */ + uint8_t slew_rate; +}; + +struct al_serdes_adv_rx_params { + /* + * select the input values location. + * When set to true the values will be taken from the internal registers + * that will be override with the next following parameters. + * When set to false the values will be taken based in the equalization + * results (the other parameters in this case is not needed) + */ + al_bool override; + /* RX agc high frequency dc gain: + * -3'b000: -3dB + * -3'b001: -2.5dB + * -3'b010: -2dB + * -3'b011: -1.5dB + * -3'b100: -1dB + * -3'b101: -0.5dB + * -3'b110: -0dB + * -3'b111: 0.5dB + */ + uint8_t dcgain; + /* DFE post-shaping tap 3dB frequency + * -3'b000: 684MHz + * -3'b001: 576MHz + * -3'b010: 514MHz + * -3'b011: 435MHz + * -3'b100: 354MHz + * -3'b101: 281MHz + * -3'b110: 199MHz + * -3'b111: 125MHz + */ + uint8_t dfe_3db_freq; + /* DFE post-shaping tap gain + * 0: no pulse shaping tap + * 1: -24mVpeak + * 2: -45mVpeak + * 3: -64mVpeak + * 4: -80mVpeak + * 5: -93mVpeak + * 6: -101mVpeak + * 7: -105mVpeak + */ + uint8_t dfe_gain; + /* DFE first tap gain control + * -4'b0000: +1mVpeak + * -4'b0001: +10mVpeak + * .... + * -4'b0110: +55mVpeak + * -4'b0111: +64mVpeak + * -4'b1000: -1mVpeak + * -4'b1001: -10mVpeak + * .... + * -4'b1110: -55mVpeak + * -4'b1111: -64mVpeak + */ + uint8_t dfe_first_tap_ctrl; + /* DFE second tap gain control + * -4'b0000: +0mVpeak + * -4'b0001: +9mVpeak + * .... + * -4'b0110: +46mVpeak + * -4'b0111: +53mVpeak + * -4'b1000: -0mVpeak + * -4'b1001: -9mVpeak + * .... + * -4'b1110: -46mVpeak + * -4'b1111: -53mVpeak + */ + uint8_t dfe_secound_tap_ctrl; + /* DFE third tap gain control + * -4'b0000: +0mVpeak + * -4'b0001: +7mVpeak + * .... + * -4'b0110: +38mVpeak + * -4'b0111: +44mVpeak + * -4'b1000: -0mVpeak + * -4'b1001: -7mVpeak + * .... + * -4'b1110: -38mVpeak + * -4'b1111: -44mVpeak + */ + uint8_t dfe_third_tap_ctrl; + /* DFE fourth tap gain control + * -4'b0000: +0mVpeak + * -4'b0001: +6mVpeak + * .... + * -4'b0110: +29mVpeak + * -4'b0111: +33mVpeak + * -4'b1000: -0mVpeak + * -4'b1001: -6mVpeak + * .... + * -4'b1110: -29mVpeak + * -4'b1111: -33mVpeak + */ + uint8_t dfe_fourth_tap_ctrl; + /* Low frequency agc gain (att) select + * -3'b000: Disconnected + * -3'b001: -18.5dB + * -3'b010: -12.5dB + * -3'b011: -9dB + * -3'b100: -6.5dB + * -3'b101: -4.5dB + * -3'b110: -2.9dB + * -3'b111: -1.6dB + */ + uint8_t low_freq_agc_gain; + /* Provides a RX Equalizer pre-hint, prior to beginning + * adaptive equalization */ + uint8_t precal_code_sel; + /* High frequency agc boost control + * Min d0: Boost ~4dB + * Max d31: Boost ~20dB + */ + uint8_t high_freq_agc_boost; +}; + +/** + * configure tx advanced parameters + * + * @param obj The object context + * + * @param grp The SERDES group + * + * @param lane The SERDES lane within the group + * + * @param params pointer to the tx parameters + */ +void al_serdes_tx_advanced_params_set(struct al_serdes_obj *obj, + enum al_serdes_group grp, + enum al_serdes_lane lane, + struct al_serdes_adv_tx_params *params); + +/** + * read tx advanced parameters + * + * @param obj The object context + * + * @param grp The SERDES group + * + * @param lane The SERDES lane within the group + * + * @param params pointer to the tx parameters + */ +void al_serdes_tx_advanced_params_get(struct al_serdes_obj *obj, + enum al_serdes_group grp, + enum al_serdes_lane lane, + struct al_serdes_adv_tx_params *params); + +/** + * configure rx advanced parameters + * + * @param obj The object context + * + * @param grp The SERDES group + * + * @param lane The SERDES lane within the group + * + * @param params pointer to the rx parameters + */ +void al_serdes_rx_advanced_params_set(struct al_serdes_obj *obj, + enum al_serdes_group grp, + enum al_serdes_lane lane, + struct al_serdes_adv_rx_params *params); + +/** + * read rx advanced parameters + * + * @param obj The object context + * + * @param grp The SERDES group + * + * @param lane The SERDES lane within the group + * + * @param params pointer to the rx parameters + */ +void al_serdes_rx_advanced_params_get(struct al_serdes_obj *obj, + enum al_serdes_group grp, + enum al_serdes_lane lane, + struct al_serdes_adv_rx_params* params); + +/** + * Switch entire SerDes group to SGMII mode based on 156.25 Mhz reference clock + * + * @param obj The object context + * + * @param grp The SERDES group + */ +void al_serdes_mode_set_sgmii( + struct al_serdes_obj *obj, + enum al_serdes_group grp); + +/** + * Switch entire SerDes group to KR mode based on 156.25 Mhz reference clock + * + * @param obj The object context + * + * @param grp The SERDES group + */ +void al_serdes_mode_set_kr( + struct al_serdes_obj *obj, + enum al_serdes_group grp); + +/** + * performs SerDes HW equalization test and update equalization parameters + * + * @param obj the object context + * + * @param grp the SERDES group + * + * @param lane The SERDES lane within the group + */ +int al_serdes_rx_equalization( + struct al_serdes_obj *obj, + enum al_serdes_group grp, + enum al_serdes_lane lane); + +/** + * performs Rx equalization and compute the width and height of the eye + * + * @param obj the object context + * + * @param grp the SERDES group + * + * @param lane The SERDES lane within the group + * + * @param width the output width of the eye + * + * @param height the output height of the eye + */ +int al_serdes_calc_eye_size( + struct al_serdes_obj *obj, + enum al_serdes_group grp, + enum al_serdes_lane lane, + int* width, + int* height); + +/** + * SRIS parameters + */ +struct al_serdes_sris_params { + /* Controls the frequency accuracy threshold (ppm) for lock detection CDR */ + uint16_t ppm_drift_count; + /* Controls the frequency accuracy threshold (ppm) for lock detection in the CDR */ + uint16_t ppm_drift_max; + /* Controls the frequency accuracy threshold (ppm) for lock detection in PLL */ + uint16_t synth_ppm_drift_max; + /* Elastic buffer full threshold for PCIE modes: GEN1/GEN2 */ + uint8_t full_d2r1; + /* Elastic buffer full threshold for PCIE modes: GEN3 */ + uint8_t full_pcie_g3; + /* Elastic buffer midpoint threshold. + * Sets the depth of the buffer while in PCIE mode, GEN1/GEN2 + */ + uint8_t rd_threshold_d2r1; + /* Elastic buffer midpoint threshold. + * Sets the depth of the buffer while in PCIE mode, GEN3 + */ + uint8_t rd_threshold_pcie_g3; +}; + +/** + * SRIS: Separate Refclk Independent SSC (Spread Spectrum Clocking) + * Currently available only for PCIe interfaces. + * When working with local Refclk, same SRIS configuration in both serdes sides + * (EP and RC in PCIe interface) is required. + * + * performs SRIS configuration according to params + * + * @param obj the object context + * + * @param grp the SERDES group + * + * @param params the SRIS parameters + */ +void al_serdes_sris_config( + struct al_serdes_obj *obj, + enum al_serdes_group grp, + struct al_serdes_sris_params *params); + +/* *INDENT-OFF* */ +#ifdef __cplusplus +} +#endif + +/* *INDENT-ON* */ +#endif /* __AL_SRDS__ */ + +/** @} end of SERDES group */ + diff --git a/al_hal_serdes_internal_regs.h b/al_hal_serdes_internal_regs.h new file mode 100644 index 00000000000..8f53469bc4c --- /dev/null +++ b/al_hal_serdes_internal_regs.h @@ -0,0 +1,750 @@ +/*- +******************************************************************************* +Copyright (C) 2015 Annapurna Labs Ltd. + +This file may be licensed under the terms of the Annapurna Labs Commercial +License Agreement. + +Alternatively, this file can be distributed under the terms of the GNU General +Public License V2 as published by the Free Software Foundation and can be +found at http://www.gnu.org/licenses/gpl-2.0.html + +Alternatively, redistribution and use in source and binary forms, with or +without modification, are permitted provided that the following conditions are +met: + + * Redistributions of source code must retain the above copyright notice, +this list of conditions and the following disclaimer. + + * Redistributions in binary form must reproduce the above copyright +notice, this list of conditions and the following disclaimer in +the documentation and/or other materials provided with the +distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +*******************************************************************************/ +#ifndef __AL_SERDES_INTERNAL_REGS_H__ +#define __AL_SERDES_INTERNAL_REGS_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +/******************************************************************************* + * Per lane register fields + ******************************************************************************/ +/* + * RX and TX lane hard reset + * 0 - Hard reset is asserted + * 1 - Hard reset is de-asserted + */ +#define SERDES_IREG_FLD_CMNCTLPOR_HARDRSTBYPASS_REG_NUM 2 +#define SERDES_IREG_FLD_CMNCTLPOR_HARDRSTBYPASS_MASK 0x01 +#define SERDES_IREG_FLD_CMNCTLPOR_HARDRSTBYPASS_VAL_ASSERT 0x00 +#define SERDES_IREG_FLD_CMNCTLPOR_HARDRSTBYPASS_VAL_DEASSERT 0x01 + +/* + * RX and TX lane hard reset control + * 0 - Hard reset is taken from the interface pins + * 1 - Hard reset is taken from registers + */ +#define SERDES_IREG_FLD_CMNCTLPOR_HARDRSTBYPASSEN_REG_NUM 2 +#define SERDES_IREG_FLD_CMNCTLPOR_HARDRSTBYPASSEN_MASK 0x02 +#define SERDES_IREG_FLD_CMNCTLPOR_HARDRSTBYPASSEN_VAL_IFACE 0x00 +#define SERDES_IREG_FLD_CMNCTLPOR_HARDRSTBYPASSEN_VAL_REGS 0x02 + +/* RX lane power state control */ +#define SERDES_IREG_FLD_LANEPCSPSTATE_RX_REG_NUM 3 +#define SERDES_IREG_FLD_LANEPCSPSTATE_RX_MASK 0x1f +#define SERDES_IREG_FLD_LANEPCSPSTATE_RX_VAL_PD 0x01 +#define SERDES_IREG_FLD_LANEPCSPSTATE_RX_VAL_P2 0x02 +#define SERDES_IREG_FLD_LANEPCSPSTATE_RX_VAL_P1 0x04 +#define SERDES_IREG_FLD_LANEPCSPSTATE_RX_VAL_P0S 0x08 +#define SERDES_IREG_FLD_LANEPCSPSTATE_RX_VAL_P0 0x10 + +/* TX lane power state control */ +#define SERDES_IREG_FLD_LANEPCSPSTATE_TX_REG_NUM 4 +#define SERDES_IREG_FLD_LANEPCSPSTATE_TX_MASK 0x1f +#define SERDES_IREG_FLD_LANEPCSPSTATE_TX_VAL_PD 0x01 +#define SERDES_IREG_FLD_LANEPCSPSTATE_TX_VAL_P2 0x02 +#define SERDES_IREG_FLD_LANEPCSPSTATE_TX_VAL_P1 0x04 +#define SERDES_IREG_FLD_LANEPCSPSTATE_TX_VAL_P0S 0x08 +#define SERDES_IREG_FLD_LANEPCSPSTATE_TX_VAL_P0 0x10 + +/* RX lane word width */ +#define SERDES_IREG_FLD_PCSRX_DATAWIDTH_REG_NUM 5 +#define SERDES_IREG_FLD_PCSRX_DATAWIDTH_MASK 0x07 +#define SERDES_IREG_FLD_PCSRX_DATAWIDTH_VAL_8 0x00 +#define SERDES_IREG_FLD_PCSRX_DATAWIDTH_VAL_10 0x01 +#define SERDES_IREG_FLD_PCSRX_DATAWIDTH_VAL_16 0x02 +#define SERDES_IREG_FLD_PCSRX_DATAWIDTH_VAL_20 0x03 +#define SERDES_IREG_FLD_PCSRX_DATAWIDTH_VAL_32 0x04 +#define SERDES_IREG_FLD_PCSRX_DATAWIDTH_VAL_40 0x05 + +/* TX lane word width */ +#define SERDES_IREG_FLD_PCSTX_DATAWIDTH_REG_NUM 5 +#define SERDES_IREG_FLD_PCSTX_DATAWIDTH_MASK 0x70 +#define SERDES_IREG_FLD_PCSTX_DATAWIDTH_VAL_8 0x00 +#define SERDES_IREG_FLD_PCSTX_DATAWIDTH_VAL_10 0x10 +#define SERDES_IREG_FLD_PCSTX_DATAWIDTH_VAL_16 0x20 +#define SERDES_IREG_FLD_PCSTX_DATAWIDTH_VAL_20 0x30 +#define SERDES_IREG_FLD_PCSTX_DATAWIDTH_VAL_32 0x40 +#define SERDES_IREG_FLD_PCSTX_DATAWIDTH_VAL_40 0x50 + +/* RX lane rate select */ +#define SERDES_IREG_FLD_PCSRX_DIVRATE_REG_NUM 6 +#define SERDES_IREG_FLD_PCSRX_DIVRATE_MASK 0x07 +#define SERDES_IREG_FLD_PCSRX_DIVRATE_VAL_1_8 0x00 +#define SERDES_IREG_FLD_PCSRX_DIVRATE_VAL_1_4 0x01 +#define SERDES_IREG_FLD_PCSRX_DIVRATE_VAL_1_2 0x02 +#define SERDES_IREG_FLD_PCSRX_DIVRATE_VAL_1_1 0x03 + +/* TX lane rate select */ +#define SERDES_IREG_FLD_PCSTX_DIVRATE_REG_NUM 6 +#define SERDES_IREG_FLD_PCSTX_DIVRATE_MASK 0x70 +#define SERDES_IREG_FLD_PCSTX_DIVRATE_VAL_1_8 0x00 +#define SERDES_IREG_FLD_PCSTX_DIVRATE_VAL_1_4 0x10 +#define SERDES_IREG_FLD_PCSTX_DIVRATE_VAL_1_2 0x20 +#define SERDES_IREG_FLD_PCSTX_DIVRATE_VAL_1_1 0x30 + +/* + * PMA serial RX-to-TX loop-back enable (from AGC to IO Driver). Serial receive + * to transmit loopback: 0 - Disables loopback 1 - Transmits the untimed, + * partial equalized RX signal out the transmit IO pins + */ +#define SERDES_IREG_FLD_LB_RX2TXUNTIMEDEN_REG_NUM 7 +#define SERDES_IREG_FLD_LB_RX2TXUNTIMEDEN 0x10 + +/* + * PMA TX-to-RX buffered serial loop-back enable (bypasses IO Driver). Serial + * transmit to receive buffered loopback: 0 - Disables loopback 1 - Loops back + * the TX serializer output into the CDR + */ +#define SERDES_IREG_FLD_LB_TX2RXBUFTIMEDEN_REG_NUM 7 +#define SERDES_IREG_FLD_LB_TX2RXBUFTIMEDEN 0x20 + +/* + * PMA TX-to-RX I/O serial loop-back enable (loop back done directly from TX to + * RX pads). Serial IO loopback from the transmit lane IO pins to the receive + * lane IO pins: 0 - Disables loopback 1 - Loops back the driver IO signal to + * the RX IO pins + */ +#define SERDES_IREG_FLD_LB_TX2RXIOTIMEDEN_REG_NUM 7 +#define SERDES_IREG_FLD_LB_TX2RXIOTIMEDEN 0x40 + +/* + * PMA Parallel RX-to-TX loop-back enable. Parallel loopback from the PMA + * receive lane 20-bit data ports, to the transmit lane 20-bit data ports 0 - + * Disables loopback 1 - Loops back the 20-bit receive data port to the + * transmitter + */ +#define SERDES_IREG_FLD_LB_PARRX2TXTIMEDEN_REG_NUM 7 +#define SERDES_IREG_FLD_LB_PARRX2TXTIMEDEN 0x80 + +/* + * PMA CDR recovered-clock loopback enable; asserted when PARRX2TXTIMEDEN is 1. + * Transmit bit clock select: 0 - Selects synthesizer bit clock for transmit 1 + * - Selects CDR clock for transmit + */ +#define SERDES_IREG_FLD_LB_CDRCLK2TXEN_REG_NUM 7 +#define SERDES_IREG_FLD_LB_CDRCLK2TXEN 0x01 + +/* Receive lane BIST enable. Active High */ +#define SERDES_IREG_FLD_PCSRXBIST_EN_REG_NUM 8 +#define SERDES_IREG_FLD_PCSRXBIST_EN 0x01 + +/* TX lane BIST enable. Active High */ +#define SERDES_IREG_FLD_PCSTXBIST_EN_REG_NUM 8 +#define SERDES_IREG_FLD_PCSTXBIST_EN 0x02 + +/* + * RX BIST completion signal 0 - Indicates test is not completed 1 - Indicates + * the test has completed, and will remain high until a new test is initiated + */ +#define SERDES_IREG_FLD_RXBIST_DONE_REG_NUM 8 +#define SERDES_IREG_FLD_RXBIST_DONE 0x04 + +/* + * RX BIST error count overflow indicator. Indicates an overflow in the number + * of byte errors identified during the course of the test. This word is stable + * to sample when *_DONE_* signal has asserted + */ +#define SERDES_IREG_FLD_RXBIST_ERRCOUNT_OVERFLOW_REG_NUM 8 +#define SERDES_IREG_FLD_RXBIST_ERRCOUNT_OVERFLOW 0x08 + +/* + * RX BIST locked indicator 0 - Indicates BIST is not word locked and error + * comparisons have not begun yet 1 - Indicates BIST is word locked and error + * comparisons have begun + */ +#define SERDES_IREG_FLD_RXBIST_RXLOCKED_REG_NUM 8 +#define SERDES_IREG_FLD_RXBIST_RXLOCKED 0x10 + +/* + * RX BIST error count word. Indicates the number of byte errors identified + * during the course of the test. This word is stable to sample when *_DONE_* + * signal has asserted + */ +#define SERDES_IREG_FLD_RXBIST_ERRCOUNT_MSB_REG_NUM 9 +#define SERDES_IREG_FLD_RXBIST_ERRCOUNT_LSB_REG_NUM 10 + +/* Tx params */ +#define SERDES_IREG_TX_DRV_1_REG_NUM 21 +#define SERDES_IREG_TX_DRV_1_HLEV_MASK 0x7 +#define SERDES_IREG_TX_DRV_1_HLEV_SHIFT 0 +#define SERDES_IREG_TX_DRV_1_LEVN_MASK 0xf8 +#define SERDES_IREG_TX_DRV_1_LEVN_SHIFT 3 + +#define SERDES_IREG_TX_DRV_2_REG_NUM 22 +#define SERDES_IREG_TX_DRV_2_LEVNM1_MASK 0xf +#define SERDES_IREG_TX_DRV_2_LEVNM1_SHIFT 0 +#define SERDES_IREG_TX_DRV_2_LEVNM2_MASK 0x30 +#define SERDES_IREG_TX_DRV_2_LEVNM2_SHIFT 4 + +#define SERDES_IREG_TX_DRV_3_REG_NUM 23 +#define SERDES_IREG_TX_DRV_3_LEVNP1_MASK 0x7 +#define SERDES_IREG_TX_DRV_3_LEVNP1_SHIFT 0 +#define SERDES_IREG_TX_DRV_3_SLEW_MASK 0x18 +#define SERDES_IREG_TX_DRV_3_SLEW_SHIFT 3 + +/* Rx params */ +#define SERDES_IREG_RX_CALEQ_1_REG_NUM 24 +#define SERDES_IREG_RX_CALEQ_1_DCGAIN_MASK 0x7 +#define SERDES_IREG_RX_CALEQ_1_DCGAIN_SHIFT 0 +/* DFE post-shaping tap 3dB frequency */ +#define SERDES_IREG_RX_CALEQ_1_DFEPSTAP3DB_MASK 0x38 +#define SERDES_IREG_RX_CALEQ_1_DFEPSTAP3DB_SHIFT 3 + +#define SERDES_IREG_RX_CALEQ_2_REG_NUM 25 +/* DFE post-shaping tap gain */ +#define SERDES_IREG_RX_CALEQ_2_DFEPSTAPGAIN_MASK 0x7 +#define SERDES_IREG_RX_CALEQ_2_DFEPSTAPGAIN_SHIFT 0 +/* DFE first tap gain control */ +#define SERDES_IREG_RX_CALEQ_2_DFETAP1GAIN_MASK 0x78 +#define SERDES_IREG_RX_CALEQ_2_DFETAP1GAIN_SHIFT 3 + +#define SERDES_IREG_RX_CALEQ_3_REG_NUM 26 +#define SERDES_IREG_RX_CALEQ_3_DFETAP2GAIN_MASK 0xf +#define SERDES_IREG_RX_CALEQ_3_DFETAP2GAIN_SHIFT 0 +#define SERDES_IREG_RX_CALEQ_3_DFETAP3GAIN_MASK 0xf0 +#define SERDES_IREG_RX_CALEQ_3_DFETAP3GAIN_SHIFT 4 + +#define SERDES_IREG_RX_CALEQ_4_REG_NUM 27 +#define SERDES_IREG_RX_CALEQ_4_DFETAP4GAIN_MASK 0xf +#define SERDES_IREG_RX_CALEQ_4_DFETAP4GAIN_SHIFT 0 +#define SERDES_IREG_RX_CALEQ_4_LOFREQAGCGAIN_MASK 0x70 +#define SERDES_IREG_RX_CALEQ_4_LOFREQAGCGAIN_SHIFT 4 + +#define SERDES_IREG_RX_CALEQ_5_REG_NUM 28 +#define SERDES_IREG_RX_CALEQ_5_PRECAL_CODE_SEL_MASK 0x7 +#define SERDES_IREG_RX_CALEQ_5_PRECAL_CODE_SEL_SHIFT 0 +#define SERDES_IREG_RX_CALEQ_5_HIFREQAGCCAP_MASK 0xf8 +#define SERDES_IREG_RX_CALEQ_5_HIFREQAGCCAP_SHIFT 3 + +/* RX lane best eye point measurement result */ +#define SERDES_IREG_RXEQ_BEST_EYE_MSB_VAL_REG_NUM 29 +#define SERDES_IREG_RXEQ_BEST_EYE_LSB_VAL_REG_NUM 30 +#define SERDES_IREG_RXEQ_BEST_EYE_LSB_VAL_MASK 0x3F + +/* + * Adaptive RX Equalization enable + * 0 - Disables adaptive RX equalization. + * 1 - Enables adaptive RX equalization. + */ +#define SERDES_IREG_FLD_PCSRXEQ_START_REG_NUM 31 +#define SERDES_IREG_FLD_PCSRXEQ_START (1 << 0) + +/* + * Enables an eye diagram measurement + * within the PHY. + * 0 - Disables eye diagram measurement + * 1 - Enables eye diagram measurement + */ +#define SERDES_IREG_FLD_RXCALEYEDIAGFSMIN_START_REG_NUM 31 +#define SERDES_IREG_FLD_RXCALEYEDIAGFSMIN_START (1 << 1) + + +/* + * RX lane single roam eye point measurement start signal. + * If asserted, single measurement at fix XADJUST and YADJUST is started. + */ +#define SERDES_IREG_FLD_RXCALROAMEYEMEASIN_CYCLEEN_REG_NUM 31 +#define SERDES_IREG_FLD_RXCALROAMEYEMEASIN_CYCLEEN_START (1 << 2) + + +/* + * PHY Eye diagram measurement status + * signal + * 0 - Indicates eye diagram results are not + * valid for sampling + * 1 - Indicates eye diagram is complete and + * results are valid for sampling + */ +#define SERDES_IREG_FLD_RXCALEYEDIAGFSM_DONE_REG_NUM 32 +#define SERDES_IREG_FLD_RXCALEYEDIAGFSM_DONE (1 << 0) + +/* + * Eye diagram error signal. Indicates if the + * measurement was invalid because the eye + * diagram was interrupted by the link entering + * electrical idle. + * 0 - Indicates eye diagram is valid + * 1- Indicates an error occurred, and the eye + * diagram measurement should be re-run + */ +#define SERDES_IREG_FLD_RXCALEYEDIAGFSM_ERR_REG_NUM 32 +#define SERDES_IREG_FLD_RXCALEYEDIAGFSM_ERR (1 << 1) + +/* + * PHY Adaptive Equalization status + * 0 - Indicates Adaptive Equalization results are not valid for sampling + * 1 - Indicates Adaptive Equalization is complete and results are valid for + * sampling + */ +#define SERDES_IREG_FLD_RXCALROAMEYEMEASDONE_REG_NUM 32 +#define SERDES_IREG_FLD_RXCALROAMEYEMEASDONE (1 << 2) + +/* + * + * PHY Adaptive Equalization Status Signal + * 0 – Indicates adaptive equalization results + * are not valid for sampling + * 1 – Indicates adaptive equalization is + * complete and results are valid for sampling. + */ +#define SERDES_IREG_FLD_RXEQ_DONE_REG_NUM 32 +#define SERDES_IREG_FLD_RXEQ_DONE (1 << 3) + + +/* + * 7-bit eye diagram time adjust control + * - 6-bits per UI + * - spans 2 UI + */ +#define SERDES_IREG_FLD_RXCALROAMXADJUST_REG_NUM 33 + +/* 6-bit eye diagram voltage adjust control - spans +/-300mVdiff */ +#define SERDES_IREG_FLD_RXCALROAMYADJUST_REG_NUM 34 + +/* + * Eye diagram status signal. Safe for + * sampling when *DONE* signal has + * asserted + * 14'h0000 - Completely Closed Eye + * 14'hFFFF - Completely Open Eye + */ +#define SERDES_IREG_FLD_RXCALEYEDIAGFSM_EYESUM_MSB_REG_NUM 35 +#define SERDES_IREG_FLD_RXCALEYEDIAGFSM_EYESUM_MSB_MAKE 0xFF +#define SERDES_IREG_FLD_RXCALEYEDIAGFSM_EYESUM_MSB_SHIFT 0 + +#define SERDES_IREG_FLD_RXCALEYEDIAGFSM_EYESUM_LSB_REG_NUM 36 +#define SERDES_IREG_FLD_RXCALEYEDIAGFSM_EYESUM_LSB_MAKE 0x3F +#define SERDES_IREG_FLD_RXCALEYEDIAGFSM_EYESUM_LSB_SHIFT 0 + +/* + * RX lane single roam eye point measurement result. + * If 0, eye is open at current XADJUST and YADJUST settings. + */ +#define SERDES_IREG_FLD_RXCALROAMEYEMEAS_ACC_MSB_REG_NUM 37 +#define SERDES_IREG_FLD_RXCALROAMEYEMEAS_ACC_LSB_REG_NUM 38 + +/* + * Override enable for CDR lock to reference clock + * 0 - CDR is always locked to reference + * 1 - CDR operation mode (Lock2Reference or Lock2data are controlled internally + * depending on the incoming signal and ppm status) + */ +#define SERDES_IREG_FLD_RXLOCK2REF_OVREN_REG_NUM 39 +#define SERDES_IREG_FLD_RXLOCK2REF_OVREN (1 << 1) + +/* + * Selects Eye to capture based on edge + * 0 - Capture 1st Eye in Eye Diagram + * 1 - Capture 2nd Eye in Eye Diagram measurement + */ +#define SERDES_IREG_FLD_RXROAM_XORBITSEL_REG_NUM 39 +#define SERDES_IREG_FLD_RXROAM_XORBITSEL (1 << 2) +#define SERDES_IREG_FLD_RXROAM_XORBITSEL_1ST 0 +#define SERDES_IREG_FLD_RXROAM_XORBITSEL_2ND (1 << 2) + +/* + * RX Signal detect. 0 indicates no signal, 1 indicates signal detected. + */ +#define SERDES_IREG_FLD_RXRANDET_REG_NUM 41 +#define SERDES_IREG_FLD_RXRANDET_STAT 0x20 + +/* + * RX data polarity inversion control: + * 1'b0: no inversion + * 1'b1: invert polarity + */ +#define SERDES_IREG_FLD_POLARITY_RX_REG_NUM 46 +#define SERDES_IREG_FLD_POLARITY_RX_INV (1 << 0) + +/* + * TX data polarity inversion control: + * 1'b0: no inversion + * 1'b1: invert polarity + */ +#define SERDES_IREG_FLD_POLARITY_TX_REG_NUM 46 +#define SERDES_IREG_FLD_POLARITY_TX_INV (1 << 1) + +/* LANEPCSPSTATE* override enable (Active low) */ +#define SERDES_IREG_FLD_LANEPCSPSTATE_LOCWREN_REG_NUM 85 +#define SERDES_IREG_FLD_LANEPCSPSTATE_LOCWREN (1 << 0) + +/* LB* override enable (Active low) */ +#define SERDES_IREG_FLD_LB_LOCWREN_REG_NUM 85 +#define SERDES_IREG_FLD_LB_LOCWREN (1 << 1) + +/* PCSRX* override enable (Active low) */ +#define SERDES_IREG_FLD_PCSRX_LOCWREN_REG_NUM 85 +#define SERDES_IREG_FLD_PCSRX_LOCWREN (1 << 4) + +/* PCSRXBIST* override enable (Active low) */ +#define SERDES_IREG_FLD_PCSRXBIST_LOCWREN_REG_NUM 85 +#define SERDES_IREG_FLD_PCSRXBIST_LOCWREN (1 << 5) + +/* PCSRXEQ* override enable (Active low) */ +#define SERDES_IREG_FLD_PCSRXEQ_LOCWREN_REG_NUM 85 +#define SERDES_IREG_FLD_PCSRXEQ_LOCWREN (1 << 6) + +/* PCSTX* override enable (Active low) */ +#define SERDES_IREG_FLD_PCSTX_LOCWREN_REG_NUM 85 +#define SERDES_IREG_FLD_PCSTX_LOCWREN (1 << 7) + +/* + * group registers: + * SERDES_IREG_FLD_RXCALEYEDIAGFSMIN_LOCWREN, + * SERDES_IREG_FLD_RXCALROAMEYEMEASIN_LOCWREN + * SERDES_IREG_FLD_RXCALROAMXADJUST_LOCWREN + */ +#define SERDES_IREG_FLD_RXCAL_LOCWREN_REG_NUM 86 + +/* PCSTXBIST* override enable (Active low) */ +#define SERDES_IREG_FLD_PCSTXBIST_LOCWREN_REG_NUM 86 +#define SERDES_IREG_FLD_PCSTXBIST_LOCWREN (1 << 0) + +/* Override RX_CALCEQ through the internal registers (Active low) */ +#define SERDES_IREG_FLD_RX_DRV_OVERRIDE_EN_REG_NUM 86 +#define SERDES_IREG_FLD_RX_DRV_OVERRIDE_EN (1 << 3) + +#define SERDES_IREG_FLD_RXCALEYEDIAGFSMIN_LOCWREN_REG_NUM 86 +#define SERDES_IREG_FLD_RXCALEYEDIAGFSMIN_LOCWREN (1 << 4) + + +/* RXCALROAMEYEMEASIN* override enable - Active Low */ +#define SERDES_IREG_FLD_RXCALROAMEYEMEASIN_LOCWREN_REG_NUM 86 +#define SERDES_IREG_FLD_RXCALROAMEYEMEASIN_LOCWREN (1 << 6) + +/* RXCALROAMXADJUST* override enable - Active Low */ +#define SERDES_IREG_FLD_RXCALROAMXADJUST_LOCWREN_REG_NUM 86 +#define SERDES_IREG_FLD_RXCALROAMXADJUST_LOCWREN (1 << 7) + +/* RXCALROAMYADJUST* override enable - Active Low */ +#define SERDES_IREG_FLD_RXCALROAMYADJUST_LOCWREN_REG_NUM 87 +#define SERDES_IREG_FLD_RXCALROAMYADJUST_LOCWREN (1 << 0) + +/* RXCDRCALFOSC* override enable. Active Low */ +#define SERDES_IREG_FLD_RXCDRCALFOSC_LOCWREN_REG_NUM 87 +#define SERDES_IREG_FLD_RXCDRCALFOSC_LOCWREN (1 << 1) + +/* Over-write enable for RXEYEDIAGFSM_INITXVAL */ +#define SERDES_IREG_FLD_RXEYEDIAGFSM_LOCWREN_REG_NUM 87 +#define SERDES_IREG_FLD_RXEYEDIAGFSM_LOCWREN (1 << 2) + +/* Over-write enable for CMNCLKGENMUXSEL_TXINTERNAL */ +#define SERDES_IREG_FLD_RXTERMHIZ_LOCWREN_REG_NUM 87 +#define SERDES_IREG_FLD_RXTERMHIZ_LOCWREN (1 << 3) + +/* TXCALTCLKDUTY* override enable. Active Low */ +#define SERDES_IREG_FLD_TXCALTCLKDUTY_LOCWREN_REG_NUM 87 +#define SERDES_IREG_FLD_TXCALTCLKDUTY_LOCWREN (1 << 4) + +/* Override TX_DRV through the internal registers (Active low) */ +#define SERDES_IREG_FLD_TX_DRV_OVERRIDE_EN_REG_NUM 87 +#define SERDES_IREG_FLD_TX_DRV_OVERRIDE_EN (1 << 5) + +/******************************************************************************* + * Common lane register fields - PMA + ******************************************************************************/ +/* + * Common lane hard reset control + * 0 - Hard reset is taken from the interface pins + * 1 - Hard reset is taken from registers + */ +#define SERDES_IREG_FLD_CMNCTLPOR_HARDRSTBYPASSEN_SYNTH_REG_NUM 2 +#define SERDES_IREG_FLD_CMNCTLPOR_HARDRSTBYPASSEN_SYNTH_MASK 0x01 +#define SERDES_IREG_FLD_CMNCTLPOR_HARDRSTBYPASSEN_SYNTH_VAL_IFACE 0x00 +#define SERDES_IREG_FLD_CMNCTLPOR_HARDRSTBYPASSEN_SYNTH_VAL_REGS 0x01 + +/* + * Common lane hard reset + * 0 - Hard reset is asserted + * 1 - Hard reset is de-asserted + */ +#define SERDES_IREG_FLD_CMNCTLPOR_HARDRSTBYPASS_SYNTH_REG_NUM 2 +#define SERDES_IREG_FLD_CMNCTLPOR_HARDRSTBYPASS_SYNTH_MASK 0x02 +#define SERDES_IREG_FLD_CMNCTLPOR_HARDRSTBYPASS_SYNTH_VAL_ASSERT 0x00 +#define SERDES_IREG_FLD_CMNCTLPOR_HARDRSTBYPASS_SYNTH_VAL_DEASSERT 0x02 + +/* Synth power state control */ +#define SERDES_IREG_FLD_CMNPCSPSTATE_SYNTH_REG_NUM 3 +#define SERDES_IREG_FLD_CMNPCSPSTATE_SYNTH_MASK 0x1f +#define SERDES_IREG_FLD_CMNPCSPSTATE_SYNTH_VAL_PD 0x01 +#define SERDES_IREG_FLD_CMNPCSPSTATE_SYNTH_VAL_P2 0x02 +#define SERDES_IREG_FLD_CMNPCSPSTATE_SYNTH_VAL_P1 0x04 +#define SERDES_IREG_FLD_CMNPCSPSTATE_SYNTH_VAL_P0S 0x08 +#define SERDES_IREG_FLD_CMNPCSPSTATE_SYNTH_VAL_P0 0x10 + +/* Transmit datapath FIFO enable (Active High) */ +#define SERDES_IREG_FLD_CMNPCS_TXENABLE_REG_NUM 8 +#define SERDES_IREG_FLD_CMNPCS_TXENABLE (1 << 2) + +/* + * RX lost of signal detector enable + * - 0 - disable + * - 1 - enable + */ +#define SERDES_IREG_FLD_RXLOSDET_ENABLE_REG_NUM 13 +#define SERDES_IREG_FLD_RXLOSDET_ENABLE AL_BIT(4) + +/* Signal Detect Threshold Level */ +#define SERDES_IREG_FLD_RXELECIDLE_SIGDETTHRESH_REG_NUM 15 +#define SERDES_IREG_FLD_RXELECIDLE_SIGDETTHRESH_MASK AL_FIELD_MASK(2, 0) + +/* LOS Detect Threshold Level */ +#define SERDES_IREG_FLD_RXLOSDET_THRESH_REG_NUM 15 +#define SERDES_IREG_FLD_RXLOSDET_THRESH_MASK AL_FIELD_MASK(4, 3) +#define SERDES_IREG_FLD_RXLOSDET_THRESH_SHIFT 3 + +#define SERDES_IREG_FLD_RXEQ_COARSE_ITER_NUM_REG_NUM 30 +#define SERDES_IREG_FLD_RXEQ_COARSE_ITER_NUM_MASK 0x7f +#define SERDES_IREG_FLD_RXEQ_COARSE_ITER_NUM_SHIFT 0 + +#define SERDES_IREG_FLD_RXEQ_FINE_ITER_NUM_REG_NUM 31 +#define SERDES_IREG_FLD_RXEQ_FINE_ITER_NUM_MASK 0x7f +#define SERDES_IREG_FLD_RXEQ_FINE_ITER_NUM_SHIFT 0 + +#define SERDES_IREG_FLD_RXEQ_COARSE_RUN1_MASK_REG_NUM 32 +#define SERDES_IREG_FLD_RXEQ_COARSE_RUN1_MASK_MASK 0xff +#define SERDES_IREG_FLD_RXEQ_COARSE_RUN1_MASK_SHIFT 0 + +#define SERDES_IREG_FLD_RXEQ_COARSE_RUN2_MASK_REG_NUM 33 +#define SERDES_IREG_FLD_RXEQ_COARSE_RUN2_MASK_MASK 0x1 +#define SERDES_IREG_FLD_RXEQ_COARSE_RUN2_MASK_SHIFT 0 + +#define SERDES_IREG_FLD_RXEQ_COARSE_STEP_REG_NUM 33 +#define SERDES_IREG_FLD_RXEQ_COARSE_STEP_MASK 0x3e +#define SERDES_IREG_FLD_RXEQ_COARSE_STEP_SHIFT 1 + +#define SERDES_IREG_FLD_RXEQ_FINE_RUN1_MASK_REG_NUM 34 +#define SERDES_IREG_FLD_RXEQ_FINE_RUN1_MASK_MASK 0xff +#define SERDES_IREG_FLD_RXEQ_FINE_RUN1_MASK_SHIFT 0 + +#define SERDES_IREG_FLD_RXEQ_FINE_RUN2_MASK_REG_NUM 35 +#define SERDES_IREG_FLD_RXEQ_FINE_RUN2_MASK_MASK 0x1 +#define SERDES_IREG_FLD_RXEQ_FINE_RUN2_MASK_SHIFT 0 + +#define SERDES_IREG_FLD_RXEQ_FINE_STEP_REG_NUM 35 +#define SERDES_IREG_FLD_RXEQ_FINE_STEP_MASK 0x3e +#define SERDES_IREG_FLD_RXEQ_FINE_STEP_SHIFT 1 + +#define SERDES_IREG_FLD_RXEQ_LOOKUP_CODE_EN_REG_NUM 36 +#define SERDES_IREG_FLD_RXEQ_LOOKUP_CODE_EN_MASK 0xff +#define SERDES_IREG_FLD_RXEQ_LOOKUP_CODE_EN_SHIFT 0 + +#define SERDES_IREG_FLD_RXEQ_LOOKUP_LASTCODE_REG_NUM 37 +#define SERDES_IREG_FLD_RXEQ_LOOKUP_LASTCODE_MASK 0x7 +#define SERDES_IREG_FLD_RXEQ_LOOKUP_LASTCODE_SHIFT 0 + +#define SERDES_IREG_FLD_RXEQ_DCGAIN_LUP0_REG_NUM 43 +#define SERDES_IREG_FLD_RXEQ_DCGAIN_LUP0_MASK 0x7 +#define SERDES_IREG_FLD_RXEQ_DCGAIN_LUP0_SHIFT 0 + +#define SERDES_IREG_FLD_TX_BIST_PAT_REG_NUM(byte_num) (56 + (byte_num)) +#define SERDES_IREG_FLD_TX_BIST_PAT_NUM_BYTES 10 + +/* + * Selects the transmit BIST mode: + * 0 - Uses the 80-bit internal memory pattern (w/ OOB) + * 1 - Uses a 27 PRBS pattern + * 2 - Uses a 223 PRBS pattern + * 3 - Uses a 231 PRBS pattern + * 4 - Uses a 1010 clock pattern + * 5 and above - Reserved + */ +#define SERDES_IREG_FLD_CMNPCSBIST_MODESEL_REG_NUM 80 +#define SERDES_IREG_FLD_CMNPCSBIST_MODESEL_MASK 0x07 +#define SERDES_IREG_FLD_CMNPCSBIST_MODESEL_VAL_USER 0x00 +#define SERDES_IREG_FLD_CMNPCSBIST_MODESEL_VAL_PRBS7 0x01 +#define SERDES_IREG_FLD_CMNPCSBIST_MODESEL_VAL_PRBS23 0x02 +#define SERDES_IREG_FLD_CMNPCSBIST_MODESEL_VAL_PRBS31 0x03 +#define SERDES_IREG_FLD_CMNPCSBIST_MODESEL_VAL_CLK1010 0x04 + +/* Single-Bit error injection enable (on posedge) */ +#define SERDES_IREG_FLD_TXBIST_BITERROR_EN_REG_NUM 80 +#define SERDES_IREG_FLD_TXBIST_BITERROR_EN 0x20 + +/* CMNPCIEGEN3* override enable (Active Low) */ +#define SERDES_IREG_FLD_CMNPCIEGEN3_LOCWREN_REG_NUM 95 +#define SERDES_IREG_FLD_CMNPCIEGEN3_LOCWREN (1 << 2) + +/* CMNPCS* override enable (Active Low) */ +#define SERDES_IREG_FLD_CMNPCS_LOCWREN_REG_NUM 95 +#define SERDES_IREG_FLD_CMNPCS_LOCWREN (1 << 3) + +/* CMNPCSBIST* override enable (Active Low) */ +#define SERDES_IREG_FLD_CMNPCSBIST_LOCWREN_REG_NUM 95 +#define SERDES_IREG_FLD_CMNPCSBIST_LOCWREN (1 << 4) + +/* CMNPCSPSTATE* override enable (Active Low) */ +#define SERDES_IREG_FLD_CMNPCSPSTATE_LOCWREN_REG_NUM 95 +#define SERDES_IREG_FLD_CMNPCSPSTATE_LOCWREN (1 << 5) + +/* PCS_EN* override enable (Active Low) */ +#define SERDES_IREG_FLD_PCS_LOCWREN_REG_NUM 96 +#define SERDES_IREG_FLD_PCS_LOCWREN (1 << 3) + +/* Eye diagram sample count */ +#define SERDES_IREG_FLD_EYE_DIAG_SAMPLE_CNT_MSB_REG_NUM 150 +#define SERDES_IREG_FLD_EYE_DIAG_SAMPLE_CNT_MSB_MASK 0xff +#define SERDES_IREG_FLD_EYE_DIAG_SAMPLE_CNT_MSB_SHIFT 0 + +#define SERDES_IREG_FLD_EYE_DIAG_SAMPLE_CNT_LSB_REG_NUM 151 +#define SERDES_IREG_FLD_EYE_DIAG_SAMPLE_CNT_LSB_MASK 0xff +#define SERDES_IREG_FLD_EYE_DIAG_SAMPLE_CNT_LSB_SHIFT 0 + +/* override control */ +#define SERDES_IREG_FLD_RXLOCK2REF_LOCWREN_REG_NUM 230 +#define SERDES_IREG_FLD_RXLOCK2REF_LOCWREN 1 << 0 + +#define SERDES_IREG_FLD_RXCALEYEDIAGFSM_BERTHRESHOLD1_REG_NUM 623 +#define SERDES_IREG_FLD_RXCALEYEDIAGFSM_BERTHRESHOLD1_MASK 0xff +#define SERDES_IREG_FLD_RXCALEYEDIAGFSM_BERTHRESHOLD1_SHIFT 0 + +#define SERDES_IREG_FLD_RXCALEYEDIAGFSM_BERTHRESHOLD2_REG_NUM 624 +#define SERDES_IREG_FLD_RXCALEYEDIAGFSM_BERTHRESHOLD2_MASK 0xff +#define SERDES_IREG_FLD_RXCALEYEDIAGFSM_BERTHRESHOLD2_SHIFT 0 + +/* X and Y coefficient return value */ +#define SERDES_IREG_FLD_RXCALEYEDIAGFSM_X_Y_VALWEIGHT_REG_NUM 626 +#define SERDES_IREG_FLD_RXCALEYEDIAGFSM_XVALWEIGHT_MASK 0x0F +#define SERDES_IREG_FLD_RXCALEYEDIAGFSM_XVALWEIGHT_SHIFT 0 +#define SERDES_IREG_FLD_RXCALEYEDIAGFSM_YVALWEIGHT_MASK 0xF0 +#define SERDES_IREG_FLD_RXCALEYEDIAGFSM_YVALWEIGHT_SHIFT 4 + +/* X coarse scan step */ +#define SERDES_IREG_FLD_RXCALEYEDIAGFSM_XVALCOARSE_REG_NUM 627 +#define SERDES_IREG_FLD_RXCALEYEDIAGFSM_XVALCOARSE_MASK 0x7F +#define SERDES_IREG_FLD_RXCALEYEDIAGFSM_XVALCOARSE_SHIFT 0 + +/* X fine scan step */ +#define SERDES_IREG_FLD_RXCALEYEDIAGFSM_XVALFINE_REG_NUM 628 +#define SERDES_IREG_FLD_RXCALEYEDIAGFSM_XVALFINE_MASK 0x7F +#define SERDES_IREG_FLD_RXCALEYEDIAGFSM_XVALFINE_SHIFT 0 + +/* Y coarse scan step */ +#define SERDES_IREG_FLD_RXCALEYEDIAGFSM_YVALCOARSE_REG_NUM 629 +#define SERDES_IREG_FLD_RXCALEYEDIAGFSM_YVALCOARSE_MASK 0x0F +#define SERDES_IREG_FLD_RXCALEYEDIAGFSM_YVALCOARSE_SHIFT 0 + +/* Y fine scan step */ +#define SERDES_IREG_FLD_RXCALEYEDIAGFSM_YVALFINE_REG_NUM 630 +#define SERDES_IREG_FLD_RXCALEYEDIAGFSM_YVALFINE_MASK 0x0F +#define SERDES_IREG_FLD_RXCALEYEDIAGFSM_YVALFINE_SHIFT 0 + +#define SERDES_IREG_FLD_PPMDRIFTCOUNT1_REG_NUM 157 + +#define SERDES_IREG_FLD_PPMDRIFTCOUNT2_REG_NUM 158 + +#define SERDES_IREG_FLD_PPMDRIFTMAX1_REG_NUM 159 + +#define SERDES_IREG_FLD_PPMDRIFTMAX2_REG_NUM 160 + +#define SERDES_IREG_FLD_SYNTHPPMDRIFTMAX1_REG_NUM 163 + +#define SERDES_IREG_FLD_SYNTHPPMDRIFTMAX2_REG_NUM 164 + +/******************************************************************************* + * Common lane register fields - PCS + ******************************************************************************/ +#define SERDES_IREG_FLD_PCS_VPCSIF_OVR_RATE_REG_NUM 3 +#define SERDES_IREG_FLD_PCS_VPCSIF_OVR_RATE_MASK AL_FIELD_MASK(5, 4) +#define SERDES_IREG_FLD_PCS_VPCSIF_OVR_RATE_SHIFT 4 + +#define SERDES_IREG_FLD_PCS_VPCSIF_OVR_RATE_ENA_REG_NUM 6 +#define SERDES_IREG_FLD_PCS_VPCSIF_OVR_RATE_ENA AL_BIT(2) + +#define SERDES_IREG_FLD_PCS_EBUF_FULL_D2R1_REG_NUM 18 +#define SERDES_IREG_FLD_PCS_EBUF_FULL_D2R1_REG_MASK 0x1F +#define SERDES_IREG_FLD_PCS_EBUF_FULL_D2R1_REG_SHIFT 0 + +#define SERDES_IREG_FLD_PCS_EBUF_FULL_PCIE_G3_REG_NUM 19 +#define SERDES_IREG_FLD_PCS_EBUF_FULL_PCIE_G3_REG_MASK 0x7C +#define SERDES_IREG_FLD_PCS_EBUF_FULL_PCIE_G3_REG_SHIFT 2 + +#define SERDES_IREG_FLD_PCS_EBUF_RD_THRESHOLD_D2R1_REG_NUM 20 +#define SERDES_IREG_FLD_PCS_EBUF_RD_THRESHOLD_D2R1_REG_MASK 0x1F +#define SERDES_IREG_FLD_PCS_EBUF_RD_THRESHOLD_D2R1_REG_SHIFT 0 + +#define SERDES_IREG_FLD_PCS_EBUF_RD_THRESHOLD_PCIE_G3_REG_NUM 21 +#define SERDES_IREG_FLD_PCS_EBUF_RD_THRESHOLD_PCIE_G3_REG_MASK 0x7C +#define SERDES_IREG_FLD_PCS_EBUF_RD_THRESHOLD_PCIE_G3_REG_SHIFT 2 + +#define SERDES_IREG_FLD_PCS_RXEQ_COARSE_ITER_NUM_REG_NUM 22 +#define SERDES_IREG_FLD_PCS_RXEQ_COARSE_ITER_NUM_MASK 0x7f +#define SERDES_IREG_FLD_PCS_RXEQ_COARSE_ITER_NUM_SHIFT 0 + +#define SERDES_IREG_FLD_PCS_RXEQ_FINE_ITER_NUM_REG_NUM 34 +#define SERDES_IREG_FLD_PCS_RXEQ_FINE_ITER_NUM_MASK 0x7f +#define SERDES_IREG_FLD_PCS_RXEQ_FINE_ITER_NUM_SHIFT 0 + +#define SERDES_IREG_FLD_PCS_RXEQ_COARSE_RUN1_MASK_REG_NUM 23 +#define SERDES_IREG_FLD_PCS_RXEQ_COARSE_RUN1_MASK_MASK 0xff +#define SERDES_IREG_FLD_PCS_RXEQ_COARSE_RUN1_MASK_SHIFT 0 + +#define SERDES_IREG_FLD_PCS_RXEQ_COARSE_RUN2_MASK_REG_NUM 22 +#define SERDES_IREG_FLD_PCS_RXEQ_COARSE_RUN2_MASK_MASK 0x80 +#define SERDES_IREG_FLD_PCS_RXEQ_COARSE_RUN2_MASK_SHIFT 7 + +#define SERDES_IREG_FLD_PCS_RXEQ_COARSE_STEP_REG_NUM 24 +#define SERDES_IREG_FLD_PCS_RXEQ_COARSE_STEP_MASK 0x3e +#define SERDES_IREG_FLD_PCS_RXEQ_COARSE_STEP_SHIFT 1 + +#define SERDES_IREG_FLD_PCS_RXEQ_FINE_RUN1_MASK_REG_NUM 35 +#define SERDES_IREG_FLD_PCS_RXEQ_FINE_RUN1_MASK_MASK 0xff +#define SERDES_IREG_FLD_PCS_RXEQ_FINE_RUN1_MASK_SHIFT 0 + +#define SERDES_IREG_FLD_PCS_RXEQ_FINE_RUN2_MASK_REG_NUM 34 +#define SERDES_IREG_FLD_PCS_RXEQ_FINE_RUN2_MASK_MASK 0x80 +#define SERDES_IREG_FLD_PCS_RXEQ_FINE_RUN2_MASK_SHIFT 7 + +#define SERDES_IREG_FLD_PCS_RXEQ_FINE_STEP_REG_NUM 36 +#define SERDES_IREG_FLD_PCS_RXEQ_FINE_STEP_MASK 0x1f +#define SERDES_IREG_FLD_PCS_RXEQ_FINE_STEP_SHIFT 0 + +#define SERDES_IREG_FLD_PCS_RXEQ_LOOKUP_CODE_EN_REG_NUM 37 +#define SERDES_IREG_FLD_PCS_RXEQ_LOOKUP_CODE_EN_MASK 0xff +#define SERDES_IREG_FLD_PCS_RXEQ_LOOKUP_CODE_EN_SHIFT 0 + +#define SERDES_IREG_FLD_PCS_RXEQ_LOOKUP_LASTCODE_REG_NUM 36 +#define SERDES_IREG_FLD_PCS_RXEQ_LOOKUP_LASTCODE_MASK 0xe0 +#define SERDES_IREG_FLD_PCS_RXEQ_LOOKUP_LASTCODE_SHIFT 5 + +#ifdef __cplusplus +} +#endif + +#endif /* __AL_serdes_REG_H */ + diff --git a/al_hal_serdes_regs.h b/al_hal_serdes_regs.h new file mode 100644 index 00000000000..1af7a918e21 --- /dev/null +++ b/al_hal_serdes_regs.h @@ -0,0 +1,495 @@ +/*- +******************************************************************************* +Copyright (C) 2015 Annapurna Labs Ltd. + +This file may be licensed under the terms of the Annapurna Labs Commercial +License Agreement. + +Alternatively, this file can be distributed under the terms of the GNU General +Public License V2 as published by the Free Software Foundation and can be +found at http://www.gnu.org/licenses/gpl-2.0.html + +Alternatively, redistribution and use in source and binary forms, with or +without modification, are permitted provided that the following conditions are +met: + + * Redistributions of source code must retain the above copyright notice, +this list of conditions and the following disclaimer. + + * Redistributions in binary form must reproduce the above copyright +notice, this list of conditions and the following disclaimer in +the documentation and/or other materials provided with the +distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +*******************************************************************************/ + +/** + * @{ + * @file al_hal_serdes_regs.h + * + * @brief ... registers + * + */ + +#ifndef __AL_HAL_SERDES_REGS_H__ +#define __AL_HAL_SERDES_REGS_H__ + +#include "al_hal_plat_types.h" + +#ifdef __cplusplus +extern "C" { +#endif +/* +* Unit Registers +*/ + +struct serdes_gen { + /* [0x0] SerDes Registers Version */ + uint32_t version; + uint32_t rsrvd_0[3]; + /* [0x10] SerDes register file address */ + uint32_t reg_addr; + /* [0x14] SerDes register file data */ + uint32_t reg_data; + uint32_t rsrvd_1[2]; + /* [0x20] SerDes control */ + uint32_t ictl_multi_bist; + /* [0x24] SerDes control */ + uint32_t ictl_pcs; + /* [0x28] SerDes control */ + uint32_t ictl_pma; + uint32_t rsrvd_2; + /* [0x30] SerDes control */ + uint32_t ipd_multi_synth; + /* [0x34] SerDes control */ + uint32_t irst; + /* [0x38] SerDes control */ + uint32_t octl_multi_synthready; + /* [0x3c] SerDes control */ + uint32_t octl_multi_synthstatus; + /* [0x40] SerDes control */ + uint32_t clk_out; + uint32_t rsrvd[47]; +}; +struct serdes_lane { + uint32_t rsrvd1[4]; + /* [0x10] SerDes status */ + uint32_t octl_pma; + /* [0x14] SerDes control */ + uint32_t ictl_multi_andme; + /* [0x18] SerDes control */ + uint32_t ictl_multi_lb; + /* [0x1c] SerDes control */ + uint32_t ictl_multi_rxbist; + /* [0x20] SerDes control */ + uint32_t ictl_multi_txbist; + /* [0x24] SerDes control */ + uint32_t ictl_multi; + /* [0x28] SerDes control */ + uint32_t ictl_multi_rxeq; + /* [0x2c] SerDes control */ + uint32_t ictl_multi_rxeq_l_low; + /* [0x30] SerDes control */ + uint32_t ictl_multi_rxeq_l_high; + /* [0x34] SerDes control */ + uint32_t ictl_multi_rxeyediag; + /* [0x38] SerDes control */ + uint32_t ictl_multi_txdeemph; + /* [0x3c] SerDes control */ + uint32_t ictl_multi_txmargin; + /* [0x40] SerDes control */ + uint32_t ictl_multi_txswing; + /* [0x44] SerDes control */ + uint32_t idat_multi; + /* [0x48] SerDes control */ + uint32_t ipd_multi; + /* [0x4c] SerDes control */ + uint32_t octl_multi_rxbist; + /* [0x50] SerDes control */ + uint32_t octl_multi; + /* [0x54] SerDes control */ + uint32_t octl_multi_rxeyediag; + /* [0x58] SerDes control */ + uint32_t odat_multi_rxbist; + /* [0x5c] SerDes control */ + uint32_t odat_multi_rxeq; + /* [0x60] SerDes control */ + uint32_t multi_rx_dvalid; + /* [0x64] SerDes control */ + uint32_t reserved; + uint32_t rsrvd[6]; +}; + +struct al_serdes_regs { + uint32_t rsrvd_0[64]; + struct serdes_gen gen; /* [0x100] */ + struct serdes_lane lane[4]; /* [0x200] */ +}; + + +/* +* Registers Fields +*/ + + +/**** version register ****/ +/* Revision number (Minor) */ +#define SERDES_GEN_VERSION_RELEASE_NUM_MINOR_MASK 0x000000FF +#define SERDES_GEN_VERSION_RELEASE_NUM_MINOR_SHIFT 0 +/* Revision number (Major) */ +#define SERDES_GEN_VERSION_RELEASE_NUM_MAJOR_MASK 0x0000FF00 +#define SERDES_GEN_VERSION_RELEASE_NUM_MAJOR_SHIFT 8 +/* Date of release */ +#define SERDES_GEN_VERSION_DATE_DAY_MASK 0x001F0000 +#define SERDES_GEN_VERSION_DATE_DAY_SHIFT 16 +/* Month of release */ +#define SERDES_GEN_VERSION_DATA_MONTH_MASK 0x01E00000 +#define SERDES_GEN_VERSION_DATA_MONTH_SHIFT 21 +/* Year of release (starting from 2000) */ +#define SERDES_GEN_VERSION_DATE_YEAR_MASK 0x3E000000 +#define SERDES_GEN_VERSION_DATE_YEAR_SHIFT 25 +/* Reserved */ +#define SERDES_GEN_VERSION_RESERVED_MASK 0xC0000000 +#define SERDES_GEN_VERSION_RESERVED_SHIFT 30 + +/**** reg_addr register ****/ +/* Address value */ +#define SERDES_GEN_REG_ADDR_VAL_MASK 0x0000FFFF +#define SERDES_GEN_REG_ADDR_VAL_SHIFT 0 + +/**** reg_data register ****/ +/* Data value */ +#define SERDES_GEN_REG_DATA_VAL_MASK 0x000000FF +#define SERDES_GEN_REG_DATA_VAL_SHIFT 0 + +/**** ICTL_MULTI_BIST register ****/ + +#define SERDES_GEN_ICTL_MULTI_BIST_MODESEL_NT_MASK 0x00000007 +#define SERDES_GEN_ICTL_MULTI_BIST_MODESEL_NT_SHIFT 0 + +/**** ICTL_PCS register ****/ + +#define SERDES_GEN_ICTL_PCS_EN_NT (1 << 0) + +/**** ICTL_PMA register ****/ + +#define SERDES_GEN_ICTL_PMA_REF_SEL_NT_MASK 0x00000007 +#define SERDES_GEN_ICTL_PMA_REF_SEL_NT_SHIFT 0 + +#define SERDES_GEN_ICTL_PMA_REF_SEL_NT_REF \ + (0 << (SERDES_GEN_ICTL_PMA_REF_SEL_NT_SHIFT)) +#define SERDES_GEN_ICTL_PMA_REF_SEL_NT_R2L \ + (3 << (SERDES_GEN_ICTL_PMA_REF_SEL_NT_SHIFT)) +#define SERDES_GEN_ICTL_PMA_REF_SEL_NT_L2R \ + (4 << (SERDES_GEN_ICTL_PMA_REF_SEL_NT_SHIFT)) + +#define SERDES_GEN_ICTL_PMA_REFBUSRIGHT2LEFT_MODE_NT_MASK 0x00000070 +#define SERDES_GEN_ICTL_PMA_REFBUSRIGHT2LEFT_MODE_NT_SHIFT 4 + +#define SERDES_GEN_ICTL_PMA_REFBUSRIGHT2LEFT_MODE_NT_0 \ + (0 << (SERDES_GEN_ICTL_PMA_REFBUSRIGHT2LEFT_MODE_NT_SHIFT)) +#define SERDES_GEN_ICTL_PMA_REFBUSRIGHT2LEFT_MODE_NT_REF \ + (2 << (SERDES_GEN_ICTL_PMA_REFBUSRIGHT2LEFT_MODE_NT_SHIFT)) +#define SERDES_GEN_ICTL_PMA_REFBUSRIGHT2LEFT_MODE_NT_R2L \ + (3 << (SERDES_GEN_ICTL_PMA_REFBUSRIGHT2LEFT_MODE_NT_SHIFT)) + +#define SERDES_GEN_ICTL_PMA_REFBUSLEFT2RIGHT_MODE_NT_MASK 0x00000700 +#define SERDES_GEN_ICTL_PMA_REFBUSLEFT2RIGHT_MODE_NT_SHIFT 8 + +#define SERDES_GEN_ICTL_PMA_REFBUSLEFT2RIGHT_MODE_NT_0 \ + (0 << (SERDES_GEN_ICTL_PMA_REFBUSLEFT2RIGHT_MODE_NT_SHIFT)) +#define SERDES_GEN_ICTL_PMA_REFBUSLEFT2RIGHT_MODE_NT_REF \ + (2 << (SERDES_GEN_ICTL_PMA_REFBUSLEFT2RIGHT_MODE_NT_SHIFT)) +#define SERDES_GEN_ICTL_PMA_REFBUSLEFT2RIGHT_MODE_NT_L2R \ + (3 << (SERDES_GEN_ICTL_PMA_REFBUSLEFT2RIGHT_MODE_NT_SHIFT)) + +#define SERDES_GEN_ICTL_PMA_TXENABLE_A_SRC (1 << 11) +#define SERDES_GEN_ICTL_PMA_TXENABLE_A_SRC_THIS (0 << 11) +#define SERDES_GEN_ICTL_PMA_TXENABLE_A_SRC_MASTER (1 << 11) + +#define SERDES_GEN_ICTL_PMA_TXENABLE_A (1 << 12) + +#define SERDES_GEN_ICTL_PMA_SYNTHCKBYPASSEN_NT (1 << 13) + +/**** IPD_MULTI_SYNTH register ****/ + +#define SERDES_GEN_IPD_MULTI_SYNTH_B (1 << 0) + +/**** IRST register ****/ + +#define SERDES_GEN_IRST_PIPE_RST_L3_B_A (1 << 0) + +#define SERDES_GEN_IRST_PIPE_RST_L2_B_A (1 << 1) + +#define SERDES_GEN_IRST_PIPE_RST_L1_B_A (1 << 2) + +#define SERDES_GEN_IRST_PIPE_RST_L0_B_A (1 << 3) + +#define SERDES_GEN_IRST_MULTI_HARD_TXRX_L3_B_A (1 << 4) + +#define SERDES_GEN_IRST_MULTI_HARD_TXRX_L2_B_A (1 << 5) + +#define SERDES_GEN_IRST_MULTI_HARD_TXRX_L1_B_A (1 << 6) + +#define SERDES_GEN_IRST_MULTI_HARD_TXRX_L0_B_A (1 << 7) + +#define SERDES_GEN_IRST_MULTI_HARD_SYNTH_B_A (1 << 8) + +#define SERDES_GEN_IRST_POR_B_A (1 << 12) + +#define SERDES_GEN_IRST_PIPE_RST_L3_B_A_SEL (1 << 16) + +#define SERDES_GEN_IRST_PIPE_RST_L2_B_A_SEL (1 << 17) + +#define SERDES_GEN_IRST_PIPE_RST_L1_B_A_SEL (1 << 18) + +#define SERDES_GEN_IRST_PIPE_RST_L0_B_A_SEL (1 << 19) + +#define SERDES_GEN_IRST_MULTI_HARD_TXRX_L3_B_A_SEL (1 << 20) + +#define SERDES_GEN_IRST_MULTI_HARD_TXRX_L2_B_A_SEL (1 << 21) + +#define SERDES_GEN_IRST_MULTI_HARD_TXRX_L1_B_A_SEL (1 << 22) + +#define SERDES_GEN_IRST_MULTI_HARD_TXRX_L0_B_A_SEL (1 << 23) + +/**** OCTL_MULTI_SYNTHREADY register ****/ + +#define SERDES_GEN_OCTL_MULTI_SYNTHREADY_A (1 << 0) + +/**** OCTL_MULTI_SYNTHSTATUS register ****/ + +#define SERDES_GEN_OCTL_MULTI_SYNTHSTATUS_A (1 << 0) + +/**** clk_out register ****/ + +#define SERDES_GEN_CLK_OUT_SEL_MASK 0x0000003F +#define SERDES_GEN_CLK_OUT_SEL_SHIFT 0 + +/**** OCTL_PMA register ****/ + +#define SERDES_LANE_OCTL_PMA_TXSTATUS_L_A (1 << 0) + +/**** ICTL_MULTI_ANDME register ****/ + +#define SERDES_LANE_ICTL_MULTI_ANDME_EN_L_A (1 << 0) + +#define SERDES_LANE_ICTL_MULTI_ANDME_EN_L_A_SEL (1 << 1) + +/**** ICTL_MULTI_LB register ****/ + +#define SERDES_LANE_ICTL_MULTI_LB_TX2RXIOTIMEDEN_L_NT (1 << 0) + +#define SERDES_LANE_ICTL_MULTI_LB_TX2RXBUFTIMEDEN_L_NT (1 << 1) + +#define SERDES_LANE_ICTL_MULTI_LB_RX2TXUNTIMEDEN_L_NT (1 << 2) + +#define SERDES_LANE_ICTL_MULTI_LB_PARRX2TXTIMEDEN_L_NT (1 << 3) + +#define SERDES_LANE_ICTL_MULTI_LB_CDRCLK2TXEN_L_NT (1 << 4) + +#define SERDES_LANE_ICTL_MULTI_LB_TX2RXBUFTIMEDEN_L_NT_SEL (1 << 8) + +#define SERDES_LANE_ICTL_MULTI_LB_RX2TXUNTIMEDEN_L_NT_SEL (1 << 9) + +/**** ICTL_MULTI_RXBIST register ****/ + +#define SERDES_LANE_ICTL_MULTI_RXBIST_EN_L_A (1 << 0) + +/**** ICTL_MULTI_TXBIST register ****/ + +#define SERDES_LANE_ICTL_MULTI_TXBIST_EN_L_A (1 << 0) + +/**** ICTL_MULTI register ****/ + +#define SERDES_LANE_ICTL_MULTI_PSTATE_L_MASK 0x00000003 +#define SERDES_LANE_ICTL_MULTI_PSTATE_L_SHIFT 0 + +#define SERDES_LANE_ICTL_MULTI_PSTATE_L_SEL (1 << 2) + +#define SERDES_LANE_ICTL_MULTI_RXDATAWIDTH_L_MASK 0x00000070 +#define SERDES_LANE_ICTL_MULTI_RXDATAWIDTH_L_SHIFT 4 + +#define SERDES_LANE_ICTL_MULTI_RXOVRCDRLOCK2DATAEN_L_A (1 << 8) + +#define SERDES_LANE_ICTL_MULTI_RXOVRCDRLOCK2DATA_L_A (1 << 9) + +#define SERDES_LANE_ICTL_MULTI_TXBEACON_L_A (1 << 12) + +#define SERDES_LANE_ICTL_MULTI_TXDETECTRXREQ_L_A (1 << 13) + +#define SERDES_LANE_ICTL_MULTI_RXRATE_L_MASK 0x00070000 +#define SERDES_LANE_ICTL_MULTI_RXRATE_L_SHIFT 16 + +#define SERDES_LANE_ICTL_MULTI_RXRATE_L_SEL (1 << 19) + +#define SERDES_LANE_ICTL_MULTI_TXRATE_L_MASK 0x00700000 +#define SERDES_LANE_ICTL_MULTI_TXRATE_L_SHIFT 20 + +#define SERDES_LANE_ICTL_MULTI_TXRATE_L_SEL (1 << 23) + +#define SERDES_LANE_ICTL_MULTI_TXAMP_L_MASK 0x07000000 +#define SERDES_LANE_ICTL_MULTI_TXAMP_L_SHIFT 24 + +#define SERDES_LANE_ICTL_MULTI_TXAMP_EN_L (1 << 27) + +#define SERDES_LANE_ICTL_MULTI_TXDATAWIDTH_L_MASK 0x70000000 +#define SERDES_LANE_ICTL_MULTI_TXDATAWIDTH_L_SHIFT 28 + +/**** ICTL_MULTI_RXEQ register ****/ + +#define SERDES_LANE_ICTL_MULTI_RXEQ_EN_L (1 << 0) + +#define SERDES_LANE_ICTL_MULTI_RXEQ_START_L_A (1 << 1) + +#define SERDES_LANE_ICTL_MULTI_RXEQ_PRECAL_CODE_SEL_MASK 0x00000070 +#define SERDES_LANE_ICTL_MULTI_RXEQ_PRECAL_CODE_SEL_SHIFT 4 + +/**** ICTL_MULTI_RXEQ_L_high register ****/ + +#define SERDES_LANE_ICTL_MULTI_RXEQ_L_HIGH_VAL (1 << 0) + +/**** ICTL_MULTI_RXEYEDIAG register ****/ + +#define SERDES_LANE_ICTL_MULTI_RXEYEDIAG_START_L_A (1 << 0) + +/**** ICTL_MULTI_TXDEEMPH register ****/ + +#define SERDES_LANE_ICTL_MULTI_TXDEEMPH_L_MASK 0x0003FFFF +#define SERDES_LANE_ICTL_MULTI_TXDEEMPH_L_SHIFT 0 + +#define SERDES_LANE_ICTL_MULTI_TXDEEMPH_C_ZERO_MASK 0x7c0 +#define SERDES_LANE_ICTL_MULTI_TXDEEMPH_C_ZERO_SHIFT 6 +#define SERDES_LANE_ICTL_MULTI_TXDEEMPH_C_PLUS_MASK 0xf000 +#define SERDES_LANE_ICTL_MULTI_TXDEEMPH_C_PLUS_SHIFT 12 +#define SERDES_LANE_ICTL_MULTI_TXDEEMPH_C_MINUS_MASK 0x7 +#define SERDES_LANE_ICTL_MULTI_TXDEEMPH_C_MINUS_SHIFT 0 + +/**** ICTL_MULTI_TXMARGIN register ****/ + +#define SERDES_LANE_ICTL_MULTI_TXMARGIN_L_MASK 0x00000007 +#define SERDES_LANE_ICTL_MULTI_TXMARGIN_L_SHIFT 0 + +/**** ICTL_MULTI_TXSWING register ****/ + +#define SERDES_LANE_ICTL_MULTI_TXSWING_L (1 << 0) + +/**** IDAT_MULTI register ****/ + +#define SERDES_LANE_IDAT_MULTI_TXELECIDLE_L_MASK 0x0000000F +#define SERDES_LANE_IDAT_MULTI_TXELECIDLE_L_SHIFT 0 + +#define SERDES_LANE_IDAT_MULTI_TXELECIDLE_L_SEL (1 << 4) + +/**** IPD_MULTI register ****/ + +#define SERDES_LANE_IPD_MULTI_TX_L_B (1 << 0) + +#define SERDES_LANE_IPD_MULTI_RX_L_B (1 << 1) + +/**** OCTL_MULTI_RXBIST register ****/ + +#define SERDES_LANE_OCTL_MULTI_RXBIST_DONE_L_A (1 << 0) + +#define SERDES_LANE_OCTL_MULTI_RXBIST_RXLOCKED_L_A (1 << 1) + +/**** OCTL_MULTI register ****/ + +#define SERDES_LANE_OCTL_MULTI_RXCDRLOCK2DATA_L_A (1 << 0) + +#define SERDES_LANE_OCTL_MULTI_RXEQ_DONE_L_A (1 << 1) + +#define SERDES_LANE_OCTL_MULTI_RXREADY_L_A (1 << 2) + +#define SERDES_LANE_OCTL_MULTI_RXSTATUS_L_A (1 << 3) + +#define SERDES_LANE_OCTL_MULTI_TXREADY_L_A (1 << 4) + +#define SERDES_LANE_OCTL_MULTI_TXDETECTRXSTAT_L_A (1 << 5) + +#define SERDES_LANE_OCTL_MULTI_TXDETECTRXACK_L_A (1 << 6) + +#define SERDES_LANE_OCTL_MULTI_RXSIGNALDETECT_L_A (1 << 7) + +/**** OCTL_MULTI_RXEYEDIAG register ****/ + +#define SERDES_LANE_OCTL_MULTI_RXEYEDIAG_STAT_L_A_MASK 0x00003FFF +#define SERDES_LANE_OCTL_MULTI_RXEYEDIAG_STAT_L_A_SHIFT 0 + +#define SERDES_LANE_OCTL_MULTI_RXEYEDIAG_DONE_L_A (1 << 16) + +#define SERDES_LANE_OCTL_MULTI_RXEYEDIAG_ERR_L_A (1 << 17) + +/**** ODAT_MULTI_RXBIST register ****/ + +#define SERDES_LANE_ODAT_MULTI_RXBIST_ERRCOUNT_L_A_MASK 0x0000FFFF +#define SERDES_LANE_ODAT_MULTI_RXBIST_ERRCOUNT_L_A_SHIFT 0 + +#define SERDES_LANE_ODAT_MULTI_RXBIST_ERRCOUNT_OVERFLOW_L_A (1 << 16) + +/**** ODAT_MULTI_RXEQ register ****/ + +#define SERDES_LANE_ODAT_MULTI_RXEQ_BEST_EYE_VAL_L_A_MASK 0x00003FFF +#define SERDES_LANE_ODAT_MULTI_RXEQ_BEST_EYE_VAL_L_A_SHIFT 0 + +/**** MULTI_RX_DVALID register ****/ + +#define SERDES_LANE_MULTI_RX_DVALID_MASK_CDR_LOCK (1 << 0) + +#define SERDES_LANE_MULTI_RX_DVALID_MASK_SIGNALDETECT (1 << 1) + +#define SERDES_LANE_MULTI_RX_DVALID_MASK_TX_READY (1 << 2) + +#define SERDES_LANE_MULTI_RX_DVALID_MASK_RX_READY (1 << 3) + +#define SERDES_LANE_MULTI_RX_DVALID_MASK_SYNT_READY (1 << 4) + +#define SERDES_LANE_MULTI_RX_DVALID_MASK_RX_ELECIDLE (1 << 5) + +#define SERDES_LANE_MULTI_RX_DVALID_MUX_SEL_MASK 0x00FF0000 +#define SERDES_LANE_MULTI_RX_DVALID_MUX_SEL_SHIFT 16 + +#define SERDES_LANE_MULTI_RX_DVALID_PS_00_SEL (1 << 24) + +#define SERDES_LANE_MULTI_RX_DVALID_PS_00_VAL (1 << 25) + +#define SERDES_LANE_MULTI_RX_DVALID_PS_01_SEL (1 << 26) + +#define SERDES_LANE_MULTI_RX_DVALID_PS_01_VAL (1 << 27) + +#define SERDES_LANE_MULTI_RX_DVALID_PS_10_SEL (1 << 28) + +#define SERDES_LANE_MULTI_RX_DVALID_PS_10_VAL (1 << 29) + +#define SERDES_LANE_MULTI_RX_DVALID_PS_11_SEL (1 << 30) + +#define SERDES_LANE_MULTI_RX_DVALID_PS_11_VAL (1 << 31) + +/**** reserved register ****/ + +#define SERDES_LANE_RESERVED_OUT_MASK 0x000000FF +#define SERDES_LANE_RESERVED_OUT_SHIFT 0 + +#define SERDES_LANE_RESERVED_IN_MASK 0x00FF0000 +#define SERDES_LANE_RESERVED_IN_SHIFT 16 + +#ifdef __cplusplus +} +#endif + +#endif /* __AL_HAL_serdes_REGS_H__ */ + +/** @} end of ... group */ + + diff --git a/al_hal_udma.h b/al_hal_udma.h new file mode 100644 index 00000000000..a1bdb4fe8db --- /dev/null +++ b/al_hal_udma.h @@ -0,0 +1,672 @@ +/*- +******************************************************************************* +Copyright (C) 2015 Annapurna Labs Ltd. + +This file may be licensed under the terms of the Annapurna Labs Commercial +License Agreement. + +Alternatively, this file can be distributed under the terms of the GNU General +Public License V2 as published by the Free Software Foundation and can be +found at http://www.gnu.org/licenses/gpl-2.0.html + +Alternatively, redistribution and use in source and binary forms, with or +without modification, are permitted provided that the following conditions are +met: + + * Redistributions of source code must retain the above copyright notice, +this list of conditions and the following disclaimer. + + * Redistributions in binary form must reproduce the above copyright +notice, this list of conditions and the following disclaimer in +the documentation and/or other materials provided with the +distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +*******************************************************************************/ + +/** + * @defgroup group_udma_api API + * @ingroup group_udma + * UDMA API + * @{ + * @} + * + * @defgroup group_udma_main UDMA Main + * @ingroup group_udma_api + * UDMA main API + * @{ + * @file al_hal_udma.h + * + * @brief C Header file for the Universal DMA HAL driver + * + */ + +#ifndef __AL_HAL_UDMA_H__ +#define __AL_HAL_UDMA_H__ + +#include "al_hal_common.h" +#include "al_hal_udma_regs.h" + +/* *INDENT-OFF* */ +#ifdef __cplusplus +extern "C" { +#endif +/* *INDENT-ON* */ + +#define DMA_MAX_Q 4 +#define AL_UDMA_MIN_Q_SIZE 4 +#define AL_UDMA_MAX_Q_SIZE (1 << 16) /* hw can do more, but we limit it */ + +/* Default Max number of descriptors supported per action */ +#define AL_UDMA_DEFAULT_MAX_ACTN_DESCS 16 + +#define AL_UDMA_REV_ID_0 0 +#define AL_UDMA_REV_ID_1 1 +#define AL_UDMA_REV_ID_2 2 + +#define DMA_RING_ID_MASK 0x3 +/* New registers ?? */ +/* Statistics - TBD */ + +/** UDMA submission descriptor */ +union al_udma_desc { + /* TX */ + struct { + uint32_t len_ctrl; + uint32_t meta_ctrl; + uint64_t buf_ptr; + } tx; + /* TX Meta, used by upper layer */ + struct { + uint32_t len_ctrl; + uint32_t meta_ctrl; + uint32_t meta1; + uint32_t meta2; + } tx_meta; + /* RX */ + struct { + uint32_t len_ctrl; + uint32_t buf2_ptr_lo; + uint64_t buf1_ptr; + } rx; +} __packed_a16; + +/* TX desc length and control fields */ + +#define AL_M2S_DESC_CONCAT AL_BIT(31) /* concatenate */ +#define AL_M2S_DESC_DMB AL_BIT(30) + /** Data Memory Barrier */ +#define AL_M2S_DESC_NO_SNOOP_H AL_BIT(29) +#define AL_M2S_DESC_INT_EN AL_BIT(28) /** enable interrupt */ +#define AL_M2S_DESC_LAST AL_BIT(27) +#define AL_M2S_DESC_FIRST AL_BIT(26) +#define AL_M2S_DESC_RING_ID_SHIFT 24 +#define AL_M2S_DESC_RING_ID_MASK (0x3 << AL_M2S_DESC_RING_ID_SHIFT) +#define AL_M2S_DESC_META_DATA AL_BIT(23) +#define AL_M2S_DESC_DUMMY AL_BIT(22) /* for Metdata only */ +#define AL_M2S_DESC_LEN_ADJ_SHIFT 20 +#define AL_M2S_DESC_LEN_ADJ_MASK (0x7 << AL_M2S_DESC_LEN_ADJ_SHIFT) +#define AL_M2S_DESC_LEN_SHIFT 0 +#define AL_M2S_DESC_LEN_MASK (0xfffff << AL_M2S_DESC_LEN_SHIFT) + +#define AL_S2M_DESC_DUAL_BUF AL_BIT(31) +#define AL_S2M_DESC_NO_SNOOP_H AL_BIT(29) +#define AL_S2M_DESC_INT_EN AL_BIT(28) /** enable interrupt */ +#define AL_S2M_DESC_RING_ID_SHIFT 24 +#define AL_S2M_DESC_RING_ID_MASK (0x3 << AL_S2M_DESC_RING_ID_SHIFT) +#define AL_S2M_DESC_LEN_SHIFT 0 +#define AL_S2M_DESC_LEN_MASK (0xffff << AL_S2M_DESC_LEN_SHIFT) +#define AL_S2M_DESC_LEN2_SHIFT 16 +#define AL_S2M_DESC_LEN2_MASK (0x3fff << AL_S2M_DESC_LEN2_SHIFT) +#define AL_S2M_DESC_LEN2_GRANULARITY_SHIFT 6 + +/* TX/RX descriptor VMID field (in the buffer address 64 bit field) */ +#define AL_UDMA_DESC_VMID_SHIFT 48 + +/** UDMA completion descriptor */ +union al_udma_cdesc { + /* TX completion */ + struct { + uint32_t ctrl_meta; + } al_desc_comp_tx; + /* RX completion */ + struct { + /* TBD */ + uint32_t ctrl_meta; + } al_desc_comp_rx; +} __packed_a4; + +/* TX/RX common completion desc ctrl_meta feilds */ +#define AL_UDMA_CDESC_ERROR AL_BIT(31) +#define AL_UDMA_CDESC_BUF1_USED AL_BIT(30) +#define AL_UDMA_CDESC_DDP AL_BIT(29) +#define AL_UDMA_CDESC_LAST AL_BIT(27) +#define AL_UDMA_CDESC_FIRST AL_BIT(26) +/* word 2 */ +#define AL_UDMA_CDESC_BUF2_USED AL_BIT(31) +#define AL_UDMA_CDESC_BUF2_LEN_SHIFT 16 +#define AL_UDMA_CDESC_BUF2_LEN_MASK AL_FIELD_MASK(29, 16) +/** Basic Buffer structure */ +struct al_buf { + al_phys_addr_t addr; /**< Buffer physical address */ + uint32_t len; /**< Buffer lenght in bytes */ +}; + +/** Block is a set of buffers that belong to same source or destination */ +struct al_block { + struct al_buf *bufs; /**< The buffers of the block */ + uint32_t num; /**< Number of buffers of the block */ + + /**< + * VMID to be assigned to the block descriptors + * Requires VMID in descriptor to be enabled for the specific UDMA + * queue. + */ + uint16_t vmid; +}; + +/** UDMA type */ +enum al_udma_type { + UDMA_TX, + UDMA_RX +}; + +/** UDMA state */ +enum al_udma_state { + UDMA_DISABLE = 0, + UDMA_IDLE, + UDMA_NORMAL, + UDMA_ABORT, + UDMA_RESET +}; + +extern const char *const al_udma_states_name[]; + +/** UDMA Q specific parameters from upper layer */ +struct al_udma_q_params { + uint32_t size; /**< ring size (in descriptors), submission and + * completion rings must have same size + */ + union al_udma_desc *desc_base; /**< cpu address for submission ring + * descriptors + */ + al_phys_addr_t desc_phy_base; /**< submission ring descriptors + * physical base address + */ +#ifdef __FreeBSD__ + bus_dma_tag_t desc_phy_base_tag; + bus_dmamap_t desc_phy_base_map; +#endif + uint8_t *cdesc_base; /**< completion descriptors pointer, NULL */ + /* means no completion update */ + al_phys_addr_t cdesc_phy_base; /**< completion descriptors ring + * physical base address + */ +#ifdef __FreeBSD__ + bus_dma_tag_t cdesc_phy_base_tag; + bus_dmamap_t cdesc_phy_base_map; +#endif + uint32_t cdesc_size; /**< size (in bytes) of a single dma completion + * descriptor + */ + + uint8_t adapter_rev_id; /**next_cdesc_idx - (udma_q->next_desc_idx + 1); + tmp &= udma_q->size_mask; + + return (uint32_t) tmp; +} + +/** + * check if queue has pending descriptors + * + * @param udma_q queue handle + * + * @return AL_TRUE if descriptors are submitted to completion ring and still + * not completed (with ack). AL_FALSE otherwise. + */ +static INLINE al_bool al_udma_is_empty(struct al_udma_q *udma_q) +{ + if (((udma_q->next_cdesc_idx - udma_q->next_desc_idx) & + udma_q->size_mask) == 0) + return AL_TRUE; + + return AL_FALSE; +} + +/** + * get next available descriptor + * @param udma_q queue handle + * + * @return pointer to the next available descriptor + */ +static INLINE union al_udma_desc *al_udma_desc_get(struct al_udma_q *udma_q) +{ + union al_udma_desc *desc; + uint16_t next_desc_idx; + + al_assert(udma_q); + + next_desc_idx = udma_q->next_desc_idx; + desc = udma_q->desc_base_ptr + next_desc_idx; + + next_desc_idx++; + + /* if reached end of queue, wrap around */ + udma_q->next_desc_idx = next_desc_idx & udma_q->size_mask; + + return desc; +} + +/** + * get ring id for the last allocated descriptor + * @param udma_q + * + * @return ring id for the last allocated descriptor + * this function must be called each time a new descriptor is allocated + * by the al_udma_desc_get(), unless ring id is ignored. + */ +static INLINE uint32_t al_udma_ring_id_get(struct al_udma_q *udma_q) +{ + uint32_t ring_id; + + al_assert(udma_q); + + ring_id = udma_q->desc_ring_id; + + /* calculate the ring id of the next desc */ + /* if next_desc points to first desc, then queue wrapped around */ + if (unlikely(udma_q->next_desc_idx) == 0) + udma_q->desc_ring_id = (udma_q->desc_ring_id + 1) & + DMA_RING_ID_MASK; + return ring_id; +} + +/* add DMA action - trigger the engine */ +/** + * add num descriptors to the submission queue. + * + * @param udma_q queue handle + * @param num number of descriptors to add to the queues ring. + * + * @return 0; + */ +static INLINE int al_udma_desc_action_add(struct al_udma_q *udma_q, + uint32_t num) +{ + uint32_t *addr; + + al_assert(udma_q); + al_assert((num > 0) && (num <= udma_q->size)); + + addr = &udma_q->q_regs->rings.drtp_inc; + /* make sure data written to the descriptors will be visible by the */ + /* DMA */ + al_local_data_memory_barrier(); + + /* + * As we explicitly invoke the synchronization function + * (al_data_memory_barrier()), then we can use the relaxed version. + */ + al_reg_write32_relaxed(addr, num); + + return 0; +} + +#define cdesc_is_first(flags) ((flags) & AL_UDMA_CDESC_FIRST) +#define cdesc_is_last(flags) ((flags) & AL_UDMA_CDESC_LAST) + +/** + * return pointer to the cdesc + offset desciptors. wrap around when needed. + * + * @param udma_q queue handle + * @param cdesc pointer that set by this function + * @param offset offset desciptors + * + */ +static INLINE volatile union al_udma_cdesc *al_cdesc_next( + struct al_udma_q *udma_q, + volatile union al_udma_cdesc *cdesc, + uint32_t offset) +{ + volatile uint8_t *tmp = (volatile uint8_t *) cdesc + offset * udma_q->cdesc_size; + al_assert(udma_q); + al_assert(cdesc); + + /* if wrap around */ + if (unlikely((tmp > udma_q->end_cdesc_ptr))) + return (union al_udma_cdesc *) + (udma_q->cdesc_base_ptr + + (tmp - udma_q->end_cdesc_ptr - udma_q->cdesc_size)); + + return (volatile union al_udma_cdesc *) tmp; +} + +/** + * check if the flags of the descriptor indicates that is new one + * the function uses the ring id from the descriptor flags to know whether it + * new one by comparing it with the curring ring id of the queue + * + * @param udma_q queue handle + * @param flags the flags of the completion descriptor + * + * @return AL_TRUE if the completion descriptor is new one. + * AL_FALSE if it old one. + */ +static INLINE al_bool al_udma_new_cdesc(struct al_udma_q *udma_q, + uint32_t flags) +{ + if (((flags & AL_M2S_DESC_RING_ID_MASK) >> AL_M2S_DESC_RING_ID_SHIFT) + == udma_q->comp_ring_id) + return AL_TRUE; + return AL_FALSE; +} + +/** + * get next completion descriptor + * this function will also increment the completion ring id when the ring wraps + * around + * + * @param udma_q queue handle + * @param cdesc current completion descriptor + * + * @return pointer to the completion descriptor that follows the one pointed by + * cdesc + */ +static INLINE volatile union al_udma_cdesc *al_cdesc_next_update( + struct al_udma_q *udma_q, + volatile union al_udma_cdesc *cdesc) +{ + /* if last desc, wrap around */ + if (unlikely(((volatile uint8_t *) cdesc == udma_q->end_cdesc_ptr))) { + udma_q->comp_ring_id = + (udma_q->comp_ring_id + 1) & DMA_RING_ID_MASK; + return (union al_udma_cdesc *) udma_q->cdesc_base_ptr; + } + return (volatile union al_udma_cdesc *) ((volatile uint8_t *) cdesc + udma_q->cdesc_size); +} + +/** + * get next completed packet from completion ring of the queue + * + * @param udma_q udma queue handle + * @param desc pointer that set by this function to the first descriptor + * note: desc is valid only when return value is not zero + * @return number of descriptors that belong to the packet. 0 means no completed + * full packet was found. + * If the descriptors found in the completion queue don't form full packet (no + * desc with LAST flag), then this function will do the following: + * (1) save the number of processed descriptors. + * (2) save last processed descriptor, so next time it called, it will resume + * from there. + * (3) return 0. + * note: the descriptors that belong to the completed packet will still be + * considered as used, that means the upper layer is safe to access those + * descriptors when this function returns. the al_udma_cdesc_ack() should be + * called to inform the udma driver that those descriptors are freed. + */ +uint32_t al_udma_cdesc_packet_get( + struct al_udma_q *udma_q, + volatile union al_udma_cdesc **desc); + +/** get completion descriptor pointer from its index */ +#define al_udma_cdesc_idx_to_ptr(udma_q, idx) \ + ((volatile union al_udma_cdesc *) ((udma_q)->cdesc_base_ptr + \ + (idx) * (udma_q)->cdesc_size)) + + +/** + * return number of all completed descriptors in the completion ring + * + * @param udma_q udma queue handle + * @param cdesc pointer that set by this function to the first descriptor + * note: desc is valid only when return value is not zero + * note: pass NULL if not interested + * @return number of descriptors. 0 means no completed descriptors were found. + * note: the descriptors that belong to the completed packet will still be + * considered as used, that means the upper layer is safe to access those + * descriptors when this function returns. the al_udma_cdesc_ack() should be + * called to inform the udma driver that those descriptors are freed. + */ +static INLINE uint32_t al_udma_cdesc_get_all( + struct al_udma_q *udma_q, + volatile union al_udma_cdesc **cdesc) +{ + uint16_t count = 0; + + al_assert(udma_q); + + udma_q->comp_head_idx = (uint16_t) + (al_reg_read32(&udma_q->q_regs->rings.crhp) & + 0xFFFF); + + count = (udma_q->comp_head_idx - udma_q->next_cdesc_idx) & + udma_q->size_mask; + + if (cdesc) + *cdesc = al_udma_cdesc_idx_to_ptr(udma_q, udma_q->next_cdesc_idx); + + return (uint32_t)count; +} + +/** + * acknowledge the driver that the upper layer completed processing completion + * descriptors + * + * @param udma_q udma queue handle + * @param num number of descriptors to acknowledge + * + * @return 0 + */ +static INLINE int al_udma_cdesc_ack(struct al_udma_q *udma_q, uint32_t num) +{ + al_assert(udma_q); + + udma_q->next_cdesc_idx += num; + udma_q->next_cdesc_idx &= udma_q->size_mask; + + return 0; +} + +/* *INDENT-OFF* */ +#ifdef __cplusplus +} +#endif +/* *INDENT-ON* */ + +#endif /* __AL_HAL_UDMA_H__ */ +/** @} end of UDMA group */ diff --git a/al_hal_udma_config.c b/al_hal_udma_config.c new file mode 100644 index 00000000000..a06f7898308 --- /dev/null +++ b/al_hal_udma_config.c @@ -0,0 +1,1373 @@ +/*- +******************************************************************************* +Copyright (C) 2015 Annapurna Labs Ltd. + +This file may be licensed under the terms of the Annapurna Labs Commercial +License Agreement. + +Alternatively, this file can be distributed under the terms of the GNU General +Public License V2 as published by the Free Software Foundation and can be +found at http://www.gnu.org/licenses/gpl-2.0.html + +Alternatively, redistribution and use in source and binary forms, with or +without modification, are permitted provided that the following conditions are +met: + + * Redistributions of source code must retain the above copyright notice, +this list of conditions and the following disclaimer. + + * Redistributions in binary form must reproduce the above copyright +notice, this list of conditions and the following disclaimer in +the documentation and/or other materials provided with the +distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +*******************************************************************************/ + +/** + * @file al_hal_udma_config.c + * + * @brief Universal DMA HAL driver for configurations + * + */ + +#include +#include +#include + +/**************** Misc configurations *********************/ +/** Configure AXI generic configuration */ +int al_udma_axi_set(struct udma_gen_axi *axi_regs, + struct al_udma_axi_conf *axi) +{ + uint32_t reg; + + al_reg_write32(&axi_regs->cfg_1, axi->axi_timeout); + + reg = al_reg_read32(&axi_regs->cfg_2); + reg &= ~UDMA_GEN_AXI_CFG_2_ARB_PROMOTION_MASK; + reg |= axi->arb_promotion; + al_reg_write32(&axi_regs->cfg_2, reg); + + reg = al_reg_read32(&axi_regs->endian_cfg); + if (axi->swap_8_bytes == AL_TRUE) + reg |= UDMA_GEN_AXI_ENDIAN_CFG_SWAP_64B_EN; + else + reg &= ~UDMA_GEN_AXI_ENDIAN_CFG_SWAP_64B_EN; + + if (axi->swap_s2m_data == AL_TRUE) + reg |= UDMA_GEN_AXI_ENDIAN_CFG_SWAP_S2M_DATA; + else + reg &= ~UDMA_GEN_AXI_ENDIAN_CFG_SWAP_S2M_DATA; + + if (axi->swap_s2m_desc == AL_TRUE) + reg |= UDMA_GEN_AXI_ENDIAN_CFG_SWAP_S2M_DESC; + else + reg &= ~UDMA_GEN_AXI_ENDIAN_CFG_SWAP_S2M_DESC; + + if (axi->swap_m2s_data == AL_TRUE) + reg |= UDMA_GEN_AXI_ENDIAN_CFG_SWAP_M2S_DATA; + else + reg &= ~UDMA_GEN_AXI_ENDIAN_CFG_SWAP_M2S_DATA; + + if (axi->swap_m2s_desc == AL_TRUE) + reg |= UDMA_GEN_AXI_ENDIAN_CFG_SWAP_M2S_DESC; + else + reg &= ~UDMA_GEN_AXI_ENDIAN_CFG_SWAP_M2S_DESC; + + al_reg_write32(&axi_regs->endian_cfg, reg); + return 0; +} + +/* Configure UDMA AXI M2S configuration */ +/** Configure AXI M2S submaster */ +static int al_udma_m2s_axi_sm_set(struct al_udma_axi_submaster *m2s_sm, + uint32_t *cfg_1, uint32_t *cfg_2, + uint32_t *cfg_max_beats) +{ + uint32_t reg; + reg = al_reg_read32(cfg_1); + reg &= ~UDMA_AXI_M2S_COMP_WR_CFG_1_AWID_MASK; + reg |= m2s_sm->id & UDMA_AXI_M2S_COMP_WR_CFG_1_AWID_MASK; + reg &= ~UDMA_AXI_M2S_COMP_WR_CFG_1_AWCACHE_MASK; + reg |= (m2s_sm->cache_type << + UDMA_AXI_M2S_COMP_WR_CFG_1_AWCACHE_SHIFT) & + UDMA_AXI_M2S_COMP_WR_CFG_1_AWCACHE_MASK; + reg &= ~UDMA_AXI_M2S_COMP_WR_CFG_1_AWBURST_MASK; + reg |= (m2s_sm->burst << UDMA_AXI_M2S_COMP_WR_CFG_1_AWBURST_SHIFT) & + UDMA_AXI_M2S_COMP_WR_CFG_1_AWBURST_MASK; + al_reg_write32(cfg_1, reg); + + reg = al_reg_read32(cfg_2); + reg &= ~UDMA_AXI_M2S_COMP_WR_CFG_2_AWUSER_MASK; + reg |= m2s_sm->used_ext & UDMA_AXI_M2S_COMP_WR_CFG_2_AWUSER_MASK; + reg &= ~UDMA_AXI_M2S_COMP_WR_CFG_2_AWSIZE_MASK; + reg |= (m2s_sm->bus_size << + UDMA_AXI_M2S_COMP_WR_CFG_2_AWSIZE_SHIFT) & + UDMA_AXI_M2S_COMP_WR_CFG_2_AWSIZE_MASK; + reg &= ~UDMA_AXI_M2S_COMP_WR_CFG_2_AWQOS_MASK; + reg |= (m2s_sm->qos << UDMA_AXI_M2S_COMP_WR_CFG_2_AWQOS_SHIFT) & + UDMA_AXI_M2S_COMP_WR_CFG_2_AWQOS_MASK; + reg &= ~UDMA_AXI_M2S_COMP_WR_CFG_2_AWPROT_MASK; + reg |= (m2s_sm->prot << UDMA_AXI_M2S_COMP_WR_CFG_2_AWPROT_SHIFT) & + UDMA_AXI_M2S_COMP_WR_CFG_2_AWPROT_MASK; + al_reg_write32(cfg_2, reg); + + reg = al_reg_read32(cfg_max_beats); + reg &= ~UDMA_AXI_M2S_DESC_WR_CFG_1_MAX_AXI_BEATS_MASK; + reg |= m2s_sm->max_beats & + UDMA_AXI_M2S_DESC_WR_CFG_1_MAX_AXI_BEATS_MASK; + al_reg_write32(cfg_max_beats, reg); + + return 0; +} + +/** Configure UDMA AXI M2S configuration */ +int al_udma_m2s_axi_set(struct al_udma *udma, + struct al_udma_m2s_axi_conf *axi_m2s) +{ + uint32_t reg; + + al_udma_m2s_axi_sm_set(&axi_m2s->comp_write, + &udma->udma_regs->m2s.axi_m2s.comp_wr_cfg_1, + &udma->udma_regs->m2s.axi_m2s.comp_wr_cfg_2, + &udma->udma_regs->m2s.axi_m2s.desc_wr_cfg_1); + + al_udma_m2s_axi_sm_set(&axi_m2s->data_read, + &udma->udma_regs->m2s.axi_m2s.data_rd_cfg_1, + &udma->udma_regs->m2s.axi_m2s.data_rd_cfg_2, + &udma->udma_regs->m2s.axi_m2s.data_rd_cfg); + + al_udma_m2s_axi_sm_set(&axi_m2s->desc_read, + &udma->udma_regs->m2s.axi_m2s.desc_rd_cfg_1, + &udma->udma_regs->m2s.axi_m2s.desc_rd_cfg_2, + &udma->udma_regs->m2s.axi_m2s.desc_rd_cfg_3); + + reg = al_reg_read32(&udma->udma_regs->m2s.axi_m2s.data_rd_cfg); + if (axi_m2s->break_on_max_boundary == AL_TRUE) + reg |= UDMA_AXI_M2S_DATA_RD_CFG_ALWAYS_BREAK_ON_MAX_BOUDRY; + else + reg &= ~UDMA_AXI_M2S_DATA_RD_CFG_ALWAYS_BREAK_ON_MAX_BOUDRY; + al_reg_write32(&udma->udma_regs->m2s.axi_m2s.data_rd_cfg, reg); + + reg = al_reg_read32(&udma->udma_regs->m2s.axi_m2s.desc_wr_cfg_1); + reg &= ~UDMA_AXI_M2S_DESC_WR_CFG_1_MIN_AXI_BEATS_MASK; + reg |= (axi_m2s->min_axi_beats << + UDMA_AXI_M2S_DESC_WR_CFG_1_MIN_AXI_BEATS_SHIFT) & + UDMA_AXI_M2S_DESC_WR_CFG_1_MIN_AXI_BEATS_MASK; + al_reg_write32(&udma->udma_regs->m2s.axi_m2s.desc_wr_cfg_1, reg); + + reg = al_reg_read32(&udma->udma_regs->m2s.axi_m2s.ostand_cfg); + reg &= ~UDMA_AXI_M2S_OSTAND_CFG_MAX_DATA_RD_MASK; + reg |= axi_m2s->ostand_max_data_read & + UDMA_AXI_M2S_OSTAND_CFG_MAX_DATA_RD_MASK; + reg &= ~UDMA_AXI_M2S_OSTAND_CFG_MAX_DESC_RD_MASK; + reg |= (axi_m2s->ostand_max_desc_read << + UDMA_AXI_M2S_OSTAND_CFG_MAX_DESC_RD_SHIFT) & + UDMA_AXI_M2S_OSTAND_CFG_MAX_DESC_RD_MASK; + reg &= ~UDMA_AXI_M2S_OSTAND_CFG_MAX_COMP_REQ_MASK; + reg |= (axi_m2s->ostand_max_comp_req << + UDMA_AXI_M2S_OSTAND_CFG_MAX_COMP_REQ_SHIFT) & + UDMA_AXI_M2S_OSTAND_CFG_MAX_COMP_REQ_MASK; + reg &= ~UDMA_AXI_M2S_OSTAND_CFG_MAX_COMP_DATA_WR_MASK; + reg |= (axi_m2s->ostand_max_comp_write << + UDMA_AXI_M2S_OSTAND_CFG_MAX_COMP_DATA_WR_SHIFT) & + UDMA_AXI_M2S_OSTAND_CFG_MAX_COMP_DATA_WR_MASK; + al_reg_write32(&udma->udma_regs->m2s.axi_m2s.ostand_cfg, reg); + return 0; +} + +/** Configure AXI S2M submaster */ +static int al_udma_s2m_axi_sm_set(struct al_udma_axi_submaster *s2m_sm, + uint32_t *cfg_1, uint32_t *cfg_2, + uint32_t *cfg_max_beats) +{ + uint32_t reg; + reg = al_reg_read32(cfg_1); + reg &= ~UDMA_AXI_S2M_COMP_WR_CFG_1_AWID_MASK; + reg |= s2m_sm->id & UDMA_AXI_S2M_COMP_WR_CFG_1_AWID_MASK; + reg &= ~UDMA_AXI_S2M_COMP_WR_CFG_1_AWCACHE_MASK; + reg |= (s2m_sm->cache_type << + UDMA_AXI_S2M_COMP_WR_CFG_1_AWCACHE_SHIFT) & + UDMA_AXI_S2M_COMP_WR_CFG_1_AWCACHE_MASK; + reg &= ~UDMA_AXI_S2M_COMP_WR_CFG_1_AWBURST_MASK; + reg |= (s2m_sm->burst << UDMA_AXI_S2M_COMP_WR_CFG_1_AWBURST_SHIFT) & + UDMA_AXI_S2M_COMP_WR_CFG_1_AWBURST_MASK; + al_reg_write32(cfg_1, reg); + + reg = al_reg_read32(cfg_2); + reg &= ~UDMA_AXI_S2M_COMP_WR_CFG_2_AWUSER_MASK; + reg |= s2m_sm->used_ext & UDMA_AXI_S2M_COMP_WR_CFG_2_AWUSER_MASK; + reg &= ~UDMA_AXI_S2M_COMP_WR_CFG_2_AWSIZE_MASK; + reg |= (s2m_sm->bus_size << UDMA_AXI_S2M_COMP_WR_CFG_2_AWSIZE_SHIFT) & + UDMA_AXI_S2M_COMP_WR_CFG_2_AWSIZE_MASK; + reg &= ~UDMA_AXI_S2M_COMP_WR_CFG_2_AWQOS_MASK; + reg |= (s2m_sm->qos << UDMA_AXI_S2M_COMP_WR_CFG_2_AWQOS_SHIFT) & + UDMA_AXI_S2M_COMP_WR_CFG_2_AWQOS_MASK; + reg &= ~UDMA_AXI_S2M_COMP_WR_CFG_2_AWPROT_MASK; + reg |= (s2m_sm->prot << UDMA_AXI_S2M_COMP_WR_CFG_2_AWPROT_SHIFT) & + UDMA_AXI_S2M_COMP_WR_CFG_2_AWPROT_MASK; + al_reg_write32(cfg_2, reg); + + reg = al_reg_read32(cfg_max_beats); + reg &= ~UDMA_AXI_S2M_DESC_WR_CFG_1_MAX_AXI_BEATS_MASK; + reg |= s2m_sm->max_beats & + UDMA_AXI_S2M_DESC_WR_CFG_1_MAX_AXI_BEATS_MASK; + al_reg_write32(cfg_max_beats, reg); + + return 0; +} + +/** Configure UDMA AXI S2M configuration */ +int al_udma_s2m_axi_set(struct al_udma *udma, + struct al_udma_s2m_axi_conf *axi_s2m) +{ + + uint32_t reg; + + al_udma_s2m_axi_sm_set(&axi_s2m->data_write, + &udma->udma_regs->s2m.axi_s2m.data_wr_cfg_1, + &udma->udma_regs->s2m.axi_s2m.data_wr_cfg_2, + &udma->udma_regs->s2m.axi_s2m.data_wr_cfg); + + al_udma_s2m_axi_sm_set(&axi_s2m->desc_read, + &udma->udma_regs->s2m.axi_s2m.desc_rd_cfg_4, + &udma->udma_regs->s2m.axi_s2m.desc_rd_cfg_5, + &udma->udma_regs->s2m.axi_s2m.desc_rd_cfg_3); + + al_udma_s2m_axi_sm_set(&axi_s2m->comp_write, + &udma->udma_regs->s2m.axi_s2m.comp_wr_cfg_1, + &udma->udma_regs->s2m.axi_s2m.comp_wr_cfg_2, + &udma->udma_regs->s2m.axi_s2m.desc_wr_cfg_1); + + reg = al_reg_read32(&udma->udma_regs->s2m.axi_s2m.desc_rd_cfg_3); + if (axi_s2m->break_on_max_boundary == AL_TRUE) + reg |= UDMA_AXI_S2M_DESC_RD_CFG_3_ALWAYS_BREAK_ON_MAX_BOUDRY; + else + reg &= ~UDMA_AXI_S2M_DESC_RD_CFG_3_ALWAYS_BREAK_ON_MAX_BOUDRY; + al_reg_write32(&udma->udma_regs->s2m.axi_s2m.desc_rd_cfg_3, reg); + + reg = al_reg_read32(&udma->udma_regs->s2m.axi_s2m.desc_wr_cfg_1); + reg &= ~UDMA_AXI_S2M_DESC_WR_CFG_1_MIN_AXI_BEATS_MASK; + reg |= (axi_s2m->min_axi_beats << + UDMA_AXI_S2M_DESC_WR_CFG_1_MIN_AXI_BEATS_SHIFT) & + UDMA_AXI_S2M_DESC_WR_CFG_1_MIN_AXI_BEATS_MASK; + al_reg_write32(&udma->udma_regs->s2m.axi_s2m.desc_wr_cfg_1, reg); + + reg = al_reg_read32(&udma->udma_regs->s2m.axi_s2m.ostand_cfg_rd); + reg &= ~UDMA_AXI_S2M_OSTAND_CFG_RD_MAX_DESC_RD_OSTAND_MASK; + reg |= axi_s2m->ostand_max_desc_read & + UDMA_AXI_S2M_OSTAND_CFG_RD_MAX_DESC_RD_OSTAND_MASK; + + reg &= ~UDMA_AXI_S2M_OSTAND_CFG_RD_MAX_STREAM_ACK_MASK; + reg |= (axi_s2m->ack_fifo_depth << + UDMA_AXI_S2M_OSTAND_CFG_RD_MAX_STREAM_ACK_SHIFT) & + UDMA_AXI_S2M_OSTAND_CFG_RD_MAX_STREAM_ACK_MASK; + + al_reg_write32(&udma->udma_regs->s2m.axi_s2m.ostand_cfg_rd, reg); + + reg = al_reg_read32(&udma->udma_regs->s2m.axi_s2m.ostand_cfg_wr); + reg &= ~UDMA_AXI_S2M_OSTAND_CFG_WR_MAX_DATA_WR_OSTAND_MASK; + reg |= axi_s2m->ostand_max_data_req & + UDMA_AXI_S2M_OSTAND_CFG_WR_MAX_DATA_WR_OSTAND_MASK; + reg &= ~UDMA_AXI_S2M_OSTAND_CFG_WR_MAX_DATA_BEATS_WR_OSTAND_MASK; + reg |= (axi_s2m->ostand_max_data_write << + UDMA_AXI_S2M_OSTAND_CFG_WR_MAX_DATA_BEATS_WR_OSTAND_SHIFT) & + UDMA_AXI_S2M_OSTAND_CFG_WR_MAX_DATA_BEATS_WR_OSTAND_MASK; + reg &= ~UDMA_AXI_S2M_OSTAND_CFG_WR_MAX_COMP_REQ_MASK; + reg |= (axi_s2m->ostand_max_comp_req << + UDMA_AXI_S2M_OSTAND_CFG_WR_MAX_COMP_REQ_SHIFT) & + UDMA_AXI_S2M_OSTAND_CFG_WR_MAX_COMP_REQ_MASK; + reg &= ~UDMA_AXI_S2M_OSTAND_CFG_WR_MAX_COMP_DATA_WR_OSTAND_MASK; + reg |= (axi_s2m->ostand_max_comp_write << + UDMA_AXI_S2M_OSTAND_CFG_WR_MAX_COMP_DATA_WR_OSTAND_SHIFT) & + UDMA_AXI_S2M_OSTAND_CFG_WR_MAX_COMP_DATA_WR_OSTAND_MASK; + al_reg_write32(&udma->udma_regs->s2m.axi_s2m.ostand_cfg_wr, reg); + return 0; +} + +/** M2S packet len configuration */ +int al_udma_m2s_packet_size_cfg_set(struct al_udma *udma, + struct al_udma_m2s_pkt_len_conf *conf) +{ + uint32_t reg = al_reg_read32(&udma->udma_regs->m2s.m2s.cfg_len); + uint32_t max_supported_size = UDMA_M2S_CFG_LEN_MAX_PKT_SIZE_MASK; + + al_assert(udma->type == UDMA_TX); + + if (conf->encode_64k_as_zero == AL_TRUE) + max_supported_size += 1; /* 64K */ + + if (conf->max_pkt_size > max_supported_size) { + al_err("udma [%s]: requested max_pkt_size (0x%x) exceeds the" + "supported limit (0x%x)\n", udma->name, + conf->max_pkt_size, max_supported_size); + return -EINVAL; + } + + reg &= ~UDMA_M2S_CFG_LEN_ENCODE_64K; + if (conf->encode_64k_as_zero == AL_TRUE) + reg |= UDMA_M2S_CFG_LEN_ENCODE_64K; + else + reg &= ~UDMA_M2S_CFG_LEN_ENCODE_64K; + + reg &= ~UDMA_M2S_CFG_LEN_MAX_PKT_SIZE_MASK; + reg |= conf->max_pkt_size; + + al_reg_write32(&udma->udma_regs->m2s.m2s.cfg_len, reg); + return 0; +} + +/** Report Error - to be used for abort */ +void al_udma_err_report(struct al_udma *udma __attribute__((__unused__))) +{ + return; +} + +/** Statistics - TBD */ +void al_udma_stats_get(struct al_udma *udma __attribute__((__unused__))) +{ + return; +} + +/** Configure UDMA M2S descriptor prefetch */ +int al_udma_m2s_pref_set(struct al_udma *udma, + struct al_udma_m2s_desc_pref_conf *conf) +{ + uint32_t reg; + + reg = al_reg_read32(&udma->udma_regs->m2s.m2s_rd.desc_pref_cfg_1); + reg &= ~UDMA_M2S_RD_DESC_PREF_CFG_1_FIFO_DEPTH_MASK; + reg |= conf->desc_fifo_depth; + al_reg_write32(&udma->udma_regs->m2s.m2s_rd.desc_pref_cfg_1, reg); + + reg = al_reg_read32(&udma->udma_regs->m2s.m2s_rd.desc_pref_cfg_2); + + if (conf->sch_mode == SRR) + reg |= UDMA_M2S_RD_DESC_PREF_CFG_2_PREF_FORCE_RR; + else if (conf->sch_mode == STRICT) + reg &= ~UDMA_M2S_RD_DESC_PREF_CFG_2_PREF_FORCE_RR; + else { + al_err("udma [%s]: requested descriptor preferch arbiter " + "mode (%d) is invalid\n", udma->name, conf->sch_mode); + return -EINVAL; + } + reg &= ~UDMA_M2S_RD_DESC_PREF_CFG_2_MAX_DESC_PER_PKT_MASK; + reg |= conf->max_desc_per_packet & + UDMA_M2S_RD_DESC_PREF_CFG_2_MAX_DESC_PER_PKT_MASK; + al_reg_write32(&udma->udma_regs->m2s.m2s_rd.desc_pref_cfg_2, reg); + + reg = al_reg_read32(&udma->udma_regs->m2s.m2s_rd.desc_pref_cfg_3); + reg &= ~UDMA_M2S_RD_DESC_PREF_CFG_3_MIN_BURST_BELOW_THR_MASK; + reg |= conf->min_burst_below_thr & + UDMA_M2S_RD_DESC_PREF_CFG_3_MIN_BURST_BELOW_THR_MASK; + + reg &= ~UDMA_M2S_RD_DESC_PREF_CFG_3_MIN_BURST_ABOVE_THR_MASK; + reg |=(conf->min_burst_above_thr << + UDMA_M2S_RD_DESC_PREF_CFG_3_MIN_BURST_ABOVE_THR_SHIFT) & + UDMA_M2S_RD_DESC_PREF_CFG_3_MIN_BURST_ABOVE_THR_MASK; + + reg &= ~UDMA_M2S_RD_DESC_PREF_CFG_3_PREF_THR_MASK; + reg |= (conf->pref_thr << + UDMA_M2S_RD_DESC_PREF_CFG_3_PREF_THR_SHIFT) & + UDMA_M2S_RD_DESC_PREF_CFG_3_PREF_THR_MASK; + + al_reg_write32(&udma->udma_regs->m2s.m2s_rd.desc_pref_cfg_3, reg); + + reg = al_reg_read32(&udma->udma_regs->m2s.m2s_rd.data_cfg); + reg &= ~UDMA_M2S_RD_DATA_CFG_DATA_FIFO_DEPTH_MASK; + reg |= conf->data_fifo_depth & + UDMA_M2S_RD_DATA_CFG_DATA_FIFO_DEPTH_MASK; + + reg &= ~UDMA_M2S_RD_DATA_CFG_MAX_PKT_LIMIT_MASK; + reg |= (conf->max_pkt_limit + << UDMA_M2S_RD_DATA_CFG_MAX_PKT_LIMIT_SHIFT) & + UDMA_M2S_RD_DATA_CFG_MAX_PKT_LIMIT_MASK; + al_reg_write32(&udma->udma_regs->m2s.m2s_rd.data_cfg, reg); + + return 0; +} + +/** Ger the M2S UDMA descriptor prefetch */ +int al_udma_m2s_pref_get(struct al_udma *udma, + struct al_udma_m2s_desc_pref_conf *conf) +{ + uint32_t reg; + + reg = al_reg_read32(&udma->udma_regs->m2s.m2s_rd.desc_pref_cfg_1); + conf->desc_fifo_depth = + AL_REG_FIELD_GET(reg, UDMA_M2S_RD_DESC_PREF_CFG_1_FIFO_DEPTH_MASK, + UDMA_M2S_RD_DESC_PREF_CFG_1_FIFO_DEPTH_SHIFT); + + reg = al_reg_read32(&udma->udma_regs->m2s.m2s_rd.desc_pref_cfg_2); + if (reg & UDMA_M2S_RD_DESC_PREF_CFG_2_MAX_DESC_PER_PKT_MASK) + conf->sch_mode = SRR; + else + conf->sch_mode = STRICT; + conf->max_desc_per_packet = + AL_REG_FIELD_GET(reg, + UDMA_M2S_RD_DESC_PREF_CFG_2_MAX_DESC_PER_PKT_MASK, + UDMA_M2S_RD_DESC_PREF_CFG_2_MAX_DESC_PER_PKT_SHIFT); + + reg = al_reg_read32(&udma->udma_regs->m2s.m2s_rd.desc_pref_cfg_3); + + conf->min_burst_below_thr = + AL_REG_FIELD_GET(reg, + UDMA_M2S_RD_DESC_PREF_CFG_3_MIN_BURST_BELOW_THR_MASK, + UDMA_M2S_RD_DESC_PREF_CFG_3_MIN_BURST_BELOW_THR_SHIFT); + + conf->min_burst_above_thr = + AL_REG_FIELD_GET(reg, + UDMA_M2S_RD_DESC_PREF_CFG_3_MIN_BURST_ABOVE_THR_MASK, + UDMA_M2S_RD_DESC_PREF_CFG_3_MIN_BURST_ABOVE_THR_SHIFT); + + conf->pref_thr = AL_REG_FIELD_GET(reg, + UDMA_M2S_RD_DESC_PREF_CFG_3_PREF_THR_MASK, + UDMA_M2S_RD_DESC_PREF_CFG_3_PREF_THR_SHIFT); + return 0; +} + +/* set max descriptors */ +int al_udma_m2s_max_descs_set(struct al_udma *udma, uint8_t max_descs) +{ + uint32_t pref_thr = max_descs; + uint32_t min_burst_above_thr = 4; + al_assert(max_descs <= AL_UDMA_M2S_MAX_ALLOWED_DESCS_PER_PACKET); + al_assert(max_descs > 0); + + /* increase min_burst_above_thr so larger burst can be used to fetch + * descriptors */ + if (pref_thr >= 8) + min_burst_above_thr = 8; + else { + /* don't set prefetch threshold too low so we can have the + * min_burst_above_thr >= 4 */ + pref_thr = 4; + } + + al_reg_write32_masked(&udma->udma_regs->m2s.m2s_rd.desc_pref_cfg_2, + UDMA_M2S_RD_DESC_PREF_CFG_2_MAX_DESC_PER_PKT_MASK, + max_descs << UDMA_M2S_RD_DESC_PREF_CFG_2_MAX_DESC_PER_PKT_SHIFT); + + al_reg_write32_masked(&udma->udma_regs->m2s.m2s_rd.desc_pref_cfg_3, + UDMA_M2S_RD_DESC_PREF_CFG_3_PREF_THR_MASK | + UDMA_M2S_RD_DESC_PREF_CFG_3_MIN_BURST_ABOVE_THR_MASK, + (pref_thr << UDMA_M2S_RD_DESC_PREF_CFG_3_PREF_THR_SHIFT) | + (min_burst_above_thr << UDMA_M2S_RD_DESC_PREF_CFG_3_MIN_BURST_ABOVE_THR_SHIFT)); + + return 0; +} + +/* set s2m max descriptors */ +int al_udma_s2m_max_descs_set(struct al_udma *udma, uint8_t max_descs) +{ + uint32_t pref_thr = max_descs; + uint32_t min_burst_above_thr = 4; + al_assert(max_descs <= AL_UDMA_S2M_MAX_ALLOWED_DESCS_PER_PACKET); + al_assert(max_descs > 0); + + /* increase min_burst_above_thr so larger burst can be used to fetch + * descriptors */ + if (pref_thr >= 8) + min_burst_above_thr = 8; + else + /* don't set prefetch threshold too low so we can have the + * min_burst_above_thr >= 4 */ + pref_thr = 4; + + al_reg_write32_masked(&udma->udma_regs->s2m.s2m_rd.desc_pref_cfg_3, + UDMA_S2M_RD_DESC_PREF_CFG_3_PREF_THR_MASK | + UDMA_S2M_RD_DESC_PREF_CFG_3_MIN_BURST_ABOVE_THR_MASK, + (pref_thr << UDMA_S2M_RD_DESC_PREF_CFG_3_PREF_THR_SHIFT) | + (min_burst_above_thr << UDMA_S2M_RD_DESC_PREF_CFG_3_MIN_BURST_ABOVE_THR_SHIFT)); + + return 0; +} + +int al_udma_s2m_full_line_write_set(struct al_udma *udma, al_bool enable) +{ + uint32_t val = 0; + + if (enable == AL_TRUE) { + val = UDMA_S2M_WR_DATA_CFG_2_FULL_LINE_MODE; + al_info("udma [%s]: full line write enabled\n", udma->name); + } + + al_reg_write32_masked(&udma->udma_regs->s2m.s2m_wr.data_cfg_2, + UDMA_S2M_WR_DATA_CFG_2_FULL_LINE_MODE, + val); + return 0; +} + +/** Configure S2M UDMA descriptor prefetch */ +int al_udma_s2m_pref_set(struct al_udma *udma, + struct al_udma_s2m_desc_pref_conf *conf) +{ + uint32_t reg; + + reg = al_reg_read32(&udma->udma_regs->s2m.s2m_rd.desc_pref_cfg_1); + reg &= ~UDMA_S2M_RD_DESC_PREF_CFG_1_FIFO_DEPTH_MASK; + reg |= conf->desc_fifo_depth; + al_reg_write32(&udma->udma_regs->s2m.s2m_rd.desc_pref_cfg_1, reg); + + reg = al_reg_read32(&udma->udma_regs->s2m.s2m_rd.desc_pref_cfg_2); + + if (conf->sch_mode == SRR) + reg |= UDMA_S2M_RD_DESC_PREF_CFG_2_PREF_FORCE_RR; + else if (conf->sch_mode == STRICT) + reg &= ~UDMA_S2M_RD_DESC_PREF_CFG_2_PREF_FORCE_RR; + else { + al_err("udma [%s]: requested descriptor preferch arbiter " + "mode (%d) is invalid\n", udma->name, conf->sch_mode); + return -EINVAL; + } + if (conf->q_promotion == AL_TRUE) + reg |= UDMA_S2M_RD_DESC_PREF_CFG_2_Q_PROMOTION; + else + reg &= ~UDMA_S2M_RD_DESC_PREF_CFG_2_Q_PROMOTION; + + if (conf->force_promotion == AL_TRUE) + reg |= UDMA_S2M_RD_DESC_PREF_CFG_2_FORCE_PROMOTION; + else + reg &= ~UDMA_S2M_RD_DESC_PREF_CFG_2_FORCE_PROMOTION; + + if (conf->en_pref_prediction == AL_TRUE) + reg |= UDMA_S2M_RD_DESC_PREF_CFG_2_EN_PREF_PREDICTION; + else + reg &= ~UDMA_S2M_RD_DESC_PREF_CFG_2_EN_PREF_PREDICTION; + + reg &= ~UDMA_S2M_RD_DESC_PREF_CFG_2_PROMOTION_TH_MASK; + reg |= (conf->promotion_th + << UDMA_S2M_RD_DESC_PREF_CFG_2_PROMOTION_TH_SHIFT) & + UDMA_S2M_RD_DESC_PREF_CFG_2_PROMOTION_TH_MASK; + + al_reg_write32(&udma->udma_regs->s2m.s2m_rd.desc_pref_cfg_2, reg); + + reg = al_reg_read32(&udma->udma_regs->s2m.s2m_rd.desc_pref_cfg_3); + reg &= ~UDMA_S2M_RD_DESC_PREF_CFG_3_PREF_THR_MASK; + reg |= (conf->pref_thr << UDMA_S2M_RD_DESC_PREF_CFG_3_PREF_THR_SHIFT) & + UDMA_S2M_RD_DESC_PREF_CFG_3_PREF_THR_MASK; + + reg &= ~UDMA_S2M_RD_DESC_PREF_CFG_3_MIN_BURST_BELOW_THR_MASK; + reg |= conf->min_burst_below_thr & + UDMA_S2M_RD_DESC_PREF_CFG_3_MIN_BURST_BELOW_THR_MASK; + + reg &= ~UDMA_S2M_RD_DESC_PREF_CFG_3_MIN_BURST_ABOVE_THR_MASK; + reg |=(conf->min_burst_above_thr << + UDMA_S2M_RD_DESC_PREF_CFG_3_MIN_BURST_ABOVE_THR_SHIFT) & + UDMA_S2M_RD_DESC_PREF_CFG_3_MIN_BURST_BELOW_THR_MASK; + + al_reg_write32(&udma->udma_regs->s2m.s2m_rd.desc_pref_cfg_3, reg); + + reg = al_reg_read32(&udma->udma_regs->s2m.s2m_rd.desc_pref_cfg_4); + reg &= ~UDMA_S2M_RD_DESC_PREF_CFG_4_A_FULL_THR_MASK; + reg |= conf->a_full_thr & UDMA_S2M_RD_DESC_PREF_CFG_4_A_FULL_THR_MASK; + al_reg_write32(&udma->udma_regs->s2m.s2m_rd.desc_pref_cfg_4, reg); + + + return 0; +} + +/* Configure S2M UDMA data write */ +int al_udma_s2m_data_write_set(struct al_udma *udma, + struct al_udma_s2m_data_write_conf *conf) +{ + uint32_t reg; + + reg = al_reg_read32(&udma->udma_regs->s2m.s2m_wr.data_cfg_1); + reg &= ~UDMA_S2M_WR_DATA_CFG_1_DATA_FIFO_DEPTH_MASK; + reg |= conf->data_fifo_depth & + UDMA_S2M_WR_DATA_CFG_1_DATA_FIFO_DEPTH_MASK; + reg &= ~UDMA_S2M_WR_DATA_CFG_1_MAX_PKT_LIMIT_MASK; + reg |= (conf->max_pkt_limit << + UDMA_S2M_WR_DATA_CFG_1_MAX_PKT_LIMIT_SHIFT) & + UDMA_S2M_WR_DATA_CFG_1_MAX_PKT_LIMIT_MASK; + reg &= ~UDMA_S2M_WR_DATA_CFG_1_FIFO_MARGIN_MASK; + reg |= (conf->fifo_margin << + UDMA_S2M_WR_DATA_CFG_1_FIFO_MARGIN_SHIFT) & + UDMA_S2M_WR_DATA_CFG_1_FIFO_MARGIN_MASK; + al_reg_write32(&udma->udma_regs->s2m.s2m_wr.data_cfg_1, reg); + + reg = al_reg_read32(&udma->udma_regs->s2m.s2m_wr.data_cfg_2); + reg &= ~UDMA_S2M_WR_DATA_CFG_2_DESC_WAIT_TIMER_MASK; + reg |= conf->desc_wait_timer & + UDMA_S2M_WR_DATA_CFG_2_DESC_WAIT_TIMER_MASK; + reg &= ~(UDMA_S2M_WR_DATA_CFG_2_DROP_IF_NO_DESC | + UDMA_S2M_WR_DATA_CFG_2_HINT_IF_NO_DESC | + UDMA_S2M_WR_DATA_CFG_2_WAIT_FOR_PREF | + UDMA_S2M_WR_DATA_CFG_2_FULL_LINE_MODE | + UDMA_S2M_WR_DATA_CFG_2_DIRECT_HDR_USE_BUF1); + reg |= conf->flags & + (UDMA_S2M_WR_DATA_CFG_2_DROP_IF_NO_DESC | + UDMA_S2M_WR_DATA_CFG_2_HINT_IF_NO_DESC | + UDMA_S2M_WR_DATA_CFG_2_WAIT_FOR_PREF | + UDMA_S2M_WR_DATA_CFG_2_FULL_LINE_MODE | + UDMA_S2M_WR_DATA_CFG_2_DIRECT_HDR_USE_BUF1); + al_reg_write32(&udma->udma_regs->s2m.s2m_wr.data_cfg_2, reg); + + return 0; +} + +/* Configure S2M UDMA completion */ +int al_udma_s2m_completion_set(struct al_udma *udma, + struct al_udma_s2m_completion_conf *conf) +{ + uint32_t reg = al_reg_read32(&udma->udma_regs->s2m.s2m_comp.cfg_1c); + reg &= ~UDMA_S2M_COMP_CFG_1C_DESC_SIZE_MASK; + reg |= conf->desc_size & UDMA_S2M_COMP_CFG_1C_DESC_SIZE_MASK; + if (conf->cnt_words == AL_TRUE) + reg |= UDMA_S2M_COMP_CFG_1C_CNT_WORDS; + else + reg &= ~UDMA_S2M_COMP_CFG_1C_CNT_WORDS; + if (conf->q_promotion == AL_TRUE) + reg |= UDMA_S2M_COMP_CFG_1C_Q_PROMOTION; + else + reg &= ~UDMA_S2M_COMP_CFG_1C_Q_PROMOTION; + if (conf->force_rr == AL_TRUE) + reg |= UDMA_S2M_COMP_CFG_1C_FORCE_RR; + else + reg &= ~UDMA_S2M_COMP_CFG_1C_FORCE_RR; + reg &= ~UDMA_S2M_COMP_CFG_1C_Q_FREE_MIN_MASK; + reg |= (conf->q_free_min << UDMA_S2M_COMP_CFG_1C_Q_FREE_MIN_SHIFT) & + UDMA_S2M_COMP_CFG_1C_Q_FREE_MIN_MASK; + al_reg_write32(&udma->udma_regs->s2m.s2m_comp.cfg_1c, reg); + + reg = al_reg_read32(&udma->udma_regs->s2m.s2m_comp.cfg_2c); + reg &= ~UDMA_S2M_COMP_CFG_2C_COMP_FIFO_DEPTH_MASK; + reg |= conf->comp_fifo_depth + & UDMA_S2M_COMP_CFG_2C_COMP_FIFO_DEPTH_MASK; + reg &= ~UDMA_S2M_COMP_CFG_2C_UNACK_FIFO_DEPTH_MASK; + reg |= (conf->unack_fifo_depth + << UDMA_S2M_COMP_CFG_2C_UNACK_FIFO_DEPTH_SHIFT) & + UDMA_S2M_COMP_CFG_2C_UNACK_FIFO_DEPTH_MASK; + al_reg_write32(&udma->udma_regs->s2m.s2m_comp.cfg_2c, reg); + + al_reg_write32(&udma->udma_regs->s2m.s2m_comp.cfg_application_ack, + conf->timeout); + return 0; +} + +/** Configure the M2S UDMA scheduling mode */ +int al_udma_m2s_sc_set(struct al_udma *udma, + struct al_udma_m2s_dwrr_conf *sched) +{ + uint32_t reg = al_reg_read32(&udma->udma_regs->m2s.m2s_dwrr.cfg_sched); + + if (sched->enable_dwrr == AL_TRUE) + reg |= UDMA_M2S_DWRR_CFG_SCHED_EN_DWRR; + else + reg &= ~UDMA_M2S_DWRR_CFG_SCHED_EN_DWRR; + + if (sched->pkt_mode == AL_TRUE) + reg |= UDMA_M2S_DWRR_CFG_SCHED_PKT_MODE_EN; + else + reg &= ~UDMA_M2S_DWRR_CFG_SCHED_PKT_MODE_EN; + + reg &= ~UDMA_M2S_DWRR_CFG_SCHED_WEIGHT_INC_MASK; + reg |= sched->weight << UDMA_M2S_DWRR_CFG_SCHED_WEIGHT_INC_SHIFT; + reg &= ~UDMA_M2S_DWRR_CFG_SCHED_INC_FACTOR_MASK; + reg |= sched->inc_factor << UDMA_M2S_DWRR_CFG_SCHED_INC_FACTOR_SHIFT; + al_reg_write32(&udma->udma_regs->m2s.m2s_dwrr.cfg_sched, reg); + + reg = al_reg_read32(&udma->udma_regs->m2s.m2s_dwrr.ctrl_deficit_cnt); + reg &= ~UDMA_M2S_DWRR_CTRL_DEFICIT_CNT_INIT_MASK; + reg |= sched->deficit_init_val; + al_reg_write32(&udma->udma_regs->m2s.m2s_dwrr.ctrl_deficit_cnt, reg); + + return 0; +} + +/** Configure the M2S UDMA rate limitation */ +int al_udma_m2s_rlimit_set(struct al_udma *udma, + struct al_udma_m2s_rlimit_mode *mode) +{ + uint32_t reg = al_reg_read32( + &udma->udma_regs->m2s.m2s_rate_limiter.gen_cfg); + + if (mode->pkt_mode_en == AL_TRUE) + reg |= UDMA_M2S_RATE_LIMITER_GEN_CFG_PKT_MODE_EN; + else + reg &= ~UDMA_M2S_RATE_LIMITER_GEN_CFG_PKT_MODE_EN; + reg &= ~UDMA_M2S_RATE_LIMITER_GEN_CFG_SHORT_CYCLE_SIZE_MASK; + reg |= mode->short_cycle_sz & + UDMA_M2S_RATE_LIMITER_GEN_CFG_SHORT_CYCLE_SIZE_MASK; + al_reg_write32(&udma->udma_regs->m2s.m2s_rate_limiter.gen_cfg, reg); + + reg = al_reg_read32(&udma->udma_regs->m2s.m2s_rate_limiter.ctrl_token); + reg &= ~UDMA_M2S_RATE_LIMITER_CTRL_TOKEN_RST_MASK; + reg |= mode->token_init_val & + UDMA_M2S_RATE_LIMITER_CTRL_TOKEN_RST_MASK; + al_reg_write32(&udma->udma_regs->m2s.m2s_rate_limiter.ctrl_token, reg); + + return 0; +} + +int al_udma_m2s_rlimit_reset(struct al_udma *udma) +{ + uint32_t reg = al_reg_read32( + &udma->udma_regs->m2s.m2s_rate_limiter.ctrl_cycle_cnt); + reg |= UDMA_M2S_RATE_LIMITER_CTRL_CYCLE_CNT_RST; + al_reg_write32(&udma->udma_regs->m2s.m2s_rate_limiter.ctrl_cycle_cnt, + reg); + return 0; +} + +/** Configure the Stream/Q rate limitation */ +static int al_udma_common_rlimit_set(struct udma_rlimit_common *regs, + struct al_udma_m2s_rlimit_cfg *conf) +{ + uint32_t reg = al_reg_read32(®s->cfg_1s); + /* mask max burst size, and enable/pause control bits */ + reg &= ~UDMA_M2S_STREAM_RATE_LIMITER_CFG_1S_MAX_BURST_SIZE_MASK; + reg &= ~UDMA_M2S_STREAM_RATE_LIMITER_CFG_1S_EN; + reg &= ~UDMA_M2S_STREAM_RATE_LIMITER_CFG_1S_PAUSE; + reg |= conf->max_burst_sz & + UDMA_M2S_STREAM_RATE_LIMITER_CFG_1S_MAX_BURST_SIZE_MASK; + al_reg_write32(®s->cfg_1s, reg); + + reg = al_reg_read32(®s->cfg_cycle); + reg &= ~UDMA_M2S_STREAM_RATE_LIMITER_CFG_CYCLE_LONG_CYCLE_SIZE_MASK; + reg |= conf->long_cycle_sz & + UDMA_M2S_STREAM_RATE_LIMITER_CFG_CYCLE_LONG_CYCLE_SIZE_MASK; + al_reg_write32(®s->cfg_cycle, reg); + + reg = al_reg_read32(®s->cfg_token_size_1); + reg &= ~UDMA_M2S_STREAM_RATE_LIMITER_CFG_TOKEN_SIZE_1_LONG_CYCLE_MASK; + reg |= conf->long_cycle & + UDMA_M2S_STREAM_RATE_LIMITER_CFG_TOKEN_SIZE_1_LONG_CYCLE_MASK; + al_reg_write32(®s->cfg_token_size_1, reg); + + reg = al_reg_read32(®s->cfg_token_size_2); + reg &= ~UDMA_M2S_STREAM_RATE_LIMITER_CFG_TOKEN_SIZE_2_SHORT_CYCLE_MASK; + reg |= conf->short_cycle & + UDMA_M2S_STREAM_RATE_LIMITER_CFG_TOKEN_SIZE_2_SHORT_CYCLE_MASK; + al_reg_write32(®s->cfg_token_size_2, reg); + + reg = al_reg_read32(®s->mask); + reg &= ~0xf; /* only bits 0-3 defined */ + reg |= conf->mask & 0xf; + al_reg_write32(®s->mask, reg); + + return 0; +} + +static int al_udma_common_rlimit_act(struct udma_rlimit_common *regs, + enum al_udma_m2s_rlimit_action act) +{ + uint32_t reg; + + switch (act) { + case AL_UDMA_STRM_RLIMIT_ENABLE: + reg = al_reg_read32(®s->cfg_1s); + reg |= UDMA_M2S_STREAM_RATE_LIMITER_CFG_1S_EN; + al_reg_write32(®s->cfg_1s, reg); + break; + case AL_UDMA_STRM_RLIMIT_PAUSE: + reg = al_reg_read32(®s->cfg_1s); + reg |= UDMA_M2S_STREAM_RATE_LIMITER_CFG_1S_PAUSE; + al_reg_write32(®s->cfg_1s, reg); + break; + case AL_UDMA_STRM_RLIMIT_RESET: + reg = al_reg_read32(®s->sw_ctrl); + reg |= UDMA_M2S_STREAM_RATE_LIMITER_SW_CTRL_RST_TOKEN_CNT; + al_reg_write32(®s->sw_ctrl, reg); + break; + default: + return -EINVAL; + } + return 0; +} + +/** Configure the M2S Stream rate limitation */ +int al_udma_m2s_strm_rlimit_set(struct al_udma *udma, + struct al_udma_m2s_rlimit_cfg *conf) +{ + struct udma_rlimit_common *rlimit_regs = + &udma->udma_regs->m2s.m2s_stream_rate_limiter.rlimit; + + return al_udma_common_rlimit_set(rlimit_regs, conf); +} + +int al_udma_m2s_strm_rlimit_act(struct al_udma *udma, + enum al_udma_m2s_rlimit_action act) +{ + struct udma_rlimit_common *rlimit_regs = + &udma->udma_regs->m2s.m2s_stream_rate_limiter.rlimit; + + if (al_udma_common_rlimit_act(rlimit_regs, act) == -EINVAL) { + al_err("udma [%s]: udma stream rate limit invalid action " + "(%d)\n", udma->name, act); + return -EINVAL; + } + return 0; +} + +/** Configure the M2S UDMA Q rate limitation */ +int al_udma_m2s_q_rlimit_set(struct al_udma_q *udma_q, + struct al_udma_m2s_rlimit_cfg *conf) +{ + struct udma_rlimit_common *rlimit_regs = &udma_q->q_regs->m2s_q.rlimit; + + return al_udma_common_rlimit_set(rlimit_regs, conf); +} + +int al_udma_m2s_q_rlimit_act(struct al_udma_q *udma_q, + enum al_udma_m2s_rlimit_action act) +{ + struct udma_rlimit_common *rlimit_regs = &udma_q->q_regs->m2s_q.rlimit; + + if (al_udma_common_rlimit_act(rlimit_regs, act) == -EINVAL) { + al_err("udma [%s %d]: udma stream rate limit invalid action " + "(%d)\n", + udma_q->udma->name, udma_q->qid, act); + return -EINVAL; + } + return 0; +} + +/** Configure the M2S UDMA Q scheduling mode */ +int al_udma_m2s_q_sc_set(struct al_udma_q *udma_q, + struct al_udma_m2s_q_dwrr_conf *conf) +{ + uint32_t reg = al_reg_read32(&udma_q->q_regs->m2s_q.dwrr_cfg_1); + + reg &= ~UDMA_M2S_Q_DWRR_CFG_1_MAX_DEFICIT_CNT_SIZE_MASK; + reg |= conf->max_deficit_cnt_sz & + UDMA_M2S_Q_DWRR_CFG_1_MAX_DEFICIT_CNT_SIZE_MASK; + if (conf->strict == AL_TRUE) + reg |= UDMA_M2S_Q_DWRR_CFG_1_STRICT; + else + reg &= ~UDMA_M2S_Q_DWRR_CFG_1_STRICT; + al_reg_write32(&udma_q->q_regs->m2s_q.dwrr_cfg_1, reg); + + reg = al_reg_read32(&udma_q->q_regs->m2s_q.dwrr_cfg_2); + reg &= ~UDMA_M2S_Q_DWRR_CFG_2_Q_QOS_MASK; + reg |= (conf->axi_qos << UDMA_M2S_Q_DWRR_CFG_2_Q_QOS_SHIFT) & + UDMA_M2S_Q_DWRR_CFG_2_Q_QOS_MASK; + reg &= ~UDMA_M2S_Q_DWRR_CFG_2_Q_QOS_MASK; + reg |= conf->q_qos & UDMA_M2S_Q_DWRR_CFG_2_Q_QOS_MASK; + al_reg_write32(&udma_q->q_regs->m2s_q.dwrr_cfg_2, reg); + + reg = al_reg_read32(&udma_q->q_regs->m2s_q.dwrr_cfg_3); + reg &= ~UDMA_M2S_Q_DWRR_CFG_3_WEIGHT_MASK; + reg |= conf->weight & UDMA_M2S_Q_DWRR_CFG_3_WEIGHT_MASK; + al_reg_write32(&udma_q->q_regs->m2s_q.dwrr_cfg_3, reg); + + return 0; +} + +int al_udma_m2s_q_sc_pause(struct al_udma_q *udma_q, al_bool set) +{ + uint32_t reg = al_reg_read32(&udma_q->q_regs->m2s_q.dwrr_cfg_1); + + if (set == AL_TRUE) + reg |= UDMA_M2S_Q_DWRR_CFG_1_PAUSE; + else + reg &= ~UDMA_M2S_Q_DWRR_CFG_1_PAUSE; + al_reg_write32(&udma_q->q_regs->m2s_q.dwrr_cfg_1, reg); + + return 0; +} + +int al_udma_m2s_q_sc_reset(struct al_udma_q *udma_q) +{ + uint32_t reg = al_reg_read32(&udma_q->q_regs->m2s_q.dwrr_sw_ctrl); + + reg |= UDMA_M2S_Q_DWRR_SW_CTRL_RST_CNT; + al_reg_write32(&udma_q->q_regs->m2s_q.dwrr_sw_ctrl, reg); + + return 0; +} + +/** M2S UDMA completion and application timeouts */ +int al_udma_m2s_comp_timeouts_set(struct al_udma *udma, + struct al_udma_m2s_comp_timeouts *conf) +{ + uint32_t reg = al_reg_read32(&udma->udma_regs->m2s.m2s_comp.cfg_1c); + + if (conf->sch_mode == SRR) + reg |= UDMA_M2S_COMP_CFG_1C_FORCE_RR; + else if (conf->sch_mode == STRICT) + reg &= ~UDMA_M2S_COMP_CFG_1C_FORCE_RR; + else { + al_err("udma [%s]: requested completion descriptor preferch " + "arbiter mode (%d) is invalid\n", + udma->name, conf->sch_mode); + return -EINVAL; + } + if (conf->enable_q_promotion == AL_TRUE) + reg |= UDMA_M2S_COMP_CFG_1C_Q_PROMOTION; + else + reg &= ~UDMA_M2S_COMP_CFG_1C_Q_PROMOTION; + reg &= ~UDMA_M2S_COMP_CFG_1C_COMP_FIFO_DEPTH_MASK; + reg |= + conf->comp_fifo_depth << UDMA_M2S_COMP_CFG_1C_COMP_FIFO_DEPTH_SHIFT; + + reg &= ~UDMA_M2S_COMP_CFG_1C_UNACK_FIFO_DEPTH_MASK; + reg |= conf->unack_fifo_depth + << UDMA_M2S_COMP_CFG_1C_UNACK_FIFO_DEPTH_SHIFT; + al_reg_write32(&udma->udma_regs->m2s.m2s_comp.cfg_1c, reg); + + al_reg_write32(&udma->udma_regs->m2s.m2s_comp.cfg_coal + , conf->coal_timeout); + + reg = al_reg_read32(&udma->udma_regs->m2s.m2s_comp.cfg_application_ack); + reg &= ~UDMA_M2S_COMP_CFG_APPLICATION_ACK_TOUT_MASK; + reg |= conf->app_timeout << UDMA_M2S_COMP_CFG_APPLICATION_ACK_TOUT_SHIFT; + al_reg_write32(&udma->udma_regs->m2s.m2s_comp.cfg_application_ack, reg); + return 0; +} + +int al_udma_m2s_comp_timeouts_get(struct al_udma *udma, + struct al_udma_m2s_comp_timeouts *conf) +{ + uint32_t reg = al_reg_read32(&udma->udma_regs->m2s.m2s_comp.cfg_1c); + + if (reg & UDMA_M2S_COMP_CFG_1C_FORCE_RR) + conf->sch_mode = SRR; + else + conf->sch_mode = STRICT; + + if (reg & UDMA_M2S_COMP_CFG_1C_Q_PROMOTION) + conf->enable_q_promotion = AL_TRUE; + else + conf->enable_q_promotion = AL_FALSE; + + conf->comp_fifo_depth = + AL_REG_FIELD_GET(reg, + UDMA_M2S_COMP_CFG_1C_COMP_FIFO_DEPTH_MASK, + UDMA_M2S_COMP_CFG_1C_COMP_FIFO_DEPTH_SHIFT); + conf->unack_fifo_depth = + AL_REG_FIELD_GET(reg, + UDMA_M2S_COMP_CFG_1C_UNACK_FIFO_DEPTH_MASK, + UDMA_M2S_COMP_CFG_1C_UNACK_FIFO_DEPTH_SHIFT); + + conf->coal_timeout = al_reg_read32( + &udma->udma_regs->m2s.m2s_comp.cfg_coal); + + reg = al_reg_read32( + &udma->udma_regs->m2s.m2s_comp.cfg_application_ack); + + conf->app_timeout = + AL_REG_FIELD_GET(reg, + UDMA_M2S_COMP_CFG_APPLICATION_ACK_TOUT_MASK, + UDMA_M2S_COMP_CFG_APPLICATION_ACK_TOUT_SHIFT); + + return 0; +} + +/** + * S2M UDMA configure no descriptors behaviour + */ +int al_udma_s2m_no_desc_cfg_set(struct al_udma *udma, al_bool drop_packet, al_bool gen_interrupt, uint32_t wait_for_desc_timeout) +{ + uint32_t reg; + + reg = al_reg_read32(&udma->udma_regs->s2m.s2m_wr.data_cfg_2); + + if ((drop_packet == AL_TRUE) && (wait_for_desc_timeout == 0)) { + al_err("udam [%s]: setting timeout to 0 will cause the udma to wait forever instead of dropping the packet", udma->name); + return -EINVAL; + } + + if (drop_packet == AL_TRUE) + reg |= UDMA_S2M_WR_DATA_CFG_2_DROP_IF_NO_DESC; + else + reg &= ~UDMA_S2M_WR_DATA_CFG_2_DROP_IF_NO_DESC; + + if (gen_interrupt == AL_TRUE) + reg |= UDMA_S2M_WR_DATA_CFG_2_HINT_IF_NO_DESC; + else + reg &= ~UDMA_S2M_WR_DATA_CFG_2_HINT_IF_NO_DESC; + + AL_REG_FIELD_SET(reg, UDMA_S2M_WR_DATA_CFG_2_DESC_WAIT_TIMER_MASK, UDMA_S2M_WR_DATA_CFG_2_DESC_WAIT_TIMER_SHIFT, wait_for_desc_timeout); + + al_reg_write32(&udma->udma_regs->s2m.s2m_wr.data_cfg_2, reg); + + return 0; +} + +/* S2M UDMA configure a queue's completion update */ +int al_udma_s2m_q_compl_updade_config(struct al_udma_q *udma_q, al_bool enable) +{ + uint32_t reg = al_reg_read32(&udma_q->q_regs->s2m_q.comp_cfg); + + if (enable == AL_TRUE) + reg |= UDMA_S2M_Q_COMP_CFG_EN_COMP_RING_UPDATE; + else + reg &= ~UDMA_S2M_Q_COMP_CFG_EN_COMP_RING_UPDATE; + + al_reg_write32(&udma_q->q_regs->s2m_q.comp_cfg, reg); + + return 0; +} + +/* S2M UDMA configure a queue's completion descriptors coalescing */ +int al_udma_s2m_q_compl_coal_config(struct al_udma_q *udma_q, al_bool enable, uint32_t + coal_timeout) +{ + uint32_t reg = al_reg_read32(&udma_q->q_regs->s2m_q.comp_cfg); + + if (enable == AL_TRUE) + reg &= ~UDMA_S2M_Q_COMP_CFG_DIS_COMP_COAL; + else + reg |= UDMA_S2M_Q_COMP_CFG_DIS_COMP_COAL; + + al_reg_write32(&udma_q->q_regs->s2m_q.comp_cfg, reg); + + al_reg_write32(&udma_q->q_regs->s2m_q.comp_cfg_2, coal_timeout); + return 0; +} + +/* S2M UDMA configure completion descriptors write burst parameters */ +int al_udma_s2m_compl_desc_burst_config(struct al_udma *udma, uint16_t + burst_size) +{ + if ((burst_size != 64) && (burst_size != 128) && (burst_size != 256)) { + al_err("%s: invalid burst_size value (%d)\n", __func__, + burst_size); + return -EINVAL; + } + + /* convert burst size from bytes to beats (16 byte) */ + burst_size = burst_size / 16; + al_reg_write32_masked(&udma->udma_regs->s2m.axi_s2m.desc_wr_cfg_1, + UDMA_AXI_S2M_DESC_WR_CFG_1_MIN_AXI_BEATS_MASK | + UDMA_AXI_S2M_DESC_WR_CFG_1_MAX_AXI_BEATS_MASK, + burst_size << UDMA_AXI_S2M_DESC_WR_CFG_1_MIN_AXI_BEATS_SHIFT | + burst_size << UDMA_AXI_S2M_DESC_WR_CFG_1_MAX_AXI_BEATS_SHIFT); + return 0; +} + +/* S2M UDMA configure a queue's completion descriptors header split */ +int al_udma_s2m_q_compl_hdr_split_config(struct al_udma_q *udma_q, al_bool enable, + al_bool force_hdr_split, uint32_t hdr_len) +{ + uint32_t reg = al_reg_read32(&udma_q->q_regs->s2m_q.pkt_cfg); + + reg &= ~UDMA_S2M_Q_PKT_CFG_HDR_SPLIT_SIZE_MASK; + reg &= ~UDMA_S2M_Q_PKT_CFG_EN_HDR_SPLIT; + reg &= ~UDMA_S2M_Q_PKT_CFG_FORCE_HDR_SPLIT; + + if (enable == AL_TRUE) { + reg |= hdr_len & UDMA_S2M_Q_PKT_CFG_HDR_SPLIT_SIZE_MASK; + reg |= UDMA_S2M_Q_PKT_CFG_EN_HDR_SPLIT; + + if (force_hdr_split == AL_TRUE) + reg |= UDMA_S2M_Q_PKT_CFG_FORCE_HDR_SPLIT; + } + + al_reg_write32(&udma_q->q_regs->s2m_q.pkt_cfg, reg); + + return 0; +} + +/* S2M UDMA per queue completion configuration */ +int al_udma_s2m_q_comp_set(struct al_udma_q *udma_q, + struct al_udma_s2m_q_comp_conf *conf) +{ + uint32_t reg = al_reg_read32(&udma_q->q_regs->s2m_q.comp_cfg); + if (conf->en_comp_ring_update == AL_TRUE) + reg |= UDMA_S2M_Q_COMP_CFG_EN_COMP_RING_UPDATE; + else + reg &= ~UDMA_S2M_Q_COMP_CFG_EN_COMP_RING_UPDATE; + + if (conf->dis_comp_coal == AL_TRUE) + reg |= UDMA_S2M_Q_COMP_CFG_DIS_COMP_COAL; + else + reg &= ~UDMA_S2M_Q_COMP_CFG_DIS_COMP_COAL; + + al_reg_write32(&udma_q->q_regs->s2m_q.comp_cfg, reg); + + al_reg_write32(&udma_q->q_regs->s2m_q.comp_cfg_2, conf->comp_timer); + + reg = al_reg_read32(&udma_q->q_regs->s2m_q.pkt_cfg); + + reg &= ~UDMA_S2M_Q_PKT_CFG_HDR_SPLIT_SIZE_MASK; + reg |= conf->hdr_split_size & UDMA_S2M_Q_PKT_CFG_HDR_SPLIT_SIZE_MASK; + if (conf->force_hdr_split == AL_TRUE) + reg |= UDMA_S2M_Q_PKT_CFG_FORCE_HDR_SPLIT; + else + reg &= ~UDMA_S2M_Q_PKT_CFG_FORCE_HDR_SPLIT; + if (conf->en_hdr_split == AL_TRUE) + reg |= UDMA_S2M_Q_PKT_CFG_EN_HDR_SPLIT; + else + reg &= ~UDMA_S2M_Q_PKT_CFG_EN_HDR_SPLIT; + + al_reg_write32(&udma_q->q_regs->s2m_q.pkt_cfg, reg); + + reg = al_reg_read32(&udma_q->q_regs->s2m_q.qos_cfg); + reg &= ~UDMA_S2M_QOS_CFG_Q_QOS_MASK; + reg |= conf->q_qos & UDMA_S2M_QOS_CFG_Q_QOS_MASK; + al_reg_write32(&udma_q->q_regs->s2m_q.qos_cfg, reg); + + return 0; +} + +/* UDMA VMID control configuration */ +void al_udma_gen_vmid_conf_set( + struct unit_regs *unit_regs, + struct al_udma_gen_vmid_conf *conf) +{ + unsigned int rev_id; + + al_reg_write32_masked( + &unit_regs->gen.vmid.cfg_vmid_0, + UDMA_GEN_VMID_CFG_VMID_0_TX_Q_VMID_DESC_EN_MASK | + UDMA_GEN_VMID_CFG_VMID_0_TX_Q_VMID_QUEUE_EN_MASK | + UDMA_GEN_VMID_CFG_VMID_0_RX_Q_VMID_DESC_EN_MASK | + UDMA_GEN_VMID_CFG_VMID_0_RX_Q_VMID_QUEUE_EN_MASK, + (((conf->tx_q_conf[0].desc_en << 0) | + (conf->tx_q_conf[1].desc_en << 1) | + (conf->tx_q_conf[2].desc_en << 2) | + (conf->tx_q_conf[3].desc_en << 3)) << + UDMA_GEN_VMID_CFG_VMID_0_TX_Q_VMID_DESC_EN_SHIFT) | + (((conf->tx_q_conf[0].queue_en << 0) | + (conf->tx_q_conf[1].queue_en << 1) | + (conf->tx_q_conf[2].queue_en << 2) | + (conf->tx_q_conf[3].queue_en << 3)) << + UDMA_GEN_VMID_CFG_VMID_0_TX_Q_VMID_QUEUE_EN_SHIFT) | + (((conf->rx_q_conf[0].desc_en << 0) | + (conf->rx_q_conf[1].desc_en << 1) | + (conf->rx_q_conf[2].desc_en << 2) | + (conf->rx_q_conf[3].desc_en << 3)) << + UDMA_GEN_VMID_CFG_VMID_0_RX_Q_VMID_DESC_EN_SHIFT) | + (((conf->rx_q_conf[0].queue_en << 0) | + (conf->rx_q_conf[1].queue_en << 1) | + (conf->rx_q_conf[2].queue_en << 2) | + (conf->rx_q_conf[3].queue_en << 3)) << + UDMA_GEN_VMID_CFG_VMID_0_RX_Q_VMID_QUEUE_EN_SHIFT)); + + /* VMID per queue */ + al_reg_write32( + &unit_regs->gen.vmid.cfg_vmid_1, + (conf->tx_q_conf[0].vmid << + UDMA_GEN_VMID_CFG_VMID_1_TX_Q_0_VMID_SHIFT) | + (conf->tx_q_conf[1].vmid << + UDMA_GEN_VMID_CFG_VMID_1_TX_Q_1_VMID_SHIFT)); + + al_reg_write32( + &unit_regs->gen.vmid.cfg_vmid_2, + (conf->tx_q_conf[2].vmid << + UDMA_GEN_VMID_CFG_VMID_2_TX_Q_2_VMID_SHIFT) | + (conf->tx_q_conf[3].vmid << + UDMA_GEN_VMID_CFG_VMID_2_TX_Q_3_VMID_SHIFT)); + + al_reg_write32( + &unit_regs->gen.vmid.cfg_vmid_3, + (conf->rx_q_conf[0].vmid << + UDMA_GEN_VMID_CFG_VMID_3_RX_Q_0_VMID_SHIFT) | + (conf->rx_q_conf[1].vmid << + UDMA_GEN_VMID_CFG_VMID_3_RX_Q_1_VMID_SHIFT)); + + al_reg_write32( + &unit_regs->gen.vmid.cfg_vmid_4, + (conf->rx_q_conf[2].vmid << + UDMA_GEN_VMID_CFG_VMID_4_RX_Q_2_VMID_SHIFT) | + (conf->rx_q_conf[3].vmid << + UDMA_GEN_VMID_CFG_VMID_4_RX_Q_3_VMID_SHIFT)); + + /* VMADDR per queue */ + rev_id = al_udma_get_revision(unit_regs); + if (rev_id >= AL_UDMA_REV_ID_REV2) { + al_reg_write32( + &unit_regs->gen.vmaddr.cfg_vmaddr_0, + (conf->tx_q_conf[0].vmaddr << + UDMA_GEN_VMADDR_CFG_VMADDR_0_TX_Q_0_VMADDR_SHIFT) | + (conf->tx_q_conf[1].vmaddr << + UDMA_GEN_VMADDR_CFG_VMADDR_0_TX_Q_1_VMADDR_SHIFT)); + + al_reg_write32( + &unit_regs->gen.vmaddr.cfg_vmaddr_1, + (conf->tx_q_conf[2].vmaddr << + UDMA_GEN_VMADDR_CFG_VMADDR_1_TX_Q_2_VMADDR_SHIFT) | + (conf->tx_q_conf[3].vmaddr << + UDMA_GEN_VMADDR_CFG_VMADDR_1_TX_Q_3_VMADDR_SHIFT)); + + al_reg_write32( + &unit_regs->gen.vmaddr.cfg_vmaddr_2, + (conf->rx_q_conf[0].vmaddr << + UDMA_GEN_VMADDR_CFG_VMADDR_2_RX_Q_0_VMADDR_SHIFT) | + (conf->rx_q_conf[1].vmaddr << + UDMA_GEN_VMADDR_CFG_VMADDR_2_RX_Q_1_VMADDR_SHIFT)); + + al_reg_write32( + &unit_regs->gen.vmaddr.cfg_vmaddr_3, + (conf->rx_q_conf[2].vmaddr << + UDMA_GEN_VMADDR_CFG_VMADDR_3_RX_Q_2_VMADDR_SHIFT) | + (conf->rx_q_conf[3].vmaddr << + UDMA_GEN_VMADDR_CFG_VMADDR_3_RX_Q_3_VMADDR_SHIFT)); + } +} + +/* UDMA VMID MSIX control configuration */ +void al_udma_gen_vmid_msix_conf_set( + struct unit_regs *unit_regs, + struct al_udma_gen_vmid_msix_conf *conf) +{ + al_reg_write32_masked( + &unit_regs->gen.vmid.cfg_vmid_0, + UDMA_GEN_VMID_CFG_VMID_0_MSIX_VMID_ACCESS_EN | + UDMA_GEN_VMID_CFG_VMID_0_MSIX_VMID_SEL, + (conf->access_en ? UDMA_GEN_VMID_CFG_VMID_0_MSIX_VMID_ACCESS_EN : 0) | + (conf->sel ? UDMA_GEN_VMID_CFG_VMID_0_MSIX_VMID_SEL : 0)); +} + +/* UDMA VMID control advanced Tx queue configuration */ +void al_udma_gen_vmid_advanced_tx_q_conf( + struct al_udma_q *q, + struct al_udma_gen_vmid_advanced_tx_q_conf *conf) +{ + struct udma_gen_regs *gen_regs = q->udma->gen_regs; + struct udma_gen_vmpr *vmpr = &gen_regs->vmpr[q->qid]; + + al_reg_write32_masked( + &vmpr->cfg_vmpr_0, + UDMA_GEN_VMPR_CFG_VMPR_0_TX_Q_HISEL_MASK | + UDMA_GEN_VMPR_CFG_VMPR_0_TX_Q_DATA_VMID_EN | + UDMA_GEN_VMPR_CFG_VMPR_0_TX_Q_PREF_VMID_EN | + UDMA_GEN_VMPR_CFG_VMPR_0_TX_Q_CMPL_VMID_EN, + conf->tx_q_addr_hi_sel | + ((conf->tx_q_data_vmid_en == AL_TRUE) ? + UDMA_GEN_VMPR_CFG_VMPR_0_TX_Q_DATA_VMID_EN : 0) | + ((conf->tx_q_prefetch_vmid_en == AL_TRUE) ? + UDMA_GEN_VMPR_CFG_VMPR_0_TX_Q_PREF_VMID_EN : 0) | + ((conf->tx_q_compl_vmid_en == AL_TRUE) ? + UDMA_GEN_VMPR_CFG_VMPR_0_TX_Q_CMPL_VMID_EN : 0)); + + al_reg_write32( + &vmpr->cfg_vmpr_1, + conf->tx_q_addr_hi); + + al_reg_write32_masked( + &vmpr->cfg_vmpr_2, + UDMA_GEN_VMPR_CFG_VMPR_2_TX_Q_PREF_VMID_MASK | + UDMA_GEN_VMPR_CFG_VMPR_2_TX_Q_CMPL_VMID_MASK, + (conf->tx_q_prefetch_vmid << + UDMA_GEN_VMPR_CFG_VMPR_2_TX_Q_PREF_VMID_SHIFT) | + (conf->tx_q_compl_vmid << + UDMA_GEN_VMPR_CFG_VMPR_2_TX_Q_CMPL_VMID_SHIFT)); + + al_reg_write32_masked( + &vmpr->cfg_vmpr_3, + UDMA_GEN_VMPR_CFG_VMPR_3_TX_Q_DATA_VMID_MASK | + UDMA_GEN_VMPR_CFG_VMPR_3_TX_Q_DATA_VMID_SEL_MASK, + (conf->tx_q_data_vmid << + UDMA_GEN_VMPR_CFG_VMPR_3_TX_Q_DATA_VMID_SHIFT) | + (conf->tx_q_data_vmid_mask << + UDMA_GEN_VMPR_CFG_VMPR_3_TX_Q_DATA_VMID_SEL_SHIFT)); +} + +/** UDMA VMID control advanced Rx queue configuration */ +void al_udma_gen_vmid_advanced_rx_q_conf( + struct al_udma_q *q, + struct al_udma_gen_vmid_advanced_rx_q_conf *conf) +{ + struct udma_gen_regs *gen_regs = q->udma->gen_regs; + struct udma_gen_vmpr *vmpr = &gen_regs->vmpr[q->qid]; + + al_reg_write32_masked( + &vmpr->cfg_vmpr_4, + UDMA_GEN_VMPR_CFG_VMPR_4_RX_Q_BUF1_HISEL_MASK | + UDMA_GEN_VMPR_CFG_VMPR_4_RX_Q_BUF1_VMID_EN | + UDMA_GEN_VMPR_CFG_VMPR_4_RX_Q_BUF2_HISEL_MASK | + UDMA_GEN_VMPR_CFG_VMPR_4_RX_Q_BUF2_VMID_EN | + UDMA_GEN_VMPR_CFG_VMPR_4_RX_Q_DDP_HISEL_MASK | + UDMA_GEN_VMPR_CFG_VMPR_4_RX_Q_DDP_VMID_EN | + UDMA_GEN_VMPR_CFG_VMPR_4_RX_Q_PREF_VMID_EN | + UDMA_GEN_VMPR_CFG_VMPR_4_RX_Q_CMPL_VMID_EN, + (conf->rx_q_addr_hi_sel << + UDMA_GEN_VMPR_CFG_VMPR_4_RX_Q_BUF1_HISEL_SHIFT) | + ((conf->rx_q_data_vmid_en == AL_TRUE) ? + UDMA_GEN_VMPR_CFG_VMPR_4_RX_Q_BUF1_VMID_EN : 0) | + (conf->rx_q_data_buff2_addr_hi_sel << + UDMA_GEN_VMPR_CFG_VMPR_4_RX_Q_BUF2_HISEL_SHIFT) | + ((conf->rx_q_data_buff2_vmid_en == AL_TRUE) ? + UDMA_GEN_VMPR_CFG_VMPR_4_RX_Q_BUF2_VMID_EN : 0) | + (conf->rx_q_ddp_addr_hi_sel << + UDMA_GEN_VMPR_CFG_VMPR_4_RX_Q_DDP_HISEL_SHIFT) | + ((conf->rx_q_ddp_vmid_en == AL_TRUE) ? + UDMA_GEN_VMPR_CFG_VMPR_4_RX_Q_DDP_VMID_EN : 0) | + ((conf->rx_q_prefetch_vmid_en == AL_TRUE) ? + UDMA_GEN_VMPR_CFG_VMPR_4_RX_Q_PREF_VMID_EN : 0) | + ((conf->rx_q_compl_vmid_en == AL_TRUE) ? + UDMA_GEN_VMPR_CFG_VMPR_4_RX_Q_CMPL_VMID_EN : 0)); + + al_reg_write32_masked( + &vmpr->cfg_vmpr_6, + UDMA_GEN_VMPR_CFG_VMPR_6_RX_Q_PREF_VMID_MASK | + UDMA_GEN_VMPR_CFG_VMPR_6_RX_Q_CMPL_VMID_MASK, + (conf->rx_q_prefetch_vmid << + UDMA_GEN_VMPR_CFG_VMPR_6_RX_Q_PREF_VMID_SHIFT) | + (conf->rx_q_compl_vmid << + UDMA_GEN_VMPR_CFG_VMPR_6_RX_Q_CMPL_VMID_SHIFT)); + + al_reg_write32_masked( + &vmpr->cfg_vmpr_7, + UDMA_GEN_VMPR_CFG_VMPR_7_RX_Q_BUF1_VMID_MASK | + UDMA_GEN_VMPR_CFG_VMPR_7_RX_Q_BUF1_VMID_SEL_MASK, + (conf->rx_q_data_vmid << + UDMA_GEN_VMPR_CFG_VMPR_7_RX_Q_BUF1_VMID_SHIFT) | + (conf->rx_q_data_vmid_mask << + UDMA_GEN_VMPR_CFG_VMPR_7_RX_Q_BUF1_VMID_SEL_SHIFT)); + + al_reg_write32_masked( + &vmpr->cfg_vmpr_8, + UDMA_GEN_VMPR_CFG_VMPR_8_RX_Q_BUF2_VMID_MASK | + UDMA_GEN_VMPR_CFG_VMPR_8_RX_Q_BUF2_VMID_SEL_MASK, + (conf->rx_q_data_buff2_vmid << + UDMA_GEN_VMPR_CFG_VMPR_8_RX_Q_BUF2_VMID_SHIFT) | + (conf->rx_q_data_buff2_mask << + UDMA_GEN_VMPR_CFG_VMPR_8_RX_Q_BUF2_VMID_SEL_SHIFT)); + + al_reg_write32_masked( + &vmpr->cfg_vmpr_9, + UDMA_GEN_VMPR_CFG_VMPR_9_RX_Q_DDP_VMID_MASK | + UDMA_GEN_VMPR_CFG_VMPR_9_RX_Q_DDP_VMID_SEL_MASK, + (conf->rx_q_ddp_vmid << + UDMA_GEN_VMPR_CFG_VMPR_9_RX_Q_DDP_VMID_SHIFT) | + (conf->rx_q_ddp_mask << + UDMA_GEN_VMPR_CFG_VMPR_9_RX_Q_DDP_VMID_SEL_SHIFT)); + + al_reg_write32( + &vmpr->cfg_vmpr_10, + conf->rx_q_addr_hi); + + al_reg_write32( + &vmpr->cfg_vmpr_11, + conf->rx_q_data_buff2_addr_hi); + + al_reg_write32( + &vmpr->cfg_vmpr_12, + conf->rx_q_ddp_addr_hi); +} + +/* UDMA header split buffer 2 Rx queue configuration */ +void al_udma_gen_hdr_split_buff2_rx_q_conf( + struct al_udma_q *q, + struct al_udma_gen_hdr_split_buff2_q_conf *conf) +{ + struct udma_gen_regs *gen_regs = q->udma->gen_regs; + struct udma_gen_vmpr *vmpr = &gen_regs->vmpr[q->qid]; + + al_reg_write32_masked( + &vmpr->cfg_vmpr_4, + UDMA_GEN_VMPR_CFG_VMPR_4_RX_Q_BUF2_MSB_ADDR_SEL_MASK, + conf->add_msb_sel << + UDMA_GEN_VMPR_CFG_VMPR_4_RX_Q_BUF2_MSB_ADDR_SEL_SHIFT); + + al_reg_write32( + &vmpr->cfg_vmpr_5, + conf->addr_msb); +} + diff --git a/al_hal_udma_config.h b/al_hal_udma_config.h new file mode 100644 index 00000000000..b742e1824c9 --- /dev/null +++ b/al_hal_udma_config.h @@ -0,0 +1,755 @@ +/*- +******************************************************************************* +Copyright (C) 2015 Annapurna Labs Ltd. + +This file may be licensed under the terms of the Annapurna Labs Commercial +License Agreement. + +Alternatively, this file can be distributed under the terms of the GNU General +Public License V2 as published by the Free Software Foundation and can be +found at http://www.gnu.org/licenses/gpl-2.0.html + +Alternatively, redistribution and use in source and binary forms, with or +without modification, are permitted provided that the following conditions are +met: + + * Redistributions of source code must retain the above copyright notice, +this list of conditions and the following disclaimer. + + * Redistributions in binary form must reproduce the above copyright +notice, this list of conditions and the following disclaimer in +the documentation and/or other materials provided with the +distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +*******************************************************************************/ + +/** + * @defgroup group_udma_config UDMA Config + * @ingroup group_udma_api + * UDMA Config API + * @{ + * @file al_hal_udma_config.h + * + * @brief C Header file for the Universal DMA HAL driver for configuration APIs + * + */ + +#ifndef __AL_HAL_UDMA_CONFIG_H__ +#define __AL_HAL_UDMA_CONFIG_H__ + +#include + + +/* *INDENT-OFF* */ +#ifdef __cplusplus +extern "C" { +#endif +/* *INDENT-ON* */ + +/** Scheduling mode */ +enum al_udma_sch_mode { + STRICT, /* Strict */ + SRR, /* Simple Sound Rubin */ + DWRR /* Deficit Weighted Round Rubin */ +}; + +/** AXI configuration */ +struct al_udma_axi_conf { + uint32_t axi_timeout; /* Timeout for AXI transactions */ + uint8_t arb_promotion; /* arbitration promotion */ + al_bool swap_8_bytes; /* enable 8 bytes swap instead of 4 bytes */ + al_bool swap_s2m_data; + al_bool swap_s2m_desc; + al_bool swap_m2s_data; + al_bool swap_m2s_desc; +}; + +/** UDMA AXI M2S configuration */ +struct al_udma_axi_submaster { + uint8_t id; /* AXI ID */ + uint8_t cache_type; + uint8_t burst; + uint16_t used_ext; + uint8_t bus_size; + uint8_t qos; + uint8_t prot; + uint8_t max_beats; +}; + +/** UDMA AXI M2S configuration */ +struct al_udma_m2s_axi_conf { + struct al_udma_axi_submaster comp_write; + struct al_udma_axi_submaster data_read; + struct al_udma_axi_submaster desc_read; + al_bool break_on_max_boundary; /* Data read break on max boundary */ + uint8_t min_axi_beats; /* Minimum burst for writing completion desc. */ + uint8_t ostand_max_data_read; + uint8_t ostand_max_desc_read; + uint8_t ostand_max_comp_req; + uint8_t ostand_max_comp_write; +}; + +/** UDMA AXI S2M configuration */ +struct al_udma_s2m_axi_conf { + struct al_udma_axi_submaster data_write; + struct al_udma_axi_submaster desc_read; + struct al_udma_axi_submaster comp_write; + al_bool break_on_max_boundary; /* Data read break on max boundary */ + uint8_t min_axi_beats; /* Minimum burst for writing completion desc. */ + uint8_t ostand_max_data_req; + uint8_t ostand_max_data_write; + uint8_t ostand_max_comp_req; + uint8_t ostand_max_comp_write; + uint8_t ostand_max_desc_read; + uint8_t ack_fifo_depth; /* size of the stream application ack fifo */ +}; + +/** M2S error logging */ +struct al_udma_err_log { + uint32_t error_status; + uint32_t header[4]; +}; + +/** M2S max packet size configuration */ +struct al_udma_m2s_pkt_len_conf { + uint32_t max_pkt_size; + al_bool encode_64k_as_zero; +}; + +/** M2S Descriptor Prefetch configuration */ +struct al_udma_m2s_desc_pref_conf { + uint8_t desc_fifo_depth; + enum al_udma_sch_mode sch_mode; /* Scheduling mode + * (either strict or RR) */ + + uint8_t max_desc_per_packet; /* max number of descriptors to + * prefetch */ + /* in one burst (5b) */ + uint8_t pref_thr; + uint8_t min_burst_above_thr; /* min burst size when fifo above + * pref_thr (4b) + */ + uint8_t min_burst_below_thr; /* min burst size when fifo below + * pref_thr (4b) + */ + uint8_t max_pkt_limit; /* maximum number of packets in the data + * read FIFO, defined based on header + * FIFO size + */ + uint16_t data_fifo_depth; /* maximum number of data beats in the + * data read FIFO, + * defined based on header FIFO size + */ +}; + +/** S2M Descriptor Prefetch configuration */ +struct al_udma_s2m_desc_pref_conf { + uint8_t desc_fifo_depth; + enum al_udma_sch_mode sch_mode; /* Scheduling mode * + * (either strict or RR) + */ + + al_bool q_promotion; /* enable promotion */ + al_bool force_promotion; /* force promotion */ + al_bool en_pref_prediction; /* enable prefetch prediction */ + uint8_t promotion_th; /* Threshold for queue promotion */ + + uint8_t pref_thr; + uint8_t min_burst_above_thr; /* min burst size when fifo above + * pref_thr (4b) + */ + uint8_t min_burst_below_thr; /* min burst size when fifo below + * pref_thr (4b) + */ + uint8_t a_full_thr; /* almost full threshold */ +}; + +/** S2M Data write configuration */ +struct al_udma_s2m_data_write_conf { + uint16_t data_fifo_depth; /* maximum number of data beats in the + * data write FIFO, defined based on + * header FIFO size + */ + uint8_t max_pkt_limit; /* maximum number of packets in the + * data write FIFO,defined based on + * header FIFO size + */ + uint8_t fifo_margin; + uint32_t desc_wait_timer; /* waiting time for the host to write + * new descriptor to the queue + * (for the current packet in process) + */ + uint32_t flags; /* bitwise of flags of s2m + * data_cfg_2 register + */ +}; + +/** S2M Completion configuration */ +struct al_udma_s2m_completion_conf { + uint8_t desc_size; /* Size of completion descriptor + * in words + */ + al_bool cnt_words; /* Completion fifo in use counter: + * AL_TRUE words, AL_FALS descriptors + */ + al_bool q_promotion; /* Enable promotion of the current + * unack in progress */ + /* in the completion write scheduler */ + al_bool force_rr; /* force RR arbitration in the + * scheduler + */ + // uint8_t ack_fifo_depth; /* size of the stream application ack fifo */ + uint8_t q_free_min; /* minimum number of free completion + * entries + */ + /* to qualify for promotion */ + + uint16_t comp_fifo_depth; /* Size of completion fifo in words */ + uint16_t unack_fifo_depth; /* Size of unacked fifo in descs */ + uint32_t timeout; /* Ack timout from stream interface */ +}; + +/** M2S UDMA DWRR configuration */ +struct al_udma_m2s_dwrr_conf { + al_bool enable_dwrr; + uint8_t inc_factor; + uint8_t weight; + al_bool pkt_mode; + uint32_t deficit_init_val; +}; + +/** M2S DMA Rate Limitation mode */ +struct al_udma_m2s_rlimit_mode { + al_bool pkt_mode_en; + uint16_t short_cycle_sz; + uint32_t token_init_val; +}; + +/** M2S Stream/Q Rate Limitation */ +struct al_udma_m2s_rlimit_cfg { + uint32_t max_burst_sz; /* maximum number of accumulated bytes in the + * token counter + */ + uint16_t long_cycle_sz; /* number of short cycles between token fill */ + uint32_t long_cycle; /* number of bits to add in each long cycle */ + uint32_t short_cycle; /* number of bits to add in each cycle */ + uint32_t mask; /* mask the different types of rate limiters */ +}; + +enum al_udma_m2s_rlimit_action { + AL_UDMA_STRM_RLIMIT_ENABLE, + AL_UDMA_STRM_RLIMIT_PAUSE, + AL_UDMA_STRM_RLIMIT_RESET +}; + +/** M2S UDMA Q scheduling configuration */ +struct al_udma_m2s_q_dwrr_conf { + uint32_t max_deficit_cnt_sz; /*maximum number of accumulated bytes + * in the deficit counter + */ + al_bool strict; /* bypass DWRR */ + uint8_t axi_qos; + uint16_t q_qos; + uint8_t weight; +}; + +/** M2S UDMA / UDMA Q scheduling configuration */ +struct al_udma_m2s_sc { + enum al_udma_sch_mode sch_mode; /* Scheduling Mode */ + struct al_udma_m2s_dwrr_conf dwrr; /* DWRR configuration */ +}; + +/** UDMA / UDMA Q rate limitation configuration */ +struct al_udma_m2s_rlimit { + struct al_udma_m2s_rlimit_mode rlimit_mode; + /* rate limitation enablers */ +#if 0 + struct al_udma_tkn_bkt_conf token_bkt; /* Token Bucket configuration */ +#endif +}; + +/** UDMA Data read configuration */ +struct al_udma_m2s_data_rd_conf { + uint8_t max_rd_d_beats; /* max burst size for reading data + * (in AXI beats-128b) (5b) + */ + uint8_t max_rd_d_out_req; /* max number of outstanding data + * read requests (6b) + */ + uint16_t max_rd_d_out_beats; /* max num. of data read beats (10b) */ +}; + +/** M2S UDMA completion and application timeouts */ +struct al_udma_m2s_comp_timeouts { + enum al_udma_sch_mode sch_mode; /* Scheduling mode + * (either strict or RR) + */ + al_bool enable_q_promotion; + uint8_t unack_fifo_depth; /* unacked desc fifo size */ + uint8_t comp_fifo_depth; /* desc fifo size */ + uint32_t coal_timeout; /* (24b) */ + uint32_t app_timeout; /* (24b) */ +}; + +/** S2M UDMA per queue completion configuration */ +struct al_udma_s2m_q_comp_conf { + al_bool dis_comp_coal; /* disable completion coalescing */ + al_bool en_comp_ring_update; /* enable writing completion descs */ + uint32_t comp_timer; /* completion coalescing timer */ + al_bool en_hdr_split; /* enable header split */ + al_bool force_hdr_split; /* force header split */ + uint16_t hdr_split_size; /* size used for the header split */ + uint8_t q_qos; /* queue QoS */ +}; + +/** UDMA per queue VMID control configuration */ +struct al_udma_gen_vmid_q_conf { + /* Enable usage of the VMID per queue according to 'vmid' */ + al_bool queue_en; + + /* Enable usage of the VMID from the descriptor buffer address 63:48 */ + al_bool desc_en; + + /* VMID to be applied when 'queue_en' is asserted */ + uint16_t vmid; + + /* VMADDR to be applied to msbs when 'desc_en' is asserted. + * Relevant for revisions >= AL_UDMA_REV_ID_REV2 */ + uint16_t vmaddr; +}; + +/** UDMA VMID control configuration */ +struct al_udma_gen_vmid_conf { + /* TX queue configuration */ + struct al_udma_gen_vmid_q_conf tx_q_conf[DMA_MAX_Q]; + + /* RX queue configuration */ + struct al_udma_gen_vmid_q_conf rx_q_conf[DMA_MAX_Q]; +}; + +/** UDMA VMID MSIX control configuration */ +struct al_udma_gen_vmid_msix_conf { + /* Enable write to all VMID_n registers in the MSI-X Controller */ + al_bool access_en; + + /* use VMID_n [7:0] from MSI-X Controller for MSI-X message */ + al_bool sel; +}; + +/** UDMA per Tx queue advanced VMID control configuration */ +struct al_udma_gen_vmid_advanced_tx_q_conf { + /********************************************************************** + * Tx Data VMID + **********************************************************************/ + /* Tx data VMID enable */ + al_bool tx_q_data_vmid_en; + + /* + * For Tx data reads, replacement bits for the original address. + * The number of bits replaced is determined according to + * 'tx_q_addr_hi_sel' + */ + unsigned int tx_q_addr_hi; + + /* + * For Tx data reads, 6 bits serving the number of bits taken from the + * extra register on account of bits coming from the original address + * field. + * When 'tx_q_addr_hi_sel'=32 all of 'tx_q_addr_hi' will be taken. + * When 'tx_q_addr_hi_sel'=0 none of it will be taken, and when any + * value in between, it will start from the MSB bit and sweep down as + * many bits as needed. For example if 'tx_q_addr_hi_sel'=8, the final + * address [63:56] will carry 'tx_q_addr_hi'[31:24] while [55:32] will + * carry the original buffer address[55:32]. + */ + unsigned int tx_q_addr_hi_sel; + + /* + * Tx data read VMID + * Masked per bit with 'tx_q_data_vmid_mask' + */ + unsigned int tx_q_data_vmid; + + /* + * Tx data read VMID mask + * Each '1' selects from the buffer address, each '0' selects from + * 'tx_q_data_vmid' + */ + unsigned int tx_q_data_vmid_mask; + + /********************************************************************** + * Tx prefetch VMID + **********************************************************************/ + /* Tx prefetch VMID enable */ + al_bool tx_q_prefetch_vmid_en; + + /* Tx prefetch VMID */ + unsigned int tx_q_prefetch_vmid; + + /********************************************************************** + * Tx completion VMID + **********************************************************************/ + /* Tx completion VMID enable */ + al_bool tx_q_compl_vmid_en; + + /* Tx completion VMID */ + unsigned int tx_q_compl_vmid; +}; + +/** UDMA per Rx queue advanced VMID control configuration */ +struct al_udma_gen_vmid_advanced_rx_q_conf { + /********************************************************************** + * Rx Data VMID + **********************************************************************/ + /* Rx data VMID enable */ + al_bool rx_q_data_vmid_en; + + /* + * For Rx data writes, replacement bits for the original address. + * The number of bits replaced is determined according to + * 'rx_q_addr_hi_sel' + */ + unsigned int rx_q_addr_hi; + + /* + * For Rx data writes, 6 bits serving the number of bits taken from the + * extra register on account of bits coming from the original address + * field. + */ + unsigned int rx_q_addr_hi_sel; + + /* + * Rx data write VMID + * Masked per bit with 'rx_q_data_vmid_mask' + */ + unsigned int rx_q_data_vmid; + + /* Rx data write VMID mask */ + unsigned int rx_q_data_vmid_mask; + + /********************************************************************** + * Rx Data Buffer 2 VMID + **********************************************************************/ + /* Rx data buff2 VMID enable */ + al_bool rx_q_data_buff2_vmid_en; + + /* + * For Rx data buff2 writes, replacement bits for the original address. + * The number of bits replaced is determined according to + * 'rx_q_data_buff2_addr_hi_sel' + */ + unsigned int rx_q_data_buff2_addr_hi; + + /* + * For Rx data buff2 writes, 6 bits serving the number of bits taken + * from the extra register on account of bits coming from the original + * address field. + */ + unsigned int rx_q_data_buff2_addr_hi_sel; + + /* + * Rx data buff2 write VMID + * Masked per bit with 'rx_q_data_buff2_mask' + */ + unsigned int rx_q_data_buff2_vmid; + + /* Rx data buff2 write VMID mask */ + unsigned int rx_q_data_buff2_mask; + + /********************************************************************** + * Rx DDP VMID + **********************************************************************/ + /* Rx DDP write VMID enable */ + al_bool rx_q_ddp_vmid_en; + + /* + * For Rx DDP writes, replacement bits for the original address. + * The number of bits replaced is determined according to + * 'rx_q_ddp_addr_hi_sel' + */ + unsigned int rx_q_ddp_addr_hi; + + /* + * For Rx DDP writes, 6 bits serving the number of bits taken from the + * extra register on account of bits coming from the original address + * field. + */ + unsigned int rx_q_ddp_addr_hi_sel; + + /* + * Rx DDP write VMID + * Masked per bit with 'rx_q_ddp_mask' + */ + unsigned int rx_q_ddp_vmid; + + /* Rx DDP write VMID mask */ + unsigned int rx_q_ddp_mask; + + /********************************************************************** + * Rx prefetch VMID + **********************************************************************/ + /* Rx prefetch VMID enable */ + al_bool rx_q_prefetch_vmid_en; + + /* Rx prefetch VMID */ + unsigned int rx_q_prefetch_vmid; + + /********************************************************************** + * Rx completion VMID + **********************************************************************/ + /* Rx completion VMID enable */ + al_bool rx_q_compl_vmid_en; + + /* Rx completion VMID */ + unsigned int rx_q_compl_vmid; +}; + +/** + * Header split, buffer 2 per queue configuration + * When header split is enabled, Buffer_2 is used as an address for the header + * data. Buffer_2 is defined as 32-bits in the RX descriptor and it is defined + * that the MSB ([63:32]) of Buffer_1 is used as address [63:32] for the header + * address. + */ +struct al_udma_gen_hdr_split_buff2_q_conf { + /* + * MSB of the 64-bit address (bits [63:32]) that can be used for header + * split for this queue + */ + unsigned int addr_msb; + + /* + * Determine how to select the MSB (bits [63:32]) of the address when + * header split is enabled (4 bits, one per byte) + * - Bits [3:0]: + * [0] – selector for bits [39:32] + * [1] – selector for bits [47:40] + * [2] – selector for bits [55:48] + * [3] – selector for bits [63:55] + * - Bit value: + * 0 – Use Buffer_1 (legacy operation) + * 1 – Use the queue configuration 'addr_msb' + */ + unsigned int add_msb_sel; +}; + +/* Report Error - to be used for abort */ +void al_udma_err_report(struct al_udma *udma); + +/* Statistics - TBD */ +void al_udma_stats_get(struct al_udma *udma); + +/* Misc configurations */ +/* Configure AXI configuration */ +int al_udma_axi_set(struct udma_gen_axi *axi_regs, + struct al_udma_axi_conf *axi); + +/* Configure UDMA AXI M2S configuration */ +int al_udma_m2s_axi_set(struct al_udma *udma, + struct al_udma_m2s_axi_conf *axi_m2s); + +/* Configure UDMA AXI S2M configuration */ +int al_udma_s2m_axi_set(struct al_udma *udma, + struct al_udma_s2m_axi_conf *axi_s2m); + +/* Configure M2S packet len */ +int al_udma_m2s_packet_size_cfg_set(struct al_udma *udma, + struct al_udma_m2s_pkt_len_conf *conf); + +/* Configure M2S UDMA descriptor prefetch */ +int al_udma_m2s_pref_set(struct al_udma *udma, + struct al_udma_m2s_desc_pref_conf *conf); +int al_udma_m2s_pref_get(struct al_udma *udma, + struct al_udma_m2s_desc_pref_conf *conf); + +/* set m2s packet's max descriptors (including meta descriptors) */ +#define AL_UDMA_M2S_MAX_ALLOWED_DESCS_PER_PACKET 31 +int al_udma_m2s_max_descs_set(struct al_udma *udma, uint8_t max_descs); + +/* set s2m packets' max descriptors */ +#define AL_UDMA_S2M_MAX_ALLOWED_DESCS_PER_PACKET 31 +int al_udma_s2m_max_descs_set(struct al_udma *udma, uint8_t max_descs); + + +/* Configure S2M UDMA descriptor prefetch */ +int al_udma_s2m_pref_set(struct al_udma *udma, + struct al_udma_s2m_desc_pref_conf *conf); +int al_udma_m2s_pref_get(struct al_udma *udma, + struct al_udma_m2s_desc_pref_conf *conf); + +/* Configure S2M UDMA data write */ +int al_udma_s2m_data_write_set(struct al_udma *udma, + struct al_udma_s2m_data_write_conf *conf); + +/* Configure the s2m full line write feature */ +int al_udma_s2m_full_line_write_set(struct al_udma *umda, al_bool enable); + +/* Configure S2M UDMA completion */ +int al_udma_s2m_completion_set(struct al_udma *udma, + struct al_udma_s2m_completion_conf *conf); + +/* Configure the M2S UDMA scheduling mode */ +int al_udma_m2s_sc_set(struct al_udma *udma, + struct al_udma_m2s_dwrr_conf *sched); + +/* Configure the M2S UDMA rate limitation */ +int al_udma_m2s_rlimit_set(struct al_udma *udma, + struct al_udma_m2s_rlimit_mode *mode); +int al_udma_m2s_rlimit_reset(struct al_udma *udma); + +/* Configure the M2S Stream rate limitation */ +int al_udma_m2s_strm_rlimit_set(struct al_udma *udma, + struct al_udma_m2s_rlimit_cfg *conf); +int al_udma_m2s_strm_rlimit_act(struct al_udma *udma, + enum al_udma_m2s_rlimit_action act); + +/* Configure the M2S UDMA Q rate limitation */ +int al_udma_m2s_q_rlimit_set(struct al_udma_q *udma_q, + struct al_udma_m2s_rlimit_cfg *conf); +int al_udma_m2s_q_rlimit_act(struct al_udma_q *udma_q, + enum al_udma_m2s_rlimit_action act); + +/* Configure the M2S UDMA Q scheduling mode */ +int al_udma_m2s_q_sc_set(struct al_udma_q *udma_q, + struct al_udma_m2s_q_dwrr_conf *conf); +int al_udma_m2s_q_sc_pause(struct al_udma_q *udma_q, al_bool set); +int al_udma_m2s_q_sc_reset(struct al_udma_q *udma_q); + +/* M2S UDMA completion and application timeouts */ +int al_udma_m2s_comp_timeouts_set(struct al_udma *udma, + struct al_udma_m2s_comp_timeouts *conf); +int al_udma_m2s_comp_timeouts_get(struct al_udma *udma, + struct al_udma_m2s_comp_timeouts *conf); + +/* UDMA get revision */ +static INLINE unsigned int al_udma_get_revision(struct unit_regs __iomem *unit_regs) +{ + return (al_reg_read32(&unit_regs->gen.dma_misc.revision) + & UDMA_GEN_DMA_MISC_REVISION_PROGRAMMING_ID_MASK) >> + UDMA_GEN_DMA_MISC_REVISION_PROGRAMMING_ID_SHIFT; +} + +/** + * S2M UDMA Configure the expected behavior of Rx/S2M UDMA when there are no Rx Descriptors. + * + * @param udma + * @param drop_packet when set to true, the UDMA will drop packet. + * @param gen_interrupt when set to true, the UDMA will generate + * no_desc_hint interrupt when a packet received and the UDMA + * doesn't find enough free descriptors for it. + * @param wait_for_desc_timeout timeout in SB cycles to wait for new + * descriptors before dropping the packets. + * Notes: + * - The hint interrupt is raised immediately without waiting + * for new descs. + * - value 0 means wait for ever. + * + * Notes: + * - When get_interrupt is set, the API won't program the iofic to unmask this + * interrupt, in this case the callee should take care for doing that unmask + * using the al_udma_iofic_config() API. + * + * - The hardware's default configuration is: no drop packet, generate hint + * interrupt. + * - This API must be called once and before enabling the UDMA + * + * @return 0 if no error found. + */ +int al_udma_s2m_no_desc_cfg_set(struct al_udma *udma, al_bool drop_packet, al_bool gen_interrupt, uint32_t wait_for_desc_timeout); + +/** + * S2M UDMA configure a queue's completion update + * + * @param q_udma + * @param enable set to true to enable completion update + * + * completion update better be disabled for tx queues as those descriptors + * doesn't carry useful information, thus disabling it saves DMA accesses. + * + * @return 0 if no error found. + */ +int al_udma_s2m_q_compl_updade_config(struct al_udma_q *udma_q, al_bool enable); + +/** + * S2M UDMA configure a queue's completion descriptors coalescing + * + * @param q_udma + * @param enable set to true to enable completion coalescing + * @param coal_timeout in South Bridge cycles. + * + * @return 0 if no error found. + */ +int al_udma_s2m_q_compl_coal_config(struct al_udma_q *udma_q, al_bool enable, uint32_t coal_timeout); + +/** + * S2M UDMA configure completion descriptors write burst parameters + * + * @param udma + * @param burst_size completion descriptors write burst size in bytes. + * + * @return 0 if no error found. + */int al_udma_s2m_compl_desc_burst_config(struct al_udma *udma, uint16_t + burst_size); + +/** + * S2M UDMA configure a queue's completion header split + * + * @param q_udma + * @param enable set to true to enable completion header split + * @param force_hdr_split the header split length will be taken from the queue configuration + * @param hdr_len header split length. + * + * @return 0 if no error found. + */ +int al_udma_s2m_q_compl_hdr_split_config(struct al_udma_q *udma_q, + al_bool enable, + al_bool force_hdr_split, + uint32_t hdr_len); + +/* S2M UDMA per queue completion configuration */ +int al_udma_s2m_q_comp_set(struct al_udma_q *udma_q, + struct al_udma_s2m_q_comp_conf *conf); + +/** UDMA VMID control configuration */ +void al_udma_gen_vmid_conf_set( + struct unit_regs __iomem *unit_regs, + struct al_udma_gen_vmid_conf *conf); + +/** UDMA VMID MSIX control configuration */ +void al_udma_gen_vmid_msix_conf_set( + struct unit_regs __iomem *unit_regs, + struct al_udma_gen_vmid_msix_conf *conf); + +/** UDMA VMID control advanced Tx queue configuration */ +void al_udma_gen_vmid_advanced_tx_q_conf( + struct al_udma_q *q, + struct al_udma_gen_vmid_advanced_tx_q_conf *conf); + +/** UDMA VMID control advanced Rx queue configuration */ +void al_udma_gen_vmid_advanced_rx_q_conf( + struct al_udma_q *q, + struct al_udma_gen_vmid_advanced_rx_q_conf *conf); + +/** UDMA header split buffer 2 Rx queue configuration */ +void al_udma_gen_hdr_split_buff2_rx_q_conf( + struct al_udma_q *q, + struct al_udma_gen_hdr_split_buff2_q_conf *conf); + +/* *INDENT-OFF* */ +#ifdef __cplusplus +} +#endif +/* *INDENT-ON* */ +/** @} end of UDMA config group */ +#endif /* __AL_HAL_UDMA_CONFIG_H__ */ diff --git a/al_hal_udma_debug.c b/al_hal_udma_debug.c new file mode 100644 index 00000000000..c6b9bf4b9bf --- /dev/null +++ b/al_hal_udma_debug.c @@ -0,0 +1,497 @@ +/*- +******************************************************************************* +Copyright (C) 2015 Annapurna Labs Ltd. + +This file may be licensed under the terms of the Annapurna Labs Commercial +License Agreement. + +Alternatively, this file can be distributed under the terms of the GNU General +Public License V2 as published by the Free Software Foundation and can be +found at http://www.gnu.org/licenses/gpl-2.0.html + +Alternatively, redistribution and use in source and binary forms, with or +without modification, are permitted provided that the following conditions are +met: + + * Redistributions of source code must retain the above copyright notice, +this list of conditions and the following disclaimer. + + * Redistributions in binary form must reproduce the above copyright +notice, this list of conditions and the following disclaimer in +the documentation and/or other materials provided with the +distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +*******************************************************************************/ + +/** + * @file al_hal_udma_debug.c + * + * @brief Universal DMA HAL driver for debug + * + */ + +#define DEBUG + +#include +#include +#include + +static void al_udma_regs_m2s_axi_print(struct al_udma *udma) +{ + al_dbg("M2S AXI regs:\n"); + AL_UDMA_PRINT_REG(udma, " ", "\n", m2s, axi_m2s, comp_wr_cfg_1); + AL_UDMA_PRINT_REG(udma, " ", "\n", m2s, axi_m2s, comp_wr_cfg_2); + AL_UDMA_PRINT_REG(udma, " ", "\n", m2s, axi_m2s, data_rd_cfg_1); + AL_UDMA_PRINT_REG(udma, " ", "\n", m2s, axi_m2s, data_rd_cfg_2); + AL_UDMA_PRINT_REG(udma, " ", "\n", m2s, axi_m2s, desc_rd_cfg_1); + AL_UDMA_PRINT_REG(udma, " ", "\n", m2s, axi_m2s, desc_rd_cfg_2); + AL_UDMA_PRINT_REG(udma, " ", "\n", m2s, axi_m2s, data_rd_cfg); + AL_UDMA_PRINT_REG(udma, " ", "\n", m2s, axi_m2s, desc_rd_cfg_3); + + AL_UDMA_PRINT_REG(udma, " ", "\n", m2s, axi_m2s, desc_wr_cfg_1); + AL_UDMA_PRINT_REG_FIELD(udma, " ", "\n", "%d", m2s, axi_m2s, + desc_wr_cfg_1, + max_axi_beats, + UDMA_AXI_M2S_DESC_WR_CFG_1_MAX_AXI_BEATS); + AL_UDMA_PRINT_REG_FIELD(udma, " ", "\n", "%d", m2s, axi_m2s, + desc_wr_cfg_1, + min_axi_beats, + UDMA_AXI_M2S_DESC_WR_CFG_1_MIN_AXI_BEATS); + + AL_UDMA_PRINT_REG(udma, " ", "\n", m2s, axi_m2s, ostand_cfg); +} + +static void al_udma_regs_m2s_general_print(struct al_udma *udma) +{ + al_dbg("M2S general regs:\n"); + + AL_UDMA_PRINT_REG(udma, " ", "\n", m2s, m2s, state); + AL_UDMA_PRINT_REG_FIELD(udma, " ", "\n", "%d", m2s, m2s, state, + comp_ctrl, + UDMA_M2S_STATE_COMP_CTRL); + AL_UDMA_PRINT_REG_FIELD(udma, " ", "\n", "%d", m2s, m2s, state, + stream_if, + UDMA_M2S_STATE_STREAM_IF); + AL_UDMA_PRINT_REG_FIELD(udma, " ", "\n", "%d", m2s, m2s, state, + rd_ctrl, + UDMA_M2S_STATE_DATA_RD_CTRL); + AL_UDMA_PRINT_REG_FIELD(udma, " ", "\n", "%d", m2s, m2s, state, + desc_pref, + UDMA_M2S_STATE_DESC_PREF); + + AL_UDMA_PRINT_REG(udma, " ", "\n", m2s, m2s, err_log_mask); + AL_UDMA_PRINT_REG(udma, " ", "\n", m2s, m2s, log_0); + AL_UDMA_PRINT_REG(udma, " ", "\n", m2s, m2s, log_1); + AL_UDMA_PRINT_REG(udma, " ", "\n", m2s, m2s, log_2); + AL_UDMA_PRINT_REG(udma, " ", "\n", m2s, m2s, log_3); + AL_UDMA_PRINT_REG(udma, " ", "\n", m2s, m2s, data_fifo_status); + AL_UDMA_PRINT_REG(udma, " ", "\n", m2s, m2s, header_fifo_status); + AL_UDMA_PRINT_REG(udma, " ", "\n", m2s, m2s, unack_fifo_status); + AL_UDMA_PRINT_REG(udma, " ", "\n", m2s, m2s, check_en); + AL_UDMA_PRINT_REG(udma, " ", "\n", m2s, m2s, fifo_en); + AL_UDMA_PRINT_REG(udma, " ", "\n", m2s, m2s, cfg_len); + AL_UDMA_PRINT_REG(udma, " ", "\n", m2s, m2s, stream_cfg); +} + +static void al_udma_regs_m2s_rd_print(struct al_udma *udma) +{ + al_dbg("M2S read regs:\n"); + AL_UDMA_PRINT_REG(udma, " ", "\n", m2s, m2s_rd, desc_pref_cfg_1); + AL_UDMA_PRINT_REG(udma, " ", "\n", m2s, m2s_rd, desc_pref_cfg_2); + + AL_UDMA_PRINT_REG(udma, " ", "\n", m2s, m2s_rd, desc_pref_cfg_3); + AL_UDMA_PRINT_REG_FIELD(udma, " ", "\n", "%d", m2s, m2s_rd, + desc_pref_cfg_3, + min_burst_below_thr, + UDMA_M2S_RD_DESC_PREF_CFG_3_MIN_BURST_BELOW_THR); + AL_UDMA_PRINT_REG_FIELD(udma, " ", "\n", "%d", m2s, m2s_rd, + desc_pref_cfg_3, + min_burst_above_thr, + UDMA_M2S_RD_DESC_PREF_CFG_3_MIN_BURST_ABOVE_THR); + AL_UDMA_PRINT_REG_FIELD(udma, " ", "\n", "%d", m2s, m2s_rd, + desc_pref_cfg_3, + pref_thr, + UDMA_M2S_RD_DESC_PREF_CFG_3_PREF_THR); + + AL_UDMA_PRINT_REG(udma, " ", "\n", m2s, m2s_rd, data_cfg); +} + +static void al_udma_regs_m2s_dwrr_print(struct al_udma *udma) +{ + al_dbg("M2S DWRR regs:\n"); + AL_UDMA_PRINT_REG(udma, " ", "\n", m2s, m2s_dwrr, cfg_sched); +} + +static void al_udma_regs_m2s_rate_limiter_print(struct al_udma *udma) +{ + al_dbg("M2S rate limiter regs:\n"); + AL_UDMA_PRINT_REG(udma, " ", "\n", m2s, m2s_rate_limiter, gen_cfg); +} + +static void al_udma_regs_m2s_stream_rate_limiter_print(struct al_udma *udma) +{ + al_dbg("M2S stream rate limiter regs:\n"); + + AL_UDMA_PRINT_REG(udma, " ", "\n", m2s, m2s_stream_rate_limiter, + rlimit.cfg_1s); + AL_UDMA_PRINT_REG(udma, " ", "\n", m2s, m2s_stream_rate_limiter, + rlimit.cfg_cycle); + AL_UDMA_PRINT_REG(udma, " ", "\n", m2s, m2s_stream_rate_limiter, + rlimit.cfg_token_size_1); + AL_UDMA_PRINT_REG(udma, " ", "\n", m2s, m2s_stream_rate_limiter, + rlimit.cfg_token_size_2); + AL_UDMA_PRINT_REG(udma, " ", "\n", m2s, m2s_stream_rate_limiter, + rlimit.mask); +} + +static void al_udma_regs_m2s_comp_print(struct al_udma *udma) +{ + al_dbg("M2S completion regs:\n"); + + AL_UDMA_PRINT_REG(udma, " ", "\n", m2s, m2s_comp, cfg_1c); + + AL_UDMA_PRINT_REG_FIELD(udma, " ", "\n", "%d", m2s, m2s_comp, cfg_1c, + comp_fifo_depth, + UDMA_M2S_COMP_CFG_1C_COMP_FIFO_DEPTH); + AL_UDMA_PRINT_REG_FIELD(udma, " ", "\n", "%d", m2s, m2s_comp, cfg_1c, + unack_fifo_depth, + UDMA_M2S_COMP_CFG_1C_UNACK_FIFO_DEPTH); + AL_UDMA_PRINT_REG_BIT(udma, " ", "\n", m2s, m2s_comp, cfg_1c, + q_promotion, + UDMA_M2S_COMP_CFG_1C_Q_PROMOTION); + AL_UDMA_PRINT_REG_BIT(udma, " ", "\n", m2s, m2s_comp, cfg_1c, + force_rr, + UDMA_M2S_COMP_CFG_1C_FORCE_RR); + AL_UDMA_PRINT_REG_FIELD(udma, " ", "\n", "%d", m2s, m2s_comp, cfg_1c, + q_free_min, + UDMA_M2S_COMP_CFG_1C_Q_FREE_MIN); + + AL_UDMA_PRINT_REG(udma, " ", "\n", m2s, m2s_comp, cfg_coal); + AL_UDMA_PRINT_REG(udma, " ", "\n", m2s, m2s_comp, cfg_application_ack); +} + +static void al_udma_regs_m2s_stat_print(struct al_udma *udma) +{ + al_dbg("M2S statistics regs:\n"); + AL_UDMA_PRINT_REG(udma, " ", "\n", m2s, m2s_stat, cfg_st); + AL_UDMA_PRINT_REG(udma, " ", "\n", m2s, m2s_stat, tx_pkt); + AL_UDMA_PRINT_REG(udma, " ", "\n", m2s, m2s_stat, tx_bytes_low); + AL_UDMA_PRINT_REG(udma, " ", "\n", m2s, m2s_stat, tx_bytes_high); + AL_UDMA_PRINT_REG(udma, " ", "\n", m2s, m2s_stat, prefed_desc); + AL_UDMA_PRINT_REG(udma, " ", "\n", m2s, m2s_stat, comp_pkt); + AL_UDMA_PRINT_REG(udma, " ", "\n", m2s, m2s_stat, comp_desc); + AL_UDMA_PRINT_REG(udma, " ", "\n", m2s, m2s_stat, ack_pkts); +} + +static void al_udma_regs_m2s_feature_print(struct al_udma *udma) +{ + al_dbg("M2S feature regs:\n"); + AL_UDMA_PRINT_REG(udma, " ", "\n", m2s, m2s_feature, reg_1); + AL_UDMA_PRINT_REG(udma, " ", "\n", m2s, m2s_feature, reg_3); + AL_UDMA_PRINT_REG(udma, " ", "\n", m2s, m2s_feature, reg_4); + AL_UDMA_PRINT_REG(udma, " ", "\n", m2s, m2s_feature, reg_5); +} + +static void al_udma_regs_m2s_q_print(struct al_udma *udma, uint32_t qid) +{ + al_dbg("M2S Q[%d] status regs:\n", qid); + al_reg_write32(&udma->udma_regs->m2s.m2s.indirect_ctrl, qid); + AL_UDMA_PRINT_REG(udma, " ", "\n", m2s, m2s, sel_pref_fifo_status); + AL_UDMA_PRINT_REG(udma, " ", "\n", m2s, m2s, sel_comp_fifo_status); + AL_UDMA_PRINT_REG(udma, " ", "\n", m2s, m2s, sel_rate_limit_status); + AL_UDMA_PRINT_REG(udma, " ", "\n", m2s, m2s, sel_dwrr_status); + + al_dbg("M2S Q[%d] regs:\n", qid); + AL_UDMA_PRINT_REG(udma, " ", "\n", m2s, m2s_q[qid], cfg); + AL_UDMA_PRINT_REG(udma, " ", "\n", m2s, m2s_q[qid], status); + AL_UDMA_PRINT_REG(udma, " ", "\n", m2s, m2s_q[qid], tdrbp_low); + AL_UDMA_PRINT_REG(udma, " ", "\n", m2s, m2s_q[qid], tdrbp_high); + AL_UDMA_PRINT_REG(udma, " ", "\n", m2s, m2s_q[qid], tdrl); + AL_UDMA_PRINT_REG(udma, " ", "\n", m2s, m2s_q[qid], tdrhp); + AL_UDMA_PRINT_REG(udma, " ", "\n", m2s, m2s_q[qid], tdrtp); + AL_UDMA_PRINT_REG(udma, " ", "\n", m2s, m2s_q[qid], tdcp); + AL_UDMA_PRINT_REG(udma, " ", "\n", m2s, m2s_q[qid], tcrbp_low); + AL_UDMA_PRINT_REG(udma, " ", "\n", m2s, m2s_q[qid], tcrbp_high); + AL_UDMA_PRINT_REG(udma, " ", "\n", m2s, m2s_q[qid], tcrhp); + + AL_UDMA_PRINT_REG(udma, " ", "\n", m2s, m2s_q[qid], rlimit.cfg_1s); + AL_UDMA_PRINT_REG(udma, " ", "\n", m2s, m2s_q[qid], rlimit.cfg_cycle); + AL_UDMA_PRINT_REG(udma, " ", "\n", m2s, m2s_q[qid], + rlimit.cfg_token_size_1); + AL_UDMA_PRINT_REG(udma, " ", "\n", m2s, m2s_q[qid], + rlimit.cfg_token_size_2); + AL_UDMA_PRINT_REG(udma, " ", "\n", m2s, m2s_q[qid], rlimit.mask); + + AL_UDMA_PRINT_REG(udma, " ", "\n", m2s, m2s_q[qid], dwrr_cfg_1); + AL_UDMA_PRINT_REG(udma, " ", "\n", m2s, m2s_q[qid], dwrr_cfg_2); + AL_UDMA_PRINT_REG(udma, " ", "\n", m2s, m2s_q[qid], dwrr_cfg_3); + AL_UDMA_PRINT_REG(udma, " ", "\n", m2s, m2s_q[qid], comp_cfg); + AL_UDMA_PRINT_REG(udma, " ", "\n", m2s, m2s_q[qid], q_tx_pkt); +} + +static void al_udma_regs_s2m_axi_print(struct al_udma *udma) +{ + al_dbg("S2M AXI regs:\n"); + AL_UDMA_PRINT_REG(udma, " ", "\n", s2m, axi_s2m, data_wr_cfg_1); + AL_UDMA_PRINT_REG(udma, " ", "\n", s2m, axi_s2m, data_wr_cfg_2); + AL_UDMA_PRINT_REG(udma, " ", "\n", s2m, axi_s2m, desc_rd_cfg_4); + AL_UDMA_PRINT_REG(udma, " ", "\n", s2m, axi_s2m, desc_rd_cfg_5); + AL_UDMA_PRINT_REG(udma, " ", "\n", s2m, axi_s2m, comp_wr_cfg_1); + AL_UDMA_PRINT_REG(udma, " ", "\n", s2m, axi_s2m, comp_wr_cfg_2); + AL_UDMA_PRINT_REG(udma, " ", "\n", s2m, axi_s2m, data_wr_cfg); + AL_UDMA_PRINT_REG(udma, " ", "\n", s2m, axi_s2m, desc_rd_cfg_3); + AL_UDMA_PRINT_REG(udma, " ", "\n", s2m, axi_s2m, desc_wr_cfg_1); + AL_UDMA_PRINT_REG(udma, " ", "\n", s2m, axi_s2m, ostand_cfg_rd); + AL_UDMA_PRINT_REG(udma, " ", "\n", s2m, axi_s2m, ostand_cfg_wr); +} + +static void al_udma_regs_s2m_general_print(struct al_udma *udma) +{ + al_dbg("S2M general regs:\n"); + AL_UDMA_PRINT_REG(udma, " ", "\n", s2m, s2m, state); + AL_UDMA_PRINT_REG(udma, " ", "\n", s2m, s2m, err_log_mask); + AL_UDMA_PRINT_REG(udma, " ", "\n", s2m, s2m, log_0); + AL_UDMA_PRINT_REG(udma, " ", "\n", s2m, s2m, log_1); + AL_UDMA_PRINT_REG(udma, " ", "\n", s2m, s2m, log_2); + AL_UDMA_PRINT_REG(udma, " ", "\n", s2m, s2m, log_3); + AL_UDMA_PRINT_REG(udma, " ", "\n", s2m, s2m, s_data_fifo_status); + AL_UDMA_PRINT_REG(udma, " ", "\n", s2m, s2m, s_header_fifo_status); + AL_UDMA_PRINT_REG(udma, " ", "\n", s2m, s2m, axi_data_fifo_status); + AL_UDMA_PRINT_REG(udma, " ", "\n", s2m, s2m, unack_fifo_status); + AL_UDMA_PRINT_REG(udma, " ", "\n", s2m, s2m, check_en); + AL_UDMA_PRINT_REG(udma, " ", "\n", s2m, s2m, fifo_en); + AL_UDMA_PRINT_REG(udma, " ", "\n", s2m, s2m, stream_cfg); +} + +static void al_udma_regs_s2m_rd_print(struct al_udma *udma) +{ + al_dbg("S2M read regs:\n"); + AL_UDMA_PRINT_REG(udma, " ", "\n", s2m, s2m_rd, desc_pref_cfg_1); + AL_UDMA_PRINT_REG(udma, " ", "\n", s2m, s2m_rd, desc_pref_cfg_2); + AL_UDMA_PRINT_REG(udma, " ", "\n", s2m, s2m_rd, desc_pref_cfg_3); + AL_UDMA_PRINT_REG(udma, " ", "\n", s2m, s2m_rd, desc_pref_cfg_4); +} + +static void al_udma_regs_s2m_wr_print(struct al_udma *udma) +{ + al_dbg("S2M write regs:\n"); + AL_UDMA_PRINT_REG(udma, " ", "\n", s2m, s2m_wr, data_cfg_1); + AL_UDMA_PRINT_REG(udma, " ", "\n", s2m, s2m_wr, data_cfg_1); +} + +static void al_udma_regs_s2m_comp_print(struct al_udma *udma) +{ + al_dbg("S2M completion regs:\n"); + AL_UDMA_PRINT_REG(udma, " ", "\n", s2m, s2m_comp, cfg_1c); + AL_UDMA_PRINT_REG(udma, " ", "\n", s2m, s2m_comp, cfg_2c); + AL_UDMA_PRINT_REG(udma, " ", "\n", s2m, s2m_comp, cfg_application_ack); +} + +static void al_udma_regs_s2m_stat_print(struct al_udma *udma) +{ + al_dbg("S2M statistics regs:\n"); + AL_UDMA_PRINT_REG(udma, " ", "\n", s2m, s2m_stat, drop_pkt); + AL_UDMA_PRINT_REG(udma, " ", "\n", s2m, s2m_stat, rx_bytes_low); + AL_UDMA_PRINT_REG(udma, " ", "\n", s2m, s2m_stat, rx_bytes_high); + AL_UDMA_PRINT_REG(udma, " ", "\n", s2m, s2m_stat, prefed_desc); + AL_UDMA_PRINT_REG(udma, " ", "\n", s2m, s2m_stat, comp_pkt); + AL_UDMA_PRINT_REG(udma, " ", "\n", s2m, s2m_stat, comp_desc); + AL_UDMA_PRINT_REG(udma, " ", "\n", s2m, s2m_stat, ack_pkts); +} + +static void al_udma_regs_s2m_feature_print(struct al_udma *udma) +{ + al_dbg("S2M feature regs:\n"); + AL_UDMA_PRINT_REG(udma, " ", "\n", s2m, s2m_feature, reg_1); + AL_UDMA_PRINT_REG(udma, " ", "\n", s2m, s2m_feature, reg_3); + AL_UDMA_PRINT_REG(udma, " ", "\n", s2m, s2m_feature, reg_4); + AL_UDMA_PRINT_REG(udma, " ", "\n", s2m, s2m_feature, reg_5); + AL_UDMA_PRINT_REG(udma, " ", "\n", s2m, s2m_feature, reg_6); +} + +static void al_udma_regs_s2m_q_print(struct al_udma *udma, uint32_t qid) +{ + al_dbg("S2M Q[%d] status regs:\n", qid); + al_reg_write32(&udma->udma_regs->m2s.m2s.indirect_ctrl, qid); + AL_UDMA_PRINT_REG(udma, " ", "\n", s2m, s2m, sel_pref_fifo_status); + AL_UDMA_PRINT_REG(udma, " ", "\n", s2m, s2m, sel_comp_fifo_status); + + al_dbg("S2M Q[%d] regs:\n", qid); + AL_UDMA_PRINT_REG(udma, " ", "\n", s2m, s2m_q[qid], cfg); + AL_UDMA_PRINT_REG(udma, " ", "\n", s2m, s2m_q[qid], status); + AL_UDMA_PRINT_REG(udma, " ", "\n", s2m, s2m_q[qid], rdrbp_low); + AL_UDMA_PRINT_REG(udma, " ", "\n", s2m, s2m_q[qid], rdrbp_high); + AL_UDMA_PRINT_REG(udma, " ", "\n", s2m, s2m_q[qid], rdrl); + AL_UDMA_PRINT_REG(udma, " ", "\n", s2m, s2m_q[qid], rdrhp); + AL_UDMA_PRINT_REG(udma, " ", "\n", s2m, s2m_q[qid], rdrtp); + AL_UDMA_PRINT_REG(udma, " ", "\n", s2m, s2m_q[qid], rdcp); + AL_UDMA_PRINT_REG(udma, " ", "\n", s2m, s2m_q[qid], rcrbp_low); + AL_UDMA_PRINT_REG(udma, " ", "\n", s2m, s2m_q[qid], rcrbp_high); + AL_UDMA_PRINT_REG(udma, " ", "\n", s2m, s2m_q[qid], rcrhp); + AL_UDMA_PRINT_REG(udma, " ", "\n", s2m, s2m_q[qid], rcrhp_internal); + AL_UDMA_PRINT_REG(udma, " ", "\n", s2m, s2m_q[qid], comp_cfg); + AL_UDMA_PRINT_REG(udma, " ", "\n", s2m, s2m_q[qid], comp_cfg_2); + AL_UDMA_PRINT_REG(udma, " ", "\n", s2m, s2m_q[qid], pkt_cfg); + AL_UDMA_PRINT_REG(udma, " ", "\n", s2m, s2m_q[qid], qos_cfg); + AL_UDMA_PRINT_REG(udma, " ", "\n", s2m, s2m_q[qid], q_rx_pkt); +} + +void al_udma_regs_print(struct al_udma *udma, unsigned int mask) +{ + uint32_t i; + + if (!udma) + return; + + if (udma->type == UDMA_TX) { + if (mask & AL_UDMA_DEBUG_AXI) + al_udma_regs_m2s_axi_print(udma); + if (mask & AL_UDMA_DEBUG_GENERAL) + al_udma_regs_m2s_general_print(udma); + if (mask & AL_UDMA_DEBUG_READ) + al_udma_regs_m2s_rd_print(udma); + if (mask & AL_UDMA_DEBUG_DWRR) + al_udma_regs_m2s_dwrr_print(udma); + if (mask & AL_UDMA_DEBUG_RATE_LIMITER) + al_udma_regs_m2s_rate_limiter_print(udma); + if (mask & AL_UDMA_DEBUG_STREAM_RATE_LIMITER) + al_udma_regs_m2s_stream_rate_limiter_print(udma); + if (mask & AL_UDMA_DEBUG_COMP) + al_udma_regs_m2s_comp_print(udma); + if (mask & AL_UDMA_DEBUG_STAT) + al_udma_regs_m2s_stat_print(udma); + if (mask & AL_UDMA_DEBUG_FEATURE) + al_udma_regs_m2s_feature_print(udma); + for (i = 0; i < DMA_MAX_Q; i++) { + if (mask & AL_UDMA_DEBUG_QUEUE(i)) + al_udma_regs_m2s_q_print(udma, i); + } + } else { + if (mask & AL_UDMA_DEBUG_AXI) + al_udma_regs_s2m_axi_print(udma); + if (mask & AL_UDMA_DEBUG_GENERAL) + al_udma_regs_s2m_general_print(udma); + if (mask & AL_UDMA_DEBUG_READ) + al_udma_regs_s2m_rd_print(udma); + if (mask & AL_UDMA_DEBUG_WRITE) + al_udma_regs_s2m_wr_print(udma); + if (mask & AL_UDMA_DEBUG_COMP) + al_udma_regs_s2m_comp_print(udma); + if (mask & AL_UDMA_DEBUG_STAT) + al_udma_regs_s2m_stat_print(udma); + if (mask & AL_UDMA_DEBUG_FEATURE) + al_udma_regs_s2m_feature_print(udma); + for (i = 0; i < DMA_MAX_Q; i++) { + if (mask & AL_UDMA_DEBUG_QUEUE(i)) + al_udma_regs_s2m_q_print(udma, i); + } + } +} + +void al_udma_q_struct_print(struct al_udma *udma, uint32_t qid) +{ + struct al_udma_q *queue; + + if (!udma) + return; + + if (qid >= DMA_MAX_Q) + return; + + queue = &udma->udma_q[qid]; + + al_dbg("Q[%d] struct:\n", qid); + al_dbg(" size_mask = 0x%08x\n", (uint32_t)queue->size_mask); + al_dbg(" q_regs = %p\n", queue->q_regs); + al_dbg(" desc_base_ptr = %p\n", queue->desc_base_ptr); + al_dbg(" next_desc_idx = %d\n", (uint16_t)queue->next_desc_idx); + al_dbg(" desc_ring_id = %d\n", (uint32_t)queue->desc_ring_id); + al_dbg(" cdesc_base_ptr = %p\n", queue->cdesc_base_ptr); + al_dbg(" cdesc_size = %d\n", (uint32_t)queue->cdesc_size); + al_dbg(" next_cdesc_idx = %d\n", (uint16_t)queue->next_cdesc_idx); + al_dbg(" end_cdesc_ptr = %p\n", queue->end_cdesc_ptr); + al_dbg(" comp_head_idx = %d\n", (uint16_t)queue->comp_head_idx); + al_dbg(" comp_head_ptr = %p\n", queue->comp_head_ptr); + al_dbg(" pkt_crnt_descs = %d\n", (uint32_t)queue->pkt_crnt_descs); + al_dbg(" comp_ring_id = %d\n", (uint32_t)queue->comp_ring_id); + al_dbg(" desc_phy_base = 0x%016llx\n", (uint64_t)queue->desc_phy_base); + al_dbg(" cdesc_phy_base = 0x%016llx\n", + (uint64_t)queue->cdesc_phy_base); + al_dbg(" flags = 0x%08x\n", (uint32_t)queue->flags); + al_dbg(" size = %d\n", (uint32_t)queue->size); + al_dbg(" status = %d\n", (uint32_t)queue->status); + al_dbg(" udma = %p\n", queue->udma); + al_dbg(" qid = %d\n", (uint32_t)queue->qid); +} + +void al_udma_ring_print(struct al_udma *udma, uint32_t qid, + enum al_udma_ring_type rtype) +{ + struct al_udma_q *queue; + uint32_t desc_size; + void *base_ptr; + uint32_t i; + + if (!udma) + return; + + if (qid >= DMA_MAX_Q) + return; + + queue = &udma->udma_q[qid]; + if (rtype == AL_RING_SUBMISSION) { + base_ptr = queue->desc_base_ptr; + desc_size = sizeof(union al_udma_desc); + if (base_ptr) + al_dbg("Q[%d] submission ring pointers:\n", qid); + else { + al_dbg("Q[%d] submission ring is not allocated\n", qid); + return; + } + } else { + base_ptr = queue->cdesc_base_ptr; + desc_size = queue->cdesc_size; + if (base_ptr) + al_dbg("Q[%d] completion ring pointers:\n", qid); + else { + al_dbg("Q[%d] completion ring is not allocated\n", qid); + return; + } + } + + for (i = 0; i < queue->size; i++) { + uint32_t *curr_addr = (void*)((uint32_t)base_ptr + i * desc_size); + if (desc_size == 16) + al_dbg("[%04d](%p): %08x %08x %08x %08x\n", + i, + curr_addr, + (uint32_t)*curr_addr, + (uint32_t)*(curr_addr+1), + (uint32_t)*(curr_addr+2), + (uint32_t)*(curr_addr+3)); + else if (desc_size == 8) + al_dbg("[%04d](%p): %08x %08x\n", + i, + curr_addr, + (uint32_t)*curr_addr, + (uint32_t)*(curr_addr+1)); + else if (desc_size == 4) + al_dbg("[%04d](%p): %08x\n", + i, + curr_addr, + (uint32_t)*curr_addr); + else + break; + } +} diff --git a/al_hal_udma_debug.h b/al_hal_udma_debug.h new file mode 100644 index 00000000000..7bd1d972917 --- /dev/null +++ b/al_hal_udma_debug.h @@ -0,0 +1,134 @@ +/*- +******************************************************************************* +Copyright (C) 2015 Annapurna Labs Ltd. + +This file may be licensed under the terms of the Annapurna Labs Commercial +License Agreement. + +Alternatively, this file can be distributed under the terms of the GNU General +Public License V2 as published by the Free Software Foundation and can be +found at http://www.gnu.org/licenses/gpl-2.0.html + +Alternatively, redistribution and use in source and binary forms, with or +without modification, are permitted provided that the following conditions are +met: + + * Redistributions of source code must retain the above copyright notice, +this list of conditions and the following disclaimer. + + * Redistributions in binary form must reproduce the above copyright +notice, this list of conditions and the following disclaimer in +the documentation and/or other materials provided with the +distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +*******************************************************************************/ + +/** + * @defgroup group_udma_debug UDMA Debug + * @ingroup group_udma_api + * UDMA Debug + * @{ + * @file al_hal_udma_debug.h + * + * @brief C Header file for the Universal DMA HAL driver for debug APIs + * + */ + +#ifndef __AL_HAL_UDMA_DEBUG_H__ +#define __AL_HAL_UDMA_DEBUG_H__ + +#include + +/* *INDENT-OFF* */ +#ifdef __cplusplus +extern "C" { +#endif +/* *INDENT-ON* */ + +/* UDMA register print helper macros */ +#define AL_UDMA_PRINT_REG(UDMA, PREFIX, POSTFIX, TYPE, GROUP, REG) \ + al_dbg(PREFIX #REG " = 0x%08x" POSTFIX, al_reg_read32( \ + &(UDMA->udma_regs->TYPE.GROUP.REG))) + +#define AL_UDMA_PRINT_REG_FIELD( \ + UDMA, PREFIX, POSTFIX, FMT, TYPE, GROUP, REG, LBL, FIELD) \ + al_dbg(PREFIX #LBL " = " FMT POSTFIX, al_reg_read32( \ + &(UDMA->udma_regs->TYPE.GROUP.REG)) \ + & FIELD ## _MASK >> FIELD ## _SHIFT) + +#define AL_UDMA_PRINT_REG_BIT( \ + UDMA, PREFIX, POSTFIX, TYPE, GROUP, REG, LBL, FIELD) \ + al_dbg(PREFIX #LBL " = %d" POSTFIX, ((al_reg_read32( \ + &(UDMA->udma_regs->TYPE.GROUP.REG)) \ + & FIELD) != 0)) + +/* UDMA register print mask definitions */ +#define AL_UDMA_DEBUG_QUEUE(n) AL_BIT(n) +#define AL_UDMA_DEBUG_AXI AL_BIT(DMA_MAX_Q) +#define AL_UDMA_DEBUG_GENERAL AL_BIT(DMA_MAX_Q + 1) +#define AL_UDMA_DEBUG_READ AL_BIT(DMA_MAX_Q + 2) +#define AL_UDMA_DEBUG_WRITE AL_BIT(DMA_MAX_Q + 3) +#define AL_UDMA_DEBUG_DWRR AL_BIT(DMA_MAX_Q + 4) +#define AL_UDMA_DEBUG_RATE_LIMITER AL_BIT(DMA_MAX_Q + 5) +#define AL_UDMA_DEBUG_STREAM_RATE_LIMITER AL_BIT(DMA_MAX_Q + 6) +#define AL_UDMA_DEBUG_COMP AL_BIT(DMA_MAX_Q + 7) +#define AL_UDMA_DEBUG_STAT AL_BIT(DMA_MAX_Q + 8) +#define AL_UDMA_DEBUG_FEATURE AL_BIT(DMA_MAX_Q + 9) +#define AL_UDMA_DEBUG_ALL 0xFFFFFFFF + +/* Debug functions */ + +/** + * Print udma registers according to the provided mask + * + * @param udma udma data structure + * @param mask mask that specifies which registers groups to print + * e.g. AL_UDMA_DEBUG_AXI prints AXI registers, AL_UDMA_DEBUG_ALL prints all + * registers + */ +void al_udma_regs_print(struct al_udma *udma, unsigned int mask); + +/** + * Print udma queue software structure + * + * @param udma udma data structure + * @param qid queue index + */ +void al_udma_q_struct_print(struct al_udma *udma, uint32_t qid); + +/** UDMA ring type */ +enum al_udma_ring_type { + AL_RING_SUBMISSION, + AL_RING_COMPLETION +}; + +/** + * Print the ring entries for the specified queue index and ring type + * (submission/completion) + * + * @param udma udma data structure + * @param qid queue index + * @param rtype udma ring type + */ +void al_udma_ring_print(struct al_udma *udma, uint32_t qid, + enum al_udma_ring_type rtype); + + +/* *INDENT-OFF* */ +#ifdef __cplusplus +} +#endif +/* *INDENT-ON* */ +#endif /* __AL_HAL_UDMA_DEBUG_H__ */ +/** @} end of UDMA debug group */ diff --git a/al_hal_udma_iofic.c b/al_hal_udma_iofic.c new file mode 100644 index 00000000000..d6ba485296c --- /dev/null +++ b/al_hal_udma_iofic.c @@ -0,0 +1,151 @@ +/*- +******************************************************************************* +Copyright (C) 2015 Annapurna Labs Ltd. + +This file may be licensed under the terms of the Annapurna Labs Commercial +License Agreement. + +Alternatively, this file can be distributed under the terms of the GNU General +Public License V2 as published by the Free Software Foundation and can be +found at http://www.gnu.org/licenses/gpl-2.0.html + +Alternatively, redistribution and use in source and binary forms, with or +without modification, are permitted provided that the following conditions are +met: + + * Redistributions of source code must retain the above copyright notice, +this list of conditions and the following disclaimer. + + * Redistributions in binary form must reproduce the above copyright +notice, this list of conditions and the following disclaimer in +the documentation and/or other materials provided with the +distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +*******************************************************************************/ + +/** + * @{ + * @file al_hal_udma_iofic.c + * + * @brief unit interrupts configurations + * + */ + +#include "al_hal_udma_iofic.h" +#include "al_hal_udma_regs.h" + +/* + * configure the interrupt registers, interrupts will are kept masked + */ +static int al_udma_main_iofic_config(struct al_iofic_regs __iomem *base, + enum al_iofic_mode mode) +{ + switch (mode) { + case AL_IOFIC_MODE_LEGACY: + al_iofic_config(base, AL_INT_GROUP_A, + INT_CONTROL_GRP_SET_ON_POSEDGE | + INT_CONTROL_GRP_MASK_MSI_X | + INT_CONTROL_GRP_CLEAR_ON_READ); + al_iofic_config(base, AL_INT_GROUP_B, + INT_CONTROL_GRP_CLEAR_ON_READ | + INT_CONTROL_GRP_MASK_MSI_X); + al_iofic_config(base, AL_INT_GROUP_C, + INT_CONTROL_GRP_CLEAR_ON_READ | + INT_CONTROL_GRP_MASK_MSI_X); + al_iofic_config(base, AL_INT_GROUP_D, + INT_CONTROL_GRP_SET_ON_POSEDGE | + INT_CONTROL_GRP_MASK_MSI_X | + INT_CONTROL_GRP_CLEAR_ON_READ); + break; + case AL_IOFIC_MODE_MSIX_PER_Q: + al_iofic_config(base, AL_INT_GROUP_A, + INT_CONTROL_GRP_SET_ON_POSEDGE | + INT_CONTROL_GRP_AUTO_MASK | + INT_CONTROL_GRP_AUTO_CLEAR); + al_iofic_config(base, AL_INT_GROUP_B, + INT_CONTROL_GRP_AUTO_CLEAR | + INT_CONTROL_GRP_AUTO_MASK | + INT_CONTROL_GRP_CLEAR_ON_READ); + al_iofic_config(base, AL_INT_GROUP_C, + INT_CONTROL_GRP_AUTO_CLEAR | + INT_CONTROL_GRP_AUTO_MASK | + INT_CONTROL_GRP_CLEAR_ON_READ); + al_iofic_config(base, AL_INT_GROUP_D, + INT_CONTROL_GRP_SET_ON_POSEDGE | + INT_CONTROL_GRP_CLEAR_ON_READ | + INT_CONTROL_GRP_MASK_MSI_X); + break; + case AL_IOFIC_MODE_MSIX_PER_GROUP: + al_iofic_config(base, AL_INT_GROUP_A, + INT_CONTROL_GRP_SET_ON_POSEDGE | + INT_CONTROL_GRP_AUTO_CLEAR | + INT_CONTROL_GRP_AUTO_MASK); + al_iofic_config(base, AL_INT_GROUP_B, + INT_CONTROL_GRP_CLEAR_ON_READ | + INT_CONTROL_GRP_MASK_MSI_X); + al_iofic_config(base, AL_INT_GROUP_C, + INT_CONTROL_GRP_CLEAR_ON_READ | + INT_CONTROL_GRP_MASK_MSI_X); + al_iofic_config(base, AL_INT_GROUP_D, + INT_CONTROL_GRP_SET_ON_POSEDGE | + INT_CONTROL_GRP_CLEAR_ON_READ | + INT_CONTROL_GRP_MASK_MSI_X); + break; + default: + al_err("%s: invalid mode (%d)\n", __func__, mode); + return -EINVAL; + } + + al_dbg("%s: base.%p mode %d\n", __func__, base, mode); + return 0; +} + +/* + * configure the UDMA interrupt registers, interrupts are kept masked + */ +int al_udma_iofic_config(struct unit_regs __iomem *regs, enum al_iofic_mode mode, + uint32_t m2s_errors_disable, + uint32_t m2s_aborts_disable, + uint32_t s2m_errors_disable, + uint32_t s2m_aborts_disable) +{ + int rc; + + rc = al_udma_main_iofic_config(®s->gen.interrupt_regs.main_iofic, mode); + if (rc != 0) + return rc; + + al_iofic_unmask(®s->gen.interrupt_regs.secondary_iofic_ctrl, AL_INT_GROUP_A, ~m2s_errors_disable); + al_iofic_abort_mask(®s->gen.interrupt_regs.secondary_iofic_ctrl, AL_INT_GROUP_A, m2s_aborts_disable); + + al_iofic_unmask(®s->gen.interrupt_regs.secondary_iofic_ctrl, AL_INT_GROUP_B, ~s2m_errors_disable); + al_iofic_abort_mask(®s->gen.interrupt_regs.secondary_iofic_ctrl, AL_INT_GROUP_B, s2m_aborts_disable); + + al_dbg("%s base.%p mode %d\n", __func__, regs, mode); + return 0; +} + +/* + * return the offset of the unmask register for a given group + */ +uint32_t __iomem * al_udma_iofic_unmask_offset_get( + struct unit_regs __iomem *regs, + enum al_udma_iofic_level level, + int group) +{ + al_assert(al_udma_iofic_level_and_group_valid(level, group)); + return al_iofic_unmask_offset_get(al_udma_iofic_reg_base_get(regs, level), group); +} + +/** @} end of UDMA group */ diff --git a/al_hal_udma_iofic.h b/al_hal_udma_iofic.h new file mode 100644 index 00000000000..9e795004837 --- /dev/null +++ b/al_hal_udma_iofic.h @@ -0,0 +1,614 @@ +/*- +******************************************************************************* +Copyright (C) 2015 Annapurna Labs Ltd. + +This file may be licensed under the terms of the Annapurna Labs Commercial +License Agreement. + +Alternatively, this file can be distributed under the terms of the GNU General +Public License V2 as published by the Free Software Foundation and can be +found at http://www.gnu.org/licenses/gpl-2.0.html + +Alternatively, redistribution and use in source and binary forms, with or +without modification, are permitted provided that the following conditions are +met: + + * Redistributions of source code must retain the above copyright notice, +this list of conditions and the following disclaimer. + + * Redistributions in binary form must reproduce the above copyright +notice, this list of conditions and the following disclaimer in +the documentation and/or other materials provided with the +distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +*******************************************************************************/ + +/** + * @defgroup group_udma_interrupts UDMA I/O Fabric Interrupt Controller + * @ingroup group_udma_api + * UDMA IOFIC API + * @{ + * @file al_hal_udma_iofic.h + * + * @brief C Header file for programming the interrupt controller that found + * in UDMA based units. These APIs rely and use some the Interrupt controller + * API under al_hal_iofic.h + */ + +#ifndef __AL_HAL_UDMA_IOFIC_H__ +#define __AL_HAL_UDMA_IOFIC_H__ + +#include +#include +#include + +/* *INDENT-OFF* */ +#ifdef __cplusplus +extern "C" { +#endif +/* *INDENT-ON* */ + +/** + * Interrupt Mode + * This is the interrupt mode for the primary interrupt level The secondary + * interrupt level does not have mode and it is always a level sensitive + * interrupt that is reflected in group D of the primary. + */ +enum al_iofic_mode { + AL_IOFIC_MODE_LEGACY, /**< level-sensitive interrupt wire */ + AL_IOFIC_MODE_MSIX_PER_Q, /**< per UDMA queue MSI-X interrupt */ + AL_IOFIC_MODE_MSIX_PER_GROUP +}; + +/** interrupt controller level (primary/secondary) */ +enum al_udma_iofic_level { + AL_UDMA_IOFIC_LEVEL_PRIMARY, + AL_UDMA_IOFIC_LEVEL_SECONDARY +}; + +/* + * The next four groups represents the standard 4 groups in the primary + * interrupt controller of each bus-master unit in the I/O Fabric. + * The first two groups can be used when accessing the secondary interrupt + * controller as well. + */ +#define AL_INT_GROUP_A 0 /**< summary of the below events */ +#define AL_INT_GROUP_B 1 /**< RX completion queues */ +#define AL_INT_GROUP_C 2 /**< TX completion queues */ +#define AL_INT_GROUP_D 3 /**< Misc */ + +/******************************************************************************* + * Primary interrupt controller, group A bits + ******************************************************************************/ +/* Group A bits which are just summary bits of GROUP B, C and D */ +#define AL_INT_GROUP_A_GROUP_B_SUM AL_BIT(0) +#define AL_INT_GROUP_A_GROUP_C_SUM AL_BIT(1) +#define AL_INT_GROUP_A_GROUP_D_SUM AL_BIT(2) + +/******************************************************************************* + * MSIX entry indices + ******************************************************************************/ +/** MSIX entry index for summary of group D in group A */ +#define AL_INT_MSIX_GROUP_A_SUM_D_IDX 2 +/** MSIX entry index for RX completion queue 0 */ +#define AL_INT_MSIX_RX_COMPLETION_START 3 + +/******************************************************************************* + * Primary interrupt controller, group D bits + ******************************************************************************/ +#define AL_INT_GROUP_D_CROSS_MAIL_BOXES \ + (AL_BIT(0) | AL_BIT(1) | AL_BIT(2) | AL_BIT(3)) +/** Summary of secondary interrupt controller, group A) */ +#define AL_INT_GROUP_D_M2S AL_BIT(8) +/** Summary of secondary interrupt controller, group B) */ +#define AL_INT_GROUP_D_S2M AL_BIT(9) +#define AL_INT_GROUP_D_SW_TIMER_INT AL_BIT(10) +#define AL_INT_GROUP_D_APP_EXT_INT AL_BIT(11) +#define AL_INT_GROUP_D_ALL \ + AL_INT_GROUP_D_CROSS_MAIL_BOXES | \ + AL_INT_GROUP_D_M2S | \ + AL_INT_GROUP_D_S2M | \ + AL_INT_GROUP_D_SW_TIMER_INT | \ + AL_INT_GROUP_D_APP_EXT_INT + +/* + * Until this point, all description above is for Groups A/B/C/D in the PRIMARY + * Interrupt controller. + * Following are definitions related to the secondary interrupt controller with + * two cause registers (group A and group B) that covers UDMA M2S/S2M errors. + * Secondary interrupt controller summary bits are not mapped to the Processor + * GIC directly, rather they are represented in Group D of the primary interrupt + * controller. + */ + +/****************************************************************************** + * Secondary interrupt Controller, Group A, which holds the TX (M2S) error + * interrupt bits + ******************************************************************************/ + +/** + * MSIx response + * MSIX Bus generator response error, the Bus response received with error indication + */ +#define AL_INT_2ND_GROUP_A_M2S_MSIX_RESP AL_BIT(27) +/** + * MSIx timeout MSIX Bus generator timeout error. + * The generator didn't receive bus response for the MSIx write transaction. + */ +#define AL_INT_2ND_GROUP_A_M2S_MSIX_TO AL_BIT(26) +/** Prefetch header buffer parity error */ +#define AL_INT_2ND_GROUP_A_M2S_PREFETCH_HDR_PARITY AL_BIT(25) +/** Prefetch descriptor buffer parity error */ +#define AL_INT_2ND_GROUP_A_M2S_PREFETCH_DESC_PARITY AL_BIT(24) +/** Data buffer parity error */ +#define AL_INT_2ND_GROUP_A_M2S_DATA_PARITY AL_BIT(23) +/** Data header buffer parity error */ +#define AL_INT_2ND_GROUP_A_M2S_HDR_PARITY AL_BIT(22) +/** Completion coalescing buffer parity error */ +#define AL_INT_2ND_GROUP_A_M2S_COMPL_COAL_PARITY AL_BIT(21) +/** UNACK packets buffer parity error */ +#define AL_INT_2ND_GROUP_A_M2S_UNACK_PKT_PARITY AL_BIT(20) +/** ACK packets buffer parity error */ +#define AL_INT_2ND_GROUP_A_M2S_ACK_PKT_PARITY AL_BIT(19) +/** AXI data buffer parity error */ +#define AL_INT_2ND_GROUP_A_M2S_AX_DATA_PARITY AL_BIT(18) +/** + * Prefetch Ring ID error + * A wrong RingId was received while prefetching submission descriptor. This + * could indicate a software bug or hardware failure, unless the UDMA is + * working in a mode to ignore RingId (the al_udma_iofic_config() API can be + * used to configure the UDMA to ignore the Ring ID check) + */ +#define AL_INT_2ND_GROUP_A_M2S_PREFETCH_RING_ID AL_BIT(17) +/** + * Prefetch last + * Error in last bit indication of the descriptor + * Descriptor with Last bit asserted is read from the queue to the prefetch + * FIFO when the prefetch engine is not in a middle of packet processing (a + * descriptor with First bit asserted should be read first to indicate start of + * packet) + */ +#define AL_INT_2ND_GROUP_A_M2S_PREFETCH_LAST AL_BIT(16) +/** + * Prefetch first + * Error in first bit indication of the descriptor + * Descriptor with First bit asserted is read from the queue to the prefetch + * FIFO while the prefetch engine is in a middle of packet processing ( a + * descriptor with Last bit asserted should be read to indicate end of packet + * before starting a new one) + */ +#define AL_INT_2ND_GROUP_A_M2S_PREFETCH_FIRST AL_BIT(15) +/** + * Prefetch max descriptors + * Number of descriptors per packet exceeds the configurable maximum + * descriptors per packet. This could indicate a software bug or a hardware + * failure. (The al_udma_m2s_max_descs_set() API is used to configure the + * maximum descriptors per packet) + */ +#define AL_INT_2ND_GROUP_A_M2S_PREFETCH_MAX_DESC AL_BIT(14) +/** + * Packet length + * Packet length exceeds the configurable maximum packet size. The + * al_udma_m2s_packet_size_cfg_set() API is used to configure the maximum + * packet size) + */ +#define AL_INT_2ND_GROUP_A_M2S_PKT_LEN AL_BIT(13) +/** + * Prefetch AXI timeout + * Bus request to I/O Fabric timeout error + */ +#define AL_INT_2ND_GROUP_A_M2S_PREFETCH_AXI_TO AL_BIT(12) +/** + * Prefetch AXI response + * Bus response from I/O Fabric error + */ +#define AL_INT_2ND_GROUP_A_M2S_PREFETCH_AXI_RESP AL_BIT(11) +/** + * Prefetch AXI parity + * Bus parity error on descriptor being prefetched + */ +#define AL_INT_2ND_GROUP_A_M2S_PREFETCH_AXI_PARITY AL_BIT(10) +/** + * Data AXI timeout + * Bus request to I/O Fabric timeout error + */ +#define AL_INT_2ND_GROUP_A_M2S_DATA_AXI_TO AL_BIT(9) +/** + * Data AXI response + * Bus response from I/O Fabric error + */ +#define AL_INT_2ND_GROUP_A_M2S_DATA_AXI_RESP AL_BIT(8) +/** + * Data AXI parity + * Bus parity error on data being read + */ +#define AL_INT_2ND_GROUP_A_M2S_DATA_AXI_PARITY AL_BIT(7) +/** + * Completion AXI timeout + * Bus request to I/O Fabric timeout error + */ +#define AL_INT_2ND_GROUP_A_M2S_CONPL_AXI_TO AL_BIT(6) +/** + * Completion AXI response + * Bus response from I/O Fabric error + */ +#define AL_INT_2ND_GROUP_A_M2S_COMPL_AXI_RESP AL_BIT(5) +/** + * Completion AXI parity + * Bus generator internal SRAM parity error + */ +#define AL_INT_2ND_GROUP_A_M2S_COMP_AXI_PARITY AL_BIT(4) +/** + * Stream timeout + * Application stream interface timeout indicating a failure at the Application + * layer (RAID, Ethernet etc) + */ +#define AL_INT_2ND_GROUP_A_M2S_STRM_TO AL_BIT(3) +/** + * Stream response + * Application stream interface response error indicating a failure at the + * Application layer (RAID, Ethernet etc) + */ +#define AL_INT_2ND_GROUP_A_M2S_STRM_RESP AL_BIT(2) +/** + * Stream parity + * Application stream interface parity error indicating a failure at the + * Application layer (RAID, Ethernet etc) + */ +#define AL_INT_2ND_GROUP_A_M2S_STRM_PARITY AL_BIT(1) +/** + * Stream completion mismatch + * Application stream interface, packet serial mismatch error indicating a + * failure at the Application layer (RAID, Ethernet etc) + */ +#define AL_INT_2ND_GROUP_A_M2S_STRM_COMPL_MISMATCH AL_BIT(0) + +/******************************************************************************* + * Secondary interrupt Controller, Group B, which holds the RX (S2M) error + * interrupt bits + ******************************************************************************/ + +/** Prefetch descriptor buffer parity error */ +#define AL_INT_2ND_GROUP_B_S2M_PREFETCH_DESC_PARITY AL_BIT(30) +/** Completion coalescing buffer parity error */ +#define AL_INT_2ND_GROUP_B_S2M_COMPL_COAL_PARITY AL_BIT(29) +/** PRE-UNACK packets buffer parity error */ +#define AL_INT_2ND_GROUP_B_S2M_PRE_UNACK_PKT_PARITY AL_BIT(28) +/** UNACK packets buffer parity error */ +#define AL_INT_2ND_GROUP_B_S2M_UNACK_PKT_PARITY AL_BIT(27) +/** Data buffer parity error */ +#define AL_INT_2ND_GROUP_B_S2M_DATA_PARITY AL_BIT(26) +/** Data header buffer parity error */ +#define AL_INT_2ND_GROUP_B_S2M_DATA_HDR_PARITY AL_BIT(25) +/** + * Packet length + * Application stream interface, Data counter length mismatch with metadata + * packet length indicating a failure at the Application layer (RAID, Ethernet + * etc) + */ +#define AL_INT_2ND_GROUP_B_S2M_PKT_LEN AL_BIT(24) +/** + * Stream last + * Application stream interface, error in Last bit indication, this error is + * asserted when a 'last' indication is asserted on the stream interface + * (between the application and the UDMA) when the interface is not in the + * middle of packet, meaning that there was no 'first' indication before. This + * indicates a failure at the application layer. + */ +#define AL_INT_2ND_GROUP_B_S2M_STRM_LAST AL_BIT(23) +/** + * Stream first + * Application stream interface error in first bit indication, this error is + * asserted when a 'first' indication is asserted on the stream interface + * (between the application and the UDMA) when the interface is in the middle + * of packet, meaning that there was a 'first' indication before and the UDMA + * is waiting for a 'last' indication to end the packet. This indicates a + * failure at the application layer. + */ +#define AL_INT_2ND_GROUP_B_S2M_STRM_FIRST AL_BIT(22) +/** + * Stream data + * Application stream interface, error indication during data transaction + */ +#define AL_INT_2ND_GROUP_B_S2M_STRM_DATA AL_BIT(21) +/** + * Stream Data parity + * Application stream interface, parity error during data transaction + */ +#define AL_INT_2ND_GROUP_B_S2M_STRM_DATA_PARITY AL_BIT(20) +/** + * Stream Header error + * Application stream interface, error indication during header transaction + */ +#define AL_INT_2ND_GROUP_B_S2M_STRM_HDR AL_BIT(19) +/** + * Stream Header parity + * Application stream interface, parity error during header transaction + */ +#define AL_INT_2ND_GROUP_B_S2M_STRM_HDR_PARITY AL_BIT(18) +/** + * Completion UNACK + * Completion write, UNACK timeout due to completion FIFO back pressure + */ +#define AL_INT_2ND_GROUP_B_S2M_COMPL_UNACK AL_BIT(17) +/** + * Completion stream + * Completion write, UNACK timeout due to stream ACK FIFO back pressure + */ +#define AL_INT_2ND_GROUP_B_S2M_COMPL_STRM AL_BIT(16) +/** + * Completion AXI timeout + * Bus request to I/O Fabric timeout error + */ +#define AL_INT_2ND_GROUP_B_S2M_COMPL_AXI_TO AL_BIT(15) +/** + * Completion AXI response + * Bus response from I/O Fabric error + */ +#define AL_INT_2ND_GROUP_B_S2M_COMPL_AXI_RESP AL_BIT(14) +/** + * Completion AXI parity + * Completion Bus generator internal SRAM parity error + */ +#define AL_INT_2ND_GROUP_B_S2M_COMPL_AXI_PARITY AL_BIT(13) +/** + * Prefetch saturate + * Prefetch engine, packet length counter saturated (32 bit) , this is caused + * by an error at the application layer which sends packet data without + * 'last'/'first' indication. + */ +#define AL_INT_2ND_GROUP_B_S2M_PREFETCH_SAT AL_BIT(12) +/** + * Prefetch ring ID + * Prefetch engine, Ring ID is not matching the expected RingID. This could + * indicate a software bug or hardware failure, unless the UDMA is working in a + * mode to ignore RingId (the al_udma_iofic_config() API can be used to + * configure the UDMA to ignore the Ring ID check) + */ +#define AL_INT_2ND_GROUP_B_S2M_PREFETCH_RING_ID AL_BIT(11) +/** + * Prefetch AXI timeout + * Bus request to I/O Fabric timeout error + */ +#define AL_INT_2ND_GROUP_B_S2M_PREFETCH_AXI_TO AL_BIT(10) +/** + * Prefetch AXI response + * Bus response from I/O Fabric error + */ +#define AL_INT_2ND_GROUP_B_S2M_PREFETCH_AXI_RESP AL_BIT(9) +/** + * Prefetch AXI parity + * Bus parity error on descriptor being prefetched + */ +#define AL_INT_2ND_GROUP_B_S2M_PREFETCH_AXI_PARITY AL_BIT(8) +/** + * No descriptors hint + * Data write, Hint to the SW that there are not enough descriptors in the + * queue for the current received packet. This is considered a hint and not an + * error, as it could be a normal situation in certain application. The S2M + * UDMA behavior when it runs out of Rx Descriptor is controlled by driver + * which can use this hint to add more descriptors to the Rx queue. + */ +#define AL_INT_2ND_GROUP_B_S2M_NO_DESC_HINT AL_BIT(7) +/** + * No descriptors timeout + * Data write, Timeout indication when there are not enough descriptors for the + * current packet and the timeout expires. The S2M UDMA behavior when it runs + * out of Rx Descriptor is controlled by driver which can use this hint to add + * more descriptors to the Rx queue. The al_udma_s2m_no_desc_cfg_set() is used + * to configure theUDMA S2M timeout and behavior when there are no Rx + * descriptors for the received packet. + */ +#define AL_INT_2ND_GROUP_B_S2M_NO_DESC_TO AL_BIT(6) +/** + * Promotion indication + * Data write, the data write engine checks the queue number of the two packets + * at the head of the data FIFO, the data write engine notify the prefetch + * engine to promote these queue numbers in the prefetch scheduler to make sure + * that these queue will have RX descriptors for these packets. This error + * indicates that the prefetch promotion didn't work for the second packet in + * the FIFO. This is an indication used for system debug and not an error. + */ +#define AL_INT_2ND_GROUP_B_S2M_PROM_IND AL_BIT(5) +/** + * Header split ignored + * Data write, The application requested header split but the buffer descriptor + * doesn't include a second buffer for the header + */ +#define AL_INT_2ND_GROUP_B_S2M_HDR_SPLT_IGNORED AL_BIT(4) +/** + * Header split length + * Data write, The application requested header split and the length of the + * second buffer allocated for the header is not enough for the requested + * header length. The remaining of the header is written to buffer 1 (data + * buffer). + */ +#define AL_INT_2ND_GROUP_B_S2M_HDR_SPLT_LEN AL_BIT(3) +/** + * Data AXI timeout + * Bus request to I/O Fabric timeout error + */ +#define AL_INT_2ND_GROUP_B_S2M_DATA_AXI_TO AL_BIT(2) +/** + * Data AXI response + * Bus response from I/O Fabric error + */ +#define AL_INT_2ND_GROUP_B_S2M_DATA_AXI_RESP AL_BIT(1) +/** + * Data AXI parity + * Bus parity error on data being read + */ +#define AL_INT_2ND_GROUP_B_S2M_DATA_AXI_PARITY AL_BIT(0) + +/******************************************************************************* + * Configurations + ******************************************************************************/ + +/** + * Configure the UDMA interrupt controller registers, interrupts will are kept + * masked. + * This is a static setting that should be called while initialized the + * interrupt controller within a given UDMA, and should not be modified during + * runtime unless the UDMA is completely disabled. The first argument sets the + * interrupt and MSIX modes. The m2s/s2m errors/abort are a set of bit-wise + * masks to define the behaviour of the UDMA once an error happens: The _abort + * will put the UDMA in abort state once an error happens The _error bitmask + * will indicate and error in the secondary cause register but will not abort. + * The bit-mask that the _errors_disable and _aborts_disable are described in + * 'AL_INT_2ND_GROUP_A_*' and 'AL_INT_2ND_GROUP_B_*' + * + * @param regs pointer to unit registers + * @param mode interrupt scheme mode (legacy, MSI-X..) + * @param m2s_errors_disable + * This is a bit-wise mask, to indicate which one of the error causes in + * secondary interrupt group_A should generate an interrupt. When a bit is + * set, the error cause is ignored. + * Recommended value: 0 (enable all errors). + * @param m2s_aborts_disable + * This is a bit-wise mask, to indicate which one of the error causes in + * secondary interrupt group_A should automatically put the UDMA in + * abort state. When a bit is set, the error cause does cause an abort. + * Recommended value: 0 (enable all aborts). + * @param s2m_errors_disable + * This is a bit-wise mask, to indicate which one of the error causes in + * secondary interrupt group_A should generate an interrupt. When a bit is + * set, the error cause is ignored. + * Recommended value: 0xE0 (disable hint errors). + * @param s2m_aborts_disable + * This is a bit-wise mask, to indicate which one of the error causes in + * secondary interrupt group_A should automatically put the UDMA in + * abort state. When a bit is set, the error cause does cause an abort. + * Recommended value: 0xE0 (disable hint aborts). + * + * @return 0 on success. -EINVAL otherwise. + */ +int al_udma_iofic_config(struct unit_regs __iomem *regs, + enum al_iofic_mode mode, + uint32_t m2s_errors_disable, + uint32_t m2s_aborts_disable, + uint32_t s2m_errors_disable, + uint32_t s2m_aborts_disable); +/** + * return the offset of the unmask register for a given group. + * this function can be used when the upper layer wants to directly + * access the unmask regiter and bypass the al_udma_iofic_unmask() API. + * + * @param regs pointer to udma registers + * @param level the interrupt controller level (primary / secondary) + * @param group the interrupt group ('AL_INT_GROUP_*') + * @return the offset of the unmask register. + */ +uint32_t __iomem * al_udma_iofic_unmask_offset_get( + struct unit_regs __iomem *regs, + enum al_udma_iofic_level level, + int group); + +/** + * Get the interrupt controller base address for either the primary or secondary + * interrupt controller + * + * @param regs pointer to udma unit registers + * @param level the interrupt controller level (primary / secondary) + * + * @returns The interrupt controller base address + * + */ +static INLINE void __iomem *al_udma_iofic_reg_base_get( + struct unit_regs __iomem *regs, + enum al_udma_iofic_level level) +{ + void __iomem *iofic_regs = (level == AL_UDMA_IOFIC_LEVEL_PRIMARY) ? + (void __iomem *)®s->gen.interrupt_regs.main_iofic : + (void __iomem *)®s->gen.interrupt_regs.secondary_iofic_ctrl; + + return iofic_regs; +} + +/** + * Check the interrupt controller level/group validity + * + * @param level the interrupt controller level (primary / secondary) + * @param group the interrupt group ('AL_INT_GROUP_*') + * + * @returns 0 - invalid, 1 - valid + * + */ +static INLINE int al_udma_iofic_level_and_group_valid( + enum al_udma_iofic_level level, + int group) +{ + if (((level == AL_UDMA_IOFIC_LEVEL_PRIMARY) && (group >= 0) && (group < 4)) || + ((level == AL_UDMA_IOFIC_LEVEL_SECONDARY) && (group >= 0) && (group < 2))) + return 1; + + return 0; +} +/** + * unmask specific interrupts for a given group + * this functions uses the interrupt mask clear register to guarantee atomicity + * it's safe to call it while the mask is changed by the HW (auto mask) or another cpu. + * + * @param regs pointer to udma unit registers + * @param level the interrupt controller level (primary / secondary) + * @param group the interrupt group ('AL_INT_GROUP_*') + * @param mask bitwise of interrupts to unmask, set bits will be unmasked. + */ +static INLINE void al_udma_iofic_unmask( + struct unit_regs __iomem *regs, + enum al_udma_iofic_level level, + int group, + uint32_t mask) +{ + al_assert(al_udma_iofic_level_and_group_valid(level, group)); + al_iofic_unmask(al_udma_iofic_reg_base_get(regs, level), group, mask); +} + +/** + * mask specific interrupts for a given group + * this functions modifies interrupt mask register, the callee must make sure + * the mask is not changed by another cpu. + * + * @param regs pointer to udma unit registers + * @param level the interrupt controller level (primary / secondary) + * @param group the interrupt group ('AL_INT_GROUP_*') + * @param mask bitwise of interrupts to mask, set bits will be masked. + */ +static INLINE void al_udma_iofic_mask( + struct unit_regs __iomem *regs, + enum al_udma_iofic_level level, + int group, + uint32_t mask) +{ + al_assert(al_udma_iofic_level_and_group_valid(level, group)); + al_iofic_mask(al_udma_iofic_reg_base_get(regs, level), group, mask); +} + +/** + * read interrupt cause register for a given group + * this will clear the set bits if the Clear on Read mode enabled. + * @param regs pointer to udma unit registers + * @param level the interrupt controller level (primary / secondary) + * @param group the interrupt group ('AL_INT_GROUP_*') + */ +static INLINE uint32_t al_udma_iofic_read_cause( + struct unit_regs __iomem *regs, + enum al_udma_iofic_level level, + int group) +{ + al_assert(al_udma_iofic_level_and_group_valid(level, group)); + return al_iofic_read_cause(al_udma_iofic_reg_base_get(regs, level), group); +} + +#endif +/** @} end of UDMA group */ diff --git a/al_hal_udma_iofic_regs.h b/al_hal_udma_iofic_regs.h new file mode 100644 index 00000000000..8e53aa673cc --- /dev/null +++ b/al_hal_udma_iofic_regs.h @@ -0,0 +1,66 @@ +/*- +******************************************************************************* +Copyright (C) 2015 Annapurna Labs Ltd. + +This file may be licensed under the terms of the Annapurna Labs Commercial +License Agreement. + +Alternatively, this file can be distributed under the terms of the GNU General +Public License V2 as published by the Free Software Foundation and can be +found at http://www.gnu.org/licenses/gpl-2.0.html + +Alternatively, redistribution and use in source and binary forms, with or +without modification, are permitted provided that the following conditions are +met: + + * Redistributions of source code must retain the above copyright notice, +this list of conditions and the following disclaimer. + + * Redistributions in binary form must reproduce the above copyright +notice, this list of conditions and the following disclaimer in +the documentation and/or other materials provided with the +distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +*******************************************************************************/ + + +#ifndef __AL_HAL_UDMA_IOFIC_REG_H +#define __AL_HAL_UDMA_IOFIC_REG_H + +#include "al_hal_iofic_regs.h" +#ifdef __cplusplus +extern "C" { +#endif + +/** This structure covers all interrupt registers of a given UDMA, which is + * built of an al_iofic_regs, which is the common I/O Fabric Interrupt + * controller (IOFIC), and additional two interrupts groups dedicated for the + * application-specific engine attached to the UDMA, the interrupt summary + * of those two groups routed to gourp D of the main controller. + */ +struct udma_iofic_regs { + struct al_iofic_regs main_iofic; + uint32_t rsrvd1[(0x1c00) >> 2]; + struct al_iofic_grp_ctrl secondary_iofic_ctrl[2]; +}; + +#ifdef __cplusplus +} +#endif + +#endif /* __AL_HAL_UDMA_IOFIC_REG_H */ + + + + diff --git a/al_hal_udma_main.c b/al_hal_udma_main.c new file mode 100644 index 00000000000..6e9919b3596 --- /dev/null +++ b/al_hal_udma_main.c @@ -0,0 +1,618 @@ +/*- +******************************************************************************* +Copyright (C) 2015 Annapurna Labs Ltd. + +This file may be licensed under the terms of the Annapurna Labs Commercial +License Agreement. + +Alternatively, this file can be distributed under the terms of the GNU General +Public License V2 as published by the Free Software Foundation and can be +found at http://www.gnu.org/licenses/gpl-2.0.html + +Alternatively, redistribution and use in source and binary forms, with or +without modification, are permitted provided that the following conditions are +met: + + * Redistributions of source code must retain the above copyright notice, +this list of conditions and the following disclaimer. + + * Redistributions in binary form must reproduce the above copyright +notice, this list of conditions and the following disclaimer in +the documentation and/or other materials provided with the +distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +*******************************************************************************/ + +/** + * @{ + * @file al_hal_udma_main.c + * + * @brief Universal DMA HAL driver for main functions (initialization, data path) + * + */ + +#include +#include + +#define AL_UDMA_Q_RST_TOUT 10000 /* Queue reset timeout [uSecs] */ + +#define UDMA_STATE_IDLE 0x0 +#define UDMA_STATE_NORMAL 0x1 +#define UDMA_STATE_ABORT 0x2 +#define UDMA_STATE_RESERVED 0x3 + +const char *const al_udma_states_name[] = { + "Disable", + "Idle", + "Normal", + "Abort", + "Reset" +}; + +#define AL_UDMA_INITIAL_RING_ID 1 + +/* dma_q flags */ +#define AL_UDMA_Q_FLAGS_IGNORE_RING_ID AL_BIT(0) +#define AL_UDMA_Q_FLAGS_NO_COMP_UPDATE AL_BIT(1) +#define AL_UDMA_Q_FLAGS_EN_COMP_COAL AL_BIT(2) + + +static void al_udma_set_defaults(struct al_udma *udma) +{ + uint32_t tmp; + uint8_t rev_id = udma->rev_id; + + if (udma->type == UDMA_TX) { + struct unit_regs* tmp_unit_regs = + (struct unit_regs*)udma->udma_regs; + + /* Setting the data fifo depth to 4K (256 strips of 16B) + * This allows the UDMA to have 16 outstanding writes */ + if (rev_id >= AL_UDMA_REV_ID_2) { + al_reg_write32_masked(&tmp_unit_regs->m2s.m2s_rd.data_cfg, + UDMA_M2S_RD_DATA_CFG_DATA_FIFO_DEPTH_MASK, + 256 << UDMA_M2S_RD_DATA_CFG_DATA_FIFO_DEPTH_SHIFT); + } + + if (rev_id == AL_UDMA_REV_ID_0) + /* disable AXI timeout for M0*/ + al_reg_write32(&tmp_unit_regs->gen.axi.cfg_1, 0); + else + /* set AXI timeout to 1M (~2.6 ms) */ + al_reg_write32(&tmp_unit_regs->gen.axi.cfg_1, 1000000); + + al_reg_write32(&tmp_unit_regs->m2s.m2s_comp.cfg_application_ack + , 0); /* Ack time out */ + + + if (rev_id == AL_UDMA_REV_ID_0) { + tmp = al_reg_read32(&udma->udma_regs->m2s.axi_m2s.desc_wr_cfg_1); + tmp &= ~UDMA_AXI_M2S_DESC_WR_CFG_1_MAX_AXI_BEATS_MASK; + tmp |= 4 << UDMA_AXI_M2S_DESC_WR_CFG_1_MAX_AXI_BEATS_SHIFT; + al_reg_write32(&udma->udma_regs->m2s.axi_m2s.desc_wr_cfg_1 + , tmp); + } + + } + if (udma->type == UDMA_RX) { + al_reg_write32( + &udma->udma_regs->s2m.s2m_comp.cfg_application_ack, 0); + /* Ack time out */ + + } +} +/** + * misc queue configurations + * + * @param udma_q udma queue data structure + * + * @return 0 + */ +static int al_udma_q_config(struct al_udma_q *udma_q) +{ + uint32_t *reg_addr; + uint32_t val; + + if (udma_q->udma->type == UDMA_TX) { + reg_addr = &udma_q->q_regs->m2s_q.rlimit.mask; + + val = al_reg_read32(reg_addr); + // enable DMB + val &= ~UDMA_M2S_Q_RATE_LIMIT_MASK_INTERNAL_PAUSE_DMB; + al_reg_write32(reg_addr, val); + } + return 0; +} + +/** + * set the queue's completion configuration register + * + * @param udma_q udma queue data structure + * + * @return 0 + */ +static int al_udma_q_config_compl(struct al_udma_q *udma_q) +{ + uint32_t *reg_addr; + uint32_t val; + + if (udma_q->udma->type == UDMA_TX) + reg_addr = &udma_q->q_regs->m2s_q.comp_cfg; + else + reg_addr = &udma_q->q_regs->s2m_q.comp_cfg; + + val = al_reg_read32(reg_addr); + + if (udma_q->flags & AL_UDMA_Q_FLAGS_NO_COMP_UPDATE) + val &= ~UDMA_M2S_Q_COMP_CFG_EN_COMP_RING_UPDATE; + else + val |= UDMA_M2S_Q_COMP_CFG_EN_COMP_RING_UPDATE; + + if (udma_q->flags & AL_UDMA_Q_FLAGS_EN_COMP_COAL) + val &= ~UDMA_M2S_Q_COMP_CFG_DIS_COMP_COAL; + else + val |= UDMA_M2S_Q_COMP_CFG_DIS_COMP_COAL; + + al_reg_write32(reg_addr, val); + + /* set the completion queue size */ + if (udma_q->udma->type == UDMA_RX) { + val = al_reg_read32( + &udma_q->udma->udma_regs->s2m.s2m_comp.cfg_1c); + val &= ~UDMA_S2M_COMP_CFG_1C_DESC_SIZE_MASK; + /* the register expects it to be in words */ + val |= (udma_q->cdesc_size >> 2) + & UDMA_S2M_COMP_CFG_1C_DESC_SIZE_MASK; + al_reg_write32(&udma_q->udma->udma_regs->s2m.s2m_comp.cfg_1c + , val); + } + return 0; +} + +/** + * reset the queues pointers (Head, Tail, etc) and set the base addresses + * + * @param udma_q udma queue data structure + */ +static int al_udma_q_set_pointers(struct al_udma_q *udma_q) +{ + /* reset the descriptors ring pointers */ + /* assert descriptor base address aligned. */ + al_assert((AL_ADDR_LOW(udma_q->desc_phy_base) & + ~UDMA_M2S_Q_TDRBP_LOW_ADDR_MASK) == 0); + al_reg_write32(&udma_q->q_regs->rings.drbp_low, + AL_ADDR_LOW(udma_q->desc_phy_base)); + al_reg_write32(&udma_q->q_regs->rings.drbp_high, + AL_ADDR_HIGH(udma_q->desc_phy_base)); + + al_reg_write32(&udma_q->q_regs->rings.drl, udma_q->size); + + /* if completion ring update disabled */ + if (udma_q->cdesc_base_ptr == NULL) { + udma_q->flags |= AL_UDMA_Q_FLAGS_NO_COMP_UPDATE; + } else { + /* reset the completion descriptors ring pointers */ + /* assert completion base address aligned. */ + al_assert((AL_ADDR_LOW(udma_q->cdesc_phy_base) & + ~UDMA_M2S_Q_TCRBP_LOW_ADDR_MASK) == 0); + al_reg_write32(&udma_q->q_regs->rings.crbp_low, + AL_ADDR_LOW(udma_q->cdesc_phy_base)); + al_reg_write32(&udma_q->q_regs->rings.crbp_high, + AL_ADDR_HIGH(udma_q->cdesc_phy_base)); + } + al_udma_q_config_compl(udma_q); + return 0; +} + +/** + * enable/disable udma queue + * + * @param udma_q udma queue data structure + * @param enable none zero value enables the queue, zero means disable + * + * @return 0 + */ +static int al_udma_q_enable(struct al_udma_q *udma_q, int enable) +{ + uint32_t reg = al_reg_read32(&udma_q->q_regs->rings.cfg); + + if (enable) { + reg |= (UDMA_M2S_Q_CFG_EN_PREF | UDMA_M2S_Q_CFG_EN_SCHEDULING); + udma_q->status = AL_QUEUE_ENABLED; + } else { + reg &= ~(UDMA_M2S_Q_CFG_EN_PREF | UDMA_M2S_Q_CFG_EN_SCHEDULING); + udma_q->status = AL_QUEUE_DISABLED; + } + al_reg_write32(&udma_q->q_regs->rings.cfg, reg); + return 0; +} + + +/************************ API functions ***************************************/ + +/* Initializations functions */ +/* + * Initialize the udma engine + */ +int al_udma_init(struct al_udma *udma, struct al_udma_params *udma_params) +{ + int i; + + al_assert(udma); + + if (udma_params->num_of_queues > DMA_MAX_Q) { + al_err("udma: invalid num_of_queues parameter\n"); + return -EINVAL; + } + + udma->type = udma_params->type; + udma->num_of_queues = udma_params->num_of_queues; + udma->gen_regs = &udma_params->udma_regs_base->gen; + + if (udma->type == UDMA_TX) + udma->udma_regs = (union udma_regs *)&udma_params->udma_regs_base->m2s; + else + udma->udma_regs = (union udma_regs *)&udma_params->udma_regs_base->s2m; + + udma->rev_id = al_udma_get_revision(udma_params->udma_regs_base); + + if (udma_params->name == NULL) + udma->name = ""; + else + udma->name = udma_params->name; + + udma->state = UDMA_DISABLE; + for (i = 0; i < DMA_MAX_Q; i++) { + udma->udma_q[i].status = AL_QUEUE_NOT_INITIALIZED; + } + /* initialize configuration registers to correct values */ + al_udma_set_defaults(udma); + al_dbg("udma [%s] initialized. base %p\n", udma->name, + udma->udma_regs); + return 0; +} + +/* + * Initialize the udma queue data structure + */ +int al_udma_q_init(struct al_udma *udma, uint32_t qid, + struct al_udma_q_params *q_params) +{ + struct al_udma_q *udma_q; + + al_assert(udma); + al_assert(q_params); + + if (qid >= udma->num_of_queues) { + al_err("udma: invalid queue id (%d)\n", qid); + return -EINVAL; + } + + if (udma->udma_q[qid].status == AL_QUEUE_ENABLED) { + al_err("udma: queue (%d) already enabled!\n", qid); + return -EIO; + } + + if (q_params->size < AL_UDMA_MIN_Q_SIZE) { + al_err("udma: queue (%d) size too small\n", qid); + return -EINVAL; + } + + if (q_params->size > AL_UDMA_MAX_Q_SIZE) { + al_err("udma: queue (%d) size too large\n", qid); + return -EINVAL; + } + + if (q_params->size & (q_params->size - 1)) { + al_err("udma: queue (%d) size (%d) must be power of 2\n", + q_params->size, qid); + return -EINVAL; + } + + udma_q = &udma->udma_q[qid]; + /* set the queue's regs base address */ + if (udma->type == UDMA_TX) + udma_q->q_regs = (union udma_q_regs __iomem *) + &udma->udma_regs->m2s.m2s_q[qid]; + else + udma_q->q_regs = (union udma_q_regs __iomem *) + &udma->udma_regs->s2m.s2m_q[qid]; + + udma_q->adapter_rev_id = q_params->adapter_rev_id; + udma_q->size = q_params->size; + udma_q->size_mask = q_params->size - 1; + udma_q->desc_base_ptr = q_params->desc_base; + udma_q->desc_phy_base = q_params->desc_phy_base; + udma_q->cdesc_base_ptr = q_params->cdesc_base; + udma_q->cdesc_phy_base = q_params->cdesc_phy_base; + udma_q->cdesc_size = q_params->cdesc_size; + + udma_q->next_desc_idx = 0; + udma_q->next_cdesc_idx = 0; + udma_q->end_cdesc_ptr = (uint8_t *) udma_q->cdesc_base_ptr + + (udma_q->size - 1) * udma_q->cdesc_size; + udma_q->comp_head_idx = 0; + udma_q->comp_head_ptr = (union al_udma_cdesc *)udma_q->cdesc_base_ptr; + udma_q->desc_ring_id = AL_UDMA_INITIAL_RING_ID; + udma_q->comp_ring_id = AL_UDMA_INITIAL_RING_ID; +#if 0 + udma_q->desc_ctrl_bits = AL_UDMA_INITIAL_RING_ID << + AL_M2S_DESC_RING_ID_SHIFT; +#endif + udma_q->pkt_crnt_descs = 0; + udma_q->flags = 0; + udma_q->status = AL_QUEUE_DISABLED; + udma_q->udma = udma; + udma_q->qid = qid; + + /* start hardware configuration: */ + al_udma_q_config(udma_q); + /* reset the queue pointers */ + al_udma_q_set_pointers(udma_q); + + /* enable the q */ + al_udma_q_enable(udma_q, 1); + + al_dbg("udma [%s %d]: %s q init. size 0x%x\n" + " desc ring info: phys base 0x%llx virt base %p\n" + " cdesc ring info: phys base 0x%llx virt base %p " + "entry size 0x%x", + udma_q->udma->name, udma_q->qid, + udma->type == UDMA_TX ? "Tx" : "Rx", + q_params->size, + (unsigned long long)q_params->desc_phy_base, + q_params->desc_base, + (unsigned long long)q_params->cdesc_phy_base, + q_params->cdesc_base, + q_params->cdesc_size); + + return 0; +} + +/* + * Reset a udma queue + */ +int al_udma_q_reset(struct al_udma_q *udma_q) +{ + unsigned int remaining_time = AL_UDMA_Q_RST_TOUT; + uint32_t *status_reg; + uint32_t *dcp_reg; + uint32_t *crhp_reg; + uint32_t *q_sw_ctrl_reg; + + al_assert(udma_q); + + /* De-assert scheduling and prefetch */ + al_udma_q_enable(udma_q, 0); + + /* Wait for scheduling and prefetch to stop */ + status_reg = &udma_q->q_regs->rings.status; + + while (remaining_time) { + uint32_t status = al_reg_read32(status_reg); + + if (!(status & (UDMA_M2S_Q_STATUS_PREFETCH | + UDMA_M2S_Q_STATUS_SCHEDULER))) + break; + + remaining_time--; + al_udelay(1); + } + + if (!remaining_time) { + al_err("udma [%s %d]: %s timeout waiting for prefetch and " + "scheduler disable\n", udma_q->udma->name, udma_q->qid, + __func__); + return -ETIMEDOUT; + } + + /* Wait for the completion queue to reach to the same pointer as the + * prefetch stopped at ([TR]DCP == [TR]CRHP) */ + dcp_reg = &udma_q->q_regs->rings.dcp; + crhp_reg = &udma_q->q_regs->rings.crhp; + + while (remaining_time) { + uint32_t dcp = al_reg_read32(dcp_reg); + uint32_t crhp = al_reg_read32(crhp_reg); + + if (dcp == crhp) + break; + + remaining_time--; + al_udelay(1); + }; + + if (!remaining_time) { + al_err("udma [%s %d]: %s timeout waiting for dcp==crhp\n", + udma_q->udma->name, udma_q->qid, __func__); + return -ETIMEDOUT; + } + + /* Assert the queue reset */ + if (udma_q->udma->type == UDMA_TX) + q_sw_ctrl_reg = &udma_q->q_regs->m2s_q.q_sw_ctrl; + else + q_sw_ctrl_reg = &udma_q->q_regs->s2m_q.q_sw_ctrl; + + al_reg_write32(q_sw_ctrl_reg, UDMA_M2S_Q_SW_CTRL_RST_Q); + + return 0; +} + +/* + * return (by reference) a pointer to a specific queue date structure. + */ +int al_udma_q_handle_get(struct al_udma *udma, uint32_t qid, + struct al_udma_q **q_handle) +{ + + al_assert(udma); + al_assert(q_handle); + + if (unlikely(qid >= udma->num_of_queues)) { + al_err("udma [%s]: invalid queue id (%d)\n", udma->name, qid); + return -EINVAL; + } + *q_handle = &udma->udma_q[qid]; + return 0; +} + +/* + * Change the UDMA's state + */ +int al_udma_state_set(struct al_udma *udma, enum al_udma_state state) +{ + uint32_t reg; + + al_assert(udma != NULL); + if (state == udma->state) + al_dbg("udma [%s]: requested state identical to " + "current state (%d)\n", udma->name, state); + + al_dbg("udma [%s]: change state from (%s) to (%s)\n", + udma->name, al_udma_states_name[udma->state], + al_udma_states_name[state]); + + reg = 0; + switch (state) { + case UDMA_DISABLE: + reg |= UDMA_M2S_CHANGE_STATE_DIS; + break; + case UDMA_NORMAL: + reg |= UDMA_M2S_CHANGE_STATE_NORMAL; + break; + case UDMA_ABORT: + reg |= UDMA_M2S_CHANGE_STATE_ABORT; + break; + default: + al_err("udma: invalid state (%d)\n", state); + return -EINVAL; + } + + if (udma->type == UDMA_TX) + al_reg_write32(&udma->udma_regs->m2s.m2s.change_state, reg); + else + al_reg_write32(&udma->udma_regs->s2m.s2m.change_state, reg); + + udma->state = state; + return 0; +} + +/* + * return the current UDMA hardware state + */ +enum al_udma_state al_udma_state_get(struct al_udma *udma) +{ + uint32_t state_reg; + uint32_t comp_ctrl; + uint32_t stream_if; + uint32_t data_rd; + uint32_t desc_pref; + + if (udma->type == UDMA_TX) + state_reg = al_reg_read32(&udma->udma_regs->m2s.m2s.state); + else + state_reg = al_reg_read32(&udma->udma_regs->s2m.s2m.state); + + comp_ctrl = AL_REG_FIELD_GET(state_reg, + UDMA_M2S_STATE_COMP_CTRL_MASK, + UDMA_M2S_STATE_COMP_CTRL_SHIFT); + stream_if = AL_REG_FIELD_GET(state_reg, + UDMA_M2S_STATE_STREAM_IF_MASK, + UDMA_M2S_STATE_STREAM_IF_SHIFT); + data_rd = AL_REG_FIELD_GET(state_reg, + UDMA_M2S_STATE_DATA_RD_CTRL_MASK, + UDMA_M2S_STATE_DATA_RD_CTRL_SHIFT); + desc_pref = AL_REG_FIELD_GET(state_reg, + UDMA_M2S_STATE_DESC_PREF_MASK, + UDMA_M2S_STATE_DESC_PREF_SHIFT); + + al_assert(comp_ctrl != UDMA_STATE_RESERVED); + al_assert(stream_if != UDMA_STATE_RESERVED); + al_assert(data_rd != UDMA_STATE_RESERVED); + al_assert(desc_pref != UDMA_STATE_RESERVED); + + /* if any of the states is abort then return abort */ + if ((comp_ctrl == UDMA_STATE_ABORT) || (stream_if == UDMA_STATE_ABORT) + || (data_rd == UDMA_STATE_ABORT) + || (desc_pref == UDMA_STATE_ABORT)) + return UDMA_ABORT; + + /* if any of the states is normal then return normal */ + if ((comp_ctrl == UDMA_STATE_NORMAL) + || (stream_if == UDMA_STATE_NORMAL) + || (data_rd == UDMA_STATE_NORMAL) + || (desc_pref == UDMA_STATE_NORMAL)) + return UDMA_NORMAL; + + return UDMA_IDLE; +} + +/* + * Action handling + */ + +/* + * get next completed packet from completion ring of the queue + */ +uint32_t al_udma_cdesc_packet_get( + struct al_udma_q *udma_q, + volatile union al_udma_cdesc **cdesc) +{ + uint32_t count; + volatile union al_udma_cdesc *curr; + uint32_t comp_flags; + + /* this function requires the completion ring update */ + al_assert(!(udma_q->flags & AL_UDMA_Q_FLAGS_NO_COMP_UPDATE)); + + /* comp_head points to the last comp desc that was processed */ + curr = udma_q->comp_head_ptr; + comp_flags = swap32_from_le(curr->al_desc_comp_tx.ctrl_meta); + + /* check if the completion descriptor is new */ + if (unlikely(al_udma_new_cdesc(udma_q, comp_flags) == AL_FALSE)) + return 0; + /* if new desc found, increment the current packets descriptors */ + count = udma_q->pkt_crnt_descs + 1; + while (!cdesc_is_last(comp_flags)) { + curr = al_cdesc_next_update(udma_q, curr); + comp_flags = swap32_from_le(curr->al_desc_comp_tx.ctrl_meta); + if (unlikely(al_udma_new_cdesc(udma_q, comp_flags) + == AL_FALSE)) { + /* the current packet here doesn't have all */ + /* descriptors completed. log the current desc */ + /* location and number of completed descriptors so */ + /* far. then return */ + udma_q->pkt_crnt_descs = count; + udma_q->comp_head_ptr = curr; + return 0; + } + count++; + /* check against max descs per packet. */ + al_assert(count <= udma_q->size); + } + /* return back the first descriptor of the packet */ + *cdesc = al_udma_cdesc_idx_to_ptr(udma_q, udma_q->next_cdesc_idx); + udma_q->pkt_crnt_descs = 0; + udma_q->comp_head_ptr = al_cdesc_next_update(udma_q, curr); + + al_dbg("udma [%s %d]: packet completed. first desc %p (ixd 0x%x)" + " descs %d\n", udma_q->udma->name, udma_q->qid, *cdesc, + udma_q->next_cdesc_idx, count); + + return count; +} + +/** @} end of UDMA group */ diff --git a/al_hal_udma_regs.h b/al_hal_udma_regs.h new file mode 100644 index 00000000000..ed37215ae44 --- /dev/null +++ b/al_hal_udma_regs.h @@ -0,0 +1,104 @@ +/*- +******************************************************************************* +Copyright (C) 2015 Annapurna Labs Ltd. + +This file may be licensed under the terms of the Annapurna Labs Commercial +License Agreement. + +Alternatively, this file can be distributed under the terms of the GNU General +Public License V2 as published by the Free Software Foundation and can be +found at http://www.gnu.org/licenses/gpl-2.0.html + +Alternatively, redistribution and use in source and binary forms, with or +without modification, are permitted provided that the following conditions are +met: + + * Redistributions of source code must retain the above copyright notice, +this list of conditions and the following disclaimer. + + * Redistributions in binary form must reproduce the above copyright +notice, this list of conditions and the following disclaimer in +the documentation and/or other materials provided with the +distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +*******************************************************************************/ + +/** + * @{ + * @file al_hal_udma_regs.h + * + * @brief udma registers definition + * + * + */ +#ifndef __AL_HAL_UDMA_REG_H +#define __AL_HAL_UDMA_REG_H + +#include "al_hal_udma_regs_m2s.h" +#include "al_hal_udma_regs_s2m.h" +#include "al_hal_udma_regs_gen.h" + +#define AL_UDMA_REV_ID_REV0 0 +#define AL_UDMA_REV_ID_REV1 1 +#define AL_UDMA_REV_ID_REV2 2 + +#ifdef __cplusplus +extern "C" { +#endif + +/** UDMA registers, either m2s or s2m */ +union udma_regs { + struct udma_m2s_regs m2s; + struct udma_s2m_regs s2m; +}; + +struct unit_regs { + struct udma_m2s_regs m2s; + uint32_t rsrvd0[(0x10000 - sizeof(struct udma_m2s_regs)) >> 2]; + struct udma_s2m_regs s2m; + uint32_t rsrvd1[((0x1C000 - 0x10000) - sizeof(struct udma_s2m_regs)) >> 2]; + struct udma_gen_regs gen; +}; + +/** UDMA submission and completion registers, M2S and S2M UDMAs have same stucture */ +struct udma_rings_regs { + uint32_t rsrvd0[8]; + uint32_t cfg; /* Descriptor ring configuration */ + uint32_t status; /* Descriptor ring status and information */ + uint32_t drbp_low; /* Descriptor Ring Base Pointer [31:4] */ + uint32_t drbp_high; /* Descriptor Ring Base Pointer [63:32] */ + uint32_t drl; /* Descriptor Ring Length[23:2] */ + uint32_t drhp; /* Descriptor Ring Head Pointer */ + uint32_t drtp_inc; /* Descriptor Tail Pointer increment */ + uint32_t drtp; /* Descriptor Tail Pointer */ + uint32_t dcp; /* Descriptor Current Pointer */ + uint32_t crbp_low; /* Completion Ring Base Pointer [31:4] */ + uint32_t crbp_high; /* Completion Ring Base Pointer [63:32] */ + uint32_t crhp; /* Completion Ring Head Pointer */ + uint32_t crhp_internal; /* Completion Ring Head Pointer internal, before AX ... */ +}; + +/** M2S and S2M generic structure of Q registers */ +union udma_q_regs { + struct udma_rings_regs rings; + struct udma_m2s_q m2s_q; + struct udma_s2m_q s2m_q; +}; + +#ifdef __cplusplus +} +#endif + +#endif /* __AL_HAL_UDMA_REG_H */ +/** @} end of UDMA group */ diff --git a/al_hal_udma_regs_gen.h b/al_hal_udma_regs_gen.h new file mode 100644 index 00000000000..89f94b85a56 --- /dev/null +++ b/al_hal_udma_regs_gen.h @@ -0,0 +1,414 @@ +/*- +******************************************************************************* +Copyright (C) 2015 Annapurna Labs Ltd. + +This file may be licensed under the terms of the Annapurna Labs Commercial +License Agreement. + +Alternatively, this file can be distributed under the terms of the GNU General +Public License V2 as published by the Free Software Foundation and can be +found at http://www.gnu.org/licenses/gpl-2.0.html + +Alternatively, redistribution and use in source and binary forms, with or +without modification, are permitted provided that the following conditions are +met: + + * Redistributions of source code must retain the above copyright notice, +this list of conditions and the following disclaimer. + + * Redistributions in binary form must reproduce the above copyright +notice, this list of conditions and the following disclaimer in +the documentation and/or other materials provided with the +distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +*******************************************************************************/ + +/** + * @file al_hal_udma_regs_gen.h + * + * @brief C Header file for the UDMA general registers + * + */ + +#ifndef __AL_HAL_UDMA_GEN_REG_H +#define __AL_HAL_UDMA_GEN_REG_H + +#include "al_hal_udma_iofic_regs.h" + +#ifdef __cplusplus +extern "C" { +#endif +/* +* Unit Registers +*/ + + + +struct udma_gen_dma_misc { + /* [0x0] Reserved register for the interrupt controller */ + uint32_t int_cfg; + /* [0x4] Revision register */ + uint32_t revision; + /* [0x8] Reserved for future use */ + uint32_t general_cfg_1; + /* [0xc] Reserved for future use */ + uint32_t general_cfg_2; + /* [0x10] Reserved for future use */ + uint32_t general_cfg_3; + /* [0x14] Reserved for future use */ + uint32_t general_cfg_4; + /* [0x18] General timer configuration */ + uint32_t general_cfg_5; + uint32_t rsrvd[57]; +}; +struct udma_gen_mailbox { + /* + * [0x0] Mailbox interrupt generator. + * Generates interrupt to neighbor DMA + */ + uint32_t interrupt; + /* [0x4] Mailbox message data out */ + uint32_t msg_out; + /* [0x8] Mailbox message data in */ + uint32_t msg_in; + uint32_t rsrvd[13]; +}; +struct udma_gen_axi { + /* [0x0] Configuration of the AXI masters */ + uint32_t cfg_1; + /* [0x4] Configuration of the AXI masters */ + uint32_t cfg_2; + /* [0x8] Configuration of the AXI masters. Endianess configuration */ + uint32_t endian_cfg; + uint32_t rsrvd[61]; +}; +struct udma_gen_sram_ctrl { + /* [0x0] Timing configuration */ + uint32_t timing; +}; +struct udma_gen_vmid { + /* [0x0] VMID control */ + uint32_t cfg_vmid_0; + /* [0x4] TX queue 0/1 VMID */ + uint32_t cfg_vmid_1; + /* [0x8] TX queue 2/3 VMID */ + uint32_t cfg_vmid_2; + /* [0xc] RX queue 0/1 VMID */ + uint32_t cfg_vmid_3; + /* [0x10] RX queue 2/3 VMID */ + uint32_t cfg_vmid_4; +}; +struct udma_gen_vmaddr { + /* [0x0] TX queue 0/1 VMADDR */ + uint32_t cfg_vmaddr_0; + /* [0x4] TX queue 2/3 VMADDR */ + uint32_t cfg_vmaddr_1; + /* [0x8] RX queue 0/1 VMADDR */ + uint32_t cfg_vmaddr_2; + /* [0xc] RX queue 2/3 VMADDR */ + uint32_t cfg_vmaddr_3; +}; +struct udma_gen_vmpr { + /* [0x0] TX VMPR control */ + uint32_t cfg_vmpr_0; + /* [0x4] TX VMPR Address High Regsiter */ + uint32_t cfg_vmpr_1; + /* [0x8] TX queue VMID values */ + uint32_t cfg_vmpr_2; + /* [0xc] TX queue VMID values */ + uint32_t cfg_vmpr_3; + /* [0x10] RX VMPR control */ + uint32_t cfg_vmpr_4; + /* [0x14] RX VMPR Buffer2 MSB address */ + uint32_t cfg_vmpr_5; + /* [0x18] RX queue VMID values */ + uint32_t cfg_vmpr_6; + /* [0x1c] RX queue BUF1 VMID values */ + uint32_t cfg_vmpr_7; + /* [0x20] RX queue BUF2 VMID values */ + uint32_t cfg_vmpr_8; + /* [0x24] RX queue Direct Data Placement VMID values */ + uint32_t cfg_vmpr_9; + /* [0x28] RX VMPR BUF1 Address High Regsiter */ + uint32_t cfg_vmpr_10; + /* [0x2c] RX VMPR BUF2 Address High Regsiter */ + uint32_t cfg_vmpr_11; + /* [0x30] RX VMPR DDP Address High Regsiter */ + uint32_t cfg_vmpr_12; + uint32_t rsrvd[3]; +}; + +struct udma_gen_regs { + struct udma_iofic_regs interrupt_regs; /* [0x0000] */ + struct udma_gen_dma_misc dma_misc; /* [0x2080] */ + struct udma_gen_mailbox mailbox[4]; /* [0x2180] */ + struct udma_gen_axi axi; /* [0x2280] */ + struct udma_gen_sram_ctrl sram_ctrl[25]; /* [0x2380] */ + uint32_t rsrvd_1[2]; + struct udma_gen_vmid vmid; /* [0x23ec] */ + struct udma_gen_vmaddr vmaddr; /* [0x2400] */ + uint32_t rsrvd_2[252]; + struct udma_gen_vmpr vmpr[4]; /* [0x2800] */ +}; + + +/* +* Registers Fields +*/ + + +/**** int_cfg register ****/ +/* + * MSIX data width + * 1 - 64 bit + * 0 – 32 bit + */ +#define UDMA_GEN_DMA_MISC_INT_CFG_MSIX_64 (1 << 0) +/* General configuration */ +#define UDMA_GEN_DMA_MISC_INT_CFG_RESERVED_3_1_MASK 0x0000000E +#define UDMA_GEN_DMA_MISC_INT_CFG_RESERVED_3_1_SHIFT 1 +/* MSIx AXI QoS */ +#define UDMA_GEN_DMA_MISC_INT_CFG_MSIX_AXI_QOS_MASK 0x00000070 +#define UDMA_GEN_DMA_MISC_INT_CFG_MSIX_AXI_QOS_SHIFT 4 + +#define UDMA_GEN_DMA_MISC_INT_CFG_RESERVED_31_7_MASK 0xFFFFFF80 +#define UDMA_GEN_DMA_MISC_INT_CFG_RESERVED_31_7_SHIFT 7 + +/**** revision register ****/ +/* Design programming interface revision ID */ +#define UDMA_GEN_DMA_MISC_REVISION_PROGRAMMING_ID_MASK 0x00000FFF +#define UDMA_GEN_DMA_MISC_REVISION_PROGRAMMING_ID_SHIFT 0 +/* Design minor revision ID */ +#define UDMA_GEN_DMA_MISC_REVISION_MINOR_ID_MASK 0x00FFF000 +#define UDMA_GEN_DMA_MISC_REVISION_MINOR_ID_SHIFT 12 +/* Design major revision ID */ +#define UDMA_GEN_DMA_MISC_REVISION_MAJOR_ID_MASK 0xFF000000 +#define UDMA_GEN_DMA_MISC_REVISION_MAJOR_ID_SHIFT 24 + +/**** Interrupt register ****/ +/* Generate interrupt to another DMA */ +#define UDMA_GEN_MAILBOX_INTERRUPT_SET (1 << 0) + +/**** cfg_2 register ****/ +/* + * Enable arbitration promotion. + * Increment master priority after configured number of arbitration cycles + */ +#define UDMA_GEN_AXI_CFG_2_ARB_PROMOTION_MASK 0x0000000F +#define UDMA_GEN_AXI_CFG_2_ARB_PROMOTION_SHIFT 0 + +/**** endian_cfg register ****/ +/* Swap M2S descriptor read and completion descriptor write. */ +#define UDMA_GEN_AXI_ENDIAN_CFG_SWAP_M2S_DESC (1 << 0) +/* Swap M2S data read. */ +#define UDMA_GEN_AXI_ENDIAN_CFG_SWAP_M2S_DATA (1 << 1) +/* Swap S2M descriptor read and completion descriptor write. */ +#define UDMA_GEN_AXI_ENDIAN_CFG_SWAP_S2M_DESC (1 << 2) +/* Swap S2M data write. */ +#define UDMA_GEN_AXI_ENDIAN_CFG_SWAP_S2M_DATA (1 << 3) +/* + * Swap 32 or 64 bit mode: + * 0 - Swap groups of 4 bytes + * 1 - Swap groups of 8 bytes + */ +#define UDMA_GEN_AXI_ENDIAN_CFG_SWAP_64B_EN (1 << 4) + +/**** timing register ****/ +/* Write margin */ +#define UDMA_GEN_SRAM_CTRL_TIMING_RMA_MASK 0x0000000F +#define UDMA_GEN_SRAM_CTRL_TIMING_RMA_SHIFT 0 +/* Write margin enable */ +#define UDMA_GEN_SRAM_CTRL_TIMING_RMEA (1 << 8) +/* Read margin */ +#define UDMA_GEN_SRAM_CTRL_TIMING_RMB_MASK 0x000F0000 +#define UDMA_GEN_SRAM_CTRL_TIMING_RMB_SHIFT 16 +/* Read margin enable */ +#define UDMA_GEN_SRAM_CTRL_TIMING_RMEB (1 << 24) + +/**** cfg_vmid_0 register ****/ +/* For M2S queues 3:0, enable usage of the VMID from the buffer address 63:56 */ +#define UDMA_GEN_VMID_CFG_VMID_0_TX_Q_VMID_DESC_EN_MASK 0x0000000F +#define UDMA_GEN_VMID_CFG_VMID_0_TX_Q_VMID_DESC_EN_SHIFT 0 +/* + * For M2S queues 3:0, enable usage of the VMID from the configuration register + * (cfg_vmid_1/2 used for M2S queue_x) + */ +#define UDMA_GEN_VMID_CFG_VMID_0_TX_Q_VMID_QUEUE_EN_MASK 0x000000F0 +#define UDMA_GEN_VMID_CFG_VMID_0_TX_Q_VMID_QUEUE_EN_SHIFT 4 +/* use VMID_n [7:0] from MSI-X Controller for MSI-X message */ +#define UDMA_GEN_VMID_CFG_VMID_0_MSIX_VMID_SEL (1 << 8) +/* Enable write to all VMID_n registers in the MSI-X Controller */ +#define UDMA_GEN_VMID_CFG_VMID_0_MSIX_VMID_ACCESS_EN (1 << 9) +/* For S2M queues 3:0, enable usage of the VMID from the buffer address 63:56 */ +#define UDMA_GEN_VMID_CFG_VMID_0_RX_Q_VMID_DESC_EN_MASK 0x000F0000 +#define UDMA_GEN_VMID_CFG_VMID_0_RX_Q_VMID_DESC_EN_SHIFT 16 +/* + * For S2M queues 3:0, enable usage of the VMID from the configuration register + * (cfg_vmid_3/4 used for M2S queue_x) + */ +#define UDMA_GEN_VMID_CFG_VMID_0_RX_Q_VMID_QUEUE_EN_MASK 0x00F00000 +#define UDMA_GEN_VMID_CFG_VMID_0_RX_Q_VMID_QUEUE_EN_SHIFT 20 + +/**** cfg_vmid_1 register ****/ +/* TX queue 0 VMID value */ +#define UDMA_GEN_VMID_CFG_VMID_1_TX_Q_0_VMID_MASK 0x0000FFFF +#define UDMA_GEN_VMID_CFG_VMID_1_TX_Q_0_VMID_SHIFT 0 +/* TX queue 1 VMID value */ +#define UDMA_GEN_VMID_CFG_VMID_1_TX_Q_1_VMID_MASK 0xFFFF0000 +#define UDMA_GEN_VMID_CFG_VMID_1_TX_Q_1_VMID_SHIFT 16 + +/**** cfg_vmid_2 register ****/ +/* TX queue 2 VMID value */ +#define UDMA_GEN_VMID_CFG_VMID_2_TX_Q_2_VMID_MASK 0x0000FFFF +#define UDMA_GEN_VMID_CFG_VMID_2_TX_Q_2_VMID_SHIFT 0 +/* TX queue 3 VMID value */ +#define UDMA_GEN_VMID_CFG_VMID_2_TX_Q_3_VMID_MASK 0xFFFF0000 +#define UDMA_GEN_VMID_CFG_VMID_2_TX_Q_3_VMID_SHIFT 16 + +/**** cfg_vmid_3 register ****/ +/* RX queue 0 VMID value */ +#define UDMA_GEN_VMID_CFG_VMID_3_RX_Q_0_VMID_MASK 0x0000FFFF +#define UDMA_GEN_VMID_CFG_VMID_3_RX_Q_0_VMID_SHIFT 0 +/* RX queue 1 VMID value */ +#define UDMA_GEN_VMID_CFG_VMID_3_RX_Q_1_VMID_MASK 0xFFFF0000 +#define UDMA_GEN_VMID_CFG_VMID_3_RX_Q_1_VMID_SHIFT 16 + +/**** cfg_vmid_4 register ****/ +/* RX queue 2 VMID value */ +#define UDMA_GEN_VMID_CFG_VMID_4_RX_Q_2_VMID_MASK 0x0000FFFF +#define UDMA_GEN_VMID_CFG_VMID_4_RX_Q_2_VMID_SHIFT 0 +/* RX queue 3 VMID value */ +#define UDMA_GEN_VMID_CFG_VMID_4_RX_Q_3_VMID_MASK 0xFFFF0000 +#define UDMA_GEN_VMID_CFG_VMID_4_RX_Q_3_VMID_SHIFT 16 + +/**** cfg_vmaddr_0 register ****/ +/* TX queue 0 VMADDR value */ +#define UDMA_GEN_VMADDR_CFG_VMADDR_0_TX_Q_0_VMADDR_MASK 0x0000FFFF +#define UDMA_GEN_VMADDR_CFG_VMADDR_0_TX_Q_0_VMADDR_SHIFT 0 +/* TX queue 1 VMADDR value */ +#define UDMA_GEN_VMADDR_CFG_VMADDR_0_TX_Q_1_VMADDR_MASK 0xFFFF0000 +#define UDMA_GEN_VMADDR_CFG_VMADDR_0_TX_Q_1_VMADDR_SHIFT 16 + +/**** cfg_vmaddr_1 register ****/ +/* TX queue 2 VMADDR value */ +#define UDMA_GEN_VMADDR_CFG_VMADDR_1_TX_Q_2_VMADDR_MASK 0x0000FFFF +#define UDMA_GEN_VMADDR_CFG_VMADDR_1_TX_Q_2_VMADDR_SHIFT 0 +/* TX queue 3 VMADDR value */ +#define UDMA_GEN_VMADDR_CFG_VMADDR_1_TX_Q_3_VMADDR_MASK 0xFFFF0000 +#define UDMA_GEN_VMADDR_CFG_VMADDR_1_TX_Q_3_VMADDR_SHIFT 16 + +/**** cfg_vmaddr_2 register ****/ +/* RX queue 0 VMADDR value */ +#define UDMA_GEN_VMADDR_CFG_VMADDR_2_RX_Q_0_VMADDR_MASK 0x0000FFFF +#define UDMA_GEN_VMADDR_CFG_VMADDR_2_RX_Q_0_VMADDR_SHIFT 0 +/* RX queue 1 VMADDR value */ +#define UDMA_GEN_VMADDR_CFG_VMADDR_2_RX_Q_1_VMADDR_MASK 0xFFFF0000 +#define UDMA_GEN_VMADDR_CFG_VMADDR_2_RX_Q_1_VMADDR_SHIFT 16 + +/**** cfg_vmaddr_3 register ****/ +/* RX queue 2 VMADDR value */ +#define UDMA_GEN_VMADDR_CFG_VMADDR_3_RX_Q_2_VMADDR_MASK 0x0000FFFF +#define UDMA_GEN_VMADDR_CFG_VMADDR_3_RX_Q_2_VMADDR_SHIFT 0 +/* RX queue 3 VMADDR value */ +#define UDMA_GEN_VMADDR_CFG_VMADDR_3_RX_Q_3_VMADDR_MASK 0xFFFF0000 +#define UDMA_GEN_VMADDR_CFG_VMADDR_3_RX_Q_3_VMADDR_SHIFT 16 + +/**** cfg_vmpr_0 register ****/ +/* TX High Address Select Per Q */ +#define UDMA_GEN_VMPR_CFG_VMPR_0_TX_Q_HISEL_MASK 0x0000003F +#define UDMA_GEN_VMPR_CFG_VMPR_0_TX_Q_HISEL_SHIFT 0 +/* TX Data VMID Enable Per Q */ +#define UDMA_GEN_VMPR_CFG_VMPR_0_TX_Q_DATA_VMID_EN (1 << 7) +/* TX Prefetch VMID Enable Per Q */ +#define UDMA_GEN_VMPR_CFG_VMPR_0_TX_Q_PREF_VMID_EN (1 << 28) +/* TX Completions VMID Enable Per Q */ +#define UDMA_GEN_VMPR_CFG_VMPR_0_TX_Q_CMPL_VMID_EN (1 << 29) + +/**** cfg_vmpr_2 register ****/ +/* TX queue Prefetch VMID */ +#define UDMA_GEN_VMPR_CFG_VMPR_2_TX_Q_PREF_VMID_MASK 0x0000FFFF +#define UDMA_GEN_VMPR_CFG_VMPR_2_TX_Q_PREF_VMID_SHIFT 0 +/* TX queue Completion VMID */ +#define UDMA_GEN_VMPR_CFG_VMPR_2_TX_Q_CMPL_VMID_MASK 0xFFFF0000 +#define UDMA_GEN_VMPR_CFG_VMPR_2_TX_Q_CMPL_VMID_SHIFT 16 + +/**** cfg_vmpr_3 register ****/ +/* TX queue Data VMID */ +#define UDMA_GEN_VMPR_CFG_VMPR_3_TX_Q_DATA_VMID_MASK 0x0000FFFF +#define UDMA_GEN_VMPR_CFG_VMPR_3_TX_Q_DATA_VMID_SHIFT 0 +/* TX queue Data VMID select */ +#define UDMA_GEN_VMPR_CFG_VMPR_3_TX_Q_DATA_VMID_SEL_MASK 0xFFFF0000 +#define UDMA_GEN_VMPR_CFG_VMPR_3_TX_Q_DATA_VMID_SEL_SHIFT 16 + +/**** cfg_vmpr_4 register ****/ +/* RX Data Buffer1 - High Address Select Per Q */ +#define UDMA_GEN_VMPR_CFG_VMPR_4_RX_Q_BUF1_HISEL_MASK 0x0000003F +#define UDMA_GEN_VMPR_CFG_VMPR_4_RX_Q_BUF1_HISEL_SHIFT 0 +/* RX Data Buffer1 VMID Enable Per Q */ +#define UDMA_GEN_VMPR_CFG_VMPR_4_RX_Q_BUF1_VMID_EN (1 << 7) +/* RX Data Buffer2 - High Address Select Per Q */ +#define UDMA_GEN_VMPR_CFG_VMPR_4_RX_Q_BUF2_HISEL_MASK 0x00003F00 +#define UDMA_GEN_VMPR_CFG_VMPR_4_RX_Q_BUF2_HISEL_SHIFT 8 +/* RX Data Buffer2 VMID Enable Per Q */ +#define UDMA_GEN_VMPR_CFG_VMPR_4_RX_Q_BUF2_VMID_EN (1 << 15) +/* RX Direct Data Placement - High Address Select Per Q */ +#define UDMA_GEN_VMPR_CFG_VMPR_4_RX_Q_DDP_HISEL_MASK 0x003F0000 +#define UDMA_GEN_VMPR_CFG_VMPR_4_RX_Q_DDP_HISEL_SHIFT 16 +/* RX Direct Data Placement VMID Enable Per Q */ +#define UDMA_GEN_VMPR_CFG_VMPR_4_RX_Q_DDP_VMID_EN (1 << 23) +/* RX Buffer 2 MSB address word selects per bytes, per queue */ +#define UDMA_GEN_VMPR_CFG_VMPR_4_RX_Q_BUF2_MSB_ADDR_SEL_MASK 0x0F000000 +#define UDMA_GEN_VMPR_CFG_VMPR_4_RX_Q_BUF2_MSB_ADDR_SEL_SHIFT 24 +/* RX Prefetch VMID Enable Per Q */ +#define UDMA_GEN_VMPR_CFG_VMPR_4_RX_Q_PREF_VMID_EN (1 << 28) +/* RX Completions VMID Enable Per Q */ +#define UDMA_GEN_VMPR_CFG_VMPR_4_RX_Q_CMPL_VMID_EN (1 << 29) + +/**** cfg_vmpr_6 register ****/ +/* RX queue Prefetch VMID */ +#define UDMA_GEN_VMPR_CFG_VMPR_6_RX_Q_PREF_VMID_MASK 0x0000FFFF +#define UDMA_GEN_VMPR_CFG_VMPR_6_RX_Q_PREF_VMID_SHIFT 0 +/* RX queue Completion VMID */ +#define UDMA_GEN_VMPR_CFG_VMPR_6_RX_Q_CMPL_VMID_MASK 0xFFFF0000 +#define UDMA_GEN_VMPR_CFG_VMPR_6_RX_Q_CMPL_VMID_SHIFT 16 + +/**** cfg_vmpr_7 register ****/ +/* RX queue Data Buffer 1 VMID */ +#define UDMA_GEN_VMPR_CFG_VMPR_7_RX_Q_BUF1_VMID_MASK 0x0000FFFF +#define UDMA_GEN_VMPR_CFG_VMPR_7_RX_Q_BUF1_VMID_SHIFT 0 +/* RX queue Data Buffer 1 VMID select */ +#define UDMA_GEN_VMPR_CFG_VMPR_7_RX_Q_BUF1_VMID_SEL_MASK 0xFFFF0000 +#define UDMA_GEN_VMPR_CFG_VMPR_7_RX_Q_BUF1_VMID_SEL_SHIFT 16 + +/**** cfg_vmpr_8 register ****/ +/* RX queue Data Buffer 2 VMID */ +#define UDMA_GEN_VMPR_CFG_VMPR_8_RX_Q_BUF2_VMID_MASK 0x0000FFFF +#define UDMA_GEN_VMPR_CFG_VMPR_8_RX_Q_BUF2_VMID_SHIFT 0 +/* RX queue Data Buffer 2 VMID select */ +#define UDMA_GEN_VMPR_CFG_VMPR_8_RX_Q_BUF2_VMID_SEL_MASK 0xFFFF0000 +#define UDMA_GEN_VMPR_CFG_VMPR_8_RX_Q_BUF2_VMID_SEL_SHIFT 16 + +/**** cfg_vmpr_9 register ****/ +/* RX queue DDP VMID */ +#define UDMA_GEN_VMPR_CFG_VMPR_9_RX_Q_DDP_VMID_MASK 0x0000FFFF +#define UDMA_GEN_VMPR_CFG_VMPR_9_RX_Q_DDP_VMID_SHIFT 0 +/* RX queue DDP VMID select */ +#define UDMA_GEN_VMPR_CFG_VMPR_9_RX_Q_DDP_VMID_SEL_MASK 0xFFFF0000 +#define UDMA_GEN_VMPR_CFG_VMPR_9_RX_Q_DDP_VMID_SEL_SHIFT 16 + +#ifdef __cplusplus +} +#endif + +#endif /* __AL_HAL_UDMA_GEN_REG_H */ diff --git a/al_hal_udma_regs_m2s.h b/al_hal_udma_regs_m2s.h new file mode 100644 index 00000000000..06cea8db8f6 --- /dev/null +++ b/al_hal_udma_regs_m2s.h @@ -0,0 +1,1159 @@ +/*- +******************************************************************************* +Copyright (C) 2015 Annapurna Labs Ltd. + +This file may be licensed under the terms of the Annapurna Labs Commercial +License Agreement. + +Alternatively, this file can be distributed under the terms of the GNU General +Public License V2 as published by the Free Software Foundation and can be +found at http://www.gnu.org/licenses/gpl-2.0.html + +Alternatively, redistribution and use in source and binary forms, with or +without modification, are permitted provided that the following conditions are +met: + + * Redistributions of source code must retain the above copyright notice, +this list of conditions and the following disclaimer. + + * Redistributions in binary form must reproduce the above copyright +notice, this list of conditions and the following disclaimer in +the documentation and/or other materials provided with the +distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +*******************************************************************************/ + +/** + * @file al_hal_udma_regs_m2s.h + * + * @brief C Header file for the UDMA M2S registers + * + */ + +#ifndef __AL_HAL_UDMA_M2S_REG_H +#define __AL_HAL_UDMA_M2S_REG_H + +#include "al_hal_plat_types.h" + +#ifdef __cplusplus +extern "C" { +#endif +/* +* Unit Registers +*/ + + + +struct udma_axi_m2s { + /* [0x0] Completion write master configuration */ + uint32_t comp_wr_cfg_1; + /* [0x4] Completion write master configuration */ + uint32_t comp_wr_cfg_2; + /* [0x8] Data read master configuration */ + uint32_t data_rd_cfg_1; + /* [0xc] Data read master configuration */ + uint32_t data_rd_cfg_2; + /* [0x10] Descriptor read master configuration */ + uint32_t desc_rd_cfg_1; + /* [0x14] Descriptor read master configuration */ + uint32_t desc_rd_cfg_2; + /* [0x18] Data read master configuration */ + uint32_t data_rd_cfg; + /* [0x1c] Descriptors read master configuration */ + uint32_t desc_rd_cfg_3; + /* [0x20] Descriptors write master configuration (completion) */ + uint32_t desc_wr_cfg_1; + /* [0x24] AXI outstanding configuration */ + uint32_t ostand_cfg; + uint32_t rsrvd[54]; +}; +struct udma_m2s { + /* + * [0x0] DMA state. + * 00 - No pending tasks + * 01 – Normal (active) + * 10 – Abort (error condition) + * 11 – Reserved + */ + uint32_t state; + /* [0x4] CPU request to change DMA state */ + uint32_t change_state; + uint32_t rsrvd_0; + /* + * [0xc] M2S DMA error log mask. + * Each error has an interrupt controller cause bit. + * This register determines if these errors cause the M2S DMA to log the + * error condition. + * 0 - Log is enabled. + * 1 - Log is masked. + */ + uint32_t err_log_mask; + uint32_t rsrvd_1; + /* + * [0x14] DMA header log. + * Sample the packet header that caused the error. + */ + uint32_t log_0; + /* + * [0x18] DMA header log. + * Sample the packet header that caused the error. + */ + uint32_t log_1; + /* + * [0x1c] DMA header log. + * Sample the packet header that caused the error. + */ + uint32_t log_2; + /* + * [0x20] DMA header log. + * Sample the packet header that caused the error. + */ + uint32_t log_3; + /* [0x24] DMA clear error log */ + uint32_t clear_err_log; + /* [0x28] M2S data FIFO status */ + uint32_t data_fifo_status; + /* [0x2c] M2S header FIFO status */ + uint32_t header_fifo_status; + /* [0x30] M2S unack FIFO status */ + uint32_t unack_fifo_status; + /* [0x34] Select queue for debug */ + uint32_t indirect_ctrl; + /* + * [0x38] M2S prefetch FIFO status. + * Status of the selected queue in M2S_indirect_ctrl + */ + uint32_t sel_pref_fifo_status; + /* + * [0x3c] M2S completion FIFO status. + * Status of the selected queue in M2S_indirect_ctrl + */ + uint32_t sel_comp_fifo_status; + /* + * [0x40] M2S rate limit status. + * Status of the selected queue in M2S_indirect_ctrl + */ + uint32_t sel_rate_limit_status; + /* + * [0x44] M2S DWRR scheduler status. + * Status of the selected queue in M2S_indirect_ctrl + */ + uint32_t sel_dwrr_status; + /* [0x48] M2S state machine and FIFO clear control */ + uint32_t clear_ctrl; + /* [0x4c] Misc Check enable */ + uint32_t check_en; + /* [0x50] M2S FIFO enable control, internal */ + uint32_t fifo_en; + /* [0x54] M2S packet length configuration */ + uint32_t cfg_len; + /* [0x58] Stream interface configuration */ + uint32_t stream_cfg; + uint32_t rsrvd[41]; +}; +struct udma_m2s_rd { + /* [0x0] M2S descriptor prefetch configuration */ + uint32_t desc_pref_cfg_1; + /* [0x4] M2S descriptor prefetch configuration */ + uint32_t desc_pref_cfg_2; + /* [0x8] M2S descriptor prefetch configuration */ + uint32_t desc_pref_cfg_3; + uint32_t rsrvd_0; + /* [0x10] Data burst read configuration */ + uint32_t data_cfg; + uint32_t rsrvd[11]; +}; +struct udma_m2s_dwrr { + /* [0x0] Tx DMA DWRR scheduler configuration */ + uint32_t cfg_sched; + /* [0x4] Token bucket rate limit control */ + uint32_t ctrl_deficit_cnt; + uint32_t rsrvd[14]; +}; +struct udma_m2s_rate_limiter { + /* [0x0] Token bucket rate limit configuration */ + uint32_t gen_cfg; + /* + * [0x4] Token bucket rate limit control. + * Controls the cycle counters. + */ + uint32_t ctrl_cycle_cnt; + /* + * [0x8] Token bucket rate limit control. + * Controls the token bucket counter. + */ + uint32_t ctrl_token; + uint32_t rsrvd[13]; +}; + +struct udma_rlimit_common { + /* [0x0] Token bucket configuration */ + uint32_t cfg_1s; + /* [0x4] Token bucket rate limit configuration */ + uint32_t cfg_cycle; + /* [0x8] Token bucket rate limit configuration */ + uint32_t cfg_token_size_1; + /* [0xc] Token bucket rate limit configuration */ + uint32_t cfg_token_size_2; + /* [0x10] Token bucket rate limit configuration */ + uint32_t sw_ctrl; + /* + * [0x14] Mask the different types of rate limiter. + * 0 - Rate limit is active. + * 1 - Rate limit is masked. + */ + uint32_t mask; +}; + +struct udma_m2s_stream_rate_limiter { + struct udma_rlimit_common rlimit; + uint32_t rsrvd[10]; +}; +struct udma_m2s_comp { + /* [0x0] Completion controller configuration */ + uint32_t cfg_1c; + /* [0x4] Completion controller coalescing configuration */ + uint32_t cfg_coal; + /* [0x8] Completion controller application acknowledge configuration */ + uint32_t cfg_application_ack; + uint32_t rsrvd[61]; +}; +struct udma_m2s_stat { + /* [0x0] Statistics counters configuration */ + uint32_t cfg_st; + /* [0x4] Counting number of descriptors with First-bit set. */ + uint32_t tx_pkt; + /* + * [0x8] Counting the net length of the data buffers [64-bit] + * Should be read before tx_bytes_high + */ + uint32_t tx_bytes_low; + /* + * [0xc] Counting the net length of the data buffers [64-bit], + * Should be read after tx_bytes_low (value is sampled when reading + * Should be read before tx_bytes_low + */ + uint32_t tx_bytes_high; + /* [0x10] Total number of descriptors read from the host memory */ + uint32_t prefed_desc; + /* [0x14] Number of packets read from the unack FIFO */ + uint32_t comp_pkt; + /* [0x18] Number of descriptors written into the completion ring */ + uint32_t comp_desc; + /* + * [0x1c] Number of acknowledged packets. + * (acknowledge received from the stream interface) + */ + uint32_t ack_pkts; + uint32_t rsrvd[56]; +}; +struct udma_m2s_feature { + /* + * [0x0] M2S Feature register. + * M2S instantiation parameters + */ + uint32_t reg_1; + /* [0x4] Reserved M2S feature register */ + uint32_t reg_2; + /* + * [0x8] M2S Feature register. + * M2S instantiation parameters + */ + uint32_t reg_3; + /* + * [0xc] M2S Feature register. + * M2S instantiation parameters + */ + uint32_t reg_4; + /* + * [0x10] M2S Feature register. + * M2S instantiation parameters + */ + uint32_t reg_5; + uint32_t rsrvd[59]; +}; +struct udma_m2s_q { + uint32_t rsrvd_0[8]; + /* [0x20] M2S descriptor ring configuration */ + uint32_t cfg; + /* [0x24] M2S descriptor ring status and information */ + uint32_t status; + /* [0x28] TX Descriptor Ring Base Pointer [31:4] */ + uint32_t tdrbp_low; + /* [0x2c] TX Descriptor Ring Base Pointer [63:32] */ + uint32_t tdrbp_high; + /* + * [0x30] TX Descriptor Ring Length[23:2] + */ + uint32_t tdrl; + /* [0x34] TX Descriptor Ring Head Pointer */ + uint32_t tdrhp; + /* [0x38] Tx Descriptor Tail Pointer increment */ + uint32_t tdrtp_inc; + /* [0x3c] Tx Descriptor Tail Pointer */ + uint32_t tdrtp; + /* [0x40] TX Descriptor Current Pointer */ + uint32_t tdcp; + /* [0x44] Tx Completion Ring Base Pointer [31:4] */ + uint32_t tcrbp_low; + /* [0x48] TX Completion Ring Base Pointer [63:32] */ + uint32_t tcrbp_high; + /* [0x4c] TX Completion Ring Head Pointer */ + uint32_t tcrhp; + /* + * [0x50] Tx Completion Ring Head Pointer internal (Before the + * coalescing FIFO) + */ + uint32_t tcrhp_internal; + uint32_t rsrvd_1[3]; + /* [0x60] Rate limit configuration */ + struct udma_rlimit_common rlimit; + uint32_t rsrvd_2[2]; + /* [0x80] DWRR scheduler configuration */ + uint32_t dwrr_cfg_1; + /* [0x84] DWRR scheduler configuration */ + uint32_t dwrr_cfg_2; + /* [0x88] DWRR scheduler configuration */ + uint32_t dwrr_cfg_3; + /* [0x8c] DWRR scheduler software control */ + uint32_t dwrr_sw_ctrl; + uint32_t rsrvd_3[4]; + /* [0xa0] Completion controller configuration */ + uint32_t comp_cfg; + uint32_t rsrvd_4[3]; + /* [0xb0] SW control */ + uint32_t q_sw_ctrl; + uint32_t rsrvd_5[3]; + /* [0xc0] Number of M2S Tx packets after the scheduler */ + uint32_t q_tx_pkt; + uint32_t rsrvd[975]; +}; + +struct udma_m2s_regs { + uint32_t rsrvd_0[64]; + struct udma_axi_m2s axi_m2s; /* [0x100] */ + struct udma_m2s m2s; /* [0x200] */ + struct udma_m2s_rd m2s_rd; /* [0x300] */ + struct udma_m2s_dwrr m2s_dwrr; /* [0x340] */ + struct udma_m2s_rate_limiter m2s_rate_limiter; /* [0x380] */ + struct udma_m2s_stream_rate_limiter m2s_stream_rate_limiter; /* [0x3c0] */ + struct udma_m2s_comp m2s_comp; /* [0x400] */ + struct udma_m2s_stat m2s_stat; /* [0x500] */ + struct udma_m2s_feature m2s_feature; /* [0x600] */ + uint32_t rsrvd_1[576]; + struct udma_m2s_q m2s_q[4]; /* [0x1000] */ +}; + + +/* +* Registers Fields +*/ + + +/**** comp_wr_cfg_1 register ****/ +/* AXI write ID (AWID) */ +#define UDMA_AXI_M2S_COMP_WR_CFG_1_AWID_MASK 0x000000FF +#define UDMA_AXI_M2S_COMP_WR_CFG_1_AWID_SHIFT 0 +/* Cache Type */ +#define UDMA_AXI_M2S_COMP_WR_CFG_1_AWCACHE_MASK 0x000F0000 +#define UDMA_AXI_M2S_COMP_WR_CFG_1_AWCACHE_SHIFT 16 +/* Burst type */ +#define UDMA_AXI_M2S_COMP_WR_CFG_1_AWBURST_MASK 0x03000000 +#define UDMA_AXI_M2S_COMP_WR_CFG_1_AWBURST_SHIFT 24 + +/**** comp_wr_cfg_2 register ****/ +/* User extension */ +#define UDMA_AXI_M2S_COMP_WR_CFG_2_AWUSER_MASK 0x000FFFFF +#define UDMA_AXI_M2S_COMP_WR_CFG_2_AWUSER_SHIFT 0 +/* Bus size, 128-bit */ +#define UDMA_AXI_M2S_COMP_WR_CFG_2_AWSIZE_MASK 0x00700000 +#define UDMA_AXI_M2S_COMP_WR_CFG_2_AWSIZE_SHIFT 20 +/* + * AXI Master QoS. + * Used for arbitration between AXI masters + */ +#define UDMA_AXI_M2S_COMP_WR_CFG_2_AWQOS_MASK 0x07000000 +#define UDMA_AXI_M2S_COMP_WR_CFG_2_AWQOS_SHIFT 24 +/* Protection Type */ +#define UDMA_AXI_M2S_COMP_WR_CFG_2_AWPROT_MASK 0x70000000 +#define UDMA_AXI_M2S_COMP_WR_CFG_2_AWPROT_SHIFT 28 + +/**** data_rd_cfg_1 register ****/ +/* AXI read ID (ARID) */ +#define UDMA_AXI_M2S_DATA_RD_CFG_1_ARID_MASK 0x000000FF +#define UDMA_AXI_M2S_DATA_RD_CFG_1_ARID_SHIFT 0 +/* Cache Type */ +#define UDMA_AXI_M2S_DATA_RD_CFG_1_ARCACHE_MASK 0x000F0000 +#define UDMA_AXI_M2S_DATA_RD_CFG_1_ARCACHE_SHIFT 16 +/* Burst type */ +#define UDMA_AXI_M2S_DATA_RD_CFG_1_ARBURST_MASK 0x03000000 +#define UDMA_AXI_M2S_DATA_RD_CFG_1_ARBURST_SHIFT 24 + +/**** data_rd_cfg_2 register ****/ +/* User extension */ +#define UDMA_AXI_M2S_DATA_RD_CFG_2_ARUSER_MASK 0x000FFFFF +#define UDMA_AXI_M2S_DATA_RD_CFG_2_ARUSER_SHIFT 0 +/* Bus size, 128-bit */ +#define UDMA_AXI_M2S_DATA_RD_CFG_2_ARSIZE_MASK 0x00700000 +#define UDMA_AXI_M2S_DATA_RD_CFG_2_ARSIZE_SHIFT 20 +/* + * AXI Master QoS. + * Used for arbitration between AXI masters + */ +#define UDMA_AXI_M2S_DATA_RD_CFG_2_ARQOS_MASK 0x07000000 +#define UDMA_AXI_M2S_DATA_RD_CFG_2_ARQOS_SHIFT 24 +/* Protection Type */ +#define UDMA_AXI_M2S_DATA_RD_CFG_2_ARPROT_MASK 0x70000000 +#define UDMA_AXI_M2S_DATA_RD_CFG_2_ARPROT_SHIFT 28 + +/**** desc_rd_cfg_1 register ****/ +/* AXI read ID (ARID) */ +#define UDMA_AXI_M2S_DESC_RD_CFG_1_ARID_MASK 0x000000FF +#define UDMA_AXI_M2S_DESC_RD_CFG_1_ARID_SHIFT 0 +/* Cache Type */ +#define UDMA_AXI_M2S_DESC_RD_CFG_1_ARCACHE_MASK 0x000F0000 +#define UDMA_AXI_M2S_DESC_RD_CFG_1_ARCACHE_SHIFT 16 +/* Burst type */ +#define UDMA_AXI_M2S_DESC_RD_CFG_1_ARBURST_MASK 0x03000000 +#define UDMA_AXI_M2S_DESC_RD_CFG_1_ARBURST_SHIFT 24 + +/**** desc_rd_cfg_2 register ****/ +/* User extension */ +#define UDMA_AXI_M2S_DESC_RD_CFG_2_ARUSER_MASK 0x000FFFFF +#define UDMA_AXI_M2S_DESC_RD_CFG_2_ARUSER_SHIFT 0 +/* Bus size, 128-bit */ +#define UDMA_AXI_M2S_DESC_RD_CFG_2_ARSIZE_MASK 0x00700000 +#define UDMA_AXI_M2S_DESC_RD_CFG_2_ARSIZE_SHIFT 20 +/* + * AXI Master QoS + * Used for arbitration between AXI masters + */ +#define UDMA_AXI_M2S_DESC_RD_CFG_2_ARQOS_MASK 0x07000000 +#define UDMA_AXI_M2S_DESC_RD_CFG_2_ARQOS_SHIFT 24 +/* Protection Type */ +#define UDMA_AXI_M2S_DESC_RD_CFG_2_ARPROT_MASK 0x70000000 +#define UDMA_AXI_M2S_DESC_RD_CFG_2_ARPROT_SHIFT 28 + +/**** data_rd_cfg register ****/ +/* + * Defines the maximum number of AXI beats for a single AXI burst. + * This value is used for a burst split decision. + */ +#define UDMA_AXI_M2S_DATA_RD_CFG_MAX_AXI_BEATS_MASK 0x000000FF +#define UDMA_AXI_M2S_DATA_RD_CFG_MAX_AXI_BEATS_SHIFT 0 +/* + * Enable breaking data read request. + * Aligned to max_AXI_beats when the total read size is less than max_AXI_beats + */ +#define UDMA_AXI_M2S_DATA_RD_CFG_ALWAYS_BREAK_ON_MAX_BOUDRY (1 << 16) + +/**** desc_rd_cfg_3 register ****/ +/* + * Defines the maximum number of AXI beats for a single AXI burst. + * This value is used for a burst split decision. + * Maximum burst size for reading data( in AXI beats, 128-bits) + * (default – 16 beats, 256 bytes) + */ +#define UDMA_AXI_M2S_DESC_RD_CFG_3_MAX_AXI_BEATS_MASK 0x000000FF +#define UDMA_AXI_M2S_DESC_RD_CFG_3_MAX_AXI_BEATS_SHIFT 0 +/* + * Enable breaking descriptor read request. + * Aligned to max_AXI_beats when the total read size is less than max_AXI_beats. + */ +#define UDMA_AXI_M2S_DESC_RD_CFG_3_ALWAYS_BREAK_ON_MAX_BOUDRY (1 << 16) + +/**** desc_wr_cfg_1 register ****/ +/* + * Defines the maximum number of AXI beats for a single AXI burst. + * This value is used for a burst split decision. + */ +#define UDMA_AXI_M2S_DESC_WR_CFG_1_MAX_AXI_BEATS_MASK 0x000000FF +#define UDMA_AXI_M2S_DESC_WR_CFG_1_MAX_AXI_BEATS_SHIFT 0 +/* + * Minimum burst for writing completion descriptors. + * Defined in AXI beats + * 4 Descriptors per beat. + * Value must be aligned to cache lines (64 bytes). + * Default value is 2 cache lines, 32 descriptors, 8 beats. + */ +#define UDMA_AXI_M2S_DESC_WR_CFG_1_MIN_AXI_BEATS_MASK 0x00FF0000 +#define UDMA_AXI_M2S_DESC_WR_CFG_1_MIN_AXI_BEATS_SHIFT 16 + +/**** ostand_cfg register ****/ +/* Maximum number of outstanding data reads to the AXI (AXI transactions) */ +#define UDMA_AXI_M2S_OSTAND_CFG_MAX_DATA_RD_MASK 0x0000003F +#define UDMA_AXI_M2S_OSTAND_CFG_MAX_DATA_RD_SHIFT 0 +/* + * Maximum number of outstanding descriptor reads to the AXI (AXI transactions) + */ +#define UDMA_AXI_M2S_OSTAND_CFG_MAX_DESC_RD_MASK 0x00003F00 +#define UDMA_AXI_M2S_OSTAND_CFG_MAX_DESC_RD_SHIFT 8 +/* + * Maximum number of outstanding descriptor writes to the AXI (AXI transactions) + */ +#define UDMA_AXI_M2S_OSTAND_CFG_MAX_COMP_REQ_MASK 0x003F0000 +#define UDMA_AXI_M2S_OSTAND_CFG_MAX_COMP_REQ_SHIFT 16 +/* + * Maximum number of outstanding data beats for descriptor write to AXI (AXI + * beats) + */ +#define UDMA_AXI_M2S_OSTAND_CFG_MAX_COMP_DATA_WR_MASK 0xFF000000 +#define UDMA_AXI_M2S_OSTAND_CFG_MAX_COMP_DATA_WR_SHIFT 24 + +/**** state register ****/ +/* Completion control */ +#define UDMA_M2S_STATE_COMP_CTRL_MASK 0x00000003 +#define UDMA_M2S_STATE_COMP_CTRL_SHIFT 0 +/* Stream interface */ +#define UDMA_M2S_STATE_STREAM_IF_MASK 0x00000030 +#define UDMA_M2S_STATE_STREAM_IF_SHIFT 4 +/* Data read control */ +#define UDMA_M2S_STATE_DATA_RD_CTRL_MASK 0x00000300 +#define UDMA_M2S_STATE_DATA_RD_CTRL_SHIFT 8 +/* Descriptor prefetch */ +#define UDMA_M2S_STATE_DESC_PREF_MASK 0x00003000 +#define UDMA_M2S_STATE_DESC_PREF_SHIFT 12 + +/**** change_state register ****/ +/* Start normal operation */ +#define UDMA_M2S_CHANGE_STATE_NORMAL (1 << 0) +/* Stop normal operation */ +#define UDMA_M2S_CHANGE_STATE_DIS (1 << 1) +/* + * Stop all machines. + * (Prefetch, scheduling, completion and stream interface) + */ +#define UDMA_M2S_CHANGE_STATE_ABORT (1 << 2) + +/**** err_log_mask register ****/ +/* + * Mismatch of packet serial number. + * (between first packet in the unacknowledged FIFO and received ack from the + * stream) + */ +#define UDMA_M2S_ERR_LOG_MASK_COMP_PKT_MISMATCH (1 << 0) +/* Parity error */ +#define UDMA_M2S_ERR_LOG_MASK_STREAM_AXI_PARITY (1 << 1) +/* AXI response error */ +#define UDMA_M2S_ERR_LOG_MASK_STREAM_AXI_RESPONSE (1 << 2) +/* AXI timeout (ack not received) */ +#define UDMA_M2S_ERR_LOG_MASK_STREAM_AXI_TOUT (1 << 3) +/* Parity error */ +#define UDMA_M2S_ERR_LOG_MASK_COMP_AXI_PARITY (1 << 4) +/* AXI response error */ +#define UDMA_M2S_ERR_LOG_MASK_COMP_AXI_RESPONSE (1 << 5) +/* AXI timeout */ +#define UDMA_M2S_ERR_LOG_MASK_COMP_AXI_TOUT (1 << 6) +/* Parity error */ +#define UDMA_M2S_ERR_LOG_MASK_DATA_AXI_PARITY (1 << 7) +/* AXI response error */ +#define UDMA_M2S_ERR_LOG_MASK_DATA_AXI_RESPONSE (1 << 8) +/* AXI timeout */ +#define UDMA_M2S_ERR_LOG_MASK_DATA_AXI_TOUT (1 << 9) +/* Parity error */ +#define UDMA_M2S_ERR_LOG_MASK_PREF_AXI_PARITY (1 << 10) +/* AXI response error */ +#define UDMA_M2S_ERR_LOG_MASK_PREF_AXI_RESPONSE (1 << 11) +/* AXI timeout */ +#define UDMA_M2S_ERR_LOG_MASK_PREF_AXI_TOUT (1 << 12) +/* Packet length error */ +#define UDMA_M2S_ERR_LOG_MASK_PREF_PKT_LEN_OVERFLOW (1 << 13) +/* Maximum number of descriptors per packet error */ +#define UDMA_M2S_ERR_LOG_MASK_PREF_MAX_DESC_CNT (1 << 14) +/* Error in first bit indication of the descriptor */ +#define UDMA_M2S_ERR_LOG_MASK_PREF_FIRST (1 << 15) +/* Error in last bit indication of the descriptor */ +#define UDMA_M2S_ERR_LOG_MASK_PREF_LAST (1 << 16) +/* Ring_ID error */ +#define UDMA_M2S_ERR_LOG_MASK_PREF_RING_ID (1 << 17) +/* Data buffer parity error */ +#define UDMA_M2S_ERR_LOG_MASK_DATA_BUFF_PARITY (1 << 18) +/* Internal error */ +#define UDMA_M2S_ERR_LOG_MASK_INTERNAL_MASK 0xFFF80000 +#define UDMA_M2S_ERR_LOG_MASK_INTERNAL_SHIFT 19 + +/**** clear_err_log register ****/ +/* Clear error log */ +#define UDMA_M2S_CLEAR_ERR_LOG_CLEAR (1 << 0) + +/**** data_fifo_status register ****/ +/* FIFO used indication */ +#define UDMA_M2S_DATA_FIFO_STATUS_USED_MASK 0x0000FFFF +#define UDMA_M2S_DATA_FIFO_STATUS_USED_SHIFT 0 +/* FIFO empty indication */ +#define UDMA_M2S_DATA_FIFO_STATUS_EMPTY (1 << 24) +/* FIFO full indication */ +#define UDMA_M2S_DATA_FIFO_STATUS_FULL (1 << 28) + +/**** header_fifo_status register ****/ +/* FIFO used indication */ +#define UDMA_M2S_HEADER_FIFO_STATUS_USED_MASK 0x0000FFFF +#define UDMA_M2S_HEADER_FIFO_STATUS_USED_SHIFT 0 +/* FIFO empty indication */ +#define UDMA_M2S_HEADER_FIFO_STATUS_EMPTY (1 << 24) +/* FIFO full indication */ +#define UDMA_M2S_HEADER_FIFO_STATUS_FULL (1 << 28) + +/**** unack_fifo_status register ****/ +/* FIFO used indication */ +#define UDMA_M2S_UNACK_FIFO_STATUS_USED_MASK 0x0000FFFF +#define UDMA_M2S_UNACK_FIFO_STATUS_USED_SHIFT 0 +/* FIFO empty indication */ +#define UDMA_M2S_UNACK_FIFO_STATUS_EMPTY (1 << 24) +/* FIFO full indication */ +#define UDMA_M2S_UNACK_FIFO_STATUS_FULL (1 << 28) + +/**** indirect_ctrl register ****/ +/* Selected queue for status read */ +#define UDMA_M2S_INDIRECT_CTRL_Q_NUM_MASK 0x00000FFF +#define UDMA_M2S_INDIRECT_CTRL_Q_NUM_SHIFT 0 + +/**** sel_pref_fifo_status register ****/ +/* FIFO used indication */ +#define UDMA_M2S_SEL_PREF_FIFO_STATUS_USED_MASK 0x0000FFFF +#define UDMA_M2S_SEL_PREF_FIFO_STATUS_USED_SHIFT 0 +/* FIFO empty indication */ +#define UDMA_M2S_SEL_PREF_FIFO_STATUS_EMPTY (1 << 24) +/* FIFO full indication */ +#define UDMA_M2S_SEL_PREF_FIFO_STATUS_FULL (1 << 28) + +/**** sel_comp_fifo_status register ****/ +/* FIFO used indication */ +#define UDMA_M2S_SEL_COMP_FIFO_STATUS_USED_MASK 0x0000FFFF +#define UDMA_M2S_SEL_COMP_FIFO_STATUS_USED_SHIFT 0 +/* FIFO empty indication */ +#define UDMA_M2S_SEL_COMP_FIFO_STATUS_EMPTY (1 << 24) +/* FIFO full indication */ +#define UDMA_M2S_SEL_COMP_FIFO_STATUS_FULL (1 << 28) + +/**** sel_rate_limit_status register ****/ +/* Token counter */ +#define UDMA_M2S_SEL_RATE_LIMIT_STATUS_TOKEN_CNT_MASK 0x00FFFFFF +#define UDMA_M2S_SEL_RATE_LIMIT_STATUS_TOKEN_CNT_SHIFT 0 + +/**** sel_dwrr_status register ****/ +/* Deficit counter */ +#define UDMA_M2S_SEL_DWRR_STATUS_DEFICIT_CNT_MASK 0x00FFFFFF +#define UDMA_M2S_SEL_DWRR_STATUS_DEFICIT_CNT_SHIFT 0 + +/**** cfg_len register ****/ +/* Maximum packet size for the M2S */ +#define UDMA_M2S_CFG_LEN_MAX_PKT_SIZE_MASK 0x000FFFFF +#define UDMA_M2S_CFG_LEN_MAX_PKT_SIZE_SHIFT 0 +/* + * Length encoding for 64K. + * 0 - length 0x0000 = 0 + * 1 - length 0x0000 = 64k + */ +#define UDMA_M2S_CFG_LEN_ENCODE_64K (1 << 24) + +/**** stream_cfg register ****/ +/* + * Disables the stream interface operation. + * Changing to 1 stops at the end of packet transmission. + */ +#define UDMA_M2S_STREAM_CFG_DISABLE (1 << 0) +/* + * Configuration of the stream FIFO read control. + * 0 - Cut through + * 1 - Threshold based + */ +#define UDMA_M2S_STREAM_CFG_RD_MODE (1 << 1) +/* Minimum number of beats to start packet transmission. */ +#define UDMA_M2S_STREAM_CFG_RD_TH_MASK 0x0003FF00 +#define UDMA_M2S_STREAM_CFG_RD_TH_SHIFT 8 + +/**** desc_pref_cfg_1 register ****/ +/* Size of the descriptor prefetch FIFO (in descriptors) */ +#define UDMA_M2S_RD_DESC_PREF_CFG_1_FIFO_DEPTH_MASK 0x000000FF +#define UDMA_M2S_RD_DESC_PREF_CFG_1_FIFO_DEPTH_SHIFT 0 + +/**** desc_pref_cfg_2 register ****/ +/* Maximum number of descriptors per packet */ +#define UDMA_M2S_RD_DESC_PREF_CFG_2_MAX_DESC_PER_PKT_MASK 0x0000001F +#define UDMA_M2S_RD_DESC_PREF_CFG_2_MAX_DESC_PER_PKT_SHIFT 0 +/* + * Force RR arbitration in the prefetch arbiter. + * 0 -Standard arbitration based on queue QoS + * 1 - Force Round Robin arbitration + */ +#define UDMA_M2S_RD_DESC_PREF_CFG_2_PREF_FORCE_RR (1 << 16) + +/**** desc_pref_cfg_3 register ****/ +/* + * Minimum descriptor burst size when prefetch FIFO level is below the + * descriptor prefetch threshold + * (must be 1) + */ +#define UDMA_M2S_RD_DESC_PREF_CFG_3_MIN_BURST_BELOW_THR_MASK 0x0000000F +#define UDMA_M2S_RD_DESC_PREF_CFG_3_MIN_BURST_BELOW_THR_SHIFT 0 +/* + * Minimum descriptor burst size when prefetch FIFO level is above the + * descriptor prefetch threshold + */ +#define UDMA_M2S_RD_DESC_PREF_CFG_3_MIN_BURST_ABOVE_THR_MASK 0x000000F0 +#define UDMA_M2S_RD_DESC_PREF_CFG_3_MIN_BURST_ABOVE_THR_SHIFT 4 +/* + * Descriptor fetch threshold. + * Used as a threshold to determine the allowed minimum descriptor burst size. + * (Must be at least max_desc_per_pkt) + */ +#define UDMA_M2S_RD_DESC_PREF_CFG_3_PREF_THR_MASK 0x0000FF00 +#define UDMA_M2S_RD_DESC_PREF_CFG_3_PREF_THR_SHIFT 8 + +/**** data_cfg register ****/ +/* + * Maximum number of data beats in the data read FIFO. + * Defined based on data FIFO size + * (default FIFO size 2KB → 128 beats) + */ +#define UDMA_M2S_RD_DATA_CFG_DATA_FIFO_DEPTH_MASK 0x000003FF +#define UDMA_M2S_RD_DATA_CFG_DATA_FIFO_DEPTH_SHIFT 0 +/* + * Maximum number of packets in the data read FIFO. + * Defined based on header FIFO size + */ +#define UDMA_M2S_RD_DATA_CFG_MAX_PKT_LIMIT_MASK 0x00FF0000 +#define UDMA_M2S_RD_DATA_CFG_MAX_PKT_LIMIT_SHIFT 16 + +/**** cfg_sched register ****/ +/* + * Enable the DWRR scheduler. + * If this bit is 0, queues with same QoS will be served with RR scheduler. + */ +#define UDMA_M2S_DWRR_CFG_SCHED_EN_DWRR (1 << 0) +/* + * Scheduler operation mode. + * 0 - Byte mode + * 1 - Packet mode + */ +#define UDMA_M2S_DWRR_CFG_SCHED_PKT_MODE_EN (1 << 4) +/* + * Enable incrementing the weight factor between DWRR iterations. + * 00 - Don't increase the increment factor. + * 01 - Increment once + * 10 - Increment exponential + * 11 - Reserved + */ +#define UDMA_M2S_DWRR_CFG_SCHED_WEIGHT_INC_MASK 0x00000300 +#define UDMA_M2S_DWRR_CFG_SCHED_WEIGHT_INC_SHIFT 8 +/* + * Increment factor power of 2. + * 7 --> 128 bytes + * This is the factor used to multiply the weight. + */ +#define UDMA_M2S_DWRR_CFG_SCHED_INC_FACTOR_MASK 0x000F0000 +#define UDMA_M2S_DWRR_CFG_SCHED_INC_FACTOR_SHIFT 16 + +/**** ctrl_deficit_cnt register ****/ +/* + * Init value for the deficit counter. + * Initializes the deficit counters of all queues to this value any time this + * register is written. + */ +#define UDMA_M2S_DWRR_CTRL_DEFICIT_CNT_INIT_MASK 0x00FFFFFF +#define UDMA_M2S_DWRR_CTRL_DEFICIT_CNT_INIT_SHIFT 0 + +/**** gen_cfg register ****/ +/* Size of the basic token fill cycle, system clock cycles */ +#define UDMA_M2S_RATE_LIMITER_GEN_CFG_SHORT_CYCLE_SIZE_MASK 0x0000FFFF +#define UDMA_M2S_RATE_LIMITER_GEN_CFG_SHORT_CYCLE_SIZE_SHIFT 0 +/* + * Rate limiter operation mode. + * 0 - Byte mode + * 1 - Packet mode + */ +#define UDMA_M2S_RATE_LIMITER_GEN_CFG_PKT_MODE_EN (1 << 24) + +/**** ctrl_cycle_cnt register ****/ +/* Reset the short and long cycle counters. */ +#define UDMA_M2S_RATE_LIMITER_CTRL_CYCLE_CNT_RST (1 << 0) + +/**** ctrl_token register ****/ +/* + * Init value for the token counter. + * Initializes the token counters of all queues to this value any time this + * register is written. + */ +#define UDMA_M2S_RATE_LIMITER_CTRL_TOKEN_RST_MASK 0x00FFFFFF +#define UDMA_M2S_RATE_LIMITER_CTRL_TOKEN_RST_SHIFT 0 + +/**** cfg_1s register ****/ +/* Maximum number of accumulated bytes in the token counter */ +#define UDMA_M2S_STREAM_RATE_LIMITER_CFG_1S_MAX_BURST_SIZE_MASK 0x00FFFFFF +#define UDMA_M2S_STREAM_RATE_LIMITER_CFG_1S_MAX_BURST_SIZE_SHIFT 0 +/* Enable the rate limiter. */ +#define UDMA_M2S_STREAM_RATE_LIMITER_CFG_1S_EN (1 << 24) +/* Stop token fill. */ +#define UDMA_M2S_STREAM_RATE_LIMITER_CFG_1S_PAUSE (1 << 25) + +/**** cfg_cycle register ****/ +/* Number of short cycles between token fills */ +#define UDMA_M2S_STREAM_RATE_LIMITER_CFG_CYCLE_LONG_CYCLE_SIZE_MASK 0x0000FFFF +#define UDMA_M2S_STREAM_RATE_LIMITER_CFG_CYCLE_LONG_CYCLE_SIZE_SHIFT 0 + +/**** cfg_token_size_1 register ****/ +/* Number of bits to add in each long cycle */ +#define UDMA_M2S_STREAM_RATE_LIMITER_CFG_TOKEN_SIZE_1_LONG_CYCLE_MASK 0x0007FFFF +#define UDMA_M2S_STREAM_RATE_LIMITER_CFG_TOKEN_SIZE_1_LONG_CYCLE_SHIFT 0 + +/**** cfg_token_size_2 register ****/ +/* Number of bits to add in each short cycle */ +#define UDMA_M2S_STREAM_RATE_LIMITER_CFG_TOKEN_SIZE_2_SHORT_CYCLE_MASK 0x0007FFFF +#define UDMA_M2S_STREAM_RATE_LIMITER_CFG_TOKEN_SIZE_2_SHORT_CYCLE_SHIFT 0 + +/**** sw_ctrl register ****/ +/* Reset the token bucket counter. */ +#define UDMA_M2S_STREAM_RATE_LIMITER_SW_CTRL_RST_TOKEN_CNT (1 << 0) + +/**** mask register ****/ +/* Mask the external rate limiter. */ +#define UDMA_M2S_STREAM_RATE_LIMITER_MASK_EXTERNAL_RATE_LIMITER (1 << 0) +/* Mask the internal rate limiter. */ +#define UDMA_M2S_STREAM_RATE_LIMITER_MASK_INTERNAL_RATE_LIMITER (1 << 1) +/* Mask the external application pause interface. */ +#define UDMA_M2S_STREAM_RATE_LIMITER_MASK_EXTERNAL_PAUSE (1 << 3) + +/**** cfg_1c register ****/ +/* + * Completion FIFO size + * (descriptors per queue) + */ +#define UDMA_M2S_COMP_CFG_1C_COMP_FIFO_DEPTH_MASK 0x000000FF +#define UDMA_M2S_COMP_CFG_1C_COMP_FIFO_DEPTH_SHIFT 0 +/* + * Unacknowledged FIFO size. + * (descriptors) + */ +#define UDMA_M2S_COMP_CFG_1C_UNACK_FIFO_DEPTH_MASK 0x0001FF00 +#define UDMA_M2S_COMP_CFG_1C_UNACK_FIFO_DEPTH_SHIFT 8 +/* + * Enable promotion. + * Enable the promotion of the current queue in progress for the completion + * write scheduler. + */ +#define UDMA_M2S_COMP_CFG_1C_Q_PROMOTION (1 << 24) +/* Force RR arbitration in the completion arbiter */ +#define UDMA_M2S_COMP_CFG_1C_FORCE_RR (1 << 25) +/* Minimum number of free completion entries to qualify for promotion */ +#define UDMA_M2S_COMP_CFG_1C_Q_FREE_MIN_MASK 0xF0000000 +#define UDMA_M2S_COMP_CFG_1C_Q_FREE_MIN_SHIFT 28 + +/**** cfg_application_ack register ****/ +/* + * Acknowledge timeout timer. + * ACK from the application through the stream interface) + */ +#define UDMA_M2S_COMP_CFG_APPLICATION_ACK_TOUT_MASK 0x00FFFFFF +#define UDMA_M2S_COMP_CFG_APPLICATION_ACK_TOUT_SHIFT 0 + +/**** cfg_st register ****/ +/* Use additional length value for all statistics counters. */ +#define UDMA_M2S_STAT_CFG_ST_USE_EXTRA_LEN (1 << 0) + +/**** reg_1 register ****/ +/* + * Read the size of the descriptor prefetch FIFO + * (descriptors). + */ +#define UDMA_M2S_FEATURE_REG_1_DESC_PREFERCH_FIFO_DEPTH_MASK 0x000000FF +#define UDMA_M2S_FEATURE_REG_1_DESC_PREFERCH_FIFO_DEPTH_SHIFT 0 + +/**** reg_3 register ****/ +/* + * Maximum number of data beats in the data read FIFO. + * Defined based on data FIFO size + * (default FIFO size 2KB → 128 beats) + */ +#define UDMA_M2S_FEATURE_REG_3_DATA_FIFO_DEPTH_MASK 0x000003FF +#define UDMA_M2S_FEATURE_REG_3_DATA_FIFO_DEPTH_SHIFT 0 +/* + * Maximum number of packets in the data read FIFO. + * Defined based on header FIFO size + */ +#define UDMA_M2S_FEATURE_REG_3_DATA_RD_MAX_PKT_LIMIT_MASK 0x00FF0000 +#define UDMA_M2S_FEATURE_REG_3_DATA_RD_MAX_PKT_LIMIT_SHIFT 16 + +/**** reg_4 register ****/ +/* + * Size of the completion FIFO of each queue + * (words) + */ +#define UDMA_M2S_FEATURE_REG_4_COMP_FIFO_DEPTH_MASK 0x000000FF +#define UDMA_M2S_FEATURE_REG_4_COMP_FIFO_DEPTH_SHIFT 0 +/* Size of the unacknowledged FIFO (descriptors) */ +#define UDMA_M2S_FEATURE_REG_4_COMP_UNACK_FIFO_DEPTH_MASK 0x0001FF00 +#define UDMA_M2S_FEATURE_REG_4_COMP_UNACK_FIFO_DEPTH_SHIFT 8 + +/**** reg_5 register ****/ +/* Maximum number of outstanding data reads to AXI */ +#define UDMA_M2S_FEATURE_REG_5_MAX_DATA_RD_OSTAND_MASK 0x0000003F +#define UDMA_M2S_FEATURE_REG_5_MAX_DATA_RD_OSTAND_SHIFT 0 +/* Maximum number of outstanding descriptor reads to AXI */ +#define UDMA_M2S_FEATURE_REG_5_MAX_DESC_RD_OSTAND_MASK 0x00003F00 +#define UDMA_M2S_FEATURE_REG_5_MAX_DESC_RD_OSTAND_SHIFT 8 +/* + * Maximum number of outstanding descriptor writes to AXI. + * (AXI transactions) + */ +#define UDMA_M2S_FEATURE_REG_5_MAX_COMP_REQ_MASK 0x003F0000 +#define UDMA_M2S_FEATURE_REG_5_MAX_COMP_REQ_SHIFT 16 +/* + * Maximum number of outstanding data beats for descriptor write to AXI. + * (AXI beats) + */ +#define UDMA_M2S_FEATURE_REG_5_MAX_COMP_DATA_WR_OSTAND_MASK 0xFF000000 +#define UDMA_M2S_FEATURE_REG_5_MAX_COMP_DATA_WR_OSTAND_SHIFT 24 + +/**** cfg register ****/ +/* + * Length offset to be used for each packet from this queue. + * (length offset is used for the scheduler and rate limiter). + */ +#define UDMA_M2S_Q_CFG_PKT_LEN_OFFSET_MASK 0x0000FFFF +#define UDMA_M2S_Q_CFG_PKT_LEN_OFFSET_SHIFT 0 +/* + * Enable operation of this queue. + * Start prefetch. + */ +#define UDMA_M2S_Q_CFG_EN_PREF (1 << 16) +/* + * Enable operation of this queue. + * Start scheduling. + */ +#define UDMA_M2S_Q_CFG_EN_SCHEDULING (1 << 17) +/* Allow prefetch of less than minimum prefetch burst size. */ +#define UDMA_M2S_Q_CFG_ALLOW_LT_MIN_PREF (1 << 20) +/* Configure the AXI AWCACHE for completion write. */ +#define UDMA_M2S_Q_CFG_AXI_AWCACHE_COMP_MASK 0x0F000000 +#define UDMA_M2S_Q_CFG_AXI_AWCACHE_COMP_SHIFT 24 +/* + * AXI QoS for the selected queue. + * This value is used in AXI transactions associated with this queue and the + * prefetch and completion arbiters. + */ +#define UDMA_M2S_Q_CFG_AXI_QOS_MASK 0x70000000 +#define UDMA_M2S_Q_CFG_AXI_QOS_SHIFT 28 + +/**** status register ****/ +/* Indicates how many entries are used in the queue */ +#define UDMA_M2S_Q_STATUS_Q_USED_MASK 0x01FFFFFF +#define UDMA_M2S_Q_STATUS_Q_USED_SHIFT 0 +/* + * prefetch status + * 0 – prefetch operation is stopped + * 1 – prefetch is operational + */ +#define UDMA_M2S_Q_STATUS_PREFETCH (1 << 28) +/* + * Queue scheduler status + * 0 – queue is not active and not participating in scheduling + * 1 – queue is active and participating in the scheduling process + */ +#define UDMA_M2S_Q_STATUS_SCHEDULER (1 << 29) +/* Queue is suspended due to DMB */ +#define UDMA_M2S_Q_STATUS_Q_DMB (1 << 30) +/* + * Queue full indication. + * (used by the host when head pointer equals tail pointer). + */ +#define UDMA_M2S_Q_STATUS_Q_FULL (1 << 31) +/* + * M2S Descriptor Ring Base address [31:4]. + * Value of the base address of the M2S descriptor ring + * [3:0] - 0 - 16B alignment is enforced + * ([11:4] should be 0 for 4KB alignment) + */ +#define UDMA_M2S_Q_TDRBP_LOW_ADDR_MASK 0xFFFFFFF0 +#define UDMA_M2S_Q_TDRBP_LOW_ADDR_SHIFT 4 + +/**** TDRL register ****/ +/* + * Length of the descriptor ring. + * (descriptors) + * Associated with the ring base address, ends at maximum burst size alignment. + */ +#define UDMA_M2S_Q_TDRL_OFFSET_MASK 0x00FFFFFF +#define UDMA_M2S_Q_TDRL_OFFSET_SHIFT 0 + +/**** TDRHP register ****/ +/* + * Relative offset of the next descriptor that needs to be read into the + * prefetch FIFO. + * Incremented when the DMA reads valid descriptors from the host memory to the + * prefetch FIFO. + * Note that this is the offset in # of descriptors and not in byte address. + */ +#define UDMA_M2S_Q_TDRHP_OFFSET_MASK 0x00FFFFFF +#define UDMA_M2S_Q_TDRHP_OFFSET_SHIFT 0 +/* Ring ID */ +#define UDMA_M2S_Q_TDRHP_RING_ID_MASK 0xC0000000 +#define UDMA_M2S_Q_TDRHP_RING_ID_SHIFT 30 + +/**** TDRTP_inc register ****/ +/* Increments the value in Q_TDRTP (descriptors) */ +#define UDMA_M2S_Q_TDRTP_INC_VAL_MASK 0x00FFFFFF +#define UDMA_M2S_Q_TDRTP_INC_VAL_SHIFT 0 + +/**** TDRTP register ****/ +/* + * Relative offset of the next free descriptor in the host memory. + * Note that this is the offset in # of descriptors and not in byte address. + */ +#define UDMA_M2S_Q_TDRTP_OFFSET_MASK 0x00FFFFFF +#define UDMA_M2S_Q_TDRTP_OFFSET_SHIFT 0 +/* Ring ID */ +#define UDMA_M2S_Q_TDRTP_RING_ID_MASK 0xC0000000 +#define UDMA_M2S_Q_TDRTP_RING_ID_SHIFT 30 + +/**** TDCP register ****/ +/* + * Relative offset of the first descriptor in the prefetch FIFO. + * This is the next descriptor that will be read by the scheduler. + */ +#define UDMA_M2S_Q_TDCP_OFFSET_MASK 0x00FFFFFF +#define UDMA_M2S_Q_TDCP_OFFSET_SHIFT 0 +/* Ring ID */ +#define UDMA_M2S_Q_TDCP_RING_ID_MASK 0xC0000000 +#define UDMA_M2S_Q_TDCP_RING_ID_SHIFT 30 +/* + * M2S Descriptor Ring Base address [31:4]. + * Value of the base address of the M2S descriptor ring + * [3:0] - 0 - 16B alignment is enforced + * ([11:4] should be 0 for 4KB alignment) + * NOTE: + * Length of the descriptor ring (in descriptors) associated with the ring base + * address. Ends at maximum burst size alignment. + */ +#define UDMA_M2S_Q_TCRBP_LOW_ADDR_MASK 0xFFFFFFF0 +#define UDMA_M2S_Q_TCRBP_LOW_ADDR_SHIFT 4 + +/**** TCRHP register ****/ +/* + * Relative offset of the next descriptor that needs to be updated by the + * completion controller. + * Note: This is in descriptors and not in byte address. + */ +#define UDMA_M2S_Q_TCRHP_OFFSET_MASK 0x00FFFFFF +#define UDMA_M2S_Q_TCRHP_OFFSET_SHIFT 0 +/* Ring ID */ +#define UDMA_M2S_Q_TCRHP_RING_ID_MASK 0xC0000000 +#define UDMA_M2S_Q_TCRHP_RING_ID_SHIFT 30 + +/**** TCRHP_internal register ****/ +/* + * Relative offset of the next descriptor that needs to be updated by the + * completion controller. + * Note: This is in descriptors and not in byte address. + */ +#define UDMA_M2S_Q_TCRHP_INTERNAL_OFFSET_MASK 0x00FFFFFF +#define UDMA_M2S_Q_TCRHP_INTERNAL_OFFSET_SHIFT 0 +/* Ring ID */ +#define UDMA_M2S_Q_TCRHP_INTERNAL_RING_ID_MASK 0xC0000000 +#define UDMA_M2S_Q_TCRHP_INTERNAL_RING_ID_SHIFT 30 + +/**** rate_limit_cfg_1 register ****/ +/* Maximum number of accumulated bytes in the token counter. */ +#define UDMA_M2S_Q_RATE_LIMIT_CFG_1_MAX_BURST_SIZE_MASK 0x00FFFFFF +#define UDMA_M2S_Q_RATE_LIMIT_CFG_1_MAX_BURST_SIZE_SHIFT 0 +/* Enable the rate limiter. */ +#define UDMA_M2S_Q_RATE_LIMIT_CFG_1_EN (1 << 24) +/* Stop token fill. */ +#define UDMA_M2S_Q_RATE_LIMIT_CFG_1_PAUSE (1 << 25) + +/**** rate_limit_cfg_cycle register ****/ +/* Number of short cycles between token fills */ +#define UDMA_M2S_Q_RATE_LIMIT_CFG_CYCLE_LONG_CYCLE_SIZE_MASK 0x0000FFFF +#define UDMA_M2S_Q_RATE_LIMIT_CFG_CYCLE_LONG_CYCLE_SIZE_SHIFT 0 + +/**** rate_limit_cfg_token_size_1 register ****/ +/* Number of bits to add in each long cycle */ +#define UDMA_M2S_Q_RATE_LIMIT_CFG_TOKEN_SIZE_1_LONG_CYCLE_MASK 0x0007FFFF +#define UDMA_M2S_Q_RATE_LIMIT_CFG_TOKEN_SIZE_1_LONG_CYCLE_SHIFT 0 + +/**** rate_limit_cfg_token_size_2 register ****/ +/* Number of bits to add in each cycle */ +#define UDMA_M2S_Q_RATE_LIMIT_CFG_TOKEN_SIZE_2_SHORT_CYCLE_MASK 0x0007FFFF +#define UDMA_M2S_Q_RATE_LIMIT_CFG_TOKEN_SIZE_2_SHORT_CYCLE_SHIFT 0 + +/**** rate_limit_sw_ctrl register ****/ +/* Reset the token bucket counter. */ +#define UDMA_M2S_Q_RATE_LIMIT_SW_CTRL_RST_TOKEN_CNT (1 << 0) + +/**** rate_limit_mask register ****/ +/* Mask the external rate limiter. */ +#define UDMA_M2S_Q_RATE_LIMIT_MASK_EXTERNAL_RATE_LIMITER (1 << 0) +/* Mask the internal rate limiter. */ +#define UDMA_M2S_Q_RATE_LIMIT_MASK_INTERNAL_RATE_LIMITER (1 << 1) +/* + * Mask the internal pause mechanism for DMB. + * (Data Memory Barrier). + */ +#define UDMA_M2S_Q_RATE_LIMIT_MASK_INTERNAL_PAUSE_DMB (1 << 2) +/* Mask the external application pause interface. */ +#define UDMA_M2S_Q_RATE_LIMIT_MASK_EXTERNAL_PAUSE (1 << 3) + +/**** dwrr_cfg_1 register ****/ +/* Maximum number of accumulated bytes in the deficit counter */ +#define UDMA_M2S_Q_DWRR_CFG_1_MAX_DEFICIT_CNT_SIZE_MASK 0x00FFFFFF +#define UDMA_M2S_Q_DWRR_CFG_1_MAX_DEFICIT_CNT_SIZE_SHIFT 0 +/* Bypass the DWRR. */ +#define UDMA_M2S_Q_DWRR_CFG_1_STRICT (1 << 24) +/* Stop deficit counter increment. */ +#define UDMA_M2S_Q_DWRR_CFG_1_PAUSE (1 << 25) + +/**** dwrr_cfg_2 register ****/ +/* + * Value for the queue QoS. + * Queues with the same QoS value are scheduled with RR/DWRR. + * Only LOG(number of queues) is used. + */ +#define UDMA_M2S_Q_DWRR_CFG_2_Q_QOS_MASK 0x000000FF +#define UDMA_M2S_Q_DWRR_CFG_2_Q_QOS_SHIFT 0 + +/**** dwrr_cfg_3 register ****/ +/* Queue weight */ +#define UDMA_M2S_Q_DWRR_CFG_3_WEIGHT_MASK 0x000000FF +#define UDMA_M2S_Q_DWRR_CFG_3_WEIGHT_SHIFT 0 + +/**** dwrr_sw_ctrl register ****/ +/* Reset the DWRR deficit counter. */ +#define UDMA_M2S_Q_DWRR_SW_CTRL_RST_CNT (1 << 0) + +/**** comp_cfg register ****/ +/* Enable writing to the completion ring */ +#define UDMA_M2S_Q_COMP_CFG_EN_COMP_RING_UPDATE (1 << 0) +/* Disable the completion coalescing function. */ +#define UDMA_M2S_Q_COMP_CFG_DIS_COMP_COAL (1 << 1) + +/**** q_sw_ctrl register ****/ +/* + * Reset the DMB hardware barrier + * (enable queue operation). + */ +#define UDMA_M2S_Q_SW_CTRL_RST_DMB (1 << 0) +/* Reset the tail pointer hardware. */ +#define UDMA_M2S_Q_SW_CTRL_RST_TAIL_PTR (1 << 1) +/* Reset the head pointer hardware. */ +#define UDMA_M2S_Q_SW_CTRL_RST_HEAD_PTR (1 << 2) +/* Reset the current pointer hardware. */ +#define UDMA_M2S_Q_SW_CTRL_RST_CURRENT_PTR (1 << 3) +/* Reset the queue */ +#define UDMA_M2S_Q_SW_CTRL_RST_Q (1 << 8) + +#ifdef __cplusplus +} +#endif + +#endif /* __AL_HAL_UDMA_M2S_REG_H */ diff --git a/al_hal_udma_regs_s2m.h b/al_hal_udma_regs_s2m.h new file mode 100644 index 00000000000..4b3149b97ae --- /dev/null +++ b/al_hal_udma_regs_s2m.h @@ -0,0 +1,998 @@ +/*- +******************************************************************************* +Copyright (C) 2015 Annapurna Labs Ltd. + +This file may be licensed under the terms of the Annapurna Labs Commercial +License Agreement. + +Alternatively, this file can be distributed under the terms of the GNU General +Public License V2 as published by the Free Software Foundation and can be +found at http://www.gnu.org/licenses/gpl-2.0.html + +Alternatively, redistribution and use in source and binary forms, with or +without modification, are permitted provided that the following conditions are +met: + + * Redistributions of source code must retain the above copyright notice, +this list of conditions and the following disclaimer. + + * Redistributions in binary form must reproduce the above copyright +notice, this list of conditions and the following disclaimer in +the documentation and/or other materials provided with the +distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +*******************************************************************************/ + +/** + * @file al_hal_udma_regs_s2m.h + * + * @brief C Header file for the UDMA S2M registers + * + */ + +#ifndef __AL_HAL_UDMA_S2M_REG_H +#define __AL_HAL_UDMA_S2M_REG_H + +#include "al_hal_plat_types.h" + +#ifdef __cplusplus +extern "C" { +#endif +/* +* Unit Registers +*/ + + + +struct udma_axi_s2m { + /* [0x0] Data write master configuration */ + uint32_t data_wr_cfg_1; + /* [0x4] Data write master configuration */ + uint32_t data_wr_cfg_2; + /* [0x8] Descriptor read master configuration */ + uint32_t desc_rd_cfg_4; + /* [0xc] Descriptor read master configuration */ + uint32_t desc_rd_cfg_5; + /* [0x10] Completion write master configuration */ + uint32_t comp_wr_cfg_1; + /* [0x14] Completion write master configuration */ + uint32_t comp_wr_cfg_2; + /* [0x18] Data write master configuration */ + uint32_t data_wr_cfg; + /* [0x1c] Descriptors read master configuration */ + uint32_t desc_rd_cfg_3; + /* [0x20] Completion descriptors write master configuration */ + uint32_t desc_wr_cfg_1; + /* [0x24] AXI outstanding read configuration */ + uint32_t ostand_cfg_rd; + /* [0x28] AXI outstanding write configuration */ + uint32_t ostand_cfg_wr; + uint32_t rsrvd[53]; +}; +struct udma_s2m { + /* + * [0x0] DMA state + * 00 - No pending tasks + * 01 – Normal (active) + * 10 – Abort (error condition) + * 11 – Reserved + */ + uint32_t state; + /* [0x4] CPU request to change DMA state */ + uint32_t change_state; + uint32_t rsrvd_0; + /* + * [0xc] S2M DMA error log mask. + * Each error has an interrupt controller cause bit. + * This register determines if these errors cause the S2M DMA to log the + * error condition. + * 0 - Log is enable + * 1 - Log is masked. + */ + uint32_t err_log_mask; + uint32_t rsrvd_1; + /* + * [0x14] DMA header log + * Sample the packet header that caused the error + */ + uint32_t log_0; + /* + * [0x18] DMA header log + * Sample the packet header that caused the error. + */ + uint32_t log_1; + /* + * [0x1c] DMA header log + * Sample the packet header that caused the error. + */ + uint32_t log_2; + /* + * [0x20] DMA header log + * Sample the packet header that caused the error + */ + uint32_t log_3; + /* [0x24] DMA clear error log */ + uint32_t clear_err_log; + /* [0x28] S2M stream data FIFO status */ + uint32_t s_data_fifo_status; + /* [0x2c] S2M stream header FIFO status */ + uint32_t s_header_fifo_status; + /* [0x30] S2M AXI data FIFO status */ + uint32_t axi_data_fifo_status; + /* [0x34] S2M unack FIFO status */ + uint32_t unack_fifo_status; + /* [0x38] Select queue for debug */ + uint32_t indirect_ctrl; + /* + * [0x3c] S2M prefetch FIFO status. + * Status of the selected queue in S2M_indirect_ctrl + */ + uint32_t sel_pref_fifo_status; + /* + * [0x40] S2M completion FIFO status. + * Status of the selected queue in S2M_indirect_ctrl + */ + uint32_t sel_comp_fifo_status; + /* [0x44] S2M state machine and FIFO clear control */ + uint32_t clear_ctrl; + /* [0x48] S2M Misc Check enable */ + uint32_t check_en; + /* [0x4c] S2M FIFO enable control, internal */ + uint32_t fifo_en; + /* [0x50] Stream interface configuration */ + uint32_t stream_cfg; + uint32_t rsrvd[43]; +}; +struct udma_s2m_rd { + /* [0x0] S2M descriptor prefetch configuration */ + uint32_t desc_pref_cfg_1; + /* [0x4] S2M descriptor prefetch configuration */ + uint32_t desc_pref_cfg_2; + /* [0x8] S2M descriptor prefetch configuration */ + uint32_t desc_pref_cfg_3; + /* [0xc] S2M descriptor prefetch configuration */ + uint32_t desc_pref_cfg_4; + uint32_t rsrvd[12]; +}; +struct udma_s2m_wr { + /* [0x0] Stream data FIFO configuration */ + uint32_t data_cfg_1; + /* [0x4] Data write configuration */ + uint32_t data_cfg_2; + uint32_t rsrvd[14]; +}; +struct udma_s2m_comp { + /* [0x0] Completion controller configuration */ + uint32_t cfg_1c; + /* [0x4] Completion controller configuration */ + uint32_t cfg_2c; + uint32_t rsrvd_0; + /* [0xc] Completion controller application acknowledge configuration */ + uint32_t cfg_application_ack; + uint32_t rsrvd[12]; +}; +struct udma_s2m_stat { + uint32_t rsrvd_0; + /* [0x4] Number of dropped packets */ + uint32_t drop_pkt; + /* + * [0x8] Counting the net length of the data buffers [64-bit] + * Should be read before rx_bytes_high + */ + uint32_t rx_bytes_low; + /* + * [0xc] Counting the net length of the data buffers [64-bit] + * Should be read after tx_bytes_low (value is sampled when reading + * Should be read before rx_bytes_low + */ + uint32_t rx_bytes_high; + /* [0x10] Total number of descriptors read from the host memory */ + uint32_t prefed_desc; + /* [0x14] Number of packets written into the completion ring */ + uint32_t comp_pkt; + /* [0x18] Number of descriptors written into the completion ring */ + uint32_t comp_desc; + /* + * [0x1c] Number of acknowledged packets. + * (acknowledge sent to the stream interface) + */ + uint32_t ack_pkts; + uint32_t rsrvd[56]; +}; +struct udma_s2m_feature { + /* + * [0x0] S2M Feature register + * S2M instantiation parameters + */ + uint32_t reg_1; + /* [0x4] Reserved S2M feature register */ + uint32_t reg_2; + /* + * [0x8] S2M Feature register + * S2M instantiation parameters + */ + uint32_t reg_3; + /* + * [0xc] S2M Feature register. + * S2M instantiation parameters. + */ + uint32_t reg_4; + /* + * [0x10] S2M Feature register. + * S2M instantiation parameters. + */ + uint32_t reg_5; + /* [0x14] S2M Feature register. S2M instantiation parameters. */ + uint32_t reg_6; + uint32_t rsrvd[58]; +}; +struct udma_s2m_q { + uint32_t rsrvd_0[8]; + /* [0x20] S2M Descriptor ring configuration */ + uint32_t cfg; + /* [0x24] S2M Descriptor ring status and information */ + uint32_t status; + /* [0x28] Rx Descriptor Ring Base Pointer [31:4] */ + uint32_t rdrbp_low; + /* [0x2c] Rx Descriptor Ring Base Pointer [63:32] */ + uint32_t rdrbp_high; + /* + * [0x30] Rx Descriptor Ring Length[23:2] + */ + uint32_t rdrl; + /* [0x34] RX Descriptor Ring Head Pointer */ + uint32_t rdrhp; + /* [0x38] Rx Descriptor Tail Pointer increment */ + uint32_t rdrtp_inc; + /* [0x3c] Rx Descriptor Tail Pointer */ + uint32_t rdrtp; + /* [0x40] RX Descriptor Current Pointer */ + uint32_t rdcp; + /* [0x44] Rx Completion Ring Base Pointer [31:4] */ + uint32_t rcrbp_low; + /* [0x48] Rx Completion Ring Base Pointer [63:32] */ + uint32_t rcrbp_high; + /* [0x4c] Rx Completion Ring Head Pointer */ + uint32_t rcrhp; + /* + * [0x50] RX Completion Ring Head Pointer internal. + * (Before the coalescing FIFO) + */ + uint32_t rcrhp_internal; + /* [0x54] Completion controller configuration for the queue */ + uint32_t comp_cfg; + /* [0x58] Completion controller configuration for the queue */ + uint32_t comp_cfg_2; + /* [0x5c] Packet handler configuration */ + uint32_t pkt_cfg; + /* [0x60] Queue QoS configuration */ + uint32_t qos_cfg; + /* [0x64] DMB software control */ + uint32_t q_sw_ctrl; + /* [0x68] Number of S2M Rx packets after completion */ + uint32_t q_rx_pkt; + uint32_t rsrvd[997]; +}; + +struct udma_s2m_regs { + uint32_t rsrvd_0[64]; + struct udma_axi_s2m axi_s2m; /* [0x100] */ + struct udma_s2m s2m; /* [0x200] */ + struct udma_s2m_rd s2m_rd; /* [0x300] */ + struct udma_s2m_wr s2m_wr; /* [0x340] */ + struct udma_s2m_comp s2m_comp; /* [0x380] */ + uint32_t rsrvd_1[80]; + struct udma_s2m_stat s2m_stat; /* [0x500] */ + struct udma_s2m_feature s2m_feature; /* [0x600] */ + uint32_t rsrvd_2[576]; + struct udma_s2m_q s2m_q[4]; /* [0x1000] */ +}; + + +/* +* Registers Fields +*/ + + +/**** data_wr_cfg_1 register ****/ +/* AXI write ID (AWID) */ +#define UDMA_AXI_S2M_DATA_WR_CFG_1_AWID_MASK 0x000000FF +#define UDMA_AXI_S2M_DATA_WR_CFG_1_AWID_SHIFT 0 +/* Cache Type */ +#define UDMA_AXI_S2M_DATA_WR_CFG_1_AWCACHE_MASK 0x000F0000 +#define UDMA_AXI_S2M_DATA_WR_CFG_1_AWCACHE_SHIFT 16 +/* Burst type */ +#define UDMA_AXI_S2M_DATA_WR_CFG_1_AWBURST_MASK 0x03000000 +#define UDMA_AXI_S2M_DATA_WR_CFG_1_AWBURST_SHIFT 24 + +/**** data_wr_cfg_2 register ****/ +/* User extension */ +#define UDMA_AXI_S2M_DATA_WR_CFG_2_AWUSER_MASK 0x000FFFFF +#define UDMA_AXI_S2M_DATA_WR_CFG_2_AWUSER_SHIFT 0 +/* Bus size, 128-bit */ +#define UDMA_AXI_S2M_DATA_WR_CFG_2_AWSIZE_MASK 0x00700000 +#define UDMA_AXI_S2M_DATA_WR_CFG_2_AWSIZE_SHIFT 20 +/* + * AXI Master QoS. + * Used for arbitration between AXI masters + */ +#define UDMA_AXI_S2M_DATA_WR_CFG_2_AWQOS_MASK 0x07000000 +#define UDMA_AXI_S2M_DATA_WR_CFG_2_AWQOS_SHIFT 24 +/* Protection Type */ +#define UDMA_AXI_S2M_DATA_WR_CFG_2_AWPROT_MASK 0x70000000 +#define UDMA_AXI_S2M_DATA_WR_CFG_2_AWPROT_SHIFT 28 + +/**** desc_rd_cfg_4 register ****/ +/* AXI read ID (ARID) */ +#define UDMA_AXI_S2M_DESC_RD_CFG_4_ARID_MASK 0x000000FF +#define UDMA_AXI_S2M_DESC_RD_CFG_4_ARID_SHIFT 0 +/* Cache Type */ +#define UDMA_AXI_S2M_DESC_RD_CFG_4_ARCACHE_MASK 0x000F0000 +#define UDMA_AXI_S2M_DESC_RD_CFG_4_ARCACHE_SHIFT 16 +/* Burst type */ +#define UDMA_AXI_S2M_DESC_RD_CFG_4_ARBURST_MASK 0x03000000 +#define UDMA_AXI_S2M_DESC_RD_CFG_4_ARBURST_SHIFT 24 + +/**** desc_rd_cfg_5 register ****/ +/* User extension */ +#define UDMA_AXI_S2M_DESC_RD_CFG_5_ARUSER_MASK 0x000FFFFF +#define UDMA_AXI_S2M_DESC_RD_CFG_5_ARUSER_SHIFT 0 +/* Bus size, 128-bit */ +#define UDMA_AXI_S2M_DESC_RD_CFG_5_ARSIZE_MASK 0x00700000 +#define UDMA_AXI_S2M_DESC_RD_CFG_5_ARSIZE_SHIFT 20 +/* + * AXI Master QoS. + * Used for arbitration between AXI masters + */ +#define UDMA_AXI_S2M_DESC_RD_CFG_5_ARQOS_MASK 0x07000000 +#define UDMA_AXI_S2M_DESC_RD_CFG_5_ARQOS_SHIFT 24 +/* Protection Type */ +#define UDMA_AXI_S2M_DESC_RD_CFG_5_ARPROT_MASK 0x70000000 +#define UDMA_AXI_S2M_DESC_RD_CFG_5_ARPROT_SHIFT 28 + +/**** comp_wr_cfg_1 register ****/ +/* AXI write ID (AWID) */ +#define UDMA_AXI_S2M_COMP_WR_CFG_1_AWID_MASK 0x000000FF +#define UDMA_AXI_S2M_COMP_WR_CFG_1_AWID_SHIFT 0 +/* Cache Type */ +#define UDMA_AXI_S2M_COMP_WR_CFG_1_AWCACHE_MASK 0x000F0000 +#define UDMA_AXI_S2M_COMP_WR_CFG_1_AWCACHE_SHIFT 16 +/* Burst type */ +#define UDMA_AXI_S2M_COMP_WR_CFG_1_AWBURST_MASK 0x03000000 +#define UDMA_AXI_S2M_COMP_WR_CFG_1_AWBURST_SHIFT 24 + +/**** comp_wr_cfg_2 register ****/ +/* User extension */ +#define UDMA_AXI_S2M_COMP_WR_CFG_2_AWUSER_MASK 0x000FFFFF +#define UDMA_AXI_S2M_COMP_WR_CFG_2_AWUSER_SHIFT 0 +/* Bus size, 128-bit */ +#define UDMA_AXI_S2M_COMP_WR_CFG_2_AWSIZE_MASK 0x00700000 +#define UDMA_AXI_S2M_COMP_WR_CFG_2_AWSIZE_SHIFT 20 +/* + * AXI Master QoS. + * Used for arbitration between AXI masters + */ +#define UDMA_AXI_S2M_COMP_WR_CFG_2_AWQOS_MASK 0x07000000 +#define UDMA_AXI_S2M_COMP_WR_CFG_2_AWQOS_SHIFT 24 +/* Protection Type */ +#define UDMA_AXI_S2M_COMP_WR_CFG_2_AWPROT_MASK 0x70000000 +#define UDMA_AXI_S2M_COMP_WR_CFG_2_AWPROT_SHIFT 28 + +/**** data_wr_cfg register ****/ +/* + * Defines the maximum number of AXI beats for a single AXI burst. This value is + * used for the burst split decision. + */ +#define UDMA_AXI_S2M_DATA_WR_CFG_MAX_AXI_BEATS_MASK 0x000000FF +#define UDMA_AXI_S2M_DATA_WR_CFG_MAX_AXI_BEATS_SHIFT 0 + +/**** desc_rd_cfg_3 register ****/ +/* + * Defines the maximum number of AXI beats for a single AXI burst. This value is + * used for the burst split decision. + */ +#define UDMA_AXI_S2M_DESC_RD_CFG_3_MAX_AXI_BEATS_MASK 0x000000FF +#define UDMA_AXI_S2M_DESC_RD_CFG_3_MAX_AXI_BEATS_SHIFT 0 +/* + * Enables breaking descriptor read request. + * Aligned to max_AXI_beats when the total read size is less than max_AXI_beats. + */ +#define UDMA_AXI_S2M_DESC_RD_CFG_3_ALWAYS_BREAK_ON_MAX_BOUDRY (1 << 16) + +/**** desc_wr_cfg_1 register ****/ +/* + * Defines the maximum number of AXI beats for a single AXI burst. This value is + * used for the burst split decision. + */ +#define UDMA_AXI_S2M_DESC_WR_CFG_1_MAX_AXI_BEATS_MASK 0x000000FF +#define UDMA_AXI_S2M_DESC_WR_CFG_1_MAX_AXI_BEATS_SHIFT 0 +/* + * Minimum burst for writing completion descriptors. + * (AXI beats). + * Value must be aligned to cache lines (64 bytes). + * Default value is 2 cache lines, 8 beats. + */ +#define UDMA_AXI_S2M_DESC_WR_CFG_1_MIN_AXI_BEATS_MASK 0x00FF0000 +#define UDMA_AXI_S2M_DESC_WR_CFG_1_MIN_AXI_BEATS_SHIFT 16 + +/**** ostand_cfg_rd register ****/ +/* + * Maximum number of outstanding descriptor reads to the AXI. + * (AXI transactions). + */ +#define UDMA_AXI_S2M_OSTAND_CFG_RD_MAX_DESC_RD_OSTAND_MASK 0x0000003F +#define UDMA_AXI_S2M_OSTAND_CFG_RD_MAX_DESC_RD_OSTAND_SHIFT 0 +/* Maximum number of outstanding stream acknowledges. */ +#define UDMA_AXI_S2M_OSTAND_CFG_RD_MAX_STREAM_ACK_MASK 0x001F0000 +#define UDMA_AXI_S2M_OSTAND_CFG_RD_MAX_STREAM_ACK_SHIFT 16 + +/**** ostand_cfg_wr register ****/ +/* + * Maximum number of outstanding data writes to the AXI. + * (AXI transactions). + */ +#define UDMA_AXI_S2M_OSTAND_CFG_WR_MAX_DATA_WR_OSTAND_MASK 0x0000003F +#define UDMA_AXI_S2M_OSTAND_CFG_WR_MAX_DATA_WR_OSTAND_SHIFT 0 +/* + * Maximum number of outstanding data beats for data write to AXI. + * (AXI beats). + */ +#define UDMA_AXI_S2M_OSTAND_CFG_WR_MAX_DATA_BEATS_WR_OSTAND_MASK 0x0000FF00 +#define UDMA_AXI_S2M_OSTAND_CFG_WR_MAX_DATA_BEATS_WR_OSTAND_SHIFT 8 +/* + * Maximum number of outstanding descriptor writes to the AXI. + * (AXI transactions). + */ +#define UDMA_AXI_S2M_OSTAND_CFG_WR_MAX_COMP_REQ_MASK 0x003F0000 +#define UDMA_AXI_S2M_OSTAND_CFG_WR_MAX_COMP_REQ_SHIFT 16 +/* + * Maximum number of outstanding data beats for descriptor write to AXI. + * (AXI beats). + */ +#define UDMA_AXI_S2M_OSTAND_CFG_WR_MAX_COMP_DATA_WR_OSTAND_MASK 0xFF000000 +#define UDMA_AXI_S2M_OSTAND_CFG_WR_MAX_COMP_DATA_WR_OSTAND_SHIFT 24 + +/**** state register ****/ + +#define UDMA_S2M_STATE_COMP_CTRL_MASK 0x00000003 +#define UDMA_S2M_STATE_COMP_CTRL_SHIFT 0 + +#define UDMA_S2M_STATE_STREAM_IF_MASK 0x00000030 +#define UDMA_S2M_STATE_STREAM_IF_SHIFT 4 + +#define UDMA_S2M_STATE_DATA_WR_CTRL_MASK 0x00000300 +#define UDMA_S2M_STATE_DATA_WR_CTRL_SHIFT 8 + +#define UDMA_S2M_STATE_DESC_PREF_MASK 0x00003000 +#define UDMA_S2M_STATE_DESC_PREF_SHIFT 12 + +#define UDMA_S2M_STATE_AXI_WR_DATA_MASK 0x00030000 +#define UDMA_S2M_STATE_AXI_WR_DATA_SHIFT 16 + +/**** change_state register ****/ +/* Start normal operation */ +#define UDMA_S2M_CHANGE_STATE_NORMAL (1 << 0) +/* Stop normal operation */ +#define UDMA_S2M_CHANGE_STATE_DIS (1 << 1) +/* + * Stop all machines. + * (Prefetch, scheduling, completion and stream interface) + */ +#define UDMA_S2M_CHANGE_STATE_ABORT (1 << 2) + +/**** clear_err_log register ****/ +/* Clear error log */ +#define UDMA_S2M_CLEAR_ERR_LOG_CLEAR (1 << 0) + +/**** s_data_fifo_status register ****/ +/* FIFO used indication */ +#define UDMA_S2M_S_DATA_FIFO_STATUS_USED_MASK 0x0000FFFF +#define UDMA_S2M_S_DATA_FIFO_STATUS_USED_SHIFT 0 +/* FIFO empty indication */ +#define UDMA_S2M_S_DATA_FIFO_STATUS_EMPTY (1 << 24) +/* FIFO full indication */ +#define UDMA_S2M_S_DATA_FIFO_STATUS_FULL (1 << 28) + +/**** s_header_fifo_status register ****/ +/* FIFO used indication */ +#define UDMA_S2M_S_HEADER_FIFO_STATUS_USED_MASK 0x0000FFFF +#define UDMA_S2M_S_HEADER_FIFO_STATUS_USED_SHIFT 0 +/* FIFO empty indication */ +#define UDMA_S2M_S_HEADER_FIFO_STATUS_EMPTY (1 << 24) +/* FIFO full indication */ +#define UDMA_S2M_S_HEADER_FIFO_STATUS_FULL (1 << 28) + +/**** axi_data_fifo_status register ****/ +/* FIFO used indication */ +#define UDMA_S2M_AXI_DATA_FIFO_STATUS_USED_MASK 0x0000FFFF +#define UDMA_S2M_AXI_DATA_FIFO_STATUS_USED_SHIFT 0 +/* FIFO empty indication */ +#define UDMA_S2M_AXI_DATA_FIFO_STATUS_EMPTY (1 << 24) +/* FIFO full indication */ +#define UDMA_S2M_AXI_DATA_FIFO_STATUS_FULL (1 << 28) + +/**** unack_fifo_status register ****/ +/* FIFO used indication */ +#define UDMA_S2M_UNACK_FIFO_STATUS_USED_MASK 0x0000FFFF +#define UDMA_S2M_UNACK_FIFO_STATUS_USED_SHIFT 0 +/* FIFO empty indication */ +#define UDMA_S2M_UNACK_FIFO_STATUS_EMPTY (1 << 24) +/* FIFO full indication */ +#define UDMA_S2M_UNACK_FIFO_STATUS_FULL (1 << 28) + +/**** indirect_ctrl register ****/ +/* Selected queue for status read */ +#define UDMA_S2M_INDIRECT_CTRL_Q_NUM_MASK 0x00000FFF +#define UDMA_S2M_INDIRECT_CTRL_Q_NUM_SHIFT 0 + +/**** sel_pref_fifo_status register ****/ +/* FIFO used indication */ +#define UDMA_S2M_SEL_PREF_FIFO_STATUS_USED_MASK 0x0000FFFF +#define UDMA_S2M_SEL_PREF_FIFO_STATUS_USED_SHIFT 0 +/* FIFO empty indication */ +#define UDMA_S2M_SEL_PREF_FIFO_STATUS_EMPTY (1 << 24) +/* FIFO full indication */ +#define UDMA_S2M_SEL_PREF_FIFO_STATUS_FULL (1 << 28) + +/**** sel_comp_fifo_status register ****/ +/* FIFO used indication */ +#define UDMA_S2M_SEL_COMP_FIFO_STATUS_USED_MASK 0x0000FFFF +#define UDMA_S2M_SEL_COMP_FIFO_STATUS_USED_SHIFT 0 +/* Coalescing ACTIVE FSM state indication. */ +#define UDMA_S2M_SEL_COMP_FIFO_STATUS_COAL_ACTIVE_STATE_MASK 0x00300000 +#define UDMA_S2M_SEL_COMP_FIFO_STATUS_COAL_ACTIVE_STATE_SHIFT 20 +/* FIFO empty indication */ +#define UDMA_S2M_SEL_COMP_FIFO_STATUS_EMPTY (1 << 24) +/* FIFO full indication */ +#define UDMA_S2M_SEL_COMP_FIFO_STATUS_FULL (1 << 28) + +/**** stream_cfg register ****/ +/* + * Disables the stream interface operation. + * Changing to 1 stops at the end of packet reception. + */ +#define UDMA_S2M_STREAM_CFG_DISABLE (1 << 0) +/* + * Flush the stream interface operation. + * Changing to 1 stops at the end of packet reception and assert ready to the + * stream I/F. + */ +#define UDMA_S2M_STREAM_CFG_FLUSH (1 << 4) +/* Stop descriptor prefetch when the stream is disabled and the S2M is idle. */ +#define UDMA_S2M_STREAM_CFG_STOP_PREFETCH (1 << 8) + +/**** desc_pref_cfg_1 register ****/ +/* + * Size of the descriptor prefetch FIFO. + * (descriptors) + */ +#define UDMA_S2M_RD_DESC_PREF_CFG_1_FIFO_DEPTH_MASK 0x000000FF +#define UDMA_S2M_RD_DESC_PREF_CFG_1_FIFO_DEPTH_SHIFT 0 + +/**** desc_pref_cfg_2 register ****/ +/* Enable promotion of the current queue in progress */ +#define UDMA_S2M_RD_DESC_PREF_CFG_2_Q_PROMOTION (1 << 0) +/* Force promotion of the current queue in progress */ +#define UDMA_S2M_RD_DESC_PREF_CFG_2_FORCE_PROMOTION (1 << 1) +/* Enable prefetch prediction of next packet in line. */ +#define UDMA_S2M_RD_DESC_PREF_CFG_2_EN_PREF_PREDICTION (1 << 2) +/* + * Threshold for queue promotion. + * Queue is promoted for prefetch if there are less descriptors in the prefetch + * FIFO than the threshold + */ +#define UDMA_S2M_RD_DESC_PREF_CFG_2_PROMOTION_TH_MASK 0x0000FF00 +#define UDMA_S2M_RD_DESC_PREF_CFG_2_PROMOTION_TH_SHIFT 8 +/* + * Force RR arbitration in the prefetch arbiter. + * 0 - Standard arbitration based on queue QoS + * 1 - Force round robin arbitration + */ +#define UDMA_S2M_RD_DESC_PREF_CFG_2_PREF_FORCE_RR (1 << 16) + +/**** desc_pref_cfg_3 register ****/ +/* + * Minimum descriptor burst size when prefetch FIFO level is below the + * descriptor prefetch threshold + * (must be 1) + */ +#define UDMA_S2M_RD_DESC_PREF_CFG_3_MIN_BURST_BELOW_THR_MASK 0x0000000F +#define UDMA_S2M_RD_DESC_PREF_CFG_3_MIN_BURST_BELOW_THR_SHIFT 0 +/* + * Minimum descriptor burst size when prefetch FIFO level is above the + * descriptor prefetch threshold + */ +#define UDMA_S2M_RD_DESC_PREF_CFG_3_MIN_BURST_ABOVE_THR_MASK 0x000000F0 +#define UDMA_S2M_RD_DESC_PREF_CFG_3_MIN_BURST_ABOVE_THR_SHIFT 4 +/* + * Descriptor fetch threshold. + * Used as a threshold to determine the allowed minimum descriptor burst size. + * (Must be at least "max_desc_per_pkt") + */ +#define UDMA_S2M_RD_DESC_PREF_CFG_3_PREF_THR_MASK 0x0000FF00 +#define UDMA_S2M_RD_DESC_PREF_CFG_3_PREF_THR_SHIFT 8 + +/**** desc_pref_cfg_4 register ****/ +/* + * Used as a threshold for generating almost FULL indication to the application + */ +#define UDMA_S2M_RD_DESC_PREF_CFG_4_A_FULL_THR_MASK 0x000000FF +#define UDMA_S2M_RD_DESC_PREF_CFG_4_A_FULL_THR_SHIFT 0 + +/**** data_cfg_1 register ****/ +/* + * Maximum number of data beats in the data write FIFO. + * Defined based on data FIFO size + * (default FIFO size 512B → 32 beats) + */ +#define UDMA_S2M_WR_DATA_CFG_1_DATA_FIFO_DEPTH_MASK 0x000003FF +#define UDMA_S2M_WR_DATA_CFG_1_DATA_FIFO_DEPTH_SHIFT 0 +/* + * Maximum number of packets in the data write FIFO. + * Defined based on header FIFO size + */ +#define UDMA_S2M_WR_DATA_CFG_1_MAX_PKT_LIMIT_MASK 0x00FF0000 +#define UDMA_S2M_WR_DATA_CFG_1_MAX_PKT_LIMIT_SHIFT 16 +/* + * Internal use + * Data FIFO margin + */ +#define UDMA_S2M_WR_DATA_CFG_1_FIFO_MARGIN_MASK 0xFF000000 +#define UDMA_S2M_WR_DATA_CFG_1_FIFO_MARGIN_SHIFT 24 + +/**** data_cfg_2 register ****/ +/* + * Drop timer. + * Waiting time for the host to write new descriptor to the queue + * (for the current packet in process) + */ +#define UDMA_S2M_WR_DATA_CFG_2_DESC_WAIT_TIMER_MASK 0x00FFFFFF +#define UDMA_S2M_WR_DATA_CFG_2_DESC_WAIT_TIMER_SHIFT 0 +/* + * Drop enable. + * Enable packet drop if there are no available descriptors in the system for + * this queue + */ +#define UDMA_S2M_WR_DATA_CFG_2_DROP_IF_NO_DESC (1 << 27) +/* + * Lack of descriptors hint. + * Generate interrupt when a packet is waiting but there are no available + * descriptors in the queue + */ +#define UDMA_S2M_WR_DATA_CFG_2_HINT_IF_NO_DESC (1 << 28) +/* + * Drop conditions + * Wait until a descriptor is available in the prefetch FIFO or the host before + * dropping packet. + * 1 - Drop if a descriptor is not available in the prefetch. + * 0 - Drop if a descriptor is not available in the system + */ +#define UDMA_S2M_WR_DATA_CFG_2_WAIT_FOR_PREF (1 << 29) +/* + * DRAM write optimization + * 0 - Data write with byte enable + * 1 - Data write is always in Full AXI bus width (128 bit) + */ +#define UDMA_S2M_WR_DATA_CFG_2_FULL_LINE_MODE (1 << 30) +/* + * Direct data write address + * 1 - Use buffer 1 instead of buffer 2 when direct data placement is used with + * header split. + * 0 - Use buffer 2 for the header. + */ +#define UDMA_S2M_WR_DATA_CFG_2_DIRECT_HDR_USE_BUF1 (1 << 31) + +/**** cfg_1c register ****/ +/* + * Completion descriptor size. + * (words) + */ +#define UDMA_S2M_COMP_CFG_1C_DESC_SIZE_MASK 0x0000000F +#define UDMA_S2M_COMP_CFG_1C_DESC_SIZE_SHIFT 0 +/* + * Completion queue counter configuration. + * Completion FIFO in use counter measured in words or descriptors + * 1 - Words + * 0 - Descriptors + */ +#define UDMA_S2M_COMP_CFG_1C_CNT_WORDS (1 << 8) +/* + * Enable promotion of the current queue in progress in the completion write + * scheduler. + */ +#define UDMA_S2M_COMP_CFG_1C_Q_PROMOTION (1 << 12) +/* Force RR arbitration in the completion arbiter */ +#define UDMA_S2M_COMP_CFG_1C_FORCE_RR (1 << 16) +/* Minimum number of free completion entries to qualify for promotion */ +#define UDMA_S2M_COMP_CFG_1C_Q_FREE_MIN_MASK 0xF0000000 +#define UDMA_S2M_COMP_CFG_1C_Q_FREE_MIN_SHIFT 28 + +/**** cfg_2c register ****/ +/* + * Completion FIFO size. + * (words per queue) + */ +#define UDMA_S2M_COMP_CFG_2C_COMP_FIFO_DEPTH_MASK 0x00000FFF +#define UDMA_S2M_COMP_CFG_2C_COMP_FIFO_DEPTH_SHIFT 0 +/* + * Unacknowledged FIFO size. + * (descriptors) + */ +#define UDMA_S2M_COMP_CFG_2C_UNACK_FIFO_DEPTH_MASK 0x0FFF0000 +#define UDMA_S2M_COMP_CFG_2C_UNACK_FIFO_DEPTH_SHIFT 16 + +/**** reg_1 register ****/ +/* + * Descriptor prefetch FIFO size + * (descriptors) + */ +#define UDMA_S2M_FEATURE_REG_1_DESC_PREFERCH_FIFO_DEPTH_MASK 0x000000FF +#define UDMA_S2M_FEATURE_REG_1_DESC_PREFERCH_FIFO_DEPTH_SHIFT 0 + +/**** reg_3 register ****/ +/* + * Maximum number of data beats in the data write FIFO. + * Defined based on data FIFO size + * (default FIFO size 512B →32 beats) + */ +#define UDMA_S2M_FEATURE_REG_3_DATA_FIFO_DEPTH_MASK 0x000003FF +#define UDMA_S2M_FEATURE_REG_3_DATA_FIFO_DEPTH_SHIFT 0 +/* + * Maximum number of packets in the data write FIFO. + * Defined based on header FIFO size + */ +#define UDMA_S2M_FEATURE_REG_3_DATA_WR_MAX_PKT_LIMIT_MASK 0x00FF0000 +#define UDMA_S2M_FEATURE_REG_3_DATA_WR_MAX_PKT_LIMIT_SHIFT 16 + +/**** reg_4 register ****/ +/* + * Completion FIFO size. + * (words per queue) + */ +#define UDMA_S2M_FEATURE_REG_4_COMP_FIFO_DEPTH_MASK 0x00000FFF +#define UDMA_S2M_FEATURE_REG_4_COMP_FIFO_DEPTH_SHIFT 0 +/* + * Unacknowledged FIFO size. + * (descriptors) + */ +#define UDMA_S2M_FEATURE_REG_4_COMP_UNACK_FIFO_DEPTH_MASK 0x0FFF0000 +#define UDMA_S2M_FEATURE_REG_4_COMP_UNACK_FIFO_DEPTH_SHIFT 16 + +/**** reg_5 register ****/ +/* Maximum number of outstanding data writes to the AXI */ +#define UDMA_S2M_FEATURE_REG_5_MAX_DATA_WR_OSTAND_MASK 0x0000003F +#define UDMA_S2M_FEATURE_REG_5_MAX_DATA_WR_OSTAND_SHIFT 0 +/* + * Maximum number of outstanding data beats for data write to AXI. + * (AXI beats) + */ +#define UDMA_S2M_FEATURE_REG_5_MAX_DATA_BEATS_WR_OSTAND_MASK 0x0000FF00 +#define UDMA_S2M_FEATURE_REG_5_MAX_DATA_BEATS_WR_OSTAND_SHIFT 8 +/* + * Maximum number of outstanding descriptor reads to the AXI. + * (AXI transactions) + */ +#define UDMA_S2M_FEATURE_REG_5_MAX_COMP_REQ_MASK 0x003F0000 +#define UDMA_S2M_FEATURE_REG_5_MAX_COMP_REQ_SHIFT 16 +/* + * Maximum number of outstanding data beats for descriptor write to AXI. + * (AXI beats) + */ +#define UDMA_S2M_FEATURE_REG_5_MAX_COMP_DATA_WR_OSTAND_MASK 0xFF000000 +#define UDMA_S2M_FEATURE_REG_5_MAX_COMP_DATA_WR_OSTAND_SHIFT 24 + +/**** reg_6 register ****/ +/* Maximum number of outstanding descriptor reads to the AXI */ +#define UDMA_S2M_FEATURE_REG_6_MAX_DESC_RD_OSTAND_MASK 0x0000003F +#define UDMA_S2M_FEATURE_REG_6_MAX_DESC_RD_OSTAND_SHIFT 0 +/* Maximum number of outstanding stream acknowledges */ +#define UDMA_S2M_FEATURE_REG_6_MAX_STREAM_ACK_MASK 0x001F0000 +#define UDMA_S2M_FEATURE_REG_6_MAX_STREAM_ACK_SHIFT 16 + +/**** cfg register ****/ +/* + * Configure the AXI AWCACHE + * for header write. + */ +#define UDMA_S2M_Q_CFG_AXI_AWCACHE_HDR_MASK 0x0000000F +#define UDMA_S2M_Q_CFG_AXI_AWCACHE_HDR_SHIFT 0 +/* + * Configure the AXI AWCACHE + * for data write. + */ +#define UDMA_S2M_Q_CFG_AXI_AWCACHE_DATA_MASK 0x000000F0 +#define UDMA_S2M_Q_CFG_AXI_AWCACHE_DATA_SHIFT 4 +/* + * Enable operation of this queue. + * Start prefetch. + */ +#define UDMA_S2M_Q_CFG_EN_PREF (1 << 16) +/* Enables the reception of packets from the stream to this queue */ +#define UDMA_S2M_Q_CFG_EN_STREAM (1 << 17) +/* Allow prefetch of less than minimum prefetch burst size. */ +#define UDMA_S2M_Q_CFG_ALLOW_LT_MIN_PREF (1 << 20) +/* + * Configure the AXI AWCACHE + * for completion descriptor write + */ +#define UDMA_S2M_Q_CFG_AXI_AWCACHE_COMP_MASK 0x0F000000 +#define UDMA_S2M_Q_CFG_AXI_AWCACHE_COMP_SHIFT 24 +/* + * AXI QoS + * This value is used in AXI transactions associated with this queue and the + * prefetch and completion arbiters. + */ +#define UDMA_S2M_Q_CFG_AXI_QOS_MASK 0x70000000 +#define UDMA_S2M_Q_CFG_AXI_QOS_SHIFT 28 + +/**** status register ****/ +/* Indicates how many entries are used in the Queue */ +#define UDMA_S2M_Q_STATUS_Q_USED_MASK 0x01FFFFFF +#define UDMA_S2M_Q_STATUS_Q_USED_SHIFT 0 +/* + * prefetch status + * 0 – prefetch operation is stopped + * 1 – prefetch is operational + */ +#define UDMA_S2M_Q_STATUS_PREFETCH (1 << 28) +/* + * Queue receive status + * 0 -queue RX operation is stopped + * 1 – RX queue is active and processing packets + */ +#define UDMA_S2M_Q_STATUS_RX (1 << 29) +/* + * Indicates if the queue is full. + * (Used by the host when head pointer equals tail pointer) + */ +#define UDMA_S2M_Q_STATUS_Q_FULL (1 << 31) +/* + * S2M Descriptor Ring Base address [31:4]. + * Value of the base address of the S2M descriptor ring + * [3:0] - 0 - 16B alignment is enforced + * ([11:4] should be 0 for 4KB alignment) + */ +#define UDMA_S2M_Q_RDRBP_LOW_ADDR_MASK 0xFFFFFFF0 +#define UDMA_S2M_Q_RDRBP_LOW_ADDR_SHIFT 4 + +/**** RDRL register ****/ +/* + * Length of the descriptor ring. + * (descriptors) + * Associated with the ring base address ends at maximum burst size alignment + */ +#define UDMA_S2M_Q_RDRL_OFFSET_MASK 0x00FFFFFF +#define UDMA_S2M_Q_RDRL_OFFSET_SHIFT 0 + +/**** RDRHP register ****/ +/* + * Relative offset of the next descriptor that needs to be read into the + * prefetch FIFO. + * Incremented when the DMA reads valid descriptors from the host memory to the + * prefetch FIFO. + * Note that this is the offset in # of descriptors and not in byte address. + */ +#define UDMA_S2M_Q_RDRHP_OFFSET_MASK 0x00FFFFFF +#define UDMA_S2M_Q_RDRHP_OFFSET_SHIFT 0 +/* Ring ID */ +#define UDMA_S2M_Q_RDRHP_RING_ID_MASK 0xC0000000 +#define UDMA_S2M_Q_RDRHP_RING_ID_SHIFT 30 + +/**** RDRTP_inc register ****/ +/* + * Increments the value in Q_RDRTP with the value written to this field in + * number of descriptors. + */ +#define UDMA_S2M_Q_RDRTP_INC_VAL_MASK 0x00FFFFFF +#define UDMA_S2M_Q_RDRTP_INC_VAL_SHIFT 0 + +/**** RDRTP register ****/ +/* + * Relative offset of the next free descriptor in the host memory. + * Note that this is the offset in # of descriptors and not in byte address. + */ +#define UDMA_S2M_Q_RDRTP_OFFSET_MASK 0x00FFFFFF +#define UDMA_S2M_Q_RDRTP_OFFSET_SHIFT 0 +/* Ring ID */ +#define UDMA_S2M_Q_RDRTP_RING_ID_MASK 0xC0000000 +#define UDMA_S2M_Q_RDRTP_RING_ID_SHIFT 30 + +/**** RDCP register ****/ +/* Relative offset of the first descriptor in the prefetch FIFO. */ +#define UDMA_S2M_Q_RDCP_OFFSET_MASK 0x00FFFFFF +#define UDMA_S2M_Q_RDCP_OFFSET_SHIFT 0 +/* Ring ID */ +#define UDMA_S2M_Q_RDCP_RING_ID_MASK 0xC0000000 +#define UDMA_S2M_Q_RDCP_RING_ID_SHIFT 30 +/* + * S2M Descriptor Ring Base address [31:4]. + * Value of the base address of the S2M descriptor ring + * [3:0] - 0 - 16B alignment is enforced + * ([11:4] Must be 0 for 4KB alignment) + * NOTE: + * Length of the descriptor ring (in descriptors) associated with the ring base + * address ends at maximum burst size alignment + */ +#define UDMA_S2M_Q_RCRBP_LOW_ADDR_MASK 0xFFFFFFF0 +#define UDMA_S2M_Q_RCRBP_LOW_ADDR_SHIFT 4 + +/**** RCRHP register ****/ +/* + * Relative offset of the next descriptor that needs to be updated by the + * completion controller. + * Note: This is in descriptors and not in byte address. + */ +#define UDMA_S2M_Q_RCRHP_OFFSET_MASK 0x00FFFFFF +#define UDMA_S2M_Q_RCRHP_OFFSET_SHIFT 0 +/* Ring ID */ +#define UDMA_S2M_Q_RCRHP_RING_ID_MASK 0xC0000000 +#define UDMA_S2M_Q_RCRHP_RING_ID_SHIFT 30 + +/**** RCRHP_internal register ****/ +/* + * Relative offset of the next descriptor that needs to be updated by the + * completion controller. + * Note: This is in descriptors and not in byte address. + */ +#define UDMA_S2M_Q_RCRHP_INTERNAL_OFFSET_MASK 0x00FFFFFF +#define UDMA_S2M_Q_RCRHP_INTERNAL_OFFSET_SHIFT 0 +/* Ring ID */ +#define UDMA_S2M_Q_RCRHP_INTERNAL_RING_ID_MASK 0xC0000000 +#define UDMA_S2M_Q_RCRHP_INTERNAL_RING_ID_SHIFT 30 + +/**** comp_cfg register ****/ +/* Enables writing to the completion ring. */ +#define UDMA_S2M_Q_COMP_CFG_EN_COMP_RING_UPDATE (1 << 0) +/* Disables the completion coalescing function. */ +#define UDMA_S2M_Q_COMP_CFG_DIS_COMP_COAL (1 << 1) +/* Reserved */ +#define UDMA_S2M_Q_COMP_CFG_FIRST_PKT_PROMOTION (1 << 2) +/* + * Buffer 2 location. + * Determines the position of the buffer 2 length in the S2M completion + * descriptor. + * 0 - WORD 1 [31:16] + * 1 - WORD 2 [31:16] + */ +#define UDMA_S2M_Q_COMP_CFG_BUF2_LEN_LOCATION (1 << 3) + +/**** pkt_cfg register ****/ +/* Header size. (bytes) */ +#define UDMA_S2M_Q_PKT_CFG_HDR_SPLIT_SIZE_MASK 0x0000FFFF +#define UDMA_S2M_Q_PKT_CFG_HDR_SPLIT_SIZE_SHIFT 0 +/* Force header split */ +#define UDMA_S2M_Q_PKT_CFG_FORCE_HDR_SPLIT (1 << 16) +/* Enable header split. */ +#define UDMA_S2M_Q_PKT_CFG_EN_HDR_SPLIT (1 << 17) + +/**** qos_cfg register ****/ +/* Queue QoS */ +#define UDMA_S2M_QOS_CFG_Q_QOS_MASK 0x000000FF +#define UDMA_S2M_QOS_CFG_Q_QOS_SHIFT 0 +/* Reset the tail pointer hardware. */ +#define UDMA_S2M_Q_SW_CTRL_RST_TAIL_PTR (1 << 1) +/* Reset the head pointer hardware. */ +#define UDMA_S2M_Q_SW_CTRL_RST_HEAD_PTR (1 << 2) +/* Reset the current pointer hardware. */ +#define UDMA_S2M_Q_SW_CTRL_RST_CURRENT_PTR (1 << 3) +/* Reset the prefetch FIFO */ +#define UDMA_S2M_Q_SW_CTRL_RST_PREFETCH (1 << 4) +/* Reset the queue */ +#define UDMA_S2M_Q_SW_CTRL_RST_Q (1 << 8) + +#ifdef __cplusplus +} +#endif + +#endif /* __AL_HAL_UDMA_S2M_REG_H */ diff --git a/eth/al_hal_an_lt_wrapper_regs.h b/eth/al_hal_an_lt_wrapper_regs.h new file mode 100644 index 00000000000..72b5cc66fb4 --- /dev/null +++ b/eth/al_hal_an_lt_wrapper_regs.h @@ -0,0 +1,264 @@ +/*- +******************************************************************************* +Copyright (C) 2015 Annapurna Labs Ltd. + +This file may be licensed under the terms of the Annapurna Labs Commercial +License Agreement. + +Alternatively, this file can be distributed under the terms of the GNU General +Public License V2 as published by the Free Software Foundation and can be +found at http://www.gnu.org/licenses/gpl-2.0.html + +Alternatively, redistribution and use in source and binary forms, with or +without modification, are permitted provided that the following conditions are +met: + + * Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in + the documentation and/or other materials provided with the + distribution. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR + ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +*******************************************************************************/ + +/** + * @{ + * @file al_hal_an_lt_wrapper_regs.h + * + * @brief ... registers + * + */ + +#ifndef __AL_HAL_AN_LT_wrapper_REGS_H__ +#define __AL_HAL_AN_LT_wrapper_REGS_H__ + +#include "al_hal_plat_types.h" + +#ifdef __cplusplus +extern "C" { +#endif +/* +* Unit Registers +*/ + + + +struct al_an_lt_wrapper_gen { + /* [0x0] AN LT wrapper Version */ + uint32_t version; + /* [0x4] AN LT general configuration */ + uint32_t cfg; + uint32_t rsrvd[14]; +}; +struct al_an_lt_wrapper_an_lt { + /* [0x0] AN LT register file address */ + uint32_t addr; + /* [0x4] PCS register file data */ + uint32_t data; + /* [0x8] AN LT control signals */ + uint32_t ctrl; + /* [0xc] AN LT status signals */ + uint32_t status; + uint32_t rsrvd[4]; +}; + +enum al_eth_an_lt_unit { + AL_ETH_AN_LT_UNIT_32_BIT = 0, + AL_ETH_AN_LT_UNIT_20_BIT = 1, + AL_ETH_AN_LT_UNIT_16_BIT = 2, +}; + +struct al_an_lt_wrapper_regs { + uint32_t rsrvd_0[64]; + struct al_an_lt_wrapper_gen gen; /* [0x100] */ + struct al_an_lt_wrapper_an_lt an_lt[3]; /* [0x140] */ +}; + + +/* +* Registers Fields +*/ + + +/**** version register ****/ +/* Revision number (Minor) */ +#define AN_LT_WRAPPER_GEN_VERSION_RELEASE_NUM_MINOR_MASK 0x000000FF +#define AN_LT_WRAPPER_GEN_VERSION_RELEASE_NUM_MINOR_SHIFT 0 +/* Revision number (Major) */ +#define AN_LT_WRAPPER_GEN_VERSION_RELEASE_NUM_MAJOR_MASK 0x0000FF00 +#define AN_LT_WRAPPER_GEN_VERSION_RELEASE_NUM_MAJOR_SHIFT 8 +/* Date of release */ +#define AN_LT_WRAPPER_GEN_VERSION_DATE_DAY_MASK 0x001F0000 +#define AN_LT_WRAPPER_GEN_VERSION_DATE_DAY_SHIFT 16 +/* Month of release */ +#define AN_LT_WRAPPER_GEN_VERSION_DATA_MONTH_MASK 0x01E00000 +#define AN_LT_WRAPPER_GEN_VERSION_DATA_MONTH_SHIFT 21 +/* Year of release (starting from 2000) */ +#define AN_LT_WRAPPER_GEN_VERSION_DATE_YEAR_MASK 0x3E000000 +#define AN_LT_WRAPPER_GEN_VERSION_DATE_YEAR_SHIFT 25 +/* Reserved */ +#define AN_LT_WRAPPER_GEN_VERSION_RESERVED_MASK 0xC0000000 +#define AN_LT_WRAPPER_GEN_VERSION_RESERVED_SHIFT 30 + +/**** cfg register ****/ +/* + * selection between different bus widths: + * 0 – 16 + * 1 – 20 + * 2 – 32 + * 3 – N/A + */ +#define AN_LT_WRAPPER_GEN_CFG_AN_LT_SEL_RX_MASK 0x00000003 +#define AN_LT_WRAPPER_GEN_CFG_AN_LT_SEL_RX_SHIFT 0 +/* + * selection between different bus widths: + * 0 – 16 + * 1 – 20 + * 2 – 32 + * 3 – N/A + */ +#define AN_LT_WRAPPER_GEN_CFG_AN_LT_SEL_TX_MASK 0x0000000C +#define AN_LT_WRAPPER_GEN_CFG_AN_LT_SEL_TX_SHIFT 2 +/* bypass the AN/LT block */ +#define AN_LT_WRAPPER_GEN_CFG_BYPASS_RX (1 << 4) +/* bypass the AN/LT block */ +#define AN_LT_WRAPPER_GEN_CFG_BYPASS_TX (1 << 5) + +/**** addr register ****/ +/* Address value */ +#define AN_LT_WRAPPER_AN_LT_ADDR_VAL_MASK 0x000007FF +#define AN_LT_WRAPPER_AN_LT_ADDR_VAL_SHIFT 0 + +/**** data register ****/ +/* Data value */ +#define AN_LT_WRAPPER_AN_LT_DATA_VAL_MASK 0x0000FFFF +#define AN_LT_WRAPPER_AN_LT_DATA_VAL_SHIFT 0 + +/**** ctrl register ****/ +/* + * Default Auto-Negotiation Enable. If ‘1’, the auto-negotiation process will + * start after reset de-assertion. The application can also start the + * auto-negotiation process by writing the KXAN_CONTROL.an_enable bit with ‘1’. + * Important: This signal is OR'ed with the KXAN_CONTROL.an_enable bit. Hence, + * when asserted (1) the application is unable to disable autonegotiation and + * writing the an_enable bit has no effect. + * Note: Even if enabled by this pin, the application must write the correct + * abilities in the KXAN_ABILITY_1/2/3 registers within 60ms from reset + * deassertion (break_link_timer). + */ +#define AN_LT_WRAPPER_AN_LT_CTRL_AN_ENA (1 << 0) +/* + * If set to 1, the Arbitration State Machine reached the TRANSMIT_DISABLE + * state. + */ +#define AN_LT_WRAPPER_AN_LT_CTRL_AN_DIS_TIMER (1 << 1) + +#define AN_LT_WRAPPER_AN_LT_CTRL_LINK_STATUS_KX (1 << 4) + +#define AN_LT_WRAPPER_AN_LT_CTRL_LINK_STATUS_KX4 (1 << 5) + +#define AN_LT_WRAPPER_AN_LT_CTRL_LINK_STATUS (1 << 6) +/* + * PHY LOS indication selection + * 0 - Select input from the SerDes + * 1 - Select register value from phy_los_in_def + */ +#define AN_LT_WRAPPER_AN_LT_CTRL_PHY_LOS_IN_SEL (1 << 8) +/* PHY LOS default value */ +#define AN_LT_WRAPPER_AN_LT_CTRL_PHY_LOS_IN_DEF (1 << 9) +/* PHY LOS polarity */ +#define AN_LT_WRAPPER_AN_LT_CTRL_PHY_LOS_IN_POL (1 << 10) +/* + * PHY LOS indication selection + * 0 – select AN output + * 1 - Select register value from phy_los_out_def + * 2 - Select input from the SerDes + * 3 – 0 + */ +#define AN_LT_WRAPPER_AN_LT_CTRL_PHY_LOS_OUT_SEL_MASK 0x00003000 +#define AN_LT_WRAPPER_AN_LT_CTRL_PHY_LOS_OUT_SEL_SHIFT 12 +/* PHY LOS default value */ +#define AN_LT_WRAPPER_AN_LT_CTRL_PHY_LOS_OUT_DEF (1 << 14) +/* PHY LOS polarity */ +#define AN_LT_WRAPPER_AN_LT_CTRL_PHY_LOS_OUT_POL (1 << 15) + +/**** status register ****/ +/* Auto-Negotiation Done. If ‘1’, the auto-negotiation process has completed. */ +#define AN_LT_WRAPPER_AN_LT_STATUS_AN_DONE (1 << 0) +/* + * If set to 1, auto-negotiation is enabled on the link. It represents the + * enable control bit KXAN_CONTROL.an_enable. When set to 1, the signals + * an_status/an_select are valid. + */ +#define AN_LT_WRAPPER_AN_LT_STATUS_AN_VAL (1 << 1) +/* + * If set to 0, auto-negotiation is in progress, if set to 1, the Arbitration + * State Machine reached the AN_GOOD_CHECK state (i.e. before autonegotiation is + * done, but the link no longer is used to transfer DME pages). Stays asserted + * also during AN_GOOD (autoneg done). + */ +#define AN_LT_WRAPPER_AN_LT_STATUS_AN_STATUS (1 << 2) +/* + * Selected Technology. Becomes valid when an_status is 1. + * The selection mode number (from 0 to 24) corresponds to the Technology + * Ability (A0-A24) from the ability pages (see 4.3.2.3 page 13). The mode + * selection is based on the matching technology abilities and priority. + * A value of 31 is an invalid setting that indicates that no common technology + * could be resolved. The application should then inspect the base page results + * to determine if the link is operable or not. + */ +#define AN_LT_WRAPPER_AN_LT_STATUS_AN_SELECT_MASK 0x000001F0 +#define AN_LT_WRAPPER_AN_LT_STATUS_AN_SELECT_SHIFT 4 +/* + * If set to 1, the Arbitration State Machine reached the TRANSMIT_DISABLE state + */ +#define AN_LT_WRAPPER_AN_LT_STATUS_AN_TR_DIS_STATUS (1 << 16) +/* + * FEC Enable. Asserts when autonegotiation base page exchange identified both + * link partners advertising FEC capability and at least one is requesting FEC. + * The signal stays constant following base page exchange until autonegotiation + * is disabled or restarted. + * Note: the information can also be extracted from the base page exchange or + * the BP_ETH_STATUS register. + */ +#define AN_LT_WRAPPER_AN_LT_STATUS_FEC_ENA (1 << 17) +/* + * Link Training Frame Lock. If set to 1 the training frame delineation has been + * acquired. + */ +#define AN_LT_WRAPPER_AN_LT_STATUS_LT_LOCK (1 << 20) +/* + * If set to 0, link-training is in progress, if set to 1, the training is + * completed and the PCS datapath has been enabled (phy_los_out no longer + * gated). + */ +#define AN_LT_WRAPPER_AN_LT_STATUS_LT_STATUS (1 << 21) +/* + * If set to 1, link-training is enabled on the link. It represents the enable + * control bit PMD Control.taining enable. When set to 1, the signal lt_status + * is valid + */ +#define AN_LT_WRAPPER_AN_LT_STATUS_LT_VAL (1 << 22) + +#ifdef __cplusplus +} +#endif + +#endif /* __AL_HAL_AN_LT_wrapper_REGS_H__ */ + +/** @} end of ... group */ + + diff --git a/eth/al_hal_eth.h b/eth/al_hal_eth.h new file mode 100644 index 00000000000..86108b0df4c --- /dev/null +++ b/eth/al_hal_eth.h @@ -0,0 +1,2381 @@ +/*- +******************************************************************************* +Copyright (C) 2015 Annapurna Labs Ltd. + +This file may be licensed under the terms of the Annapurna Labs Commercial +License Agreement. + +Alternatively, this file can be distributed under the terms of the GNU General +Public License V2 as published by the Free Software Foundation and can be +found at http://www.gnu.org/licenses/gpl-2.0.html + +Alternatively, redistribution and use in source and binary forms, with or +without modification, are permitted provided that the following conditions are +met: + + * Redistributions of source code must retain the above copyright notice, +this list of conditions and the following disclaimer. + + * Redistributions in binary form must reproduce the above copyright +notice, this list of conditions and the following disclaimer in +the documentation and/or other materials provided with the +distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +*******************************************************************************/ + +/** + * @defgroup group_eth_api API + * Ethernet Controller HAL driver API + * @ingroup group_eth + * @{ + * @file al_hal_eth.h + * + * @brief Header file for Unified GbE and 10GbE Ethernet Controllers This is a + * common header file that covers both Standard and Advanced Controller + * + * + */ + +#ifndef __AL_HAL_ETH_H__ +#define __AL_HAL_ETH_H__ + +#include "al_hal_common.h" +#include "al_hal_udma.h" +#include "al_hal_eth_alu.h" +#ifdef AL_ETH_EX +#include "al_hal_eth_ex.h" +#include "al_hal_eth_ex_internal.h" +#endif + +/* *INDENT-OFF* */ +#ifdef __cplusplus +extern "C" { +#endif +/* *INDENT-ON* */ + +#ifndef AL_ETH_PKT_MAX_BUFS +#ifndef AL_ETH_EX +#define AL_ETH_PKT_MAX_BUFS 19 +#else +#define AL_ETH_PKT_MAX_BUFS 29 +#endif +#endif + +#define AL_ETH_UDMA_TX_QUEUES 4 +#define AL_ETH_UDMA_RX_QUEUES 4 + +/* PCI Adapter Device/Revision ID */ +#define AL_ETH_DEV_ID_STANDARD 0x0001 +#define AL_ETH_DEV_ID_ADVANCED 0x0002 +#define AL_ETH_REV_ID_0 0 /* Alpine V1 Rev 0 */ +#define AL_ETH_REV_ID_1 1 /* Alpine V1 Rev 1 */ +#define AL_ETH_REV_ID_2 2 /* Alpine V2 basic */ +#define AL_ETH_REV_ID_3 3 /* Alpine V2 advanced */ + +/* PCI BARs */ +#define AL_ETH_UDMA_BAR 0 +#define AL_ETH_EC_BAR 4 +#define AL_ETH_MAC_BAR 2 + +#define AL_ETH_MAX_FRAME_LEN 10000 +#define AL_ETH_MIN_FRAME_LEN 60 + +#define AL_ETH_TSO_MSS_MAX_IDX 8 +#define AL_ETH_TSO_MSS_MIN_VAL 1 +/*TODO: update with correct value*/ +#define AL_ETH_TSO_MSS_MAX_VAL (AL_ETH_MAX_FRAME_LEN - 200) + +enum AL_ETH_PROTO_ID { + AL_ETH_PROTO_ID_UNKNOWN = 0, + AL_ETH_PROTO_ID_IPv4 = 8, + AL_ETH_PROTO_ID_IPv6 = 11, + AL_ETH_PROTO_ID_TCP = 12, + AL_ETH_PROTO_ID_UDP = 13, + AL_ETH_PROTO_ID_FCOE = 21, + AL_ETH_PROTO_ID_GRH = 22, /** RoCE l3 header */ + AL_ETH_PROTO_ID_BTH = 23, /** RoCE l4 header */ + AL_ETH_PROTO_ID_ANY = 32, /**< for sw usage only */ +}; +#define AL_ETH_PROTOCOLS_NUM (AL_ETH_PROTO_ID_ANY) + +enum AL_ETH_TX_TUNNEL_MODE { + AL_ETH_NO_TUNNELING = 0, + AL_ETH_TUNNEL_NO_UDP = 1, /* NVGRE / IP over IP */ + AL_ETH_TUNNEL_WITH_UDP = 3, /* VXLAN */ +}; + +#define AL_ETH_RX_THASH_TABLE_SIZE (1 << 8) +#define AL_ETH_RX_FSM_TABLE_SIZE (1 << 7) +#define AL_ETH_RX_CTRL_TABLE_SIZE (1 << 11) +#define AL_ETH_RX_HASH_KEY_NUM 10 +#define AL_ETH_FWD_MAC_NUM 32 +#define AL_ETH_FWD_MAC_HASH_NUM 256 +#define AL_ETH_FWD_PBITS_TABLE_NUM (1 << 3) +#define AL_ETH_FWD_PRIO_TABLE_NUM (1 << 3) +#define AL_ETH_FWD_VID_TABLE_NUM (1 << 12) +#define AL_ETH_FWD_DSCP_TABLE_NUM (1 << 8) +#define AL_ETH_FWD_TC_TABLE_NUM (1 << 8) + +/** MAC media mode */ +enum al_eth_mac_mode { + AL_ETH_MAC_MODE_RGMII, + AL_ETH_MAC_MODE_SGMII, + AL_ETH_MAC_MODE_SGMII_2_5G, + AL_ETH_MAC_MODE_10GbE_Serial, /**< Applies to XFI and KR modes */ + AL_ETH_MAC_MODE_10G_SGMII, /**< SGMII using the 10G MAC, don't use*/ + AL_ETH_MAC_MODE_XLG_LL_40G, /**< applies to 40G mode using the 40G low latency (LL) MAC */ + AL_ETH_MAC_MODE_KR_LL_25G, /**< applies to 25G mode using the 10/25G low latency (LL) MAC */ + AL_ETH_MAC_MODE_XLG_LL_50G /**< applies to 50G mode using the 40/50G low latency (LL) MAC */ +}; + +struct al_eth_capabilities { + al_bool speed_10_HD; + al_bool speed_10_FD; + al_bool speed_100_HD; + al_bool speed_100_FD; + al_bool speed_1000_HD; + al_bool speed_1000_FD; + al_bool speed_10000_HD; + al_bool speed_10000_FD; + al_bool pfc; /**< priority flow control */ + al_bool eee; /**< Energy Efficient Ethernet */ +}; + +/** interface type used for MDIO */ +enum al_eth_mdio_if { + AL_ETH_MDIO_IF_1G_MAC = 0, + AL_ETH_MDIO_IF_10G_MAC = 1 +}; + +/** MDIO protocol type */ +enum al_eth_mdio_type { + AL_ETH_MDIO_TYPE_CLAUSE_22 = 0, + AL_ETH_MDIO_TYPE_CLAUSE_45 = 1 +}; + +/** flow control mode */ +enum al_eth_flow_control_type { + AL_ETH_FLOW_CONTROL_TYPE_LINK_PAUSE, + AL_ETH_FLOW_CONTROL_TYPE_PFC +}; + +/** Tx to Rx switching decision type */ +enum al_eth_tx_switch_dec_type { + AL_ETH_TX_SWITCH_TYPE_MAC = 0, + AL_ETH_TX_SWITCH_TYPE_VLAN_TABLE = 1, + AL_ETH_TX_SWITCH_TYPE_VLAN_TABLE_AND_MAC = 2, + AL_ETH_TX_SWITCH_TYPE_BITMAP = 3 +}; + +/** Tx to Rx VLAN ID selection type */ +enum al_eth_tx_switch_vid_sel_type { + AL_ETH_TX_SWITCH_VID_SEL_TYPE_VLAN1 = 0, + AL_ETH_TX_SWITCH_VID_SEL_TYPE_VLAN2 = 1, + AL_ETH_TX_SWITCH_VID_SEL_TYPE_NEW_VLAN1 = 2, + AL_ETH_TX_SWITCH_VID_SEL_TYPE_NEW_VLAN2 = 3, + AL_ETH_TX_SWITCH_VID_SEL_TYPE_DEFAULT_VLAN1 = 4, + AL_ETH_TX_SWITCH_VID_SEL_TYPE_FINAL_VLAN1 = 5 +}; + +/** Rx descriptor configurations */ +/* Note: when selecting rx descriptor field to inner packet, then that field +* will be set according to inner packet when packet is tunneled, for non-tunneled +* packets, the field will be set according to the packets header */ + +/** selection of the LRO_context_value result in the Metadata */ +enum al_eth_rx_desc_lro_context_val_res { + AL_ETH_LRO_CONTEXT_VALUE = 0, /**< LRO_context_value */ + AL_ETH_L4_OFFSET = 1, /**< L4_offset */ +}; + +/** selection of the L4 offset in the Metadata */ +enum al_eth_rx_desc_l4_offset_sel { + AL_ETH_L4_OFFSET_OUTER = 0, /**< set L4 offset of the outer packet */ + AL_ETH_L4_OFFSET_INNER = 1, /**< set L4 offset of the inner packet */ +}; + +/** selection of the L4 checksum result in the Metadata */ +enum al_eth_rx_desc_l4_chk_res_sel { + AL_ETH_L4_INNER_CHK = 0, /**< L4 checksum */ + AL_ETH_L4_INNER_OUTER_CHK = 1, /**< Logic AND between outer and inner + L4 checksum result */ +}; + +/** selection of the L3 checksum result in the Metadata */ +enum al_eth_rx_desc_l3_chk_res_sel { + AL_ETH_L3_CHK_TYPE_0 = 0, /**< L3 checksum */ + AL_ETH_L3_CHK_TYPE_1 = 1, /**< L3 checksum or RoCE/FCoE CRC, + based on outer header */ + AL_ETH_L3_CHK_TYPE_2 = 2, /**< If tunnel exist = 0, + L3 checksum or RoCE/FCoE CRC, + based on outer header. + Else, + logic AND between outer L3 checksum + (Ipv4) and inner CRC (RoCE or FcoE) */ + AL_ETH_L3_CHK_TYPE_3 = 3, /**< combination of the L3 checksum result and + CRC result,based on the checksum and + RoCE/FCoE CRC input selections. */ +}; + +/** selection of the L3 protocol index in the Metadata */ +enum al_eth_rx_desc_l3_proto_idx_sel { + AL_ETH_L3_PROTO_IDX_OUTER = 0, /**< set L3 proto index of the outer packet */ + AL_ETH_L3_PROTO_IDX_INNER = 1, /**< set L3 proto index of the inner packet */ +}; + +/** selection of the L3 offset in the Metadata */ +enum al_eth_rx_desc_l3_offset_sel { + AL_ETH_L3_OFFSET_OUTER = 0, /**< set L3 offset of the outer packet */ + AL_ETH_L3_OFFSET_INNER = 1, /**< set L3 offset of the inner packet */ +}; + + +/** selection of the L4 protocol index in the Metadata */ +enum al_eth_rx_desc_l4_proto_idx_sel { + AL_ETH_L4_PROTO_IDX_OUTER = 0, /**< set L4 proto index of the outer packet */ + AL_ETH_L4_PROTO_IDX_INNER = 1, /**< set L4 proto index of the inner packet */ +}; + +/** selection of the frag indication in the Metadata */ +enum al_eth_rx_desc_frag_sel { + AL_ETH_FRAG_OUTER = 0, /**< set frag of the outer packet */ + AL_ETH_FRAG_INNER = 1, /**< set frag of the inner packet */ +}; + +/** Ethernet Rx completion descriptor */ +typedef struct { + uint32_t ctrl_meta; + uint32_t len; + uint32_t word2; + uint32_t word3; +} al_eth_rx_cdesc; + +/** Flow Contol parameters */ +struct al_eth_flow_control_params{ + enum al_eth_flow_control_type type; /**< flow control type */ + al_bool obay_enable; /**< stop tx when pause received */ + al_bool gen_enable; /**< generate pause frames */ + uint16_t rx_fifo_th_high; + uint16_t rx_fifo_th_low; + uint16_t quanta; + uint16_t quanta_th; + uint8_t prio_q_map[4][8]; /**< for each UDMA, defines the mapping between + * PFC priority and queues(in bit mask). + * same mapping used for obay and generation. + * for example: + * if prio_q_map[1][7] = 0xC, then TX queues 2 + * and 3 of UDMA 1 will be stopped when pause + * received with priority 7, also, when RX queues + * 2 and 3 of UDMA 1 become almost full, then + * pause frame with priority 7 will be sent. + * + *note: + * 1) if specific a queue is not used, the caller must + * make set the prio_q_map to 0 otherwise that queue + * will make the controller keep sending PAUSE packets. + * 2) queues of unused UDMA must be treated as above. + * 3) when working in LINK PAUSE mode, only entries at + * priority 0 will be considered. + */ +}; + +/* Packet Tx flags */ +#define AL_ETH_TX_FLAGS_TSO AL_BIT(7) /**< Enable TCP/UDP segmentation offloading */ +#define AL_ETH_TX_FLAGS_IPV4_L3_CSUM AL_BIT(13) /**< Enable IPv4 header checksum calculation */ +#define AL_ETH_TX_FLAGS_L4_CSUM AL_BIT(14) /**< Enable TCP/UDP checksum calculation */ +#define AL_ETH_TX_FLAGS_L4_PARTIAL_CSUM AL_BIT(17) /**< L4 partial checksum calculation */ +#define AL_ETH_TX_FLAGS_L2_MACSEC_PKT AL_BIT(16) /**< L2 Packet type 802_3 or 802_3_MACSEC, V2 */ +#define AL_ETH_TX_FLAGS_ENCRYPT AL_BIT(16) /**< Enable TX packet encryption, V3 */ +#define AL_ETH_TX_FLAGS_L2_DIS_FCS AL_BIT(15) /**< Disable CRC calculation*/ +#define AL_ETH_TX_FLAGS_TS AL_BIT(21) /**< Timestamp the packet */ + +#define AL_ETH_TX_FLAGS_INT AL_M2S_DESC_INT_EN +#define AL_ETH_TX_FLAGS_NO_SNOOP AL_M2S_DESC_NO_SNOOP_H + +/** this structure used for tx packet meta data */ +struct al_eth_meta_data{ + uint8_t store :1; /**< store the meta into the queues cache */ + uint8_t words_valid :4; /**< valid bit per word */ + + uint8_t vlan1_cfi_sel:2; + uint8_t vlan2_vid_sel:2; + uint8_t vlan2_cfi_sel:2; + uint8_t vlan2_pbits_sel:2; + uint8_t vlan2_ether_sel:2; + + uint16_t vlan1_new_vid:12; + uint8_t vlan1_new_cfi :1; + uint8_t vlan1_new_pbits :3; + uint16_t vlan2_new_vid:12; + uint8_t vlan2_new_cfi :1; + uint8_t vlan2_new_pbits :3; + + uint8_t l3_header_len; /**< in bytes */ + uint8_t l3_header_offset; + uint8_t l4_header_len; /**< in words(32-bits) */ + + /* rev 0 specific */ + uint8_t mss_idx_sel:3; /**< for TSO, select the register that holds the MSS */ + + /* rev 1 specific */ + uint8_t ts_index:4; /**< index of regiser where to store the tx timestamp */ + uint16_t mss_val :14; /**< for TSO, set the mss value */ + uint8_t outer_l3_offset; /**< for tunneling mode. up to 64 bytes */ + uint8_t outer_l3_len; /**< for tunneling mode. up to 128 bytes */ +}; + +/* Packet Rx flags when adding buffer to receive queue */ + +/**< + * VMID to be assigned to the packet descriptors + * Requires VMID in descriptor to be enabled for the specific UDMA + * queue. + */ +#define AL_ETH_RX_FLAGS_VMID_MASK AL_FIELD_MASK(15, 0) +#define AL_ETH_RX_FLAGS_NO_SNOOP AL_M2S_DESC_NO_SNOOP_H +#define AL_ETH_RX_FLAGS_INT AL_M2S_DESC_INT_EN +#define AL_ETH_RX_FLAGS_DUAL_BUF AL_BIT(31) + +/* Packet Rx flags set by HW when receiving packet */ +#define AL_ETH_RX_ERROR AL_BIT(16) /**< layer 2 errors (FCS, bad len, etc) */ +#define AL_ETH_RX_FLAGS_L4_CSUM_ERR AL_BIT(14) +#define AL_ETH_RX_FLAGS_L3_CSUM_ERR AL_BIT(13) + +/* Packet Rx flags - word 3 in Rx completion descriptor */ +#define AL_ETH_RX_FLAGS_CRC AL_BIT(31) +#define AL_ETH_RX_FLAGS_L3_CSUM_2 AL_BIT(30) +#define AL_ETH_RX_FLAGS_L4_CSUM_2 AL_BIT(29) +#define AL_ETH_RX_FLAGS_SW_SRC_PORT_SHIFT 13 +#define AL_ETH_RX_FLAGS_SW_SRC_PORT_MASK AL_FIELD_MASK(15, 13) +#define AL_ETH_RX_FLAGS_LRO_CONTEXT_VAL_SHIFT 3 +#define AL_ETH_RX_FLAGS_LRO_CONTEXT_VAL_MASK AL_FIELD_MASK(10, 3) +#define AL_ETH_RX_FLAGS_L4_OFFSET_SHIFT 3 +#define AL_ETH_RX_FLAGS_L4_OFFSET_MASK AL_FIELD_MASK(10, 3) +#define AL_ETH_RX_FLAGS_PRIORITY_SHIFT 0 +#define AL_ETH_RX_FLAGS_PRIORITY_MASK AL_FIELD_MASK(2, 0) + +/** packet structure. used for packet transmission and reception */ +struct al_eth_pkt{ + uint32_t flags; /**< see flags above, depends on context(tx or rx) */ + enum AL_ETH_PROTO_ID l3_proto_idx; + enum AL_ETH_PROTO_ID l4_proto_idx; + uint8_t source_vlan_count:2; + uint8_t vlan_mod_add_count:2; + uint8_t vlan_mod_del_count:2; + uint8_t vlan_mod_v1_ether_sel:2; + uint8_t vlan_mod_v1_vid_sel:2; + uint8_t vlan_mod_v1_pbits_sel:2; + + /* rev 1 specific */ + enum AL_ETH_TX_TUNNEL_MODE tunnel_mode; + enum AL_ETH_PROTO_ID outer_l3_proto_idx; /**< for tunneling mode */ + + /**< + * VMID to be assigned to the packet descriptors + * Requires VMID in descriptor to be enabled for the specific UDMA + * queue. + */ + uint16_t vmid; + + uint32_t rx_header_len; /**< header buffer length of rx packet, not used */ + struct al_eth_meta_data *meta; /**< if null, then no meta added */ +#ifdef AL_ETH_RX_DESC_RAW_GET + uint32_t rx_desc_raw[4]; +#endif + uint16_t rxhash; + uint16_t l3_offset; + +#ifdef AL_ETH_EX + struct al_eth_ext_metadata *ext_meta_data; +#endif + + uint8_t num_of_bufs; + struct al_buf bufs[AL_ETH_PKT_MAX_BUFS]; +}; + +struct al_ec_regs; + + +/** Ethernet Adapter private data structure used by this driver */ +struct al_hal_eth_adapter{ + uint8_t rev_id; /**tx_udma, qid, &udma_q); + + return al_udma_available_get(udma_q); +} + +/** + * prepare packet descriptors in tx queue. + * + * This functions prepares the descriptors for the given packet in the tx + * submission ring. the caller must call al_eth_tx_pkt_action() below + * in order to notify the hardware about the new descriptors. + * + * @param tx_dma_q pointer to UDMA tx queue + * @param pkt the packet to transmit + * + * @return number of descriptors used for this packet, 0 if no free + * room in the descriptors ring + */ +int al_eth_tx_pkt_prepare(struct al_udma_q *tx_dma_q, struct al_eth_pkt *pkt); + + +/** + * Trigger the DMA about previously added tx descriptors. + * + * @param tx_dma_q pointer to UDMA tx queue + * @param tx_descs number of descriptors to notify the DMA about. + * the tx_descs can be sum of descriptor numbers of multiple prepared packets, + * this way the caller can use this function to notify the DMA about multiple + * packets. + */ +void al_eth_tx_dma_action(struct al_udma_q *tx_dma_q, uint32_t tx_descs); + +/** + * get number of completed tx descriptors, upper layer should derive from + * this information which packets were completed. + * + * @param tx_dma_q pointer to UDMA tx queue + * + * @return number of completed tx descriptors. + */ +int al_eth_comp_tx_get(struct al_udma_q *tx_dma_q); + +/** + * configure a TSO MSS val + * + * the TSO MSS vals are preconfigured values for MSS stored in hardware and the + * packet could use them when not working in MSS explicit mode. + * @param adapter pointer to the private structure + * @param idx the mss index + * @param mss_val the MSS value + * + * @return 0 on success. otherwise on failure. + */ +int al_eth_tso_mss_config(struct al_hal_eth_adapter *adapter, uint8_t idx, uint32_t mss_val); + +/* RX */ +/** + * Config the RX descriptor fields + * + * @param adapter pointer to the private structure + * @param lro_sel select LRO context or l4 offset + * @param l4_offset_sel select l4 offset source + * @param l4_sel select the l4 checksum result + * @param l3_sel select the l3 checksum result + * @param l3_proto_sel select the l3 protocol index source + * @param l4_proto_sel select the l4 protocol index source + * @param frag_sel select the frag indication source + */ +void al_eth_rx_desc_config( + struct al_hal_eth_adapter *adapter, + enum al_eth_rx_desc_lro_context_val_res lro_sel, + enum al_eth_rx_desc_l4_offset_sel l4_offset_sel, + enum al_eth_rx_desc_l3_offset_sel l3_offset_sel, + enum al_eth_rx_desc_l4_chk_res_sel l4_sel, + enum al_eth_rx_desc_l3_chk_res_sel l3_sel, + enum al_eth_rx_desc_l3_proto_idx_sel l3_proto_sel, + enum al_eth_rx_desc_l4_proto_idx_sel l4_proto_sel, + enum al_eth_rx_desc_frag_sel frag_sel); + +/** + * Configure RX header split + * + * @param adapter pointer to the private structure + * @param enable header split when AL_TRUE + * @param header_split_len length in bytes of the header split, this value used when + * CTRL TABLE header split len select is set to + * AL_ETH_CTRL_TABLE_HDR_SPLIT_LEN_SEL_REG, in this case the controller will + * store the first header_split_len bytes into buf2, then the rest (if any) into buf1. + * when CTRL_TABLE header split len select set to other value, then the header_len + * determined according to the parser, and the header_split_len parameter is not + * used. + * + * return 0 on success. otherwise on failure. + */ +int al_eth_rx_header_split_config(struct al_hal_eth_adapter *adapter, al_bool enable, uint32_t header_len); + +/** + * enable / disable header split in the udma queue. + * length will be taken from the udma configuration to enable different length per queue. + * + * @param adapter pointer to the private structure + * @param enable header split when AL_TRUE + * @param qid the queue id to enable/disable header split + * @param header_len in what len the udma will cut the header + * + * return 0 on success. + */ +int al_eth_rx_header_split_force_len_config(struct al_hal_eth_adapter *adapter, + al_bool enable, + uint32_t qid, + uint32_t header_len); + +/** + * add buffer to receive queue + * + * @param rx_dma_q pointer to UDMA rx queue + * @param buf pointer to data buffer + * @param flags bitwise of AL_ETH_RX_FLAGS + * @param header_buf this is not used for far and header_buf should be set to + * NULL. + * + * @return 0 on success. otherwise on failure. + */ +int al_eth_rx_buffer_add(struct al_udma_q *rx_dma_q, + struct al_buf *buf, uint32_t flags, + struct al_buf *header_buf); + +/** + * notify the hw engine about rx descriptors that were added to the receive queue + * + * @param rx_dma_q pointer to UDMA rx queue + * @param descs_num number of rx descriptors + */ +void al_eth_rx_buffer_action(struct al_udma_q *rx_dma_q, + uint32_t descs_num); + +/** + * get packet from RX completion ring + * + * @param rx_dma_q pointer to UDMA rx queue + * @param pkt pointer to a packet data structure, this function fills this + * structure with the information about the received packet. the buffers + * structures filled only with the length of the data written into the buffer, + * the address fields are not updated as the upper layer can retrieve this + * information by itself because the hardware uses the buffers in the same order + * were those buffers inserted into the ring of the receive queue. + * this structure should be allocated by the caller function. + * + * @return return number of descriptors or 0 if no completed packet found. + */ + uint32_t al_eth_pkt_rx(struct al_udma_q *rx_dma_q, struct al_eth_pkt *pkt); + + +/* RX parser table */ +struct al_eth_epe_p_reg_entry { + uint32_t data; + uint32_t mask; + uint32_t ctrl; +}; + +struct al_eth_epe_control_entry { + uint32_t data[6]; +}; + +/** + * update rx parser entry + * + * @param adapter pointer to the private structure + * @param idx the protocol index to update + * @param reg_entry contents of parser register entry + * @param control entry contents of control table entry + * + * @return 0 on success. otherwise on failure. + */ +int al_eth_rx_parser_entry_update(struct al_hal_eth_adapter *adapter, uint32_t idx, + struct al_eth_epe_p_reg_entry *reg_entry, + struct al_eth_epe_control_entry *control_entry); + +/* Flow Steering and filtering */ +int al_eth_thash_table_set(struct al_hal_eth_adapter *adapter, uint32_t idx, uint8_t udma, uint32_t queue); + +/* FSM table bits */ +/** FSM table has 7 bits input address: + * bits[2:0] are the outer packet's type (IPv4, TCP...) + * bits[5:3] are the inner packet's type + * bit[6] is set when packet is tunneled. + * + * The output of each entry: + * bits[1:0] - input selection: selects the input for the thash (2/4 tuple, inner/outer) + * bit[2] - selects whether to use thash output, or default values for the queue and udma + * bits[6:3] default UDMA mask: the UDMAs to select when bit 2 above was unset + * bits[9:5] defualt queue: the queue index to select when bit 2 above was unset + */ + +#define AL_ETH_FSM_ENTRY_IPV4_TCP 0 +#define AL_ETH_FSM_ENTRY_IPV4_UDP 1 +#define AL_ETH_FSM_ENTRY_IPV6_TCP 2 +#define AL_ETH_FSM_ENTRY_IPV6_UDP 3 +#define AL_ETH_FSM_ENTRY_IPV6_NO_UDP_TCP 4 +#define AL_ETH_FSM_ENTRY_IPV4_NO_UDP_TCP 5 +#define AL_ETH_FSM_ENTRY_IPV4_FRAGMENTED 6 +#define AL_ETH_FSM_ENTRY_NOT_IP 7 + +#define AL_ETH_FSM_ENTRY_OUTER(idx) ((idx) & 7) +#define AL_ETH_FSM_ENTRY_INNER(idx) (((idx) >> 3) & 7) +#define AL_ETH_FSM_ENTRY_TUNNELED(idx) (((idx) >> 6) & 1) + +/* FSM DATA format */ +#define AL_ETH_FSM_DATA_OUTER_2_TUPLE 0 +#define AL_ETH_FSM_DATA_OUTER_4_TUPLE 1 +#define AL_ETH_FSM_DATA_INNER_2_TUPLE 2 +#define AL_ETH_FSM_DATA_INNER_4_TUPLE 3 + +#define AL_ETH_FSM_DATA_HASH_SEL (1 << 2) + +#define AL_ETH_FSM_DATA_DEFAULT_Q_SHIFT 5 +#define AL_ETH_FSM_DATA_DEFAULT_UDMA_SHIFT 3 + +/* set fsm table entry */ +int al_eth_fsm_table_set(struct al_hal_eth_adapter *adapter, uint32_t idx, uint32_t entry); + +enum AL_ETH_FWD_CTRL_IDX_VLAN_TABLE_OUT { + AL_ETH_FWD_CTRL_IDX_VLAN_TABLE_OUT_0 = 0, + AL_ETH_FWD_CTRL_IDX_VLAN_TABLE_OUT_1 = 1, + AL_ETH_FWD_CTRL_IDX_VLAN_TABLE_OUT_ANY = 2, +}; + +enum AL_ETH_FWD_CTRL_IDX_TUNNEL { + AL_ETH_FWD_CTRL_IDX_TUNNEL_NOT_EXIST = 0, + AL_ETH_FWD_CTRL_IDX_TUNNEL_EXIST = 1, + AL_ETH_FWD_CTRL_IDX_TUNNEL_ANY = 2, +}; + +enum AL_ETH_FWD_CTRL_IDX_VLAN { + AL_ETH_FWD_CTRL_IDX_VLAN_NOT_EXIST = 0, + AL_ETH_FWD_CTRL_IDX_VLAN_EXIST = 1, + AL_ETH_FWD_CTRL_IDX_VLAN_ANY = 2, +}; + +enum AL_ETH_FWD_CTRL_IDX_MAC_TABLE { + AL_ETH_FWD_CTRL_IDX_MAC_TABLE_NO_MATCH = 0, + AL_ETH_FWD_CTRL_IDX_MAC_TABLE_MATCH = 1, + AL_ETH_FWD_CTRL_IDX_MAC_TABLE_ANY = 2, +}; + +enum AL_ETH_FWD_CTRL_IDX_MAC_DA_TYPE { + AL_ETH_FWD_CTRL_IDX_MAC_DA_TYPE_UC = 0, /**< unicast */ + AL_ETH_FWD_CTRL_IDX_MAC_DA_TYPE_MC = 1, /**< multicast */ + AL_ETH_FWD_CTRL_IDX_MAC_DA_TYPE_BC = 2, /**< broadcast */ + AL_ETH_FWD_CTRL_IDX_MAC_DA_TYPE_ANY = 4, /**< for sw usage */ +}; + +/** + * This structure defines the index or group of indeces within the control table. + * each field has special enum value (with _ANY postfix) that indicates all + * possible values of that field. + */ +struct al_eth_fwd_ctrl_table_index { + enum AL_ETH_FWD_CTRL_IDX_VLAN_TABLE_OUT vlan_table_out; + enum AL_ETH_FWD_CTRL_IDX_TUNNEL tunnel_exist; + enum AL_ETH_FWD_CTRL_IDX_VLAN vlan_exist; + enum AL_ETH_FWD_CTRL_IDX_MAC_TABLE mac_table_match; + enum AL_ETH_PROTO_ID protocol_id; + enum AL_ETH_FWD_CTRL_IDX_MAC_DA_TYPE mac_type; +}; + +enum AL_ETH_CTRL_TABLE_PRIO_SEL { + AL_ETH_CTRL_TABLE_PRIO_SEL_PBITS_TABLE = 0, + AL_ETH_CTRL_TABLE_PRIO_SEL_DSCP_TABLE = 1, + AL_ETH_CTRL_TABLE_PRIO_SEL_TC_TABLE = 2, + AL_ETH_CTRL_TABLE_PRIO_SEL_REG1 = 3, + AL_ETH_CTRL_TABLE_PRIO_SEL_REG2 = 4, + AL_ETH_CTRL_TABLE_PRIO_SEL_REG3 = 5, + AL_ETH_CTRL_TABLE_PRIO_SEL_REG4 = 6, + AL_ETH_CTRL_TABLE_PRIO_SEL_REG5 = 7, + AL_ETH_CTRL_TABLE_PRIO_SEL_REG6 = 7, + AL_ETH_CTRL_TABLE_PRIO_SEL_REG7 = 9, + AL_ETH_CTRL_TABLE_PRIO_SEL_REG8 = 10, + AL_ETH_CTRL_TABLE_PRIO_SEL_VAL_3 = 11, + AL_ETH_CTRL_TABLE_PRIO_SEL_VAL_0 = 12, +}; +/** where to select the initial queue from */ +enum AL_ETH_CTRL_TABLE_QUEUE_SEL_1 { + AL_ETH_CTRL_TABLE_QUEUE_SEL_1_PRIO_TABLE = 0, + AL_ETH_CTRL_TABLE_QUEUE_SEL_1_THASH_TABLE = 1, + AL_ETH_CTRL_TABLE_QUEUE_SEL_1_MAC_TABLE = 2, + AL_ETH_CTRL_TABLE_QUEUE_SEL_1_MHASH_TABLE = 3, + AL_ETH_CTRL_TABLE_QUEUE_SEL_1_REG1 = 4, + AL_ETH_CTRL_TABLE_QUEUE_SEL_1_REG2 = 5, + AL_ETH_CTRL_TABLE_QUEUE_SEL_1_REG3 = 6, + AL_ETH_CTRL_TABLE_QUEUE_SEL_1_REG4 = 7, + AL_ETH_CTRL_TABLE_QUEUE_SEL_1_VAL_3 = 12, + AL_ETH_CTRL_TABLE_QUEUE_SEL_1_VAL_0 = 13, +}; + +/** target queue will be built up from the priority and initial queue */ +enum AL_ETH_CTRL_TABLE_QUEUE_SEL_2 { + AL_ETH_CTRL_TABLE_QUEUE_SEL_2_PRIO_TABLE = 0, /**< target queue is the output of priority table */ + AL_ETH_CTRL_TABLE_QUEUE_SEL_2_PRIO = 1, /**< target queue is the priority */ + AL_ETH_CTRL_TABLE_QUEUE_SEL_2_PRIO_QUEUE = 2, /**< target queue is initial queue[0], priority[1] */ + AL_ETH_CTRL_TABLE_QUEUE_SEL_2_NO_PRIO = 3, /**< target queue is the initial */ +}; + +enum AL_ETH_CTRL_TABLE_UDMA_SEL { + AL_ETH_CTRL_TABLE_UDMA_SEL_THASH_TABLE = 0, + AL_ETH_CTRL_TABLE_UDMA_SEL_THASH_AND_VLAN = 1, + AL_ETH_CTRL_TABLE_UDMA_SEL_VLAN_TABLE = 2, + AL_ETH_CTRL_TABLE_UDMA_SEL_VLAN_AND_MAC = 3, + AL_ETH_CTRL_TABLE_UDMA_SEL_MAC_TABLE = 4, + AL_ETH_CTRL_TABLE_UDMA_SEL_MAC_AND_MHASH = 5, + AL_ETH_CTRL_TABLE_UDMA_SEL_MHASH_TABLE = 6, + AL_ETH_CTRL_TABLE_UDMA_SEL_REG1 = 7, + AL_ETH_CTRL_TABLE_UDMA_SEL_REG2 = 8, + AL_ETH_CTRL_TABLE_UDMA_SEL_REG3 = 9, + AL_ETH_CTRL_TABLE_UDMA_SEL_REG4 = 10, + AL_ETH_CTRL_TABLE_UDMA_SEL_REG5 = 11, + AL_ETH_CTRL_TABLE_UDMA_SEL_REG6 = 12, + AL_ETH_CTRL_TABLE_UDMA_SEL_REG7 = 13, + AL_ETH_CTRL_TABLE_UDMA_SEL_REG8 = 14, + AL_ETH_CTRL_TABLE_UDMA_SEL_VAL_0 = 15, +}; + +enum AL_ETH_CTRL_TABLE_HDR_SPLIT_LEN_SEL { + AL_ETH_CTRL_TABLE_HDR_SPLIT_LEN_SEL_0 = 0, + AL_ETH_CTRL_TABLE_HDR_SPLIT_LEN_SEL_REG = 1, /**< select header len from the hdr_split register (set by al_eth_rx_header_split_config())*/ + AL_ETH_CTRL_TABLE_HDR_SPLIT_LEN_SEL_OUTER_L3_OFFSET = 2, + AL_ETH_CTRL_TABLE_HDR_SPLIT_LEN_SEL_OUTER_L4_OFFSET = 3, + AL_ETH_CTRL_TABLE_HDR_SPLIT_LEN_SEL_TUNNEL_START_OFFSET = 4, + AL_ETH_CTRL_TABLE_HDR_SPLIT_LEN_SEL_INNER_L3_OFFSET = 5, + AL_ETH_CTRL_TABLE_HDR_SPLIT_LEN_SEL_INNER_L4_OFFSET = 6, +}; + +struct al_eth_fwd_ctrl_table_entry { + enum AL_ETH_CTRL_TABLE_PRIO_SEL prio_sel; + enum AL_ETH_CTRL_TABLE_QUEUE_SEL_1 queue_sel_1; /**< queue id source */ + enum AL_ETH_CTRL_TABLE_QUEUE_SEL_2 queue_sel_2; /**< mix queue id with priority */ + enum AL_ETH_CTRL_TABLE_UDMA_SEL udma_sel; + enum AL_ETH_CTRL_TABLE_HDR_SPLIT_LEN_SEL hdr_split_len_sel; + al_bool filter; /**< set to AL_TRUE to enable filtering */ +}; +/** + * Configure default control table entry + * + * @param adapter pointer to the private structure + * @param use_table set to AL_TRUE if control table is used, when set to AL_FALSE + * then control table will be bypassed and the entry value will be used. + * @param entry defines the value to be used when bypassing control table. + * + * @return 0 on success. otherwise on failure. + */ +int al_eth_ctrl_table_def_set(struct al_hal_eth_adapter *adapter, + al_bool use_table, + struct al_eth_fwd_ctrl_table_entry *entry); + +/** + * Configure control table entry + * + * @param adapter pointer to the private structure + * @param index the entry index within the control table. + * @param entry the value to write to the control table entry + * + * @return 0 on success. otherwise on failure. + */ +int al_eth_ctrl_table_set(struct al_hal_eth_adapter *adapter, + struct al_eth_fwd_ctrl_table_index *index, + struct al_eth_fwd_ctrl_table_entry *entry); + +int al_eth_ctrl_table_raw_set(struct al_hal_eth_adapter *adapter, uint32_t idx, uint32_t entry); +int al_eth_ctrl_table_def_raw_set(struct al_hal_eth_adapter *adapter, uint32_t val); + +/** + * Configure hash key initial registers + * Those registers define the initial key values, those values used for + * the THASH and MHASH hash functions. + * + * @param adapter pointer to the private structure + * @param idx the register index + * @param val the register value + * + * @return 0 on success. otherwise on failure. + */ +int al_eth_hash_key_set(struct al_hal_eth_adapter *adapter, uint32_t idx, uint32_t val); + +struct al_eth_fwd_mac_table_entry { + uint8_t addr[6]; /**< byte 0 is the first byte seen on the wire */ + uint8_t mask[6]; + al_bool tx_valid; + uint8_t tx_target; + al_bool rx_valid; + uint8_t udma_mask; /**< target udma */ + uint8_t qid; /**< target queue */ + al_bool filter; /**< set to AL_TRUE to enable filtering */ +}; + +/** + * Configure mac table entry + * The HW traverse this table and looks for match from lowest index, + * when the packets MAC DA & mask == addr, and the valid bit is set, then match occurs. + * + * @param adapter pointer to the private structure + * @param idx the entry index within the mac table. + * @param entry the contents of the MAC table entry + * + * @return 0 on success. otherwise on failure. + */ +int al_eth_fwd_mac_table_set(struct al_hal_eth_adapter *adapter, uint32_t idx, + struct al_eth_fwd_mac_table_entry *entry); + +int al_eth_fwd_mac_addr_raw_set(struct al_hal_eth_adapter *adapter, uint32_t idx, + uint32_t addr_lo, uint32_t addr_hi, uint32_t mask_lo, uint32_t mask_hi); +int al_eth_fwd_mac_ctrl_raw_set(struct al_hal_eth_adapter *adapter, uint32_t idx, uint32_t ctrl); + +int al_eth_mac_addr_store(void * __iomem ec_base, uint32_t idx, uint8_t *addr); +int al_eth_mac_addr_read(void * __iomem ec_base, uint32_t idx, uint8_t *addr); + +/** + * Configure pbits table entry + * The HW uses this table to translate between vlan pbits field to priority. + * The vlan pbits is used as the index of this table. + * + * @param adapter pointer to the private structure + * @param idx the entry index within the table. + * @param prio the priority to set for this entry + * + * @return 0 on success. otherwise on failure. + */ +int al_eth_fwd_pbits_table_set(struct al_hal_eth_adapter *adapter, uint32_t idx, uint8_t prio); + +/** + * Configure priority table entry + * The HW uses this table to translate between priority to queue index. + * The priority is used as the index of this table. + * + * @param adapter pointer to the private structure + * @param prio the entry index within the table. + * @param qid the queue index to set for this entry (priority). + * + * @return 0 on success. otherwise on failure. + */ +int al_eth_fwd_priority_table_set(struct al_hal_eth_adapter *adapter, uint8_t prio, uint8_t qid); + +/** + * Configure DSCP table entry + * The HW uses this table to translate between IPv4 DSCP field to priority. + * The IPv4 byte 1 (DSCP+ECN) used as index to this table. + * + * @param adapter pointer to the private structure + * @param idx the entry index within the table. + * @param prio the queue index to set for this entry (priority). + * + * @return 0 on success. otherwise on failure. + */ +int al_eth_fwd_dscp_table_set(struct al_hal_eth_adapter *adapter, uint32_t idx, uint8_t prio); + +/** + * Configure TC table entry + * The HW uses this table to translate between IPv6 TC field to priority. + * The IPv6 TC used as index to this table. + * + * @param adapter pointer to the private structure + * @param idx the entry index within the table. + * @param prio the queue index to set for this entry (priority). + * + * @return 0 on success. otherwise on failure. + */ +int al_eth_fwd_tc_table_set(struct al_hal_eth_adapter *adapter, uint32_t idx, uint8_t prio); + +/** + * Configure MAC HASH table entry + * The HW uses 8 bits from the hash result on the MAC DA as index to this table. + * + * @param adapter pointer to the private structure + * @param idx the entry index within the table. + * @param udma_mask the target udma to set for this entry. + * @param qid the target queue index to set for this entry. + * + * @return 0 on success. otherwise on failure. + */ +int al_eth_fwd_mhash_table_set(struct al_hal_eth_adapter *adapter, uint32_t idx, uint8_t udma_mask, uint8_t qid); + +struct al_eth_fwd_vid_table_entry { + uint8_t control:1; /**< used as input for the control table */ + uint8_t filter:1; /**< set to 1 to enable filtering */ + uint8_t udma_mask:4; /**< target udmas */ +}; + +/** + * Configure default vlan table entry + * + * @param adapter pointer to the private structure + * @param use_table set to AL_TRUE if vlan table is used, when set to AL_FALSE + * then vid table will be bypassed and the default_entry value will be used. + * @param default_entry defines the value to be used when bypassing vid table. + * @param default_vlan defines the value will be used when untagget packet + * received. this value will be used only for steering and filtering control, + * the packet's data will not be changed. + * + * @return 0 on success. otherwise on failure. + */ +int al_eth_fwd_vid_config_set(struct al_hal_eth_adapter *adapter, al_bool use_table, + struct al_eth_fwd_vid_table_entry *default_entry, + uint32_t default_vlan); +/** + * Configure vlan table entry + * + * @param adapter pointer to the private structure + * @param idx the entry index within the vlan table. The HW uses the vlan id + * field of the packet when accessing this table. + * @param entry the value to write to the vlan table entry + * + * @return 0 on success. otherwise on failure. + */ +int al_eth_fwd_vid_table_set(struct al_hal_eth_adapter *adapter, uint32_t idx, + struct al_eth_fwd_vid_table_entry *entry); + + +/** + * Configure default UDMA register + * When the control table entry udma selection set to AL_ETH_CTRL_TABLE_UDMA_SEL_REG, + * then the target UDMA will be set according to the register n of the default + * UDMA registers. + * + * @param adapter pointer to the private structure + * @param idx the index of the default register. + * @param udma_mask the value of the register. + * + * @return 0 on success. otherwise on failure. + */ +int al_eth_fwd_default_udma_config(struct al_hal_eth_adapter *adapter, uint32_t idx, + uint8_t udma_mask); + +/** + * Configure default queue register + * When the control table entry queue selection 1 set to AL_ETH_CTRL_TABLE_QUEUE_SEL_1_REG, + * then the target queue will be set according to the register n of the default + * queue registers. + * + * @param adapter pointer to the private structure + * @param idx the index of the default register. + * @param qid the value of the register. + * + * @return 0 on success. otherwise on failure. + */ +int al_eth_fwd_default_queue_config(struct al_hal_eth_adapter *adapter, uint32_t idx, + uint8_t qid); + +/** + * Configure default priority register + * When the control table entry queue selection 1 set to AL_ETH_CTRL_TABLE_PRIO_SEL_1_REG, + * then the target priority will be set according to the register n of the default + * priority registers. + * + * @param adapter pointer to the private structure + * @param idx the index of the default register. + * @param prio the value of the register. + * + * @return 0 on success. otherwise on failure. + */ +int al_eth_fwd_default_priority_config(struct al_hal_eth_adapter *adapter, uint32_t idx, + uint8_t prio); + + + +/* filter undetected MAC DA */ +#define AL_ETH_RFW_FILTER_UNDET_MAC (1 << 0) +/* filter specific MAC DA based on MAC table output */ +#define AL_ETH_RFW_FILTER_DET_MAC (1 << 1) +/* filter all tagged */ +#define AL_ETH_RFW_FILTER_TAGGED (1 << 2) +/* filter all untagged */ +#define AL_ETH_RFW_FILTER_UNTAGGED (1 << 3) +/* filter all broadcast */ +#define AL_ETH_RFW_FILTER_BC (1 << 4) +/* filter all multicast */ +#define AL_ETH_RFW_FILTER_MC (1 << 5) +/* filter packet based on parser drop */ +#define AL_ETH_RFW_FILTER_PARSE (1 << 6) +/* filter packet based on VLAN table output */ +#define AL_ETH_RFW_FILTER_VLAN_VID (1 << 7) +/* filter packet based on control table output */ +#define AL_ETH_RFW_FILTER_CTRL_TABLE (1 << 8) +/* filter packet based on protocol index */ +#define AL_ETH_RFW_FILTER_PROT_INDEX (1 << 9) +/* filter packet based on WoL decision */ +#define AL_ETH_RFW_FILTER_WOL (1 << 10) + + +struct al_eth_filter_params { + al_bool enable; + uint32_t filters; /**< bitmask of AL_ETH_RFW_FILTER.. for filters to enable */ + al_bool filter_proto[AL_ETH_PROTOCOLS_NUM]; /**< set AL_TRUE for protocols to filter */ +}; + +struct al_eth_filter_override_params { + uint32_t filters; /**< bitmask of AL_ETH_RFW_FILTER.. for filters to override */ + uint8_t udma; /**< target udma id */ + uint8_t qid; /**< target queue id */ +}; + +/** + * Configure the receive filters + * this function enables/disables filtering packets and which filtering + * types to apply. + * filters that indicated in tables (MAC table, VLAN and Control tables) + * are not configured by this function. This functions only enables/disables + * respecting the filter indication from those tables. + * + * @param adapter pointer to the private structure + * @param params the parameters passed from upper layer + * + * @return 0 on success. otherwise on failure. + */ +int al_eth_filter_config(struct al_hal_eth_adapter *adapter, struct al_eth_filter_params *params); + +/** + * Configure the receive override filters + * This function controls whither to force forwarding filtered packets + * to a specific UDMA/queue. The override filters apply only for + * filters that enabled by al_eth_filter_config(). + * + * @param adapter pointer to the private structure + * @param params override config parameters + * + * @return 0 on success. otherwise on failure. + */ +int al_eth_filter_override_config(struct al_hal_eth_adapter *adapter, + struct al_eth_filter_override_params *params); + + +int al_eth_switching_config_set(struct al_hal_eth_adapter *adapter, uint8_t udma_id, uint8_t forward_all_to_mac, uint8_t enable_int_switching, + enum al_eth_tx_switch_vid_sel_type vid_sel_type, + enum al_eth_tx_switch_dec_type uc_dec, + enum al_eth_tx_switch_dec_type mc_dec, + enum al_eth_tx_switch_dec_type bc_dec); +int al_eth_switching_default_bitmap_set(struct al_hal_eth_adapter *adapter, uint8_t udma_id, uint8_t udma_uc_bitmask, + uint8_t udma_mc_bitmask,uint8_t udma_bc_bitmask); +int al_eth_flow_control_config(struct al_hal_eth_adapter *adapter, struct al_eth_flow_control_params *params); + +struct al_eth_eee_params{ + uint8_t enable; + uint32_t tx_eee_timer; /**< time in cycles the interface delays prior to entering eee state */ + uint32_t min_interval; /**< minimum interval in cycles between two eee states */ + uint32_t stop_cnt; /**< time in cycles to stop Tx mac i/f after getting out of eee state */ +}; + +/** + * configure EEE mode + * @param adapter pointer to the private structure. + * @param params pointer to the eee input parameters. + * + * @return return 0 on success. otherwise on failure. + */ +int al_eth_eee_config(struct al_hal_eth_adapter *adapter, struct al_eth_eee_params *params); + +/** + * get EEE configuration + * @param adapter pointer to the private structure. + * @param params pointer to the eee output parameters. + * + * @return return 0 on success. otherwise on failure. + */ +int al_eth_eee_get(struct al_hal_eth_adapter *adapter, struct al_eth_eee_params *params); + +int al_eth_vlan_mod_config(struct al_hal_eth_adapter *adapter, uint8_t udma_id, uint16_t udma_etype, uint16_t vlan1_data, uint16_t vlan2_data); + +/* Timestamp + * This is a generic time-stamp mechanism that can be used as generic to + * time-stamp every received or transmit packet it can also support IEEE 1588v2 + * PTP time synchronization protocol. + * In addition to time-stamp, an internal system time is maintained. For + * further accuracy, the chip support transmit/receive clock synchronization + * including recovery of master clock from one of the ports and distributing it + * to the rest of the ports - that is outside the scope of the Ethernet + * Controller - please refer to Annapurna Labs Alpine Hardware Wiki + */ + +/* Timestamp management APIs */ + +/** + * prepare the adapter for timestamping packets. + * Rx timestamps requires using 8 words (8x4 bytes) rx completion descriptor + * size as the timestamp value added into word 4. + * + * This function should be called after al_eth_mac_config() and before + * enabling the queues. + * @param adapter pointer to the private structure. + * @return 0 on success. otherwise on failure. + */ +int al_eth_ts_init(struct al_hal_eth_adapter *adapter); + +/* Timestamp data path APIs */ + +/* + * This is the size of the on-chip array that keeps the time-stamp of the + * latest transmitted packets + */ +#define AL_ETH_PTH_TX_SAMPLES_NUM 16 + +/** + * read Timestamp sample value of previously transmitted packet. + * + * The adapter includes AL_ETH_PTH_TX_SAMPLES_NUM timestamp samples for tx + * packets, those samples shared for all the UDMAs and queues. the al_eth_pkt + * data structure includes the index of which sample to use for the packet + * to transmit. It's the caller's responsibility to manage those samples, + * for example, when using an index, the caller must make sure the packet + * is completed and the tx time is sampled before using that index for + * another packet. + * + * This function should be called after the completion indication of the + * tx packet. however, there is a little chance that the timestamp sample + * won't be updated yet, thus this function must be called again when it + * returns -EAGAIN. + * @param adapter pointer to the private structure. + * @param ts_index the index (out of 16) of the timestamp register + * @param timestamp the timestamp value in 2^18 femtoseconds resolution. + * @return -EAGAIN if the sample was not updated yet. 0 when the sample + * was updated and no errors found. + */ +int al_eth_tx_ts_val_get(struct al_hal_eth_adapter *adapter, uint8_t ts_index, + uint32_t *timestamp); + +/* Timestamp PTH (PTP Timestamp Handler) control and times management */ +/** structure for describing PTH epoch time */ +struct al_eth_pth_time { + uint32_t seconds; /**< seconds */ + uint64_t femto; /**< femto seconds */ +}; + +/** + * Read the systime value + * This API should not be used to get the timestamp of packets. + * The HW maintains 50 bits for the sub-seconds portion in femto resolution, + * but this function reads only the 32 MSB bits since the LSB provides + * sub-nanoseconds accuracy, which is not needed. + * @param adapter pointer to the private structure. + * @param systime pointer to structure where the time will be stored. + * @return 0 on success. otherwise on failure. + */ +int al_eth_pth_systime_read(struct al_hal_eth_adapter *adapter, + struct al_eth_pth_time *systime); + +/** + * Set the clock period to a given value. + * The systime will be incremented by this value on each posedge of the + * adapters internal clock which driven by the SouthBridge clock. + * @param adapter pointer to the private structure. + * @param clk_period the clock period in femto seconds. + * @return 0 on success. otherwise on failure. + */ +int al_eth_pth_clk_period_write(struct al_hal_eth_adapter *adapter, + uint64_t clk_period); + +/**< enum for methods when updating systime using triggers */ +enum al_eth_pth_update_method { + AL_ETH_PTH_UPDATE_METHOD_SET = 0, /**< Set the time in int/ext update time */ + AL_ETH_PTH_UPDATE_METHOD_INC = 1, /**< increment */ + AL_ETH_PTH_UPDATE_METHOD_DEC = 2, /**< decrement */ + AL_ETH_PTH_UPDATE_METHOD_ADD_TO_LAST = 3, /**< Set to last time + int/ext update time.*/ +}; + +/**< systime internal update trigger types */ +enum al_eth_pth_int_trig { + AL_ETH_PTH_INT_TRIG_OUT_PULSE_0 = 0, /**< use output pulse as trigger */ + AL_ETH_PTH_INT_TRIG_REG_WRITE = 1, /**< use the int update register + * write as a trigger + */ +}; + +/**< parameters for internal trigger update */ +struct al_eth_pth_int_update_params { + al_bool enable; /**< enable internal trigger update */ + enum al_eth_pth_update_method method; /**< internal trigger update + * method + */ + enum al_eth_pth_int_trig trigger; /**< which internal trigger to + * use + */ +}; + +/** + * Configure the systime internal update + * + * @param adapter pointer to the private structure. + * @param params the configuration of the internal update. + * @return 0 on success. otherwise on failure. + */ +int al_eth_pth_int_update_config(struct al_hal_eth_adapter *adapter, + struct al_eth_pth_int_update_params *params); + +/** + * set internal update time + * + * The update time used when updating the systime with + * internal update method. + * + * @param adapter pointer to the private structure. + * @param time the internal update time value + * @return 0 on success. otherwise on failure. + */ +int al_eth_pth_int_update_time_set(struct al_hal_eth_adapter *adapter, + struct al_eth_pth_time *time); + +/**< parameters for external trigger update */ +struct al_eth_pth_ext_update_params { + uint8_t triggers; /**< bitmask of external triggers to enable */ + enum al_eth_pth_update_method method; /**< external trigger update + * method + */ +}; + +/** + * Configure the systime external update. + * external update triggered by external signals such as GPIO or pulses + * from other eth controllers on the SoC. + * + * @param adapter pointer to the private structure. + * @param params the configuration of the external update. + * @return 0 on success. otherwise on failure. + */ +int al_eth_pth_ext_update_config(struct al_hal_eth_adapter *adapter, + struct al_eth_pth_ext_update_params *params); + +/** + * set external update time + * + * The update time used when updating the systime with + * external update method. + * @param adapter pointer to the private structure. + * @param time the external update time value + * @return 0 on success. otherwise on failure. + */ +int al_eth_pth_ext_update_time_set(struct al_hal_eth_adapter *adapter, + struct al_eth_pth_time *time); +/** + * set the read compensation delay + * + * When reading the systime, the HW adds this value to compensate + * read latency. + * + * @param adapter pointer to the private structure. + * @param subseconds the read latency delay in femto seconds. + * @return 0 on success. otherwise on failure. + */ +int al_eth_pth_read_compensation_set(struct al_hal_eth_adapter *adapter, + uint64_t subseconds); +/** + * set the internal write compensation delay + * + * When updating the systime due to an internal trigger's event, the HW adds + * this value to compensate latency. + * + * @param adapter pointer to the private structure. + * @param subseconds the write latency delay in femto seconds. + * @return 0 on success. otherwise on failure. + */ +int al_eth_pth_int_write_compensation_set(struct al_hal_eth_adapter *adapter, + uint64_t subseconds); + +/** + * set the external write compensation delay + * + * When updating the systime due to an external trigger's event, the HW adds + * this value to compensate pulse propagation latency. + * + * @param adapter pointer to the private structure. + * @param subseconds the write latency delay in femto seconds. + * @return 0 on success. otherwise on failure. + */ +int al_eth_pth_ext_write_compensation_set(struct al_hal_eth_adapter *adapter, + uint64_t subseconds); + +/** + * set the sync compensation delay + * + * When the adapter passes systime from PTH to MAC to do the packets + * timestamping, the sync compensation delay is added to systime value to + * compensate the latency between the PTH and the MAC. + * + * @param adapter pointer to the private structure. + * @param subseconds the sync latency delay in femto seconds. + * @return 0 on success. otherwise on failure. + */ +int al_eth_pth_sync_compensation_set(struct al_hal_eth_adapter *adapter, + uint64_t subseconds); + +#define AL_ETH_PTH_PULSE_OUT_NUM 8 +struct al_eth_pth_pulse_out_params { + uint8_t index; /**< id of the pulse (0..7) */ + al_bool enable; + al_bool periodic; /**< when true, generate periodic pulse (PPS) */ + uint8_t period_sec; /**< for periodic pulse, this is seconds + * portion of the period time + */ + uint32_t period_us; /**< this is microseconds portion of the + * period + */ + struct al_eth_pth_time start_time; /**< when to start pulse triggering */ + uint64_t pulse_width; /**< pulse width in femto seconds */ +}; + +/** + * Configure an output pulse + * This function configures an output pulse coming from the internal System + * Time. This is typically a 1Hhz pulse that is used to synchronize the + * rest of the components of the system. This API configure the Ethernet + * Controller pulse. An additional set up is required to configure the chip + * General Purpose I/O (GPIO) to enable the chip output pin. + * + * @param adapter pointer to the private structure. + * @param params output pulse configuration. + * @return 0 on success. otherwise on failure. + */ +int al_eth_pth_pulse_out_config(struct al_hal_eth_adapter *adapter, + struct al_eth_pth_pulse_out_params *params); + +/* link */ +struct al_eth_link_status { + al_bool link_up; +}; + +/** + * get link status + * + * this function should be used when no external phy is used to get + * information about the link + * + * @param adapter pointer to the private structure. + * @param status pointer to struct where to set link information + * + * @return return 0 on success. otherwise on failure. + */ +int al_eth_link_status_get(struct al_hal_eth_adapter *adapter, struct al_eth_link_status *status); + +/** + * Set LEDs to represent link status. + * + * @param adapter pointer to the private structure. + * @param link_is_up boolean indicating current link status. + * In case link is down the leds will be turned off. + * In case link is up the leds will be turned on, that means + * leds will be blinking on traffic and will be constantly lighting + * on inactive link + * @return return 0 on success. otherwise on failure. + */ +int al_eth_led_set(struct al_hal_eth_adapter *adapter, al_bool link_is_up); + +/* get statistics */ + +struct al_eth_mac_stats{ + /* sum the data and padding octets (i.e. without header and FCS) received with a valid frame. */ + uint64_t aOctetsReceivedOK; + /* sum of Payload and padding octets of frames transmitted without error*/ + uint64_t aOctetsTransmittedOK; + /* total number of packets received. Good and bad packets */ + uint32_t etherStatsPkts; + /* number of received unicast packets */ + uint32_t ifInUcastPkts; + /* number of received multicast packets */ + uint32_t ifInMulticastPkts; + /* number of received broadcast packets */ + uint32_t ifInBroadcastPkts; + /* Number of frames received with FIFO Overflow, CRC, Payload Length, Jabber and Oversized, Alignment or PHY/PCS error indication */ + uint32_t ifInErrors; + + /* number of transmitted unicast packets */ + uint32_t ifOutUcastPkts; + /* number of transmitted multicast packets */ + uint32_t ifOutMulticastPkts; + /* number of transmitted broadcast packets */ + uint32_t ifOutBroadcastPkts; + /* number of frames transmitted with FIFO Overflow, FIFO Underflow or Controller indicated error */ + uint32_t ifOutErrors; + + /* number of Frame received without error (Including Pause Frames). */ + uint32_t aFramesReceivedOK; + /* number of Frames transmitter without error (Including Pause Frames) */ + uint32_t aFramesTransmittedOK; + /* number of packets received with less than 64 octets */ + uint32_t etherStatsUndersizePkts; + /* Too short frames with CRC error, available only for RGMII and 1G Serial modes */ + uint32_t etherStatsFragments; + /* Too long frames with CRC error */ + uint32_t etherStatsJabbers; + /* packet that exceeds the valid maximum programmed frame length */ + uint32_t etherStatsOversizePkts; + /* number of frames received with a CRC error */ + uint32_t aFrameCheckSequenceErrors; + /* number of frames received with alignment error */ + uint32_t aAlignmentErrors; + /* number of dropped packets due to FIFO overflow */ + uint32_t etherStatsDropEvents; + /* number of transmitted pause frames. */ + uint32_t aPAUSEMACCtrlFramesTransmitted; + /* number of received pause frames. */ + uint32_t aPAUSEMACCtrlFramesReceived; + /* frame received exceeded the maximum length programmed with register FRM_LGTH, available only for 10G modes */ + uint32_t aFrameTooLongErrors; + /* received frame with bad length/type (between 46 and 0x600 or less + * than 46 for packets longer than 64), available only for 10G modes */ + uint32_t aInRangeLengthErrors; + /* Valid VLAN tagged frames transmitted */ + uint32_t VLANTransmittedOK; + /* Valid VLAN tagged frames received */ + uint32_t VLANReceivedOK; + /* Total number of octets received. Good and bad packets */ + uint32_t etherStatsOctets; + + /* packets of 64 octets length is received (good and bad frames are counted) */ + uint32_t etherStatsPkts64Octets; + /* Frames (good and bad) with 65 to 127 octets */ + uint32_t etherStatsPkts65to127Octets; + /* Frames (good and bad) with 128 to 255 octets */ + uint32_t etherStatsPkts128to255Octets; + /* Frames (good and bad) with 256 to 511 octets */ + uint32_t etherStatsPkts256to511Octets; + /* Frames (good and bad) with 512 to 1023 octets */ + uint32_t etherStatsPkts512to1023Octets; + /* Frames (good and bad) with 1024 to 1518 octets */ + uint32_t etherStatsPkts1024to1518Octets; + /* frames with 1519 bytes to the maximum length programmed in the register FRAME_LENGTH. */ + uint32_t etherStatsPkts1519toX; + + uint32_t eee_in; + uint32_t eee_out; +}; + +/** + * get mac statistics + * @param adapter pointer to the private structure. + * @param stats pointer to structure that will be filled with statistics. + * + * @return return 0 on success. otherwise on failure. + */ +int al_eth_mac_stats_get(struct al_hal_eth_adapter *adapter, struct al_eth_mac_stats *stats); + +struct al_eth_ec_stats{ + /* Rx Frequency adjust FIFO input packets */ + uint32_t faf_in_rx_pkt; + /* Rx Frequency adjust FIFO input short error packets */ + uint32_t faf_in_rx_short; + /* Rx Frequency adjust FIFO input long error packets */ + uint32_t faf_in_rx_long; + /* Rx Frequency adjust FIFO output packets */ + uint32_t faf_out_rx_pkt; + /* Rx Frequency adjust FIFO output short error packets */ + uint32_t faf_out_rx_short; + /* Rx Frequency adjust FIFO output long error packets */ + uint32_t faf_out_rx_long; + /* Rx Frequency adjust FIFO output drop packets */ + uint32_t faf_out_drop; + /* Number of packets written into the Rx FIFO (without FIFO error indication) */ + uint32_t rxf_in_rx_pkt; + /* Number of error packets written into the Rx FIFO (with FIFO error indication, */ + /* FIFO full indication during packet reception) */ + uint32_t rxf_in_fifo_err; + /* Number of packets read from Rx FIFO 1 */ + uint32_t lbf_in_rx_pkt; + /* Number of packets read from Rx FIFO 2 (loopback FIFO) */ + uint32_t lbf_in_fifo_err; + /* Rx FIFO output drop packets from FIFO 1 */ + uint32_t rxf_out_rx_1_pkt; + /* Rx FIFO output drop packets from FIFO 2 (loop back) */ + uint32_t rxf_out_rx_2_pkt; + /* Rx FIFO output drop packets from FIFO 1 */ + uint32_t rxf_out_drop_1_pkt; + /* Rx FIFO output drop packets from FIFO 2 (loop back) */ + uint32_t rxf_out_drop_2_pkt; + /* Rx Parser 1, input packet counter */ + uint32_t rpe_1_in_rx_pkt; + /* Rx Parser 1, output packet counter */ + uint32_t rpe_1_out_rx_pkt; + /* Rx Parser 2, input packet counter */ + uint32_t rpe_2_in_rx_pkt; + /* Rx Parser 2, output packet counter */ + uint32_t rpe_2_out_rx_pkt; + /* Rx Parser 3 (MACsec), input packet counter */ + uint32_t rpe_3_in_rx_pkt; + /* Rx Parser 3 (MACsec), output packet counter */ + uint32_t rpe_3_out_rx_pkt; + /* Tx parser, input packet counter */ + uint32_t tpe_in_tx_pkt; + /* Tx parser, output packet counter */ + uint32_t tpe_out_tx_pkt; + /* Tx packet modification, input packet counter */ + uint32_t tpm_tx_pkt; + /* Tx forwarding input packet counter */ + uint32_t tfw_in_tx_pkt; + /* Tx forwarding input packet counter */ + uint32_t tfw_out_tx_pkt; + /* Rx forwarding input packet counter */ + uint32_t rfw_in_rx_pkt; + /* Rx Forwarding, packet with VLAN command drop indication */ + uint32_t rfw_in_vlan_drop; + /* Rx Forwarding, packets with parse drop indication */ + uint32_t rfw_in_parse_drop; + /* Rx Forwarding, multicast packets */ + uint32_t rfw_in_mc; + /* Rx Forwarding, broadcast packets */ + uint32_t rfw_in_bc; + /* Rx Forwarding, tagged packets */ + uint32_t rfw_in_vlan_exist; + /* Rx Forwarding, untagged packets */ + uint32_t rfw_in_vlan_nexist; + /* Rx Forwarding, packets with MAC address drop indication (from the MAC address table) */ + uint32_t rfw_in_mac_drop; + /* Rx Forwarding, packets with undetected MAC address */ + uint32_t rfw_in_mac_ndet_drop; + /* Rx Forwarding, packets with drop indication from the control table */ + uint32_t rfw_in_ctrl_drop; + /* Rx Forwarding, packets with L3_protocol_index drop indication */ + uint32_t rfw_in_prot_i_drop; + /* EEE, number of times the system went into EEE state */ + uint32_t eee_in; +}; + +/** + * get ec statistics + * @param adapter pointer to the private structure. + * @param stats pointer to structure that will be filled with statistics. + * + * @return return 0 on success. otherwise on failure. + */ +int al_eth_ec_stats_get(struct al_hal_eth_adapter *adapter, struct al_eth_ec_stats *stats); + +struct al_eth_ec_stat_udma{ + /* Rx forwarding output packet counter */ + uint32_t rfw_out_rx_pkt; + /* Rx forwarding output drop packet counter */ + uint32_t rfw_out_drop; + /* Multi-stream write, number of Rx packets */ + uint32_t msw_in_rx_pkt; + /* Multi-stream write, number of dropped packets at SOP, Q full indication */ + uint32_t msw_drop_q_full; + /* Multi-stream write, number of dropped packets at SOP */ + uint32_t msw_drop_sop; + /* Multi-stream write, number of dropped packets at EOP, */ + /*EOP was written with error indication (not all packet data was written) */ + uint32_t msw_drop_eop; + /* Multi-stream write, number of packets written to the stream FIFO with EOP and without packet loss */ + uint32_t msw_wr_eop; + /* Multi-stream write, number of packets read from the FIFO into the stream */ + uint32_t msw_out_rx_pkt; + /* Number of transmitted packets without TSO enabled */ + uint32_t tso_no_tso_pkt; + /* Number of transmitted packets with TSO enabled */ + uint32_t tso_tso_pkt; + /* Number of TSO segments that were generated */ + uint32_t tso_seg_pkt; + /* Number of TSO segments that required padding */ + uint32_t tso_pad_pkt; + /* Tx Packet modification, MAC SA spoof error */ + uint32_t tpm_tx_spoof; + /* Tx MAC interface, input packet counter */ + uint32_t tmi_in_tx_pkt; + /* Tx MAC interface, number of packets forwarded to the MAC */ + uint32_t tmi_out_to_mac; + /* Tx MAC interface, number of packets forwarded to the Rx data path */ + uint32_t tmi_out_to_rx; + /* Tx MAC interface, number of transmitted bytes */ + uint32_t tx_q0_bytes; + /* Tx MAC interface, number of transmitted bytes */ + uint32_t tx_q1_bytes; + /* Tx MAC interface, number of transmitted bytes */ + uint32_t tx_q2_bytes; + /* Tx MAC interface, number of transmitted bytes */ + uint32_t tx_q3_bytes; + /* Tx MAC interface, number of transmitted packets */ + uint32_t tx_q0_pkts; + /* Tx MAC interface, number of transmitted packets */ + uint32_t tx_q1_pkts; + /* Tx MAC interface, number of transmitted packets */ + uint32_t tx_q2_pkts; + /* Tx MAC interface, number of transmitted packets */ + uint32_t tx_q3_pkts; +}; + +/** + * get per_udma statistics + * @param adapter pointer to the private structure. + * @param idx udma_id value + * @param stats pointer to structure that will be filled with statistics. + * + * @return return 0 on success. otherwise on failure. + */ +int al_eth_ec_stat_udma_get(struct al_hal_eth_adapter *adapter, uint8_t idx, struct al_eth_ec_stat_udma *stats); + +/* trafic control */ + +/** + * perform Function Level Reset RMN + * + * Addressing RMN: 714 + * + * @param pci_read_config_u32 pointer to function that reads register from pci header + * @param pci_write_config_u32 pointer to function that writes register from pci header + * @param handle pointer passes to the above functions as first parameter + * @param mac_base base address of the MAC registers + * + * @return 0. + */ +int al_eth_flr_rmn(int (* pci_read_config_u32)(void *handle, int where, uint32_t *val), + int (* pci_write_config_u32)(void *handle, int where, uint32_t val), + void *handle, + void __iomem *mac_base); + +/** + * perform Function Level Reset RMN but restore registers that contain board specific data + * + * the data that save and restored is the board params and mac addresses + * + * @param pci_read_config_u32 pointer to function that reads register from pci header + * @param pci_write_config_u32 pointer to function that writes register from pci header + * @param handle pointer passes to the above functions as first parameter + * @param mac_base base address of the MAC registers + * @param ec_base base address of the Ethernet Controller registers + * @param mac_addresses_num number of mac addresses to restore + * + * @return 0. + */ +int al_eth_flr_rmn_restore_params(int (* pci_read_config_u32)(void *handle, int where, uint32_t *val), + int (* pci_write_config_u32)(void *handle, int where, uint32_t val), + void *handle, + void __iomem *mac_base, + void __iomem *ec_base, + int mac_addresses_num); + +/* board specific information (media type, phy address, etc.. */ + + +enum al_eth_board_media_type { + AL_ETH_BOARD_MEDIA_TYPE_AUTO_DETECT = 0, + AL_ETH_BOARD_MEDIA_TYPE_RGMII = 1, + AL_ETH_BOARD_MEDIA_TYPE_10GBASE_SR = 2, + AL_ETH_BOARD_MEDIA_TYPE_SGMII = 3, + AL_ETH_BOARD_MEDIA_TYPE_1000BASE_X = 4, + AL_ETH_BOARD_MEDIA_TYPE_AUTO_DETECT_AUTO_SPEED = 5, + AL_ETH_BOARD_MEDIA_TYPE_SGMII_2_5G = 6, + AL_ETH_BOARD_MEDIA_TYPE_NBASE_T = 7, +}; + +enum al_eth_board_mdio_freq { + AL_ETH_BOARD_MDIO_FREQ_2_5_MHZ = 0, + AL_ETH_BOARD_MDIO_FREQ_1_MHZ = 1, +}; + +enum al_eth_board_ext_phy_if { + AL_ETH_BOARD_PHY_IF_MDIO = 0, + AL_ETH_BOARD_PHY_IF_XMDIO = 1, + AL_ETH_BOARD_PHY_IF_I2C = 2, + +}; + +enum al_eth_board_auto_neg_mode { + AL_ETH_BOARD_AUTONEG_OUT_OF_BAND = 0, + AL_ETH_BOARD_AUTONEG_IN_BAND = 1, + +}; + +/* declare the 1G mac active speed when auto negotiation disabled */ +enum al_eth_board_1g_speed { + AL_ETH_BOARD_1G_SPEED_1000M = 0, + AL_ETH_BOARD_1G_SPEED_100M = 1, + AL_ETH_BOARD_1G_SPEED_10M = 2, +}; + +enum al_eth_retimer_channel { + AL_ETH_RETIMER_CHANNEL_A = 0, + AL_ETH_RETIMER_CHANNEL_B = 1, + AL_ETH_RETIMER_CHANNEL_C = 2, + AL_ETH_RETIMER_CHANNEL_D = 3, + AL_ETH_RETIMER_CHANNEL_MAX = 4 +}; + +/* list of supported retimers */ +enum al_eth_retimer_type { + AL_ETH_RETIMER_BR_210 = 0, + AL_ETH_RETIMER_BR_410 = 1, + + AL_ETH_RETIMER_TYPE_MAX = 4, +}; + +/** structure represents the board information. this info set by boot loader + * and read by OS driver. + */ +struct al_eth_board_params { + enum al_eth_board_media_type media_type; + al_bool phy_exist; /**< external phy exist */ + uint8_t phy_mdio_addr; /**< mdio address of external phy */ + al_bool sfp_plus_module_exist; /**< SFP+ module connected */ + al_bool autoneg_enable; /**< enable Auto-Negotiation */ + al_bool kr_lt_enable; /**< enable KR Link-Training */ + al_bool kr_fec_enable; /**< enable KR FEC */ + enum al_eth_board_mdio_freq mdio_freq; /**< MDIO frequency */ + uint8_t i2c_adapter_id; /**< identifier for the i2c adapter to use to access SFP+ module */ + enum al_eth_board_ext_phy_if phy_if; /**< phy interface */ + enum al_eth_board_auto_neg_mode an_mode; /**< auto-negotiation mode (in-band / out-of-band) */ + uint8_t serdes_grp; /**< serdes's group id */ + uint8_t serdes_lane; /**< serdes's lane id */ + enum al_eth_ref_clk_freq ref_clk_freq; /**< reference clock frequency */ + al_bool dont_override_serdes; /**< prevent override serdes parameters */ + al_bool force_1000_base_x; /**< set mac to 1000 base-x mode (instead sgmii) */ + al_bool an_disable; /**< disable auto negotiation */ + enum al_eth_board_1g_speed speed; /**< port speed if AN disabled */ + al_bool half_duplex; /**< force half duplex if AN disabled */ + al_bool fc_disable; /**< disable flow control */ + al_bool retimer_exist; /**< retimer is exist on the board */ + uint8_t retimer_bus_id; /**< in what i2c bus the retimer is on */ + uint8_t retimer_i2c_addr; /**< i2c address of the retimer */ + enum al_eth_retimer_channel retimer_channel; /**< what channel connected to this port */ + al_bool dac; /**< assume direct attached cable is connected if auto detect is off or failed */ + uint8_t dac_len; /**< assume this cable length if auto detect is off or failed */ + enum al_eth_retimer_type retimer_type; /**< the type of the specific retimer */ +}; + +/** + * set board parameter of the eth port + * this function used to set the board parameters into scratchpad + * registers. those paramters can be read later by OS driver. + * + * @param mac_base the virtual address of the mac registers (PCI BAR 2) + * @param params pointer to structure the includes the paramters + * + * @return 0 on success. otherwise on failure. + */ +int al_eth_board_params_set(void * __iomem mac_base, struct al_eth_board_params *params); + +/** + * get board parameter of the eth port + * this function used to get the board parameters from scratchpad + * registers. + * + * @param mac_base the virtual address of the mac registers (PCI BAR 2) + * @param params pointer to structure where the parameters will be stored. + * + * @return 0 on success. otherwise on failure. + */ +int al_eth_board_params_get(void * __iomem mac_base, struct al_eth_board_params *params); + +/* + * Wake-On-Lan (WoL) + * + * The following few functions configure the Wake-On-Lan packet detection + * inside the Integrated Ethernet MAC. + * + * There are other alternative ways to set WoL, such using the + * external 1000Base-T transceiver to set WoL mode. + * + * These APIs do not set the system-wide power-state, nor responsible on the + * transition from Sleep to Normal power state. + * + * For system level considerations, please refer to Annapurna Labs Alpine Wiki. + */ +/* Interrupt enable WoL MAC DA Unicast detected packet */ +#define AL_ETH_WOL_INT_UNICAST AL_BIT(0) +/* Interrupt enable WoL L2 Multicast detected packet */ +#define AL_ETH_WOL_INT_MULTICAST AL_BIT(1) +/* Interrupt enable WoL L2 Broadcast detected packet */ +#define AL_ETH_WOL_INT_BROADCAST AL_BIT(2) +/* Interrupt enable WoL IPv4 detected packet */ +#define AL_ETH_WOL_INT_IPV4 AL_BIT(3) +/* Interrupt enable WoL IPv6 detected packet */ +#define AL_ETH_WOL_INT_IPV6 AL_BIT(4) +/* Interrupt enable WoL EtherType+MAC DA detected packet */ +#define AL_ETH_WOL_INT_ETHERTYPE_DA AL_BIT(5) +/* Interrupt enable WoL EtherType+L2 Broadcast detected packet */ +#define AL_ETH_WOL_INT_ETHERTYPE_BC AL_BIT(6) +/* Interrupt enable WoL parser detected packet */ +#define AL_ETH_WOL_INT_PARSER AL_BIT(7) +/* Interrupt enable WoL magic detected packet */ +#define AL_ETH_WOL_INT_MAGIC AL_BIT(8) +/* Interrupt enable WoL magic+password detected packet */ +#define AL_ETH_WOL_INT_MAGIC_PSWD AL_BIT(9) + +/* Forward enable WoL MAC DA Unicast detected packet */ +#define AL_ETH_WOL_FWRD_UNICAST AL_BIT(0) +/* Forward enable WoL L2 Multicast detected packet */ +#define AL_ETH_WOL_FWRD_MULTICAST AL_BIT(1) +/* Forward enable WoL L2 Broadcast detected packet */ +#define AL_ETH_WOL_FWRD_BROADCAST AL_BIT(2) +/* Forward enable WoL IPv4 detected packet */ +#define AL_ETH_WOL_FWRD_IPV4 AL_BIT(3) +/* Forward enable WoL IPv6 detected packet */ +#define AL_ETH_WOL_FWRD_IPV6 AL_BIT(4) +/* Forward enable WoL EtherType+MAC DA detected packet */ +#define AL_ETH_WOL_FWRD_ETHERTYPE_DA AL_BIT(5) +/* Forward enable WoL EtherType+L2 Broadcast detected packet */ +#define AL_ETH_WOL_FWRD_ETHERTYPE_BC AL_BIT(6) +/* Forward enable WoL parser detected packet */ +#define AL_ETH_WOL_FWRD_PARSER AL_BIT(7) + +struct al_eth_wol_params { + uint8_t *dest_addr; /**< 6 bytes array of destanation address for + magic packet detection */ + uint8_t *pswd; /**< 6 bytes array of the password to use */ + uint8_t *ipv4; /**< 4 bytes array of the ipv4 to use. + example: for ip = 192.168.1.2 + ipv4[0]=2, ipv4[1]=1, ipv4[2]=168, ipv4[3]=192 */ + uint8_t *ipv6; /** 16 bytes array of the ipv6 to use. + example: ip = 2607:f0d0:1002:0051:0000:0000:5231:1234 + ipv6[0]=34, ipv6[1]=12, ipv6[2]=31 .. */ + uint16_t ethr_type1; /**< first ethertype to use */ + uint16_t ethr_type2; /**< secound ethertype to use */ + uint16_t forward_mask; /**< bitmask of AL_ETH_WOL_FWRD_* of the packet + types needed to be forward. */ + uint16_t int_mask; /**< bitmask of AL_ETH_WOL_INT_* of the packet types + that will send interrupt to wake the system. */ +}; + +/** + * enable the wol mechanism + * set what type of packets will wake up the system and what type of packets + * neet to forward after the system is up + * + * beside this function wol filter also need to be set by + * calling al_eth_filter_config with AL_ETH_RFW_FILTER_WOL + * + * @param adapter pointer to the private structure + * @param wol the parameters needed to configure the wol + * + * @return 0 on success. otherwise on failure. + */ +int al_eth_wol_enable( + struct al_hal_eth_adapter *adapter, + struct al_eth_wol_params *wol); + +/** + * Disable the WoL mechnism. + * + * @param adapter pointer to the private structure + * + * @return 0 on success. otherwise on failure. + */ +int al_eth_wol_disable( + struct al_hal_eth_adapter *adapter); + +/** + * Configure tx fwd vlan table entry + * + * @param adapter pointer to the private structure + * @param idx the entry index within the vlan table. The HW uses the vlan id + * field of the packet when accessing this table. + * @param udma_mask vlan table value that indicates that the packet should be forward back to + * the udmas, through the Rx path (udma_mask is one-hot representation) + * @param fwd_to_mac vlan table value that indicates that the packet should be forward to mac + * + * @return 0 on success. otherwise on failure. + */ +int al_eth_tx_fwd_vid_table_set(struct al_hal_eth_adapter *adapter, uint32_t idx, uint8_t udma_mask, al_bool fwd_to_mac); + +/** Tx Generic protocol detect Cam compare table entry */ +struct al_eth_tx_gpd_cam_entry { + enum AL_ETH_PROTO_ID l3_proto_idx; + enum AL_ETH_PROTO_ID l4_proto_idx; + enum AL_ETH_TX_TUNNEL_MODE tunnel_control; + uint8_t source_vlan_count:2; + uint8_t tx_gpd_cam_ctrl:1; + uint8_t l3_proto_idx_mask:5; + uint8_t l4_proto_idx_mask:5; + uint8_t tunnel_control_mask:3; + uint8_t source_vlan_count_mask:2; +}; + +/** Rx Generic protocol detect Cam compare table entry */ +struct al_eth_rx_gpd_cam_entry { + enum AL_ETH_PROTO_ID outer_l3_proto_idx; + enum AL_ETH_PROTO_ID outer_l4_proto_idx; + enum AL_ETH_PROTO_ID inner_l3_proto_idx; + enum AL_ETH_PROTO_ID inner_l4_proto_idx; + uint8_t parse_ctrl; + uint8_t outer_l3_len; + uint8_t l3_priority; + uint8_t l4_dst_port_lsb; + uint8_t rx_gpd_cam_ctrl:1; + uint8_t outer_l3_proto_idx_mask:5; + uint8_t outer_l4_proto_idx_mask:5; + uint8_t inner_l3_proto_idx_mask:5; + uint8_t inner_l4_proto_idx_mask:5; + uint8_t parse_ctrl_mask; + uint8_t outer_l3_len_mask; + uint8_t l3_priority_mask; + uint8_t l4_dst_port_lsb_mask; +}; + +enum AL_ETH_TX_GCP_ALU_OPSEL { + AL_ETH_TX_GCP_ALU_L3_OFFSET = 0, + AL_ETH_TX_GCP_ALU_OUTER_L3_OFFSET = 1, + AL_ETH_TX_GCP_ALU_L3_LEN = 2, + AL_ETH_TX_GCP_ALU_OUTER_L3_LEN = 3, + AL_ETH_TX_GCP_ALU_L4_OFFSET = 4, + AL_ETH_TX_GCP_ALU_L4_LEN = 5, + AL_ETH_TX_GCP_ALU_TABLE_VAL = 10 +}; + +enum AL_ETH_RX_GCP_ALU_OPSEL { + AL_ETH_RX_GCP_ALU_OUTER_L3_OFFSET = 0, + AL_ETH_RX_GCP_ALU_INNER_L3_OFFSET = 1, + AL_ETH_RX_GCP_ALU_OUTER_L4_OFFSET = 2, + AL_ETH_RX_GCP_ALU_INNER_L4_OFFSET = 3, + AL_ETH_RX_GCP_ALU_OUTER_L3_HDR_LEN_LAT = 4, + AL_ETH_RX_GCP_ALU_INNER_L3_HDR_LEN_LAT = 5, + AL_ETH_RX_GCP_ALU_OUTER_L3_HDR_LEN_SEL = 6, + AL_ETH_RX_GCP_ALU_INNER_L3_HDR_LEN_SEL = 7, + AL_ETH_RX_GCP_ALU_PARSE_RESULT_VECTOR_OFFSET_1 = 8, + AL_ETH_RX_GCP_ALU_PARSE_RESULT_VECTOR_OFFSET_2 = 9, + AL_ETH_RX_GCP_ALU_TABLE_VAL = 10 +}; + +/** Tx Generic crc prameters table entry */ + +struct al_eth_tx_gcp_table_entry { + uint8_t poly_sel:1; + uint8_t crc32_bit_comp:1; + uint8_t crc32_bit_swap:1; + uint8_t crc32_byte_swap:1; + uint8_t data_bit_swap:1; + uint8_t data_byte_swap:1; + uint8_t trail_size:4; + uint8_t head_size:8; + uint8_t head_calc:1; + uint8_t mask_polarity:1; + enum AL_ETH_ALU_OPCODE tx_alu_opcode_1; + enum AL_ETH_ALU_OPCODE tx_alu_opcode_2; + enum AL_ETH_ALU_OPCODE tx_alu_opcode_3; + enum AL_ETH_TX_GCP_ALU_OPSEL tx_alu_opsel_1; + enum AL_ETH_TX_GCP_ALU_OPSEL tx_alu_opsel_2; + enum AL_ETH_TX_GCP_ALU_OPSEL tx_alu_opsel_3; + enum AL_ETH_TX_GCP_ALU_OPSEL tx_alu_opsel_4; + uint32_t gcp_mask[6]; + uint32_t crc_init; + uint8_t gcp_table_res:7; + uint16_t alu_val:9; +}; + +/** Rx Generic crc prameters table entry */ + +struct al_eth_rx_gcp_table_entry { + uint8_t poly_sel:1; + uint8_t crc32_bit_comp:1; + uint8_t crc32_bit_swap:1; + uint8_t crc32_byte_swap:1; + uint8_t data_bit_swap:1; + uint8_t data_byte_swap:1; + uint8_t trail_size:4; + uint8_t head_size:8; + uint8_t head_calc:1; + uint8_t mask_polarity:1; + enum AL_ETH_ALU_OPCODE rx_alu_opcode_1; + enum AL_ETH_ALU_OPCODE rx_alu_opcode_2; + enum AL_ETH_ALU_OPCODE rx_alu_opcode_3; + enum AL_ETH_RX_GCP_ALU_OPSEL rx_alu_opsel_1; + enum AL_ETH_RX_GCP_ALU_OPSEL rx_alu_opsel_2; + enum AL_ETH_RX_GCP_ALU_OPSEL rx_alu_opsel_3; + enum AL_ETH_RX_GCP_ALU_OPSEL rx_alu_opsel_4; + uint32_t gcp_mask[6]; + uint32_t crc_init; + uint32_t gcp_table_res:27; + uint16_t alu_val:9; +}; + +/** Tx per_protocol_number crc & l3_checksum & l4_checksum command table entry */ + +struct al_eth_tx_crc_chksum_replace_cmd_for_protocol_num_entry { + al_bool crc_en_00; /*from Tx_buffer_descriptor: enable_l4_checksum is 0 ,enable_l3_checksum is 0 */ + al_bool crc_en_01; /*from Tx_buffer_descriptor: enable_l4_checksum is 0 ,enable_l3_checksum is 1 */ + al_bool crc_en_10; /*from Tx_buffer_descriptor: enable_l4_checksum is 1 ,enable_l3_checksum is 0 */ + al_bool crc_en_11; /*from Tx_buffer_descriptor: enable_l4_checksum is 1 ,enable_l3_checksum is 1 */ + al_bool l4_csum_en_00; /*from Tx_buffer_descriptor: enable_l4_checksum is 0 ,enable_l3_checksum is 0 */ + al_bool l4_csum_en_01; /*from Tx_buffer_descriptor: enable_l4_checksum is 0 ,enable_l3_checksum is 1 */ + al_bool l4_csum_en_10; /*from Tx_buffer_descriptor: enable_l4_checksum is 1 ,enable_l3_checksum is 0 */ + al_bool l4_csum_en_11; /*from Tx_buffer_descriptor: enable_l4_checksum is 1 ,enable_l3_checksum is 1 */ + al_bool l3_csum_en_00; /*from Tx_buffer_descriptor: enable_l4_checksum is 0 ,enable_l3_checksum is 0 */ + al_bool l3_csum_en_01; /*from Tx_buffer_descriptor: enable_l4_checksum is 0 ,enable_l3_checksum is 1 */ + al_bool l3_csum_en_10; /*from Tx_buffer_descriptor: enable_l4_checksum is 1 ,enable_l3_checksum is 0 */ + al_bool l3_csum_en_11; /*from Tx_buffer_descriptor: enable_l4_checksum is 1 ,enable_l3_checksum is 1 */ +}; + +/** + * Configure tx_gpd_entry + * + * @param adapter pointer to the private structure + * @param idx the entry index + * @param tx_gpd_entry entry data for the Tx protocol detect Cam compare table + * + * @return 0 on success. otherwise on failure. + * + */ +int al_eth_tx_protocol_detect_table_entry_set(struct al_hal_eth_adapter *adapter, uint32_t idx, + struct al_eth_tx_gpd_cam_entry *tx_gpd_entry); + +/** + * Configure tx_gcp_entry + * + * @param adapter pointer to the private structure + * @param idx the entry index + * @param tx_gcp_entry entry data for the Tx Generic crc prameters table + * + * @return 0 on success. otherwise on failure. + * + */ +int al_eth_tx_generic_crc_table_entry_set(struct al_hal_eth_adapter *adapter, uint32_t idx, + struct al_eth_tx_gcp_table_entry *tx_gcp_entry); + +/** + * Configure tx_crc_chksum_replace_cmd_entry + * + * @param adapter pointer to the private structure + * @param idx the entry index + * @param tx_replace_entry entry data for the Tx crc_&_l3_checksum_&_l4_checksum replace command table + * + * @return 0 on success. otherwise on failure. + * + */ +int al_eth_tx_crc_chksum_replace_cmd_entry_set(struct al_hal_eth_adapter *adapter, uint32_t idx, + struct al_eth_tx_crc_chksum_replace_cmd_for_protocol_num_entry *tx_replace_entry); + +/** + * Configure rx_gpd_entry + * + * @param adapter pointer to the private structure + * @param idx the entry index + * @param rx_gpd_entry entry data for the Tx protocol detect Cam compare table + * + * @return 0 on success. otherwise on failure. + * + */ +int al_eth_rx_protocol_detect_table_entry_set(struct al_hal_eth_adapter *adapter, uint32_t idx, + struct al_eth_rx_gpd_cam_entry *rx_gpd_entry); + +/** + * Configure rx_gcp_entry + * + * @param adapter pointer to the private structure + * @param idx the entry index + * @param rx_gpd_entry entry data for the Tx protocol detect Cam compare table + * @param rx_gcp_entry entry data for the Tx Generic crc prameters table + * + * @return 0 on success. otherwise on failure. + * + */ +int al_eth_rx_generic_crc_table_entry_set(struct al_hal_eth_adapter *adapter, uint32_t idx, + struct al_eth_rx_gcp_table_entry *rx_gcp_entry); + +/** + * Configure tx_gpd_table and regs + * + * @param adapter pointer to the private structure + * + */ +int al_eth_tx_protocol_detect_table_init(struct al_hal_eth_adapter *adapter); + +/** + * Configure crc_chksum_replace_cmd_table + * + * @param adapter pointer to the private structure + * + */ +int al_eth_tx_crc_chksum_replace_cmd_init(struct al_hal_eth_adapter *adapter); + +/** + * Configure tx_gcp_table and regs + * + * @param adapter pointer to the private structure + * + */ +int al_eth_tx_generic_crc_table_init(struct al_hal_eth_adapter *adapter); + +/** + * Configure rx_gpd_table and regs + * + * @param adapter pointer to the private structure + * + */ +int al_eth_rx_protocol_detect_table_init(struct al_hal_eth_adapter *adapter); + +/** + * Configure rx_gcp_table and regs + * + * @param adapter pointer to the private structure + * + */ +int al_eth_rx_generic_crc_table_init(struct al_hal_eth_adapter *adapter); + +#ifdef __cplusplus +} +#endif +/* *INDENT-ON* */ +#endif /* __AL_HAL_ETH_H__ */ +/** @} end of Ethernet group */ diff --git a/eth/al_hal_eth_alu.h b/eth/al_hal_eth_alu.h new file mode 100644 index 00000000000..2f5f1fa2301 --- /dev/null +++ b/eth/al_hal_eth_alu.h @@ -0,0 +1,95 @@ +/******************************************************************************* +Copyright (C) 2015 Annapurna Labs Ltd. + +This file may be licensed under the terms of the Annapurna Labs Commercial +License Agreement. + +Alternatively, this file can be distributed under the terms of the GNU General +Public License V2 as published by the Free Software Foundation and can be +found at http://www.gnu.org/licenses/gpl-2.0.html + +Alternatively, redistribution and use in source and binary forms, with or +without modification, are permitted provided that the following conditions are +met: + +* Redistributions of source code must retain the above copyright notice, +this list of conditions and the following disclaimer. + +* Redistributions in binary form must reproduce the above copyright +notice, this list of conditions and the following disclaimer in +the documentation and/or other materials provided with the +distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +*******************************************************************************/ + +/** + * @defgroup group_eth_alu_api API + * Ethernet Controller generic ALU API + * @ingroup group_eth + * @{ + * @file al_hal_eth_alu.h + * + * @brief Header file for control parameters for the generic ALU unit in the Ethernet Datapath for Advanced Ethernet port. + * + */ + +#ifndef __AL_HAL_ETH_ALU_H__ +#define __AL_HAL_ETH_ALU_H__ + +/* *INDENT-OFF* */ +#ifdef __cplusplus +extern "C" { +#endif +/* *INDENT-ON* */ + +enum AL_ETH_ALU_OPCODE +{ + AL_ALU_FWD_A = 0, + AL_ALU_ARITHMETIC_ADD = 1, + AL_ALU_ARITHMETIC_SUBTRACT = 2, + AL_ALU_BITWISE_AND = 3, + AL_ALU_BITWISE_OR = 4, + AL_ALU_SHIFT_RIGHT_A_BY_B = 5, + AL_ALU_SHIFT_LEFT_A_BY_B = 6, + AL_ALU_BITWISE_XOR = 7, + AL_ALU_FWD_INV_A = 16, + AL_ALU_ARITHMETIC_ADD_INV_A_AND_B = 17, + AL_ALU_ARITHMETIC_SUBTRACT_INV_A_AND_B = 18, + AL_ALU_BITWISE_AND_INV_A_AND_B = 19, + AL_ALU_BITWISE_OR_INV_A_AND_B = 20, + AL_ALU_SHIFT_RIGHT_INV_A_BY_B = 21, + AL_ALU_SHIFT_LEFT_INV_A_BY_B = 22, + AL_ALU_BITWISE_XOR_INV_A_AND_B = 23, + AL_ALU_ARITHMETIC_ADD_A_AND_INV_B = 33, + AL_ALU_ARITHMETIC_SUBTRACT_A_AND_INV_B = 34, + AL_ALU_BITWISE_AND_A_AND_INV_B = 35, + AL_ALU_BITWISE_OR_A_AND_INV_B = 36, + AL_ALU_SHIFT_RIGHT_A_BY_INV_B = 37, + AL_ALU_SHIFT_LEFT_A_BY_INV_B = 38, + AL_ALU_BITWISE_XOR_A_AND_INV_B = 39, + AL_ALU_ARITHMETIC_ADD_INV_A_AND_INV_B = 49, + AL_ALU_ARITHMETIC_SUBTRACT_INV_A_AND = 50, + AL_ALU_BITWISE_AND_INV_A_AND_INV_B = 51, + AL_ALU_BITWISE_OR_INV_A_AND_INV_B = 52, + AL_ALU_SHIFT_RIGHT_INV_A_BY_INV_B = 53, + AL_ALU_SHIFT_LEFT_INV_A_BY_INV_B = 54, + AL_ALU_BITWISE_XOR_INV_A_AND_INV_B = 55 +}; + +#ifdef __cplusplus +} +#endif +/* *INDENT-ON* */ +#endif /* __AL_HAL_ETH_ALU_H__ */ +/** @} end of Ethernet group */ diff --git a/eth/al_hal_eth_ec_regs.h b/eth/al_hal_eth_ec_regs.h new file mode 100644 index 00000000000..153e0d57a45 --- /dev/null +++ b/eth/al_hal_eth_ec_regs.h @@ -0,0 +1,3362 @@ +/*- +******************************************************************************* +Copyright (C) 2015 Annapurna Labs Ltd. + +This file may be licensed under the terms of the Annapurna Labs Commercial +License Agreement. + +Alternatively, this file can be distributed under the terms of the GNU General +Public License V2 as published by the Free Software Foundation and can be +found at http://www.gnu.org/licenses/gpl-2.0.html + +Alternatively, redistribution and use in source and binary forms, with or +without modification, are permitted provided that the following conditions are +met: + + * Redistributions of source code must retain the above copyright notice, +this list of conditions and the following disclaimer. + + * Redistributions in binary form must reproduce the above copyright +notice, this list of conditions and the following disclaimer in +the documentation and/or other materials provided with the +distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +*******************************************************************************/ + +/** + * @{ + * @file al_hal_eth_ec_regs.h + * + * @brief Ethernet controller registers + * + */ + +#ifndef __AL_HAL_EC_REG_H +#define __AL_HAL_EC_REG_H + +#include "al_hal_plat_types.h" + +#ifdef __cplusplus +extern "C" { +#endif +/* +* Unit Registers +*/ + + + +struct al_ec_gen { + /* [0x0] Ethernet controller Version */ + uint32_t version; + /* [0x4] Enable modules operation. */ + uint32_t en; + /* [0x8] Enable FIFO operation on the EC side. */ + uint32_t fifo_en; + /* [0xc] General L2 configuration for the Ethernet controlle ... */ + uint32_t l2; + /* [0x10] Configure protocol index values */ + uint32_t cfg_i; + /* [0x14] Configure protocol index values (extended protocols ... */ + uint32_t cfg_i_ext; + /* [0x18] Enable modules operation (extended operations). */ + uint32_t en_ext; + uint32_t rsrvd[9]; +}; +struct al_ec_mac { + /* [0x0] General configuration of the MAC side of the Ethern ... */ + uint32_t gen; + /* [0x4] Minimum packet size */ + uint32_t min_pkt; + /* [0x8] Maximum packet size */ + uint32_t max_pkt; + uint32_t rsrvd[13]; +}; +struct al_ec_rxf { + /* [0x0] Rx FIFO input controller configuration 1 */ + uint32_t cfg_1; + /* [0x4] Rx FIFO input controller configuration 2 */ + uint32_t cfg_2; + /* [0x8] Threshold to start reading packet from the Rx FIFO */ + uint32_t rd_fifo; + /* [0xc] Threshold to stop writing packet to the Rx FIFO */ + uint32_t wr_fifo; + /* [0x10] Threshold to stop writing packet to the loopback FI ... */ + uint32_t lb_fifo; + /* [0x14] Rx FIFO input controller loopback FIFO configuratio ... */ + uint32_t cfg_lb; + /* [0x18] Configuration for dropping packet at the FIFO outpu ... */ + uint32_t out_drop; + uint32_t rsrvd[25]; +}; +struct al_ec_epe { + /* [0x0] Ethernet parsing engine configuration 1 */ + uint32_t parse_cfg; + /* [0x4] Protocol index action table address */ + uint32_t act_table_addr; + /* [0x8] Protocol index action table data */ + uint32_t act_table_data_1; + /* [0xc] Protocol index action table data */ + uint32_t act_table_data_2; + /* [0x10] Protocol index action table data */ + uint32_t act_table_data_3; + /* [0x14] Protocol index action table data */ + uint32_t act_table_data_4; + /* [0x18] Protocol index action table data */ + uint32_t act_table_data_5; + /* [0x1c] Protocol index action table data */ + uint32_t act_table_data_6; + /* [0x20] Input result vector, default values for parser inpu ... */ + uint32_t res_def; + /* [0x24] Result input vector selection */ + uint32_t res_in; + uint32_t rsrvd[6]; +}; +struct al_ec_epe_res { + /* [0x0] Parser result vector pointer */ + uint32_t p1; + /* [0x4] Parser result vector pointer */ + uint32_t p2; + /* [0x8] Parser result vector pointer */ + uint32_t p3; + /* [0xc] Parser result vector pointer */ + uint32_t p4; + /* [0x10] Parser result vector pointer */ + uint32_t p5; + /* [0x14] Parser result vector pointer */ + uint32_t p6; + /* [0x18] Parser result vector pointer */ + uint32_t p7; + /* [0x1c] Parser result vector pointer */ + uint32_t p8; + /* [0x20] Parser result vector pointer */ + uint32_t p9; + /* [0x24] Parser result vector pointer */ + uint32_t p10; + /* [0x28] Parser result vector pointer */ + uint32_t p11; + /* [0x2c] Parser result vector pointer */ + uint32_t p12; + /* [0x30] Parser result vector pointer */ + uint32_t p13; + /* [0x34] Parser result vector pointer */ + uint32_t p14; + /* [0x38] Parser result vector pointer */ + uint32_t p15; + /* [0x3c] Parser result vector pointer */ + uint32_t p16; + /* [0x40] Parser result vector pointer */ + uint32_t p17; + /* [0x44] Parser result vector pointer */ + uint32_t p18; + /* [0x48] Parser result vector pointer */ + uint32_t p19; + /* [0x4c] Parser result vector pointer */ + uint32_t p20; + uint32_t rsrvd[12]; +}; +struct al_ec_epe_h { + /* [0x0] Header length, support for header length table for ... */ + uint32_t hdr_len; +}; +struct al_ec_epe_p { + /* [0x0] Data for comparison */ + uint32_t comp_data; + /* [0x4] Mask for comparison */ + uint32_t comp_mask; + /* [0x8] Compare control */ + uint32_t comp_ctrl; + uint32_t rsrvd[4]; +}; +struct al_ec_epe_a { + /* [0x0] Protocol index action register */ + uint32_t prot_act; +}; +struct al_ec_rfw { + /* [0x0] Tuple (4/2) Hash configuration */ + uint32_t thash_cfg_1; + /* [0x4] Tuple (4/2) Hash configuration */ + uint32_t thash_cfg_2; + /* [0x8] MAC Hash configuration */ + uint32_t mhash_cfg_1; + /* [0xc] MAC Hash configuration */ + uint32_t mhash_cfg_2; + /* [0x10] MAC Hash configuration */ + uint32_t hdr_split; + /* [0x14] Masking the errors described in register rxf_drop ... */ + uint32_t meta_err; + /* [0x18] Configuration for generating the MetaData for the R ... */ + uint32_t meta; + /* [0x1c] Configuration for generating the MetaData for the R ... */ + uint32_t filter; + /* [0x20] 4 tupple hash table address */ + uint32_t thash_table_addr; + /* [0x24] 4 tupple hash table data */ + uint32_t thash_table_data; + /* [0x28] MAC hash table address */ + uint32_t mhash_table_addr; + /* [0x2c] MAC hash table data */ + uint32_t mhash_table_data; + /* [0x30] VLAN table address */ + uint32_t vid_table_addr; + /* [0x34] VLAN table data */ + uint32_t vid_table_data; + /* [0x38] VLAN p-bits table address */ + uint32_t pbits_table_addr; + /* [0x3c] VLAN p-bits table data */ + uint32_t pbits_table_data; + /* [0x40] DSCP table address */ + uint32_t dscp_table_addr; + /* [0x44] DSCP table data */ + uint32_t dscp_table_data; + /* [0x48] TC table address */ + uint32_t tc_table_addr; + /* [0x4c] TC table data */ + uint32_t tc_table_data; + /* [0x50] Control table address */ + uint32_t ctrl_table_addr; + /* [0x54] Control table data */ + uint32_t ctrl_table_data; + /* [0x58] Forwarding output configuration */ + uint32_t out_cfg; + /* [0x5c] Flow steering mechanism, +Table address */ + uint32_t fsm_table_addr; + /* [0x60] Flow steering mechanism, +Table data */ + uint32_t fsm_table_data; + /* [0x64] Selection of data to be used in packet forwarding0 ... */ + uint32_t ctrl_sel; + /* [0x68] Default VLAN data, used for untagged packets */ + uint32_t default_vlan; + /* [0x6c] Default HASH output values */ + uint32_t default_hash; + /* [0x70] Default override values, if a packet was filtered b ... */ + uint32_t default_or; + /* [0x74] Latched information when a drop condition occurred */ + uint32_t drop_latch; + /* [0x78] Check sum calculation configuration */ + uint32_t checksum; + /* [0x7c] LRO offload engine configuration register */ + uint32_t lro_cfg_1; + /* [0x80] LRO offload engine Check rules configurations for I ... */ + uint32_t lro_check_ipv4; + /* [0x84] LRO offload engine IPv4 values configuration */ + uint32_t lro_ipv4; + /* [0x88] LRO offload engine Check rules configurations for I ... */ + uint32_t lro_check_ipv6; + /* [0x8c] LRO offload engine IPv6 values configuration */ + uint32_t lro_ipv6; + /* [0x90] LRO offload engine Check rules configurations for T ... */ + uint32_t lro_check_tcp; + /* [0x94] LRO offload engine IPv6 values configuration */ + uint32_t lro_tcp; + /* [0x98] LRO offload engine Check rules configurations for U ... */ + uint32_t lro_check_udp; + /* [0x9c] LRO offload engine Check rules configurations for U ... */ + uint32_t lro_check_l2; + /* [0xa0] LRO offload engine Check rules configurations for U ... */ + uint32_t lro_check_gen; + /* [0xa4] Rules for storing packet information into the cache ... */ + uint32_t lro_store; + /* [0xa8] VLAN table default */ + uint32_t vid_table_def; + /* [0xac] Control table default */ + uint32_t ctrl_table_def; + /* [0xb0] Additional configuration 0 */ + uint32_t cfg_a_0; + /* [0xb4] Tuple (4/2) Hash configuration (extended for RoCE a ... */ + uint32_t thash_cfg_3; + /* [0xb8] Tuple (4/2) Hash configuration , mask for the input ... */ + uint32_t thash_mask_outer_ipv6; + /* [0xbc] Tuple (4/2) Hash configuration , mask for the input ... */ + uint32_t thash_mask_outer; + /* [0xc0] Tuple (4/2) Hash configuration , mask for the input ... */ + uint32_t thash_mask_inner_ipv6; + /* [0xc4] Tuple (4/2) Hash configuration , mask for the input ... */ + uint32_t thash_mask_inner; + uint32_t rsrvd[10]; +}; +struct al_ec_rfw_udma { + /* [0x0] Per UDMA default configuration */ + uint32_t def_cfg; +}; +struct al_ec_rfw_hash { + /* [0x0] key configuration (320 bits) */ + uint32_t key; +}; +struct al_ec_rfw_priority { + /* [0x0] Priority to queue mapping configuration */ + uint32_t queue; +}; +struct al_ec_rfw_default { + /* [0x0] Default forwarding configuration options */ + uint32_t opt_1; +}; +struct al_ec_fwd_mac { + /* [0x0] MAC address data [31:0] */ + uint32_t data_l; + /* [0x4] MAC address data [15:0] */ + uint32_t data_h; + /* [0x8] MAC address mask [31:0] */ + uint32_t mask_l; + /* [0xc] MAC address mask [15:0] */ + uint32_t mask_h; + /* [0x10] MAC compare control */ + uint32_t ctrl; +}; +struct al_ec_msw { + /* [0x0] Configuration for unicast packets */ + uint32_t uc; + /* [0x4] Configuration for multicast packets */ + uint32_t mc; + /* [0x8] Configuration for broadcast packets */ + uint32_t bc; + uint32_t rsrvd[3]; +}; +struct al_ec_tso { + /* [0x0] Input configuration */ + uint32_t in_cfg; + /* [0x4] MetaData default cache table address */ + uint32_t cache_table_addr; + /* [0x8] MetaData default cache table data */ + uint32_t cache_table_data_1; + /* [0xc] MetaData default cache table data */ + uint32_t cache_table_data_2; + /* [0x10] MetaData default cache table data */ + uint32_t cache_table_data_3; + /* [0x14] MetaData default cache table data */ + uint32_t cache_table_data_4; + /* [0x18] TCP control bit operation for first segment */ + uint32_t ctrl_first; + /* [0x1c] TCP control bit operation for middle segments */ + uint32_t ctrl_middle; + /* [0x20] TCP control bit operation for last segment */ + uint32_t ctrl_last; + /* [0x24] Additional TSO configurations */ + uint32_t cfg_add_0; + /* [0x28] TSO configuration for tunnelled packets */ + uint32_t cfg_tunnel; + uint32_t rsrvd[13]; +}; +struct al_ec_tso_sel { + /* [0x0] MSS value */ + uint32_t mss; +}; +struct al_ec_tpe { + /* [0x0] Parsing configuration */ + uint32_t parse; + uint32_t rsrvd[15]; +}; +struct al_ec_tpm_udma { + /* [0x0] Default VLAN data */ + uint32_t vlan_data; + /* [0x4] UDMA MAC SA information for spoofing */ + uint32_t mac_sa_1; + /* [0x8] UDMA MAC SA information for spoofing */ + uint32_t mac_sa_2; +}; +struct al_ec_tpm_sel { + /* [0x0] Ethertype values for VLAN modification */ + uint32_t etype; +}; +struct al_ec_tfw { + /* [0x0] Tx FIFO Wr configuration */ + uint32_t tx_wr_fifo; + /* [0x4] VLAN table address */ + uint32_t tx_vid_table_addr; + /* [0x8] VLAN table data */ + uint32_t tx_vid_table_data; + /* [0xc] Tx FIFO Rd configuration */ + uint32_t tx_rd_fifo; + /* [0x10] Tx FIFO Rd configuration, checksum insertion */ + uint32_t tx_checksum; + /* [0x14] Tx forwarding general configuration register */ + uint32_t tx_gen; + /* [0x18] Tx spoofing configuration */ + uint32_t tx_spf; + /* [0x1c] TX data FIFO status */ + uint32_t data_fifo; + /* [0x20] Tx control FIFO status */ + uint32_t ctrl_fifo; + /* [0x24] Tx header FIFO status */ + uint32_t hdr_fifo; + uint32_t rsrvd[14]; +}; +struct al_ec_tfw_udma { + /* [0x0] Default GMDA output bitmap for unicast packet */ + uint32_t uc_udma; + /* [0x4] Default GMDA output bitmap for multicast packet */ + uint32_t mc_udma; + /* [0x8] Default GMDA output bitmap for broadcast packet */ + uint32_t bc_udma; + /* [0xc] Tx spoofing configuration */ + uint32_t spf_cmd; + /* [0x10] Forwarding decision control */ + uint32_t fwd_dec; + uint32_t rsrvd; +}; +struct al_ec_tmi { + /* [0x0] Forward packets back to the Rx data path for local ... */ + uint32_t tx_cfg; + uint32_t rsrvd[3]; +}; +struct al_ec_efc { + /* [0x0] Mask of pause_on [7:0] for the Ethernet controller ... */ + uint32_t ec_pause; + /* [0x4] Mask of Ethernet controller Almost Full indication ... */ + uint32_t ec_xoff; + /* [0x8] Mask for generating XON indication pulse */ + uint32_t xon; + /* [0xc] Mask for generating GPIO output XOFF indication fro ... */ + uint32_t gpio; + /* [0x10] Rx FIFO threshold for generating the Almost Full in ... */ + uint32_t rx_fifo_af; + /* [0x14] Rx FIFO threshold for generating the Almost Full in ... */ + uint32_t rx_fifo_hyst; + /* [0x18] Rx FIFO threshold for generating the Almost Full in ... */ + uint32_t stat; + /* [0x1c] XOFF timer for the 1G MACSets the interval (in SB_C ... */ + uint32_t xoff_timer_1g; + /* [0x20] PFC force flow control generation */ + uint32_t ec_pfc; + uint32_t rsrvd[3]; +}; +struct al_ec_fc_udma { + /* [0x0] Mask of "pause_on" [0] for all queues */ + uint32_t q_pause_0; + /* [0x4] Mask of "pause_on" [1] for all queues */ + uint32_t q_pause_1; + /* [0x8] Mask of "pause_on" [2] for all queues */ + uint32_t q_pause_2; + /* [0xc] Mask of "pause_on" [3] for all queues */ + uint32_t q_pause_3; + /* [0x10] Mask of "pause_on" [4] for all queues */ + uint32_t q_pause_4; + /* [0x14] Mask of "pause_on" [5] for all queues */ + uint32_t q_pause_5; + /* [0x18] Mask of "pause_on" [6] for all queues */ + uint32_t q_pause_6; + /* [0x1c] Mask of "pause_on" [7] for all queues */ + uint32_t q_pause_7; + /* [0x20] Mask of external GPIO input pause [0] for all queue ... */ + uint32_t q_gpio_0; + /* [0x24] Mask of external GPIO input pause [1] for all queue ... */ + uint32_t q_gpio_1; + /* [0x28] Mask of external GPIO input pause [2] for all queue ... */ + uint32_t q_gpio_2; + /* [0x2c] Mask of external GPIO input pause [3] for all queue ... */ + uint32_t q_gpio_3; + /* [0x30] Mask of external GPIO input [4] for all queues */ + uint32_t q_gpio_4; + /* [0x34] Mask of external GPIO input [5] for all queues */ + uint32_t q_gpio_5; + /* [0x38] Mask of external GPIO input [6] for all queues */ + uint32_t q_gpio_6; + /* [0x3c] Mask of external GPIO input [7] for all queues */ + uint32_t q_gpio_7; + /* [0x40] Mask of "pause_on" [7:0] for the UDMA stream inter ... */ + uint32_t s_pause; + /* [0x44] Mask of Rx Almost Full indication for generating XO ... */ + uint32_t q_xoff_0; + /* [0x48] Mask of Rx Almost Full indication for generating XO ... */ + uint32_t q_xoff_1; + /* [0x4c] Mask of Rx Almost Full indication for generating XO ... */ + uint32_t q_xoff_2; + /* [0x50] Mask of Rx Almost Full indication for generating XO ... */ + uint32_t q_xoff_3; + /* [0x54] Mask of Rx Almost Full indication for generating XO ... */ + uint32_t q_xoff_4; + /* [0x58] Mask of Rx Almost Full indication for generating XO ... */ + uint32_t q_xoff_5; + /* [0x5c] Mask of Rx Almost Full indication for generating XO ... */ + uint32_t q_xoff_6; + /* [0x60] Mask of Rx Almost Full indication for generating XO ... */ + uint32_t q_xoff_7; + uint32_t rsrvd[7]; +}; +struct al_ec_tpg_rpa_res { + /* [0x0] NOT used */ + uint32_t not_used; + uint32_t rsrvd[63]; +}; +struct al_ec_eee { + /* [0x0] EEE configuration */ + uint32_t cfg_e; + /* [0x4] Number of clocks to get into EEE mode. */ + uint32_t pre_cnt; + /* [0x8] Number of clocks to stop MAC EEE mode after getting ... */ + uint32_t post_cnt; + /* [0xc] Number of clocks to stop the Tx MAC interface after ... */ + uint32_t stop_cnt; + /* [0x10] EEE status */ + uint32_t stat_eee; + uint32_t rsrvd[59]; +}; +struct al_ec_stat { + /* [0x0] Rx Frequency adjust FIFO input packets */ + uint32_t faf_in_rx_pkt; + /* [0x4] Rx Frequency adjust FIFO input short error packets */ + uint32_t faf_in_rx_short; + /* [0x8] Rx Frequency adjust FIFO input long error packets */ + uint32_t faf_in_rx_long; + /* [0xc] Rx Frequency adjust FIFO output packets */ + uint32_t faf_out_rx_pkt; + /* [0x10] Rx Frequency adjust FIFO output short error packets ... */ + uint32_t faf_out_rx_short; + /* [0x14] Rx Frequency adjust FIFO output long error packets */ + uint32_t faf_out_rx_long; + /* [0x18] Rx Frequency adjust FIFO output drop packets */ + uint32_t faf_out_drop; + /* [0x1c] Number of packets written into the Rx FIFO (without ... */ + uint32_t rxf_in_rx_pkt; + /* [0x20] Number of error packets written into the Rx FIFO (w ... */ + uint32_t rxf_in_fifo_err; + /* [0x24] Number of packets written into the loopback FIFO (w ... */ + uint32_t lbf_in_rx_pkt; + /* [0x28] Number of error packets written into the loopback F ... */ + uint32_t lbf_in_fifo_err; + /* [0x2c] Number of packets read from Rx FIFO 1 */ + uint32_t rxf_out_rx_1_pkt; + /* [0x30] Number of packets read from Rx FIFO 2 (loopback FIF ... */ + uint32_t rxf_out_rx_2_pkt; + /* [0x34] Rx FIFO output drop packets from FIFO 1 */ + uint32_t rxf_out_drop_1_pkt; + /* [0x38] Rx FIFO output drop packets from FIFO 2 (loopback) */ + uint32_t rxf_out_drop_2_pkt; + /* [0x3c] Rx Parser 1, input packet counter */ + uint32_t rpe_1_in_rx_pkt; + /* [0x40] Rx Parser 1, output packet counter */ + uint32_t rpe_1_out_rx_pkt; + /* [0x44] Rx Parser 2, input packet counter */ + uint32_t rpe_2_in_rx_pkt; + /* [0x48] Rx Parser 2, output packet counter */ + uint32_t rpe_2_out_rx_pkt; + /* [0x4c] Rx Parser 3 (MACsec), input packet counter */ + uint32_t rpe_3_in_rx_pkt; + /* [0x50] Rx Parser 3 (MACsec), output packet counter */ + uint32_t rpe_3_out_rx_pkt; + /* [0x54] Tx parser, input packet counter */ + uint32_t tpe_in_tx_pkt; + /* [0x58] Tx parser, output packet counter */ + uint32_t tpe_out_tx_pkt; + /* [0x5c] Tx packet modification, input packet counter */ + uint32_t tpm_tx_pkt; + /* [0x60] Tx forwarding input packet counter */ + uint32_t tfw_in_tx_pkt; + /* [0x64] Tx forwarding input packet counter */ + uint32_t tfw_out_tx_pkt; + /* [0x68] Rx forwarding input packet counter */ + uint32_t rfw_in_rx_pkt; + /* [0x6c] Rx Forwarding, packet with VLAN command drop indica ... */ + uint32_t rfw_in_vlan_drop; + /* [0x70] Rx Forwarding, packets with parse drop indication */ + uint32_t rfw_in_parse_drop; + /* [0x74] Rx Forwarding, multicast packets */ + uint32_t rfw_in_mc; + /* [0x78] Rx Forwarding, broadcast packets */ + uint32_t rfw_in_bc; + /* [0x7c] Rx Forwarding, tagged packets */ + uint32_t rfw_in_vlan_exist; + /* [0x80] Rx Forwarding, untagged packets */ + uint32_t rfw_in_vlan_nexist; + /* [0x84] Rx Forwarding, packets with MAC address drop indica ... */ + uint32_t rfw_in_mac_drop; + /* [0x88] Rx Forwarding, packets with undetected MAC address */ + uint32_t rfw_in_mac_ndet_drop; + /* [0x8c] Rx Forwarding, packets with drop indication from th ... */ + uint32_t rfw_in_ctrl_drop; + /* [0x90] Rx Forwarding, packets with L3_protocol_index drop ... */ + uint32_t rfw_in_prot_i_drop; + /* [0x94] EEE, number of times the system went into EEE state ... */ + uint32_t eee_in; + uint32_t rsrvd[90]; +}; +struct al_ec_stat_udma { + /* [0x0] Rx forwarding output packet counter */ + uint32_t rfw_out_rx_pkt; + /* [0x4] Rx forwarding output drop packet counter */ + uint32_t rfw_out_drop; + /* [0x8] Multi-stream write, number of Rx packets */ + uint32_t msw_in_rx_pkt; + /* [0xc] Multi-stream write, number of dropped packets at SO ... */ + uint32_t msw_drop_q_full; + /* [0x10] Multi-stream write, number of dropped packets at SO ... */ + uint32_t msw_drop_sop; + /* [0x14] Multi-stream write, number of dropped packets at EO ... */ + uint32_t msw_drop_eop; + /* [0x18] Multi-stream write, number of packets written to th ... */ + uint32_t msw_wr_eop; + /* [0x1c] Multi-stream write, number of packets read from the ... */ + uint32_t msw_out_rx_pkt; + /* [0x20] Number of transmitted packets without TSO enabled */ + uint32_t tso_no_tso_pkt; + /* [0x24] Number of transmitted packets with TSO enabled */ + uint32_t tso_tso_pkt; + /* [0x28] Number of TSO segments that were generated */ + uint32_t tso_seg_pkt; + /* [0x2c] Number of TSO segments that required padding */ + uint32_t tso_pad_pkt; + /* [0x30] Tx Packet modification, MAC SA spoof error */ + uint32_t tpm_tx_spoof; + /* [0x34] Tx MAC interface, input packet counter */ + uint32_t tmi_in_tx_pkt; + /* [0x38] Tx MAC interface, number of packets forwarded to th ... */ + uint32_t tmi_out_to_mac; + /* [0x3c] Tx MAC interface, number of packets forwarded to th ... */ + uint32_t tmi_out_to_rx; + /* [0x40] Tx MAC interface, number of transmitted bytes */ + uint32_t tx_q0_bytes; + /* [0x44] Tx MAC interface, number of transmitted bytes */ + uint32_t tx_q1_bytes; + /* [0x48] Tx MAC interface, number of transmitted bytes */ + uint32_t tx_q2_bytes; + /* [0x4c] Tx MAC interface, number of transmitted bytes */ + uint32_t tx_q3_bytes; + /* [0x50] Tx MAC interface, number of transmitted packets */ + uint32_t tx_q0_pkts; + /* [0x54] Tx MAC interface, number of transmitted packets */ + uint32_t tx_q1_pkts; + /* [0x58] Tx MAC interface, number of transmitted packets */ + uint32_t tx_q2_pkts; + /* [0x5c] Tx MAC interface, number of transmitted packets */ + uint32_t tx_q3_pkts; + uint32_t rsrvd[40]; +}; +struct al_ec_msp { + /* [0x0] Ethernet parsing engine configuration 1 */ + uint32_t p_parse_cfg; + /* [0x4] Protocol index action table address */ + uint32_t p_act_table_addr; + /* [0x8] Protocol index action table data */ + uint32_t p_act_table_data_1; + /* [0xc] Protocol index action table data */ + uint32_t p_act_table_data_2; + /* [0x10] Protocol index action table data */ + uint32_t p_act_table_data_3; + /* [0x14] Protocol index action table data */ + uint32_t p_act_table_data_4; + /* [0x18] Protocol index action table data */ + uint32_t p_act_table_data_5; + /* [0x1c] Protocol index action table data */ + uint32_t p_act_table_data_6; + /* [0x20] Input result vector, default values for parser inpu ... */ + uint32_t p_res_def; + /* [0x24] Result input vector selection */ + uint32_t p_res_in; + uint32_t rsrvd[6]; +}; +struct al_ec_msp_p { + /* [0x0] Header length, support for header length table for ... */ + uint32_t h_hdr_len; +}; +struct al_ec_msp_c { + /* [0x0] Data for comparison */ + uint32_t p_comp_data; + /* [0x4] Mask for comparison */ + uint32_t p_comp_mask; + /* [0x8] Compare control */ + uint32_t p_comp_ctrl; + uint32_t rsrvd[4]; +}; +struct al_ec_wol { + /* [0x0] WoL enable configuration,Packet forwarding and inte ... */ + uint32_t wol_en; + /* [0x4] Password for magic_password packet detection - bits ... */ + uint32_t magic_pswd_l; + /* [0x8] Password for magic+password packet detection - 47: ... */ + uint32_t magic_pswd_h; + /* [0xc] Configured L3 Destination IP address for WoL IPv6 p ... */ + uint32_t ipv6_dip_word0; + /* [0x10] Configured L3 Destination IP address for WoL IPv6 p ... */ + uint32_t ipv6_dip_word1; + /* [0x14] Configured L3 Destination IP address for WoL IPv6 p ... */ + uint32_t ipv6_dip_word2; + /* [0x18] Configured L3 Destination IP address for WoL IPv6 p ... */ + uint32_t ipv6_dip_word3; + /* [0x1c] Configured L3 Destination IP address for WoL IPv4 p ... */ + uint32_t ipv4_dip; + /* [0x20] Configured EtherType for WoL EtherType_da/EtherType ... */ + uint32_t ethertype; + uint32_t rsrvd[7]; +}; +struct al_ec_pth { + /* [0x0] System time counter (Time of Day) */ + uint32_t system_time_seconds; + /* [0x4] System time subseconds in a second (MSBs) */ + uint32_t system_time_subseconds_msb; + /* [0x8] System time subseconds in a second (LSBs) */ + uint32_t system_time_subseconds_lsb; + /* [0xc] Clock period in femtoseconds (MSB) */ + uint32_t clock_period_msb; + /* [0x10] Clock period in femtoseconds (LSB) */ + uint32_t clock_period_lsb; + /* [0x14] Control register for internal updates to the system ... */ + uint32_t int_update_ctrl; + /* [0x18] Value to update system_time_seconds with */ + uint32_t int_update_seconds; + /* [0x1c] Value to update system_time_subseconds_msb with */ + uint32_t int_update_subseconds_msb; + /* [0x20] Value to update system_time_subseconds_lsb with */ + uint32_t int_update_subseconds_lsb; + /* [0x24] Control register for external updates to the system ... */ + uint32_t ext_update_ctrl; + /* [0x28] Value to update system_time_seconds with */ + uint32_t ext_update_seconds; + /* [0x2c] Value to update system_time_subseconds_msb with */ + uint32_t ext_update_subseconds_msb; + /* [0x30] Value to update system_time_subseconds_lsb with */ + uint32_t ext_update_subseconds_lsb; + /* [0x34] This value represents the APB transaction delay fro ... */ + uint32_t read_compensation_subseconds_msb; + /* [0x38] This value represents the APB transaction delay fro ... */ + uint32_t read_compensation_subseconds_lsb; + /* [0x3c] This value is used for two purposes:1 */ + uint32_t int_write_compensation_subseconds_msb; + /* [0x40] This value is used for two purposes:1 */ + uint32_t int_write_compensation_subseconds_lsb; + /* [0x44] This value represents the number of cycles it for a ... */ + uint32_t ext_write_compensation_subseconds_msb; + /* [0x48] This value represents the number of cycles it for a ... */ + uint32_t ext_write_compensation_subseconds_lsb; + /* [0x4c] Value to be added to system_time before transferrin ... */ + uint32_t sync_compensation_subseconds_msb; + /* [0x50] Value to be added to system_time before transferrin ... */ + uint32_t sync_compensation_subseconds_lsb; + uint32_t rsrvd[11]; +}; +struct al_ec_pth_egress { + /* [0x0] Control register for egress trigger #k */ + uint32_t trigger_ctrl; + /* [0x4] threshold for next egress trigger (#k) - secondsWri ... */ + uint32_t trigger_seconds; + /* [0x8] Threshold for next egress trigger (#k) - subseconds ... */ + uint32_t trigger_subseconds_msb; + /* [0xc] threshold for next egress trigger (#k) - subseconds ... */ + uint32_t trigger_subseconds_lsb; + /* [0x10] External output pulse width (subseconds_msb)(Atomic ... */ + uint32_t pulse_width_subseconds_msb; + /* [0x14] External output pulse width (subseconds_lsb)(Atomic ... */ + uint32_t pulse_width_subseconds_lsb; + uint32_t rsrvd[2]; +}; +struct al_ec_pth_db { + /* [0x0] timestamp[k], in resolution of 2^18 femtosec =~ 0 */ + uint32_t ts; + /* [0x4] Timestamp entry is valid */ + uint32_t qual; + uint32_t rsrvd[4]; +}; +struct al_ec_gen_v3 { + /* [0x0] Bypass enable */ + uint32_t bypass; + /* [0x4] Rx Completion descriptor */ + uint32_t rx_comp_desc; + /* [0x8] general configuration */ + uint32_t conf; + uint32_t rsrvd[13]; +}; +struct al_ec_tfw_v3 { + /* [0x0] Generic protocol detect Cam compare table address */ + uint32_t tx_gpd_cam_addr; + /* [0x4] Tx Generic protocol detect Cam compare data_1 (low) ... */ + uint32_t tx_gpd_cam_data_1; + /* [0x8] Tx Generic protocol detect Cam compare data_2 (high ... */ + uint32_t tx_gpd_cam_data_2; + /* [0xc] Tx Generic protocol detect Cam compare mask_1 (low) ... */ + uint32_t tx_gpd_cam_mask_1; + /* [0x10] Tx Generic protocol detect Cam compare mask_1 (high ... */ + uint32_t tx_gpd_cam_mask_2; + /* [0x14] Tx Generic protocol detect Cam compare control */ + uint32_t tx_gpd_cam_ctrl; + /* [0x18] Tx Generic crc parameters legacy */ + uint32_t tx_gcp_legacy; + /* [0x1c] Tx Generic crc prameters table address */ + uint32_t tx_gcp_table_addr; + /* [0x20] Tx Generic crc prameters table general */ + uint32_t tx_gcp_table_gen; + /* [0x24] Tx Generic crc parametrs tabel mask word 1 */ + uint32_t tx_gcp_table_mask_1; + /* [0x28] Tx Generic crc parametrs tabel mask word 2 */ + uint32_t tx_gcp_table_mask_2; + /* [0x2c] Tx Generic crc parametrs tabel mask word 3 */ + uint32_t tx_gcp_table_mask_3; + /* [0x30] Tx Generic crc parametrs tabel mask word 4 */ + uint32_t tx_gcp_table_mask_4; + /* [0x34] Tx Generic crc parametrs tabel mask word 5 */ + uint32_t tx_gcp_table_mask_5; + /* [0x38] Tx Generic crc parametrs tabel mask word 6 */ + uint32_t tx_gcp_table_mask_6; + /* [0x3c] Tx Generic crc parametrs tabel crc init */ + uint32_t tx_gcp_table_crc_init; + /* [0x40] Tx Generic crc parametrs tabel result configuration ... */ + uint32_t tx_gcp_table_res; + /* [0x44] Tx Generic crc parameters table alu opcode */ + uint32_t tx_gcp_table_alu_opcode; + /* [0x48] Tx Generic crc parameters table alu opsel */ + uint32_t tx_gcp_table_alu_opsel; + /* [0x4c] Tx Generic crc parameters table alu constant value */ + uint32_t tx_gcp_table_alu_val; + /* [0x50] Tx CRC/Checksum replace */ + uint32_t crc_csum_replace; + /* [0x54] CRC/Checksum replace table address */ + uint32_t crc_csum_replace_table_addr; + /* [0x58] CRC/Checksum replace table */ + uint32_t crc_csum_replace_table; + uint32_t rsrvd[9]; +}; + +struct al_ec_rfw_v3 { + /* [0x0] Rx Generic protocol detect Cam compare table addres ... */ + uint32_t rx_gpd_cam_addr; + /* [0x4] Rx Generic protocol detect Cam compare data_1 (low) ... */ + uint32_t rx_gpd_cam_data_1; + /* [0x8] Rx Generic protocol detect Cam compare data_2 (high ... */ + uint32_t rx_gpd_cam_data_2; + /* [0xc] Rx Generic protocol detect Cam compare mask_1 (low) ... */ + uint32_t rx_gpd_cam_mask_1; + /* [0x10] Rx Generic protocol detect Cam compare mask_1 (high ... */ + uint32_t rx_gpd_cam_mask_2; + /* [0x14] Rx Generic protocol detect Cam compare control */ + uint32_t rx_gpd_cam_ctrl; + /* [0x18] Generic protocol detect Parser result vector pointe ... */ + uint32_t gpd_p1; + /* [0x1c] Generic protocol detect Parser result vector pointe ... */ + uint32_t gpd_p2; + /* [0x20] Generic protocol detect Parser result vector pointe ... */ + uint32_t gpd_p3; + /* [0x24] Generic protocol detect Parser result vector pointe ... */ + uint32_t gpd_p4; + /* [0x28] Generic protocol detect Parser result vector pointe ... */ + uint32_t gpd_p5; + /* [0x2c] Generic protocol detect Parser result vector pointe ... */ + uint32_t gpd_p6; + /* [0x30] Generic protocol detect Parser result vector pointe ... */ + uint32_t gpd_p7; + /* [0x34] Generic protocol detect Parser result vector pointe ... */ + uint32_t gpd_p8; + /* [0x38] Rx Generic crc parameters legacy */ + uint32_t rx_gcp_legacy; + /* [0x3c] Rx Generic crc prameters table address */ + uint32_t rx_gcp_table_addr; + /* [0x40] Rx Generic crc prameters table general */ + uint32_t rx_gcp_table_gen; + /* [0x44] Rx Generic crc parametrs tabel mask word 1 */ + uint32_t rx_gcp_table_mask_1; + /* [0x48] Rx Generic crc parametrs tabel mask word 2 */ + uint32_t rx_gcp_table_mask_2; + /* [0x4c] Rx Generic crc parametrs tabel mask word 3 */ + uint32_t rx_gcp_table_mask_3; + /* [0x50] Rx Generic crc parametrs tabel mask word 4 */ + uint32_t rx_gcp_table_mask_4; + /* [0x54] Rx Generic crc parametrs tabel mask word 5 */ + uint32_t rx_gcp_table_mask_5; + /* [0x58] Rx Generic crc parametrs tabel mask word 6 */ + uint32_t rx_gcp_table_mask_6; + /* [0x5c] Rx Generic crc parametrs tabel crc init */ + uint32_t rx_gcp_table_crc_init; + /* [0x60] Rx Generic crc parametrs tabel result configuration ... */ + uint32_t rx_gcp_table_res; + /* [0x64] Rx Generic crc parameters table alu opcode */ + uint32_t rx_gcp_table_alu_opcode; + /* [0x68] Rx Generic crc parameters table alu opsel */ + uint32_t rx_gcp_table_alu_opsel; + /* [0x6c] Rx Generic crc parameters table alu constant value ... */ + uint32_t rx_gcp_table_alu_val; + /* [0x70] Generic crc engin parameters alu Parser result vect ... */ + uint32_t rx_gcp_alu_p1; + /* [0x74] Generic crc engine parameters alu Parser result vec ... */ + uint32_t rx_gcp_alu_p2; + /* [0x78] Header split control table address */ + uint32_t hs_ctrl_table_addr; + /* [0x7c] Header split control table */ + uint32_t hs_ctrl_table; + /* [0x80] Header split control alu opcode */ + uint32_t hs_ctrl_table_alu_opcode; + /* [0x84] Header split control alu opsel */ + uint32_t hs_ctrl_table_alu_opsel; + /* [0x88] Header split control alu constant value */ + uint32_t hs_ctrl_table_alu_val; + /* [0x8c] Header split control configuration */ + uint32_t hs_ctrl_cfg; + /* [0x90] Header split control alu Parser result vector point ... */ + uint32_t hs_ctrl_alu_p1; + /* [0x94] Header split control alu Parser result vector point ... */ + uint32_t hs_ctrl_alu_p2; + uint32_t rsrvd[26]; +}; +struct al_ec_crypto { + /* [0x0] Tx inline crypto configuration */ + uint32_t tx_config; + /* [0x4] Rx inline crypto configuration */ + uint32_t rx_config; + /* [0x8] reserved FFU */ + uint32_t tx_override; + /* [0xc] reserved FFU */ + uint32_t rx_override; + /* [0x10] inline XTS alpha [31:0] */ + uint32_t xts_alpha_1; + /* [0x14] inline XTS alpha [63:32] */ + uint32_t xts_alpha_2; + /* [0x18] inline XTS alpha [95:64] */ + uint32_t xts_alpha_3; + /* [0x1c] inline XTS alpha [127:96] */ + uint32_t xts_alpha_4; + /* [0x20] inline XTS sector ID increment [31:0] */ + uint32_t xts_sector_id_1; + /* [0x24] inline XTS sector ID increment [63:32] */ + uint32_t xts_sector_id_2; + /* [0x28] inline XTS sector ID increment [95:64] */ + uint32_t xts_sector_id_3; + /* [0x2c] inline XTS sector ID increment [127:96] */ + uint32_t xts_sector_id_4; + /* [0x30] IV formation configuration */ + uint32_t tx_enc_iv_construction; + /* [0x34] IV formation configuration */ + uint32_t rx_enc_iv_construction; + /* [0x38] IV formation configuration */ + uint32_t rx_enc_iv_map; + /* + [0x3c] effectively shorten shift-registers used for + eop-pkt-trim, in order to improve performance. + Each value must be built of consecutive 1's (bypassed regs), + and then consecutive 0's (non-bypassed regs) + */ + uint32_t tx_pkt_trim_len; + /* + [0x40] effectively shorten shift-registers used for + eop-pkt-trim, in order to improve performance. + Each value must be built of consecutive 1's (bypassed regs), + and then consecutive 0's (non-bypassed regs) + */ + uint32_t rx_pkt_trim_len; + /* [0x44] reserved FFU */ + uint32_t tx_reserved; + /* [0x48] reserved FFU */ + uint32_t rx_reserved; + uint32_t rsrvd[13]; +}; +struct al_ec_crypto_perf_cntr { + /* [0x0] */ + uint32_t total_tx_pkts; + /* [0x4] */ + uint32_t total_rx_pkts; + /* [0x8] */ + uint32_t total_tx_secured_pkts; + /* [0xc] */ + uint32_t total_rx_secured_pkts; + /* [0x10] */ + uint32_t total_tx_secured_pkts_cipher_mode; + /* [0x14] */ + uint32_t total_tx_secured_pkts_cipher_mode_cmpr; + /* [0x18] */ + uint32_t total_rx_secured_pkts_cipher_mode; + /* [0x1c] */ + uint32_t total_rx_secured_pkts_cipher_mode_cmpr; + /* [0x20] */ + uint32_t total_tx_secured_bytes_low; + /* [0x24] */ + uint32_t total_tx_secured_bytes_high; + /* [0x28] */ + uint32_t total_rx_secured_bytes_low; + /* [0x2c] */ + uint32_t total_rx_secured_bytes_high; + /* [0x30] */ + uint32_t total_tx_sign_calcs; + /* [0x34] */ + uint32_t total_rx_sign_calcs; + /* [0x38] */ + uint32_t total_tx_sign_errs; + /* [0x3c] */ + uint32_t total_rx_sign_errs; +}; +struct al_ec_crypto_tx_tid { + /* [0x0] tid_default_entry */ + uint32_t def_val; +}; + +struct al_ec_regs { + uint32_t rsrvd_0[32]; + struct al_ec_gen gen; /* [0x80] */ + struct al_ec_mac mac; /* [0xc0] */ + struct al_ec_rxf rxf; /* [0x100] */ + struct al_ec_epe epe[2]; /* [0x180] */ + struct al_ec_epe_res epe_res; /* [0x200] */ + struct al_ec_epe_h epe_h[32]; /* [0x280] */ + struct al_ec_epe_p epe_p[32]; /* [0x300] */ + struct al_ec_epe_a epe_a[32]; /* [0x680] */ + struct al_ec_rfw rfw; /* [0x700] */ + struct al_ec_rfw_udma rfw_udma[4]; /* [0x7f0] */ + struct al_ec_rfw_hash rfw_hash[10]; /* [0x800] */ + struct al_ec_rfw_priority rfw_priority[8]; /* [0x828] */ + struct al_ec_rfw_default rfw_default[8]; /* [0x848] */ + struct al_ec_fwd_mac fwd_mac[32]; /* [0x868] */ + struct al_ec_msw msw; /* [0xae8] */ + struct al_ec_tso tso; /* [0xb00] */ + struct al_ec_tso_sel tso_sel[8]; /* [0xb60] */ + struct al_ec_tpe tpe; /* [0xb80] */ + struct al_ec_tpm_udma tpm_udma[4]; /* [0xbc0] */ + struct al_ec_tpm_sel tpm_sel[4]; /* [0xbf0] */ + struct al_ec_tfw tfw; /* [0xc00] */ + struct al_ec_tfw_udma tfw_udma[4]; /* [0xc60] */ + struct al_ec_tmi tmi; /* [0xcc0] */ + struct al_ec_efc efc; /* [0xcd0] */ + struct al_ec_fc_udma fc_udma[4]; /* [0xd00] */ + struct al_ec_tpg_rpa_res tpg_rpa_res; /* [0xf00] */ + struct al_ec_eee eee; /* [0x1000] */ + struct al_ec_stat stat; /* [0x1100] */ + struct al_ec_stat_udma stat_udma[4]; /* [0x1300] */ + struct al_ec_msp msp; /* [0x1700] */ + struct al_ec_msp_p msp_p[32]; /* [0x1740] */ + struct al_ec_msp_c msp_c[32]; /* [0x17c0] */ + uint32_t rsrvd_1[16]; + struct al_ec_wol wol; /* [0x1b80] */ + uint32_t rsrvd_2[80]; + struct al_ec_pth pth; /* [0x1d00] */ + struct al_ec_pth_egress pth_egress[8]; /* [0x1d80] */ + struct al_ec_pth_db pth_db[16]; /* [0x1e80] */ + uint32_t rsrvd_3[416]; + struct al_ec_gen_v3 gen_v3; /* [0x2680] */ + struct al_ec_tfw_v3 tfw_v3; /* [0x26c0] */ + struct al_ec_rfw_v3 rfw_v3; /* [0x2740] */ + struct al_ec_crypto crypto; /* [0x2840] */ + struct al_ec_crypto_perf_cntr crypto_perf_cntr[2]; /* [0x28c0] */ + uint32_t rsrvd_4[48]; + struct al_ec_crypto_tx_tid crypto_tx_tid[8]; /* [0x2a00] */ +}; + + +/* +* Registers Fields +*/ + + +/**** version register ****/ +/* Revision number (Minor) */ +#define EC_GEN_VERSION_RELEASE_NUM_MINOR_MASK 0x000000FF +#define EC_GEN_VERSION_RELEASE_NUM_MINOR_SHIFT 0 +/* Revision number (Major) */ +#define EC_GEN_VERSION_RELEASE_NUM_MAJOR_MASK 0x0000FF00 +#define EC_GEN_VERSION_RELEASE_NUM_MAJOR_SHIFT 8 +/* Day of release */ +#define EC_GEN_VERSION_DATE_DAY_MASK 0x001F0000 +#define EC_GEN_VERSION_DATE_DAY_SHIFT 16 +/* Month of release */ +#define EC_GEN_VERSION_DATA_MONTH_MASK 0x01E00000 +#define EC_GEN_VERSION_DATA_MONTH_SHIFT 21 +/* Year of release (starting from 2000) */ +#define EC_GEN_VERSION_DATE_YEAR_MASK 0x3E000000 +#define EC_GEN_VERSION_DATE_YEAR_SHIFT 25 +/* Reserved */ +#define EC_GEN_VERSION_RESERVED_MASK 0xC0000000 +#define EC_GEN_VERSION_RESERVED_SHIFT 30 + +/**** en register ****/ +/* Enable Frequency adjust FIFO input controller operation. */ +#define EC_GEN_EN_FAF_IN (1 << 0) +/* Enable Frequency adjust FIFO output controller operation. */ +#define EC_GEN_EN_FAF_OUT (1 << 1) +/* Enable Rx FIFO input controller 1 operation. */ +#define EC_GEN_EN_RXF_IN (1 << 2) +/* Enable Rx FIFO output controller operation. */ +#define EC_GEN_EN_RXF_OUT (1 << 3) +/* Enable Rx forwarding input controller operation. */ +#define EC_GEN_EN_RFW_IN (1 << 4) +/* Enable Rx forwarding output controller operation. */ +#define EC_GEN_EN_RFW_OUT (1 << 5) +/* Enable Rx multi-stream write controller operation. */ +#define EC_GEN_EN_MSW_IN (1 << 6) +/* Enable Rx first parsing engine output operation. */ +#define EC_GEN_EN_RPE_1_OUT (1 << 7) +/* Enable Rx first parsing engine input operation. */ +#define EC_GEN_EN_RPE_1_IN (1 << 8) +/* Enable Rx second parsing engine output operation. */ +#define EC_GEN_EN_RPE_2_OUT (1 << 9) +/* Enable Rx second parsing engine input operation. */ +#define EC_GEN_EN_RPE_2_IN (1 << 10) +/* Enable Rx MACsec parsing engine output operation. */ +#define EC_GEN_EN_RPE_3_OUT (1 << 11) +/* Enable Rx MACsec parsing engine input operation. */ +#define EC_GEN_EN_RPE_3_IN (1 << 12) +/* Enable Loopback FIFO input controller 1 operation. */ +#define EC_GEN_EN_LBF_IN (1 << 13) +/* Enable Rx packet analyzer operation. */ +#define EC_GEN_EN_RPA (1 << 14) + +#define EC_GEN_EN_RESERVED_15 (1 << 15) +/* Enable Tx stream interface operation. */ +#define EC_GEN_EN_TSO (1 << 16) +/* Enable Tx parser input controller operation. */ +#define EC_GEN_EN_TPE_IN (1 << 17) +/* Enable Tx parser output controller operation. */ +#define EC_GEN_EN_TPE_OUT (1 << 18) +/* Enable Tx packet modification operation. */ +#define EC_GEN_EN_TPM (1 << 19) +/* Enable Tx forwarding input controller operation. */ +#define EC_GEN_EN_TFW_IN (1 << 20) +/* Enable Tx forwarding output controller operation. */ +#define EC_GEN_EN_TFW_OUT (1 << 21) +/* Enable Tx MAC interface controller operation. */ +#define EC_GEN_EN_TMI (1 << 22) +/* Enable Tx packet generator operation. */ +#define EC_GEN_EN_TPG (1 << 23) + +#define EC_GEN_EN_RESERVED_31_MASK 0xFF000000 +#define EC_GEN_EN_RESERVED_31_SHIFT 24 + +/**** fifo_en register ****/ +/* Enable Frequency adjust FIFO operation (input). */ +#define EC_GEN_FIFO_EN_FAF_IN (1 << 0) +/* Enable Frequency adjust FIFO operation (output). */ +#define EC_GEN_FIFO_EN_FAF_OUT (1 << 1) +/* Enable Rx FIFO operation. */ +#define EC_GEN_FIFO_EN_RX_FIFO (1 << 2) +/* Enable Rx forwarding FIFO operation. */ +#define EC_GEN_FIFO_EN_RFW_FIFO (1 << 3) +/* Enable Rx multi-stream write FIFO operation */ +#define EC_GEN_FIFO_EN_MSW_FIFO (1 << 4) +/* Enable Rx first parser FIFO operation. */ +#define EC_GEN_FIFO_EN_RPE_1_FIFO (1 << 5) +/* Enable Rx second parser FIFO operation. */ +#define EC_GEN_FIFO_EN_RPE_2_FIFO (1 << 6) +/* Enable Rx MACsec parser FIFO operation. */ +#define EC_GEN_FIFO_EN_RPE_3_FIFO (1 << 7) +/* Enable Loopback FIFO operation. */ +#define EC_GEN_FIFO_EN_LB_FIFO (1 << 8) + +#define EC_GEN_FIFO_EN_RESERVED_15_9_MASK 0x0000FE00 +#define EC_GEN_FIFO_EN_RESERVED_15_9_SHIFT 9 +/* Enable Tx parser FIFO operation. */ +#define EC_GEN_FIFO_EN_TPE_FIFO (1 << 16) +/* Enable Tx forwarding FIFO operation. */ +#define EC_GEN_FIFO_EN_TFW_FIFO (1 << 17) + +#define EC_GEN_FIFO_EN_RESERVED_31_18_MASK 0xFFFC0000 +#define EC_GEN_FIFO_EN_RESERVED_31_18_SHIFT 18 + +/**** l2 register ****/ +/* Size of a 802.3 Ethernet header (DA+SA) */ +#define EC_GEN_L2_SIZE_802_3_MASK 0x0000003F +#define EC_GEN_L2_SIZE_802_3_SHIFT 0 +/* Size of a 802.3 + MACsec 8 byte header */ +#define EC_GEN_L2_SIZE_802_3_MS_8_MASK 0x00003F00 +#define EC_GEN_L2_SIZE_802_3_MS_8_SHIFT 8 +/* Offset of the L2 header from the beginning of the packet. */ +#define EC_GEN_L2_OFFSET_MASK 0x7F000000 +#define EC_GEN_L2_OFFSET_SHIFT 24 + +/**** cfg_i register ****/ +/* IPv4 protocol index */ +#define EC_GEN_CFG_I_IPV4_INDEX_MASK 0x0000001F +#define EC_GEN_CFG_I_IPV4_INDEX_SHIFT 0 +/* IPv6 protocol index */ +#define EC_GEN_CFG_I_IPV6_INDEX_MASK 0x000003E0 +#define EC_GEN_CFG_I_IPV6_INDEX_SHIFT 5 +/* TCP protocol index */ +#define EC_GEN_CFG_I_TCP_INDEX_MASK 0x00007C00 +#define EC_GEN_CFG_I_TCP_INDEX_SHIFT 10 +/* UDP protocol index */ +#define EC_GEN_CFG_I_UDP_INDEX_MASK 0x000F8000 +#define EC_GEN_CFG_I_UDP_INDEX_SHIFT 15 +/* MACsec with 8 bytes SecTAG */ +#define EC_GEN_CFG_I_MACSEC_8_INDEX_MASK 0x01F00000 +#define EC_GEN_CFG_I_MACSEC_8_INDEX_SHIFT 20 +/* MACsec with 16 bytes SecTAG */ +#define EC_GEN_CFG_I_MACSEC_16_INDEX_MASK 0x3E000000 +#define EC_GEN_CFG_I_MACSEC_16_INDEX_SHIFT 25 + +/**** cfg_i_ext register ****/ +/* FcoE protocol index */ +#define EC_GEN_CFG_I_EXT_FCOE_INDEX_MASK 0x0000001F +#define EC_GEN_CFG_I_EXT_FCOE_INDEX_SHIFT 0 +/* RoCE protocol index */ +#define EC_GEN_CFG_I_EXT_ROCE_INDEX_L3_1_MASK 0x000003E0 +#define EC_GEN_CFG_I_EXT_ROCE_INDEX_L3_1_SHIFT 5 +/* RoCE protocol index */ +#define EC_GEN_CFG_I_EXT_ROCE_INDEX_L3_2_MASK 0x00007C00 +#define EC_GEN_CFG_I_EXT_ROCE_INDEX_L3_2_SHIFT 10 +/* RoCE protocol index */ +#define EC_GEN_CFG_I_EXT_ROCE_INDEX_L4_MASK 0x000F8000 +#define EC_GEN_CFG_I_EXT_ROCE_INDEX_L4_SHIFT 15 + +/**** en_ext register ****/ +/* Enable Usage of Ethernet port memories for testing */ +#define EC_GEN_EN_EXT_MEM_FOR_TEST_MASK 0x0000000F +#define EC_GEN_EN_EXT_MEM_FOR_TEST_SHIFT 0 +#define EC_GEN_EN_EXT_MEM_FOR_TEST_VAL_EN \ + (0xa << EC_GEN_EN_EXT_MEM_FOR_TEST_SHIFT) +#define EC_GEN_EN_EXT_MEM_FOR_TEST_VAL_DIS \ + (0x0 << EC_GEN_EN_EXT_MEM_FOR_TEST_SHIFT) +/* Enable MAC loop back (Rx --> Tx, after MAC layer) for 802 */ +#define EC_GEN_EN_EXT_MAC_LB (1 << 4) +/* CRC forward value for the MAC Tx when working in loopback mod ... */ +#define EC_GEN_EN_EXT_MAC_LB_CRC_FWD (1 << 5) +/* Ready signal configuration when in loopback mode:00 - Ready f ... */ +#define EC_GEN_EN_EXT_MAC_LB_READY_CFG_MASK 0x000000C0 +#define EC_GEN_EN_EXT_MAC_LB_READY_CFG_SHIFT 6 +/* Bypass the PTH completion update. */ +#define EC_GEN_EN_EXT_PTH_COMPLETION_BYPASS (1 << 16) +/* Selection between the 1G and 10G MAC: +0 - 1G +1 - 10G */ +#define EC_GEN_EN_EXT_PTH_1_10_SEL (1 << 17) +/* avoid timestamping every pkt in 1G */ +#define EC_GEN_EN_EXT_PTH_CFG_1G_TIMESTAMP_OPT (1 << 18) +/* Selection between descriptor caching options (WORD selection) ... */ +#define EC_GEN_EN_EXT_CACHE_WORD_SPLIT (1 << 20) + +/**** gen register ****/ +/* Enable swap of input byte order */ +#define EC_MAC_GEN_SWAP_IN_BYTE (1 << 0) + +/**** min_pkt register ****/ +/* Minimum packet size */ +#define EC_MAC_MIN_PKT_SIZE_MASK 0x000FFFFF +#define EC_MAC_MIN_PKT_SIZE_SHIFT 0 + +/**** max_pkt register ****/ +/* Maximum packet size */ +#define EC_MAC_MAX_PKT_SIZE_MASK 0x000FFFFF +#define EC_MAC_MAX_PKT_SIZE_SHIFT 0 + +/**** cfg_1 register ****/ +/* Drop packet at the ingress0 - Packets are not dropped at the ... */ +#define EC_RXF_CFG_1_DROP_AT_INGRESS (1 << 0) +/* Accept packet criteria at start of packet indication */ +#define EC_RXF_CFG_1_SOP_ACCEPT (1 << 1) +/* Select the arbiter between Rx packets and Tx packets (packets ... */ +#define EC_RXF_CFG_1_ARB_SEL (1 << 2) +/* Arbiter priority when strict priority is selected in arb_sel0 ... */ +#define EC_RXF_CFG_1_ARB_P (1 << 3) +/* Force loopback operation */ +#define EC_RXF_CFG_1_FORCE_LB (1 << 4) +/* Forwarding selection between Rx path and/or packet analyzer */ +#define EC_RXF_CFG_1_FWD_SEL_MASK 0x00000300 +#define EC_RXF_CFG_1_FWD_SEL_SHIFT 8 + +/**** cfg_2 register ****/ +/* FIFO USED threshold for accepting new packets, low threshold ... */ +#define EC_RXF_CFG_2_FIFO_USED_TH_L_MASK 0x0000FFFF +#define EC_RXF_CFG_2_FIFO_USED_TH_L_SHIFT 0 +/* FIFO USED threshold for accepting new packets, high threshold ... */ +#define EC_RXF_CFG_2_FIFO_USED_TH_H_MASK 0xFFFF0000 +#define EC_RXF_CFG_2_FIFO_USED_TH_H_SHIFT 16 + +/**** rd_fifo register ****/ +/* Minimum number of entries in the data FIFO to start reading p ... */ +#define EC_RXF_RD_FIFO_TH_DATA_MASK 0x0000FFFF +#define EC_RXF_RD_FIFO_TH_DATA_SHIFT 0 +/* Enable cut through operation */ +#define EC_RXF_RD_FIFO_EN_CUT_TH (1 << 16) + +/**** wr_fifo register ****/ + +#define EC_RXF_WR_FIFO_TH_DATA_MASK 0x0000FFFF +#define EC_RXF_WR_FIFO_TH_DATA_SHIFT 0 + +#define EC_RXF_WR_FIFO_TH_INFO_MASK 0xFFFF0000 +#define EC_RXF_WR_FIFO_TH_INFO_SHIFT 16 + +/**** lb_fifo register ****/ + +#define EC_RXF_LB_FIFO_TH_DATA_MASK 0x0000FFFF +#define EC_RXF_LB_FIFO_TH_DATA_SHIFT 0 + +#define EC_RXF_LB_FIFO_TH_INFO_MASK 0xFFFF0000 +#define EC_RXF_LB_FIFO_TH_INFO_SHIFT 16 + +/**** cfg_lb register ****/ +/* FIFO USED threshold for accepting new packets */ +#define EC_RXF_CFG_LB_FIFO_USED_TH_INT_MASK 0x0000FFFF +#define EC_RXF_CFG_LB_FIFO_USED_TH_INT_SHIFT 0 +/* FIFO USED threshold for generating ready for the Tx path */ +#define EC_RXF_CFG_LB_FIFO_USED_TH_EXT_MASK 0xFFFF0000 +#define EC_RXF_CFG_LB_FIFO_USED_TH_EXT_SHIFT 16 + +/**** out_drop register ****/ + +#define EC_RXF_OUT_DROP_MAC_ERR (1 << 0) + +#define EC_RXF_OUT_DROP_MAC_COL (1 << 1) + +#define EC_RXF_OUT_DROP_MAC_DEC (1 << 2) + +#define EC_RXF_OUT_DROP_MAC_LEN (1 << 3) + +#define EC_RXF_OUT_DROP_MAC_PHY (1 << 4) + +#define EC_RXF_OUT_DROP_MAC_FIFO (1 << 5) + +#define EC_RXF_OUT_DROP_MAC_FCS (1 << 6) + +#define EC_RXF_OUT_DROP_MAC_ETYPE (1 << 7) + +#define EC_RXF_OUT_DROP_EC_LEN (1 << 8) + +#define EC_RXF_OUT_DROP_EC_FIFO (1 << 9) + +/**** parse_cfg register ****/ +/* MAX number of beats for packet parsing */ +#define EC_EPE_PARSE_CFG_MAX_BEATS_MASK 0x000000FF +#define EC_EPE_PARSE_CFG_MAX_BEATS_SHIFT 0 +/* MAX number of parsing iterations for packet parsing */ +#define EC_EPE_PARSE_CFG_MAX_ITER_MASK 0x0000FF00 +#define EC_EPE_PARSE_CFG_MAX_ITER_SHIFT 8 + +/**** act_table_addr register ****/ +/* Address for accessing the table */ +#define EC_EPE_ACT_TABLE_ADDR_VAL_MASK 0x0000001F +#define EC_EPE_ACT_TABLE_ADDR_VAL_SHIFT 0 + +/**** act_table_data_1 register ****/ +/* Table data[5:0] - Offset to next protocol [bytes][6] - Next p ... */ +#define EC_EPE_ACT_TABLE_DATA_1_VAL_MASK 0x03FFFFFF +#define EC_EPE_ACT_TABLE_DATA_1_VAL_SHIFT 0 + +/**** act_table_data_2 register ****/ +/* Table Data [8:0] - Offset to data in the packet [bits][17:9] ... */ +#define EC_EPE_ACT_TABLE_DATA_2_VAL_MASK 0x1FFFFFFF +#define EC_EPE_ACT_TABLE_DATA_2_VAL_SHIFT 0 + +/**** act_table_data_3 register ****/ +/* Table Data [8:0] - Offset to data in the packet [bits] [17:9 ... */ +#define EC_EPE_ACT_TABLE_DATA_3_VAL_MASK 0x1FFFFFFF +#define EC_EPE_ACT_TABLE_DATA_3_VAL_SHIFT 0 + +/**** act_table_data_4 register ****/ +/* Table data[7:0] - Offset to header length location in the pac ... */ +#define EC_EPE_ACT_TABLE_DATA_4_VAL_MASK 0x0FFFFFFF +#define EC_EPE_ACT_TABLE_DATA_4_VAL_SHIFT 0 + +/**** act_table_data_6 register ****/ +/* Table data[0] - WR header length[10:1] - Write header length ... */ +#define EC_EPE_ACT_TABLE_DATA_6_VAL_MASK 0x007FFFFF +#define EC_EPE_ACT_TABLE_DATA_6_VAL_SHIFT 0 + +/**** res_in register ****/ +/* Selector for input parse_en0 - Input vector1 - Default value ... */ +#define EC_EPE_RES_IN_SEL_PARSE_EN (1 << 0) +/* Selector for input protocol_index 0 - Input vector 1 - Defaul ... */ +#define EC_EPE_RES_IN_SEL_PROT_INDEX (1 << 1) +/* Selector for input hdr_offset 0 - Input vector 1 - Default va ... */ +#define EC_EPE_RES_IN_SEL_HDR_OFFSET (1 << 2) + +/**** p1 register ****/ +/* Location of the input protocol index in the parser result vec ... */ +#define EC_EPE_RES_P1_IN_PROT_INDEX_MASK 0x000003FF +#define EC_EPE_RES_P1_IN_PROT_INDEX_SHIFT 0 + +/**** p2 register ****/ +/* Location of the input offset in the parser result vector */ +#define EC_EPE_RES_P2_IN_OFFSET_MASK 0x000003FF +#define EC_EPE_RES_P2_IN_OFFSET_SHIFT 0 + +/**** p3 register ****/ +/* Location of the input parse enable in the parser result vecto ... */ +#define EC_EPE_RES_P3_IN_PARSE_EN_MASK 0x000003FF +#define EC_EPE_RES_P3_IN_PARSE_EN_SHIFT 0 + +/**** p4 register ****/ +/* Location of the control bits in the parser result vector */ +#define EC_EPE_RES_P4_CTRL_BITS_MASK 0x000003FF +#define EC_EPE_RES_P4_CTRL_BITS_SHIFT 0 + +/**** p5 register ****/ +/* Location of the MAC DA in the parser result vector */ +#define EC_EPE_RES_P5_DA_MASK 0x000003FF +#define EC_EPE_RES_P5_DA_SHIFT 0 + +/**** p6 register ****/ +/* Location of the MAC SA in the parser result vector */ +#define EC_EPE_RES_P6_SA_MASK 0x000003FF +#define EC_EPE_RES_P6_SA_SHIFT 0 + +/**** p7 register ****/ +/* Location of the first VLAN in the parser result vector */ +#define EC_EPE_RES_P7_VLAN_1_MASK 0x000003FF +#define EC_EPE_RES_P7_VLAN_1_SHIFT 0 + +/**** p8 register ****/ +/* Location of the second VLAN in the parser result vector */ +#define EC_EPE_RES_P8_VLAN_2_MASK 0x000003FF +#define EC_EPE_RES_P8_VLAN_2_SHIFT 0 + +/**** p9 register ****/ +/* Location of the L3 protocol index in the parser result vector ... */ +#define EC_EPE_RES_P9_L3_PROT_INDEX_MASK 0x000003FF +#define EC_EPE_RES_P9_L3_PROT_INDEX_SHIFT 0 + +/**** p10 register ****/ +/* Location of the L3 offset in the parser result vector */ +#define EC_EPE_RES_P10_L3_OFFSET_MASK 0x000003FF +#define EC_EPE_RES_P10_L3_OFFSET_SHIFT 0 + +/**** p11 register ****/ +/* Location of the L3 SIP in the parser result vector */ +#define EC_EPE_RES_P11_L3_SIP_MASK 0x000003FF +#define EC_EPE_RES_P11_L3_SIP_SHIFT 0 + +/**** p12 register ****/ +/* Location of the L3 DIP in the parser result vector */ +#define EC_EPE_RES_P12_L3_DIP_MASK 0x000003FF +#define EC_EPE_RES_P12_L3_DIP_SHIFT 0 + +/**** p13 register ****/ +/* Location of the L3 priority in the parser result vector */ +#define EC_EPE_RES_P13_L3_PRIORITY_MASK 0x000003FF +#define EC_EPE_RES_P13_L3_PRIORITY_SHIFT 0 + +/**** p14 register ****/ +/* Location of the L3 header length in the parser result vector */ +#define EC_EPE_RES_P14_L3_HDR_LEN_MASK 0x000003FF +#define EC_EPE_RES_P14_L3_HDR_LEN_SHIFT 0 + +/**** p15 register ****/ +/* Location of the L4 protocol index in the parser result vector ... */ +#define EC_EPE_RES_P15_L4_PROT_INDEX_MASK 0x000003FF +#define EC_EPE_RES_P15_L4_PROT_INDEX_SHIFT 0 + +/**** p16 register ****/ +/* Location of the L4 source port in the parser result vector */ +#define EC_EPE_RES_P16_L4_SRC_PORT_MASK 0x000003FF +#define EC_EPE_RES_P16_L4_SRC_PORT_SHIFT 0 + +/**** p17 register ****/ +/* Location of the L4 destination port in the parser result vect ... */ +#define EC_EPE_RES_P17_L4_DST_PORT_MASK 0x000003FF +#define EC_EPE_RES_P17_L4_DST_PORT_SHIFT 0 + +/**** p18 register ****/ +/* Location of the L4 offset in the parser result vector */ +#define EC_EPE_RES_P18_L4_OFFSET_MASK 0x000003FF +#define EC_EPE_RES_P18_L4_OFFSET_SHIFT 0 + +/**** p19 register ****/ +/* Location of the Ether type in the parser result vector when w ... */ +#define EC_EPE_RES_P19_WOL_ETYPE_MASK 0x000003FF +#define EC_EPE_RES_P19_WOL_ETYPE_SHIFT 0 + +/**** p20 register ****/ +/* Location of the RoCE QP number field in the parser result vec ... */ +#define EC_EPE_RES_P20_ROCE_QPN_MASK 0x000003FF +#define EC_EPE_RES_P20_ROCE_QPN_SHIFT 0 + +/**** hdr_len register ****/ +/* Value for selecting table 1 */ +#define EC_EPE_H_HDR_LEN_TABLE_1_MASK 0x000000FF +#define EC_EPE_H_HDR_LEN_TABLE_1_SHIFT 0 +/* Value for selecting table 2 */ +#define EC_EPE_H_HDR_LEN_TABLE_2_MASK 0x00FF0000 +#define EC_EPE_H_HDR_LEN_TABLE_2_SHIFT 16 + +/**** comp_data register ****/ +/* Data 1 for comparison */ +#define EC_EPE_P_COMP_DATA_DATA_1_MASK 0x0000FFFF +#define EC_EPE_P_COMP_DATA_DATA_1_SHIFT 0 +/* Data 2 for comparison +[18:16] - Stage +[24:19] - Branch ID */ +#define EC_EPE_P_COMP_DATA_DATA_2_MASK 0x01FF0000 +#define EC_EPE_P_COMP_DATA_DATA_2_SHIFT 16 + +/**** comp_mask register ****/ +/* Data 1 for comparison */ +#define EC_EPE_P_COMP_MASK_DATA_1_MASK 0x0000FFFF +#define EC_EPE_P_COMP_MASK_DATA_1_SHIFT 0 +/* Data 2 for comparison +[18:16] - Stage +[24:19] - Branch ID */ +#define EC_EPE_P_COMP_MASK_DATA_2_MASK 0x01FF0000 +#define EC_EPE_P_COMP_MASK_DATA_2_SHIFT 16 + +/**** comp_ctrl register ****/ +/* Output result value */ +#define EC_EPE_P_COMP_CTRL_RES_MASK 0x0000001F +#define EC_EPE_P_COMP_CTRL_RES_SHIFT 0 +/* Compare command for the data_1 field00 - Compare01 - <=10 - > ... */ +#define EC_EPE_P_COMP_CTRL_CMD_1_MASK 0x00030000 +#define EC_EPE_P_COMP_CTRL_CMD_1_SHIFT 16 +/* Compare command for the data_2 field 00 - Compare 01 - <= 10 ... */ +#define EC_EPE_P_COMP_CTRL_CMD_2_MASK 0x000C0000 +#define EC_EPE_P_COMP_CTRL_CMD_2_SHIFT 18 +/* Entry is valid */ +#define EC_EPE_P_COMP_CTRL_VALID (1 << 31) + +/**** prot_act register ****/ +/* Drop indication for the selected protocol index */ +#define EC_EPE_A_PROT_ACT_DROP (1 << 0) +/* Mapping value Used when mapping the entire protocol index ran ... */ +#define EC_EPE_A_PROT_ACT_MAP_MASK 0x00000F00 +#define EC_EPE_A_PROT_ACT_MAP_SHIFT 8 + +/**** thash_cfg_1 register ****/ +/* Hash function output selection:000 - [7:0]001 - [15:8]010 - [ ... */ +#define EC_RFW_THASH_CFG_1_OUT_SEL_MASK 0x00000007 +#define EC_RFW_THASH_CFG_1_OUT_SEL_SHIFT 0 +/* Selects between hash functions00 - toeplitz01 - CRC-3210 - 0x ... */ +#define EC_RFW_THASH_CFG_1_FUNC_SEL_MASK 0x00000300 +#define EC_RFW_THASH_CFG_1_FUNC_SEL_SHIFT 8 +/* Enable SIP/DIP swap if SIP= 5. */ +#define EC_RFW_LRO_CHECK_IPV4_IHL_1 (1 << 2) +/* Compare to previous packet. */ +#define EC_RFW_LRO_CHECK_IPV4_IHL_2 (1 << 3) +/* Compare DSCP to previous packet. */ +#define EC_RFW_LRO_CHECK_IPV4_DSCP (1 << 4) +/* Check that Total length >= lro_ipv4_tlen_val. */ +#define EC_RFW_LRO_CHECK_IPV4_TLEN (1 << 5) +/* Compare to previous packet value +1. */ +#define EC_RFW_LRO_CHECK_IPV4_ID (1 << 6) +/* Compare to lro_ipv4_flags_val with lro_ipv4_flags_mask_0. */ +#define EC_RFW_LRO_CHECK_IPV4_FLAGS_0 (1 << 7) +/* Compare to previous packet flags with lro_ipv4_flags_mask_1. */ +#define EC_RFW_LRO_CHECK_IPV4_FLAGS_1 (1 << 8) +/* Verify that the fragment offset field is 0. */ +#define EC_RFW_LRO_CHECK_IPV4_FRAG (1 << 9) +/* Verify that the TTL value >0. */ +#define EC_RFW_LRO_CHECK_IPV4_TTL_0 (1 << 10) +/* Compare TTL value to previous packet. */ +#define EC_RFW_LRO_CHECK_IPV4_TTL_1 (1 << 11) +/* Compare to previous packet protocol field. */ +#define EC_RFW_LRO_CHECK_IPV4_PROT_0 (1 << 12) +/* Verify that the protocol is TCP or UDP. */ +#define EC_RFW_LRO_CHECK_IPV4_PROT_1 (1 << 13) +/* Verify that the check sum is correct. */ +#define EC_RFW_LRO_CHECK_IPV4_CHECKSUM (1 << 14) +/* Compare SIP to previous packet. */ +#define EC_RFW_LRO_CHECK_IPV4_SIP (1 << 15) +/* Compare DIP to previous packet. */ +#define EC_RFW_LRO_CHECK_IPV4_DIP (1 << 16) + +/**** lro_ipv4 register ****/ +/* Total length minimum value */ +#define EC_RFW_LRO_IPV4_TLEN_VAL_MASK 0x0000FFFF +#define EC_RFW_LRO_IPV4_TLEN_VAL_SHIFT 0 +/* Flags value */ +#define EC_RFW_LRO_IPV4_FLAGS_VAL_MASK 0x00070000 +#define EC_RFW_LRO_IPV4_FLAGS_VAL_SHIFT 16 +/* Flags mask */ +#define EC_RFW_LRO_IPV4_FLAGS_MASK_0_MASK 0x00380000 +#define EC_RFW_LRO_IPV4_FLAGS_MASK_0_SHIFT 19 +/* Flags mask */ +#define EC_RFW_LRO_IPV4_FLAGS_MASK_1_MASK 0x01C00000 +#define EC_RFW_LRO_IPV4_FLAGS_MASK_1_SHIFT 22 +/* Version value */ +#define EC_RFW_LRO_IPV4_VER_MASK 0xF0000000 +#define EC_RFW_LRO_IPV4_VER_SHIFT 28 + +/**** lro_check_ipv6 register ****/ +/* Check version field */ +#define EC_RFW_LRO_CHECK_IPV6_VER (1 << 0) +/* Compare TC to previous packet. */ +#define EC_RFW_LRO_CHECK_IPV6_TC (1 << 1) +/* Compare flow label field to previous packet. */ +#define EC_RFW_LRO_CHECK_IPV6_FLOW (1 << 2) +/* Check that Total length >= lro_ipv6_pen_val. */ +#define EC_RFW_LRO_CHECK_IPV6_PLEN (1 << 3) +/* Compare to previous packet next header field. */ +#define EC_RFW_LRO_CHECK_IPV6_NEXT_0 (1 << 4) +/* Verify that the next header is TCP or UDP. */ +#define EC_RFW_LRO_CHECK_IPV6_NEXT_1 (1 << 5) +/* Verify that hop limit is >0. */ +#define EC_RFW_LRO_CHECK_IPV6_HOP_0 (1 << 6) +/* Compare hop limit to previous packet. */ +#define EC_RFW_LRO_CHECK_IPV6_HOP_1 (1 << 7) +/* Compare SIP to previous packet. */ +#define EC_RFW_LRO_CHECK_IPV6_SIP (1 << 8) +/* Compare DIP to previous packet. */ +#define EC_RFW_LRO_CHECK_IPV6_DIP (1 << 9) + +/**** lro_ipv6 register ****/ +/* Payload length minimum value */ +#define EC_RFW_LRO_IPV6_PLEN_VAL_MASK 0x0000FFFF +#define EC_RFW_LRO_IPV6_PLEN_VAL_SHIFT 0 +/* Version value */ +#define EC_RFW_LRO_IPV6_VER_MASK 0x0F000000 +#define EC_RFW_LRO_IPV6_VER_SHIFT 24 + +/**** lro_check_tcp register ****/ +/* Compare to previous packet. */ +#define EC_RFW_LRO_CHECK_TCP_SRC_PORT (1 << 0) +/* Compare to previous packet. */ +#define EC_RFW_LRO_CHECK_TCP_DST_PORT (1 << 1) +/* If (SYN == 1), don't check */ +#define EC_RFW_LRO_CHECK_TCP_SN (1 << 2) +/* Check data offset field == 5. */ +#define EC_RFW_LRO_CHECK_TCP_OFFSET_0 (1 << 3) +/* Check data offset field >= 5. */ +#define EC_RFW_LRO_CHECK_TCP_OFFSET_1 (1 << 4) +/* Compare to previous packet. */ +#define EC_RFW_LRO_CHECK_TCP_OFFSET_2 (1 << 5) +/* Compare reserved field to lro_tcp_res. */ +#define EC_RFW_LRO_CHECK_TCP_RES (1 << 6) +/* Compare to lro_tcp_ecn_val and lro_tcp_ecn_mask_0. */ +#define EC_RFW_LRO_CHECK_TCP_ECN_0 (1 << 7) +/* Compare to previous packet ECN field with lro_tcp_ecn_mask_1 */ +#define EC_RFW_LRO_CHECK_TCP_ECN_1 (1 << 8) +/* Compare to lro_tcp_ctrl_val and lro_tcp_ctrl_mask_0. */ +#define EC_RFW_LRO_CHECK_TCP_CTRL_0 (1 << 9) +/* Compare to previous packet ECN field with lro_tcp_ctrl_mask_1 */ +#define EC_RFW_LRO_CHECK_TCP_CTRL_1 (1 << 10) +/* Verify that check sum is correct. */ +#define EC_RFW_LRO_CHECK_TCP_CHECKSUM (1 << 11) + +/**** lro_tcp register ****/ +/* Reserved field default value */ +#define EC_RFW_LRO_TCP_RES_MASK 0x00000007 +#define EC_RFW_LRO_TCP_RES_SHIFT 0 +/* ECN field value */ +#define EC_RFW_LRO_TCP_ECN_VAL_MASK 0x00000038 +#define EC_RFW_LRO_TCP_ECN_VAL_SHIFT 3 +/* ECN field mask */ +#define EC_RFW_LRO_TCP_ECN_MASK_0_MASK 0x000001C0 +#define EC_RFW_LRO_TCP_ECN_MASK_0_SHIFT 6 +/* ECN field mask */ +#define EC_RFW_LRO_TCP_ECN_MASK_1_MASK 0x00000E00 +#define EC_RFW_LRO_TCP_ECN_MASK_1_SHIFT 9 +/* Control field value */ +#define EC_RFW_LRO_TCP_CTRL_VAL_MASK 0x0003F000 +#define EC_RFW_LRO_TCP_CTRL_VAL_SHIFT 12 +/* Control field mask */ +#define EC_RFW_LRO_TCP_CTRL_MASK_0_MASK 0x00FC0000 +#define EC_RFW_LRO_TCP_CTRL_MASK_0_SHIFT 18 +/* Control field mask */ +#define EC_RFW_LRO_TCP_CTRL_MASK_1_MASK 0x3F000000 +#define EC_RFW_LRO_TCP_CTRL_MASK_1_SHIFT 24 + +/**** lro_check_udp register ****/ +/* Compare to previous packet. */ +#define EC_RFW_LRO_CHECK_UDP_SRC_PORT (1 << 0) +/* Compare to previous packet. */ +#define EC_RFW_LRO_CHECK_UDP_DST_PORT (1 << 1) +/* Verify that check sum is correct. */ +#define EC_RFW_LRO_CHECK_UDP_CHECKSUM (1 << 2) + +/**** lro_check_l2 register ****/ +/* Compare to previous packet. */ +#define EC_RFW_LRO_CHECK_L2_MAC_DA (1 << 0) +/* Compare to previous packet. */ +#define EC_RFW_LRO_CHECK_L2_MAC_SA (1 << 1) +/* Compare to previous packet. */ +#define EC_RFW_LRO_CHECK_L2_VLAN_1_EXIST (1 << 2) +/* Compare to previous packet. */ +#define EC_RFW_LRO_CHECK_L2_VLAN_1_VID (1 << 3) +/* Compare to previous packet. */ +#define EC_RFW_LRO_CHECK_L2_VLAN_1_CFI (1 << 4) +/* Compare to previous packet. */ +#define EC_RFW_LRO_CHECK_L2_VLAN_1_PBITS (1 << 5) +/* Compare to previous packet. */ +#define EC_RFW_LRO_CHECK_L2_VLAN_2_EXIST (1 << 6) +/* Compare to previous packet. */ +#define EC_RFW_LRO_CHECK_L2_VLAN_2_VID (1 << 7) +/* Compare to previous packet. */ +#define EC_RFW_LRO_CHECK_L2_VLAN_2_CFI (1 << 8) +/* Compare to previous packet. */ +#define EC_RFW_LRO_CHECK_L2_VLAN_2_PBITS (1 << 9) +/* Verify that the FCS is correct. */ +#define EC_RFW_LRO_CHECK_L2_FCS (1 << 10) + +/**** lro_check_gen register ****/ +/* Compare to previous packet */ +#define EC_RFW_LRO_CHECK_GEN_UDMA (1 << 0) +/* Compare to previous packet */ +#define EC_RFW_LRO_CHECK_GEN_QUEUE (1 << 1) + +/**** lro_store register ****/ +/* Store packet information if protocol match. */ +#define EC_RFW_LRO_STORE_IPV4 (1 << 0) +/* Store packet information if protocol match. */ +#define EC_RFW_LRO_STORE_IPV6 (1 << 1) +/* Store packet information if protocol match. */ +#define EC_RFW_LRO_STORE_TCP (1 << 2) +/* Store packet information if protocol match. */ +#define EC_RFW_LRO_STORE_UDP (1 << 3) +/* Store packet if IPv4 flags match the register value with mask */ +#define EC_RFW_LRO_STORE_IPV4_FLAGS_VAL_MASK 0x00000070 +#define EC_RFW_LRO_STORE_IPV4_FLAGS_VAL_SHIFT 4 +/* Mask for IPv4 flags */ +#define EC_RFW_LRO_STORE_IPV4_FLAGS_MASK_MASK 0x00000380 +#define EC_RFW_LRO_STORE_IPV4_FLAGS_MASK_SHIFT 7 +/* Store packet if TCP control and ECN match the register value ... */ +#define EC_RFW_LRO_STORE_TCP_CTRL_VAL_MASK 0x0007FC00 +#define EC_RFW_LRO_STORE_TCP_CTRL_VAL_SHIFT 10 +/* Mask for TCP control */ +#define EC_RFW_LRO_STORE_TCP_CTRL_MASK_MASK 0x0FF80000 +#define EC_RFW_LRO_STORE_TCP_CTRL_MASK_SHIFT 19 + +/**** vid_table_def register ****/ +/* Table default data (valid only after configuring the table ad ... */ +#define EC_RFW_VID_TABLE_DEF_VAL_MASK 0x0000003F +#define EC_RFW_VID_TABLE_DEF_VAL_SHIFT 0 +/* Default data selection +0 - Default value +1 - Table data out */ +#define EC_RFW_VID_TABLE_DEF_SEL (1 << 6) + +/**** ctrl_table_def register ****/ +/* Control table output for selecting the forwarding MUXs [3:0] ... */ +#define EC_RFW_CTRL_TABLE_DEF_VAL_MASK 0x000FFFFF +#define EC_RFW_CTRL_TABLE_DEF_VAL_SHIFT 0 +/* Default data selection 0 - Default value 1 - Table data out ... */ +#define EC_RFW_CTRL_TABLE_DEF_SEL (1 << 20) + +/**** cfg_a_0 register ****/ +/* Selection of the L3 checksum result in the Metadata00 - L3 ch ... */ +#define EC_RFW_CFG_A_0_META_L3_CHK_RES_SEL_MASK 0x00000003 +#define EC_RFW_CFG_A_0_META_L3_CHK_RES_SEL_SHIFT 0 +/* Selection of the L4 checksum result in the Metadata0 - L4 che ... */ +#define EC_RFW_CFG_A_0_META_L4_CHK_RES_SEL (1 << 2) +/* Selection of the LRO_context_value result in the Metadata0 - ... */ +#define EC_RFW_CFG_A_0_LRO_CONTEXT_SEL (1 << 4) + +/**** thash_cfg_3 register ****/ +/* Enable Hash value for RoCE packets in outer packet. */ +#define EC_RFW_THASH_CFG_3_ENABLE_OUTER_ROCE (1 << 0) +/* Enable Hash value for RoCE packets in inner packet. */ +#define EC_RFW_THASH_CFG_3_ENABLE_INNER_ROCE (1 << 1) +/* Enable Hash value for FcoE packets in outer packet. */ +#define EC_RFW_THASH_CFG_3_ENABLE_OUTER_FCOE (1 << 2) +/* Enable Hash value for FcoE packets in inner packet. */ +#define EC_RFW_THASH_CFG_3_ENABLE_INNER_FCOE (1 << 3) + +/**** thash_mask_outer_ipv6 register ****/ +/* IPv6 source IP address */ +#define EC_RFW_THASH_MASK_OUTER_IPV6_SRC_MASK 0x0000FFFF +#define EC_RFW_THASH_MASK_OUTER_IPV6_SRC_SHIFT 0 +/* IPv6 destination IP address */ +#define EC_RFW_THASH_MASK_OUTER_IPV6_DST_MASK 0xFFFF0000 +#define EC_RFW_THASH_MASK_OUTER_IPV6_DST_SHIFT 16 + +/**** thash_mask_outer register ****/ +/* IPv4 source IP address */ +#define EC_RFW_THASH_MASK_OUTER_IPV4_SRC_MASK 0x0000000F +#define EC_RFW_THASH_MASK_OUTER_IPV4_SRC_SHIFT 0 +/* IPv4 destination IP address */ +#define EC_RFW_THASH_MASK_OUTER_IPV4_DST_MASK 0x000000F0 +#define EC_RFW_THASH_MASK_OUTER_IPV4_DST_SHIFT 4 +/* TCP source port */ +#define EC_RFW_THASH_MASK_OUTER_TCP_SRC_PORT_MASK 0x00000300 +#define EC_RFW_THASH_MASK_OUTER_TCP_SRC_PORT_SHIFT 8 +/* TCP destination port */ +#define EC_RFW_THASH_MASK_OUTER_TCP_DST_PORT_MASK 0x00000C00 +#define EC_RFW_THASH_MASK_OUTER_TCP_DST_PORT_SHIFT 10 +/* UDP source port */ +#define EC_RFW_THASH_MASK_OUTER_UDP_SRC_PORT_MASK 0x00003000 +#define EC_RFW_THASH_MASK_OUTER_UDP_SRC_PORT_SHIFT 12 +/* UDP destination port */ +#define EC_RFW_THASH_MASK_OUTER_UDP_DST_PORT_MASK 0x0000C000 +#define EC_RFW_THASH_MASK_OUTER_UDP_DST_PORT_SHIFT 14 + +/**** thash_mask_inner_ipv6 register ****/ +/* IPv6 source IP address */ +#define EC_RFW_THASH_MASK_INNER_IPV6_SRC_MASK 0x0000FFFF +#define EC_RFW_THASH_MASK_INNER_IPV6_SRC_SHIFT 0 +/* IPv6 destination IP address */ +#define EC_RFW_THASH_MASK_INNER_IPV6_DST_MASK 0xFFFF0000 +#define EC_RFW_THASH_MASK_INNER_IPV6_DST_SHIFT 16 + +/**** thash_mask_inner register ****/ +/* IPv4 source IP address */ +#define EC_RFW_THASH_MASK_INNER_IPV4_SRC_MASK 0x0000000F +#define EC_RFW_THASH_MASK_INNER_IPV4_SRC_SHIFT 0 +/* IPv4 destination IP address */ +#define EC_RFW_THASH_MASK_INNER_IPV4_DST_MASK 0x000000F0 +#define EC_RFW_THASH_MASK_INNER_IPV4_DST_SHIFT 4 +/* TCP source port */ +#define EC_RFW_THASH_MASK_INNER_TCP_SRC_PORT_MASK 0x00000300 +#define EC_RFW_THASH_MASK_INNER_TCP_SRC_PORT_SHIFT 8 +/* TCP destination port */ +#define EC_RFW_THASH_MASK_INNER_TCP_DST_PORT_MASK 0x00000C00 +#define EC_RFW_THASH_MASK_INNER_TCP_DST_PORT_SHIFT 10 +/* UDP source port */ +#define EC_RFW_THASH_MASK_INNER_UDP_SRC_PORT_MASK 0x00003000 +#define EC_RFW_THASH_MASK_INNER_UDP_SRC_PORT_SHIFT 12 +/* UDP destination port */ +#define EC_RFW_THASH_MASK_INNER_UDP_DST_PORT_MASK 0x0000C000 +#define EC_RFW_THASH_MASK_INNER_UDP_DST_PORT_SHIFT 14 + +/**** def_cfg register ****/ +/* Number of padding bytes to add at the beginning of each Ether ... */ +#define EC_RFW_UDMA_DEF_CFG_RX_PAD_MASK 0x0000003F +#define EC_RFW_UDMA_DEF_CFG_RX_PAD_SHIFT 0 + +/**** queue register ****/ +/* Mapping between priority and queue number */ +#define EC_RFW_PRIORITY_QUEUE_MAP_MASK 0x00000003 +#define EC_RFW_PRIORITY_QUEUE_MAP_SHIFT 0 + +/**** opt_1 register ****/ +/* Default UDMA for forwarding */ +#define EC_RFW_DEFAULT_OPT_1_UDMA_MASK 0x0000000F +#define EC_RFW_DEFAULT_OPT_1_UDMA_SHIFT 0 +/* Default priority for forwarding */ +#define EC_RFW_DEFAULT_OPT_1_PRIORITY_MASK 0x00000700 +#define EC_RFW_DEFAULT_OPT_1_PRIORITY_SHIFT 8 +/* Default queue for forwarding */ +#define EC_RFW_DEFAULT_OPT_1_QUEUE_MASK 0x00030000 +#define EC_RFW_DEFAULT_OPT_1_QUEUE_SHIFT 16 + +/**** data_h register ****/ +/* MAC address data */ +#define EC_FWD_MAC_DATA_H_VAL_MASK 0x0000FFFF +#define EC_FWD_MAC_DATA_H_VAL_SHIFT 0 + +/**** mask_h register ****/ +/* MAC address mask */ +#define EC_FWD_MAC_MASK_H_VAL_MASK 0x0000FFFF +#define EC_FWD_MAC_MASK_H_VAL_SHIFT 0 + +/**** ctrl register ****/ +/* Control value for Rx forwarding engine[0] - Drop indication[2 ... */ +#define EC_FWD_MAC_CTRL_RX_VAL_MASK 0x000001FF +#define EC_FWD_MAC_CTRL_RX_VAL_SHIFT 0 + +/* Drop indication */ +#define EC_FWD_MAC_CTRL_RX_VAL_DROP (1 << 0) + +/* control table command input */ +#define EC_FWD_MAC_CTRL_RX_VAL_CTRL_CMD_MASK 0x00000006 +#define EC_FWD_MAC_CTRL_RX_VAL_CTRL_CMD_SHIFT 1 + +/* UDMA selection */ +#define EC_FWD_MAC_CTRL_RX_VAL_UDMA_MASK 0x000000078 +#define EC_FWD_MAC_CTRL_RX_VAL_UDMA_SHIFT 3 + +/* queue number */ +#define EC_FWD_MAC_CTRL_RX_VAL_QID_MASK 0x00000180 +#define EC_FWD_MAC_CTRL_RX_VAL_QID_SHIFT 7 + +/* Entry is valid for Rx forwarding engine. */ +#define EC_FWD_MAC_CTRL_RX_VALID (1 << 15) +/* Control value for Tx forwarding engine */ +#define EC_FWD_MAC_CTRL_TX_VAL_MASK 0x001F0000 +#define EC_FWD_MAC_CTRL_TX_VAL_SHIFT 16 +/* Entry is valid for Tx forwarding engine. */ +#define EC_FWD_MAC_CTRL_TX_VALID (1 << 31) + +/**** uc register ****/ +/* timer max value for waiting for a stream to be ready to accep ... */ +#define EC_MSW_UC_TIMER_MASK 0x0000FFFF +#define EC_MSW_UC_TIMER_SHIFT 0 +/* Drop packet if target queue in the UDMA is full */ +#define EC_MSW_UC_Q_FULL_DROP_MASK 0x000F0000 +#define EC_MSW_UC_Q_FULL_DROP_SHIFT 16 +/* Drop packet if timer expires. */ +#define EC_MSW_UC_TIMER_DROP_MASK 0x0F000000 +#define EC_MSW_UC_TIMER_DROP_SHIFT 24 + +/**** mc register ****/ +/* Timer max value for waiting for a stream to be ready to accep ... */ +#define EC_MSW_MC_TIMER_MASK 0x0000FFFF +#define EC_MSW_MC_TIMER_SHIFT 0 +/* Drop packet if target queue in UDMA is full. */ +#define EC_MSW_MC_Q_FULL_DROP_MASK 0x000F0000 +#define EC_MSW_MC_Q_FULL_DROP_SHIFT 16 +/* Drop packet if timer expires. */ +#define EC_MSW_MC_TIMER_DROP_MASK 0x0F000000 +#define EC_MSW_MC_TIMER_DROP_SHIFT 24 + +/**** bc register ****/ +/* Timer max value for waiting for a stream to be ready to accep ... */ +#define EC_MSW_BC_TIMER_MASK 0x0000FFFF +#define EC_MSW_BC_TIMER_SHIFT 0 +/* Drop packet if target queue in UDMA is full. */ +#define EC_MSW_BC_Q_FULL_DROP_MASK 0x000F0000 +#define EC_MSW_BC_Q_FULL_DROP_SHIFT 16 +/* Drop packet if timer expires. */ +#define EC_MSW_BC_TIMER_DROP_MASK 0x0F000000 +#define EC_MSW_BC_TIMER_DROP_SHIFT 24 + +/**** in_cfg register ****/ +/* Swap input bytes order */ +#define EC_TSO_IN_CFG_SWAP_BYTES (1 << 0) +/* Selects strict priority or round robin scheduling between GDM ... */ +#define EC_TSO_IN_CFG_SEL_SP_RR (1 << 1) +/* Selects scheduler numbering direction */ +#define EC_TSO_IN_CFG_SEL_SCH_DIR (1 << 2) +/* Minimum L2 packet size (not including FCS) */ +#define EC_TSO_IN_CFG_L2_MIN_SIZE_MASK 0x00007F00 +#define EC_TSO_IN_CFG_L2_MIN_SIZE_SHIFT 8 +/* Swap input bytes order */ +#define EC_TSO_IN_CFG_SP_INIT_VAL_MASK 0x000F0000 +#define EC_TSO_IN_CFG_SP_INIT_VAL_SHIFT 16 + +/**** cache_table_addr register ****/ +/* Address for accessing the table */ +#define EC_TSO_CACHE_TABLE_ADDR_VAL_MASK 0x0000000F +#define EC_TSO_CACHE_TABLE_ADDR_VAL_SHIFT 0 + +/**** ctrl_first register ****/ +/* Data to be written into the control BIS. */ +#define EC_TSO_CTRL_FIRST_DATA_MASK 0x000001FF +#define EC_TSO_CTRL_FIRST_DATA_SHIFT 0 +/* Mask for control bits */ +#define EC_TSO_CTRL_FIRST_MASK_MASK 0x01FF0000 +#define EC_TSO_CTRL_FIRST_MASK_SHIFT 16 + +/**** ctrl_middle register ****/ +/* Data to be written into the control BIS. */ +#define EC_TSO_CTRL_MIDDLE_DATA_MASK 0x000001FF +#define EC_TSO_CTRL_MIDDLE_DATA_SHIFT 0 +/* Mask for the control bits */ +#define EC_TSO_CTRL_MIDDLE_MASK_MASK 0x01FF0000 +#define EC_TSO_CTRL_MIDDLE_MASK_SHIFT 16 + +/**** ctrl_last register ****/ +/* Data to be written into the control BIS. */ +#define EC_TSO_CTRL_LAST_DATA_MASK 0x000001FF +#define EC_TSO_CTRL_LAST_DATA_SHIFT 0 +/* Mask for the control bits */ +#define EC_TSO_CTRL_LAST_MASK_MASK 0x01FF0000 +#define EC_TSO_CTRL_LAST_MASK_SHIFT 16 + +/**** cfg_add_0 register ****/ +/* MSS selection option:0 - MSS value is selected using MSS_sel ... */ +#define EC_TSO_CFG_ADD_0_MSS_SEL (1 << 0) + +/**** cfg_tunnel register ****/ +/* Enable TSO with tunnelling */ +#define EC_TSO_CFG_TUNNEL_EN_TUNNEL_TSO (1 << 0) +/* Enable outer UDP checksum update */ +#define EC_TSO_CFG_TUNNEL_EN_UDP_CHKSUM (1 << 8) +/* Enable outer UDP length update */ +#define EC_TSO_CFG_TUNNEL_EN_UDP_LEN (1 << 9) +/* Enable outer Ip6 length update */ +#define EC_TSO_CFG_TUNNEL_EN_IPV6_PLEN (1 << 10) +/* Enable outer IPv4 checksum update */ +#define EC_TSO_CFG_TUNNEL_EN_IPV4_CHKSUM (1 << 11) +/* Enable outer IPv4 Identification update */ +#define EC_TSO_CFG_TUNNEL_EN_IPV4_IDEN (1 << 12) +/* Enable outer IPv4 length update */ +#define EC_TSO_CFG_TUNNEL_EN_IPV4_TLEN (1 << 13) + +/**** mss register ****/ +/* MSS value */ +#define EC_TSO_SEL_MSS_VAL_MASK 0x000FFFFF +#define EC_TSO_SEL_MSS_VAL_SHIFT 0 + +/**** parse register ****/ +/* Max number of bus beats for parsing */ +#define EC_TPE_PARSE_MAX_BEATS_MASK 0x0000FFFF +#define EC_TPE_PARSE_MAX_BEATS_SHIFT 0 + +/**** vlan_data register ****/ +/* UDMA default VLAN 1 data */ +#define EC_TPM_UDMA_VLAN_DATA_DEF_1_MASK 0x0000FFFF +#define EC_TPM_UDMA_VLAN_DATA_DEF_1_SHIFT 0 +/* UDMA default VLAN 2 data */ +#define EC_TPM_UDMA_VLAN_DATA_DEF_2_MASK 0xFFFF0000 +#define EC_TPM_UDMA_VLAN_DATA_DEF_2_SHIFT 16 + +/**** mac_sa_2 register ****/ +/* MAC source address data [47:32] */ +#define EC_TPM_UDMA_MAC_SA_2_H_VAL_MASK 0x0000FFFF +#define EC_TPM_UDMA_MAC_SA_2_H_VAL_SHIFT 0 +/* Drop indication for MAC SA spoofing0 – Don't drop */ +#define EC_TPM_UDMA_MAC_SA_2_DROP (1 << 16) +/* Replace indication for MAC SA spoofing 0 - Don't replace */ +#define EC_TPM_UDMA_MAC_SA_2_REPLACE (1 << 17) + +/**** etype register ****/ +/* Ether type value */ +#define EC_TPM_SEL_ETYPE_VAL_MASK 0x0000FFFF +#define EC_TPM_SEL_ETYPE_VAL_SHIFT 0 + +/**** tx_wr_fifo register ****/ +/* Max data beats that can be used in the Tx FIFO */ +#define EC_TFW_TX_WR_FIFO_DATA_TH_MASK 0x0000FFFF +#define EC_TFW_TX_WR_FIFO_DATA_TH_SHIFT 0 +/* Max packets that can be stored in the Tx FIFO */ +#define EC_TFW_TX_WR_FIFO_INFO_TH_MASK 0xFFFF0000 +#define EC_TFW_TX_WR_FIFO_INFO_TH_SHIFT 16 + +/**** tx_vid_table_addr register ****/ +/* Address for accessing the table */ +#define EC_TFW_TX_VID_TABLE_ADDR_VAL_MASK 0x00000FFF +#define EC_TFW_TX_VID_TABLE_ADDR_VAL_SHIFT 0 + +/**** tx_vid_table_data register ****/ +/* Table data (valid only after configuring the table address re ... */ +#define EC_TFW_TX_VID_TABLE_DATA_VAL_MASK 0x0000001F +#define EC_TFW_TX_VID_TABLE_DATA_VAL_SHIFT 0 + +/**** tx_rd_fifo register ****/ +/* Read data threshold when cut through mode is enabled. */ +#define EC_TFW_TX_RD_FIFO_READ_TH_MASK 0x0000FFFF +#define EC_TFW_TX_RD_FIFO_READ_TH_SHIFT 0 +/* Enable cut through operation of the Tx FIFO. */ +#define EC_TFW_TX_RD_FIFO_EN_CUT_THROUGH (1 << 16) + +/**** tx_checksum register ****/ +/* Enable L3 checksum insertion. */ +#define EC_TFW_TX_CHECKSUM_L3_EN (1 << 0) +/* Enable L4 checksum insertion. */ +#define EC_TFW_TX_CHECKSUM_L4_EN (1 << 1) +/* Enable L4 checksum when L3 fragmentation is detected. */ +#define EC_TFW_TX_CHECKSUM_L4_FRAG_EN (1 << 2) + +/**** tx_gen register ****/ +/* Force forward of all Tx packets to MAC. */ +#define EC_TFW_TX_GEN_FWD_ALL_TO_MAC (1 << 0) +/* Select the Packet generator as the source of Tx packets0 - Tx ... */ +#define EC_TFW_TX_GEN_SELECT_PKT_GEN (1 << 1) + +/**** tx_spf register ****/ +/* Select the VID for spoofing check:[0] - Packet VID[1] - Forwa ... */ +#define EC_TFW_TX_SPF_VID_SEL (1 << 0) + +/**** data_fifo register ****/ +/* FIFO used value (number of entries) */ +#define EC_TFW_DATA_FIFO_USED_MASK 0x0000FFFF +#define EC_TFW_DATA_FIFO_USED_SHIFT 0 +/* FIFO FULL status */ +#define EC_TFW_DATA_FIFO_FULL (1 << 16) +/* FIFO EMPTY status */ +#define EC_TFW_DATA_FIFO_EMPTY (1 << 17) + +/**** ctrl_fifo register ****/ +/* FIFO used value (number of entries) */ +#define EC_TFW_CTRL_FIFO_USED_MASK 0x0000FFFF +#define EC_TFW_CTRL_FIFO_USED_SHIFT 0 +/* FIFO FULL status */ +#define EC_TFW_CTRL_FIFO_FULL (1 << 16) +/* FIFO EMPTY status */ +#define EC_TFW_CTRL_FIFO_EMPTY (1 << 17) + +/**** hdr_fifo register ****/ +/* FIFO used value (number of entries) */ +#define EC_TFW_HDR_FIFO_USED_MASK 0x0000FFFF +#define EC_TFW_HDR_FIFO_USED_SHIFT 0 +/* FIFO FULL status */ +#define EC_TFW_HDR_FIFO_FULL (1 << 16) +/* FIFO EMPTY status */ +#define EC_TFW_HDR_FIFO_EMPTY (1 << 17) + +/**** uc_udma register ****/ +/* Default UDMA bitmap +(MSB represents physical port) */ +#define EC_TFW_UDMA_UC_UDMA_DEF_MASK 0x0000001F +#define EC_TFW_UDMA_UC_UDMA_DEF_SHIFT 0 + +/**** mc_udma register ****/ +/* Default UDMA bitmap (MSB represents physical port.) */ +#define EC_TFW_UDMA_MC_UDMA_DEF_MASK 0x0000001F +#define EC_TFW_UDMA_MC_UDMA_DEF_SHIFT 0 + +/**** bc_udma register ****/ +/* Default UDMA bitmap (MSB represents physical port.) */ +#define EC_TFW_UDMA_BC_UDMA_DEF_MASK 0x0000001F +#define EC_TFW_UDMA_BC_UDMA_DEF_SHIFT 0 + +/**** spf_cmd register ****/ +/* Command for the VLAN spoofing00 – Ignore mismatch */ +#define EC_TFW_UDMA_SPF_CMD_VID_MASK 0x00000003 +#define EC_TFW_UDMA_SPF_CMD_VID_SHIFT 0 +/* Command for VLAN spoofing 00 - Ignore mismatch */ +#define EC_TFW_UDMA_SPF_CMD_MAC_MASK 0x0000000C +#define EC_TFW_UDMA_SPF_CMD_MAC_SHIFT 2 + +/**** fwd_dec register ****/ +/* Forwarding decision control:[0] – Enable internal switch */ +#define EC_TFW_UDMA_FWD_DEC_CTRL_MASK 0x000003FF +#define EC_TFW_UDMA_FWD_DEC_CTRL_SHIFT 0 + +/**** tx_cfg register ****/ +/* Swap output byte order */ +#define EC_TMI_TX_CFG_SWAP_BYTES (1 << 0) +/* Enable forwarding to the Rx data path. */ +#define EC_TMI_TX_CFG_EN_FWD_TO_RX (1 << 1) +/* Force forwarding all packets to the MAC. */ +#define EC_TMI_TX_CFG_FORCE_FWD_MAC (1 << 2) +/* Force forwarding all packets to the MAC. */ +#define EC_TMI_TX_CFG_FORCE_FWD_RX (1 << 3) +/* Force loop back operation */ +#define EC_TMI_TX_CFG_FORCE_LB (1 << 4) + +/**** ec_pause register ****/ +/* Mask of pause_on [7:0] */ +#define EC_EFC_EC_PAUSE_MASK_MAC_MASK 0x000000FF +#define EC_EFC_EC_PAUSE_MASK_MAC_SHIFT 0 +/* Mask of GPIO input [7:0] */ +#define EC_EFC_EC_PAUSE_MASK_GPIO_MASK 0x0000FF00 +#define EC_EFC_EC_PAUSE_MASK_GPIO_SHIFT 8 + +/**** ec_xoff register ****/ +/* Mask 1 for XOFF [7:0] +Mask 1 for Almost Full indication, */ +#define EC_EFC_EC_XOFF_MASK_1_MASK 0x000000FF +#define EC_EFC_EC_XOFF_MASK_1_SHIFT 0 +/* Mask 2 for XOFF [7:0] Mask 2 for sampled Almost Full indicati ... */ +#define EC_EFC_EC_XOFF_MASK_2_MASK 0x0000FF00 +#define EC_EFC_EC_XOFF_MASK_2_SHIFT 8 + +/**** xon register ****/ +/* Mask 1 for generating XON pulse, masking XOFF [0] */ +#define EC_EFC_XON_MASK_1 (1 << 0) +/* Mask 2 for generating XON pulse, masking Almost Full indicati ... */ +#define EC_EFC_XON_MASK_2 (1 << 1) + +/**** gpio register ****/ +/* Mask for generating GPIO output XOFF indication from XOFF[0] */ +#define EC_EFC_GPIO_MASK_1 (1 << 0) + +/**** rx_fifo_af register ****/ +/* Threshold */ +#define EC_EFC_RX_FIFO_AF_TH_MASK 0x0000FFFF +#define EC_EFC_RX_FIFO_AF_TH_SHIFT 0 + +/**** rx_fifo_hyst register ****/ +/* Threshold low */ +#define EC_EFC_RX_FIFO_HYST_TH_LOW_MASK 0x0000FFFF +#define EC_EFC_RX_FIFO_HYST_TH_LOW_SHIFT 0 +/* Threshold high */ +#define EC_EFC_RX_FIFO_HYST_TH_HIGH_MASK 0xFFFF0000 +#define EC_EFC_RX_FIFO_HYST_TH_HIGH_SHIFT 16 + +/**** stat register ****/ +/* 10G MAC PFC mode, input from the 10 MAC */ +#define EC_EFC_STAT_PFC_MODE (1 << 0) + +/**** ec_pfc register ****/ +/* Force PFC flow control */ +#define EC_EFC_EC_PFC_FORCE_MASK 0x000000FF +#define EC_EFC_EC_PFC_FORCE_SHIFT 0 + +/**** q_pause_0 register ****/ +/* [i] – Mask for Q[i] */ +#define EC_FC_UDMA_Q_PAUSE_0_MASK_MASK 0x0000000F +#define EC_FC_UDMA_Q_PAUSE_0_MASK_SHIFT 0 + +/**** q_pause_1 register ****/ +/* [i] - Mask for Q[i] */ +#define EC_FC_UDMA_Q_PAUSE_1_MASK_MASK 0x0000000F +#define EC_FC_UDMA_Q_PAUSE_1_MASK_SHIFT 0 + +/**** q_pause_2 register ****/ +/* [i] - Mask for Q[i] */ +#define EC_FC_UDMA_Q_PAUSE_2_MASK_MASK 0x0000000F +#define EC_FC_UDMA_Q_PAUSE_2_MASK_SHIFT 0 + +/**** q_pause_3 register ****/ +/* [i] - Mask for Q[i] */ +#define EC_FC_UDMA_Q_PAUSE_3_MASK_MASK 0x0000000F +#define EC_FC_UDMA_Q_PAUSE_3_MASK_SHIFT 0 + +/**** q_pause_4 register ****/ +/* [i] - Mask for Q[i] */ +#define EC_FC_UDMA_Q_PAUSE_4_MASK_MASK 0x0000000F +#define EC_FC_UDMA_Q_PAUSE_4_MASK_SHIFT 0 + +/**** q_pause_5 register ****/ +/* [i] - Mask for Q[i] */ +#define EC_FC_UDMA_Q_PAUSE_5_MASK_MASK 0x0000000F +#define EC_FC_UDMA_Q_PAUSE_5_MASK_SHIFT 0 + +/**** q_pause_6 register ****/ +/* [i] - Mask for Q[i] */ +#define EC_FC_UDMA_Q_PAUSE_6_MASK_MASK 0x0000000F +#define EC_FC_UDMA_Q_PAUSE_6_MASK_SHIFT 0 + +/**** q_pause_7 register ****/ +/* [i] - Mask for Q[i] */ +#define EC_FC_UDMA_Q_PAUSE_7_MASK_MASK 0x0000000F +#define EC_FC_UDMA_Q_PAUSE_7_MASK_SHIFT 0 + +/**** q_gpio_0 register ****/ +/* [i] - Mask for Q[i] */ +#define EC_FC_UDMA_Q_GPIO_0_MASK_MASK 0x0000000F +#define EC_FC_UDMA_Q_GPIO_0_MASK_SHIFT 0 + +/**** q_gpio_1 register ****/ +/* [i] - Mask for Q[i] */ +#define EC_FC_UDMA_Q_GPIO_1_MASK_MASK 0x0000000F +#define EC_FC_UDMA_Q_GPIO_1_MASK_SHIFT 0 + +/**** q_gpio_2 register ****/ +/* [i] - Mask for Q[i] */ +#define EC_FC_UDMA_Q_GPIO_2_MASK_MASK 0x0000000F +#define EC_FC_UDMA_Q_GPIO_2_MASK_SHIFT 0 + +/**** q_gpio_3 register ****/ +/* [i] - Mask for Q[i] */ +#define EC_FC_UDMA_Q_GPIO_3_MASK_MASK 0x0000000F +#define EC_FC_UDMA_Q_GPIO_3_MASK_SHIFT 0 + +/**** q_gpio_4 register ****/ +/* [i] - Mask for Q[i] */ +#define EC_FC_UDMA_Q_GPIO_4_MASK_MASK 0x0000000F +#define EC_FC_UDMA_Q_GPIO_4_MASK_SHIFT 0 + +/**** q_gpio_5 register ****/ +/* [i] - Mask for Q[i] */ +#define EC_FC_UDMA_Q_GPIO_5_MASK_MASK 0x0000000F +#define EC_FC_UDMA_Q_GPIO_5_MASK_SHIFT 0 + +/**** q_gpio_6 register ****/ +/* [i] - Mask for Q[i] */ +#define EC_FC_UDMA_Q_GPIO_6_MASK_MASK 0x0000000F +#define EC_FC_UDMA_Q_GPIO_6_MASK_SHIFT 0 + +/**** q_gpio_7 register ****/ +/* [i] - Mask for Q[i] */ +#define EC_FC_UDMA_Q_GPIO_7_MASK_MASK 0x0000000F +#define EC_FC_UDMA_Q_GPIO_7_MASK_SHIFT 0 + +/**** s_pause register ****/ +/* Mask of pause_on [7:0] */ +#define EC_FC_UDMA_S_PAUSE_MASK_MAC_MASK 0x000000FF +#define EC_FC_UDMA_S_PAUSE_MASK_MAC_SHIFT 0 +/* Mask of GPIO input [7:0] */ +#define EC_FC_UDMA_S_PAUSE_MASK_GPIO_MASK 0x0000FF00 +#define EC_FC_UDMA_S_PAUSE_MASK_GPIO_SHIFT 8 + +/**** q_xoff_0 register ****/ +/* [i] - Mask for Q[i] */ +#define EC_FC_UDMA_Q_XOFF_0_MASK_MASK 0x0000000F +#define EC_FC_UDMA_Q_XOFF_0_MASK_SHIFT 0 + +/**** q_xoff_1 register ****/ +/* [i] - Mask for Q[i] */ +#define EC_FC_UDMA_Q_XOFF_1_MASK_MASK 0x0000000F +#define EC_FC_UDMA_Q_XOFF_1_MASK_SHIFT 0 + +/**** q_xoff_2 register ****/ +/* [i] - Mask for Q[i] */ +#define EC_FC_UDMA_Q_XOFF_2_MASK_MASK 0x0000000F +#define EC_FC_UDMA_Q_XOFF_2_MASK_SHIFT 0 + +/**** q_xoff_3 register ****/ +/* [i] - Mask for Q[i] */ +#define EC_FC_UDMA_Q_XOFF_3_MASK_MASK 0x0000000F +#define EC_FC_UDMA_Q_XOFF_3_MASK_SHIFT 0 + +/**** q_xoff_4 register ****/ +/* [i] - Mask for Q[i] */ +#define EC_FC_UDMA_Q_XOFF_4_MASK_MASK 0x0000000F +#define EC_FC_UDMA_Q_XOFF_4_MASK_SHIFT 0 + +/**** q_xoff_5 register ****/ +/* [i] - Mask for Q[i] */ +#define EC_FC_UDMA_Q_XOFF_5_MASK_MASK 0x0000000F +#define EC_FC_UDMA_Q_XOFF_5_MASK_SHIFT 0 + +/**** q_xoff_6 register ****/ +/* [i] - Mask for Q[i] */ +#define EC_FC_UDMA_Q_XOFF_6_MASK_MASK 0x0000000F +#define EC_FC_UDMA_Q_XOFF_6_MASK_SHIFT 0 + +/**** q_xoff_7 register ****/ +/* [i] - Mask for Q[i] */ +#define EC_FC_UDMA_Q_XOFF_7_MASK_MASK 0x0000000F +#define EC_FC_UDMA_Q_XOFF_7_MASK_SHIFT 0 + +/**** cfg_e register ****/ +/* Use MAC Tx FIFO empty status for EEE control. */ +#define EC_EEE_CFG_E_USE_MAC_TX_FIFO (1 << 0) +/* Use MAC Rx FIFO empty status for EEE control. */ +#define EC_EEE_CFG_E_USE_MAC_RX_FIFO (1 << 1) +/* Use Ethernet controller Tx FIFO empty status for EEE control */ +#define EC_EEE_CFG_E_USE_EC_TX_FIFO (1 << 2) +/* Use Ethernet controller Rx FIFO empty status for EEE control */ +#define EC_EEE_CFG_E_USE_EC_RX_FIFO (1 << 3) +/* Enable Low power signalling. */ +#define EC_EEE_CFG_E_ENABLE (1 << 4) +/* Mask output to MAC. */ +#define EC_EEE_CFG_E_MASK_MAC_EEE (1 << 8) +/* Mask output to stop MAC interface. */ +#define EC_EEE_CFG_E_MASK_EC_TMI_STOP (1 << 9) + +/**** stat_eee register ****/ +/* EEE state */ +#define EC_EEE_STAT_EEE_STATE_MASK 0x0000000F +#define EC_EEE_STAT_EEE_STATE_SHIFT 0 +/* EEE detected */ +#define EC_EEE_STAT_EEE_DET (1 << 4) + +/**** p_parse_cfg register ****/ +/* MAX number of beats for packet parsing */ +#define EC_MSP_P_PARSE_CFG_MAX_BEATS_MASK 0x000000FF +#define EC_MSP_P_PARSE_CFG_MAX_BEATS_SHIFT 0 +/* MAX number of parsing iterations for packet parsing */ +#define EC_MSP_P_PARSE_CFG_MAX_ITER_MASK 0x0000FF00 +#define EC_MSP_P_PARSE_CFG_MAX_ITER_SHIFT 8 + +/**** p_act_table_addr register ****/ +/* Address for accessing the table */ +#define EC_MSP_P_ACT_TABLE_ADDR_VAL_MASK 0x0000001F +#define EC_MSP_P_ACT_TABLE_ADDR_VAL_SHIFT 0 + +/**** p_act_table_data_1 register ****/ +/* Table data[5:0] - Offset to next protocol [bytes] [6] - Next ... */ +#define EC_MSP_P_ACT_TABLE_DATA_1_VAL_MASK 0x03FFFFFF +#define EC_MSP_P_ACT_TABLE_DATA_1_VAL_SHIFT 0 + +/**** p_act_table_data_2 register ****/ +/* Table data [8:0] - Offset to data in the packet [bits][17:9] ... */ +#define EC_MSP_P_ACT_TABLE_DATA_2_VAL_MASK 0x1FFFFFFF +#define EC_MSP_P_ACT_TABLE_DATA_2_VAL_SHIFT 0 + +/**** p_act_table_data_3 register ****/ +/* Table data [8:0] - Offset to data in the packet [bits] [17 ... */ +#define EC_MSP_P_ACT_TABLE_DATA_3_VAL_MASK 0x1FFFFFFF +#define EC_MSP_P_ACT_TABLE_DATA_3_VAL_SHIFT 0 + +/**** p_act_table_data_4 register ****/ +/* Table data [7:0] - Offset to the header length location in th ... */ +#define EC_MSP_P_ACT_TABLE_DATA_4_VAL_MASK 0x0FFFFFFF +#define EC_MSP_P_ACT_TABLE_DATA_4_VAL_SHIFT 0 + +/**** p_act_table_data_6 register ****/ +/* Table data [0] - Wr header length [10:1] - Write header lengt ... */ +#define EC_MSP_P_ACT_TABLE_DATA_6_VAL_MASK 0x007FFFFF +#define EC_MSP_P_ACT_TABLE_DATA_6_VAL_SHIFT 0 + +/**** p_res_in register ****/ +/* Selector for input parse_en 0 - Input vector 1 - Default valu ... */ +#define EC_MSP_P_RES_IN_SEL_PARSE_EN (1 << 0) +/* Selector for input protocol_index 0 - Input vector 1 - Defa ... */ +#define EC_MSP_P_RES_IN_SEL_PROT_INDEX (1 << 1) +/* Selector for input hdr_offset 0 - Input vector 1 - Default v ... */ +#define EC_MSP_P_RES_IN_SEL_HDR_OFFSET (1 << 2) + +/**** h_hdr_len register ****/ +/* Value for selecting table 1 */ +#define EC_MSP_P_H_HDR_LEN_TABLE_1_MASK 0x000000FF +#define EC_MSP_P_H_HDR_LEN_TABLE_1_SHIFT 0 +/* Value for selecting table 2 */ +#define EC_MSP_P_H_HDR_LEN_TABLE_2_MASK 0x00FF0000 +#define EC_MSP_P_H_HDR_LEN_TABLE_2_SHIFT 16 + +/**** p_comp_data register ****/ +/* Data 1 for comparison */ +#define EC_MSP_C_P_COMP_DATA_DATA_1_MASK 0x0000FFFF +#define EC_MSP_C_P_COMP_DATA_DATA_1_SHIFT 0 +/* Data 2 for comparison +[18:16] - Stage +[24:19] - Branch ID */ +#define EC_MSP_C_P_COMP_DATA_DATA_2_MASK 0x01FF0000 +#define EC_MSP_C_P_COMP_DATA_DATA_2_SHIFT 16 + +/**** p_comp_mask register ****/ +/* Data 1 for comparison */ +#define EC_MSP_C_P_COMP_MASK_DATA_1_MASK 0x0000FFFF +#define EC_MSP_C_P_COMP_MASK_DATA_1_SHIFT 0 +/* Data 2 for comparison +[18:16] - Stage +[24:19] - Branch ID */ +#define EC_MSP_C_P_COMP_MASK_DATA_2_MASK 0x01FF0000 +#define EC_MSP_C_P_COMP_MASK_DATA_2_SHIFT 16 + +/**** p_comp_ctrl register ****/ +/* Output result value */ +#define EC_MSP_C_P_COMP_CTRL_RES_MASK 0x0000001F +#define EC_MSP_C_P_COMP_CTRL_RES_SHIFT 0 +/* Compare command for the data_1 field 00 - Compare 01 - <= 10 ... */ +#define EC_MSP_C_P_COMP_CTRL_CMD_1_MASK 0x00030000 +#define EC_MSP_C_P_COMP_CTRL_CMD_1_SHIFT 16 +/* Compare command for the data_2 field 00 - Compare 01 - <= 10 ... */ +#define EC_MSP_C_P_COMP_CTRL_CMD_2_MASK 0x000C0000 +#define EC_MSP_C_P_COMP_CTRL_CMD_2_SHIFT 18 +/* Entry is valid */ +#define EC_MSP_C_P_COMP_CTRL_VALID (1 << 31) + +/**** wol_en register ****/ +/* Interrupt enable WoL MAC DA Unicast detected packet */ +#define EC_WOL_WOL_EN_INTRPT_EN_UNICAST (1 << 0) +/* Interrupt enable WoL L2 Multicast detected packet */ +#define EC_WOL_WOL_EN_INTRPT_EN_MULTICAST (1 << 1) +/* Interrupt enable WoL L2 Broadcast detected packet */ +#define EC_WOL_WOL_EN_INTRPT_EN_BROADCAST (1 << 2) +/* Interrupt enable WoL IPv4 detected packet */ +#define EC_WOL_WOL_EN_INTRPT_EN_IPV4 (1 << 3) +/* Interrupt enable WoL IPv6 detected packet */ +#define EC_WOL_WOL_EN_INTRPT_EN_IPV6 (1 << 4) +/* Interrupt enable WoL EtherType+MAC DA detected packet */ +#define EC_WOL_WOL_EN_INTRPT_EN_ETHERTYPE_DA (1 << 5) +/* Interrupt enable WoL EtherType+L2 Broadcast detected packet */ +#define EC_WOL_WOL_EN_INTRPT_EN_ETHERTYPE_BC (1 << 6) +/* Interrupt enable WoL parser detected packet */ +#define EC_WOL_WOL_EN_INTRPT_EN_PARSER (1 << 7) +/* Interrupt enable WoL magic detected packet */ +#define EC_WOL_WOL_EN_INTRPT_EN_MAGIC (1 << 8) +/* Interrupt enable WoL magic+password detected packet */ +#define EC_WOL_WOL_EN_INTRPT_EN_MAGIC_PSWD (1 << 9) +/* Forward enable WoL MAC DA Unicast detected packet */ +#define EC_WOL_WOL_EN_FWRD_EN_UNICAST (1 << 16) +/* Forward enable WoL L2 Multicast detected packet */ +#define EC_WOL_WOL_EN_FWRD_EN_MULTICAST (1 << 17) +/* Forward enable WoL L2 Broadcast detected packet */ +#define EC_WOL_WOL_EN_FWRD_EN_BROADCAST (1 << 18) +/* Forward enable WoL IPv4 detected packet */ +#define EC_WOL_WOL_EN_FWRD_EN_IPV4 (1 << 19) +/* Forward enable WoL IPv6 detected packet */ +#define EC_WOL_WOL_EN_FWRD_EN_IPV6 (1 << 20) +/* Forward enable WoL EtherType+MAC DA detected packet */ +#define EC_WOL_WOL_EN_FWRD_EN_ETHERTYPE_DA (1 << 21) +/* Forward enable WoL EtherType+L2 Broadcast detected packet */ +#define EC_WOL_WOL_EN_FWRD_EN_ETHERTYPE_BC (1 << 22) +/* Forward enable WoL parser detected packet */ +#define EC_WOL_WOL_EN_FWRD_EN_PARSER (1 << 23) + +/**** magic_pswd_h register ****/ +/* Password for magic_password packet detection - bits 47:32 */ +#define EC_WOL_MAGIC_PSWD_H_VAL_MASK 0x0000FFFF +#define EC_WOL_MAGIC_PSWD_H_VAL_SHIFT 0 + +/**** ethertype register ****/ +/* Configured EtherType 1 for WoL EtherType_da/EtherType_bc pack ... */ +#define EC_WOL_ETHERTYPE_VAL_1_MASK 0x0000FFFF +#define EC_WOL_ETHERTYPE_VAL_1_SHIFT 0 +/* Configured EtherType 2 for WoL EtherType_da/EtherType_bc pack ... */ +#define EC_WOL_ETHERTYPE_VAL_2_MASK 0xFFFF0000 +#define EC_WOL_ETHERTYPE_VAL_2_SHIFT 16 + +#define EC_PTH_SYSTEM_TIME_SUBSECONDS_LSB_VAL_MASK 0xFFFFC000 +#define EC_PTH_SYSTEM_TIME_SUBSECONDS_LSB_VAL_SHIFT 14 + +#define EC_PTH_CLOCK_PERIOD_LSB_VAL_MASK 0xFFFFC000 +#define EC_PTH_CLOCK_PERIOD_LSB_VAL_SHIFT 14 + +/**** int_update_ctrl register ****/ +/* This field chooses between two methods for SW to update the s ... */ +#define EC_PTH_INT_UPDATE_CTRL_UPDATE_TRIG (1 << 0) +/* 3'b000 - Set system time according to the value in {int_updat ... */ +#define EC_PTH_INT_UPDATE_CTRL_UPDATE_METHOD_MASK 0x0000000E +#define EC_PTH_INT_UPDATE_CTRL_UPDATE_METHOD_SHIFT 1 +/* 1'b1 - Next update writes to system_time_subseconds1'b0 - Nex ... */ +#define EC_PTH_INT_UPDATE_CTRL_SUBSECOND_MASK (1 << 4) +/* 1'b1 - Next update writes to system_time_seconds1'b0 - Next u ... */ +#define EC_PTH_INT_UPDATE_CTRL_SECOND_MASK (1 << 5) +/* Enabling / disabling the internal ingress trigger (ingress_tr ... */ +#define EC_PTH_INT_UPDATE_CTRL_INT_TRIG_EN (1 << 16) +/* Determines if internal ingress trigger (ingress_trigger #0) s ... */ +#define EC_PTH_INT_UPDATE_CTRL_PULSE_LEVEL_N (1 << 17) +/* Internal ingress trigger polarity (ingress_trigger #0)1'b0 - ... */ +#define EC_PTH_INT_UPDATE_CTRL_POLARITY (1 << 18) + +/**** int_update_subseconds_lsb register ****/ + +#define EC_PTH_INT_UPDATE_SUBSECONDS_LSB_RESERVED_13_0_MASK 0x00003FFF +#define EC_PTH_INT_UPDATE_SUBSECONDS_LSB_RESERVED_13_0_SHIFT 0 + +#define EC_PTH_INT_UPDATE_SUBSECONDS_LSB_VAL_MASK 0xFFFFC000 +#define EC_PTH_INT_UPDATE_SUBSECONDS_LSB_VAL_SHIFT 14 +/* 3'b000 - Set system time according to the value in {int_updat ... */ +#define EC_PTH_EXT_UPDATE_CTRL_UPDATE_METHOD_MASK 0x0000000E +#define EC_PTH_EXT_UPDATE_CTRL_UPDATE_METHOD_SHIFT 1 +/* 1'b1 - next update writes to system_time_subseconds1'b0 - nex ... */ +#define EC_PTH_EXT_UPDATE_CTRL_SUBSECOND_MASK (1 << 4) +/* 1'b1 - Next update writes to system_time_seconds1'b0 - Next u ... */ +#define EC_PTH_EXT_UPDATE_CTRL_SECOND_MASK (1 << 5) +/* Enabling / disabling the external ingress triggers (ingress_t ... */ +#define EC_PTH_EXT_UPDATE_CTRL_EXT_TRIG_EN_MASK 0x00001F00 +#define EC_PTH_EXT_UPDATE_CTRL_EXT_TRIG_EN_SHIFT 8 +/* Determines if external ingress triggers (ingress_triggers #1- ... */ +#define EC_PTH_EXT_UPDATE_CTRL_PULSE_LEVEL_N_MASK 0x001F0000 +#define EC_PTH_EXT_UPDATE_CTRL_PULSE_LEVEL_N_SHIFT 16 +/* bit-field configurations of external ingress trigger polarity ... */ +#define EC_PTH_EXT_UPDATE_CTRL_POLARITY_MASK 0x1F000000 +#define EC_PTH_EXT_UPDATE_CTRL_POLARITY_SHIFT 24 + +/**** ext_update_subseconds_lsb register ****/ + +#define EC_PTH_EXT_UPDATE_SUBSECONDS_LSB_RESERVED_13_0_MASK 0x00003FFF +#define EC_PTH_EXT_UPDATE_SUBSECONDS_LSB_RESERVED_13_0_SHIFT 0 + +#define EC_PTH_EXT_UPDATE_SUBSECONDS_LSB_VAL_MASK 0xFFFFC000 +#define EC_PTH_EXT_UPDATE_SUBSECONDS_LSB_VAL_SHIFT 14 + +#define EC_PTH_READ_COMPENSATION_SUBSECONDS_LSB_VAL_MASK 0xFFFFC000 +#define EC_PTH_READ_COMPENSATION_SUBSECONDS_LSB_VAL_SHIFT 14 + +#define EC_PTH_INT_WRITE_COMPENSATION_SUBSECONDS_LSB_VAL_MASK 0xFFFFC000 +#define EC_PTH_INT_WRITE_COMPENSATION_SUBSECONDS_LSB_VAL_SHIFT 14 + +#define EC_PTH_EXT_WRITE_COMPENSATION_SUBSECONDS_LSB_VAL_MASK 0xFFFFC000 +#define EC_PTH_EXT_WRITE_COMPENSATION_SUBSECONDS_LSB_VAL_SHIFT 14 + +#define EC_PTH_SYNC_COMPENSATION_SUBSECONDS_LSB_VAL_MASK 0xFFFFC000 +#define EC_PTH_SYNC_COMPENSATION_SUBSECONDS_LSB_VAL_SHIFT 14 + +/**** trigger_ctrl register ****/ +/* Enabling / disabling the egress trigger1'b1 - Enabled1'b0 - D ... */ +#define EC_PTH_EGRESS_TRIGGER_CTRL_EN (1 << 0) +/* Configuration that determines if the egress trigger is a peri ... */ +#define EC_PTH_EGRESS_TRIGGER_CTRL_PERIODIC (1 << 1) +/* Configuration of egress trigger polarity */ +#define EC_PTH_EGRESS_TRIGGER_CTRL_POLARITY (1 << 2) +/* If the pulse is marked as periodic (see periodic field), this ... */ +#define EC_PTH_EGRESS_TRIGGER_CTRL_PERIOD_SUBSEC_MASK 0x00FFFFF0 +#define EC_PTH_EGRESS_TRIGGER_CTRL_PERIOD_SUBSEC_SHIFT 4 +/* If the pulse is marked as periodic (see periodic field), this ... */ +#define EC_PTH_EGRESS_TRIGGER_CTRL_PERIOD_SEC_MASK 0xFF000000 +#define EC_PTH_EGRESS_TRIGGER_CTRL_PERIOD_SEC_SHIFT 24 + +/**** trigger_subseconds_lsb register ****/ + +#define EC_PTH_EGRESS_TRIGGER_SUBSECONDS_LSB_RESERVED_13_0_MASK 0x00003FFF +#define EC_PTH_EGRESS_TRIGGER_SUBSECONDS_LSB_RESERVED_13_0_SHIFT 0 + +#define EC_PTH_EGRESS_TRIGGER_SUBSECONDS_LSB_VAL_MASK 0xFFFFC000 +#define EC_PTH_EGRESS_TRIGGER_SUBSECONDS_LSB_VAL_SHIFT 14 + +/**** pulse_width_subseconds_lsb register ****/ + +#define EC_PTH_EGRESS_PULSE_WIDTH_SUBSECONDS_LSB_RESERVED_13_0_MASK 0x00003FFF +#define EC_PTH_EGRESS_PULSE_WIDTH_SUBSECONDS_LSB_RESERVED_13_0_SHIFT 0 + +#define EC_PTH_EGRESS_PULSE_WIDTH_SUBSECONDS_LSB_VAL_MASK 0xFFFFC000 +#define EC_PTH_EGRESS_PULSE_WIDTH_SUBSECONDS_LSB_VAL_SHIFT 14 + +/**** qual register ****/ + +#define EC_PTH_DB_QUAL_TS_VALID (1 << 0) + +#define EC_PTH_DB_QUAL_RESERVED_31_1_MASK 0xFFFFFFFE +#define EC_PTH_DB_QUAL_RESERVED_31_1_SHIFT 1 + +/**** rx_comp_desc register ****/ +/* Selection for word0[13]:0- legacy SR-A01- per generic protoco ... */ +#define EC_GEN_V3_RX_COMP_DESC_W0_L3_CKS_RES_SEL (1 << 0) +/* Selection for word0[14]:0- legacy SR-A01- per generic protoco ... */ +#define EC_GEN_V3_RX_COMP_DESC_W0_L4_CKS_RES_SEL (1 << 1) +/* Selection for word3[29]:0-macsec decryption status[13] (legac ... */ +#define EC_GEN_V3_RX_COMP_DESC_W3_DEC_STAT_13_L4_CKS_RES_SEL (1 << 8) +/* Selection for word3[30]:0-macsec decryption status[14] (legac ... */ +#define EC_GEN_V3_RX_COMP_DESC_W3_DEC_STAT_14_L3_CKS_RES_SEL (1 << 9) +/* Selection for word3[31]:0-macsec decryption status[15] (legac ... */ +#define EC_GEN_V3_RX_COMP_DESC_W3_DEC_STAT_15_CRC_RES_SEL (1 << 10) +/* Selection for word 0 [6:5], source VLAN count0- source vlan c ... */ +#define EC_GEN_V3_RX_COMP_DESC_W0_SRC_VLAN_CNT (1 << 12) +/* Selection for word 0 [4:0], l3 protocol index0- l3 protocol ... */ +#define EC_GEN_V3_RX_COMP_DESC_W0_L3_PROT_INDEX (1 << 13) +/* Selection for word 1 [31:16], lP fragment checksum0- IP frag ... */ +#define EC_GEN_V3_RX_COMP_DESC_W1_IP_FRAG_CHECKSUM (1 << 14) +/* Selection for word 2 [15:9], L3 offset0- LL3 offset1- CRC re ... */ +#define EC_GEN_V3_RX_COMP_DESC_W2_L3_OFFSET (1 << 15) +/* Selection for word 2 [8:0], tunnel offset0- tunnel offset1- ... */ +#define EC_GEN_V3_RX_COMP_DESC_W2_TUNNEL_OFFSET (1 << 16) + +/**** conf register ****/ +/* Valid signal configuration when in loopback mode:00 - valid f ... */ +#define EC_GEN_V3_CONF_MAC_LB_EC_OUT_S_VALID_CFG_MASK 0x00000003 +#define EC_GEN_V3_CONF_MAC_LB_EC_OUT_S_VALID_CFG_SHIFT 0 +/* Valid signal configuration when in loopback mode:00 – valid f ... */ +#define EC_GEN_V3_CONF_MAC_LB_EC_IN_S_VALID_CFG_MASK 0x0000000C +#define EC_GEN_V3_CONF_MAC_LB_EC_IN_S_VALID_CFG_SHIFT 2 + +/**** tx_gpd_cam_addr register ****/ +/* Cam compare table address */ +#define EC_TFW_V3_TX_GPD_CAM_ADDR_VAL_MASK 0x0000001F +#define EC_TFW_V3_TX_GPD_CAM_ADDR_VAL_SHIFT 0 +/* cam entry is valid */ +#define EC_TFW_V3_TX_GPD_CAM_CTRL_VALID (1 << 31) + +/**** tx_gcp_legacy register ****/ +/* 0-choose parameters from table1- choose legacy crce roce para ... */ +#define EC_TFW_V3_TX_GCP_LEGACY_PARAM_SEL (1 << 0) + +/**** tx_gcp_table_addr register ****/ +/* parametrs table address */ +#define EC_TFW_V3_TX_GCP_TABLE_ADDR_VAL_MASK 0x0000001F +#define EC_TFW_V3_TX_GCP_TABLE_ADDR_VAL_SHIFT 0 + +/**** tx_gcp_table_gen register ****/ +/* polynomial selcet +0-crc32(0x104C11DB7) +1-crc32c(0x11EDC6F41) */ +#define EC_TFW_V3_TX_GCP_TABLE_GEN_POLY_SEL (1 << 0) +/* Enable bit complement on crc result */ +#define EC_TFW_V3_TX_GCP_TABLE_GEN_CRC32_BIT_COMP (1 << 1) +/* Enable bit swap on crc result */ +#define EC_TFW_V3_TX_GCP_TABLE_GEN_CRC32_BIT_SWAP (1 << 2) +/* Enable byte swap on crc result */ +#define EC_TFW_V3_TX_GCP_TABLE_GEN_CRC32_BYTE_SWAP (1 << 3) +/* Enable bit swap on input data */ +#define EC_TFW_V3_TX_GCP_TABLE_GEN_DATA_BIT_SWAP (1 << 4) +/* Enable byte swap on input data */ +#define EC_TFW_V3_TX_GCP_TABLE_GEN_DATA_BYTE_SWAP (1 << 5) +/* Number of bytes in trailer which are not part of crc calculat ... */ +#define EC_TFW_V3_TX_GCP_TABLE_GEN_TRAIL_SIZE_MASK 0x000003C0 +#define EC_TFW_V3_TX_GCP_TABLE_GEN_TRAIL_SIZE_SHIFT 6 +/* Number of bytes in header which are not part of crc calculati ... */ +#define EC_TFW_V3_TX_GCP_TABLE_GEN_HEAD_SIZE_MASK 0x00FF0000 +#define EC_TFW_V3_TX_GCP_TABLE_GEN_HEAD_SIZE_SHIFT 16 +/* corrected offset calculation0- subtract head_size (roce)1- ad ... */ +#define EC_TFW_V3_TX_GCP_TABLE_GEN_HEAD_CALC (1 << 24) +/* 0-replace masked bits with 01-replace masked bits with 1 (roc ... */ +#define EC_TFW_V3_TX_GCP_TABLE_GEN_MASK_POLARITY (1 << 25) + +/**** tx_gcp_table_res register ****/ +/* Not in use */ +#define EC_TFW_V3_TX_GCP_TABLE_RES_SEL_MASK 0x0000001F +#define EC_TFW_V3_TX_GCP_TABLE_RES_SEL_SHIFT 0 +/* Not in use */ +#define EC_TFW_V3_TX_GCP_TABLE_RES_EN (1 << 5) +/* Not in use */ +#define EC_TFW_V3_TX_GCP_TABLE_RES_DEF (1 << 6) + +/**** tx_gcp_table_alu_opcode register ****/ +/* first opcode +e.g. (A op1 B) op3 (C op2 D) */ +#define EC_TFW_V3_TX_GCP_TABLE_ALU_OPCODE_OPCODE_1_MASK 0x0000003F +#define EC_TFW_V3_TX_GCP_TABLE_ALU_OPCODE_OPCODE_1_SHIFT 0 +/* second opcode +e.g. (A op1 B) op3 (C op2 D) */ +#define EC_TFW_V3_TX_GCP_TABLE_ALU_OPCODE_OPCODE_2_MASK 0x00000FC0 +#define EC_TFW_V3_TX_GCP_TABLE_ALU_OPCODE_OPCODE_2_SHIFT 6 +/* third opcode +e.g. (A op1 B) op3 (C op2 D) */ +#define EC_TFW_V3_TX_GCP_TABLE_ALU_OPCODE_OPCODE_3_MASK 0x0003F000 +#define EC_TFW_V3_TX_GCP_TABLE_ALU_OPCODE_OPCODE_3_SHIFT 12 + +/**** tx_gcp_table_alu_opsel register ****/ +/* frst opsel, input selection */ +#define EC_TFW_V3_TX_GCP_TABLE_ALU_OPSEL_OPSEL_1_MASK 0x0000000F +#define EC_TFW_V3_TX_GCP_TABLE_ALU_OPSEL_OPSEL_1_SHIFT 0 +/* second opsel, input selection */ +#define EC_TFW_V3_TX_GCP_TABLE_ALU_OPSEL_OPSEL_2_MASK 0x000000F0 +#define EC_TFW_V3_TX_GCP_TABLE_ALU_OPSEL_OPSEL_2_SHIFT 4 +/* third opsel, input selction */ +#define EC_TFW_V3_TX_GCP_TABLE_ALU_OPSEL_OPSEL_3_MASK 0x00000F00 +#define EC_TFW_V3_TX_GCP_TABLE_ALU_OPSEL_OPSEL_3_SHIFT 8 +/* fourth opsel, input selction */ +#define EC_TFW_V3_TX_GCP_TABLE_ALU_OPSEL_OPSEL_4_MASK 0x0000F000 +#define EC_TFW_V3_TX_GCP_TABLE_ALU_OPSEL_OPSEL_4_SHIFT 12 + +/**** tx_gcp_table_alu_val register ****/ +/* value for alu input */ +#define EC_TFW_V3_TX_GCP_TABLE_ALU_VAL_VAL_MASK 0x000001FF +#define EC_TFW_V3_TX_GCP_TABLE_ALU_VAL_VAL_SHIFT 0 + +/**** crc_csum_replace register ****/ +/* 0- use table +1- legacy SR-A0 */ +#define EC_TFW_V3_CRC_CSUM_REPLACE_L3_CSUM_LEGACY_SEL (1 << 0) +/* 0- use table +1- legacy SR-A0 */ +#define EC_TFW_V3_CRC_CSUM_REPLACE_L4_CSUM_LEGACY_SEL (1 << 1) +/* 0- use table +1- legacy SR-A0 */ +#define EC_TFW_V3_CRC_CSUM_REPLACE_CRC_LEGACY_SEL (1 << 2) + +/**** crc_csum_replace_table_addr register ****/ +/* parametrs table address */ +#define EC_TFW_V3_CRC_CSUM_REPLACE_TABLE_ADDR_VAL_MASK 0x0000007F +#define EC_TFW_V3_CRC_CSUM_REPLACE_TABLE_ADDR_VAL_SHIFT 0 + +/**** crc_csum_replace_table register ****/ +/* L3 Checksum replace enable */ +#define EC_TFW_V3_CRC_CSUM_REPLACE_TABLE_L3_CSUM_EN (1 << 0) +/* L4 Checksum replace enable */ +#define EC_TFW_V3_CRC_CSUM_REPLACE_TABLE_L4_CSUM_EN (1 << 1) +/* CRC replace enable */ +#define EC_TFW_V3_CRC_CSUM_REPLACE_TABLE_CRC_EN (1 << 2) + +/**** rx_gpd_cam_addr register ****/ +/* Cam compare table address */ +#define EC_RFW_V3_RX_GPD_CAM_ADDR_VAL_MASK 0x0000001F +#define EC_RFW_V3_RX_GPD_CAM_ADDR_VAL_SHIFT 0 +/* cam entry is valid */ +#define EC_RFW_V3_RX_GPD_CAM_CTRL_VALID (1 << 31) + +/**** gpd_p1 register ****/ +/* Location in bytes of the gpd cam data1 in the parser result v ... */ +#define EC_RFW_V3_GPD_P1_OFFSET_MASK 0x000003FF +#define EC_RFW_V3_GPD_P1_OFFSET_SHIFT 0 + +/**** gpd_p2 register ****/ +/* Location in bytes of the gpd cam data2 in the parser result v ... */ +#define EC_RFW_V3_GPD_P2_OFFSET_MASK 0x000003FF +#define EC_RFW_V3_GPD_P2_OFFSET_SHIFT 0 + +/**** gpd_p3 register ****/ +/* Location in bytes of the gpd cam data3 in the parser result v ... */ +#define EC_RFW_V3_GPD_P3_OFFSET_MASK 0x000003FF +#define EC_RFW_V3_GPD_P3_OFFSET_SHIFT 0 + +/**** gpd_p4 register ****/ +/* Location in bytes of the gpd cam data4 in the parser result v ... */ +#define EC_RFW_V3_GPD_P4_OFFSET_MASK 0x000003FF +#define EC_RFW_V3_GPD_P4_OFFSET_SHIFT 0 + +/**** gpd_p5 register ****/ +/* Location in bytes of the gpd cam data5 in the parser result v ... */ +#define EC_RFW_V3_GPD_P5_OFFSET_MASK 0x000003FF +#define EC_RFW_V3_GPD_P5_OFFSET_SHIFT 0 + +/**** gpd_p6 register ****/ +/* Location in bytes of the gpd cam data6 in the parser result v ... */ +#define EC_RFW_V3_GPD_P6_OFFSET_MASK 0x000003FF +#define EC_RFW_V3_GPD_P6_OFFSET_SHIFT 0 + +/**** gpd_p7 register ****/ +/* Location in bytes of the gpd cam data7 in the parser result v ... */ +#define EC_RFW_V3_GPD_P7_OFFSET_MASK 0x000003FF +#define EC_RFW_V3_GPD_P7_OFFSET_SHIFT 0 + +/**** gpd_p8 register ****/ +/* Location in bytes of the gpd cam data8 in the parser result v ... */ +#define EC_RFW_V3_GPD_P8_OFFSET_MASK 0x000003FF +#define EC_RFW_V3_GPD_P8_OFFSET_SHIFT 0 + +/**** rx_gcp_legacy register ****/ +/* 0-choose parameters from table1- choose legacy crce roce para ... */ +#define EC_RFW_V3_RX_GCP_LEGACY_PARAM_SEL (1 << 0) + +/**** rx_gcp_table_addr register ****/ +/* parametrs table address */ +#define EC_RFW_V3_RX_GCP_TABLE_ADDR_VAL_MASK 0x0000001F +#define EC_RFW_V3_RX_GCP_TABLE_ADDR_VAL_SHIFT 0 + +/**** rx_gcp_table_gen register ****/ +/* polynomial selcet +0-crc32(0x104C11DB7) +1-crc32c(0x11EDC6F41) */ +#define EC_RFW_V3_RX_GCP_TABLE_GEN_POLY_SEL (1 << 0) +/* Enable bit complement on crc result */ +#define EC_RFW_V3_RX_GCP_TABLE_GEN_CRC32_BIT_COMP (1 << 1) +/* Enable bit swap on crc result */ +#define EC_RFW_V3_RX_GCP_TABLE_GEN_CRC32_BIT_SWAP (1 << 2) +/* Enable byte swap on crc result */ +#define EC_RFW_V3_RX_GCP_TABLE_GEN_CRC32_BYTE_SWAP (1 << 3) +/* Enable bit swap on input data */ +#define EC_RFW_V3_RX_GCP_TABLE_GEN_DATA_BIT_SWAP (1 << 4) +/* Enable byte swap on input data */ +#define EC_RFW_V3_RX_GCP_TABLE_GEN_DATA_BYTE_SWAP (1 << 5) +/* Number of bytes in trailer which are not part of crc calculat ... */ +#define EC_RFW_V3_RX_GCP_TABLE_GEN_TRAIL_SIZE_MASK 0x000003C0 +#define EC_RFW_V3_RX_GCP_TABLE_GEN_TRAIL_SIZE_SHIFT 6 +/* Number of bytes in header which are not part of crc calculati ... */ +#define EC_RFW_V3_RX_GCP_TABLE_GEN_HEAD_SIZE_MASK 0x00FF0000 +#define EC_RFW_V3_RX_GCP_TABLE_GEN_HEAD_SIZE_SHIFT 16 +/* corrected offset calculation0- subtract head_size (roce)1- ad ... */ +#define EC_RFW_V3_RX_GCP_TABLE_GEN_HEAD_CALC (1 << 24) +/* 0-replace masked bits with 01-replace masked bits with 1 (roc ... */ +#define EC_RFW_V3_RX_GCP_TABLE_GEN_MASK_POLARITY (1 << 25) + +/**** rx_gcp_table_res register ****/ +/* Bit mask for crc/checksum result options for metadata W0[13][ ... */ +#define EC_RFW_V3_RX_GCP_TABLE_RES_SEL_0_MASK 0x0000001F +#define EC_RFW_V3_RX_GCP_TABLE_RES_SEL_0_SHIFT 0 +/* Bit mask for crc/checksum result options for metadata W0[14][ ... */ +#define EC_RFW_V3_RX_GCP_TABLE_RES_SEL_1_MASK 0x000003E0 +#define EC_RFW_V3_RX_GCP_TABLE_RES_SEL_1_SHIFT 5 +/* Bit mask for crc/checksum result options for metadata W3[29][ ... */ +#define EC_RFW_V3_RX_GCP_TABLE_RES_SEL_2_MASK 0x00007C00 +#define EC_RFW_V3_RX_GCP_TABLE_RES_SEL_2_SHIFT 10 +/* Bit mask for crc/checksum result options for metadata W3[30][ ... */ +#define EC_RFW_V3_RX_GCP_TABLE_RES_SEL_3_MASK 0x000F8000 +#define EC_RFW_V3_RX_GCP_TABLE_RES_SEL_3_SHIFT 15 +/* Bit mask for crc/checksum result options for metadata W3[31][ ... */ +#define EC_RFW_V3_RX_GCP_TABLE_RES_SEL_4_MASK 0x01F00000 +#define EC_RFW_V3_RX_GCP_TABLE_RES_SEL_4_SHIFT 20 +/* enable crc result check */ +#define EC_RFW_V3_RX_GCP_TABLE_RES_EN (1 << 25) +/* default value for crc check for non-crc protocol */ +#define EC_RFW_V3_RX_GCP_TABLE_RES_DEF (1 << 26) + +/**** rx_gcp_table_alu_opcode register ****/ +/* first opcode +e.g. (A op1 B) op3 (C op2 D) */ +#define EC_RFW_V3_RX_GCP_TABLE_ALU_OPCODE_OPCODE_1_MASK 0x0000003F +#define EC_RFW_V3_RX_GCP_TABLE_ALU_OPCODE_OPCODE_1_SHIFT 0 +/* second opcode +e.g. (A op1 B) op3 (C op2 D) */ +#define EC_RFW_V3_RX_GCP_TABLE_ALU_OPCODE_OPCODE_2_MASK 0x00000FC0 +#define EC_RFW_V3_RX_GCP_TABLE_ALU_OPCODE_OPCODE_2_SHIFT 6 +/* third opcode +e.g. (A op1 B) op3 (C op2 D) */ +#define EC_RFW_V3_RX_GCP_TABLE_ALU_OPCODE_OPCODE_3_MASK 0x0003F000 +#define EC_RFW_V3_RX_GCP_TABLE_ALU_OPCODE_OPCODE_3_SHIFT 12 + +/**** rx_gcp_table_alu_opsel register ****/ +/* frst opsel, input selection */ +#define EC_RFW_V3_RX_GCP_TABLE_ALU_OPSEL_OPSEL_1_MASK 0x0000000F +#define EC_RFW_V3_RX_GCP_TABLE_ALU_OPSEL_OPSEL_1_SHIFT 0 +/* second opsel, input selection */ +#define EC_RFW_V3_RX_GCP_TABLE_ALU_OPSEL_OPSEL_2_MASK 0x000000F0 +#define EC_RFW_V3_RX_GCP_TABLE_ALU_OPSEL_OPSEL_2_SHIFT 4 +/* third opsel, input selction */ +#define EC_RFW_V3_RX_GCP_TABLE_ALU_OPSEL_OPSEL_3_MASK 0x00000F00 +#define EC_RFW_V3_RX_GCP_TABLE_ALU_OPSEL_OPSEL_3_SHIFT 8 +/* fourth opsel, input selction */ +#define EC_RFW_V3_RX_GCP_TABLE_ALU_OPSEL_OPSEL_4_MASK 0x0000F000 +#define EC_RFW_V3_RX_GCP_TABLE_ALU_OPSEL_OPSEL_4_SHIFT 12 + +/**** rx_gcp_table_alu_val register ****/ +/* value for alu input */ +#define EC_RFW_V3_RX_GCP_TABLE_ALU_VAL_VAL_MASK 0x000001FF +#define EC_RFW_V3_RX_GCP_TABLE_ALU_VAL_VAL_SHIFT 0 + +/**** rx_gcp_alu_p1 register ****/ +/* Location in bytes of field 1 in the parser result vector */ +#define EC_RFW_V3_RX_GCP_ALU_P1_OFFSET_MASK 0x000003FF +#define EC_RFW_V3_RX_GCP_ALU_P1_OFFSET_SHIFT 0 +/* Right shift for field 1 in the parser result vector */ +#define EC_RFW_V3_RX_GCP_ALU_P1_SHIFT_MASK 0x000F0000 +#define EC_RFW_V3_RX_GCP_ALU_P1_SHIFT_SHIFT 16 + +/**** rx_gcp_alu_p2 register ****/ +/* Location in bytes of field 2 in the parser result vector */ +#define EC_RFW_V3_RX_GCP_ALU_P2_OFFSET_MASK 0x000003FF +#define EC_RFW_V3_RX_GCP_ALU_P2_OFFSET_SHIFT 0 +/* Right shift for field 2 in the parser result vector */ +#define EC_RFW_V3_RX_GCP_ALU_P2_SHIFT_MASK 0x000F0000 +#define EC_RFW_V3_RX_GCP_ALU_P2_SHIFT_SHIFT 16 + +/**** hs_ctrl_table_addr register ****/ +/* Header split control table address */ +#define EC_RFW_V3_HS_CTRL_TABLE_ADDR_VAL_MASK 0x000000FF +#define EC_RFW_V3_HS_CTRL_TABLE_ADDR_VAL_SHIFT 0 + +/**** hs_ctrl_table register ****/ +/* Header split length select */ +#define EC_RFW_V3_HS_CTRL_TABLE_SEL_MASK 0x00000003 +#define EC_RFW_V3_HS_CTRL_TABLE_SEL_SHIFT 0 +/* enable header split */ +#define EC_RFW_V3_HS_CTRL_TABLE_ENABLE (1 << 2) + +/**** hs_ctrl_table_alu_opcode register ****/ +/* first opcode +e.g. (A op1 B) op3 (C op2 D) */ +#define EC_RFW_V3_HS_CTRL_TABLE_ALU_OPCODE_OPCODE_1_MASK 0x0000003F +#define EC_RFW_V3_HS_CTRL_TABLE_ALU_OPCODE_OPCODE_1_SHIFT 0 +/* second opcode +e.g. (A op1 B) op3 (C op2 D) */ +#define EC_RFW_V3_HS_CTRL_TABLE_ALU_OPCODE_OPCODE_2_MASK 0x00000FC0 +#define EC_RFW_V3_HS_CTRL_TABLE_ALU_OPCODE_OPCODE_2_SHIFT 6 +/* third opcode +e.g. (A op1 B) op3 (C op2 D) */ +#define EC_RFW_V3_HS_CTRL_TABLE_ALU_OPCODE_OPCODE_3_MASK 0x0003F000 +#define EC_RFW_V3_HS_CTRL_TABLE_ALU_OPCODE_OPCODE_3_SHIFT 12 + +/**** hs_ctrl_table_alu_opsel register ****/ +/* frst opsel, input selection */ +#define EC_RFW_V3_HS_CTRL_TABLE_ALU_OPSEL_OPSEL_1_MASK 0x0000000F +#define EC_RFW_V3_HS_CTRL_TABLE_ALU_OPSEL_OPSEL_1_SHIFT 0 +/* second opsel, input selection */ +#define EC_RFW_V3_HS_CTRL_TABLE_ALU_OPSEL_OPSEL_2_MASK 0x000000F0 +#define EC_RFW_V3_HS_CTRL_TABLE_ALU_OPSEL_OPSEL_2_SHIFT 4 +/* third opsel, input selction */ +#define EC_RFW_V3_HS_CTRL_TABLE_ALU_OPSEL_OPSEL_3_MASK 0x00000F00 +#define EC_RFW_V3_HS_CTRL_TABLE_ALU_OPSEL_OPSEL_3_SHIFT 8 +/* fourth opsel, input selction */ +#define EC_RFW_V3_HS_CTRL_TABLE_ALU_OPSEL_OPSEL_4_MASK 0x0000F000 +#define EC_RFW_V3_HS_CTRL_TABLE_ALU_OPSEL_OPSEL_4_SHIFT 12 + +/**** hs_ctrl_table_alu_val register ****/ +/* value for alu input */ +#define EC_RFW_V3_HS_CTRL_TABLE_ALU_VAL_VAL_MASK 0x0000FFFF +#define EC_RFW_V3_HS_CTRL_TABLE_ALU_VAL_VAL_SHIFT 0 + +/**** hs_ctrl_cfg register ****/ +/* Header split enable static selction0 – legacy1 – header split ... */ +#define EC_RFW_V3_HS_CTRL_CFG_ENABLE_SEL (1 << 0) +/* Header split length static selction0 – legacy1 – header split ... */ +#define EC_RFW_V3_HS_CTRL_CFG_LENGTH_SEL (1 << 1) + +/**** hs_ctrl_alu_p1 register ****/ +/* Location in bytes of field 1 in the parser result vector */ +#define EC_RFW_V3_HS_CTRL_ALU_P1_OFFSET_MASK 0x000003FF +#define EC_RFW_V3_HS_CTRL_ALU_P1_OFFSET_SHIFT 0 +/* Right shift for field 1 in the parser result vector */ +#define EC_RFW_V3_HS_CTRL_ALU_P1_SHIFT_MASK 0x000F0000 +#define EC_RFW_V3_HS_CTRL_ALU_P1_SHIFT_SHIFT 16 + +/**** hs_ctrl_alu_p2 register ****/ +/* Location in bytes of field 2 in the parser result vector */ +#define EC_RFW_V3_HS_CTRL_ALU_P2_OFFSET_MASK 0x000003FF +#define EC_RFW_V3_HS_CTRL_ALU_P2_OFFSET_SHIFT 0 +/* Right shift for field 2 in the parser result vector */ +#define EC_RFW_V3_HS_CTRL_ALU_P2_SHIFT_MASK 0x000F0000 +#define EC_RFW_V3_HS_CTRL_ALU_P2_SHIFT_SHIFT 16 + +/**** tx_config register ****/ +/* [0] pre increment word swap[1] pre increment byte swap[2] pre ... */ +#define EC_CRYPTO_TX_CONFIG_TWEAK_ENDIANITY_SWAP_MASK 0x0000003F +#define EC_CRYPTO_TX_CONFIG_TWEAK_ENDIANITY_SWAP_SHIFT 0 +/* [0] pre encryption word swap[1] pre encryption byte swap[2] p ... */ +#define EC_CRYPTO_TX_CONFIG_DATA_ENDIANITY_SWAP_MASK 0x00003F00 +#define EC_CRYPTO_TX_CONFIG_DATA_ENDIANITY_SWAP_SHIFT 8 +/* direction flip, used in order to use same TID entry for both TX & RX traffic */ +#define EC_CRYPTO_TX_CONFIG_CRYPTO_DIR_FLIP (1 << 14) +/* Enabling pipe line optimization */ +#define EC_CRYPTO_TX_CONFIG_PIPE_CALC_EN (1 << 16) +/* enable performance counters */ +#define EC_CRYPTO_TX_CONFIG_PERF_CNT_EN (1 << 17) +/* [0] pre aes word swap[1] pre aes byte swap[2] pre aes bit swa ... */ +#define EC_CRYPTO_TX_CONFIG_AES_ENDIANITY_SWAP_MASK 0x03F00000 +#define EC_CRYPTO_TX_CONFIG_AES_ENDIANITY_SWAP_SHIFT 20 +/* [0] pre aes key word swap[1] pre aes key byte swap[2] pre aes ... */ +#define EC_CRYPTO_TX_CONFIG_AES_KEY_ENDIANITY_SWAP_MASK 0xFC000000 +#define EC_CRYPTO_TX_CONFIG_AES_KEY_ENDIANITY_SWAP_SHIFT 26 + +/**** rx_config register ****/ +/* [0] pre increment word swap[1] pre increment byte swap[2] pre ... */ +#define EC_CRYPTO_RX_CONFIG_TWEAK_ENDIANITY_SWAP_MASK 0x0000003F +#define EC_CRYPTO_RX_CONFIG_TWEAK_ENDIANITY_SWAP_SHIFT 0 +/* [0] pre encryption word swap[1] pre encryption byte swap[2] p ... */ +#define EC_CRYPTO_RX_CONFIG_DATA_ENDIANITY_SWAP_MASK 0x00003F00 +#define EC_CRYPTO_RX_CONFIG_DATA_ENDIANITY_SWAP_SHIFT 8 +/* direction flip, used in order to use same TID entry for both TX & RX traffic */ +#define EC_CRYPTO_RX_CONFIG_CRYPTO_DIR_FLIP (1 << 14) +/* Enabling pipe line optimization */ +#define EC_CRYPTO_RX_CONFIG_PIPE_CALC_EN (1 << 16) +/* enable performance counters */ +#define EC_CRYPTO_RX_CONFIG_PERF_CNT_EN (1 << 17) +/* [0] pre aes word swap[1] pre aes byte swap[2] pre aes bit swa ... */ +#define EC_CRYPTO_RX_CONFIG_AES_ENDIANITY_SWAP_MASK 0x03F00000 +#define EC_CRYPTO_RX_CONFIG_AES_ENDIANITY_SWAP_SHIFT 20 +/* [0] data aes key word swap[1] data aes key byte swap[2] data ... */ +#define EC_CRYPTO_RX_CONFIG_AES_KEY_ENDIANITY_SWAP_MASK 0xFC000000 +#define EC_CRYPTO_RX_CONFIG_AES_KEY_ENDIANITY_SWAP_SHIFT 26 + +/**** tx_override register ****/ +/* all transactions are encrypted */ +#define EC_CRYPTO_TX_OVERRIDE_ENCRYPT_ONLY (1 << 0) +/* all transactions are decrypted */ +#define EC_CRYPTO_TX_OVERRIDE_DECRYPT_ONLY (1 << 1) +/* all pkts use IV */ +#define EC_CRYPTO_TX_OVERRIDE_ALWAYS_DRIVE_IV (1 << 2) +/* no pkt uses IV */ +#define EC_CRYPTO_TX_OVERRIDE_NEVER_DRIVE_IV (1 << 3) +/* all pkts perform authentication calculation */ +#define EC_CRYPTO_TX_OVERRIDE_ALWAYS_PERFORM_SIGN (1 << 4) +/* no pkt performs authentication calculation */ +#define EC_CRYPTO_TX_OVERRIDE_NEVER_PERFORM_SIGN (1 << 5) +/* all pkts perform encryption calculation */ +#define EC_CRYPTO_TX_OVERRIDE_ALWAYS_PERFORM_ENC (1 << 6) +/* no pkt performs encryption calculation */ +#define EC_CRYPTO_TX_OVERRIDE_NEVER_PERFORM_ENC (1 << 7) +/* Enforce pkt trimming +bit[0] relates to metadata_pkt_trim +bit[1] relates to trailer_pkt_trime +bit[2] relates to sign_trim +bit[3] relates to aes_padding_trim */ +#define EC_CRYPTO_TX_OVERRIDE_ALWAYS_BYPASS_PKT_TRIM_MASK 0x00000F00 +#define EC_CRYPTO_TX_OVERRIDE_ALWAYS_BYPASS_PKT_TRIM_SHIFT 8 +/* Enforce no pkt trimming +bit[0] relates to metadata_pkt_trim +bit[1] relates to trailer_pkt_trime +bit[2] relates to sign_trim +bit[3] relates to aes_padding_trim */ +#define EC_CRYPTO_TX_OVERRIDE_NEVER_BYPASS_PKT_TRIM_MASK 0x0000F000 +#define EC_CRYPTO_TX_OVERRIDE_NEVER_BYPASS_PKT_TRIM_SHIFT 12 +/* chicken bit to disable metadata handling optimization */ +#define EC_CRYPTO_TX_OVERRIDE_EXPLICIT_METADATA_STAGE (1 << 16) + +/**** rx_override register ****/ +/* all transactions are encrypted */ +#define EC_CRYPTO_RX_OVERRIDE_ENCRYPT_ONLY (1 << 0) +/* all transactions are decrypted */ +#define EC_CRYPTO_RX_OVERRIDE_DECRYPT_ONLY (1 << 1) +/* all pkts use IV */ +#define EC_CRYPTO_RX_OVERRIDE_ALWAYS_DRIVE_IV (1 << 2) +/* no pkt uses IV */ +#define EC_CRYPTO_RX_OVERRIDE_NEVER_DRIVE_IV (1 << 3) +/* all pkts perform authentication calculation */ +#define EC_CRYPTO_RX_OVERRIDE_ALWAYS_PERFORM_SIGN (1 << 4) +/* no pkt performs authentication calculation */ +#define EC_CRYPTO_RX_OVERRIDE_NEVER_PERFORM_SIGN (1 << 5) +/* all pkts perform encryption calculation */ +#define EC_CRYPTO_RX_OVERRIDE_ALWAYS_PERFORM_ENC (1 << 6) +/* no pkt performs encryption calculation */ +#define EC_CRYPTO_RX_OVERRIDE_NEVER_PERFORM_ENC (1 << 7) +/* Enforce pkt trimming +bit[0] relates to metadata_pkt_trim +bit[1] relates to trailer_pkt_trime +bit[2] relates to sign_trim +bit[3] relates to aes_padding_trim */ +#define EC_CRYPTO_RX_OVERRIDE_ALWAYS_BYPASS_PKT_TRIM_MASK 0x00000F00 +#define EC_CRYPTO_RX_OVERRIDE_ALWAYS_BYPASS_PKT_TRIM_SHIFT 8 +/* Enforce no pkt trimming +bit[0] relates to metadata_pkt_trim +bit[1] relates to trailer_pkt_trime +bit[2] relates to sign_trim +bit[3] relates to aes_padding_trim */ +#define EC_CRYPTO_RX_OVERRIDE_NEVER_BYPASS_PKT_TRIM_MASK 0x0000F000 +#define EC_CRYPTO_RX_OVERRIDE_NEVER_BYPASS_PKT_TRIM_SHIFT 12 +/* bit enable for writing to rx_cmpl metadata info */ +#define EC_CRYPTO_RX_OVERRIDE_META_DATA_WRITE_EN_MASK 0x00070000 +#define EC_CRYPTO_RX_OVERRIDE_META_DATA_WRITE_EN_SHIFT 16 +/* chicken bit to disable metadata handling optimization */ +#define EC_CRYPTO_RX_OVERRIDE_EXPLICIT_METADATA_STAGE (1 << 19) +/* crypto metadata offset in the rx cmpl_desc */ +#define EC_CRYPTO_RX_OVERRIDE_META_DATA_BASE_MASK 0x07F00000 +#define EC_CRYPTO_RX_OVERRIDE_META_DATA_BASE_SHIFT 20 + +/**** tx_enc_iv_construction register ****/ +/* for each IV byte, select between src1 & src2. Src1 & src2 ... */ +#define EC_CRYPTO_TX_ENC_IV_CONSTRUCTION_MUX_SEL_MASK 0x0000FFFF +#define EC_CRYPTO_TX_ENC_IV_CONSTRUCTION_MUX_SEL_SHIFT 0 +/* configure meaning of mux_sel=1'b0 (2'b00 – zeros, 2'b01 f... */ +#define EC_CRYPTO_TX_ENC_IV_CONSTRUCTION_MAP_0_MASK 0x00030000 +#define EC_CRYPTO_TX_ENC_IV_CONSTRUCTION_MAP_0_SHIFT 16 +/* configure meaning of mux_sel=1'b1 (2'b00 – zeros, 2'b01 ... */ +#define EC_CRYPTO_TX_ENC_IV_CONSTRUCTION_MAP_1_MASK 0x000C0000 +#define EC_CRYPTO_TX_ENC_IV_CONSTRUCTION_MAP_1_SHIFT 18 +/* Per-byte mux select taken from Crypto table (otherwise ... */ +#define EC_CRYPTO_TX_ENC_IV_CONSTRUCTION_SEL_FROM_TABLE (1 << 20) +/* [0] word swap en +[1] byte swap en +[2] bit swap en */ +#define EC_CRYPTO_TX_ENC_IV_CONSTRUCTION_ENDIANITY_SWAP_MASK 0x00E00000 +#define EC_CRYPTO_TX_ENC_IV_CONSTRUCTION_ENDIANITY_SWAP_SHIFT 21 + +/**** rx_enc_iv_construction register ****/ +/* for each IV byte, select between src1 & src2. Src1 & src2 ... */ +#define EC_CRYPTO_RX_ENC_IV_CONSTRUCTION_MUX_SEL_MASK 0x0000FFFF +#define EC_CRYPTO_RX_ENC_IV_CONSTRUCTION_MUX_SEL_SHIFT 0 +/* configure meaning of mux_sel=1'b0 (2'b00 – zeros, 2'b01 – ... */ +#define EC_CRYPTO_RX_ENC_IV_CONSTRUCTION_MAP_0_MASK 0x00030000 +#define EC_CRYPTO_RX_ENC_IV_CONSTRUCTION_MAP_0_SHIFT 16 +/* configure meaning of mux_sel=1'b1 (2'b00 – zeros, 2'b01 – ... */ +#define EC_CRYPTO_RX_ENC_IV_CONSTRUCTION_MAP_1_MASK 0x000C0000 +#define EC_CRYPTO_RX_ENC_IV_CONSTRUCTION_MAP_1_SHIFT 18 +/* Per-byte mux select taken from Crypto table (otherwise from ... */ +#define EC_CRYPTO_RX_ENC_IV_CONSTRUCTION_SEL_FROM_TABLE (1 << 20) +/* [0] word swap en +[1] byte swap en +[2] bit swap en */ +#define EC_CRYPTO_RX_ENC_IV_CONSTRUCTION_ENDIANITY_SWAP_MASK 0x00E00000 +#define EC_CRYPTO_RX_ENC_IV_CONSTRUCTION_ENDIANITY_SWAP_SHIFT 21 + +/**** rx_enc_iv_map register ****/ +/* [0] word swap en +[1] byte swap en +[2] bit swap en */ +#define EC_CRYPTO_RX_ENC_IV_MAP_FIELD_EXTRACT_0_OFFSET_MASK 0x0000001F +#define EC_CRYPTO_RX_ENC_IV_MAP_FIELD_EXTRACT_0_OFFSET_SHIFT 0 +/* number of valid bytes in word, as generated by field extract ... */ +#define EC_CRYPTO_RX_ENC_IV_MAP_FIELD_EXTRACT_0_LENGTH_MASK 0x000000E0 +#define EC_CRYPTO_RX_ENC_IV_MAP_FIELD_EXTRACT_0_LENGTH_SHIFT 5 +/* [0] word swap en +[1] byte swap en +[2] bit swap en */ +#define EC_CRYPTO_RX_ENC_IV_MAP_FIELD_EXTRACT_1_OFFSET_MASK 0x00001F00 +#define EC_CRYPTO_RX_ENC_IV_MAP_FIELD_EXTRACT_1_OFFSET_SHIFT 8 +/* number of valid bytes in word, as generated by field extract ... */ +#define EC_CRYPTO_RX_ENC_IV_MAP_FIELD_EXTRACT_1_LENGTH_MASK 0x0000E000 +#define EC_CRYPTO_RX_ENC_IV_MAP_FIELD_EXTRACT_1_LENGTH_SHIFT 13 +/* [0] word swap en +[1] byte swap en +[2] bit swap en */ +#define EC_CRYPTO_RX_ENC_IV_MAP_FIELD_EXTRACT_2_OFFSET_MASK 0x001F0000 +#define EC_CRYPTO_RX_ENC_IV_MAP_FIELD_EXTRACT_2_OFFSET_SHIFT 16 +/* number of valid bytes in word, as generated by field extract ... */ +#define EC_CRYPTO_RX_ENC_IV_MAP_FIELD_EXTRACT_2_LENGTH_MASK 0x00E00000 +#define EC_CRYPTO_RX_ENC_IV_MAP_FIELD_EXTRACT_2_LENGTH_SHIFT 21 +/* [0] word swap en +[1] byte swap en +[2] bit swap en */ +#define EC_CRYPTO_RX_ENC_IV_MAP_FIELD_EXTRACT_3_OFFSET_MASK 0x1F000000 +#define EC_CRYPTO_RX_ENC_IV_MAP_FIELD_EXTRACT_3_OFFSET_SHIFT 24 +/* number of valid bytes in word, as generated by field extract ... */ +#define EC_CRYPTO_RX_ENC_IV_MAP_FIELD_EXTRACT_3_LENGTH_MASK 0xE0000000 +#define EC_CRYPTO_RX_ENC_IV_MAP_FIELD_EXTRACT_3_LENGTH_SHIFT 29 + +/**** tx_pkt_trim_len register ****/ +/* metadata shift-reg length */ +#define EC_CRYPTO_TX_PKT_TRIM_LEN_META_MASK 0x00000007 +#define EC_CRYPTO_TX_PKT_TRIM_LEN_META_SHIFT 0 +/* pkt trailer shift-reg length */ +#define EC_CRYPTO_TX_PKT_TRIM_LEN_TRAIL_MASK 0x000000F0 +#define EC_CRYPTO_TX_PKT_TRIM_LEN_TRAIL_SHIFT 4 +/* sign shift-reg length */ +#define EC_CRYPTO_TX_PKT_TRIM_LEN_SIGN_MASK 0x00000300 +#define EC_CRYPTO_TX_PKT_TRIM_LEN_SIGN_SHIFT 8 +/* crypto padding shift-reg length */ +#define EC_CRYPTO_TX_PKT_TRIM_LEN_CRYPTO_PADDING_MASK 0x00003000 +#define EC_CRYPTO_TX_PKT_TRIM_LEN_CRYPTO_PADDING_SHIFT 12 +/* hardware chooses shift-registers configurations automatically – no need for sw configuration */ +#define EC_CRYPTO_TX_PKT_TRIM_LEN_AUTO_MODE (1 << 16) + +/**** rx_pkt_trim_len register ****/ +/* metadata shift-reg length */ +#define EC_CRYPTO_RX_PKT_TRIM_LEN_META_MASK 0x00000007 +#define EC_CRYPTO_RX_PKT_TRIM_LEN_META_SHIFT 0 +/* pkt trailer shift-reg length */ +#define EC_CRYPTO_RX_PKT_TRIM_LEN_TRAIL_MASK 0x000000F0 +#define EC_CRYPTO_RX_PKT_TRIM_LEN_TRAIL_SHIFT 4 +/* sign shift-reg length */ +#define EC_CRYPTO_RX_PKT_TRIM_LEN_SIGN_MASK 0x00000300 +#define EC_CRYPTO_RX_PKT_TRIM_LEN_SIGN_SHIFT 8 +/* crypto padding shift-reg length */ +#define EC_CRYPTO_RX_PKT_TRIM_LEN_CRYPTO_PADDING_MASK 0x00003000 +#define EC_CRYPTO_RX_PKT_TRIM_LEN_CRYPTO_PADDING_SHIFT 12 +/* hardware chooses shift-registers configurations automatically – no need for sw configuration */ +#define EC_CRYPTO_RX_PKT_TRIM_LEN_AUTO_MODE (1 << 16) + +/**** total_tx_secured_pkts_cipher_mode_cmpr register ****/ + +#define EC_CRYPTO_PERF_CNTR_TOTAL_TX_SECURED_PKTS_CIPHER_MODE_CMPR_MODE_MASK 0x0000000F +#define EC_CRYPTO_PERF_CNTR_TOTAL_TX_SECURED_PKTS_CIPHER_MODE_CMPR_MODE_SHIFT 0 + +/**** total_rx_secured_pkts_cipher_mode_cmpr register ****/ + +#define EC_CRYPTO_PERF_CNTR_TOTAL_RX_SECURED_PKTS_CIPHER_MODE_CMPR_MODE_MASK 0x0000000F +#define EC_CRYPTO_PERF_CNTR_TOTAL_RX_SECURED_PKTS_CIPHER_MODE_CMPR_MODE_SHIFT 0 + +#ifdef __cplusplus +} +#endif + +#endif /* __AL_HAL_EC_REG_H */ + +/** @} end of ... group */ + + diff --git a/eth/al_hal_eth_kr.c b/eth/al_hal_eth_kr.c new file mode 100644 index 00000000000..14ef797eb00 --- /dev/null +++ b/eth/al_hal_eth_kr.c @@ -0,0 +1,1030 @@ +/*- +******************************************************************************* +Copyright (C) 2015 Annapurna Labs Ltd. + +This file may be licensed under the terms of the Annapurna Labs Commercial +License Agreement. + +Alternatively, this file can be distributed under the terms of the GNU General +Public License V2 as published by the Free Software Foundation and can be +found at http://www.gnu.org/licenses/gpl-2.0.html + +Alternatively, redistribution and use in source and binary forms, with or +without modification, are permitted provided that the following conditions are +met: + + * Redistributions of source code must retain the above copyright notice, +this list of conditions and the following disclaimer. + + * Redistributions in binary form must reproduce the above copyright +notice, this list of conditions and the following disclaimer in +the documentation and/or other materials provided with the +distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +*******************************************************************************/ +/** + * Ethernet + * @{ + * @file al_hal_eth_kr.c + * + * @brief KR HAL driver for main functions (auto-neg, Link Training) + * + */ + +#include "al_hal_eth_kr.h" +#include "al_hal_eth_mac_regs.h" +#include "al_hal_an_lt_wrapper_regs.h" + +enum al_eth_lt_unit_rev { + AL_ETH_LT_UNIT_REV_1 = 0, + AL_ETH_LT_UNIT_REV_2, + + AL_ETH_LT_UNIT_REV_MAX +}; + +enum al_eth_an_lt_regs_ids { + AL_ETH_KR_AN_CONTROL = 0, + AL_ETH_KR_AN_STATUS, + AL_ETH_KR_AN_ADV0, + AL_ETH_KR_AN_ADV1, + AL_ETH_KR_AN_ADV2, + AL_ETH_KR_AN_REM_ADV0, + AL_ETH_KR_AN_REM_ADV1, + AL_ETH_KR_AN_REM_ADV2, + AL_ETH_KR_PMD_CONTROL, + AL_ETH_KR_PMD_STATUS, + AL_ETH_KR_PMD_LP_COEF_UP, + AL_ETH_KR_PMD_LP_STATUS_REPORT, + AL_ETH_KR_PMD_LD_COEF_UP, + AL_ETH_KR_PMD_LD_STATUS_REPORT, + AL_ETH_KR_AN_XNP_ADV0, + AL_ETH_KR_AN_XNP_ADV1, + AL_ETH_KR_AN_XNP_ADV2, + AL_ETH_KR_AN_REM_XNP_ADV0, + AL_ETH_KR_AN_REM_XNP_ADV1, + AL_ETH_KR_AN_REM_XNP_ADV2, +}; + +static uint32_t al_eth_an_lt_regs_addr[][AL_ETH_LT_UNIT_REV_MAX] = { + [AL_ETH_KR_AN_CONTROL] = {0 , 0x0}, + [AL_ETH_KR_AN_STATUS] = {1 , 0x4}, + [AL_ETH_KR_AN_ADV0] = {16 , 0x8}, + [AL_ETH_KR_AN_ADV1] = {17 , 0xc}, + [AL_ETH_KR_AN_ADV2] = {18 , 0x10}, + [AL_ETH_KR_AN_REM_ADV0] = {19 , 0x14}, + [AL_ETH_KR_AN_REM_ADV1] = {20 , 0x18}, + [AL_ETH_KR_AN_REM_ADV2] = {21 , 0x1c}, + [AL_ETH_KR_PMD_CONTROL] = {150, 0x400}, + [AL_ETH_KR_PMD_STATUS] = {151, 0x404}, + [AL_ETH_KR_PMD_LP_COEF_UP] = {152, 0x408}, + [AL_ETH_KR_PMD_LP_STATUS_REPORT] = {153, 0x40c}, + [AL_ETH_KR_PMD_LD_COEF_UP] = {154, 0x410}, + [AL_ETH_KR_PMD_LD_STATUS_REPORT] = {155, 0x414}, + [AL_ETH_KR_AN_XNP_ADV0] = {22 , 0x24}, + [AL_ETH_KR_AN_XNP_ADV1] = {23 , 0x28}, + [AL_ETH_KR_AN_XNP_ADV2] = {24 , 0x2c}, + [AL_ETH_KR_AN_REM_XNP_ADV0] = {25 , 0x30}, + [AL_ETH_KR_AN_REM_XNP_ADV1] = {26 , 0x34}, + [AL_ETH_KR_AN_REM_XNP_ADV2] = {27 , 0x38}, +}; + + +/* + * AN(Auto Negotiation) registers + * (read / write indirect with al_eth_an_reg_read/write) + */ +#define AL_ETH_KR_AN_CONTROL_RESTART AL_BIT(9) +#define AL_ETH_KR_AN_CONTROL_ENABLE AL_BIT(12) +#define AL_ETH_KR_AN_CONTROL_NP_ENABLE AL_BIT(13) + +#define AL_ETH_KR_AN_STATUS_COMPLETED AL_BIT(5) +#define AL_ETH_KR_AN_STATUS_BASE_PAGE_RECEIVED AL_BIT(6) +#define AL_ETH_KR_AN_STATUS_CHECK_MASK 0xFF0A +#define AL_ETH_KR_AN_STATUS_CHECK_NO_ERROR 0x0008 + +/* AN advertising registers parsing */ +/* register 1 */ +#define AL_ETH_KR_AN_ADV1_SEL_FIELD_MASK 0x001f +#define AL_ETH_KR_AN_ADV1_SEL_FIELD_SHIFT 0 +#define AL_ETH_KR_AN_ADV1_ECHOED_NONCE_MASK 0x03e0 +#define AL_ETH_KR_AN_ADV1_ECHOED_NONCE_SHIFT 5 +#define AL_ETH_KR_AN_ADV1_CAPABILITY_MASK 0x1c00 +#define AL_ETH_KR_AN_ADV1_CAPABILITY_SHIFT 10 +#define AL_ETH_KR_AN_ADV1_REM_FAULT_MASK 0x2000 +#define AL_ETH_KR_AN_ADV1_REM_FAULT_SHIFT 13 +#define AL_ETH_KR_AN_ADV1_ACK_MASK 0x4000 +#define AL_ETH_KR_AN_ADV1_ACK_SHIFT 14 +#define AL_ETH_KR_AN_ADV1_NEXT_PAGE_MASK 0x8000 +#define AL_ETH_KR_AN_ADV1_NEXT_PAGE_SHIFT 15 +/* register 2 */ +#define AL_ETH_KR_AN_ADV2_TX_NONCE_MASK 0x001f +#define AL_ETH_KR_AN_ADV2_TX_NONCE_SHIFT 0 +#define AL_ETH_KR_AN_ADV2_TECH_MASK 0xffe0 +#define AL_ETH_KR_AN_ADV2_TECH_SHIFT 5 +/* register 3 */ +/* TECH field in the third register is extended to the field in the second + * register and it is currently reserved (should be always 0) */ +#define AL_ETH_KR_AN_ADV3_TECH_MASK 0x1fff +#define AL_ETH_KR_AN_ADV3_TECH_SHIFT 0 +#define AL_ETH_KR_AN_ADV3_FEC_MASK 0xc000 +#define AL_ETH_KR_AN_ADV3_FEC_SHIFT 14 + +/* Next Page Fields */ +/* register 1 */ +#define AL_ETH_KR_AN_NP_ADV1_DATA1_MASK 0x07ff +#define AL_ETH_KR_AN_NP_ADV1_DATA1_SHIFT 0 +#define AL_ETH_KR_AN_NP_ADV1_TOGGLE_MASK 0x0800 +#define AL_ETH_KR_AN_NP_ADV1_TOGGLE_SHIFT 11 +#define AL_ETH_KR_AN_NP_ADV1_ACK2_MASK 0x1000 +#define AL_ETH_KR_AN_NP_ADV1_ACK2_SHIFT 12 +#define AL_ETH_KR_AN_NP_ADV1_MSG_PAGE_MASK 0x2000 +#define AL_ETH_KR_AN_NP_ADV1_MSG_PAGE_SHIFT 13 +#define AL_ETH_KR_AN_NP_ADV1_NP_MASK 0x8000 +#define AL_ETH_KR_AN_NP_ADV1_NP_SHIFT 15 + +/* + * LT(Link Training) registers + * (read / write indirect with al_eth_pma_reg_read/write) + */ +#define AL_ETH_KR_PMD_CONTROL_RESTART 0 +#define AL_ETH_KR_PMD_CONTROL_ENABLE 1 + +#define AL_ETH_KR_PMD_STATUS_RECEIVER_COMPLETED_SHIFT 0 +#define AL_ETH_KR_PMD_STATUS_RECEIVER_FRAME_LOCK_SHIFT 1 +#define AL_ETH_KR_PMD_STATUS_RECEIVER_START_UP_PROTO_PROG_SHIFT 2 +#define AL_ETH_KR_PMD_STATUS_FAILURE_SHIFT 3 + +#define AL_ETH_KR_PMD_LP_COEF_UP_MINUS_MASK 0x0003 +#define AL_ETH_KR_PMD_LP_COEF_UP_MINUS_SHIFT 0 +#define AL_ETH_KR_PMD_LP_COEF_UP_ZERO_MASK 0x000C +#define AL_ETH_KR_PMD_LP_COEF_UP_ZERO_SHIFT 2 +#define AL_ETH_KR_PMD_LP_COEF_UP_PLUS_MASK 0x0030 +#define AL_ETH_KR_PMD_LP_COEF_UP_PLUS_SHIFT 4 +#define AL_ETH_KR_PMD_LP_COEF_UP_INITIALIZE_SHIFT 12 +#define AL_ETH_KR_PMD_LP_COEF_UP_PRESET_SHIFT 13 + +#define AL_ETH_KR_PMD_LP_STATUS_REPORT_MINUS_MASK 0x0003 +#define AL_ETH_KR_PMD_LP_STATUS_REPORT_MINUS_SHIFT 0 +#define AL_ETH_KR_PMD_LP_STATUS_REPORT_ZERO_MASK 0x000C +#define AL_ETH_KR_PMD_LP_STATUS_REPORT_ZERO_SHIFT 2 +#define AL_ETH_KR_PMD_LP_STATUS_REPORT_PLUS_MASK 0x0030 +#define AL_ETH_KR_PMD_LP_STATUS_REPORT_PLUS_SHIFT 4 +#define AL_ETH_KR_PMD_LP_STATUS_RECEIVER_READY_SHIFT 15 + +#define AL_ETH_KR_PMD_LD_COEF_UP_MINUS_MASK 0x0003 +#define AL_ETH_KR_PMD_LD_COEF_UP_MINUS_SHIFT 0 +#define AL_ETH_KR_PMD_LD_COEF_UP_ZERO_MASK 0x000C +#define AL_ETH_KR_PMD_LD_COEF_UP_ZERO_SHIFT 2 +#define AL_ETH_KR_PMD_LD_COEF_UP_PLUS_MASK 0x0030 +#define AL_ETH_KR_PMD_LD_COEF_UP_PLUS_SHIFT 4 +#define AL_ETH_KR_PMD_LD_COEF_UP_INITIALIZE_SHIFT 12 +#define AL_ETH_KR_PMD_LD_COEF_UP_PRESET_SHIFT 13 + +#define AL_ETH_KR_PMD_LD_STATUS_REPORT_MINUS_MASK 0x0003 +#define AL_ETH_KR_PMD_LD_STATUS_REPORT_MINUS_SHIFT 0 +#define AL_ETH_KR_PMD_LD_STATUS_REPORT_ZERO_MASK 0x000C +#define AL_ETH_KR_PMD_LD_STATUS_REPORT_ZERO_SHIFT 2 +#define AL_ETH_KR_PMD_LD_STATUS_REPORT_PLUS_MASK 0x0030 +#define AL_ETH_KR_PMD_LD_STATUS_REPORT_PLUS_SHIFT 4 +#define AL_ETH_KR_PMD_LD_STATUS_REPORT_RECEIVER_READY_SHIFT 15 + + +enum al_eth_an_lt_regs { + AL_ETH_AN_REGS, + AL_ETH_LT_REGS, +}; + +static uint16_t al_eth_an_lt_reg_read( + struct al_hal_eth_adapter *adapter, + enum al_eth_an_lt_regs_ids reg_id, + enum al_eth_an_lt_regs an_lt, + enum al_eth_an_lt_lane lane) +{ + uint32_t val; + uint16_t reg_addr; + + if (adapter->rev_id < AL_ETH_REV_ID_3) { + al_assert(lane == AL_ETH_AN__LT_LANE_0); + + reg_addr = al_eth_an_lt_regs_addr[reg_id][AL_ETH_LT_UNIT_REV_1]; + if (an_lt == AL_ETH_AN_REGS) { + al_reg_write32(&adapter->mac_regs_base->kr.an_addr, reg_addr); + val = al_reg_read32(&adapter->mac_regs_base->kr.an_data); + } else { + al_reg_write32(&adapter->mac_regs_base->kr.pma_addr, reg_addr); + val = al_reg_read32(&adapter->mac_regs_base->kr.pma_data); + } + } else { + struct al_an_lt_wrapper_regs *regs = NULL; + + reg_addr = al_eth_an_lt_regs_addr[reg_id][AL_ETH_LT_UNIT_REV_2]; + + switch (lane) { + case AL_ETH_AN__LT_LANE_0: + al_reg_write32(&adapter->mac_regs_base->gen_v3.an_lt_0_addr, + (uintptr_t)®s->an_lt[adapter->curr_lt_unit].addr); + al_reg_write32(&adapter->mac_regs_base->gen_v3.an_lt_0_data, + reg_addr); + + al_reg_write32(&adapter->mac_regs_base->gen_v3.an_lt_0_addr, + (uintptr_t)®s->an_lt[adapter->curr_lt_unit].data); + val = al_reg_read32(&adapter->mac_regs_base->gen_v3.an_lt_0_data); + break; + case AL_ETH_AN__LT_LANE_1: + al_reg_write32(&adapter->mac_regs_base->gen_v3.an_lt_1_addr, + (uintptr_t)®s->an_lt[adapter->curr_lt_unit].addr); + al_reg_write32(&adapter->mac_regs_base->gen_v3.an_lt_1_data, + reg_addr); + + al_reg_write32(&adapter->mac_regs_base->gen_v3.an_lt_1_addr, + (uintptr_t)®s->an_lt[adapter->curr_lt_unit].data); + val = al_reg_read32(&adapter->mac_regs_base->gen_v3.an_lt_1_data); + break; + case AL_ETH_AN__LT_LANE_2: + al_reg_write32(&adapter->mac_regs_base->gen_v3.an_lt_2_addr, + (uintptr_t)®s->an_lt[adapter->curr_lt_unit].addr); + al_reg_write32(&adapter->mac_regs_base->gen_v3.an_lt_2_data, + reg_addr); + + al_reg_write32(&adapter->mac_regs_base->gen_v3.an_lt_2_addr, + (uintptr_t)®s->an_lt[adapter->curr_lt_unit].data); + val = al_reg_read32(&adapter->mac_regs_base->gen_v3.an_lt_2_data); + break; + case AL_ETH_AN__LT_LANE_3: + al_reg_write32(&adapter->mac_regs_base->gen_v3.an_lt_3_addr, + (uintptr_t)®s->an_lt[adapter->curr_lt_unit].addr); + al_reg_write32(&adapter->mac_regs_base->gen_v3.an_lt_3_data, + reg_addr); + + al_reg_write32(&adapter->mac_regs_base->gen_v3.an_lt_3_addr, + (uintptr_t)®s->an_lt[adapter->curr_lt_unit].data); + val = al_reg_read32(&adapter->mac_regs_base->gen_v3.an_lt_3_data); + break; + default: + al_err("%s: Unknown Lane %d\n", __func__, lane); + return 0; + } + } + + + al_dbg("[%s]: %s - (%s) lane %d, reg %d, val 0x%x", adapter->name, __func__, + (an_lt == AL_ETH_AN_REGS) ? "AN" : "LT", lane, reg_addr, val); + + return (uint16_t)val; +} + +static void al_eth_an_lt_reg_write( + struct al_hal_eth_adapter *adapter, + enum al_eth_an_lt_regs_ids reg_id, + enum al_eth_an_lt_regs an_lt, + enum al_eth_an_lt_lane lane, + uint16_t val) +{ + uint16_t reg_addr; + + if (adapter->rev_id < AL_ETH_REV_ID_3) { + reg_addr = al_eth_an_lt_regs_addr[reg_id][AL_ETH_LT_UNIT_REV_1]; + if (an_lt == AL_ETH_AN_REGS) { + al_reg_write32(&adapter->mac_regs_base->kr.an_addr, reg_addr); + al_reg_write32(&adapter->mac_regs_base->kr.an_data, val); + } else { + al_reg_write32(&adapter->mac_regs_base->kr.pma_addr, reg_addr); + al_reg_write32(&adapter->mac_regs_base->kr.pma_data, val); + } + } else { + struct al_an_lt_wrapper_regs *regs = NULL; + + reg_addr = al_eth_an_lt_regs_addr[reg_id][AL_ETH_LT_UNIT_REV_2]; + + switch (lane) { + case AL_ETH_AN__LT_LANE_0: + al_reg_write32(&adapter->mac_regs_base->gen_v3.an_lt_0_addr, + (uintptr_t)®s->an_lt[adapter->curr_lt_unit].addr); + al_reg_write32(&adapter->mac_regs_base->gen_v3.an_lt_0_data, + reg_addr); + + al_reg_write32(&adapter->mac_regs_base->gen_v3.an_lt_0_addr, + (uintptr_t)®s->an_lt[adapter->curr_lt_unit].data); + al_reg_write32(&adapter->mac_regs_base->gen_v3.an_lt_0_data, + val); + break; + case AL_ETH_AN__LT_LANE_1: + al_reg_write32(&adapter->mac_regs_base->gen_v3.an_lt_1_addr, + (uintptr_t)®s->an_lt[adapter->curr_lt_unit].addr); + al_reg_write32(&adapter->mac_regs_base->gen_v3.an_lt_1_data, + reg_addr); + + al_reg_write32(&adapter->mac_regs_base->gen_v3.an_lt_1_addr, + (uintptr_t)®s->an_lt[adapter->curr_lt_unit].data); + al_reg_write32(&adapter->mac_regs_base->gen_v3.an_lt_1_data, + val); + break; + case AL_ETH_AN__LT_LANE_2: + al_reg_write32(&adapter->mac_regs_base->gen_v3.an_lt_2_addr, + (uintptr_t)®s->an_lt[adapter->curr_lt_unit].addr); + al_reg_write32(&adapter->mac_regs_base->gen_v3.an_lt_2_data, + reg_addr); + + al_reg_write32(&adapter->mac_regs_base->gen_v3.an_lt_2_addr, + (uintptr_t)®s->an_lt[adapter->curr_lt_unit].data); + al_reg_write32(&adapter->mac_regs_base->gen_v3.an_lt_2_data, + val); + break; + case AL_ETH_AN__LT_LANE_3: + al_reg_write32(&adapter->mac_regs_base->gen_v3.an_lt_3_addr, + (uintptr_t)®s->an_lt[adapter->curr_lt_unit].addr); + al_reg_write32(&adapter->mac_regs_base->gen_v3.an_lt_3_data, + reg_addr); + + al_reg_write32(&adapter->mac_regs_base->gen_v3.an_lt_3_addr, + (uintptr_t)®s->an_lt[adapter->curr_lt_unit].data); + al_reg_write32(&adapter->mac_regs_base->gen_v3.an_lt_3_data, + val); + break; + default: + al_err("%s: Unknown Lane %d\n", __func__, lane); + return; + } + } + + + al_dbg("[%s]: %s - (%s) lane %d, reg %d, val 0x%x", adapter->name, __func__, + (an_lt == AL_ETH_AN_REGS) ? "AN" : "LT", lane, reg_addr, val); +} + +static void al_eth_an_lt_unit_config(struct al_hal_eth_adapter *adapter) +{ + struct al_an_lt_wrapper_regs *regs = NULL; + uint32_t cfg_lane_0 = (AN_LT_WRAPPER_GEN_CFG_BYPASS_RX | AN_LT_WRAPPER_GEN_CFG_BYPASS_TX); + uint32_t cfg_lane_1 = (AN_LT_WRAPPER_GEN_CFG_BYPASS_RX | AN_LT_WRAPPER_GEN_CFG_BYPASS_TX); + uint32_t cfg_lane_2 = (AN_LT_WRAPPER_GEN_CFG_BYPASS_RX | AN_LT_WRAPPER_GEN_CFG_BYPASS_TX); + uint32_t cfg_lane_3 = (AN_LT_WRAPPER_GEN_CFG_BYPASS_RX | AN_LT_WRAPPER_GEN_CFG_BYPASS_TX); + + switch (adapter->mac_mode) { + case AL_ETH_MAC_MODE_10GbE_Serial: + cfg_lane_0 = 0; + AL_REG_FIELD_SET(cfg_lane_0, + AN_LT_WRAPPER_GEN_CFG_AN_LT_SEL_RX_MASK, + AN_LT_WRAPPER_GEN_CFG_AN_LT_SEL_RX_SHIFT, + AL_ETH_AN_LT_UNIT_20_BIT); + AL_REG_FIELD_SET(cfg_lane_0, + AN_LT_WRAPPER_GEN_CFG_AN_LT_SEL_TX_MASK, + AN_LT_WRAPPER_GEN_CFG_AN_LT_SEL_TX_SHIFT, + AL_ETH_AN_LT_UNIT_20_BIT); + + adapter->curr_lt_unit = AL_ETH_AN_LT_UNIT_20_BIT; + + break; + case AL_ETH_MAC_MODE_KR_LL_25G: + cfg_lane_0 = 0; + AL_REG_FIELD_SET(cfg_lane_0, + AN_LT_WRAPPER_GEN_CFG_AN_LT_SEL_RX_MASK, + AN_LT_WRAPPER_GEN_CFG_AN_LT_SEL_RX_SHIFT, + AL_ETH_AN_LT_UNIT_32_BIT); + AL_REG_FIELD_SET(cfg_lane_0, + AN_LT_WRAPPER_GEN_CFG_AN_LT_SEL_TX_MASK, + AN_LT_WRAPPER_GEN_CFG_AN_LT_SEL_TX_SHIFT, + AL_ETH_AN_LT_UNIT_32_BIT); + + adapter->curr_lt_unit = AL_ETH_AN_LT_UNIT_32_BIT; + + break; + case AL_ETH_MAC_MODE_XLG_LL_40G: + cfg_lane_0 = 0; + AL_REG_FIELD_SET(cfg_lane_0, + AN_LT_WRAPPER_GEN_CFG_AN_LT_SEL_RX_MASK, + AN_LT_WRAPPER_GEN_CFG_AN_LT_SEL_RX_SHIFT, + AL_ETH_AN_LT_UNIT_16_BIT); + AL_REG_FIELD_SET(cfg_lane_0, + AN_LT_WRAPPER_GEN_CFG_AN_LT_SEL_TX_MASK, + AN_LT_WRAPPER_GEN_CFG_AN_LT_SEL_TX_SHIFT, + AL_ETH_AN_LT_UNIT_16_BIT); + + cfg_lane_1 = 0; + AL_REG_FIELD_SET(cfg_lane_1, + AN_LT_WRAPPER_GEN_CFG_AN_LT_SEL_RX_MASK, + AN_LT_WRAPPER_GEN_CFG_AN_LT_SEL_RX_SHIFT, + AL_ETH_AN_LT_UNIT_16_BIT); + AL_REG_FIELD_SET(cfg_lane_1, + AN_LT_WRAPPER_GEN_CFG_AN_LT_SEL_TX_MASK, + AN_LT_WRAPPER_GEN_CFG_AN_LT_SEL_TX_SHIFT, + AL_ETH_AN_LT_UNIT_16_BIT); + + cfg_lane_2 = 0; + AL_REG_FIELD_SET(cfg_lane_2, + AN_LT_WRAPPER_GEN_CFG_AN_LT_SEL_RX_MASK, + AN_LT_WRAPPER_GEN_CFG_AN_LT_SEL_RX_SHIFT, + AL_ETH_AN_LT_UNIT_16_BIT); + AL_REG_FIELD_SET(cfg_lane_2, + AN_LT_WRAPPER_GEN_CFG_AN_LT_SEL_TX_MASK, + AN_LT_WRAPPER_GEN_CFG_AN_LT_SEL_TX_SHIFT, + AL_ETH_AN_LT_UNIT_16_BIT); + + cfg_lane_3 = 0; + AL_REG_FIELD_SET(cfg_lane_3, + AN_LT_WRAPPER_GEN_CFG_AN_LT_SEL_RX_MASK, + AN_LT_WRAPPER_GEN_CFG_AN_LT_SEL_RX_SHIFT, + AL_ETH_AN_LT_UNIT_16_BIT); + AL_REG_FIELD_SET(cfg_lane_3, + AN_LT_WRAPPER_GEN_CFG_AN_LT_SEL_TX_MASK, + AN_LT_WRAPPER_GEN_CFG_AN_LT_SEL_TX_SHIFT, + AL_ETH_AN_LT_UNIT_16_BIT); + + adapter->curr_lt_unit = AL_ETH_AN_LT_UNIT_16_BIT; + + break; + case AL_ETH_MAC_MODE_XLG_LL_50G: + cfg_lane_0 = 0; + AL_REG_FIELD_SET(cfg_lane_0, + AN_LT_WRAPPER_GEN_CFG_AN_LT_SEL_RX_MASK, + AN_LT_WRAPPER_GEN_CFG_AN_LT_SEL_RX_SHIFT, + AL_ETH_AN_LT_UNIT_32_BIT); + AL_REG_FIELD_SET(cfg_lane_0, + AN_LT_WRAPPER_GEN_CFG_AN_LT_SEL_TX_MASK, + AN_LT_WRAPPER_GEN_CFG_AN_LT_SEL_TX_SHIFT, + AL_ETH_AN_LT_UNIT_32_BIT); + + cfg_lane_1 = 0; + AL_REG_FIELD_SET(cfg_lane_1, + AN_LT_WRAPPER_GEN_CFG_AN_LT_SEL_RX_MASK, + AN_LT_WRAPPER_GEN_CFG_AN_LT_SEL_RX_SHIFT, + AL_ETH_AN_LT_UNIT_32_BIT); + AL_REG_FIELD_SET(cfg_lane_1, + AN_LT_WRAPPER_GEN_CFG_AN_LT_SEL_TX_MASK, + AN_LT_WRAPPER_GEN_CFG_AN_LT_SEL_TX_SHIFT, + AL_ETH_AN_LT_UNIT_32_BIT); + + adapter->curr_lt_unit = AL_ETH_AN_LT_UNIT_32_BIT; + + break; + default: + al_err("%s: Unknown mac_mode\n", __func__); + return; + } + + al_reg_write32(&adapter->mac_regs_base->gen_v3.an_lt_0_addr, + (uintptr_t)®s->gen.cfg); + al_reg_write32(&adapter->mac_regs_base->gen_v3.an_lt_0_data, + cfg_lane_0); + + al_reg_write32(&adapter->mac_regs_base->gen_v3.an_lt_1_addr, + (uintptr_t)®s->gen.cfg); + al_reg_write32(&adapter->mac_regs_base->gen_v3.an_lt_1_data, + cfg_lane_1); + + al_reg_write32(&adapter->mac_regs_base->gen_v3.an_lt_2_addr, + (uintptr_t)®s->gen.cfg); + al_reg_write32(&adapter->mac_regs_base->gen_v3.an_lt_2_data, + cfg_lane_2); + + al_reg_write32(&adapter->mac_regs_base->gen_v3.an_lt_3_addr, + (uintptr_t)®s->gen.cfg); + al_reg_write32(&adapter->mac_regs_base->gen_v3.an_lt_3_data, + cfg_lane_3); +} + +void al_eth_lp_coeff_up_get( + struct al_hal_eth_adapter *adapter, + enum al_eth_an_lt_lane lane, + struct al_eth_kr_coef_up_data *lpcoeff) +{ + uint16_t reg; + + reg = al_eth_an_lt_reg_read(adapter, AL_ETH_KR_PMD_LP_COEF_UP, AL_ETH_LT_REGS, lane); + + lpcoeff->preset = + (AL_REG_BIT_GET( + reg, AL_ETH_KR_PMD_LP_COEF_UP_PRESET_SHIFT) != 0); + + lpcoeff->initialize = + (AL_REG_BIT_GET( + reg, AL_ETH_KR_PMD_LP_COEF_UP_INITIALIZE_SHIFT) != 0); + + lpcoeff->c_minus = AL_REG_FIELD_GET(reg, + AL_ETH_KR_PMD_LP_COEF_UP_MINUS_MASK, + AL_ETH_KR_PMD_LP_COEF_UP_MINUS_SHIFT); + + lpcoeff->c_zero = AL_REG_FIELD_GET(reg, + AL_ETH_KR_PMD_LP_COEF_UP_ZERO_MASK, + AL_ETH_KR_PMD_LP_COEF_UP_ZERO_SHIFT); + + lpcoeff->c_plus = AL_REG_FIELD_GET(reg, + AL_ETH_KR_PMD_LP_COEF_UP_PLUS_MASK, + AL_ETH_KR_PMD_LP_COEF_UP_PLUS_SHIFT); +} + +void al_eth_lp_status_report_get( + struct al_hal_eth_adapter *adapter, + enum al_eth_an_lt_lane lane, + struct al_eth_kr_status_report_data *status) +{ + uint16_t reg; + + reg = al_eth_an_lt_reg_read(adapter, AL_ETH_KR_PMD_LP_STATUS_REPORT, AL_ETH_LT_REGS, lane); + + status->c_minus = AL_REG_FIELD_GET(reg, + AL_ETH_KR_PMD_LP_STATUS_REPORT_MINUS_MASK, + AL_ETH_KR_PMD_LP_STATUS_REPORT_MINUS_SHIFT); + + status->c_zero = AL_REG_FIELD_GET(reg, + AL_ETH_KR_PMD_LP_STATUS_REPORT_ZERO_MASK, + AL_ETH_KR_PMD_LP_STATUS_REPORT_ZERO_SHIFT); + + status->c_plus = AL_REG_FIELD_GET(reg, + AL_ETH_KR_PMD_LP_STATUS_REPORT_PLUS_MASK, + AL_ETH_KR_PMD_LP_STATUS_REPORT_PLUS_SHIFT); + + status->receiver_ready = + (AL_REG_BIT_GET( + reg, AL_ETH_KR_PMD_LP_STATUS_RECEIVER_READY_SHIFT) != 0); + +} + +void al_eth_ld_coeff_up_set( + struct al_hal_eth_adapter *adapter, + enum al_eth_an_lt_lane lane, + struct al_eth_kr_coef_up_data *ldcoeff) +{ + uint16_t reg = 0; + + if (ldcoeff->preset) + AL_REG_BIT_SET(reg, AL_ETH_KR_PMD_LD_COEF_UP_PRESET_SHIFT); + + if (ldcoeff->initialize) + AL_REG_BIT_SET(reg, AL_ETH_KR_PMD_LD_COEF_UP_INITIALIZE_SHIFT); + + AL_REG_FIELD_SET(reg, + AL_ETH_KR_PMD_LD_COEF_UP_MINUS_MASK, + AL_ETH_KR_PMD_LD_COEF_UP_MINUS_SHIFT, + ldcoeff->c_minus); + + AL_REG_FIELD_SET(reg, + AL_ETH_KR_PMD_LD_COEF_UP_ZERO_MASK, + AL_ETH_KR_PMD_LD_COEF_UP_ZERO_SHIFT, + ldcoeff->c_zero); + + AL_REG_FIELD_SET(reg, + AL_ETH_KR_PMD_LD_COEF_UP_PLUS_MASK, + AL_ETH_KR_PMD_LD_COEF_UP_PLUS_SHIFT, + ldcoeff->c_plus); + + al_eth_an_lt_reg_write(adapter, AL_ETH_KR_PMD_LD_COEF_UP, AL_ETH_LT_REGS, lane, reg); +} + +void al_eth_ld_status_report_set( + struct al_hal_eth_adapter *adapter, + enum al_eth_an_lt_lane lane, + struct al_eth_kr_status_report_data *status) +{ + uint16_t reg = 0; + + AL_REG_FIELD_SET(reg, + AL_ETH_KR_PMD_LD_STATUS_REPORT_MINUS_MASK, + AL_ETH_KR_PMD_LD_STATUS_REPORT_MINUS_SHIFT, + status->c_minus); + + AL_REG_FIELD_SET(reg, + AL_ETH_KR_PMD_LD_STATUS_REPORT_ZERO_MASK, + AL_ETH_KR_PMD_LD_STATUS_REPORT_ZERO_SHIFT, + status->c_zero); + + AL_REG_FIELD_SET(reg, + AL_ETH_KR_PMD_LD_STATUS_REPORT_PLUS_MASK, + AL_ETH_KR_PMD_LD_STATUS_REPORT_PLUS_SHIFT, + status->c_plus); + + if (status->receiver_ready) + AL_REG_BIT_SET(reg, + AL_ETH_KR_PMD_LD_STATUS_REPORT_RECEIVER_READY_SHIFT); + + al_eth_an_lt_reg_write(adapter, AL_ETH_KR_PMD_LD_STATUS_REPORT, AL_ETH_LT_REGS, lane, reg); +} + +al_bool al_eth_kr_receiver_frame_lock_get(struct al_hal_eth_adapter *adapter, + enum al_eth_an_lt_lane lane) +{ + uint16_t reg; + + reg = al_eth_an_lt_reg_read(adapter, AL_ETH_KR_PMD_STATUS, AL_ETH_LT_REGS, lane); + + return (AL_REG_BIT_GET(reg, + AL_ETH_KR_PMD_STATUS_RECEIVER_FRAME_LOCK_SHIFT) != 0); +} + +al_bool al_eth_kr_startup_proto_prog_get(struct al_hal_eth_adapter *adapter, + enum al_eth_an_lt_lane lane) +{ + uint16_t reg; + + reg = al_eth_an_lt_reg_read(adapter, AL_ETH_KR_PMD_STATUS, AL_ETH_LT_REGS, lane); + + return (AL_REG_BIT_GET( + reg, AL_ETH_KR_PMD_STATUS_RECEIVER_START_UP_PROTO_PROG_SHIFT) != 0); +} + +al_bool al_eth_kr_training_status_fail_get(struct al_hal_eth_adapter *adapter, + enum al_eth_an_lt_lane lane) +{ + uint16_t reg; + + reg = al_eth_an_lt_reg_read(adapter, AL_ETH_KR_PMD_STATUS, AL_ETH_LT_REGS, lane); + + return (AL_REG_BIT_GET(reg, AL_ETH_KR_PMD_STATUS_FAILURE_SHIFT) != 0); +} + +void al_eth_receiver_ready_set(struct al_hal_eth_adapter *adapter, + enum al_eth_an_lt_lane lane) +{ + al_eth_an_lt_reg_write(adapter, AL_ETH_KR_PMD_STATUS, AL_ETH_LT_REGS, lane, 1); +} + +/*************************** auto negotiation *********************************/ +static int al_eth_kr_an_validate_adv(struct al_hal_eth_adapter *adapter, + struct al_eth_an_adv *an_adv) +{ + al_assert(adapter); + + if (an_adv == NULL) + return 0; + + if (an_adv->selector_field != 1) { + al_err("[%s]: %s failed on selector_field (%d)\n", + adapter->name, __func__, an_adv->selector_field); + return -EINVAL; + } + + if (an_adv->capability & AL_BIT(2)) { + al_err("[%s]: %s failed on capability bit 2 (%d)\n", + adapter->name, __func__, an_adv->capability); + return -EINVAL; + } + + if (an_adv->remote_fault) { + al_err("[%s]: %s failed on remote_fault (%d)\n", + adapter->name, __func__, an_adv->remote_fault); + return -EINVAL; + } + + if (an_adv->acknowledge) { + al_err("[%s]: %s failed on acknowledge (%d)\n", + adapter->name, __func__, an_adv->acknowledge); + return -EINVAL; + } + + return 0; +} + +static int al_eth_kr_an_write_adv(struct al_hal_eth_adapter *adapter, + struct al_eth_an_adv *an_adv) +{ + uint16_t reg; + + if(an_adv == NULL) + return 0; + + reg = 0; + AL_REG_FIELD_SET(reg, AL_ETH_KR_AN_ADV1_SEL_FIELD_MASK, + AL_ETH_KR_AN_ADV1_SEL_FIELD_SHIFT, + an_adv->selector_field); + + AL_REG_FIELD_SET(reg, AL_ETH_KR_AN_ADV1_ECHOED_NONCE_MASK, + AL_ETH_KR_AN_ADV1_ECHOED_NONCE_SHIFT, + an_adv->echoed_nonce); + + AL_REG_FIELD_SET(reg, AL_ETH_KR_AN_ADV1_CAPABILITY_MASK, + AL_ETH_KR_AN_ADV1_CAPABILITY_SHIFT, + an_adv->capability); + + AL_REG_BIT_VAL_SET(reg, AL_ETH_KR_AN_ADV1_REM_FAULT_SHIFT, + an_adv->remote_fault); + + AL_REG_BIT_VAL_SET(reg, AL_ETH_KR_AN_ADV1_ACK_SHIFT, + an_adv->acknowledge); + + AL_REG_BIT_VAL_SET(reg, AL_ETH_KR_AN_ADV1_NEXT_PAGE_SHIFT, + an_adv->next_page); + + al_eth_an_lt_reg_write(adapter, AL_ETH_KR_AN_ADV0, AL_ETH_AN_REGS, + AL_ETH_AN__LT_LANE_0, reg); + + reg = 0; + AL_REG_FIELD_SET(reg, AL_ETH_KR_AN_ADV2_TX_NONCE_MASK, + AL_ETH_KR_AN_ADV2_TX_NONCE_SHIFT, + an_adv->transmitted_nonce); + + AL_REG_FIELD_SET(reg, AL_ETH_KR_AN_ADV2_TECH_MASK, + AL_ETH_KR_AN_ADV2_TECH_SHIFT, + an_adv->technology); + + al_eth_an_lt_reg_write(adapter, AL_ETH_KR_AN_ADV1, AL_ETH_AN_REGS, + AL_ETH_AN__LT_LANE_0, reg); + + reg = 0; + AL_REG_FIELD_SET(reg, AL_ETH_KR_AN_ADV3_TECH_MASK, + AL_ETH_KR_AN_ADV3_TECH_SHIFT, + an_adv->technology >> 11); + + AL_REG_FIELD_SET(reg, AL_ETH_KR_AN_ADV3_FEC_MASK, + AL_ETH_KR_AN_ADV3_FEC_SHIFT, + an_adv->fec_capability); + + al_eth_an_lt_reg_write(adapter, AL_ETH_KR_AN_ADV2, AL_ETH_AN_REGS, + AL_ETH_AN__LT_LANE_0, reg); + + return 0; +} + +void al_eth_kr_an_read_adv(struct al_hal_eth_adapter *adapter, + struct al_eth_an_adv *an_adv) +{ + int16_t reg; + + al_assert(an_adv != NULL); + + + reg = al_eth_an_lt_reg_read(adapter, AL_ETH_KR_AN_REM_ADV0, + AL_ETH_AN_REGS, AL_ETH_AN__LT_LANE_0); + + an_adv->selector_field = AL_REG_FIELD_GET(reg, + AL_ETH_KR_AN_ADV1_SEL_FIELD_MASK, + AL_ETH_KR_AN_ADV1_SEL_FIELD_SHIFT); + + an_adv->echoed_nonce = AL_REG_FIELD_GET(reg, + AL_ETH_KR_AN_ADV1_ECHOED_NONCE_MASK, + AL_ETH_KR_AN_ADV1_ECHOED_NONCE_SHIFT); + + an_adv->capability = AL_REG_FIELD_GET(reg, + AL_ETH_KR_AN_ADV1_CAPABILITY_MASK, + AL_ETH_KR_AN_ADV1_CAPABILITY_SHIFT); + + an_adv->remote_fault = AL_REG_BIT_GET(reg, + AL_ETH_KR_AN_ADV1_REM_FAULT_SHIFT); + + an_adv->acknowledge = AL_REG_BIT_GET(reg, + AL_ETH_KR_AN_ADV1_ACK_SHIFT); + + an_adv->next_page = AL_REG_BIT_GET(reg, + AL_ETH_KR_AN_ADV1_NEXT_PAGE_SHIFT); + + + reg = al_eth_an_lt_reg_read(adapter, AL_ETH_KR_AN_REM_ADV1, + AL_ETH_AN_REGS, AL_ETH_AN__LT_LANE_0); + + an_adv->transmitted_nonce = AL_REG_FIELD_GET(reg, + AL_ETH_KR_AN_ADV2_TX_NONCE_MASK, + AL_ETH_KR_AN_ADV2_TX_NONCE_SHIFT); + + an_adv->technology = AL_REG_FIELD_GET(reg, + AL_ETH_KR_AN_ADV2_TECH_MASK, + AL_ETH_KR_AN_ADV2_TECH_SHIFT); + + + reg = al_eth_an_lt_reg_read(adapter, AL_ETH_KR_AN_REM_ADV2, + AL_ETH_AN_REGS, AL_ETH_AN__LT_LANE_0); + + an_adv->technology |= (AL_REG_FIELD_GET(reg, + AL_ETH_KR_AN_ADV3_TECH_MASK, + AL_ETH_KR_AN_ADV3_TECH_SHIFT) << 11); + + an_adv->fec_capability = AL_REG_FIELD_GET(reg, + AL_ETH_KR_AN_ADV3_FEC_MASK, + AL_ETH_KR_AN_ADV3_FEC_SHIFT); +} + +int al_eth_kr_next_page_read(struct al_hal_eth_adapter *adapter, + struct al_eth_an_np *np) +{ + uint16_t reg; + + reg = al_eth_an_lt_reg_read(adapter, + AL_ETH_KR_AN_REM_XNP_ADV0, + AL_ETH_AN_REGS, + AL_ETH_AN__LT_LANE_0); + + np->unformatted_code_field = AL_REG_FIELD_GET(reg, AL_ETH_KR_AN_NP_ADV1_DATA1_MASK, + AL_ETH_KR_AN_NP_ADV1_DATA1_SHIFT); + + np->toggle = AL_REG_FIELD_GET(reg, AL_ETH_KR_AN_NP_ADV1_TOGGLE_MASK, + AL_ETH_KR_AN_NP_ADV1_TOGGLE_SHIFT); + + np->ack2 = AL_REG_FIELD_GET(reg, AL_ETH_KR_AN_NP_ADV1_ACK2_MASK, + AL_ETH_KR_AN_NP_ADV1_ACK2_SHIFT); + + np->msg_page = AL_REG_FIELD_GET(reg, AL_ETH_KR_AN_NP_ADV1_MSG_PAGE_MASK, + AL_ETH_KR_AN_NP_ADV1_MSG_PAGE_SHIFT); + + np->next_page = AL_REG_FIELD_GET(reg, AL_ETH_KR_AN_NP_ADV1_NP_MASK, + AL_ETH_KR_AN_NP_ADV1_NP_SHIFT); + + np->unformatted_code_field1 = al_eth_an_lt_reg_read(adapter, + AL_ETH_KR_AN_REM_XNP_ADV1, + AL_ETH_AN_REGS, + AL_ETH_AN__LT_LANE_0); + np->unformatted_code_field2 = al_eth_an_lt_reg_read(adapter, + AL_ETH_KR_AN_REM_XNP_ADV2, + AL_ETH_AN_REGS, + AL_ETH_AN__LT_LANE_0); + + return 0; +} + +int al_eth_kr_next_page_write(struct al_hal_eth_adapter *adapter, + struct al_eth_an_np *np) +{ + uint16_t reg = 0; + + AL_REG_FIELD_SET(reg, AL_ETH_KR_AN_NP_ADV1_DATA1_MASK, + AL_ETH_KR_AN_NP_ADV1_DATA1_SHIFT, + np->unformatted_code_field); + AL_REG_FIELD_SET(reg, AL_ETH_KR_AN_NP_ADV1_TOGGLE_MASK, + AL_ETH_KR_AN_NP_ADV1_TOGGLE_SHIFT, + np->toggle); + AL_REG_FIELD_SET(reg, AL_ETH_KR_AN_NP_ADV1_ACK2_MASK, + AL_ETH_KR_AN_NP_ADV1_ACK2_SHIFT, + np->ack2); + AL_REG_FIELD_SET(reg, AL_ETH_KR_AN_NP_ADV1_MSG_PAGE_MASK, + AL_ETH_KR_AN_NP_ADV1_MSG_PAGE_SHIFT, + np->msg_page); + AL_REG_FIELD_SET(reg, AL_ETH_KR_AN_NP_ADV1_NP_MASK, + AL_ETH_KR_AN_NP_ADV1_NP_SHIFT, + np->next_page); + + al_eth_an_lt_reg_write(adapter, AL_ETH_KR_AN_XNP_ADV0, AL_ETH_AN_REGS, + AL_ETH_AN__LT_LANE_0, reg); + + al_eth_an_lt_reg_write(adapter, AL_ETH_KR_AN_XNP_ADV1, AL_ETH_AN_REGS, + AL_ETH_AN__LT_LANE_0, np->unformatted_code_field1); + al_eth_an_lt_reg_write(adapter, AL_ETH_KR_AN_XNP_ADV2, AL_ETH_AN_REGS, + AL_ETH_AN__LT_LANE_0, np->unformatted_code_field2); + + return 0; +} + +int al_eth_kr_an_init(struct al_hal_eth_adapter *adapter, + struct al_eth_an_adv *an_adv) +{ + int rc; + + if (adapter->rev_id > AL_ETH_REV_ID_2) + al_eth_an_lt_unit_config(adapter); + + rc = al_eth_kr_an_validate_adv(adapter, an_adv); + if (rc) + return rc; + + rc = al_eth_kr_an_write_adv(adapter, an_adv); + if (rc) + return rc; + + /* clear status */ + al_eth_an_lt_reg_read(adapter, AL_ETH_KR_AN_STATUS, AL_ETH_AN_REGS, AL_ETH_AN__LT_LANE_0); + + al_dbg("[%s]: autonegotiation initialized successfully", adapter->name); + return 0; +} + +int al_eth_kr_an_start(struct al_hal_eth_adapter *adapter, + enum al_eth_an_lt_lane lane, + al_bool next_page_enable, + al_bool lt_enable) +{ + uint16_t control = AL_ETH_KR_AN_CONTROL_ENABLE | AL_ETH_KR_AN_CONTROL_RESTART; + + al_dbg("Eth [%s]: enable autonegotiation. lt_en %s", + adapter->name, (lt_enable == AL_TRUE) ? "yes" : "no"); + + al_eth_an_lt_reg_write(adapter, AL_ETH_KR_PMD_CONTROL, AL_ETH_LT_REGS, + lane, AL_BIT(AL_ETH_KR_PMD_CONTROL_RESTART)); + + if (next_page_enable == AL_TRUE) + control |= AL_ETH_KR_AN_CONTROL_NP_ENABLE; + + al_eth_an_lt_reg_write(adapter, AL_ETH_KR_AN_CONTROL, AL_ETH_AN_REGS, + lane, control); + + if (lt_enable == AL_TRUE) { + al_eth_kr_lt_initialize(adapter, lane); + } + + return 0; +} + +void al_eth_kr_an_stop(struct al_hal_eth_adapter *adapter) +{ + al_eth_an_lt_reg_write(adapter, AL_ETH_KR_AN_CONTROL, AL_ETH_AN_REGS, + AL_ETH_AN__LT_LANE_0, 0); +} + +void al_eth_kr_an_status_check(struct al_hal_eth_adapter *adapter, + al_bool *page_received, + al_bool *an_completed, + al_bool *error) +{ + uint16_t reg; + + reg = al_eth_an_lt_reg_read(adapter, AL_ETH_KR_AN_STATUS, + AL_ETH_AN_REGS, AL_ETH_AN__LT_LANE_0); + + if ((reg & AL_ETH_KR_AN_STATUS_CHECK_MASK) != + AL_ETH_KR_AN_STATUS_CHECK_NO_ERROR) { + al_err("[%s]: %s AN_STATUS (0x%x) indicated error\n", + adapter->name, __func__, reg); + + *error = AL_TRUE; + } + + if (reg & AL_ETH_KR_AN_STATUS_BASE_PAGE_RECEIVED) + *page_received = AL_TRUE; + else + *page_received = AL_FALSE; + + if (reg & AL_ETH_KR_AN_STATUS_COMPLETED) + *an_completed = AL_TRUE; + else + *an_completed = AL_FALSE; +} + + +/****************************** KR Link Training *****************************/ +void al_eth_kr_lt_restart(struct al_hal_eth_adapter *adapter, + enum al_eth_an_lt_lane lane) +{ + al_dbg("[%s]: KR LT Restart Link Training.\n", adapter->name); + + al_eth_an_lt_reg_write(adapter, AL_ETH_KR_PMD_CONTROL, AL_ETH_LT_REGS, + lane, (AL_BIT(AL_ETH_KR_PMD_CONTROL_ENABLE) | + AL_BIT(AL_ETH_KR_PMD_CONTROL_RESTART))); +} + +void al_eth_kr_lt_stop(struct al_hal_eth_adapter *adapter, + enum al_eth_an_lt_lane lane) +{ + al_dbg("[%s]: KR LT Stop Link Training.\n", adapter->name); + + al_eth_an_lt_reg_write(adapter, AL_ETH_KR_PMD_CONTROL, AL_ETH_LT_REGS, + lane, AL_BIT(AL_ETH_KR_PMD_CONTROL_RESTART)); +} + +void al_eth_kr_lt_initialize(struct al_hal_eth_adapter *adapter, + enum al_eth_an_lt_lane lane) +{ + al_dbg("[%s]: KR LT Initialize.\n", adapter->name); + + /* Reset LT state machine */ + al_eth_kr_lt_stop(adapter, lane); + + /* clear receiver status */ + al_eth_an_lt_reg_write(adapter, AL_ETH_KR_PMD_STATUS, AL_ETH_LT_REGS, lane, 0); + + /* Coefficient Update to all zero (no command, hold) */ + al_eth_an_lt_reg_write(adapter, AL_ETH_KR_PMD_LD_COEF_UP, AL_ETH_LT_REGS, lane, 0); + /* Coefficient Status to all zero (not_updated) */ + al_eth_an_lt_reg_write(adapter, AL_ETH_KR_PMD_LD_STATUS_REPORT, AL_ETH_LT_REGS, lane, 0); + + /* start */ + al_eth_kr_lt_restart(adapter, lane); +} + +al_bool al_eth_kr_lt_frame_lock_wait(struct al_hal_eth_adapter *adapter, + enum al_eth_an_lt_lane lane, + uint32_t timeout) +{ + uint32_t loop; + uint16_t reg = 0; + + for (loop = 0; loop < timeout; loop++) { + reg = al_eth_an_lt_reg_read(adapter, AL_ETH_KR_PMD_STATUS, AL_ETH_LT_REGS, lane); + + if (AL_REG_BIT_GET(reg, AL_ETH_KR_PMD_STATUS_FAILURE_SHIFT)) { + al_info("[%s]: Failed on Training Failure." + " loops %d PMD STATUS 0x%04x\n", + adapter->name, loop, reg); + + return AL_FALSE; + } + if (AL_REG_BIT_GET(reg, + AL_ETH_KR_PMD_STATUS_RECEIVER_FRAME_LOCK_SHIFT)) { + al_dbg("[%s]: Frame lock received." + " loops %d PMD STATUS 0x%04x\n", + adapter->name, loop, reg); + + return AL_TRUE; + } + al_udelay(1); + } + al_info("[%s]: Failed on timeout. PMD STATUS 0x%04x\n", + adapter->name, reg); + + return AL_FALSE; +} diff --git a/eth/al_hal_eth_kr.h b/eth/al_hal_eth_kr.h new file mode 100644 index 00000000000..c8b69460aaa --- /dev/null +++ b/eth/al_hal_eth_kr.h @@ -0,0 +1,372 @@ +/*- +******************************************************************************* +Copyright (C) 2015 Annapurna Labs Ltd. + +This file may be licensed under the terms of the Annapurna Labs Commercial +License Agreement. + +Alternatively, this file can be distributed under the terms of the GNU General +Public License V2 as published by the Free Software Foundation and can be +found at http://www.gnu.org/licenses/gpl-2.0.html + +Alternatively, redistribution and use in source and binary forms, with or +without modification, are permitted provided that the following conditions are +met: + + * Redistributions of source code must retain the above copyright notice, +this list of conditions and the following disclaimer. + + * Redistributions in binary form must reproduce the above copyright +notice, this list of conditions and the following disclaimer in +the documentation and/or other materials provided with the +distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +*******************************************************************************/ +/** + * @defgroup group_eth_kr_api API + * Ethernet KR auto-neg and link-training driver API + * @ingroup group_eth + * @{ + * @file al_hal_eth_kr.h + * + * @brief Header file for KR driver + * + * + */ + +#ifndef __AL_HAL_ETH_KR_H__ +#define __AL_HAL_ETH_KR_H__ + +#include "al_hal_eth.h" + +/* *INDENT-OFF* */ +#ifdef __cplusplus +extern "C" { +#endif +/* *INDENT-ON* */ + +/* AN (Auto-negotiation) Advertisement Registers */ +struct al_eth_an_adv { + /* constant value defining 802.3ap support. + * The suggested value is 0x01.*/ + uint8_t selector_field; + /* Contains arbitrary data. */ + uint8_t echoed_nonce; + /* pause capability. */ + uint8_t capability; + /* Set to 1 to indicate a Remote Fault condition. + * Set to 0 to indicate normal operation.*/ + uint8_t remote_fault; + /* Should always be set to 0. */ + uint8_t acknowledge; + /* Set to 1 to indicate that the device has next pages to send. + * Set to 0 to indicate that that device has no next pages to send. */ + uint8_t next_page; + /* Must be set to an arbitrary value. + * Two devices must have a different nonce for autonegotiation to + * operate (a loopback will not allow autonegotiation to complete). */ + uint8_t transmitted_nonce; + uint32_t technology; +#define AL_ETH_AN_TECH_1000BASE_KX AL_BIT(0) +#define AL_ETH_AN_TECH_10GBASE_KX4 AL_BIT(1) +#define AL_ETH_AN_TECH_10GBASE_KR AL_BIT(2) +#define AL_ETH_AN_TECH_40GBASE_KR4 AL_BIT(3) +#define AL_ETH_AN_TECH_40GBASE_CR4 AL_BIT(4) +#define AL_ETH_AN_TECH_100GBASE_CR AL_BIT(5) + uint8_t fec_capability; +}; + +/* AN next page fields */ +struct al_eth_an_np { + /* These bits can be used as message code field or unformatted code field. + * When msg_page is true, these bits represent message code field. + * Predefined message code field Code Field should be used as specified in the standard + * 802.3ap. + * For the null message code the value is 0x01. + */ + uint16_t unformatted_code_field; + /* Flag to keep track of the state of the local device's Toggle bit. + * Initial value is taken from base page. Set to 0. + */ + al_bool toggle; + /* Acknowledge 2 is used to indicate that the receiver is able to act on the information + * (or perform the task) defined in the message. + */ + al_bool ack2; + al_bool msg_page; + /* If the device does not have any more Next Pages to send, set to AL_FALSE */ + al_bool next_page; + uint16_t unformatted_code_field1; + uint16_t unformatted_code_field2; +}; + +enum al_eth_kr_cl72_cstate { + C72_CSTATE_NOT_UPDATED = 0, + C72_CSTATE_UPDATED = 1, + C72_CSTATE_MIN = 2, + C72_CSTATE_MAX = 3, +}; + +enum al_eth_kr_cl72_coef_op { + AL_PHY_KR_COEF_UP_HOLD = 0, + AL_PHY_KR_COEF_UP_INC = 1, + AL_PHY_KR_COEF_UP_DEC = 2, + AL_PHY_KR_COEF_UP_RESERVED = 3 +}; + +struct al_eth_kr_coef_up_data { + enum al_eth_kr_cl72_coef_op c_zero; + enum al_eth_kr_cl72_coef_op c_plus; + enum al_eth_kr_cl72_coef_op c_minus; + al_bool preset; + al_bool initialize; +}; + +struct al_eth_kr_status_report_data { + enum al_eth_kr_cl72_cstate c_zero; + enum al_eth_kr_cl72_cstate c_plus; + enum al_eth_kr_cl72_cstate c_minus; + al_bool receiver_ready; +}; + +enum al_eth_an_lt_lane { + AL_ETH_AN__LT_LANE_0, + AL_ETH_AN__LT_LANE_1, + AL_ETH_AN__LT_LANE_2, + AL_ETH_AN__LT_LANE_3, +}; + +/** + * get the last received coefficient update message from the link partner + * + * @param adapter pointer to the private structure + * @param lane lane number + * @param lpcoeff coeff update received + * + */ +void al_eth_lp_coeff_up_get( + struct al_hal_eth_adapter *adapter, + enum al_eth_an_lt_lane lane, + struct al_eth_kr_coef_up_data *lpcoeff); + +/** + * get the last received status report message from the link partner + * + * @param adapter pointer to the private structure + * @param lane lane number + * @param status status report received + * + */ +void al_eth_lp_status_report_get( + struct al_hal_eth_adapter *adapter, + enum al_eth_an_lt_lane lane, + struct al_eth_kr_status_report_data *status); + +/** + * set the coefficient data for the next message that will be sent to lp + * + * @param adapter pointer to the private structure + * @param lane lane number + * @param ldcoeff coeff update to send + * + */ +void al_eth_ld_coeff_up_set( + struct al_hal_eth_adapter *adapter, + enum al_eth_an_lt_lane lane, + struct al_eth_kr_coef_up_data *ldcoeff); + +/** + * set the status report message for the next message that will be sent to lp + * + * @param adapter pointer to the private structure + * @param lane lane number + * @param status status report to send + * + */ +void al_eth_ld_status_report_set( + struct al_hal_eth_adapter *adapter, + enum al_eth_an_lt_lane lane, + struct al_eth_kr_status_report_data *status); + +/** + * get the receiver frame lock status + * + * @param adapter pointer to the private structure + * @param lane lane number + * + * @return true if Training frame delineation is detected, otherwise false. + */ +al_bool al_eth_kr_receiver_frame_lock_get(struct al_hal_eth_adapter *adapter, + enum al_eth_an_lt_lane lane); + +/** + * get the start up protocol progress status + * + * @param adapter pointer to the private structure + * @param lane lane number + * + * @return true if the startup protocol is in progress. + */ +al_bool al_eth_kr_startup_proto_prog_get(struct al_hal_eth_adapter *adapter, + enum al_eth_an_lt_lane lane); + +/** + * indicate the receiver is ready (the link training is completed) + * + * @param adapter pointer to the private structure + * @param lane lane number + * + */ +void al_eth_receiver_ready_set(struct al_hal_eth_adapter *adapter, + enum al_eth_an_lt_lane lane); + +/** + * read Training failure status. + * + * @param adapter pointer to the private structure + * @param lane lane number + * + *@return true if Training failure has been detected. + */ +al_bool al_eth_kr_training_status_fail_get(struct al_hal_eth_adapter *adapter, + enum al_eth_an_lt_lane lane); + +/****************************** auto negotiation *******************************/ +/** + * Initialize Auto-negotiation + * - Program Ability Registers (Advertisement Registers) + * - Clear Status latches + * @param adapter pointer to the private structure + * @param an_adv pointer to the AN Advertisement Registers structure + * when NULL, the registers will not be updated. + * + * @return 0 on success. otherwise on failure. + */ +int al_eth_kr_an_init(struct al_hal_eth_adapter *adapter, + struct al_eth_an_adv *an_adv); + +/** + * Enable/Restart Auto-negotiation + * + * @param adapter pointer to the private structure + * @param lane lane number + * @param lt_enable initialize link training as well + * + * @return 0 on success. otherwise on failure. + */ +int al_eth_kr_an_start(struct al_hal_eth_adapter *adapter, + enum al_eth_an_lt_lane lane, + al_bool next_page_enable, + al_bool lt_enable); + + +int al_eth_kr_next_page_write(struct al_hal_eth_adapter *adapter, + struct al_eth_an_np *np); + +int al_eth_kr_next_page_read(struct al_hal_eth_adapter *adapter, + struct al_eth_an_np *np); + +/** + * Stop Auto-negotiation + * + * Stopping the auto-negotiation will prevent the mac from sending the last page + * to the link partner in case it start the AN again. It must be called after + * link training is completed or the software will lose sync with the HW state + * machine + * + * @param adapter pointer to the private structure + * + */ +void al_eth_kr_an_stop(struct al_hal_eth_adapter *adapter); + +/** + * Check Auto-negotiation event done + * + * @param adapter pointer to the private structure + * @param page_received Set to true if the AN page received indication is set. + * Set to false otherwise. + * @param an_completed Set to true of the AN completed indication is set. + * Set to false otherwise. + * @param error Set to true if any error encountered + * + */ +void al_eth_kr_an_status_check(struct al_hal_eth_adapter *adapter, + al_bool *page_received, + al_bool *an_completed, + al_bool *error); + +/** + * Read the remote auto-negotiation advertising. + * This function is safe to called after al_eth_kr_an_status_check returned + * with page_received set. + * + * @param adapter pointer to the private structure + * @param an_adv pointer to the AN Advertisement Registers structure + * + */ +void al_eth_kr_an_read_adv(struct al_hal_eth_adapter *adapter, + struct al_eth_an_adv *an_adv); + +/****************************** link training **********************************/ +/** + * Initialize Link-training. + * Clear the status register and set the local coefficient update and status + * to zero. + * + * @param adapter pointer to the private structure + * @param lane lane number + * + */ +void al_eth_kr_lt_initialize(struct al_hal_eth_adapter *adapter, + enum al_eth_an_lt_lane lane); + +/** + * Wait for frame lock. + * + * @param adapter pointer to the private structure + * @param lane lane number + * @param timeout timeout in usec. + * + * @return true if frame lock received. false otherwise. + */ +al_bool al_eth_kr_lt_frame_lock_wait(struct al_hal_eth_adapter *adapter, + enum al_eth_an_lt_lane lane, + uint32_t timeout); + +/** + * reset the 10GBase- KR startup protocol and begin its operation + * + * @param adapter pointer to the private structure + * @param lane lane number + * + */ +void al_eth_kr_lt_restart(struct al_hal_eth_adapter *adapter, + enum al_eth_an_lt_lane lane); + +/** + * reset the 10GBase- KR startup protocol and end its operation + * + * @param adapter pointer to the private structure + * @param lane lane number + * + */ +void al_eth_kr_lt_stop(struct al_hal_eth_adapter *adapter, + enum al_eth_an_lt_lane lane); + +#ifdef __cplusplus +} +#endif +/* *INDENT-ON* */ +#endif /*__AL_HAL_ETH_KR_H__*/ +/** @} end of Ethernet kr group */ diff --git a/eth/al_hal_eth_mac_regs.h b/eth/al_hal_eth_mac_regs.h new file mode 100644 index 00000000000..a2dc745ffde --- /dev/null +++ b/eth/al_hal_eth_mac_regs.h @@ -0,0 +1,1809 @@ +/*- +******************************************************************************* +Copyright (C) 2015 Annapurna Labs Ltd. + +This file may be licensed under the terms of the Annapurna Labs Commercial +License Agreement. + +Alternatively, this file can be distributed under the terms of the GNU General +Public License V2 as published by the Free Software Foundation and can be +found at http://www.gnu.org/licenses/gpl-2.0.html + +Alternatively, redistribution and use in source and binary forms, with or +without modification, are permitted provided that the following conditions are +met: + + * Redistributions of source code must retain the above copyright notice, +this list of conditions and the following disclaimer. + + * Redistributions in binary form must reproduce the above copyright +notice, this list of conditions and the following disclaimer in +the documentation and/or other materials provided with the +distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +*******************************************************************************/ + +/** + * @{ + * @file al_hal_eth_mac_regs.h + * + * @brief Ethernet MAC registers + * + */ + +#ifndef __AL_HAL_ETH_MAC_REGS_H__ +#define __AL_HAL_ETH_MAC_REGS_H__ + +#include "al_hal_plat_types.h" + +#ifdef __cplusplus +extern "C" { +#endif +/* +* Unit Registers +*/ + +struct al_eth_mac_1g { + /* [0x0] */ + uint32_t rev; + uint32_t scratch; + uint32_t cmd_cfg; + uint32_t mac_0; + /* [0x10] */ + uint32_t mac_1; + uint32_t frm_len; + uint32_t pause_quant; + uint32_t rx_section_empty; + /* [0x20] */ + uint32_t rx_section_full; + uint32_t tx_section_empty; + uint32_t tx_section_full; + uint32_t rx_almost_empty; + /* [0x30] */ + uint32_t rx_almost_full; + uint32_t tx_almost_empty; + uint32_t tx_almost_full; + uint32_t mdio_addr0; + /* [0x40] */ + uint32_t mdio_addr1; + uint32_t Reserved[5]; + /* [0x58] */ + uint32_t reg_stat; + uint32_t tx_ipg_len; + /* [0x60] */ + uint32_t Reserved1[104]; + /* [0x200] */ + uint32_t phy_regs_base; + uint32_t Reserved2[127]; +}; + +struct al_eth_mac_10g { + /* [0x0] */ + uint32_t rev; + uint32_t scratch; + uint32_t cmd_cfg; + uint32_t mac_0; + /* [0x10] */ + uint32_t mac_1; + uint32_t frm_len; + uint32_t Reserved; + uint32_t rx_fifo_sections; + /* [0x20] */ + uint32_t tx_fifo_sections; + uint32_t rx_fifo_almost_f_e; + uint32_t tx_fifo_almost_f_e; + uint32_t hashtable_load; + /* [0x30] */ + uint32_t mdio_cfg_status; + uint16_t mdio_cmd; + uint16_t reserved1; + uint16_t mdio_data; + uint16_t reserved2; + uint16_t mdio_regaddr; + uint16_t reserved3; + /* [0x40] */ + uint32_t status; + uint32_t tx_ipg_len; + uint32_t Reserved1[3]; + /* [0x54] */ + uint32_t cl01_pause_quanta; + uint32_t cl23_pause_quanta; + uint32_t cl45_pause_quanta; + /* [0x60] */ + uint32_t cl67_pause_quanta; + uint32_t cl01_quanta_thresh; + uint32_t cl23_quanta_thresh; + uint32_t cl45_quanta_thresh; + /* [0x70] */ + uint32_t cl67_quanta_thresh; + uint32_t rx_pause_status; + uint32_t Reserved2; + uint32_t ts_timestamp; + /* [0x80] */ + + uint32_t Reserved3[160]; + + /* [0x300] */ + uint32_t control; + uint32_t status_reg; + uint32_t phy_id[2]; + /* [0x310] */ + uint32_t dev_ability; + uint32_t partner_ability; + uint32_t an_expansion; + uint32_t device_np; + /* [0x320] */ + uint32_t partner_np; + uint32_t Reserved4[9]; + + /* [0x348] */ + uint32_t link_timer_lo; + uint32_t link_timer_hi; + /* [0x350] */ + uint32_t if_mode; + + uint32_t Reserved5[43]; +}; + +struct al_eth_mac_gen { + /* [0x0] Ethernet Controller Version */ + uint32_t version; + uint32_t rsrvd_0[2]; + /* [0xc] MAC selection configuration */ + uint32_t cfg; + /* [0x10] 10/100/1000 MAC external configuration */ + uint32_t mac_1g_cfg; + /* [0x14] 10/100/1000 MAC status */ + uint32_t mac_1g_stat; + /* [0x18] RGMII external configuration */ + uint32_t rgmii_cfg; + /* [0x1c] RGMII status */ + uint32_t rgmii_stat; + /* [0x20] 1/2.5/10G MAC external configuration */ + uint32_t mac_10g_cfg; + /* [0x24] 1/2.5/10G MAC status */ + uint32_t mac_10g_stat; + /* [0x28] XAUI PCS configuration */ + uint32_t xaui_cfg; + /* [0x2c] XAUI PCS status */ + uint32_t xaui_stat; + /* [0x30] RXAUI PCS configuration */ + uint32_t rxaui_cfg; + /* [0x34] RXAUI PCS status */ + uint32_t rxaui_stat; + /* [0x38] Signal detect configuration */ + uint32_t sd_cfg; + /* [0x3c] MDIO control register for MDIO interface 1 */ + uint32_t mdio_ctrl_1; + /* [0x40] MDIO information register for MDIO interface 1 */ + uint32_t mdio_1; + /* [0x44] MDIO control register for MDIO interface 2 */ + uint32_t mdio_ctrl_2; + /* [0x48] MDIO information register for MDIO interface 2 */ + uint32_t mdio_2; + /* [0x4c] XGMII 32 to 64 data FIFO control */ + uint32_t xgmii_dfifo_32_64; + /* [0x50] Reserved 1 out */ + uint32_t mac_res_1_out; + /* [0x54] XGMII 64 to 32 data FIFO control */ + uint32_t xgmii_dfifo_64_32; + /* [0x58] Reserved 1 in */ + uint32_t mac_res_1_in; + /* [0x5c] SerDes TX FIFO control */ + uint32_t sd_fifo_ctrl; + /* [0x60] SerDes TX FIFO status */ + uint32_t sd_fifo_stat; + /* [0x64] SerDes in/out selection */ + uint32_t mux_sel; + /* [0x68] Clock configuration */ + uint32_t clk_cfg; + uint32_t rsrvd_1; + /* [0x70] LOS and SD selection */ + uint32_t los_sel; + /* [0x74] RGMII selection configuration */ + uint32_t rgmii_sel; + /* [0x78] Ethernet LED configuration */ + uint32_t led_cfg; + uint32_t rsrvd[33]; +}; +struct al_eth_mac_kr { + /* [0x0] PCS register file address */ + uint32_t pcs_addr; + /* [0x4] PCS register file data */ + uint32_t pcs_data; + /* [0x8] AN register file address */ + uint32_t an_addr; + /* [0xc] AN register file data */ + uint32_t an_data; + /* [0x10] PMA register file address */ + uint32_t pma_addr; + /* [0x14] PMA register file data */ + uint32_t pma_data; + /* [0x18] MTIP register file address */ + uint32_t mtip_addr; + /* [0x1c] MTIP register file data */ + uint32_t mtip_data; + /* [0x20] KR PCS config */ + uint32_t pcs_cfg; + /* [0x24] KR PCS status */ + uint32_t pcs_stat; + uint32_t rsrvd[54]; +}; +struct al_eth_mac_sgmii { + /* [0x0] PCS register file address */ + uint32_t reg_addr; + /* [0x4] PCS register file data */ + uint32_t reg_data; + /* [0x8] PCS clock divider configuration */ + uint32_t clk_div; + /* [0xc] PCS Status */ + uint32_t link_stat; + uint32_t rsrvd[60]; +}; +struct al_eth_mac_stat { + /* [0x0] Receive rate matching error */ + uint32_t match_fault; + /* [0x4] EEE, number of times the MAC went into low power mode */ + uint32_t eee_in; + /* [0x8] EEE, number of times the MAC went out of low power mode */ + uint32_t eee_out; + /* + * [0xc] 40G PCS, + * FEC corrected error indication + */ + uint32_t v3_pcs_40g_ll_cerr_0; + /* + * [0x10] 40G PCS, + * FEC corrected error indication + */ + uint32_t v3_pcs_40g_ll_cerr_1; + /* + * [0x14] 40G PCS, + * FEC corrected error indication + */ + uint32_t v3_pcs_40g_ll_cerr_2; + /* + * [0x18] 40G PCS, + * FEC corrected error indication + */ + uint32_t v3_pcs_40g_ll_cerr_3; + /* + * [0x1c] 40G PCS, + * FEC uncorrectable error indication + */ + uint32_t v3_pcs_40g_ll_ncerr_0; + /* + * [0x20] 40G PCS, + * FEC uncorrectable error indication + */ + uint32_t v3_pcs_40g_ll_ncerr_1; + /* + * [0x24] 40G PCS, + * FEC uncorrectable error indication + */ + uint32_t v3_pcs_40g_ll_ncerr_2; + /* + * [0x28] 40G PCS, + * FEC uncorrectable error indication + */ + uint32_t v3_pcs_40g_ll_ncerr_3; + /* + * [0x2c] 10G_LL PCS, + * FEC corrected error indication + */ + uint32_t v3_pcs_10g_ll_cerr; + /* + * [0x30] 10G_LL PCS, + * FEC uncorrectable error indication + */ + uint32_t v3_pcs_10g_ll_ncerr; + uint32_t rsrvd[51]; +}; +struct al_eth_mac_stat_lane { + /* [0x0] Character error */ + uint32_t char_err; + /* [0x4] Disparity error */ + uint32_t disp_err; + /* [0x8] Comma detection */ + uint32_t pat; + uint32_t rsrvd[13]; +}; +struct al_eth_mac_gen_v3 { + /* [0x0] ASYNC FIFOs control */ + uint32_t afifo_ctrl; + /* [0x4] TX ASYNC FIFO configuration */ + uint32_t tx_afifo_cfg_1; + /* [0x8] TX ASYNC FIFO configuration */ + uint32_t tx_afifo_cfg_2; + /* [0xc] TX ASYNC FIFO configuration */ + uint32_t tx_afifo_cfg_3; + /* [0x10] TX ASYNC FIFO configuration */ + uint32_t tx_afifo_cfg_4; + /* [0x14] TX ASYNC FIFO configuration */ + uint32_t tx_afifo_cfg_5; + /* [0x18] RX ASYNC FIFO configuration */ + uint32_t rx_afifo_cfg_1; + /* [0x1c] RX ASYNC FIFO configuration */ + uint32_t rx_afifo_cfg_2; + /* [0x20] RX ASYNC FIFO configuration */ + uint32_t rx_afifo_cfg_3; + /* [0x24] RX ASYNC FIFO configuration */ + uint32_t rx_afifo_cfg_4; + /* [0x28] RX ASYNC FIFO configuration */ + uint32_t rx_afifo_cfg_5; + /* [0x2c] MAC selection configuration */ + uint32_t mac_sel; + /* [0x30] 10G LL MAC configuration */ + uint32_t mac_10g_ll_cfg; + /* [0x34] 10G LL MAC control */ + uint32_t mac_10g_ll_ctrl; + /* [0x38] 10G LL PCS configuration */ + uint32_t pcs_10g_ll_cfg; + /* [0x3c] 10G LL PCS status */ + uint32_t pcs_10g_ll_status; + /* [0x40] 40G LL PCS configuration */ + uint32_t pcs_40g_ll_cfg; + /* [0x44] 40G LL PCS status */ + uint32_t pcs_40g_ll_status; + /* [0x48] PCS 40G register file address */ + uint32_t pcs_40g_ll_addr; + /* [0x4c] PCS 40G register file data */ + uint32_t pcs_40g_ll_data; + /* [0x50] 40G LL MAC configuration */ + uint32_t mac_40g_ll_cfg; + /* [0x54] 40G LL MAC status */ + uint32_t mac_40g_ll_status; + /* [0x58] Preamble configuration (high [55:32]) */ + uint32_t preamble_cfg_high; + /* [0x5c] Preamble configuration (low [31:0]) */ + uint32_t preamble_cfg_low; + /* [0x60] MAC 40G register file address */ + uint32_t mac_40g_ll_addr; + /* [0x64] MAC 40G register file data */ + uint32_t mac_40g_ll_data; + /* [0x68] 40G LL MAC control */ + uint32_t mac_40g_ll_ctrl; + /* [0x6c] PCS 40G register file address */ + uint32_t pcs_40g_fec_91_ll_addr; + /* [0x70] PCS 40G register file data */ + uint32_t pcs_40g_fec_91_ll_data; + /* [0x74] 40G LL PCS EEE configuration */ + uint32_t pcs_40g_ll_eee_cfg; + /* [0x78] 40G LL PCS EEE status */ + uint32_t pcs_40g_ll_eee_status; + /* + * [0x7c] SERDES 32-bit interface shift configuration (when swap is + * enabled) + */ + uint32_t serdes_32_tx_shift; + /* + * [0x80] SERDES 32-bit interface shift configuration (when swap is + * enabled) + */ + uint32_t serdes_32_rx_shift; + /* + * [0x84] SERDES 32-bit interface bit selection + */ + uint32_t serdes_32_tx_sel; + /* + * [0x88] SERDES 32-bit interface bit selection + */ + uint32_t serdes_32_rx_sel; + /* [0x8c] AN/LT wrapper control */ + uint32_t an_lt_ctrl; + /* [0x90] AN/LT wrapper register file address */ + uint32_t an_lt_0_addr; + /* [0x94] AN/LT wrapper register file data */ + uint32_t an_lt_0_data; + /* [0x98] AN/LT wrapper register file address */ + uint32_t an_lt_1_addr; + /* [0x9c] AN/LT wrapper register file data */ + uint32_t an_lt_1_data; + /* [0xa0] AN/LT wrapper register file address */ + uint32_t an_lt_2_addr; + /* [0xa4] AN/LT wrapper register file data */ + uint32_t an_lt_2_data; + /* [0xa8] AN/LT wrapper register file address */ + uint32_t an_lt_3_addr; + /* [0xac] AN/LT wrapper register file data */ + uint32_t an_lt_3_data; + /* [0xb0] External SERDES control */ + uint32_t ext_serdes_ctrl; + /* [0xb4] spare bits */ + uint32_t spare; + uint32_t rsrvd[18]; +}; + +struct al_eth_mac_regs { + struct al_eth_mac_1g mac_1g; /* [0x000] */ + struct al_eth_mac_10g mac_10g; /* [0x400] */ + uint32_t rsrvd_0[64]; /* [0x800] */ + struct al_eth_mac_gen gen; /* [0x900] */ + struct al_eth_mac_kr kr; /* [0xa00] */ + struct al_eth_mac_sgmii sgmii; /* [0xb00] */ + struct al_eth_mac_stat stat; /* [0xc00] */ + struct al_eth_mac_stat_lane stat_lane[4]; /* [0xd00] */ + struct al_eth_mac_gen_v3 gen_v3; /* [0xe00] */ +}; + + +/* +* Registers Fields +*/ + +/**** control register (1G mac) ****/ +/* enable Half Duplex */ +#define AL_ETH_1G_MAC_CTRL_HD_EN (1 << 10) +/* enable 1G speed */ +#define AL_ETH_1G_MAC_CTRL_1G_SPD (1 << 3) +/* enable 10M speed */ +#define AL_ETH_1G_MAC_CTRL_10M_SPD (1 << 25) + + +/**** 10G MAC register ****/ +/* mdio_cfg_status */ +#define ETH_10G_MAC_MDIO_CFG_HOLD_TIME_MASK 0x0000001c +#define ETH_10G_MAC_MDIO_CFG_HOLD_TIME_SHIFT 2 + +#define ETH_10G_MAC_MDIO_CFG_HOLD_TIME_1_CLK 0 +#define ETH_10G_MAC_MDIO_CFG_HOLD_TIME_3_CLK 1 +#define ETH_10G_MAC_MDIO_CFG_HOLD_TIME_5_CLK 2 +#define ETH_10G_MAC_MDIO_CFG_HOLD_TIME_7_CLK 3 +#define ETH_10G_MAC_MDIO_CFG_HOLD_TIME_9_CLK 4 +#define ETH_10G_MAC_MDIO_CFG_HOLD_TIME_11_CLK 5 +#define ETH_10G_MAC_MDIO_CFG_HOLD_TIME_13_CLK 6 +#define ETH_10G_MAC_MDIO_CFG_HOLD_TIME_15_CLK 7 + +/**** version register ****/ +/* Revision number (Minor) */ +#define ETH_MAC_GEN_VERSION_RELEASE_NUM_MINOR_MASK 0x000000FF +#define ETH_MAC_GEN_VERSION_RELEASE_NUM_MINOR_SHIFT 0 +/* Revision number (Major) */ +#define ETH_MAC_GEN_VERSION_RELEASE_NUM_MAJOR_MASK 0x0000FF00 +#define ETH_MAC_GEN_VERSION_RELEASE_NUM_MAJOR_SHIFT 8 +/* Date of release */ +#define ETH_MAC_GEN_VERSION_DATE_DAY_MASK 0x001F0000 +#define ETH_MAC_GEN_VERSION_DATE_DAY_SHIFT 16 +/* Month of release */ +#define ETH_MAC_GEN_VERSION_DATA_MONTH_MASK 0x01E00000 +#define ETH_MAC_GEN_VERSION_DATA_MONTH_SHIFT 21 +/* Year of release (starting from 2000) */ +#define ETH_MAC_GEN_VERSION_DATE_YEAR_MASK 0x3E000000 +#define ETH_MAC_GEN_VERSION_DATE_YEAR_SHIFT 25 +/* Reserved */ +#define ETH_MAC_GEN_VERSION_RESERVED_MASK 0xC0000000 +#define ETH_MAC_GEN_VERSION_RESERVED_SHIFT 30 + +/**** cfg register ****/ +/* + * Selects between the 10/100/1000 MAC and the 1/2.5/10G MAC: + * 0 - 10/100/1000 + * 1 - 1/2.5/10G + */ +#define ETH_MAC_GEN_CFG_MAC_1_10 (1 << 0) +/* + * Selects the operation mode of the 1/2.5/10G MAC: + * 00 - 1/2.5G SGMII + * 01 - 10G XAUI/RXAUI + * 10 – 10G KR + * 11 – Reserved + */ +#define ETH_MAC_GEN_CFG_XGMII_SGMII_MASK 0x00000006 +#define ETH_MAC_GEN_CFG_XGMII_SGMII_SHIFT 1 +/* + * Selects the operation mode of the PCS: + * 0 - XAUI + * 1 - RXAUI + */ +#define ETH_MAC_GEN_CFG_XAUI_RXAUI (1 << 3) +/* Swap bits of TBI (SGMII mode) interface */ +#define ETH_MAC_GEN_CFG_SWAP_TBI_RX (1 << 4) +/* + * Determines the offset of the TBI bus on the SerDes interface: + * 0 - LSB + * 1 - MSB + */ +#define ETH_MAC_GEN_CFG_TBI_MSB_RX (1 << 5) +/* + * Selects the SGMII PCS/MAC: + * 0 – 10G MAC with SGMII + * 1 – 1G MAC with SGMII + */ +#define ETH_MAC_GEN_CFG_SGMII_SEL (1 << 6) +/* + * Selects between RGMII and SGMII for the 1G MAC: + * 0 – RGMII + * 1 – SGMII + */ +#define ETH_MAC_GEN_CFG_RGMII_SGMII_SEL (1 << 7) +/* Swap bits of TBI (SGMII mode) interface */ +#define ETH_MAC_GEN_CFG_SWAP_TBI_TX (1 << 8) +/* + * Determines the offset of the TBI bus on the SerDes interface: + * 0 - LSB + * 1 - MSB + */ +#define ETH_MAC_GEN_CFG_TBI_MSB_TX (1 << 9) +/* + * Selection between the MDIO from 10/100/1000 MAC or the 1/2.5/10G MAC + * 0 - 10/100/1000 + * 1 - 1/2.5/10G + */ +#define ETH_MAC_GEN_CFG_MDIO_1_10 (1 << 10) +/* + * Swap MDC output + * 0 – Normal + * 1 – Flipped + */ +#define ETH_MAC_GEN_CFG_MDIO_POL (1 << 11) +/* Swap bits on SerDes interface */ +#define ETH_MAC_GEN_CFG_SWAP_SERDES_RX_MASK 0x000F0000 +#define ETH_MAC_GEN_CFG_SWAP_SERDES_RX_SHIFT 16 +/* Swap bits on SerDes interface */ +#define ETH_MAC_GEN_CFG_SWAP_SERDES_TX_MASK 0x0F000000 +#define ETH_MAC_GEN_CFG_SWAP_SERDES_TX_SHIFT 24 + +/**** mac_1g_cfg register ****/ +/* + * Selection of the input for the "set_1000" input of the Ethernet 10/100/1000 + * MAC: + * 0 - From RGMII converter (automatic speed selection) + * 1 - From register set_1000_def + */ +#define ETH_MAC_GEN_MAC_1G_CFG_SET_1000_SEL (1 << 0) +/* Default value for the 10/100/1000 MAC "set_1000" input */ +#define ETH_MAC_GEN_MAC_1G_CFG_SET_1000_DEF (1 << 1) +/* + * Selection of the input for the "set_10" input of the Ethernet 10/100/1000 + * MAC: + * 0 - From RGMII converter (automatic speed selection) + * 1 - From register set_10_def + */ +#define ETH_MAC_GEN_MAC_1G_CFG_SET_10_SEL (1 << 4) +/* Default value for the 10/100/1000 MAC "set_10" input */ +#define ETH_MAC_GEN_MAC_1G_CFG_SET_10_DEF (1 << 5) +/* Transmit low power enable */ +#define ETH_MAC_GEN_MAC_1G_CFG_LOWP_ENA (1 << 8) +/* + * Enable magic packet mode: + * 0 - Sleep mode + * 1 - Normal operation + */ +#define ETH_MAC_GEN_MAC_1G_CFG_SLEEPN (1 << 9) +/* Swap ff_tx_crc input */ +#define ETH_MAC_GEN_MAC_1G_CFG_SWAP_FF_TX_CRC (1 << 12) + +/**** mac_1g_stat register ****/ +/* Status of the en_10 output form the 10/100/1000 MAC */ +#define ETH_MAC_GEN_MAC_1G_STAT_EN_10 (1 << 0) +/* Status of the eth_mode output from th 10/100/1000 MAC */ +#define ETH_MAC_GEN_MAC_1G_STAT_ETH_MODE (1 << 1) +/* Status of the lowp output from the 10/100/1000 MAC */ +#define ETH_MAC_GEN_MAC_1G_STAT_LOWP (1 << 4) +/* Status of the wakeup output from the 10/100/1000 MAC */ +#define ETH_MAC_GEN_MAC_1G_STAT_WAKEUP (1 << 5) + +/**** rgmii_cfg register ****/ +/* + * Selection of the input for the "set_1000" input of the RGMII converter + * 0 - From MAC + * 1 - From register set_1000_def (automatic speed selection) + */ +#define ETH_MAC_GEN_RGMII_CFG_SET_1000_SEL (1 << 0) +/* Default value for the RGMII converter "set_1000" input */ +#define ETH_MAC_GEN_RGMII_CFG_SET_1000_DEF (1 << 1) +/* + * Selection of the input for the "set_10" input of the RGMII converter: + * 0 - From MAC + * 1 - From register set_10_def (automatic speed selection) + */ +#define ETH_MAC_GEN_RGMII_CFG_SET_10_SEL (1 << 4) +/* Default value for the 10/100/1000 MAC "set_10" input */ +#define ETH_MAC_GEN_RGMII_CFG_SET_10_DEF (1 << 5) +/* Enable automatic speed selection (based on PHY in-band status information) */ +#define ETH_MAC_GEN_RGMII_CFG_ENA_AUTO (1 << 8) +/* Force full duplex, only valid when ena_auto is '1'. */ +#define ETH_MAC_GEN_RGMII_CFG_SET_FD (1 << 9) + +/**** rgmii_stat register ****/ +/* + * Status of the speed output form the RGMII converter + * 00 - 10 Mbps + * 01 - 100 Mbps + * 10 - 1000 Mbps + * 11 - Reserved + */ +#define ETH_MAC_GEN_RGMII_STAT_SPEED_MASK 0x00000003 +#define ETH_MAC_GEN_RGMII_STAT_SPEED_SHIFT 0 +/* + * Link indication from the RGMII converter (valid only if the external PHY + * supports in-band status signaling) + */ +#define ETH_MAC_GEN_RGMII_STAT_LINK (1 << 4) +/* + * Full duplex indication from the RGMII converter (valid only if the external + * PHY supports in-band status signaling) + */ +#define ETH_MAC_GEN_RGMII_STAT_DUP (1 << 5) + +/**** mac_10g_cfg register ****/ +/* Instruct the XGMII to transmit local fault. */ +#define ETH_MAC_GEN_MAC_10G_CFG_TX_LOC_FAULT (1 << 0) +/* Instruct the XGMII to transmit remote fault. */ +#define ETH_MAC_GEN_MAC_10G_CFG_TX_REM_FAULT (1 << 1) +/* Instruct the XGMII to transmit link fault. */ +#define ETH_MAC_GEN_MAC_10G_CFG_TX_LI_FAULT (1 << 2) +/* + * Synchronous reset for the PCS layer. Can be used after SerDes lock assertion + * to reset the PCS state machine. + */ +#define ETH_MAC_GEN_MAC_10G_CFG_SG_SRESET (1 << 3) +/* + * PHY LOS indication selection + * 00 - Select register value from phy_los_def + * 01 - Select input from the SerDes + * 10 - Select input from GPIO + * 11 - Select inverted input from GPIO + */ +#define ETH_MAC_GEN_MAC_10G_CFG_PHY_LOS_SEL_MASK 0x00000030 +#define ETH_MAC_GEN_MAC_10G_CFG_PHY_LOS_SEL_SHIFT 4 +/* + * Default value for PHY LOS indication. Reflects the LOS indication from the + * SerDes. ('0' if not used) + */ +#define ETH_MAC_GEN_MAC_10G_CFG_PHY_LOS_DEF (1 << 6) +/* Reverse polarity of the LOS signal from the SerDes */ +#define ETH_MAC_GEN_MAC_10G_CFG_PHY_LOS_POL (1 << 7) +/* Transmit low power enable */ +#define ETH_MAC_GEN_MAC_10G_CFG_LOWP_ENA (1 << 8) +/* Swap ff_tx_crc input */ +#define ETH_MAC_GEN_MAC_10G_CFG_SWAP_FF_TX_CRC (1 << 12) + +/**** mac_10g_stat register ****/ +/* XGMII RS detects local fault */ +#define ETH_MAC_GEN_MAC_10G_STAT_LOC_FAULT (1 << 0) +/* XGMII RS detects remote fault */ +#define ETH_MAC_GEN_MAC_10G_STAT_REM_FAULT (1 << 1) +/* XGMII RS detects link fault */ +#define ETH_MAC_GEN_MAC_10G_STAT_LI_FAULT (1 << 2) +/* PFC mode */ +#define ETH_MAC_GEN_MAC_10G_STAT_PFC_MODE (1 << 3) + +#define ETH_MAC_GEN_MAC_10G_STAT_SG_ENA (1 << 4) + +#define ETH_MAC_GEN_MAC_10G_STAT_SG_ANDONE (1 << 5) + +#define ETH_MAC_GEN_MAC_10G_STAT_SG_SYNC (1 << 6) + +#define ETH_MAC_GEN_MAC_10G_STAT_SG_SPEED_MASK 0x00000180 +#define ETH_MAC_GEN_MAC_10G_STAT_SG_SPEED_SHIFT 7 +/* Status of the lowp output form the 1/2.5/10G MAC */ +#define ETH_MAC_GEN_MAC_10G_STAT_LOWP (1 << 9) +/* Status of the ts_avail output from th 1/2.5/10G MAC */ +#define ETH_MAC_GEN_MAC_10G_STAT_TS_AVAIL (1 << 10) +/* Transmit pause indication */ +#define ETH_MAC_GEN_MAC_10G_STAT_PAUSE_ON_MASK 0xFF000000 +#define ETH_MAC_GEN_MAC_10G_STAT_PAUSE_ON_SHIFT 24 + +/**** xaui_cfg register ****/ +/* Increase rate matching FIFO threshold */ +#define ETH_MAC_GEN_XAUI_CFG_JUMBO_EN (1 << 0) + +/**** xaui_stat register ****/ +/* Lane alignment status */ +#define ETH_MAC_GEN_XAUI_STAT_ALIGN_DONE (1 << 0) +/* Lane synchronization */ +#define ETH_MAC_GEN_XAUI_STAT_SYNC_MASK 0x000000F0 +#define ETH_MAC_GEN_XAUI_STAT_SYNC_SHIFT 4 +/* Code group alignment indication */ +#define ETH_MAC_GEN_XAUI_STAT_CG_ALIGN_MASK 0x00000F00 +#define ETH_MAC_GEN_XAUI_STAT_CG_ALIGN_SHIFT 8 + +/**** rxaui_cfg register ****/ +/* Increase rate matching FIFO threshold */ +#define ETH_MAC_GEN_RXAUI_CFG_JUMBO_EN (1 << 0) +/* Scrambler enable */ +#define ETH_MAC_GEN_RXAUI_CFG_SRBL_EN (1 << 1) +/* Disparity calculation across lanes enabled */ +#define ETH_MAC_GEN_RXAUI_CFG_DISP_ACROSS_LANE (1 << 2) + +/**** rxaui_stat register ****/ +/* Lane alignment status */ +#define ETH_MAC_GEN_RXAUI_STAT_ALIGN_DONE (1 << 0) +/* Lane synchronization */ +#define ETH_MAC_GEN_RXAUI_STAT_SYNC_MASK 0x000000F0 +#define ETH_MAC_GEN_RXAUI_STAT_SYNC_SHIFT 4 +/* Code group alignment indication */ +#define ETH_MAC_GEN_RXAUI_STAT_CG_ALIGN_MASK 0x00000F00 +#define ETH_MAC_GEN_RXAUI_STAT_CG_ALIGN_SHIFT 8 + +/**** sd_cfg register ****/ +/* + * Signal detect selection + * 0 - from register + * 1 - from SerDes + */ +#define ETH_MAC_GEN_SD_CFG_SEL_MASK 0x0000000F +#define ETH_MAC_GEN_SD_CFG_SEL_SHIFT 0 +/* Signal detect value */ +#define ETH_MAC_GEN_SD_CFG_VAL_MASK 0x000000F0 +#define ETH_MAC_GEN_SD_CFG_VAL_SHIFT 4 +/* Signal detect revers polarity (reverse polarity of signal from the SerDes */ +#define ETH_MAC_GEN_SD_CFG_POL_MASK 0x00000F00 +#define ETH_MAC_GEN_SD_CFG_POL_SHIFT 8 + +/**** mdio_ctrl_1 register ****/ +/* + * Available indication + * 0 - The port was available and it is captured by this Ethernet controller. + * 1 - The port is used by another Ethernet controller. + */ +#define ETH_MAC_GEN_MDIO_CTRL_1_AVAIL (1 << 0) + +/**** mdio_1 register ****/ +/* Current Ethernet interface number that controls the MDIO port */ +#define ETH_MAC_GEN_MDIO_1_INFO_MASK 0x000000FF +#define ETH_MAC_GEN_MDIO_1_INFO_SHIFT 0 + +/**** mdio_ctrl_2 register ****/ +/* + * Available indication + * 0 - The port was available and it is captured by this Ethernet controller. + * 1 - The port is used by another Ethernet controller. + */ +#define ETH_MAC_GEN_MDIO_CTRL_2_AVAIL (1 << 0) + +/**** mdio_2 register ****/ +/* Current Ethernet interface number that controls the MDIO port */ +#define ETH_MAC_GEN_MDIO_2_INFO_MASK 0x000000FF +#define ETH_MAC_GEN_MDIO_2_INFO_SHIFT 0 + +/**** xgmii_dfifo_32_64 register ****/ +/* FIFO enable */ +#define ETH_MAC_GEN_XGMII_DFIFO_32_64_ENABLE (1 << 0) +/* Read Write command every 2 cycles */ +#define ETH_MAC_GEN_XGMII_DFIFO_32_64_RW_2_CYCLES (1 << 1) +/* Swap LSB MSB when creating wider bus */ +#define ETH_MAC_GEN_XGMII_DFIFO_32_64_SWAP_LSB_MSB (1 << 2) +/* Software reset */ +#define ETH_MAC_GEN_XGMII_DFIFO_32_64_SW_RESET (1 << 4) +/* Read threshold */ +#define ETH_MAC_GEN_XGMII_DFIFO_32_64_READ_TH_MASK 0x0000FF00 +#define ETH_MAC_GEN_XGMII_DFIFO_32_64_READ_TH_SHIFT 8 +/* FIFO used */ +#define ETH_MAC_GEN_XGMII_DFIFO_32_64_USED_MASK 0x00FF0000 +#define ETH_MAC_GEN_XGMII_DFIFO_32_64_USED_SHIFT 16 + +/**** xgmii_dfifo_64_32 register ****/ +/* FIFO enable */ +#define ETH_MAC_GEN_XGMII_DFIFO_64_32_ENABLE (1 << 0) +/* Read Write command every 2 cycles */ +#define ETH_MAC_GEN_XGMII_DFIFO_64_32_RW_2_CYCLES (1 << 1) +/* Swap LSB MSB when creating wider bus */ +#define ETH_MAC_GEN_XGMII_DFIFO_64_32_SWAP_LSB_MSB (1 << 2) +/* Software reset */ +#define ETH_MAC_GEN_XGMII_DFIFO_64_32_SW_RESET (1 << 4) +/* Read threshold */ +#define ETH_MAC_GEN_XGMII_DFIFO_64_32_READ_TH_MASK 0x0000FF00 +#define ETH_MAC_GEN_XGMII_DFIFO_64_32_READ_TH_SHIFT 8 +/* FIFO used */ +#define ETH_MAC_GEN_XGMII_DFIFO_64_32_USED_MASK 0x00FF0000 +#define ETH_MAC_GEN_XGMII_DFIFO_64_32_USED_SHIFT 16 + +/**** sd_fifo_ctrl register ****/ +/* FIFO enable */ +#define ETH_MAC_GEN_SD_FIFO_CTRL_ENABLE_MASK 0x0000000F +#define ETH_MAC_GEN_SD_FIFO_CTRL_ENABLE_SHIFT 0 +/* Software reset */ +#define ETH_MAC_GEN_SD_FIFO_CTRL_SW_RESET_MASK 0x000000F0 +#define ETH_MAC_GEN_SD_FIFO_CTRL_SW_RESET_SHIFT 4 +/* Read threshold */ +#define ETH_MAC_GEN_SD_FIFO_CTRL_READ_TH_MASK 0x0000FF00 +#define ETH_MAC_GEN_SD_FIFO_CTRL_READ_TH_SHIFT 8 + +/**** sd_fifo_stat register ****/ +/* FIFO 0 used */ +#define ETH_MAC_GEN_SD_FIFO_STAT_USED_0_MASK 0x000000FF +#define ETH_MAC_GEN_SD_FIFO_STAT_USED_0_SHIFT 0 +/* FIFO 1 used */ +#define ETH_MAC_GEN_SD_FIFO_STAT_USED_1_MASK 0x0000FF00 +#define ETH_MAC_GEN_SD_FIFO_STAT_USED_1_SHIFT 8 +/* FIFO 2 used */ +#define ETH_MAC_GEN_SD_FIFO_STAT_USED_2_MASK 0x00FF0000 +#define ETH_MAC_GEN_SD_FIFO_STAT_USED_2_SHIFT 16 +/* FIFO 3 used */ +#define ETH_MAC_GEN_SD_FIFO_STAT_USED_3_MASK 0xFF000000 +#define ETH_MAC_GEN_SD_FIFO_STAT_USED_3_SHIFT 24 + +/**** mux_sel register ****/ +/* + * SGMII input selection selector + * 00 – SerDes 0 + * 01 – SerDes 1 + * 10 – SerDes 2 + * 11 – SerDes 3 + */ +#define ETH_MAC_GEN_MUX_SEL_SGMII_IN_MASK 0x00000003 +#define ETH_MAC_GEN_MUX_SEL_SGMII_IN_SHIFT 0 +/* + * RXAUI Lane 0 Input + * 00 – SerDes 0 + * 01 – SerDes 1 + * 10 – SerDes 2 + * 11 – SerDes 3 + */ +#define ETH_MAC_GEN_MUX_SEL_RXAUI_0_IN_MASK 0x0000000C +#define ETH_MAC_GEN_MUX_SEL_RXAUI_0_IN_SHIFT 2 +/* + * RXAUI Lane 1 Input + * 00 – SERDES 0 + * 01 – SERDES 1 + * 10 – SERDES 2 + * 11 – SERDES 3 + */ +#define ETH_MAC_GEN_MUX_SEL_RXAUI_1_IN_MASK 0x00000030 +#define ETH_MAC_GEN_MUX_SEL_RXAUI_1_IN_SHIFT 4 +/* + * XAUI Lane 0 Input + * 00 – SERDES 0 + * 01 – SERDES 1 + * 10 – SERDES 2 + * 11 – SERDES 3 + */ +#define ETH_MAC_GEN_MUX_SEL_XAUI_0_IN_MASK 0x000000C0 +#define ETH_MAC_GEN_MUX_SEL_XAUI_0_IN_SHIFT 6 +/* + * XAUI Lane 1 Input + * 00 – SERDES 0 + * 01 – SERDES 1 + * 10 – SERDES 2 + * 11 – SERDES 3 + */ +#define ETH_MAC_GEN_MUX_SEL_XAUI_1_IN_MASK 0x00000300 +#define ETH_MAC_GEN_MUX_SEL_XAUI_1_IN_SHIFT 8 +/* + * XAUI Lane 2 Input + * 00 – SERDES 0 + * 01 – SERDES 1 + * 10 – SERDES 2 + * 11 – SERDES 3 + */ +#define ETH_MAC_GEN_MUX_SEL_XAUI_2_IN_MASK 0x00000C00 +#define ETH_MAC_GEN_MUX_SEL_XAUI_2_IN_SHIFT 10 +/* + * XAUI Lane 3 Input + * 00 – SERDES 0 + * 01 – SERDES 1 + * 10 – SERDES 2 + * 11 – SERDES 3 + */ +#define ETH_MAC_GEN_MUX_SEL_XAUI_3_IN_MASK 0x00003000 +#define ETH_MAC_GEN_MUX_SEL_XAUI_3_IN_SHIFT 12 +/* + * KR PCS Input + * 00 - SERDES 0 + * 01 - SERDES 1 + * 10 - SERDES 2 + * 11 - SERDES 3 + */ +#define ETH_MAC_GEN_MUX_SEL_KR_IN_MASK 0x0000C000 +#define ETH_MAC_GEN_MUX_SEL_KR_IN_SHIFT 14 +/* + * SerDes 0 input selection (TX) + * 000 – XAUI lane 0 + * 001 – XAUI lane 1 + * 010 – XAUI lane 2 + * 011 – XAUI lane 3 + * 100 – RXAUI lane 0 + * 101 – RXAUI lane 1 + * 110 – SGMII + * 111 – KR + */ +#define ETH_MAC_GEN_MUX_SEL_SERDES_0_TX_MASK 0x00070000 +#define ETH_MAC_GEN_MUX_SEL_SERDES_0_TX_SHIFT 16 +/* + * SERDES 1 input selection (Tx) + * 000 – XAUI lane 0 + * 001 – XAUI lane 1 + * 010 – XAUI lane 2 + * 011 – XAUI lane 3 + * 100 – RXAUI lane 0 + * 101 – RXAUI lane 1 + * 110 – SGMII + * 111 – KR + */ +#define ETH_MAC_GEN_MUX_SEL_SERDES_1_TX_MASK 0x00380000 +#define ETH_MAC_GEN_MUX_SEL_SERDES_1_TX_SHIFT 19 +/* + * SerDes 2 input selection (Tx) + * 000 – XAUI lane 0 + * 001 – XAUI lane 1 + * 010 – XAUI lane 2 + * 011 – XAUI lane 3 + * 100 – RXAUI lane 0 + * 101 – RXAUI lane 1 + * 110 – SGMII + * 111 – KR + */ +#define ETH_MAC_GEN_MUX_SEL_SERDES_2_TX_MASK 0x01C00000 +#define ETH_MAC_GEN_MUX_SEL_SERDES_2_TX_SHIFT 22 +/* + * SerDes 3 input selection (Tx) + * 000 – XAUI lane 0 + * 001 – XAUI lane 1 + * 010 – XAUI lane 2 + * 011 – XAUI lane 3 + * 100 – RXAUI lane 0 + * 101 – RXAUI lane 1 + * 110 – SGMII + * 111 – KR + */ +#define ETH_MAC_GEN_MUX_SEL_SERDES_3_TX_MASK 0x0E000000 +#define ETH_MAC_GEN_MUX_SEL_SERDES_3_TX_SHIFT 25 + +/**** clk_cfg register ****/ +/* + * Rx/Tx lane 0 clock MUX select + * must be aligned with data selector MUXs) + * 0 – SerDes 0 clock + * 0 – SerDes 1 clock + * 2 – SerDes 2 clock + * 3 – SerDes 3 clock + */ +#define ETH_MAC_GEN_CLK_CFG_LANE_0_CLK_SEL_MASK 0x00000003 +#define ETH_MAC_GEN_CLK_CFG_LANE_0_CLK_SEL_SHIFT 0 +/* + * Rx/Tx lane 0 clock MUX select must be aligned with data selector MUXs) + * 0 - SerDes 0 clock + * 1 - SerDes 1 clock + * 2 - SerDes 2 clock + * 3 - SerDes 3 clock + */ +#define ETH_MAC_GEN_CLK_CFG_LANE_1_CLK_SEL_MASK 0x00000030 +#define ETH_MAC_GEN_CLK_CFG_LANE_1_CLK_SEL_SHIFT 4 +/* + * RX/TX lane 0 clock MUX select (should be aligned with data selector MUXs) + * 0 - SERDES 0 clock + * 1 - SERDES 1 clock + * 2 - SERDES 2 clock + * 3 - SERDES 3 clock + */ +#define ETH_MAC_GEN_CLK_CFG_LANE_2_CLK_SEL_MASK 0x00000300 +#define ETH_MAC_GEN_CLK_CFG_LANE_2_CLK_SEL_SHIFT 8 +/* + * Rx/Tx lane 0 clock MUX select must be aligned with data selector MUXs) + * 0 - SerDes 0 clock + * 1 - SerDes 1 clock + * 2 - SerDes 2 clock + * 3 - SerDes 3 clock + */ +#define ETH_MAC_GEN_CLK_CFG_LANE_3_CLK_SEL_MASK 0x00003000 +#define ETH_MAC_GEN_CLK_CFG_LANE_3_CLK_SEL_SHIFT 12 +/* + * MAC GMII Rx clock MUX select must be aligned with data selector MUXs) + * 0 – RGMII + * 1 – SGMII + */ +#define ETH_MAC_GEN_CLK_CFG_GMII_RX_CLK_SEL (1 << 16) +/* + * MAC GMII Tx clock MUX select (should be aligned with data selector MUXs) + * 0 - RGMII + * 1 - SGMII + */ +#define ETH_MAC_GEN_CLK_CFG_GMII_TX_CLK_SEL (1 << 18) +/* + * Tx clock MUX select, + * Selects the internal clock for the Tx data path + * 0 – SerDes[0] TX DWORD CLK REF (for RXAUI and SGMII) + * 1 – SerDes[0] TX WORD CLK REF (for XAUI and KR) + */ +#define ETH_MAC_GEN_CLK_CFG_TX_CLK_SEL (1 << 28) +/* + * Rxclock MUX select + * Selects the internal clock for the Rx data path + * 0 – XGMII TX CLK 32 LOCAL (for XAUI and RXAUI and KR) + * 1 – SerDes[0] RX DWORD CLK GENERATED (125M) + * (for SGMII) + */ +#define ETH_MAC_GEN_CLK_CFG_RX_CLK_SEL (1 << 30) + +/**** los_sel register ****/ +/* + * Selected LOS/SD select + * 00 – SerDes 0 + * 01 – SerDes 1 + * 10 – SerDes 2 + * 11 – SerDes 3 + */ +#define ETH_MAC_GEN_LOS_SEL_LANE_0_SEL_MASK 0x00000003 +#define ETH_MAC_GEN_LOS_SEL_LANE_0_SEL_SHIFT 0 +/* + * Selected LOS/SD select + * 00 - SerDes 0 + * 01 - SerDes 1 + * 10 - SerDes 2 + * 11 - SerDes 3 + */ +#define ETH_MAC_GEN_LOS_SEL_LANE_1_SEL_MASK 0x00000030 +#define ETH_MAC_GEN_LOS_SEL_LANE_1_SEL_SHIFT 4 +/* + * Selected LOS/SD select + * 00 - SerDes 0 + * 01 - SerDes 1 + * 10 - SerDes 2 + * 11 - SerDes 3 + */ +#define ETH_MAC_GEN_LOS_SEL_LANE_2_SEL_MASK 0x00000300 +#define ETH_MAC_GEN_LOS_SEL_LANE_2_SEL_SHIFT 8 +/* + * Selected LOS/SD select + * 00 - SerDes 0 + * 01 - SerDes 1 + * 10 - SerDes 2 + * 11 - SerDes 3 + */ +#define ETH_MAC_GEN_LOS_SEL_LANE_3_SEL_MASK 0x00003000 +#define ETH_MAC_GEN_LOS_SEL_LANE_3_SEL_SHIFT 12 + +/**** rgmii_sel register ****/ +/* Swap [3:0] input with [7:4] */ +#define ETH_MAC_GEN_RGMII_SEL_RX_SWAP_3_0 (1 << 0) +/* Swap [4] input with [9] */ +#define ETH_MAC_GEN_RGMII_SEL_RX_SWAP_4 (1 << 1) +/* Swap [7:4] input with [3:0] */ +#define ETH_MAC_GEN_RGMII_SEL_RX_SWAP_7_3 (1 << 2) +/* Swap [9] input with [4] */ +#define ETH_MAC_GEN_RGMII_SEL_RX_SWAP_9 (1 << 3) +/* Swap [3:0] input with [7:4] */ +#define ETH_MAC_GEN_RGMII_SEL_TX_SWAP_3_0 (1 << 4) +/* Swap [4] input with [9] */ +#define ETH_MAC_GEN_RGMII_SEL_TX_SWAP_4 (1 << 5) +/* Swap [7:4] input with [3:0] */ +#define ETH_MAC_GEN_RGMII_SEL_TX_SWAP_7_3 (1 << 6) +/* Swap [9] input with [4] */ +#define ETH_MAC_GEN_RGMII_SEL_TX_SWAP_9 (1 << 7) + +/**** led_cfg register ****/ +/* + * LED source selection: + * 0 – Default reg + * 1 – Rx activity + * 2 – Tx activity + * 3 – Rx | Tx activity + * 4-9 – SGMII LEDs + */ +#define ETH_MAC_GEN_LED_CFG_SEL_MASK 0x0000000F +#define ETH_MAC_GEN_LED_CFG_SEL_SHIFT 0 + +/* turn the led on/off based on default value field (ETH_MAC_GEN_LED_CFG_DEF) */ +#define ETH_MAC_GEN_LED_CFG_SEL_DEFAULT_REG 0 +#define ETH_MAC_GEN_LED_CFG_SEL_RX_ACTIVITY_DEPRECIATED 1 +#define ETH_MAC_GEN_LED_CFG_SEL_TX_ACTIVITY_DEPRECIATED 2 +#define ETH_MAC_GEN_LED_CFG_SEL_RX_TX_ACTIVITY_DEPRECIATED 3 +#define ETH_MAC_GEN_LED_CFG_SEL_LINK_ACTIVITY 10 + +/* LED default value */ +#define ETH_MAC_GEN_LED_CFG_DEF (1 << 4) +/* LED signal polarity */ +#define ETH_MAC_GEN_LED_CFG_POL (1 << 5) +/* + * activity timer (MSB) + * 32 bit timer @SB clock + */ +#define ETH_MAC_GEN_LED_CFG_ACT_TIMER_MASK 0x00FF0000 +#define ETH_MAC_GEN_LED_CFG_ACT_TIMER_SHIFT 16 +/* + * activity timer (MSB) + * 32 bit timer @SB clock + */ +#define ETH_MAC_GEN_LED_CFG_BLINK_TIMER_MASK 0xFF000000 +#define ETH_MAC_GEN_LED_CFG_BLINK_TIMER_SHIFT 24 + +/**** pcs_addr register ****/ +/* Address value */ +#define ETH_MAC_KR_PCS_ADDR_VAL_MASK 0x0000FFFF +#define ETH_MAC_KR_PCS_ADDR_VAL_SHIFT 0 + +/**** pcs_data register ****/ +/* Data value */ +#define ETH_MAC_KR_PCS_DATA_VAL_MASK 0x0000FFFF +#define ETH_MAC_KR_PCS_DATA_VAL_SHIFT 0 + +/**** an_addr register ****/ +/* Address value */ +#define ETH_MAC_KR_AN_ADDR_VAL_MASK 0x0000FFFF +#define ETH_MAC_KR_AN_ADDR_VAL_SHIFT 0 + +/**** an_data register ****/ +/* Data value */ +#define ETH_MAC_KR_AN_DATA_VAL_MASK 0x0000FFFF +#define ETH_MAC_KR_AN_DATA_VAL_SHIFT 0 + +/**** pma_addr register ****/ +/* Dddress value */ +#define ETH_MAC_KR_PMA_ADDR_VAL_MASK 0x0000FFFF +#define ETH_MAC_KR_PMA_ADDR_VAL_SHIFT 0 + +/**** pma_data register ****/ +/* Data value */ +#define ETH_MAC_KR_PMA_DATA_VAL_MASK 0x0000FFFF +#define ETH_MAC_KR_PMA_DATA_VAL_SHIFT 0 + +/**** mtip_addr register ****/ +/* Address value */ +#define ETH_MAC_KR_MTIP_ADDR_VAL_MASK 0x0000FFFF +#define ETH_MAC_KR_MTIP_ADDR_VAL_SHIFT 0 + +/**** mtip_data register ****/ +/* Data value */ +#define ETH_MAC_KR_MTIP_DATA_VAL_MASK 0x0000FFFF +#define ETH_MAC_KR_MTIP_DATA_VAL_SHIFT 0 + +/**** pcs_cfg register ****/ +/* Enable Auto-Negotiation after Reset */ +#define ETH_MAC_KR_PCS_CFG_STRAP_AN_ENA (1 << 0) +/* + * Signal detect selector for the EEE + * 0 – Register default value + * 1 – SerDes value + */ +#define ETH_MAC_KR_PCS_CFG_EEE_SD_SEL (1 << 4) +/* Signal detect default value for the EEE */ +#define ETH_MAC_KR_PCS_CFG_EEE_DEF_VAL (1 << 5) +/* Signal detect polarity reversal for the EEE */ +#define ETH_MAC_KR_PCS_CFG_EEE_SD_POL (1 << 6) +/* EEE timer value */ +#define ETH_MAC_KR_PCS_CFG_EEE_TIMER_VAL_MASK 0x0000FF00 +#define ETH_MAC_KR_PCS_CFG_EEE_TIMER_VAL_SHIFT 8 +/* + * Selects source for the enable SerDes DME signal + * 0 – Register value + * 1 – PCS output + */ +#define ETH_MAC_KR_PCS_CFG_DME_SEL (1 << 16) +/* DME default value */ +#define ETH_MAC_KR_PCS_CFG_DME_VAL (1 << 17) +/* DME default polarity reversal when selecting PCS output */ +#define ETH_MAC_KR_PCS_CFG_DME_POL (1 << 18) + +/**** pcs_stat register ****/ +/* Link enable by the Auto-Negotiation */ +#define ETH_MAC_KR_PCS_STAT_AN_LINK_CONTROL_MASK 0x0000003F +#define ETH_MAC_KR_PCS_STAT_AN_LINK_CONTROL_SHIFT 0 +/* Block lock */ +#define ETH_MAC_KR_PCS_STAT_BLOCK_LOCK (1 << 8) +/* hi BER */ +#define ETH_MAC_KR_PCS_STAT_HI_BER (1 << 9) + +#define ETH_MAC_KR_PCS_STAT_RX_WAKE_ERR (1 << 16) + +#define ETH_MAC_KR_PCS_STAT_PMA_TXMODE_ALERT (1 << 17) + +#define ETH_MAC_KR_PCS_STAT_PMA_TXMODE_QUIET (1 << 18) + +#define ETH_MAC_KR_PCS_STAT_PMA_RXMODE_QUIET (1 << 19) + +#define ETH_MAC_KR_PCS_STAT_RX_LPI_ACTIVE (1 << 20) + +#define ETH_MAC_KR_PCS_STAT_TX_LPI_ACTIVE (1 << 21) + +/**** reg_addr register ****/ +/* Address value */ +#define ETH_MAC_SGMII_REG_ADDR_VAL_MASK 0x0000001F +#define ETH_MAC_SGMII_REG_ADDR_VAL_SHIFT 0 + +#define ETH_MAC_SGMII_REG_ADDR_CTRL_REG 0x0 +#define ETH_MAC_SGMII_REG_ADDR_IF_MODE_REG 0x14 + +/**** reg_data register ****/ +/* Data value */ +#define ETH_MAC_SGMII_REG_DATA_VAL_MASK 0x0000FFFF +#define ETH_MAC_SGMII_REG_DATA_VAL_SHIFT 0 + +#define ETH_MAC_SGMII_REG_DATA_CTRL_AN_ENABLE (1 << 12) +#define ETH_MAC_SGMII_REG_DATA_IF_MODE_SGMII_EN (1 << 0) +#define ETH_MAC_SGMII_REG_DATA_IF_MODE_SGMII_AN (1 << 1) +#define ETH_MAC_SGMII_REG_DATA_IF_MODE_SGMII_SPEED_MASK 0xC +#define ETH_MAC_SGMII_REG_DATA_IF_MODE_SGMII_SPEED_SHIFT 2 +#define ETH_MAC_SGMII_REG_DATA_IF_MODE_SGMII_SPEED_10 0x0 +#define ETH_MAC_SGMII_REG_DATA_IF_MODE_SGMII_SPEED_100 0x1 +#define ETH_MAC_SGMII_REG_DATA_IF_MODE_SGMII_SPEED_1000 0x2 +#define ETH_MAC_SGMII_REG_DATA_IF_MODE_SGMII_DUPLEX (1 << 4) + +/**** clk_div register ****/ +/* Value for 1000M selection */ +#define ETH_MAC_SGMII_CLK_DIV_VAL_1000_MASK 0x000000FF +#define ETH_MAC_SGMII_CLK_DIV_VAL_1000_SHIFT 0 +/* Value for 100M selection */ +#define ETH_MAC_SGMII_CLK_DIV_VAL_100_MASK 0x0000FF00 +#define ETH_MAC_SGMII_CLK_DIV_VAL_100_SHIFT 8 +/* Value for 10M selection */ +#define ETH_MAC_SGMII_CLK_DIV_VAL_10_MASK 0x00FF0000 +#define ETH_MAC_SGMII_CLK_DIV_VAL_10_SHIFT 16 +/* Bypass PCS selection */ +#define ETH_MAC_SGMII_CLK_DIV_BYPASS (1 << 24) +/* + * Divider selection when bypass field is '1', one hot + * 001 – 1000M + * 010 – 100M + * 100 – 10M + */ +#define ETH_MAC_SGMII_CLK_DIV_SEL_MASK 0x0E000000 +#define ETH_MAC_SGMII_CLK_DIV_SEL_SHIFT 25 + +/**** link_stat register ****/ + +#define ETH_MAC_SGMII_LINK_STAT_SET_1000 (1 << 0) + +#define ETH_MAC_SGMII_LINK_STAT_SET_100 (1 << 1) + +#define ETH_MAC_SGMII_LINK_STAT_SET_10 (1 << 2) + +#define ETH_MAC_SGMII_LINK_STAT_LED_AN (1 << 3) + +#define ETH_MAC_SGMII_LINK_STAT_HD_ENA (1 << 4) + +#define ETH_MAC_SGMII_LINK_STAT_LED_LINK (1 << 5) + +/**** afifo_ctrl register ****/ +/* enable tx input operation */ +#define ETH_MAC_GEN_V3_AFIFO_CTRL_EN_TX_IN (1 << 0) +/* enable tx output operation */ +#define ETH_MAC_GEN_V3_AFIFO_CTRL_EN_TX_OUT (1 << 1) +/* enable rx input operation */ +#define ETH_MAC_GEN_V3_AFIFO_CTRL_EN_RX_IN (1 << 4) +/* enable rx output operation */ +#define ETH_MAC_GEN_V3_AFIFO_CTRL_EN_RX_OUT (1 << 5) +/* enable tx FIFO input operation */ +#define ETH_MAC_GEN_V3_AFIFO_CTRL_EN_TX_FIFO_IN (1 << 8) +/* enable tx FIFO output operation */ +#define ETH_MAC_GEN_V3_AFIFO_CTRL_EN_TX_FIFO_OUT (1 << 9) +/* enable rx FIFO input operation */ +#define ETH_MAC_GEN_V3_AFIFO_CTRL_EN_RX_FIFO_IN (1 << 12) +/* enable rx FIFO output operation */ +#define ETH_MAC_GEN_V3_AFIFO_CTRL_EN_RX_FIFO_OUT (1 << 13) + +/**** tx_afifo_cfg_1 register ****/ +/* minimum packet size configuration */ +#define ETH_MAC_GEN_V3_TX_AFIFO_CFG_1_MIN_PKT_SIZE_MASK 0x0000FFFF +#define ETH_MAC_GEN_V3_TX_AFIFO_CFG_1_MIN_PKT_SIZE_SHIFT 0 + +/**** tx_afifo_cfg_2 register ****/ +/* maximum packet size configuration */ +#define ETH_MAC_GEN_V3_TX_AFIFO_CFG_2_MAX_PKT_SIZE_MASK 0x0000FFFF +#define ETH_MAC_GEN_V3_TX_AFIFO_CFG_2_MAX_PKT_SIZE_SHIFT 0 + +/**** tx_afifo_cfg_3 register ****/ +/* input bus width */ +#define ETH_MAC_GEN_V3_TX_AFIFO_CFG_3_INPUT_BUS_W_MASK 0x0000FFFF +#define ETH_MAC_GEN_V3_TX_AFIFO_CFG_3_INPUT_BUS_W_SHIFT 0 +/* input bus width divide factor */ +#define ETH_MAC_GEN_V3_TX_AFIFO_CFG_3_INPUT_BUS_W_F_MASK 0xFFFF0000 +#define ETH_MAC_GEN_V3_TX_AFIFO_CFG_3_INPUT_BUS_W_F_SHIFT 16 + +/**** tx_afifo_cfg_4 register ****/ +/* output bus width */ +#define ETH_MAC_GEN_V3_TX_AFIFO_CFG_4_OUTPUT_BUS_W_MASK 0x0000FFFF +#define ETH_MAC_GEN_V3_TX_AFIFO_CFG_4_OUTPUT_BUS_W_SHIFT 0 +/* output bus width divide factor */ +#define ETH_MAC_GEN_V3_TX_AFIFO_CFG_4_OUTPUT_BUS_W_F_MASK 0xFFFF0000 +#define ETH_MAC_GEN_V3_TX_AFIFO_CFG_4_OUTPUT_BUS_W_F_SHIFT 16 + +/**** tx_afifo_cfg_5 register ****/ +/* + * determines if the input bus is valid/read or “write enable”. + * 0 – write enable + * 1 – valid/ready + */ +#define ETH_MAC_GEN_V3_TX_AFIFO_CFG_5_INPUT_BUS_VALID_RDY (1 << 0) +/* + * determines if the output bus is valid/read or “write enable”. + * 0 – write enable + * 1 – valid/ready + */ +#define ETH_MAC_GEN_V3_TX_AFIFO_CFG_5_OUTPUT_BUS_VALID_RDY (1 << 1) +/* Swap input bus bytes */ +#define ETH_MAC_GEN_V3_TX_AFIFO_CFG_5_INPUT_BUS_SWAP_BYTES (1 << 4) +/* Swap output bus bytes */ +#define ETH_MAC_GEN_V3_TX_AFIFO_CFG_5_OUTPUT_BUS_SWAP_BYTES (1 << 5) +/* + * output clock select + * 0 – mac_ll_tx_clk + * 1 – clk_mac_sys_clk + */ +#define ETH_MAC_GEN_V3_TX_AFIFO_CFG_5_OUTPUT_CLK_SEL (1 << 8) + +/**** rx_afifo_cfg_1 register ****/ +/* minimum packet size configuration */ +#define ETH_MAC_GEN_V3_RX_AFIFO_CFG_1_MIN_PKT_SIZE_MASK 0x0000FFFF +#define ETH_MAC_GEN_V3_RX_AFIFO_CFG_1_MIN_PKT_SIZE_SHIFT 0 + +/**** rx_afifo_cfg_2 register ****/ +/* maximum packet size configuration */ +#define ETH_MAC_GEN_V3_RX_AFIFO_CFG_2_MAX_PKT_SIZE_MASK 0x0000FFFF +#define ETH_MAC_GEN_V3_RX_AFIFO_CFG_2_MAX_PKT_SIZE_SHIFT 0 + +/**** rx_afifo_cfg_3 register ****/ +/* input bus width */ +#define ETH_MAC_GEN_V3_RX_AFIFO_CFG_3_INPUT_BUS_W_MASK 0x0000FFFF +#define ETH_MAC_GEN_V3_RX_AFIFO_CFG_3_INPUT_BUS_W_SHIFT 0 +/* input bus width divide factor */ +#define ETH_MAC_GEN_V3_RX_AFIFO_CFG_3_INPUT_BUS_W_F_MASK 0xFFFF0000 +#define ETH_MAC_GEN_V3_RX_AFIFO_CFG_3_INPUT_BUS_W_F_SHIFT 16 + +/**** rx_afifo_cfg_4 register ****/ +/* output bus width */ +#define ETH_MAC_GEN_V3_RX_AFIFO_CFG_4_OUTPUT_BUS_W_MASK 0x0000FFFF +#define ETH_MAC_GEN_V3_RX_AFIFO_CFG_4_OUTPUT_BUS_W_SHIFT 0 +/* output bus width divide factor */ +#define ETH_MAC_GEN_V3_RX_AFIFO_CFG_4_OUTPUT_BUS_W_F_MASK 0xFFFF0000 +#define ETH_MAC_GEN_V3_RX_AFIFO_CFG_4_OUTPUT_BUS_W_F_SHIFT 16 + +/**** rx_afifo_cfg_5 register ****/ +/* + * determines if the input bus is valid/read or “write enable”. + * 0 – write enable + * 1 – valid/ready + */ +#define ETH_MAC_GEN_V3_RX_AFIFO_CFG_5_INPUT_BUS_VALID_RDY (1 << 0) +/* + * determines if the output bus is valid/read or “write enable”. + * 0 – write enable + * 1 – valid/ready + */ +#define ETH_MAC_GEN_V3_RX_AFIFO_CFG_5_OUTPUT_BUS_VALID_RDY (1 << 1) +/* Swap input bus bytes */ +#define ETH_MAC_GEN_V3_RX_AFIFO_CFG_5_INPUT_BUS_SWAP_BYTES (1 << 4) +/* Swap output bus bytes */ +#define ETH_MAC_GEN_V3_RX_AFIFO_CFG_5_OUTPUT_BUS_SWAP_BYTES (1 << 5) +/* + * input clock select + * 0 – mac_ll_rx_clk + * 1 – clk_serdes_int_0_tx_dword_ref + * 2 – clk_mac_sys_clk + * 3 – mac_ll_tx_clk + */ +#define ETH_MAC_GEN_V3_RX_AFIFO_CFG_5_INPUT_CLK_SEL_MASK 0x00000300 +#define ETH_MAC_GEN_V3_RX_AFIFO_CFG_5_INPUT_CLK_SEL_SHIFT 8 + +/**** mac_sel register ****/ +/* + * Select the MAC that is connected to the SGMII PCS. + * 0 – 1G MAC + * 1 – 10G MAC + */ +#define ETH_MAC_GEN_V3_MAC_SEL_MAC_10G_SGMII (1 << 0) +/* + * Select between the 10G and 40G MAC + * 0 – 10G MAC + * 1 – 40G MAC + */ +#define ETH_MAC_GEN_V3_MAC_SEL_MAC_10G_40G (1 << 4) + +/**** mac_10g_ll_cfg register ****/ +/* + * select between 10G (KR PCS) and 1G (SGMII) mode. + * 0 – 10G + * 1 – 1G + */ +#define ETH_MAC_GEN_V3_MAC_10G_LL_CFG_MODE_1G (1 << 0) +/* enable Magic packet detection in the MAC (all other packets are dropped) */ +#define ETH_MAC_GEN_V3_MAC_10G_LL_CFG_MAGIC_ENA (1 << 5) + +/**** mac_10g_ll_ctrl register ****/ +/* Force the MAC to stop TX transmission after low power mode. */ +#define ETH_MAC_GEN_V3_MAC_10G_LL_CTRL_LPI_TXHOLD (1 << 0) + +/**** pcs_10g_ll_cfg register ****/ +/* RX FEC Enable */ +#define ETH_MAC_GEN_V3_PCS_10G_LL_CFG_FEC_EN_RX (1 << 0) +/* TX FEC enable */ +#define ETH_MAC_GEN_V3_PCS_10G_LL_CFG_FEC_EN_TX (1 << 1) +/* + * RX FEC error propagation enable, + * (debug, always 0) + */ +#define ETH_MAC_GEN_V3_PCS_10G_LL_CFG_FEC_ERR_ENA (1 << 2) +/* + * Gearbox configuration: + * 00 -16 + * 01 – 20 + * 10 – 32 + * 11 – reserved + */ +#define ETH_MAC_GEN_V3_PCS_10G_LL_CFG_TX_GB_CFG_MASK 0x00000030 +#define ETH_MAC_GEN_V3_PCS_10G_LL_CFG_TX_GB_CFG_SHIFT 4 +/* + * Gearbox configuration: + * 00 -16 + * 01 – 20 + * 10 – 32 + * 11 – reserved + */ +#define ETH_MAC_GEN_V3_PCS_10G_LL_CFG_RX_GB_CFG_MASK 0x000000C0 +#define ETH_MAC_GEN_V3_PCS_10G_LL_CFG_RX_GB_CFG_SHIFT 6 + +/**** pcs_10g_ll_status register ****/ +/* FEC locked indication */ +#define ETH_MAC_GEN_V3_PCS_10G_LL_STATUS_FEC_LOCKED (1 << 0) + +/**** pcs_40g_ll_cfg register ****/ +/* RX FEC Enable */ +#define ETH_MAC_GEN_V3_PCS_40G_LL_CFG_FEC_EN_RX_MASK 0x0000000F +#define ETH_MAC_GEN_V3_PCS_40G_LL_CFG_FEC_EN_RX_SHIFT 0 +/* TX FEC enable */ +#define ETH_MAC_GEN_V3_PCS_40G_LL_CFG_FEC_EN_TX_MASK 0x000000F0 +#define ETH_MAC_GEN_V3_PCS_40G_LL_CFG_FEC_EN_TX_SHIFT 4 +/* + * RX FEC error propagation enable, + * (debug, always 0) + */ +#define ETH_MAC_GEN_V3_PCS_40G_LL_CFG_FEC_ERR_EN_MASK 0x00000F00 +#define ETH_MAC_GEN_V3_PCS_40G_LL_CFG_FEC_ERR_EN_SHIFT 8 +/* + * SERDES width, 16 bit enable + * 1 – 16 + * 2 – 32 + */ +#define ETH_MAC_GEN_V3_PCS_40G_LL_CFG_SD_16B (1 << 12) +/* FEC 91 enable */ +#define ETH_MAC_GEN_V3_PCS_40G_LL_CFG_FEC91_ENA (1 << 13) +/* + * PHY LOS indication selection + * 00 - Select register value from phy_los_def + * 01 - Select input from the SerDes + * 10 - Select input from GPIO + * 11 - Select inverted input from GPIO + */ +#define ETH_MAC_GEN_V3_PCS_40G_LL_CFG_PHY_LOS_SEL_MASK 0x00030000 +#define ETH_MAC_GEN_V3_PCS_40G_LL_CFG_PHY_LOS_SEL_SHIFT 16 +/* PHY LOS default value */ +#define ETH_MAC_GEN_V3_PCS_40G_LL_CFG_PHY_LOS_DEF (1 << 18) +/* PHY LOS polarity */ +#define ETH_MAC_GEN_V3_PCS_40G_LL_CFG_PHY_LOS_POL (1 << 19) +/* + * Energy detect indication selection + * 00 - Select register value from phy_los_def + * 01 - Select input from the SerDes + * 10 - Select input from GPIO + * 11 - Select inverted input from GPIO + */ +#define ETH_MAC_GEN_V3_PCS_40G_LL_CFG_ENERGY_DETECT_SEL_MASK 0x00300000 +#define ETH_MAC_GEN_V3_PCS_40G_LL_CFG_ENERGY_DETECT_SEL_SHIFT 20 +/* Energy detect default value */ +#define ETH_MAC_GEN_V3_PCS_40G_LL_CFG_ENERGY_DETECT_DEF (1 << 22) +/* Energy detect polarity */ +#define ETH_MAC_GEN_V3_PCS_40G_LL_CFG_ENERGY_DETECT_POL (1 << 23) + +/**** pcs_40g_ll_status register ****/ +/* Block lock */ +#define ETH_MAC_GEN_V3_PCS_40G_LL_STATUS_BLOCK_LOCK_MASK 0x0000000F +#define ETH_MAC_GEN_V3_PCS_40G_LL_STATUS_BLOCK_LOCK_SHIFT 0 +/* align done */ +#define ETH_MAC_GEN_V3_PCS_40G_LL_STATUS_ALIGN_DONE (1 << 4) +/* high BER */ +#define ETH_MAC_GEN_V3_PCS_40G_LL_STATUS_HIGH_BER (1 << 8) +/* FEC locked indication */ +#define ETH_MAC_GEN_V3_PCS_40G_LL_STATUS_FEC_LOCKED_MASK 0x0000F000 +#define ETH_MAC_GEN_V3_PCS_40G_LL_STATUS_FEC_LOCKED_SHIFT 12 + +/**** pcs_40g_ll_addr register ****/ +/* Address value */ +#define ETH_MAC_GEN_V3_PCS_40G_LL_ADDR_VAL_MASK 0x0001FFFF +#define ETH_MAC_GEN_V3_PCS_40G_LL_ADDR_VAL_SHIFT 0 + +/**** pcs_40g_ll_data register ****/ +/* Data value */ +#define ETH_MAC_GEN_V3_PCS_40G_LL_DATA_VAL_MASK 0x0000FFFF +#define ETH_MAC_GEN_V3_PCS_40G_LL_DATA_VAL_SHIFT 0 + +/**** mac_40g_ll_cfg register ****/ +/* change TX CRC polarity */ +#define ETH_MAC_GEN_V3_MAC_40G_LL_CFG_SWAP_FF_TX_CRC (1 << 0) +/* force TX remote fault */ +#define ETH_MAC_GEN_V3_MAC_40G_LL_CFG_TX_REM_FAULT (1 << 4) +/* force TX local fault */ +#define ETH_MAC_GEN_V3_MAC_40G_LL_CFG_TX_LOC_FAULT (1 << 5) +/* force TX Link fault */ +#define ETH_MAC_GEN_V3_MAC_40G_LL_CFG_TX_LI_FAULT (1 << 6) +/* + * PHY LOS indication selection + * 00 - Select register value from phy_los_def + * 01 - Select input from the SerDes + * 10 - Select input from GPIO + * 11 - Select inverted input from GPIO + */ +#define ETH_MAC_GEN_V3_MAC_40G_LL_CFG_PHY_LOS_SEL_MASK 0x00000300 +#define ETH_MAC_GEN_V3_MAC_40G_LL_CFG_PHY_LOS_SEL_SHIFT 8 +/* PHY LOS default value */ +#define ETH_MAC_GEN_V3_MAC_40G_LL_CFG_PHY_LOS_DEF (1 << 10) +/* PHY LOS polarity */ +#define ETH_MAC_GEN_V3_MAC_40G_LL_CFG_PHY_LOS_POL (1 << 11) + +/**** mac_40g_ll_status register ****/ +/* pause on indication */ +#define ETH_MAC_GEN_V3_MAC_40G_LL_STATUS_PAUSE_ON_MASK 0x000000FF +#define ETH_MAC_GEN_V3_MAC_40G_LL_STATUS_PAUSE_ON_SHIFT 0 +/* local fault indication received */ +#define ETH_MAC_GEN_V3_MAC_40G_LL_STATUS_LOC_FAULT (1 << 8) +/* remote fault indication received */ +#define ETH_MAC_GEN_V3_MAC_40G_LL_STATUS_REM_FAULT (1 << 9) +/* Link fault indication */ +#define ETH_MAC_GEN_V3_MAC_40G_LL_STATUS_LI_FAULT (1 << 10) + +/**** preamble_cfg_high register ****/ +/* preamble value */ +#define ETH_MAC_GEN_V3_PREAMBLE_CFG_HIGH_VAL_MASK 0x00FFFFFF +#define ETH_MAC_GEN_V3_PREAMBLE_CFG_HIGH_VAL_SHIFT 0 + +/**** mac_40g_ll_addr register ****/ +/* Address value */ +#define ETH_MAC_GEN_V3_MAC_40G_LL_ADDR_VAL_MASK 0x000003FF +#define ETH_MAC_GEN_V3_MAC_40G_LL_ADDR_VAL_SHIFT 0 + +/**** mac_40g_ll_ctrl register ****/ +/* Force the MAC to stop TX transmission after low power mode. */ +#define ETH_MAC_GEN_V3_MAC_40G_LL_CTRL_LPI_TXHOLD (1 << 0) + +#define ETH_MAC_GEN_V3_MAC_40G_LL_CTRL_REG_LOWP_ENA (1 << 1) + +/**** pcs_40g_fec_91_ll_addr register ****/ +/* Address value */ +#define ETH_MAC_GEN_V3_PCS_40G_FEC_91_LL_ADDR_VAL_MASK 0x000001FF +#define ETH_MAC_GEN_V3_PCS_40G_FEC_91_LL_ADDR_VAL_SHIFT 0 + +/**** pcs_40g_fec_91_ll_data register ****/ +/* Data value */ +#define ETH_MAC_GEN_V3_PCS_40G_FEC_91_LL_DATA_VAL_MASK 0x0000FFFF +#define ETH_MAC_GEN_V3_PCS_40G_FEC_91_LL_DATA_VAL_SHIFT 0 + +/**** pcs_40g_ll_eee_cfg register ****/ +/* Low power timer configuration */ +#define ETH_MAC_GEN_V3_PCS_40G_LL_EEE_CFG_TIMER_VAL_MASK 0x000000FF +#define ETH_MAC_GEN_V3_PCS_40G_LL_EEE_CFG_TIMER_VAL_SHIFT 0 +/* Low power Fast wake */ +#define ETH_MAC_GEN_V3_PCS_40G_LL_EEE_CFG_LPI_FW (1 << 8) + +/**** pcs_40g_ll_eee_status register ****/ +/* TX LPI mode */ +#define ETH_MAC_GEN_V3_PCS_40G_LL_EEE_STATUS_TX_LPI_MODE_MASK 0x00000003 +#define ETH_MAC_GEN_V3_PCS_40G_LL_EEE_STATUS_TX_LPI_MODE_SHIFT 0 +/* TX LPI state */ +#define ETH_MAC_GEN_V3_PCS_40G_LL_EEE_STATUS_TX_LPI_STATE_MASK 0x00000070 +#define ETH_MAC_GEN_V3_PCS_40G_LL_EEE_STATUS_TX_LPI_STATE_SHIFT 4 +/* TX LPI mode */ +#define ETH_MAC_GEN_V3_PCS_40G_LL_EEE_STATUS_RX_LPI_MODE (1 << 8) +/* TX LPI state */ +#define ETH_MAC_GEN_V3_PCS_40G_LL_EEE_STATUS_RX_LPI_STATE_MASK 0x00007000 +#define ETH_MAC_GEN_V3_PCS_40G_LL_EEE_STATUS_RX_LPI_STATE_SHIFT 12 +/* TX LPI active */ +#define ETH_MAC_GEN_V3_PCS_40G_LL_EEE_STATUS_RX_LPI_ACTIVE (1 << 15) + +/**** serdes_32_tx_shift register ****/ +/* bit shift */ +#define ETH_MAC_GEN_V3_SERDES_32_TX_SHIFT_SERDES_0_MASK 0x0000001F +#define ETH_MAC_GEN_V3_SERDES_32_TX_SHIFT_SERDES_0_SHIFT 0 +/* bit shift */ +#define ETH_MAC_GEN_V3_SERDES_32_TX_SHIFT_SERDES_1_MASK 0x000003E0 +#define ETH_MAC_GEN_V3_SERDES_32_TX_SHIFT_SERDES_1_SHIFT 5 +/* bit shift */ +#define ETH_MAC_GEN_V3_SERDES_32_TX_SHIFT_SERDES_2_MASK 0x00007C00 +#define ETH_MAC_GEN_V3_SERDES_32_TX_SHIFT_SERDES_2_SHIFT 10 +/* bit shift */ +#define ETH_MAC_GEN_V3_SERDES_32_TX_SHIFT_SERDES_3_MASK 0x000F8000 +#define ETH_MAC_GEN_V3_SERDES_32_TX_SHIFT_SERDES_3_SHIFT 15 + +/**** serdes_32_rx_shift register ****/ +/* bit shift */ +#define ETH_MAC_GEN_V3_SERDES_32_RX_SHIFT_SERDES_0_MASK 0x0000001F +#define ETH_MAC_GEN_V3_SERDES_32_RX_SHIFT_SERDES_0_SHIFT 0 +/* bit shift */ +#define ETH_MAC_GEN_V3_SERDES_32_RX_SHIFT_SERDES_1_MASK 0x000003E0 +#define ETH_MAC_GEN_V3_SERDES_32_RX_SHIFT_SERDES_1_SHIFT 5 +/* bit shift */ +#define ETH_MAC_GEN_V3_SERDES_32_RX_SHIFT_SERDES_2_MASK 0x00007C00 +#define ETH_MAC_GEN_V3_SERDES_32_RX_SHIFT_SERDES_2_SHIFT 10 +/* bit shift */ +#define ETH_MAC_GEN_V3_SERDES_32_RX_SHIFT_SERDES_3_MASK 0x000F8000 +#define ETH_MAC_GEN_V3_SERDES_32_RX_SHIFT_SERDES_3_SHIFT 15 + +/**** serdes_32_tx_sel register ****/ +/* + * 0 – directly from serdes + * 1 – swapped + * 2 – swapped with shift + * 3 - legacy (based on gen cfg register) + */ +#define ETH_MAC_GEN_V3_SERDES_32_TX_SEL_SERDES_0_MASK 0x00000003 +#define ETH_MAC_GEN_V3_SERDES_32_TX_SEL_SERDES_0_SHIFT 0 +/* + * 0 – directly from serdes + * 1 – swapped + * 2 – swapped with shift + * 3 - legacy (based on gen cfg register) + */ +#define ETH_MAC_GEN_V3_SERDES_32_TX_SEL_SERDES_1_MASK 0x00000030 +#define ETH_MAC_GEN_V3_SERDES_32_TX_SEL_SERDES_1_SHIFT 4 +/* + * 0 – directly from serdes + * 1 – swapped + * 2 – swapped with shift + * 3 - legacy (based on gen cfg register) + */ +#define ETH_MAC_GEN_V3_SERDES_32_TX_SEL_SERDES_2_MASK 0x00000300 +#define ETH_MAC_GEN_V3_SERDES_32_TX_SEL_SERDES_2_SHIFT 8 +/* + * 0 – directly from serdes + * 1 – swapped + * 2 – swapped with shift + * 3 - legacy (based on gen cfg register) + */ +#define ETH_MAC_GEN_V3_SERDES_32_TX_SEL_SERDES_3_MASK 0x00003000 +#define ETH_MAC_GEN_V3_SERDES_32_TX_SEL_SERDES_3_SHIFT 12 + +/**** serdes_32_rx_sel register ****/ +/* + * 0 – directly from serdes + * 1 – swapped + * 2 – swapped with shift + * 3 - legacy (based on gen cfg register) + */ +#define ETH_MAC_GEN_V3_SERDES_32_RX_SEL_SERDES_0_MASK 0x00000003 +#define ETH_MAC_GEN_V3_SERDES_32_RX_SEL_SERDES_0_SHIFT 0 +/* + * 0 – directly from serdes + * 1 – swapped + * 2 – swapped with shift + * 3 - legacy (based on gen cfg register) + */ +#define ETH_MAC_GEN_V3_SERDES_32_RX_SEL_SERDES_1_MASK 0x00000030 +#define ETH_MAC_GEN_V3_SERDES_32_RX_SEL_SERDES_1_SHIFT 4 +/* + * 0 – directly from serdes + * 1 – swapped + * 2 – swapped with shift + * 3 - legacy (based on gen cfg register) + */ +#define ETH_MAC_GEN_V3_SERDES_32_RX_SEL_SERDES_2_MASK 0x00000300 +#define ETH_MAC_GEN_V3_SERDES_32_RX_SEL_SERDES_2_SHIFT 8 +/* + * 0 – directly from serdes + * 1 – swapped + * 2 – swapped with shift + * 3 - legacy (based on gen cfg register) + */ +#define ETH_MAC_GEN_V3_SERDES_32_RX_SEL_SERDES_3_MASK 0x00003000 +#define ETH_MAC_GEN_V3_SERDES_32_RX_SEL_SERDES_3_SHIFT 12 + +/**** an_lt_ctrl register ****/ +/* reset lane [3:0] */ +#define ETH_MAC_GEN_V3_AN_LT_CTRL_SW_RESET_MASK 0x0000000F +#define ETH_MAC_GEN_V3_AN_LT_CTRL_SW_RESET_SHIFT 0 + +/* PHY LOS indication input selection + * 0 - from serdes + * 1 - from an_lt + */ +#define ETH_MAC_GEN_V3_AN_LT_CTRL_PHY_LOS_SEL_LANE_0 (1 << 8) +/* PHY LOS indication input selection + * 0 - from serdes + * 1 - from an_lt + */ +#define ETH_MAC_GEN_V3_AN_LT_CTRL_PHY_LOS_SEL_LANE_1 (1 << 9) +/* PHY LOS indication input selection + * 0 - from serdes + * 1 - from an_lt + */ +#define ETH_MAC_GEN_V3_AN_LT_CTRL_PHY_LOS_SEL_LANE_2 (1 << 10) +/* PHY LOS indication input selection + * 0 - from serdes + * 1 - from an_lt + */ +#define ETH_MAC_GEN_V3_AN_LT_CTRL_PHY_LOS_SEL_LANE_3 (1 << 11) + +/**** an_lt_0_addr register ****/ +/* Address value */ +#define ETH_MAC_GEN_V3_AN_LT_0_ADDR_VAL_MASK 0x0000FFFF +#define ETH_MAC_GEN_V3_AN_LT_0_ADDR_VAL_SHIFT 0 + +/**** an_lt_1_addr register ****/ +/* Address value */ +#define ETH_MAC_GEN_V3_AN_LT_1_ADDR_VAL_MASK 0x0000FFFF +#define ETH_MAC_GEN_V3_AN_LT_1_ADDR_VAL_SHIFT 0 + +/**** an_lt_2_addr register ****/ +/* Address value */ +#define ETH_MAC_GEN_V3_AN_LT_2_ADDR_VAL_MASK 0x0000FFFF +#define ETH_MAC_GEN_V3_AN_LT_2_ADDR_VAL_SHIFT 0 + +/**** an_lt_3_addr register ****/ +/* Address value */ +#define ETH_MAC_GEN_V3_AN_LT_3_ADDR_VAL_MASK 0x0000FFFF +#define ETH_MAC_GEN_V3_AN_LT_3_ADDR_VAL_SHIFT 0 + +/**** ext_serdes_ctrl register ****/ +/* + * Lane 0, SERDES selection: + * 0 – 10G SERDES, lane 0 + * 1 – 25G SERDES, lane 0 + */ +#define ETH_MAC_GEN_V3_EXT_SERDES_CTRL_LANE_0_SEL_25_10 (1 << 0) +/* + * Lane 1, SERDES selection: + * 0 – 10G SERDES, lane 1 + * 1 – 25G SERDES, lane 1 + */ +#define ETH_MAC_GEN_V3_EXT_SERDES_CTRL_LANE_1_SEL_25_10 (1 << 1) +/* + * Lane 2, SERDES selection: + * 0 – 10G SERDES, lane 2 + * 1 – 25G SERDES, lane 0 + */ +#define ETH_MAC_GEN_V3_EXT_SERDES_CTRL_LANE_2_SEL_25_10 (1 << 2) +/* + * Lane 3, SERDES selection: + * 0 – 10G SERDES, lane 3 + * 1 – 25G SERDES, lane 1 + */ +#define ETH_MAC_GEN_V3_EXT_SERDES_CTRL_LANE_3_SEL_25_10 (1 << 3) + +/* Lane 0 Rx, 25G 40bit-32bit gearshitf sw reset */ +#define ETH_MAC_GEN_V3_EXT_SERDES_CTRL_LANE_0_RX_25_GS_SW_RESET (1 << 4) +/* Lane 0 Tx, 25G 40bit-32bit gearshitf sw reset */ +#define ETH_MAC_GEN_V3_EXT_SERDES_CTRL_LANE_0_TX_25_GS_SW_RESET (1 << 5) +/* Lane 1 Rx, 25G 40bit-32bit gearshitf sw reset */ +#define ETH_MAC_GEN_V3_EXT_SERDES_CTRL_LANE_1_RX_25_GS_SW_RESET (1 << 6) +/* Lane 1 Tx, 25G 40bit-32bit gearshitf sw reset */ +#define ETH_MAC_GEN_V3_EXT_SERDES_CTRL_LANE_1_TX_25_GS_SW_RESET (1 << 7) +/* SerDes 25G gear shift Tx lane selector */ +#define ETH_MAC_GEN_V3_EXT_SERDES_CTRL_SRDS25_GS_TX_LANE_CLK_SEL (1 << 8) + +/*** MAC Core registers addresses ***/ +/* command config */ +#define ETH_MAC_GEN_V3_MAC_40G_COMMAND_CONFIG_ADDR 0x00000008 +#define ETH_MAC_GEN_V3_MAC_40G_COMMAND_CONFIG_TX_ENA (1 << 0) +#define ETH_MAC_GEN_V3_MAC_40G_COMMAND_CONFIG_RX_ENA (1 << 1) +#define ETH_MAC_GEN_V3_MAC_40G_COMMAND_CONFIG_PFC_MODE (1 << 19) + +/* frame length */ +#define ETH_MAC_GEN_V3_MAC_40G_FRM_LENGTH_ADDR 0x00000014 + +#define ETH_MAC_GEN_V3_MAC_40G_CL01_PAUSE_QUANTA_ADDR 0x00000054 +#define ETH_MAC_GEN_V3_MAC_40G_CL23_PAUSE_QUANTA_ADDR 0x00000058 +#define ETH_MAC_GEN_V3_MAC_40G_CL45_PAUSE_QUANTA_ADDR 0x0000005C +#define ETH_MAC_GEN_V3_MAC_40G_CL67_PAUSE_QUANTA_ADDR 0x00000060 +#define ETH_MAC_GEN_V3_MAC_40G_CL01_QUANTA_THRESH_ADDR 0x00000064 +#define ETH_MAC_GEN_V3_MAC_40G_CL23_QUANTA_THRESH_ADDR 0x00000068 +#define ETH_MAC_GEN_V3_MAC_40G_CL45_QUANTA_THRESH_ADDR 0x0000006C +#define ETH_MAC_GEN_V3_MAC_40G_CL67_QUANTA_THRESH_ADDR 0x00000070 + +/* spare */ +#define ETH_MAC_GEN_V3_SPARE_CHICKEN_DISABLE_TIMESTAMP_STRETCH (1 << 0) + +/*** PCS Core registers addresses ***/ +/* 40g control/status */ +#define ETH_MAC_GEN_V3_PCS_40G_CONTROL_STATUS_ADDR 0x00000000 +/* 10g control_1 */ +#define ETH_MAC_KR_PCS_CONTROL_1_ADDR 0x00000000 + +#define ETH_MAC_KR_AN_MILLISECONDS_COUNTER_ADDR 0x00008000 +#define ETH_MAC_AN_LT_MILLISECONDS_COUNTER_ADDR 0x00000020 + +#ifdef __cplusplus +} +#endif + +#endif /* __AL_HAL_ETH_MAC_REGS_H__ */ + +/** @} end of Ethernet group */ diff --git a/eth/al_hal_eth_main.c b/eth/al_hal_eth_main.c new file mode 100644 index 00000000000..b3a5c70b1f0 --- /dev/null +++ b/eth/al_hal_eth_main.c @@ -0,0 +1,5260 @@ +/*- +******************************************************************************* +Copyright (C) 2015 Annapurna Labs Ltd. + +This file may be licensed under the terms of the Annapurna Labs Commercial +License Agreement. + +Alternatively, this file can be distributed under the terms of the GNU General +Public License V2 as published by the Free Software Foundation and can be +found at http://www.gnu.org/licenses/gpl-2.0.html + +Alternatively, redistribution and use in source and binary forms, with or +without modification, are permitted provided that the following conditions are +met: + + * Redistributions of source code must retain the above copyright notice, +this list of conditions and the following disclaimer. + + * Redistributions in binary form must reproduce the above copyright +notice, this list of conditions and the following disclaimer in +the documentation and/or other materials provided with the +distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +*******************************************************************************/ + +/** + * @{ + * @file al_hal_eth_main.c + * + * @brief XG Ethernet unit HAL driver for main functions (initialization, data path) + * + */ + +#include "al_hal_eth.h" +#include +#include +#include +#include "al_hal_eth_ec_regs.h" +#include "al_hal_eth_mac_regs.h" +#include +#ifdef AL_ETH_EX +#include "al_hal_eth_ex_internal.h" +#endif + +/* Number of xfi_txclk cycles that accumulate into 100ns */ +#define ETH_MAC_KR_PCS_CFG_EEE_TIMER_VAL 52 + +#define AL_ETH_TX_PKT_UDMA_FLAGS (AL_ETH_TX_FLAGS_NO_SNOOP | \ + AL_ETH_TX_FLAGS_INT) + +#define AL_ETH_TX_PKT_META_FLAGS (AL_ETH_TX_FLAGS_IPV4_L3_CSUM | \ + AL_ETH_TX_FLAGS_L4_CSUM | \ + AL_ETH_TX_FLAGS_L4_PARTIAL_CSUM | \ + AL_ETH_TX_FLAGS_L2_MACSEC_PKT | \ + AL_ETH_TX_FLAGS_L2_DIS_FCS |\ + AL_ETH_TX_FLAGS_TSO |\ + AL_ETH_TX_FLAGS_TS) + +#define AL_ETH_TX_SRC_VLAN_CNT_MASK 3 +#define AL_ETH_TX_SRC_VLAN_CNT_SHIFT 5 +#define AL_ETH_TX_L4_PROTO_IDX_MASK 0x1F +#define AL_ETH_TX_L4_PROTO_IDX_SHIFT 8 +#define AL_ETH_TX_TUNNEL_MODE_SHIFT 18 +#define AL_ETH_TX_OUTER_L3_PROTO_SHIFT 20 +#define AL_ETH_TX_VLAN_MOD_ADD_SHIFT 22 +#define AL_ETH_TX_VLAN_MOD_DEL_SHIFT 24 +#define AL_ETH_TX_VLAN_MOD_E_SEL_SHIFT 26 +#define AL_ETH_TX_VLAN_MOD_VID_SEL_SHIFT 28 +#define AL_ETH_TX_VLAN_MOD_PBIT_SEL_SHIFT 30 + +/* tx Meta Descriptor defines */ +#define AL_ETH_TX_META_STORE (1 << 21) +#define AL_ETH_TX_META_L3_LEN_MASK 0xff +#define AL_ETH_TX_META_L3_OFF_MASK 0xff +#define AL_ETH_TX_META_L3_OFF_SHIFT 8 +#define AL_ETH_TX_META_MSS_LSB_VAL_SHIFT 22 +#define AL_ETH_TX_META_MSS_MSB_TS_VAL_SHIFT 16 +#define AL_ETH_TX_META_OUTER_L3_LEN_MASK 0x1f +#define AL_ETH_TX_META_OUTER_L3_LEN_SHIFT 24 +#define AL_ETH_TX_META_OUTER_L3_OFF_HIGH_MASK 0x18 +#define AL_ETH_TX_META_OUTER_L3_OFF_HIGH_SHIFT 10 +#define AL_ETH_TX_META_OUTER_L3_OFF_LOW_MASK 0x07 +#define AL_ETH_TX_META_OUTER_L3_OFF_LOW_SHIFT 29 + +/* tx Meta Descriptor defines - MacSec */ +#define AL_ETH_TX_MACSEC_SIGN_SHIFT 0 /* Sign TX pkt */ +#define AL_ETH_TX_MACSEC_ENCRYPT_SHIFT 1 /* Encrypt TX pkt */ +#define AL_ETH_TX_MACSEC_AN_LSB_SHIFT 2 /* Association Number */ +#define AL_ETH_TX_MACSEC_AN_MSB_SHIFT 3 +#define AL_ETH_TX_MACSEC_SC_LSB_SHIFT 4 /* Secured Channel */ +#define AL_ETH_TX_MACSEC_SC_MSB_SHIFT 9 +#define AL_ETH_TX_MACSEC_SECURED_PYLD_LEN_LSB_SHIFT 10 /* Secure Payload Length (0x3FFF for non-SL packets) */ +#define AL_ETH_TX_MACSEC_SECURED_PYLD_LEN_MSB_SHIFT 23 + +/* Rx Descriptor defines */ +#define AL_ETH_RX_L3_PROTO_IDX_MASK 0x1F +#define AL_ETH_RX_SRC_VLAN_CNT_MASK 3 +#define AL_ETH_RX_SRC_VLAN_CNT_SHIFT 5 +#define AL_ETH_RX_L4_PROTO_IDX_MASK 0x1F +#define AL_ETH_RX_L4_PROTO_IDX_SHIFT 8 + +#define AL_ETH_RX_L3_OFFSET_SHIFT 9 +#define AL_ETH_RX_L3_OFFSET_MASK (0x7f << AL_ETH_RX_L3_OFFSET_SHIFT) +#define AL_ETH_RX_HASH_SHIFT 16 +#define AL_ETH_RX_HASH_MASK (0xffff << AL_ETH_RX_HASH_SHIFT) + +#define ETH_MAC_GEN_LED_CFG_BLINK_TIMER_VAL 5 +#define ETH_MAC_GEN_LED_CFG_ACT_TIMER_VAL 7 + +/* Tx VID Table*/ +#define AL_ETH_TX_VLAN_TABLE_UDMA_MASK 0xF +#define AL_ETH_TX_VLAN_TABLE_FWD_TO_MAC (1 << 4) + +/* tx gpd defines */ +#define AL_ETH_TX_GPD_L3_PROTO_MASK 0x1f +#define AL_ETH_TX_GPD_L3_PROTO_SHIFT 0 +#define AL_ETH_TX_GPD_L4_PROTO_MASK 0x1f +#define AL_ETH_TX_GPD_L4_PROTO_SHIFT 5 +#define AL_ETH_TX_GPD_TUNNEL_CTRL_MASK 0x7 +#define AL_ETH_TX_GPD_TUNNEL_CTRL_SHIFT 10 +#define AL_ETH_TX_GPD_SRC_VLAN_CNT_MASK 0x3 +#define AL_ETH_TX_GPD_SRC_VLAN_CNT_SHIFT 13 +#define AL_ETH_TX_GPD_CAM_DATA_2_SHIFT 32 +#define AL_ETH_TX_GPD_CAM_MASK_2_SHIFT 32 +#define AL_ETH_TX_GPD_CAM_CTRL_VALID_SHIFT 31 + +/* tx gcp defines */ +#define AL_ETH_TX_GCP_POLY_SEL_MASK 0x1 +#define AL_ETH_TX_GCP_POLY_SEL_SHIFT 0 +#define AL_ETH_TX_GCP_CRC32_BIT_COMP_MASK 0x1 +#define AL_ETH_TX_GCP_CRC32_BIT_COMP_SHIFT 1 +#define AL_ETH_TX_GCP_CRC32_BIT_SWAP_MASK 0x1 +#define AL_ETH_TX_GCP_CRC32_BIT_SWAP_SHIFT 2 +#define AL_ETH_TX_GCP_CRC32_BYTE_SWAP_MASK 0x1 +#define AL_ETH_TX_GCP_CRC32_BYTE_SWAP_SHIFT 3 +#define AL_ETH_TX_GCP_DATA_BIT_SWAP_MASK 0x1 +#define AL_ETH_TX_GCP_DATA_BIT_SWAP_SHIFT 4 +#define AL_ETH_TX_GCP_DATA_BYTE_SWAP_MASK 0x1 +#define AL_ETH_TX_GCP_DATA_BYTE_SWAP_SHIFT 5 +#define AL_ETH_TX_GCP_TRAIL_SIZE_MASK 0xF +#define AL_ETH_TX_GCP_TRAIL_SIZE_SHIFT 6 +#define AL_ETH_TX_GCP_HEAD_SIZE_MASK 0xFF +#define AL_ETH_TX_GCP_HEAD_SIZE_SHIFT 16 +#define AL_ETH_TX_GCP_HEAD_CALC_MASK 0x1 +#define AL_ETH_TX_GCP_HEAD_CALC_SHIFT 24 +#define AL_ETH_TX_GCP_MASK_POLARITY_MASK 0x1 +#define AL_ETH_TX_GCP_MASK_POLARITY_SHIFT 25 + +#define AL_ETH_TX_GCP_OPCODE_1_MASK 0x3F +#define AL_ETH_TX_GCP_OPCODE_1_SHIFT 0 +#define AL_ETH_TX_GCP_OPCODE_2_MASK 0x3F +#define AL_ETH_TX_GCP_OPCODE_2_SHIFT 6 +#define AL_ETH_TX_GCP_OPCODE_3_MASK 0x3F +#define AL_ETH_TX_GCP_OPCODE_3_SHIFT 12 +#define AL_ETH_TX_GCP_OPSEL_1_MASK 0xF +#define AL_ETH_TX_GCP_OPSEL_1_SHIFT 0 +#define AL_ETH_TX_GCP_OPSEL_2_MASK 0xF +#define AL_ETH_TX_GCP_OPSEL_2_SHIFT 4 +#define AL_ETH_TX_GCP_OPSEL_3_MASK 0xF +#define AL_ETH_TX_GCP_OPSEL_3_SHIFT 8 +#define AL_ETH_TX_GCP_OPSEL_4_MASK 0xF +#define AL_ETH_TX_GCP_OPSEL_4_SHIFT 12 + +/* Tx crc_chksum_replace defines */ +#define L4_CHECKSUM_DIS_AND_L3_CHECKSUM_DIS 0x00 +#define L4_CHECKSUM_DIS_AND_L3_CHECKSUM_EN 0x20 +#define L4_CHECKSUM_EN_AND_L3_CHECKSUM_DIS 0x40 +#define L4_CHECKSUM_EN_AND_L3_CHECKSUM_EN 0x60 + +/* rx gpd defines */ +#define AL_ETH_RX_GPD_OUTER_L3_PROTO_MASK 0x1f +#define AL_ETH_RX_GPD_OUTER_L3_PROTO_SHIFT (3 + 0) +#define AL_ETH_RX_GPD_OUTER_L4_PROTO_MASK 0x1f +#define AL_ETH_RX_GPD_OUTER_L4_PROTO_SHIFT (3 + 8) +#define AL_ETH_RX_GPD_INNER_L3_PROTO_MASK 0x1f +#define AL_ETH_RX_GPD_INNER_L3_PROTO_SHIFT (3 + 16) +#define AL_ETH_RX_GPD_INNER_L4_PROTO_MASK 0x1f +#define AL_ETH_RX_GPD_INNER_L4_PROTO_SHIFT (3 + 24) +#define AL_ETH_RX_GPD_OUTER_PARSE_CTRL_MASK 0xFF +#define AL_ETH_RX_GPD_OUTER_PARSE_CTRL_SHIFT 32 +#define AL_ETH_RX_GPD_INNER_PARSE_CTRL_MASK 0xFF +#define AL_ETH_RX_GPD_INNER_PARSE_CTRL_SHIFT 40 +#define AL_ETH_RX_GPD_L3_PRIORITY_MASK 0xFF +#define AL_ETH_RX_GPD_L3_PRIORITY_SHIFT 48 +#define AL_ETH_RX_GPD_L4_DST_PORT_LSB_MASK 0xFF +#define AL_ETH_RX_GPD_L4_DST_PORT_LSB_SHIFT 56 +#define AL_ETH_RX_GPD_CAM_DATA_2_SHIFT 32 +#define AL_ETH_RX_GPD_CAM_MASK_2_SHIFT 32 +#define AL_ETH_RX_GPD_CAM_CTRL_VALID_SHIFT 31 + +#define AL_ETH_RX_GPD_PARSE_RESULT_OUTER_L3_PROTO_IDX_OFFSET (106 + 5) +#define AL_ETH_RX_GPD_PARSE_RESULT_OUTER_L4_PROTO_IDX_OFFSET (106 + 10) +#define AL_ETH_RX_GPD_PARSE_RESULT_INNER_L3_PROTO_IDX_OFFSET (0 + 5) +#define AL_ETH_RX_GPD_PARSE_RESULT_INNER_L4_PROTO_IDX_OFFSET (0 + 10) +#define AL_ETH_RX_GPD_PARSE_RESULT_OUTER_PARSE_CTRL (106 + 4) +#define AL_ETH_RX_GPD_PARSE_RESULT_INNER_PARSE_CTRL 4 +#define AL_ETH_RX_GPD_PARSE_RESULT_L3_PRIORITY (106 + 13) +#define AL_ETH_RX_GPD_PARSE_RESULT_OUTER_L4_DST_PORT_LSB (106 + 65) + +/* rx gcp defines */ +#define AL_ETH_RX_GCP_POLY_SEL_MASK 0x1 +#define AL_ETH_RX_GCP_POLY_SEL_SHIFT 0 +#define AL_ETH_RX_GCP_CRC32_BIT_COMP_MASK 0x1 +#define AL_ETH_RX_GCP_CRC32_BIT_COMP_SHIFT 1 +#define AL_ETH_RX_GCP_CRC32_BIT_SWAP_MASK 0x1 +#define AL_ETH_RX_GCP_CRC32_BIT_SWAP_SHIFT 2 +#define AL_ETH_RX_GCP_CRC32_BYTE_SWAP_MASK 0x1 +#define AL_ETH_RX_GCP_CRC32_BYTE_SWAP_SHIFT 3 +#define AL_ETH_RX_GCP_DATA_BIT_SWAP_MASK 0x1 +#define AL_ETH_RX_GCP_DATA_BIT_SWAP_SHIFT 4 +#define AL_ETH_RX_GCP_DATA_BYTE_SWAP_MASK 0x1 +#define AL_ETH_RX_GCP_DATA_BYTE_SWAP_SHIFT 5 +#define AL_ETH_RX_GCP_TRAIL_SIZE_MASK 0xF +#define AL_ETH_RX_GCP_TRAIL_SIZE_SHIFT 6 +#define AL_ETH_RX_GCP_HEAD_SIZE_MASK 0xFF +#define AL_ETH_RX_GCP_HEAD_SIZE_SHIFT 16 +#define AL_ETH_RX_GCP_HEAD_CALC_MASK 0x1 +#define AL_ETH_RX_GCP_HEAD_CALC_SHIFT 24 +#define AL_ETH_RX_GCP_MASK_POLARITY_MASK 0x1 +#define AL_ETH_RX_GCP_MASK_POLARITY_SHIFT 25 + +#define AL_ETH_RX_GCP_OPCODE_1_MASK 0x3F +#define AL_ETH_RX_GCP_OPCODE_1_SHIFT 0 +#define AL_ETH_RX_GCP_OPCODE_2_MASK 0x3F +#define AL_ETH_RX_GCP_OPCODE_2_SHIFT 6 +#define AL_ETH_RX_GCP_OPCODE_3_MASK 0x3F +#define AL_ETH_RX_GCP_OPCODE_3_SHIFT 12 +#define AL_ETH_RX_GCP_OPSEL_1_MASK 0xF +#define AL_ETH_RX_GCP_OPSEL_1_SHIFT 0 +#define AL_ETH_RX_GCP_OPSEL_2_MASK 0xF +#define AL_ETH_RX_GCP_OPSEL_2_SHIFT 4 +#define AL_ETH_RX_GCP_OPSEL_3_MASK 0xF +#define AL_ETH_RX_GCP_OPSEL_3_SHIFT 8 +#define AL_ETH_RX_GCP_OPSEL_4_MASK 0xF +#define AL_ETH_RX_GCP_OPSEL_4_SHIFT 12 + +#define AL_ETH_MDIO_DELAY_PERIOD 1 /* micro seconds to wait when polling mdio status */ +#define AL_ETH_MDIO_DELAY_COUNT 150 /* number of times to poll */ +#define AL_ETH_S2M_UDMA_COMP_COAL_TIMEOUT 200 /* Rx descriptors coalescing timeout in SB clocks */ + +#define AL_ETH_EPE_ENTRIES_NUM 26 +static struct al_eth_epe_p_reg_entry al_eth_epe_p_regs[AL_ETH_EPE_ENTRIES_NUM] = { + { 0x0, 0x0, 0x0 }, + { 0x0, 0x0, 0x1 }, + { 0x0, 0x0, 0x2 }, + { 0x0, 0x0, 0x3 }, + { 0x18100, 0xFFFFF, 0x80000004 }, + { 0x188A8, 0xFFFFF, 0x80000005 }, + { 0x99100, 0xFFFFF, 0x80000006 }, + { 0x98100, 0xFFFFF, 0x80000007 }, + { 0x10800, 0x7FFFF, 0x80000008 }, + { 0x20000, 0x73FFF, 0x80000009 }, + { 0x20000, 0x70000, 0x8000000A }, + { 0x186DD, 0x7FFFF, 0x8000000B }, + { 0x30600, 0x7FF00, 0x8000000C }, + { 0x31100, 0x7FF00, 0x8000000D }, + { 0x32F00, 0x7FF00, 0x8000000E }, + { 0x32900, 0x7FF00, 0x8000000F }, + { 0x105DC, 0x7FFFF, 0x80010010 }, + { 0x188E5, 0x7FFFF, 0x80000011 }, + { 0x72000, 0x72000, 0x80000012 }, + { 0x70000, 0x72000, 0x80000013 }, + { 0x46558, 0x7FFFF, 0x80000001 }, + { 0x18906, 0x7FFFF, 0x80000015 }, + { 0x18915, 0x7FFFF, 0x80000016 }, + { 0x31B00, 0x7FF00, 0x80000017 }, + { 0x30400, 0x7FF00, 0x80000018 }, + { 0x0, 0x0, 0x8000001F } +}; + + +static struct al_eth_epe_control_entry al_eth_epe_control_table[AL_ETH_EPE_ENTRIES_NUM] = { + {{ 0x2800000, 0x0, 0x0, 0x0, 0x1, 0x400000 }}, + {{ 0x280004C, 0x746000, 0xA46030, 0xE00000, 0x2, 0x400000 }}, + {{ 0x2800054, 0x746000, 0xA46030, 0x1600000, 0x2, 0x400000 }}, + {{ 0x280005C, 0x746000, 0xA46030, 0x1E00000, 0x2, 0x400000 }}, + {{ 0x2800042, 0xD42000, 0x0, 0x400000, 0x1010412, 0x400000 }}, + {{ 0x2800042, 0xD42000, 0x0, 0x400000, 0x1010412, 0x400000 }}, + {{ 0x2800042, 0xE42000, 0x0, 0x400000, 0x2020002, 0x400000 }}, + {{ 0x2800042, 0xE42000, 0x0, 0x400000, 0x2020002, 0x400000 }}, + {{ 0x280B046, 0x0, 0x6C1008, 0x0, 0x4, 0x406800 }}, + {{ 0x2800049, 0xF44060, 0x1744080, 0x14404, 0x6, 0x400011 }}, + {{ 0x2015049, 0xF44060, 0x1744080, 0x14404, 0x8080007, 0x400011 }}, + {{ 0x280B046, 0xF60040, 0x6C1004, 0x2800000, 0x6, 0x406811 }}, + {{ 0x2815042, 0x1F42000, 0x2042010, 0x1414460, 0x10100009, 0x40B800 }}, + {{ 0x2815042, 0x1F42000, 0x2042010, 0x800000, 0x10100009, 0x40B800 }}, + {{ 0x280B042, 0x0, 0x0, 0x430400, 0x4040009, 0x0 }}, + {{ 0x2815580, 0x0, 0x0, 0x0, 0x4040005, 0x0 }}, + {{ 0x280B000, 0x0, 0x0, 0x0, 0x1, 0x400000 }}, + {{ 0x2800040, 0x174E000, 0x0, 0x0, 0xE, 0x406800 }}, + {{ 0x280B000, 0x0, 0x0, 0x600000, 0x1, 0x406800 }}, + {{ 0x280B000, 0x0, 0x0, 0xE00000, 0x1, 0x406800 }}, + {{ 0x2800000, 0x0, 0x0, 0x0, 0x1, 0x400000 }}, + {{ 0x280B046, 0x0, 0x0, 0x2800000, 0x7, 0x400000 }}, + {{ 0x280B046, 0xF60040, 0x6C1004, 0x2800000, 0x6, 0x406811 }}, + {{ 0x2815042, 0x1F43028, 0x2000000, 0xC00000, 0x10100009, 0x40B800 }}, + {{ 0x2815400, 0x0, 0x0, 0x0, 0x4040005, 0x0 }}, + {{ 0x2800000, 0x0, 0x0, 0x0, 0x1, 0x400000 }} +}; + + +#define AL_ETH_IS_1G_MAC(mac_mode) (((mac_mode) == AL_ETH_MAC_MODE_RGMII) || ((mac_mode) == AL_ETH_MAC_MODE_SGMII)) +#define AL_ETH_IS_10G_MAC(mac_mode) (((mac_mode) == AL_ETH_MAC_MODE_10GbE_Serial) || \ + ((mac_mode) == AL_ETH_MAC_MODE_10G_SGMII) || \ + ((mac_mode) == AL_ETH_MAC_MODE_SGMII_2_5G)) +#define AL_ETH_IS_25G_MAC(mac_mode) ((mac_mode) == AL_ETH_MAC_MODE_KR_LL_25G) + +static const char *al_eth_mac_mode_str(enum al_eth_mac_mode mode) +{ + switch(mode) { + case AL_ETH_MAC_MODE_RGMII: + return "RGMII"; + case AL_ETH_MAC_MODE_SGMII: + return "SGMII"; + case AL_ETH_MAC_MODE_SGMII_2_5G: + return "SGMII_2_5G"; + case AL_ETH_MAC_MODE_10GbE_Serial: + return "KR"; + case AL_ETH_MAC_MODE_KR_LL_25G: + return "KR_LL_25G"; + case AL_ETH_MAC_MODE_10G_SGMII: + return "10G_SGMII"; + case AL_ETH_MAC_MODE_XLG_LL_40G: + return "40G_LL"; + case AL_ETH_MAC_MODE_XLG_LL_50G: + return "50G_LL"; + default: + return "N/A"; + } +} + +/** + * change and wait udma state + * + * @param dma the udma to change its state + * @param new_state + * + * @return 0 on success. otherwise on failure. + */ +static int al_udma_state_set_wait(struct al_udma *dma, enum al_udma_state new_state) +{ + enum al_udma_state state; + enum al_udma_state expected_state = new_state; + int count = 1000; + int rc; + + rc = al_udma_state_set(dma, new_state); + if (rc != 0) { + al_warn("[%s] warn: failed to change state, error %d\n", dma->name, rc); + return rc; + } + + if ((new_state == UDMA_NORMAL) || (new_state == UDMA_DISABLE)) + expected_state = UDMA_IDLE; + + do { + state = al_udma_state_get(dma); + if (state == expected_state) + break; + al_udelay(1); + if (count-- == 0) { + al_warn("[%s] warn: dma state didn't change to %s\n", + dma->name, al_udma_states_name[new_state]); + return -ETIMEDOUT; + } + } while (1); + return 0; +} + +static void al_eth_epe_entry_set(struct al_hal_eth_adapter *adapter, uint32_t idx, + struct al_eth_epe_p_reg_entry *reg_entry, + struct al_eth_epe_control_entry *control_entry) +{ + al_reg_write32(&adapter->ec_regs_base->epe_p[idx].comp_data, reg_entry->data); + al_reg_write32(&adapter->ec_regs_base->epe_p[idx].comp_mask, reg_entry->mask); + al_reg_write32(&adapter->ec_regs_base->epe_p[idx].comp_ctrl, reg_entry->ctrl); + + al_reg_write32(&adapter->ec_regs_base->msp_c[idx].p_comp_data, reg_entry->data); + al_reg_write32(&adapter->ec_regs_base->msp_c[idx].p_comp_mask, reg_entry->mask); + al_reg_write32(&adapter->ec_regs_base->msp_c[idx].p_comp_ctrl, reg_entry->ctrl); + + /*control table 0*/ + al_reg_write32(&adapter->ec_regs_base->epe[0].act_table_addr, idx); + al_reg_write32(&adapter->ec_regs_base->epe[0].act_table_data_6, + control_entry->data[5]); + al_reg_write32(&adapter->ec_regs_base->epe[0].act_table_data_2, + control_entry->data[1]); + al_reg_write32(&adapter->ec_regs_base->epe[0].act_table_data_3, + control_entry->data[2]); + al_reg_write32(&adapter->ec_regs_base->epe[0].act_table_data_4, + control_entry->data[3]); + al_reg_write32(&adapter->ec_regs_base->epe[0].act_table_data_5, + control_entry->data[4]); + al_reg_write32(&adapter->ec_regs_base->epe[0].act_table_data_1, + control_entry->data[0]); + + /*control table 1*/ + al_reg_write32(&adapter->ec_regs_base->epe[1].act_table_addr, idx); + al_reg_write32(&adapter->ec_regs_base->epe[1].act_table_data_6, + control_entry->data[5]); + al_reg_write32(&adapter->ec_regs_base->epe[1].act_table_data_2, + control_entry->data[1]); + al_reg_write32(&adapter->ec_regs_base->epe[1].act_table_data_3, + control_entry->data[2]); + al_reg_write32(&adapter->ec_regs_base->epe[1].act_table_data_4, + control_entry->data[3]); + al_reg_write32(&adapter->ec_regs_base->epe[1].act_table_data_5, + control_entry->data[4]); + al_reg_write32(&adapter->ec_regs_base->epe[1].act_table_data_1, + control_entry->data[0]); +} + +static void al_eth_epe_init(struct al_hal_eth_adapter *adapter) +{ + int idx; + + if (adapter->enable_rx_parser == 0) { + al_dbg("eth [%s]: disable rx parser\n", adapter->name); + + al_reg_write32(&adapter->ec_regs_base->epe[0].res_def, 0x08000000); + al_reg_write32(&adapter->ec_regs_base->epe[0].res_in, 0x7); + + al_reg_write32(&adapter->ec_regs_base->epe[1].res_def, 0x08000000); + al_reg_write32(&adapter->ec_regs_base->epe[1].res_in, 0x7); + + return; + } + al_dbg("eth [%s]: enable rx parser\n", adapter->name); + for (idx = 0; idx < AL_ETH_EPE_ENTRIES_NUM; idx++) + al_eth_epe_entry_set(adapter, idx, &al_eth_epe_p_regs[idx], &al_eth_epe_control_table[idx]); + + al_reg_write32(&adapter->ec_regs_base->epe[0].res_def, 0x08000080); + al_reg_write32(&adapter->ec_regs_base->epe[0].res_in, 0x7); + + al_reg_write32(&adapter->ec_regs_base->epe[1].res_def, 0x08000080); + al_reg_write32(&adapter->ec_regs_base->epe[1].res_in, 0); + + /* header length as function of 4 bits value, for GRE, when C bit is set, the header len should be increase by 4*/ + al_reg_write32(&adapter->ec_regs_base->epe_h[8].hdr_len, (4 << 16) | 4); + + /* select the outer information when writing the rx descriptor (l3 protocol index etc) */ + al_reg_write32(&adapter->ec_regs_base->rfw.meta, EC_RFW_META_L3_LEN_CALC); + + al_reg_write32(&adapter->ec_regs_base->rfw.checksum, EC_RFW_CHECKSUM_HDR_SEL); +} + +/** + * read 40G MAC registers (indirect access) + * + * @param adapter pointer to the private structure + * @param reg_addr address in the an registers + * + * @return the register value + */ +static uint32_t al_eth_40g_mac_reg_read( + struct al_hal_eth_adapter *adapter, + uint32_t reg_addr) +{ + uint32_t val; + + /* indirect access */ + al_reg_write32(&adapter->mac_regs_base->gen_v3.mac_40g_ll_addr, reg_addr); + val = al_reg_read32(&adapter->mac_regs_base->gen_v3.mac_40g_ll_data); + + al_dbg("[%s]: %s - reg %d. val 0x%x", + adapter->name, __func__, reg_addr, val); + + return val; +} + +/** + * write 40G MAC registers (indirect access) + * + * @param adapter pointer to the private structure + * @param reg_addr address in the an registers + * @param reg_data value to write to the register + * + */ +static void al_eth_40g_mac_reg_write( + struct al_hal_eth_adapter *adapter, + uint32_t reg_addr, + uint32_t reg_data) +{ + /* indirect access */ + al_reg_write32(&adapter->mac_regs_base->gen_v3.mac_40g_ll_addr, reg_addr); + al_reg_write32(&adapter->mac_regs_base->gen_v3.mac_40g_ll_data, reg_data); + + al_dbg("[%s]: %s - reg %d. val 0x%x", + adapter->name, __func__, reg_addr, reg_data); +} + +/** + * read 40G PCS registers (indirect access) + * + * @param adapter pointer to the private structure + * @param reg_addr address in the an registers + * + * @return the register value + */ +static uint32_t al_eth_40g_pcs_reg_read( + struct al_hal_eth_adapter *adapter, + uint32_t reg_addr) +{ + uint32_t val; + + /* indirect access */ + al_reg_write32(&adapter->mac_regs_base->gen_v3.pcs_40g_ll_addr, reg_addr); + val = al_reg_read32(&adapter->mac_regs_base->gen_v3.pcs_40g_ll_data); + + al_dbg("[%s]: %s - reg %d. val 0x%x", + adapter->name, __func__, reg_addr, val); + + return val; +} + +/** + * write 40G PCS registers (indirect access) + * + * @param adapter pointer to the private structure + * @param reg_addr address in the an registers + * @param reg_data value to write to the register + * + */ +static void al_eth_40g_pcs_reg_write( + struct al_hal_eth_adapter *adapter, + uint32_t reg_addr, + uint32_t reg_data) +{ + /* indirect access */ + al_reg_write32(&adapter->mac_regs_base->gen_v3.pcs_40g_ll_addr, reg_addr); + al_reg_write32(&adapter->mac_regs_base->gen_v3.pcs_40g_ll_data, reg_data); + + al_dbg("[%s]: %s - reg %d. val 0x%x", + adapter->name, __func__, reg_addr, reg_data); +} + +/*****************************API Functions **********************************/ +/*adapter management */ +/** + * initialize the ethernet adapter's DMA + */ +int al_eth_adapter_init(struct al_hal_eth_adapter *adapter, struct al_eth_adapter_params *params) +{ + struct al_udma_params udma_params; + struct al_udma_m2s_pkt_len_conf conf; + int i; + uint32_t reg; + int rc; + + al_dbg("eth [%s]: initialize controller's UDMA. id = %d\n", params->name, params->udma_id); + al_dbg("eth [%s]: UDMA base regs: %p\n", params->name, params->udma_regs_base); + al_dbg("eth [%s]: EC base regs: %p\n", params->name, params->ec_regs_base); + al_dbg("eth [%s]: MAC base regs: %p\n", params->name, params->mac_regs_base); + al_dbg("eth [%s]: enable_rx_parser: %x\n", params->name, params->enable_rx_parser); + + adapter->name = params->name; + adapter->rev_id = params->rev_id; + adapter->udma_id = params->udma_id; + adapter->udma_regs_base = params->udma_regs_base; + adapter->ec_regs_base = (struct al_ec_regs __iomem*)params->ec_regs_base; + adapter->mac_regs_base = (struct al_eth_mac_regs __iomem*)params->mac_regs_base; + adapter->unit_regs = (struct unit_regs __iomem *)params->udma_regs_base; + adapter->enable_rx_parser = params->enable_rx_parser; + adapter->ec_ints_base = (void __iomem *)((uint32_t)adapter->ec_regs_base + 0x1c00); + adapter->mac_ints_base = (void __iomem *)((uint32_t)adapter->mac_regs_base + 0x800); + + /* initialize Tx udma */ + udma_params.udma_regs_base = adapter->unit_regs; + udma_params.type = UDMA_TX; + udma_params.num_of_queues = AL_ETH_UDMA_TX_QUEUES; + udma_params.name = "eth tx"; + rc = al_udma_init(&adapter->tx_udma, &udma_params); + + if (rc != 0) { + al_err("failed to initialize %s, error %d\n", + udma_params.name, rc); + return rc; + } + rc = al_udma_state_set_wait(&adapter->tx_udma, UDMA_NORMAL); + if (rc != 0) { + al_err("[%s]: failed to change state, error %d\n", + udma_params.name, rc); + return rc; + } + /* initialize Rx udma */ + udma_params.udma_regs_base = adapter->unit_regs; + udma_params.type = UDMA_RX; + udma_params.num_of_queues = AL_ETH_UDMA_RX_QUEUES; + udma_params.name = "eth rx"; + rc = al_udma_init(&adapter->rx_udma, &udma_params); + + if (rc != 0) { + al_err("failed to initialize %s, error %d\n", + udma_params.name, rc); + return rc; + } + + rc = al_udma_state_set_wait(&adapter->rx_udma, UDMA_NORMAL); + if (rc != 0) { + al_err("[%s]: failed to change state, error %d\n", + udma_params.name, rc); + return rc; + } + al_dbg("eth [%s]: controller's UDMA successfully initialized\n", + params->name); + + /* set max packet size to 1M (for TSO) */ + conf.encode_64k_as_zero = AL_TRUE; + conf.max_pkt_size = 0xfffff; + al_udma_m2s_packet_size_cfg_set(&adapter->tx_udma, &conf); + + /* set m2s (tx) max descriptors to max data buffers number and one for + * meta descriptor + */ + al_udma_m2s_max_descs_set(&adapter->tx_udma, AL_ETH_PKT_MAX_BUFS + 1); + + /* set s2m (rx) max descriptors to max data buffers */ + al_udma_s2m_max_descs_set(&adapter->rx_udma, AL_ETH_PKT_MAX_BUFS); + + /* set s2m burst lenght when writing completion descriptors to 64 bytes + */ + al_udma_s2m_compl_desc_burst_config(&adapter->rx_udma, 64); + + /* if pointer to ec regs provided, then init the tx meta cache of this udma*/ + if (adapter->ec_regs_base != NULL) { + // INIT TX CACHE TABLE: + for (i = 0; i < 4; i++) { + al_reg_write32(&adapter->ec_regs_base->tso.cache_table_addr, i + (adapter->udma_id * 4)); + al_reg_write32(&adapter->ec_regs_base->tso.cache_table_data_1, 0x00000000); + al_reg_write32(&adapter->ec_regs_base->tso.cache_table_data_2, 0x00000000); + al_reg_write32(&adapter->ec_regs_base->tso.cache_table_data_3, 0x00000000); + al_reg_write32(&adapter->ec_regs_base->tso.cache_table_data_4, 0x00000000); + } + } + // only udma 0 allowed to init ec + if (adapter->udma_id != 0) { + return 0; + } + /* enable Ethernet controller: */ + /* enable internal machines*/ + al_reg_write32(&adapter->ec_regs_base->gen.en, 0xffffffff); + al_reg_write32(&adapter->ec_regs_base->gen.fifo_en, 0xffffffff); + + if (adapter->rev_id > AL_ETH_REV_ID_0) { + /* enable A0 descriptor structure */ + al_reg_write32_masked(&adapter->ec_regs_base->gen.en_ext, + EC_GEN_EN_EXT_CACHE_WORD_SPLIT, + EC_GEN_EN_EXT_CACHE_WORD_SPLIT); + + /* use mss value in the descriptor */ + al_reg_write32(&adapter->ec_regs_base->tso.cfg_add_0, + EC_TSO_CFG_ADD_0_MSS_SEL); + + /* enable tunnel TSO */ + al_reg_write32(&adapter->ec_regs_base->tso.cfg_tunnel, + (EC_TSO_CFG_TUNNEL_EN_TUNNEL_TSO | + EC_TSO_CFG_TUNNEL_EN_UDP_CHKSUM | + EC_TSO_CFG_TUNNEL_EN_UDP_LEN | + EC_TSO_CFG_TUNNEL_EN_IPV6_PLEN | + EC_TSO_CFG_TUNNEL_EN_IPV4_CHKSUM | + EC_TSO_CFG_TUNNEL_EN_IPV4_IDEN | + EC_TSO_CFG_TUNNEL_EN_IPV4_TLEN)); + } + + /* swap input byts from MAC RX */ + al_reg_write32(&adapter->ec_regs_base->mac.gen, 0x00000001); + /* swap output bytes to MAC TX*/ + al_reg_write32(&adapter->ec_regs_base->tmi.tx_cfg, EC_TMI_TX_CFG_EN_FWD_TO_RX|EC_TMI_TX_CFG_SWAP_BYTES); + + /* TODO: check if we need this line*/ + al_reg_write32(&adapter->ec_regs_base->tfw_udma[0].fwd_dec, 0x000003fb); + + /* RFW configuration: default 0 */ + al_reg_write32(&adapter->ec_regs_base->rfw_default[0].opt_1, 0x00000001); + + /* VLAN table address*/ + al_reg_write32(&adapter->ec_regs_base->rfw.vid_table_addr, 0x00000000); + /* VLAN table data*/ + al_reg_write32(&adapter->ec_regs_base->rfw.vid_table_data, 0x00000000); + /* HASH config (select toeplitz and bits 7:0 of the thash result, enable + * symmetric hash) */ + al_reg_write32(&adapter->ec_regs_base->rfw.thash_cfg_1, + EC_RFW_THASH_CFG_1_ENABLE_IP_SWAP | + EC_RFW_THASH_CFG_1_ENABLE_PORT_SWAP); + + al_eth_epe_init(adapter); + + /* disable TSO padding and use mac padding instead */ + reg = al_reg_read32(&adapter->ec_regs_base->tso.in_cfg); + reg &= ~0x7F00; /*clear bits 14:8 */ + al_reg_write32(&adapter->ec_regs_base->tso.in_cfg, reg); + + return 0; +} + +/*****************************API Functions **********************************/ +/*adapter management */ +/** + * enable the ec and mac interrupts + */ +int al_eth_ec_mac_ints_config(struct al_hal_eth_adapter *adapter) +{ + + al_dbg("eth [%s]: enable ethernet and mac interrupts\n", adapter->name); + + // only udma 0 allowed to init ec + if (adapter->udma_id != 0) + return -EPERM; + + /* enable mac ints */ + al_iofic_config(adapter->ec_ints_base, AL_INT_GROUP_A, + INT_CONTROL_GRP_SET_ON_POSEDGE | INT_CONTROL_GRP_CLEAR_ON_READ); + al_iofic_config(adapter->ec_ints_base, AL_INT_GROUP_B, + INT_CONTROL_GRP_SET_ON_POSEDGE | INT_CONTROL_GRP_CLEAR_ON_READ); + al_iofic_config(adapter->ec_ints_base, AL_INT_GROUP_C, + INT_CONTROL_GRP_SET_ON_POSEDGE | INT_CONTROL_GRP_CLEAR_ON_READ); + al_iofic_config(adapter->ec_ints_base, AL_INT_GROUP_D, + INT_CONTROL_GRP_SET_ON_POSEDGE | INT_CONTROL_GRP_CLEAR_ON_READ); + + /* unmask MAC int */ + al_iofic_unmask(adapter->ec_ints_base, AL_INT_GROUP_A, 8); + + /* enable ec interrupts */ + al_iofic_config(adapter->mac_ints_base, AL_INT_GROUP_A, + INT_CONTROL_GRP_SET_ON_POSEDGE | INT_CONTROL_GRP_CLEAR_ON_READ); + al_iofic_config(adapter->mac_ints_base, AL_INT_GROUP_B, + INT_CONTROL_GRP_SET_ON_POSEDGE | INT_CONTROL_GRP_CLEAR_ON_READ); + al_iofic_config(adapter->mac_ints_base, AL_INT_GROUP_C, + INT_CONTROL_GRP_SET_ON_POSEDGE | INT_CONTROL_GRP_CLEAR_ON_READ); + al_iofic_config(adapter->mac_ints_base, AL_INT_GROUP_D, + INT_CONTROL_GRP_SET_ON_POSEDGE | INT_CONTROL_GRP_CLEAR_ON_READ); + + /* eee active */ + al_iofic_unmask(adapter->mac_ints_base, AL_INT_GROUP_B, AL_BIT(14)); + + al_iofic_unmask(adapter->unit_regs, AL_INT_GROUP_D, AL_BIT(11)); + return 0; +} + +/** + * ec and mac interrupt service routine + * read and print asserted interrupts + * + * @param adapter pointer to the private structure + * + * @return 0 on success. otherwise on failure. + */ +int al_eth_ec_mac_isr(struct al_hal_eth_adapter *adapter) +{ + uint32_t cause; + al_dbg("[%s]: ethernet interrupts handler\n", adapter->name); + + // only udma 0 allowed to init ec + if (adapter->udma_id != 0) + return -EPERM; + + /* read ec cause */ + cause = al_iofic_read_cause(adapter->ec_ints_base, AL_INT_GROUP_A); + al_dbg("[%s]: ethernet group A cause 0x%08x\n", adapter->name, cause); + if (cause & 1) + { + cause = al_iofic_read_cause(adapter->mac_ints_base, AL_INT_GROUP_A); + al_dbg("[%s]: mac group A cause 0x%08x\n", adapter->name, cause); + + cause = al_iofic_read_cause(adapter->mac_ints_base, AL_INT_GROUP_B); + al_dbg("[%s]: mac group B cause 0x%08x\n", adapter->name, cause); + + cause = al_iofic_read_cause(adapter->mac_ints_base, AL_INT_GROUP_C); + al_dbg("[%s]: mac group C cause 0x%08x\n", adapter->name, cause); + + cause = al_iofic_read_cause(adapter->mac_ints_base, AL_INT_GROUP_D); + al_dbg("[%s]: mac group D cause 0x%08x\n", adapter->name, cause); + } + cause = al_iofic_read_cause(adapter->ec_ints_base, AL_INT_GROUP_B); + al_dbg("[%s]: ethernet group B cause 0x%08x\n", adapter->name, cause); + cause = al_iofic_read_cause(adapter->ec_ints_base, AL_INT_GROUP_C); + al_dbg("[%s]: ethernet group C cause 0x%08x\n", adapter->name, cause); + cause = al_iofic_read_cause(adapter->ec_ints_base, AL_INT_GROUP_D); + al_dbg("[%s]: ethernet group D cause 0x%08x\n", adapter->name, cause); + + return 0; +} + +/** + * stop the DMA of the ethernet adapter + */ +int al_eth_adapter_stop(struct al_hal_eth_adapter *adapter) +{ + int rc; + + al_dbg("eth [%s]: stop controller's UDMA\n", adapter->name); + + /* disable Tx dma*/ + rc = al_udma_state_set_wait(&adapter->tx_udma, UDMA_DISABLE); + if (rc != 0) { + al_warn("[%s] warn: failed to change state, error %d\n", + adapter->tx_udma.name, rc); + return rc; + } + + al_dbg("eth [%s]: controller's TX UDMA stopped\n", + adapter->name); + /* disable Rx dma*/ + rc = al_udma_state_set_wait(&adapter->rx_udma, UDMA_DISABLE); + if (rc != 0) { + al_warn("[%s] warn: failed to change state, error %d\n", + adapter->rx_udma.name, rc); + return rc; + } + + al_dbg("eth [%s]: controller's RX UDMA stopped\n", + adapter->name); + return 0; +} + +int al_eth_adapter_reset(struct al_hal_eth_adapter *adapter) +{ + al_dbg("eth [%s]: reset controller's UDMA\n", adapter->name); + + return -EPERM; +} + +/* Q management */ +/** + * Configure and enable a queue ring + */ +int al_eth_queue_config(struct al_hal_eth_adapter *adapter, enum al_udma_type type, uint32_t qid, + struct al_udma_q_params *q_params) +{ + struct al_udma *udma; + int rc; + + al_dbg("eth [%s]: config UDMA %s queue %d\n", adapter->name, + type == UDMA_TX ? "Tx" : "Rx", qid); + + if (type == UDMA_TX) { + udma = &adapter->tx_udma; + } else { + udma = &adapter->rx_udma; + } + + q_params->adapter_rev_id = adapter->rev_id; + + rc = al_udma_q_init(udma, qid, q_params); + + if (rc) + return rc; + + if (type == UDMA_RX) { + rc = al_udma_s2m_q_compl_coal_config(&udma->udma_q[qid], + AL_TRUE, AL_ETH_S2M_UDMA_COMP_COAL_TIMEOUT); + + al_assert(q_params->cdesc_size <= 32); + + if (q_params->cdesc_size > 16) + al_reg_write32_masked(&adapter->ec_regs_base->rfw.out_cfg, + EC_RFW_OUT_CFG_META_CNT_MASK, 2); + } + return rc; +} + +int al_eth_queue_enable(struct al_hal_eth_adapter *adapter __attribute__((__unused__)), + enum al_udma_type type __attribute__((__unused__)), + uint32_t qid __attribute__((__unused__))) +{ + return -EPERM; +} +int al_eth_queue_disable(struct al_hal_eth_adapter *adapter __attribute__((__unused__)), + enum al_udma_type type __attribute__((__unused__)), + uint32_t qid __attribute__((__unused__))) +{ + return -EPERM; +} + +/* MAC layer */ +int al_eth_rx_pkt_limit_config(struct al_hal_eth_adapter *adapter, uint32_t min_rx_len, uint32_t max_rx_len) +{ + al_assert(max_rx_len <= AL_ETH_MAX_FRAME_LEN); + + /* EC minimum packet length [bytes] in RX */ + al_reg_write32(&adapter->ec_regs_base->mac.min_pkt, min_rx_len); + /* EC maximum packet length [bytes] in RX */ + al_reg_write32(&adapter->ec_regs_base->mac.max_pkt, max_rx_len); + + if (adapter->rev_id > AL_ETH_REV_ID_2) { + al_reg_write32(&adapter->mac_regs_base->gen_v3.rx_afifo_cfg_1, min_rx_len); + al_reg_write32(&adapter->mac_regs_base->gen_v3.rx_afifo_cfg_2, max_rx_len); + } + + /* configure the MAC's max rx length, add 16 bytes so the packet get + * trimmed by the EC/Async_fifo rather by the MAC + */ + if (AL_ETH_IS_1G_MAC(adapter->mac_mode)) + al_reg_write32(&adapter->mac_regs_base->mac_1g.frm_len, max_rx_len + 16); + else if (AL_ETH_IS_10G_MAC(adapter->mac_mode) || AL_ETH_IS_25G_MAC(adapter->mac_mode)) + /* 10G MAC control register */ + al_reg_write32(&adapter->mac_regs_base->mac_10g.frm_len, (max_rx_len + 16)); + else + al_eth_40g_mac_reg_write(adapter, ETH_MAC_GEN_V3_MAC_40G_FRM_LENGTH_ADDR, (max_rx_len + 16)); + + return 0; +} + +/* configure the mac media type. */ +int al_eth_mac_config(struct al_hal_eth_adapter *adapter, enum al_eth_mac_mode mode) +{ + switch(mode) { + case AL_ETH_MAC_MODE_RGMII: + al_reg_write32(&adapter->mac_regs_base->gen.clk_cfg, 0x40003210); + + /* 1G MAC control register */ + /* bit[0] - TX_ENA - zeroed by default. Should be asserted by al_eth_mac_start + * bit[1] - RX_ENA - zeroed by default. Should be asserted by al_eth_mac_start + * bit[3] - ETH_SPEED - zeroed to enable 10/100 Mbps Ethernet + * bit[4] - PROMIS_EN - asserted to enable MAC promiscuous mode + * bit[23] - CNTL_FRM-ENA - asserted to enable control frames + * bit[24] - NO_LGTH_CHECK - asserted to disable length checks, which is done in the controller + */ + al_reg_write32(&adapter->mac_regs_base->mac_1g.cmd_cfg, 0x01800010); + + /* RX_SECTION_EMPTY, */ + al_reg_write32(&adapter->mac_regs_base->mac_1g.rx_section_empty, 0x00000000); + /* RX_SECTION_FULL, */ + al_reg_write32(&adapter->mac_regs_base->mac_1g.rx_section_full, 0x0000000c); /* must be larger than almost empty */ + /* RX_ALMOST_EMPTY, */ + al_reg_write32(&adapter->mac_regs_base->mac_1g.rx_almost_empty, 0x00000008); + /* RX_ALMOST_FULL, */ + al_reg_write32(&adapter->mac_regs_base->mac_1g.rx_almost_full, 0x00000008); + + + /* TX_SECTION_EMPTY, */ + al_reg_write32(&adapter->mac_regs_base->mac_1g.tx_section_empty, 0x00000008); /* 8 ? */ + /* TX_SECTION_FULL, 0 - store and forward, */ + al_reg_write32(&adapter->mac_regs_base->mac_1g.tx_section_full, 0x0000000c); + /* TX_ALMOST_EMPTY, */ + al_reg_write32(&adapter->mac_regs_base->mac_1g.tx_almost_empty, 0x00000008); + /* TX_ALMOST_FULL, */ + al_reg_write32(&adapter->mac_regs_base->mac_1g.tx_almost_full, 0x00000008); + + /* XAUI MAC control register */ + al_reg_write32(&adapter->mac_regs_base->gen.cfg, 0x00000000); + + /* 1G MACSET 1G */ + /* taking sel_1000/sel_10 inputs from rgmii PHY, and not from register. + * disabling magic_packets detection in mac */ + al_reg_write32(&adapter->mac_regs_base->gen.mac_1g_cfg, 0x00000002); + /* RGMII set 1G */ + al_reg_write32_masked(&adapter->mac_regs_base->gen.mux_sel, ~ETH_MAC_GEN_MUX_SEL_KR_IN_MASK, 0x00063910); + al_reg_write32(&adapter->mac_regs_base->gen.rgmii_sel, 0xF); + break; + case AL_ETH_MAC_MODE_SGMII: + if (adapter->rev_id > AL_ETH_REV_ID_2) { + /* configure and enable the ASYNC FIFO between the MACs and the EC */ + /* TX min packet size */ + al_reg_write32(&adapter->mac_regs_base->gen_v3.tx_afifo_cfg_1, 0x00000037); + /* TX max packet size */ + al_reg_write32(&adapter->mac_regs_base->gen_v3.tx_afifo_cfg_2, 0x00002800); + /* TX input bus configuration */ + al_reg_write32(&adapter->mac_regs_base->gen_v3.tx_afifo_cfg_3, 0x00000080); + /* TX output bus configuration */ + al_reg_write32(&adapter->mac_regs_base->gen_v3.tx_afifo_cfg_4, 0x00030020); + /* TX Valid/ready configuration */ + al_reg_write32(&adapter->mac_regs_base->gen_v3.tx_afifo_cfg_5, 0x00000121); + /* RX min packet size */ + /* al_reg_write32(&adapter->mac_regs_base->gen_v3.rx_afifo_cfg_1, 0x00000040); */ + /* RX max packet size */ + /* al_reg_write32(&adapter->mac_regs_base->gen_v3.rx_afifo_cfg_2, 0x00002800); */ + /* RX input bus configuration */ + al_reg_write32(&adapter->mac_regs_base->gen_v3.rx_afifo_cfg_3, 0x00030020); + /* RX output bus configuration */ + al_reg_write32(&adapter->mac_regs_base->gen_v3.rx_afifo_cfg_4, 0x00000080); + /* RX Valid/ready configuration */ + al_reg_write32(&adapter->mac_regs_base->gen_v3.rx_afifo_cfg_5, 0x00000212); + /* V3 additional MAC selection */ + al_reg_write32(&adapter->mac_regs_base->gen_v3.mac_sel, 0x00000000); + al_reg_write32(&adapter->mac_regs_base->gen_v3.mac_10g_ll_cfg, 0x00000001); + al_reg_write32(&adapter->mac_regs_base->gen_v3.mac_10g_ll_ctrl, 0x00000000); + al_reg_write32(&adapter->mac_regs_base->gen_v3.pcs_10g_ll_cfg, 0x00000000); + /* ASYNC FIFO ENABLE */ + al_reg_write32(&adapter->mac_regs_base->gen_v3.afifo_ctrl, 0x00003333); + /* Timestamp_configuration */ + al_reg_write32(&adapter->mac_regs_base->gen_v3.spare, + ETH_MAC_GEN_V3_SPARE_CHICKEN_DISABLE_TIMESTAMP_STRETCH); + } + + al_reg_write32(&adapter->mac_regs_base->gen.clk_cfg, 0x40053210); + + /* 1G MAC control register */ + /* bit[0] - TX_ENA - zeroed by default. Should be asserted by al_eth_mac_start + * bit[1] - RX_ENA - zeroed by default. Should be asserted by al_eth_mac_start + * bit[3] - ETH_SPEED - zeroed to enable 10/100 Mbps Ethernet + * bit[4] - PROMIS_EN - asserted to enable MAC promiscuous mode + * bit[23] - CNTL_FRM-ENA - asserted to enable control frames + * bit[24] - NO_LGTH_CHECK - asserted to disable length checks, which is done in the controller + */ + al_reg_write32(&adapter->mac_regs_base->mac_1g.cmd_cfg, 0x01800010); + + /* RX_SECTION_EMPTY, */ + al_reg_write32(&adapter->mac_regs_base->mac_1g.rx_section_empty, 0x00000000); + /* RX_SECTION_FULL, */ + al_reg_write32(&adapter->mac_regs_base->mac_1g.rx_section_full, 0x0000000c); /* must be larger than almost empty */ + /* RX_ALMOST_EMPTY, */ + al_reg_write32(&adapter->mac_regs_base->mac_1g.rx_almost_empty, 0x00000008); + /* RX_ALMOST_FULL, */ + al_reg_write32(&adapter->mac_regs_base->mac_1g.rx_almost_full, 0x00000008); + + + /* TX_SECTION_EMPTY, */ + al_reg_write32(&adapter->mac_regs_base->mac_1g.tx_section_empty, 0x00000008); /* 8 ? */ + /* TX_SECTION_FULL, 0 - store and forward, */ + al_reg_write32(&adapter->mac_regs_base->mac_1g.tx_section_full, 0x0000000c); + /* TX_ALMOST_EMPTY, */ + al_reg_write32(&adapter->mac_regs_base->mac_1g.tx_almost_empty, 0x00000008); + /* TX_ALMOST_FULL, */ + al_reg_write32(&adapter->mac_regs_base->mac_1g.tx_almost_full, 0x00000008); + + /* XAUI MAC control register */ + al_reg_write32(&adapter->mac_regs_base->gen.cfg, 0x000000c0); + + /* 1G MACSET 1G */ + /* taking sel_1000/sel_10 inputs from rgmii_converter, and not from register. + * disabling magic_packets detection in mac */ + al_reg_write32(&adapter->mac_regs_base->gen.mac_1g_cfg, 0x00000002); + /* SerDes configuration */ + al_reg_write32_masked(&adapter->mac_regs_base->gen.mux_sel, ~ETH_MAC_GEN_MUX_SEL_KR_IN_MASK, 0x00063910); + al_reg_write32(&adapter->mac_regs_base->gen.sd_fifo_ctrl, 0x000004f0); + al_reg_write32(&adapter->mac_regs_base->gen.sd_fifo_ctrl, 0x00000401); + + // FAST AN -- Testing only +#ifdef AL_HAL_ETH_FAST_AN + al_reg_write32(&adapter->mac_regs_base->sgmii.reg_addr, 0x00000012); + al_reg_write32(&adapter->mac_regs_base->sgmii.reg_data, 0x00000040); + al_reg_write32(&adapter->mac_regs_base->sgmii.reg_addr, 0x00000013); + al_reg_write32(&adapter->mac_regs_base->sgmii.reg_data, 0x00000000); +#endif + + /* Setting PCS i/f mode to SGMII (instead of default 1000Base-X) */ + al_reg_write32(&adapter->mac_regs_base->sgmii.reg_addr, 0x00000014); + al_reg_write32(&adapter->mac_regs_base->sgmii.reg_data, 0x0000000b); + /* setting dev_ability to have speed of 1000Mb, [11:10] = 2'b10 */ + al_reg_write32(&adapter->mac_regs_base->sgmii.reg_addr, 0x00000004); + al_reg_write32(&adapter->mac_regs_base->sgmii.reg_data, 0x000009A0); + al_reg_write32_masked(&adapter->mac_regs_base->gen.led_cfg, + ETH_MAC_GEN_LED_CFG_SEL_MASK, + ETH_MAC_GEN_LED_CFG_SEL_DEFAULT_REG); + break; + + case AL_ETH_MAC_MODE_SGMII_2_5G: + if (adapter->rev_id > AL_ETH_REV_ID_2) { + /* configure and enable the ASYNC FIFO between the MACs and the EC */ + /* TX min packet size */ + al_reg_write32(&adapter->mac_regs_base->gen_v3.tx_afifo_cfg_1, 0x00000037); + /* TX max packet size */ + al_reg_write32(&adapter->mac_regs_base->gen_v3.tx_afifo_cfg_2, 0x00002800); + /* TX input bus configuration */ + al_reg_write32(&adapter->mac_regs_base->gen_v3.tx_afifo_cfg_3, 0x00000080); + /* TX output bus configuration */ + al_reg_write32(&adapter->mac_regs_base->gen_v3.tx_afifo_cfg_4, 0x00030020); + /* TX Valid/ready configuration */ + al_reg_write32(&adapter->mac_regs_base->gen_v3.tx_afifo_cfg_5, 0x00000023); + /* RX input bus configuration */ + al_reg_write32(&adapter->mac_regs_base->gen_v3.rx_afifo_cfg_3, 0x00030020); + /* RX output bus configuration */ + al_reg_write32(&adapter->mac_regs_base->gen_v3.rx_afifo_cfg_4, 0x00000080); + /* RX Valid/ready configuration */ + al_reg_write32(&adapter->mac_regs_base->gen_v3.rx_afifo_cfg_5, 0x00000012); + /* V3 additional MAC selection */ + al_reg_write32(&adapter->mac_regs_base->gen_v3.mac_sel, 0x00000000); + al_reg_write32(&adapter->mac_regs_base->gen_v3.mac_10g_ll_cfg, 0x00000000); + al_reg_write32(&adapter->mac_regs_base->gen_v3.mac_10g_ll_ctrl, 0x00000000); + al_reg_write32(&adapter->mac_regs_base->gen_v3.pcs_10g_ll_cfg, 0x00000050); + /* ASYNC FIFO ENABLE */ + al_reg_write32(&adapter->mac_regs_base->gen_v3.afifo_ctrl, 0x00003333); + } + + /* MAC register file */ + al_reg_write32(&adapter->mac_regs_base->mac_10g.cmd_cfg, 0x01022830); + /* XAUI MAC control register */ + al_reg_write32(&adapter->mac_regs_base->gen.cfg, 0x00000001); + al_reg_write32(&adapter->mac_regs_base->mac_10g.if_mode, 0x00000028); + al_reg_write32(&adapter->mac_regs_base->mac_10g.control, 0x00001140); + /* RXAUI MAC control register */ + al_reg_write32(&adapter->mac_regs_base->gen.xgmii_dfifo_32_64, 0x00000401); +/* al_reg_write32(&adapter->mac_regs_base->gen.mac_res_1_out, 0x00000401); */ + al_reg_write32(&adapter->mac_regs_base->gen.xgmii_dfifo_64_32, 0x00000401); +/* al_reg_write32(&adapter->mac_regs_base->gen.mac_res_1_in, 0x00000401); */ + al_reg_write32_masked(&adapter->mac_regs_base->gen.mux_sel, + ~ETH_MAC_GEN_MUX_SEL_KR_IN_MASK, 0x00063910); + al_reg_write32(&adapter->mac_regs_base->gen.clk_cfg, 0x40003210); + al_reg_write32(&adapter->mac_regs_base->gen.sd_fifo_ctrl, 0x000004f0); + al_reg_write32(&adapter->mac_regs_base->gen.sd_fifo_ctrl, 0x00000401); + + al_reg_write32_masked(&adapter->mac_regs_base->gen.led_cfg, + ETH_MAC_GEN_LED_CFG_SEL_MASK, + ETH_MAC_GEN_LED_CFG_SEL_DEFAULT_REG); + break; + + case AL_ETH_MAC_MODE_10GbE_Serial: + if (adapter->rev_id > AL_ETH_REV_ID_2) { + /* configure and enable the ASYNC FIFO between the MACs and the EC */ + /* TX min packet size */ + al_reg_write32(&adapter->mac_regs_base->gen_v3.tx_afifo_cfg_1, 0x00000037); + /* TX max packet size */ + al_reg_write32(&adapter->mac_regs_base->gen_v3.tx_afifo_cfg_2, 0x00002800); + /* TX input bus configuration */ + al_reg_write32(&adapter->mac_regs_base->gen_v3.tx_afifo_cfg_3, 0x00000080); + /* TX output bus configuration */ + al_reg_write32(&adapter->mac_regs_base->gen_v3.tx_afifo_cfg_4, 0x00030020); + /* TX Valid/ready configuration */ + al_reg_write32(&adapter->mac_regs_base->gen_v3.tx_afifo_cfg_5, 0x00000023); + /* RX min packet size */ + /* al_reg_write32(&adapter->mac_regs_base->gen_v3.rx_afifo_cfg_1, 0x00000040); */ + /* RX max packet size */ + /* al_reg_write32(&adapter->mac_regs_base->gen_v3.rx_afifo_cfg_2, 0x00002800); */ + /* RX input bus configuration */ + al_reg_write32(&adapter->mac_regs_base->gen_v3.rx_afifo_cfg_3, 0x00030020); + /* RX output bus configuration */ + al_reg_write32(&adapter->mac_regs_base->gen_v3.rx_afifo_cfg_4, 0x00000080); + /* RX Valid/ready configuration */ + al_reg_write32(&adapter->mac_regs_base->gen_v3.rx_afifo_cfg_5, 0x00000012); + /* V3 additional MAC selection */ + al_reg_write32(&adapter->mac_regs_base->gen_v3.mac_sel, 0x00000000); + al_reg_write32(&adapter->mac_regs_base->gen_v3.mac_10g_ll_cfg, 0x00000000); + al_reg_write32(&adapter->mac_regs_base->gen_v3.mac_10g_ll_ctrl, 0x00000000); + al_reg_write32(&adapter->mac_regs_base->gen_v3.pcs_10g_ll_cfg, 0x00000050); + /* ASYNC FIFO ENABLE */ + al_reg_write32(&adapter->mac_regs_base->gen_v3.afifo_ctrl, 0x00003333); + } + + /* MAC register file */ + al_reg_write32(&adapter->mac_regs_base->mac_10g.cmd_cfg, 0x01022810); + /* XAUI MAC control register */ + al_reg_write32(&adapter->mac_regs_base->gen.cfg, 0x00000005); + /* RXAUI MAC control register */ + al_reg_write32(&adapter->mac_regs_base->gen.rxaui_cfg, 0x00000007); + al_reg_write32(&adapter->mac_regs_base->gen.sd_cfg, 0x000001F1); + al_reg_write32(&adapter->mac_regs_base->gen.xgmii_dfifo_32_64, 0x00000401); +/* al_reg_write32(&adapter->mac_regs_base->gen.mac_res_1_out, 0x00000401); */ + al_reg_write32(&adapter->mac_regs_base->gen.xgmii_dfifo_64_32, 0x00000401); +/* al_reg_write32(&adapter->mac_regs_base->gen.mac_res_1_in, 0x00000401); */ + al_reg_write32_masked(&adapter->mac_regs_base->gen.mux_sel, + ~ETH_MAC_GEN_MUX_SEL_KR_IN_MASK, 0x00073910); + al_reg_write32(&adapter->mac_regs_base->gen.clk_cfg, 0x10003210); + al_reg_write32(&adapter->mac_regs_base->gen.sd_fifo_ctrl, 0x000004f0); + al_reg_write32(&adapter->mac_regs_base->gen.sd_fifo_ctrl, 0x00000401); + + al_reg_write32_masked(&adapter->mac_regs_base->gen.led_cfg, + ETH_MAC_GEN_LED_CFG_SEL_MASK, + ETH_MAC_GEN_LED_CFG_SEL_DEFAULT_REG); + break; + + case AL_ETH_MAC_MODE_KR_LL_25G: + /* select 25G SERDES lane 0 and lane 1 */ + al_reg_write32(&adapter->mac_regs_base->gen_v3.ext_serdes_ctrl, 0x03821101); + if (adapter->rev_id > AL_ETH_REV_ID_2) { + /* configure and enable the ASYNC FIFO between the MACs and the EC */ + /* TX min packet size */ + al_reg_write32(&adapter->mac_regs_base->gen_v3.tx_afifo_cfg_1, 0x00000037); + /* TX max packet size */ + al_reg_write32(&adapter->mac_regs_base->gen_v3.tx_afifo_cfg_2, 0x00002800); + /* TX input bus configuration */ + al_reg_write32(&adapter->mac_regs_base->gen_v3.tx_afifo_cfg_3, 0x00000080); + /* TX output bus configuration */ + al_reg_write32(&adapter->mac_regs_base->gen_v3.tx_afifo_cfg_4, 0x00030020); + /* TX Valid/ready configuration */ + al_reg_write32(&adapter->mac_regs_base->gen_v3.tx_afifo_cfg_5, 0x00000023); + /* RX min packet size */ + /* al_reg_write32(&adapter->mac_regs_base->gen_v3.rx_afifo_cfg_1, 0x00000040); */ + /* RX max packet size */ + /* al_reg_write32(&adapter->mac_regs_base->gen_v3.rx_afifo_cfg_2, 0x00002800); */ + /* RX input bus configuration */ + al_reg_write32(&adapter->mac_regs_base->gen_v3.rx_afifo_cfg_3, 0x00030020); + /* RX output bus configuration */ + al_reg_write32(&adapter->mac_regs_base->gen_v3.rx_afifo_cfg_4, 0x00000080); + /* RX Valid/ready configuration */ + al_reg_write32(&adapter->mac_regs_base->gen_v3.rx_afifo_cfg_5, 0x00000012); + /* V3 additional MAC selection */ + al_reg_write32(&adapter->mac_regs_base->gen_v3.mac_sel, 0x00000000); + al_reg_write32(&adapter->mac_regs_base->gen_v3.mac_10g_ll_cfg, 0x00000000); + al_reg_write32(&adapter->mac_regs_base->gen_v3.mac_10g_ll_ctrl, 0x00000000); + al_reg_write32(&adapter->mac_regs_base->gen_v3.pcs_10g_ll_cfg, 0x000000a0); + /* ASYNC FIFO ENABLE */ + al_reg_write32(&adapter->mac_regs_base->gen_v3.afifo_ctrl, 0x00003333); + } + + /* MAC register file */ + al_reg_write32(&adapter->mac_regs_base->mac_10g.cmd_cfg, 0x01022810); + /* XAUI MAC control register */ + al_reg_write32(&adapter->mac_regs_base->gen.cfg, 0x00000005); + /* RXAUI MAC control register */ + al_reg_write32(&adapter->mac_regs_base->gen.rxaui_cfg, 0x00000007); + al_reg_write32(&adapter->mac_regs_base->gen.sd_cfg, 0x000001F1); + al_reg_write32(&adapter->mac_regs_base->gen.xgmii_dfifo_32_64, 0x00000401); +/* al_reg_write32(&adapter->mac_regs_base->gen.mac_res_1_out, 0x00000401); */ + al_reg_write32(&adapter->mac_regs_base->gen.xgmii_dfifo_64_32, 0x00000401); +/* al_reg_write32(&adapter->mac_regs_base->gen.mac_res_1_in, 0x00000401); */ + al_reg_write32_masked(&adapter->mac_regs_base->gen.mux_sel, + ~ETH_MAC_GEN_MUX_SEL_KR_IN_MASK, 0x00073910); + al_reg_write32(&adapter->mac_regs_base->gen.clk_cfg, 0x10003210); + al_reg_write32(&adapter->mac_regs_base->gen.sd_fifo_ctrl, 0x000004f0); + al_reg_write32(&adapter->mac_regs_base->gen.sd_fifo_ctrl, 0x00000401); + + al_reg_write32_masked(&adapter->mac_regs_base->gen.led_cfg, + ETH_MAC_GEN_LED_CFG_SEL_MASK, + ETH_MAC_GEN_LED_CFG_SEL_DEFAULT_REG); + break; + + case AL_ETH_MAC_MODE_10G_SGMII: + /* MAC register file */ + al_reg_write32(&adapter->mac_regs_base->mac_10g.cmd_cfg, 0x01022810); + + /* XAUI MAC control register */ + al_reg_write32(&adapter->mac_regs_base->gen.cfg, 0x00000001); + + al_reg_write32(&adapter->mac_regs_base->mac_10g.if_mode, 0x0000002b); + al_reg_write32(&adapter->mac_regs_base->mac_10g.control, 0x00009140); + // FAST AN -- Testing only +#ifdef AL_HAL_ETH_FAST_AN + al_reg_write32(&adapter->mac_regs_base->mac_10g.link_timer_lo, 0x00000040); + al_reg_write32(&adapter->mac_regs_base->mac_10g.link_timer_hi, 0x00000000); +#endif + + /* RXAUI MAC control register */ + al_reg_write32(&adapter->mac_regs_base->gen.rxaui_cfg, 0x00000007); + al_reg_write32(&adapter->mac_regs_base->gen.xgmii_dfifo_32_64, 0x00000401); +/* al_reg_write32(&adapter->mac_regs_base->gen.mac_res_1_out, 0x00000401); */ + al_reg_write32(&adapter->mac_regs_base->gen.xgmii_dfifo_64_32, 0x00000401); +/* al_reg_write32(&adapter->mac_regs_base->gen.mac_res_1_in, 0x00000401); */ + al_reg_write32_masked(&adapter->mac_regs_base->gen.mux_sel, + ~ETH_MAC_GEN_MUX_SEL_KR_IN_MASK, 0x00063910); + al_reg_write32(&adapter->mac_regs_base->gen.clk_cfg, 0x40003210); + al_reg_write32(&adapter->mac_regs_base->gen.sd_fifo_ctrl, 0x00000401); + + al_reg_write32_masked(&adapter->mac_regs_base->gen.led_cfg, + ETH_MAC_GEN_LED_CFG_SEL_MASK, + ETH_MAC_GEN_LED_CFG_SEL_DEFAULT_REG); + break; + + case AL_ETH_MAC_MODE_XLG_LL_40G: + /* configure and enable the ASYNC FIFO between the MACs and the EC */ + /* TX min packet size */ + al_reg_write32(&adapter->mac_regs_base->gen_v3.tx_afifo_cfg_1, 0x00000037); + /* TX max packet size */ + al_reg_write32(&adapter->mac_regs_base->gen_v3.tx_afifo_cfg_2, 0x00002800); + /* TX input bus configuration */ + al_reg_write32(&adapter->mac_regs_base->gen_v3.tx_afifo_cfg_3, 0x00000080); + /* TX output bus configuration */ + al_reg_write32(&adapter->mac_regs_base->gen_v3.tx_afifo_cfg_4, 0x00010040); + /* TX Valid/ready configuration */ + al_reg_write32(&adapter->mac_regs_base->gen_v3.tx_afifo_cfg_5, 0x00000023); + /* RX min packet size */ + /* al_reg_write32(&adapter->mac_regs_base->gen_v3.rx_afifo_cfg_1, 0x00000040); */ + /* RX max packet size */ + /* al_reg_write32(&adapter->mac_regs_base->gen_v3.rx_afifo_cfg_2, 0x00002800); */ + /* RX input bus configuration */ + al_reg_write32(&adapter->mac_regs_base->gen_v3.rx_afifo_cfg_3, 0x00010040); + /* RX output bus configuration */ + al_reg_write32(&adapter->mac_regs_base->gen_v3.rx_afifo_cfg_4, 0x00000080); + /* RX Valid/ready configuration */ + al_reg_write32(&adapter->mac_regs_base->gen_v3.rx_afifo_cfg_5, 0x00000112); + /* V3 additional MAC selection */ + al_reg_write32(&adapter->mac_regs_base->gen_v3.mac_sel, 0x00000010); + al_reg_write32(&adapter->mac_regs_base->gen_v3.mac_10g_ll_cfg, 0x00000000); + al_reg_write32(&adapter->mac_regs_base->gen_v3.mac_10g_ll_ctrl, 0x00000000); + al_reg_write32(&adapter->mac_regs_base->gen_v3.pcs_10g_ll_cfg, 0x00000000); + /* ASYNC FIFO ENABLE */ + al_reg_write32(&adapter->mac_regs_base->gen_v3.afifo_ctrl, 0x00003333); + + /* cmd_cfg */ + al_reg_write32(&adapter->mac_regs_base->gen_v3.mac_40g_ll_addr, 0x00000008); + al_reg_write32(&adapter->mac_regs_base->gen_v3.mac_40g_ll_data, 0x01022810); + /* speed_ability //Read-Only */ + /* al_reg_write32(&adapter->mac_regs_base->gen_v3.pcs_40g_ll_addr, 0x00000008); */ + /* 40G capable */ + /* al_reg_write32(&adapter->mac_regs_base->gen_v3.pcs_40g_ll_data, 0x00000002); */ + +#ifdef AL_HAL_ETH_FAST_AN + al_eth_40g_pcs_reg_write(adapter, 0x00010004, 1023); + al_eth_40g_pcs_reg_write(adapter, 0x00000000, 0xA04c); + al_eth_40g_pcs_reg_write(adapter, 0x00000000, 0x204c); + +#endif + + /* XAUI MAC control register */ + al_reg_write32_masked(&adapter->mac_regs_base->gen.mux_sel, + ~ETH_MAC_GEN_MUX_SEL_KR_IN_MASK, 0x06883910); + al_reg_write32(&adapter->mac_regs_base->gen.sd_fifo_ctrl, 0x0000040f); + + /* MAC register file */ +/* al_reg_write32(&adapter->mac_regs_base->mac_10g.cmd_cfg, 0x01022810); */ + /* XAUI MAC control register */ + al_reg_write32(&adapter->mac_regs_base->gen.cfg, 0x00000005); + /* RXAUI MAC control register */ + al_reg_write32(&adapter->mac_regs_base->gen.rxaui_cfg, 0x00000007); + al_reg_write32(&adapter->mac_regs_base->gen.sd_cfg, 0x000001F1); + al_reg_write32(&adapter->mac_regs_base->gen.xgmii_dfifo_32_64, 0x00000401); +/* al_reg_write32(&adapter->mac_regs_base->gen.mac_res_1_out, 0x00000401); */ + al_reg_write32(&adapter->mac_regs_base->gen.xgmii_dfifo_64_32, 0x00000401); +/* al_reg_write32(&adapter->mac_regs_base->gen.mac_res_1_in, 0x00000401); */ +/* al_reg_write32_masked(&adapter->mac_regs_base->gen.mux_sel, ~ETH_MAC_GEN_MUX_SEL_KR_IN_MASK, 0x00073910); *//* XLG_LL_40G change */ + al_reg_write32(&adapter->mac_regs_base->gen.clk_cfg, 0x10003210); +/* al_reg_write32(&adapter->mac_regs_base->gen.sd_fifo_ctrl, 0x000004f0); *//* XLG_LL_40G change */ +/* al_reg_write32(&adapter->mac_regs_base->gen.sd_fifo_ctrl, 0x00000401); *//* XLG_LL_40G change */ + + al_reg_write32_masked(&adapter->mac_regs_base->gen.led_cfg, + ETH_MAC_GEN_LED_CFG_SEL_MASK, + ETH_MAC_GEN_LED_CFG_SEL_DEFAULT_REG); + break; + + case AL_ETH_MAC_MODE_XLG_LL_50G: + + /* configure and enable the ASYNC FIFO between the MACs and the EC */ + /* TX min packet size */ + al_reg_write32(&adapter->mac_regs_base->gen_v3.tx_afifo_cfg_1, 0x00000037); + /* TX max packet size */ + al_reg_write32(&adapter->mac_regs_base->gen_v3.tx_afifo_cfg_2, 0x00002800); + /* TX input bus configuration */ + al_reg_write32(&adapter->mac_regs_base->gen_v3.tx_afifo_cfg_3, 0x00000080); + /* TX output bus configuration */ + al_reg_write32(&adapter->mac_regs_base->gen_v3.tx_afifo_cfg_4, 0x00010040); + /* TX Valid/ready configuration */ + al_reg_write32(&adapter->mac_regs_base->gen_v3.tx_afifo_cfg_5, 0x00000023); + /* RX min packet size */ + /* al_reg_write32(&adapter->mac_regs_base->gen_v3.rx_afifo_cfg_1, 0x00000040); */ + /* RX max packet size */ + /* al_reg_write32(&adapter->mac_regs_base->gen_v3.rx_afifo_cfg_2, 0x00002800); */ + /* RX input bus configuration */ + al_reg_write32(&adapter->mac_regs_base->gen_v3.rx_afifo_cfg_3, 0x00010040); + /* RX output bus configuration */ + al_reg_write32(&adapter->mac_regs_base->gen_v3.rx_afifo_cfg_4, 0x00000080); + /* RX Valid/ready configuration */ + al_reg_write32(&adapter->mac_regs_base->gen_v3.rx_afifo_cfg_5, 0x00000112); + /* V3 additional MAC selection */ + al_reg_write32(&adapter->mac_regs_base->gen_v3.mac_sel, 0x00000010); + al_reg_write32(&adapter->mac_regs_base->gen_v3.mac_10g_ll_cfg, 0x00000000); + al_reg_write32(&adapter->mac_regs_base->gen_v3.mac_10g_ll_ctrl, 0x00000000); + al_reg_write32(&adapter->mac_regs_base->gen_v3.pcs_10g_ll_cfg, 0x00000000); + /* ASYNC FIFO ENABLE */ + al_reg_write32(&adapter->mac_regs_base->gen_v3.afifo_ctrl, 0x00003333); + + /* cmd_cfg */ + al_reg_write32(&adapter->mac_regs_base->gen_v3.mac_40g_ll_addr, 0x00000008); + al_reg_write32(&adapter->mac_regs_base->gen_v3.mac_40g_ll_data, 0x01022810); + /* speed_ability //Read-Only */ + /* al_reg_write32(&adapter->mac_regs_base->gen_v3.pcs_40g_ll_addr, 0x00000008); */ + /* 40G capable */ + /* al_reg_write32(&adapter->mac_regs_base->gen_v3.pcs_40g_ll_data, 0x00000002); */ + + /* select the 25G serdes for lanes 0/1 */ + al_reg_write32(&adapter->mac_regs_base->gen_v3.ext_serdes_ctrl, 0x0382110F); + /* configure the PCS to work with 2 lanes */ + /* configure which two of the 4 PCS Lanes (VL) are combined to one RXLAUI lane */ + /* use VL 0-2 for RXLAUI lane 0, use VL 1-3 for RXLAUI lane 1 */ + al_eth_40g_pcs_reg_write(adapter, 0x00010008, 0x0d81); + /* configure the PCS to work 32 bit interface */ + al_reg_write32(&adapter->mac_regs_base->gen_v3.pcs_40g_ll_cfg, 0x00440000); + + +#ifdef AL_HAL_ETH_FAST_AN + al_eth_40g_pcs_reg_write(adapter, 0x00010004, 1023); + al_eth_40g_pcs_reg_write(adapter, 0x00000000, 0xA04c); + al_eth_40g_pcs_reg_write(adapter, 0x00000000, 0x204c); +#endif + + /* XAUI MAC control register */ + al_reg_write32_masked(&adapter->mac_regs_base->gen.mux_sel, ~ETH_MAC_GEN_MUX_SEL_KR_IN_MASK, 0x06883910); + al_reg_write32(&adapter->mac_regs_base->gen.sd_fifo_ctrl, 0x0000040f); + + /* MAC register file */ +/* al_reg_write32(&adapter->mac_regs_base->mac_10g.cmd_cfg, 0x01022810); */ + /* XAUI MAC control register */ + al_reg_write32(&adapter->mac_regs_base->gen.cfg, 0x00000005); + /* RXAUI MAC control register */ + al_reg_write32(&adapter->mac_regs_base->gen.rxaui_cfg, 0x00000007); + al_reg_write32(&adapter->mac_regs_base->gen.sd_cfg, 0x000001F1); + al_reg_write32(&adapter->mac_regs_base->gen.xgmii_dfifo_32_64, 0x00000401); +/* al_reg_write32(&adapter->mac_regs_base->gen.mac_res_1_out, 0x00000401); */ + al_reg_write32(&adapter->mac_regs_base->gen.xgmii_dfifo_64_32, 0x00000401); +/* al_reg_write32(&adapter->mac_regs_base->gen.mac_res_1_in, 0x00000401); */ +/* al_reg_write32_masked(&adapter->mac_regs_base->gen.mux_sel, ~ETH_MAC_GEN_MUX_SEL_KR_IN_MASK, 0x00073910); *//* XLG_LL_40G change */ + al_reg_write32(&adapter->mac_regs_base->gen.clk_cfg, 0x10003210); +/* al_reg_write32(&adapter->mac_regs_base->gen.sd_fifo_ctrl, 0x000004f0); *//* XLG_LL_40G change */ +/* al_reg_write32(&adapter->mac_regs_base->gen.sd_fifo_ctrl, 0x00000401); *//* XLG_LL_40G change */ + + al_reg_write32_masked(&adapter->mac_regs_base->gen.led_cfg, + ETH_MAC_GEN_LED_CFG_SEL_MASK, + ETH_MAC_GEN_LED_CFG_SEL_DEFAULT_REG); + break; + + + default: + al_err("Eth: unsupported MAC mode %d", mode); + return -EPERM; + } + adapter->mac_mode = mode; + al_info("configured MAC to %s mode:\n", al_eth_mac_mode_str(mode)); + + return 0; +} + +/* start the mac */ +int al_eth_mac_start(struct al_hal_eth_adapter *adapter) +{ + if (AL_ETH_IS_1G_MAC(adapter->mac_mode)) { + /* 1G MAC control register */ + al_reg_write32_masked(&adapter->mac_regs_base->mac_1g.cmd_cfg, 0x3, 0x3); + } else if (AL_ETH_IS_10G_MAC(adapter->mac_mode) || AL_ETH_IS_25G_MAC(adapter->mac_mode)) { + /* 10G MAC control register */ + al_reg_write32_masked(&adapter->mac_regs_base->mac_10g.cmd_cfg, 0x3, 0x3); + } else { + uint32_t cmd_cfg; + + cmd_cfg = al_eth_40g_mac_reg_read(adapter, ETH_MAC_GEN_V3_MAC_40G_COMMAND_CONFIG_ADDR); + + cmd_cfg |= (ETH_MAC_GEN_V3_MAC_40G_COMMAND_CONFIG_TX_ENA | + ETH_MAC_GEN_V3_MAC_40G_COMMAND_CONFIG_RX_ENA); + + al_eth_40g_mac_reg_write(adapter, ETH_MAC_GEN_V3_MAC_40G_COMMAND_CONFIG_ADDR, cmd_cfg); + } + + return 0; +} + +/* stop the mac */ +int al_eth_mac_stop(struct al_hal_eth_adapter *adapter) +{ + if (AL_ETH_IS_1G_MAC(adapter->mac_mode)) + /* 1G MAC control register */ + al_reg_write32(&adapter->mac_regs_base->mac_1g.cmd_cfg, 0x0); + else if (AL_ETH_IS_10G_MAC(adapter->mac_mode) || AL_ETH_IS_25G_MAC(adapter->mac_mode)) + /* 10G MAC control register */ + al_reg_write32(&adapter->mac_regs_base->mac_10g.cmd_cfg, 0x0); + else + al_eth_40g_mac_reg_write(adapter, ETH_MAC_GEN_V3_MAC_40G_COMMAND_CONFIG_ADDR, 0); + + return 0; +} + +int al_eth_capabilities_get(struct al_hal_eth_adapter *adapter, struct al_eth_capabilities *caps) +{ + al_assert(caps); + + caps->speed_10_HD = AL_FALSE; + caps->speed_10_FD = AL_FALSE; + caps->speed_100_HD = AL_FALSE; + caps->speed_100_FD = AL_FALSE; + caps->speed_1000_HD = AL_FALSE; + caps->speed_1000_FD = AL_FALSE; + caps->speed_10000_HD = AL_FALSE; + caps->speed_10000_FD = AL_FALSE; + caps->pfc = AL_FALSE; + caps->eee = AL_FALSE; + + switch (adapter->mac_mode) { + case AL_ETH_MAC_MODE_RGMII: + case AL_ETH_MAC_MODE_SGMII: + caps->speed_10_HD = AL_TRUE; + caps->speed_10_FD = AL_TRUE; + caps->speed_100_HD = AL_TRUE; + caps->speed_100_FD = AL_TRUE; + caps->speed_1000_FD = AL_TRUE; + caps->eee = AL_TRUE; + break; + case AL_ETH_MAC_MODE_10GbE_Serial: + caps->speed_10000_FD = AL_TRUE; + caps->pfc = AL_TRUE; + break; + default: + al_err("Eth: unsupported MAC mode %d", adapter->mac_mode); + return -EPERM; + } + return 0; +} + +/* update link speed and duplex mode */ +int al_eth_mac_link_config(struct al_hal_eth_adapter *adapter, + al_bool force_1000_base_x, + al_bool an_enable, + uint32_t speed, + al_bool full_duplex) +{ + uint32_t mac_ctrl; + uint32_t sgmii_ctrl = 0; + uint32_t sgmii_if_mode = 0; + uint32_t rgmii_ctrl = 0; + + if (!AL_ETH_IS_1G_MAC(adapter->mac_mode)) { + al_err("eth [%s]: this function not supported in this mac mode.\n", + adapter->name); + return -EINVAL; + } + + if ((adapter->mac_mode != AL_ETH_MAC_MODE_RGMII) && (an_enable)) { + /* + * an_enable is not relevant to RGMII mode. + * in AN mode speed and duplex aren't relevant. + */ + al_info("eth [%s]: set auto negotiation to enable\n", adapter->name); + } else { + al_info("eth [%s]: set link speed to %dMbps. %s duplex.\n", adapter->name, + speed, full_duplex == AL_TRUE ? "full" : "half"); + + if ((speed != 10) && (speed != 100) && (speed != 1000)) { + al_err("eth [%s]: bad speed parameter (%d).\n", + adapter->name, speed); + return -EINVAL; + } + if ((speed == 1000) && (full_duplex == AL_FALSE)) { + al_err("eth [%s]: half duplex in 1Gbps is not supported.\n", + adapter->name); + return -EINVAL; + } + } + + mac_ctrl = al_reg_read32(&adapter->mac_regs_base->mac_1g.cmd_cfg); + + if (adapter->mac_mode == AL_ETH_MAC_MODE_SGMII) { + al_reg_write32(&adapter->mac_regs_base->sgmii.reg_addr, + ETH_MAC_SGMII_REG_ADDR_CTRL_REG); + sgmii_ctrl = al_reg_read32(&adapter->mac_regs_base->sgmii.reg_data); + /* + * in case bit 0 is off in sgmii_if_mode register all the other + * bits are ignored. + */ + if (force_1000_base_x == AL_FALSE) + sgmii_if_mode = ETH_MAC_SGMII_REG_DATA_IF_MODE_SGMII_EN; + + if (an_enable == AL_TRUE) { + sgmii_if_mode |= ETH_MAC_SGMII_REG_DATA_IF_MODE_SGMII_AN; + sgmii_ctrl |= ETH_MAC_SGMII_REG_DATA_CTRL_AN_ENABLE; + } else { + sgmii_ctrl &= ~(ETH_MAC_SGMII_REG_DATA_CTRL_AN_ENABLE); + } + } + + if (adapter->mac_mode == AL_ETH_MAC_MODE_RGMII) { + /* + * Use the speed provided by the MAC instead of the PHY + */ + rgmii_ctrl = al_reg_read32(&adapter->mac_regs_base->gen.rgmii_cfg); + + AL_REG_MASK_CLEAR(rgmii_ctrl, ETH_MAC_GEN_RGMII_CFG_ENA_AUTO); + AL_REG_MASK_CLEAR(rgmii_ctrl, ETH_MAC_GEN_RGMII_CFG_SET_1000_SEL); + AL_REG_MASK_CLEAR(rgmii_ctrl, ETH_MAC_GEN_RGMII_CFG_SET_10_SEL); + + al_reg_write32(&adapter->mac_regs_base->gen.rgmii_cfg, rgmii_ctrl); + } + + if (full_duplex == AL_TRUE) { + AL_REG_MASK_CLEAR(mac_ctrl, AL_ETH_1G_MAC_CTRL_HD_EN); + } else { + AL_REG_MASK_SET(mac_ctrl, AL_ETH_1G_MAC_CTRL_HD_EN); + sgmii_if_mode |= ETH_MAC_SGMII_REG_DATA_IF_MODE_SGMII_DUPLEX; + } + + if (speed == 1000) { + AL_REG_MASK_SET(mac_ctrl, AL_ETH_1G_MAC_CTRL_1G_SPD); + sgmii_if_mode |= ETH_MAC_SGMII_REG_DATA_IF_MODE_SGMII_SPEED_1000; + } else { + AL_REG_MASK_CLEAR(mac_ctrl, AL_ETH_1G_MAC_CTRL_1G_SPD); + if (speed == 10) { + AL_REG_MASK_SET(mac_ctrl, AL_ETH_1G_MAC_CTRL_10M_SPD); + } else { + sgmii_if_mode |= ETH_MAC_SGMII_REG_DATA_IF_MODE_SGMII_SPEED_100; + AL_REG_MASK_CLEAR(mac_ctrl, AL_ETH_1G_MAC_CTRL_10M_SPD); + } + } + + if (adapter->mac_mode == AL_ETH_MAC_MODE_SGMII) { + al_reg_write32(&adapter->mac_regs_base->sgmii.reg_addr, + ETH_MAC_SGMII_REG_ADDR_IF_MODE_REG); + al_reg_write32(&adapter->mac_regs_base->sgmii.reg_data, + sgmii_if_mode); + + al_reg_write32(&adapter->mac_regs_base->sgmii.reg_addr, + ETH_MAC_SGMII_REG_ADDR_CTRL_REG); + al_reg_write32(&adapter->mac_regs_base->sgmii.reg_data, + sgmii_ctrl); + } + + al_reg_write32(&adapter->mac_regs_base->mac_1g.cmd_cfg, mac_ctrl); + + return 0; +} + +int al_eth_mac_loopback_config(struct al_hal_eth_adapter *adapter, int enable) +{ + const char *state = (enable) ? "enable" : "disable"; + + al_dbg("eth [%s]: loopback %s\n", adapter->name, state); + if (AL_ETH_IS_1G_MAC(adapter->mac_mode)) { + uint32_t reg; + reg = al_reg_read32(&adapter->mac_regs_base->mac_1g.cmd_cfg); + if (enable) + reg |= AL_BIT(15); + else + reg &= ~AL_BIT(15); + al_reg_write32(&adapter->mac_regs_base->mac_1g.cmd_cfg, reg); + } else if ((AL_ETH_IS_10G_MAC(adapter->mac_mode) || AL_ETH_IS_25G_MAC(adapter->mac_mode)) + && (adapter->rev_id == AL_ETH_REV_ID_3)) { + uint32_t reg; + al_reg_write16( + (uint16_t *)&adapter->mac_regs_base->kr.pcs_addr, ETH_MAC_KR_PCS_CONTROL_1_ADDR); + reg = al_reg_read16( + (uint16_t *)&adapter->mac_regs_base->kr.pcs_data); + if (enable) + reg |= AL_BIT(14); + else + reg &= ~AL_BIT(14); + al_reg_write16( + (uint16_t *)&adapter->mac_regs_base->kr.pcs_addr, ETH_MAC_KR_PCS_CONTROL_1_ADDR); + al_reg_write16( + (uint16_t *)&adapter->mac_regs_base->kr.pcs_data, reg); + } else if (adapter->mac_mode == AL_ETH_MAC_MODE_XLG_LL_40G || + (adapter->mac_mode == AL_ETH_MAC_MODE_XLG_LL_50G)) { + uint32_t reg; + reg = al_eth_40g_pcs_reg_read(adapter, ETH_MAC_GEN_V3_PCS_40G_CONTROL_STATUS_ADDR); + if (enable) + reg |= AL_BIT(14); + else + reg &= ~AL_BIT(14); + al_eth_40g_pcs_reg_write(adapter, ETH_MAC_GEN_V3_PCS_40G_CONTROL_STATUS_ADDR, reg); + } else { + al_err("Eth: mac loopback not supported in this mode %d", adapter->mac_mode); + return -EPERM; + } + return 0; +} + +/* MDIO */ +int al_eth_mdio_config( + struct al_hal_eth_adapter *adapter, + enum al_eth_mdio_type mdio_type, + al_bool shared_mdio_if, + enum al_eth_ref_clk_freq ref_clk_freq, + unsigned int mdio_clk_freq_khz) +{ + enum al_eth_mdio_if mdio_if = AL_ETH_MDIO_IF_10G_MAC; + const char *if_name = (mdio_if == AL_ETH_MDIO_IF_1G_MAC) ? "10/100/1G MAC" : "10G MAC"; + const char *type_name = (mdio_type == AL_ETH_MDIO_TYPE_CLAUSE_22) ? "Clause 22" : "Clause 45"; + const char *shared_name = (shared_mdio_if == AL_TRUE) ? "Yes" : "No"; + + unsigned int ref_clk_freq_khz; + uint32_t val; + + al_dbg("eth [%s]: mdio config: interface %s. type %s. shared: %s\n", adapter->name, if_name, type_name, shared_name); + adapter->shared_mdio_if = shared_mdio_if; + + val = al_reg_read32(&adapter->mac_regs_base->gen.cfg); + al_dbg("eth [%s]: mdio config: 10G mac \n", adapter->name); + + switch(mdio_if) + { + case AL_ETH_MDIO_IF_1G_MAC: + val &= ~AL_BIT(10); + break; + case AL_ETH_MDIO_IF_10G_MAC: + val |= AL_BIT(10); + break; + } + al_reg_write32(&adapter->mac_regs_base->gen.cfg, val); + adapter->mdio_if = mdio_if; + + + if (mdio_if == AL_ETH_MDIO_IF_10G_MAC) + { + val = al_reg_read32(&adapter->mac_regs_base->mac_10g.mdio_cfg_status); + switch(mdio_type) + { + case AL_ETH_MDIO_TYPE_CLAUSE_22: + val &= ~AL_BIT(6); + break; + case AL_ETH_MDIO_TYPE_CLAUSE_45: + val |= AL_BIT(6); + break; + } + + /* set clock div to get 'mdio_clk_freq_khz' */ + switch (ref_clk_freq) { + default: + al_err("eth [%s]: %s: invalid reference clock frequency" + " (%d)\n", + adapter->name, __func__, ref_clk_freq); + case AL_ETH_REF_FREQ_375_MHZ: + ref_clk_freq_khz = 375000; + break; + case AL_ETH_REF_FREQ_187_5_MHZ: + ref_clk_freq_khz = 187500; + break; + case AL_ETH_REF_FREQ_250_MHZ: + ref_clk_freq_khz = 250000; + break; + case AL_ETH_REF_FREQ_500_MHZ: + ref_clk_freq_khz = 500000; + break; + case AL_ETH_REF_FREQ_428_MHZ: + ref_clk_freq_khz = 428000; + break; + }; + + val &= ~(0x1FF << 7); + val |= (ref_clk_freq_khz / (2 * mdio_clk_freq_khz)) << 7; + AL_REG_FIELD_SET(val, ETH_10G_MAC_MDIO_CFG_HOLD_TIME_MASK, + ETH_10G_MAC_MDIO_CFG_HOLD_TIME_SHIFT, + ETH_10G_MAC_MDIO_CFG_HOLD_TIME_7_CLK); + al_reg_write32(&adapter->mac_regs_base->mac_10g.mdio_cfg_status, val); + }else{ + if(mdio_type != AL_ETH_MDIO_TYPE_CLAUSE_22) { + al_err("eth [%s] mdio type not supported for this interface\n", + adapter->name); + return -EINVAL; + } + } + adapter->mdio_type = mdio_type; + + return 0; +} + +static int al_eth_mdio_1g_mac_read(struct al_hal_eth_adapter *adapter, + uint32_t phy_addr __attribute__((__unused__)), + uint32_t reg, uint16_t *val) +{ + *val = al_reg_read32( + &adapter->mac_regs_base->mac_1g.phy_regs_base + reg); + return 0; +} + +static int al_eth_mdio_1g_mac_write(struct al_hal_eth_adapter *adapter, + uint32_t phy_addr __attribute__((__unused__)), + uint32_t reg, uint16_t val) +{ + al_reg_write32( + &adapter->mac_regs_base->mac_1g.phy_regs_base + reg, val); + return 0; +} + +static int al_eth_mdio_10g_mac_wait_busy(struct al_hal_eth_adapter *adapter) +{ + int count = 0; + uint32_t mdio_cfg_status; + + do { + mdio_cfg_status = al_reg_read32(&adapter->mac_regs_base->mac_10g.mdio_cfg_status); +/* + if (mdio_cfg_status & AL_BIT(1)){ //error + al_err(" %s mdio read failed on error. phy_addr 0x%x reg 0x%x\n", + udma_params.name, phy_addr, reg); + return -EIO; + }*/ + if (mdio_cfg_status & AL_BIT(0)){ + if (count > 0) + al_dbg("eth [%s] mdio: still busy!\n", adapter->name); + }else{ + return 0; + } + al_udelay(AL_ETH_MDIO_DELAY_PERIOD); + }while(count++ < AL_ETH_MDIO_DELAY_COUNT); + + return -ETIMEDOUT; +} + +static int al_eth_mdio_10g_mac_type22( + struct al_hal_eth_adapter *adapter, + int read, uint32_t phy_addr, uint32_t reg, uint16_t *val) +{ + int rc; + const char *op = (read == 1) ? "read":"write"; + uint32_t mdio_cfg_status; + uint16_t mdio_cmd; + + //wait if the HW is busy + rc = al_eth_mdio_10g_mac_wait_busy(adapter); + if (rc) { + al_err(" eth [%s] mdio %s failed. HW is busy\n", adapter->name, op); + return rc; + } + + mdio_cmd = (uint16_t)(0x1F & reg); + mdio_cmd |= (0x1F & phy_addr) << 5; + + if (read) + mdio_cmd |= AL_BIT(15); //READ command + + al_reg_write16(&adapter->mac_regs_base->mac_10g.mdio_cmd, + mdio_cmd); + if (!read) + al_reg_write16(&adapter->mac_regs_base->mac_10g.mdio_data, + *val); + + //wait for the busy to clear + rc = al_eth_mdio_10g_mac_wait_busy(adapter); + if (rc != 0) { + al_err(" %s mdio %s failed on timeout\n", adapter->name, op); + return -ETIMEDOUT; + } + + mdio_cfg_status = al_reg_read32(&adapter->mac_regs_base->mac_10g.mdio_cfg_status); + + if (mdio_cfg_status & AL_BIT(1)){ //error + al_err(" %s mdio %s failed on error. phy_addr 0x%x reg 0x%x\n", + adapter->name, op, phy_addr, reg); + return -EIO; + } + if (read) + *val = al_reg_read16( + (uint16_t *)&adapter->mac_regs_base->mac_10g.mdio_data); + return 0; +} + +static int al_eth_mdio_10g_mac_type45( + struct al_hal_eth_adapter *adapter, + int read, uint32_t port_addr, uint32_t device, uint32_t reg, uint16_t *val) +{ + int rc; + const char *op = (read == 1) ? "read":"write"; + uint32_t mdio_cfg_status; + uint16_t mdio_cmd; + + //wait if the HW is busy + rc = al_eth_mdio_10g_mac_wait_busy(adapter); + if (rc) { + al_err(" %s mdio %s failed. HW is busy\n", adapter->name, op); + return rc; + } + // set command register + mdio_cmd = (uint16_t)(0x1F & device); + mdio_cmd |= (0x1F & port_addr) << 5; + al_reg_write16(&adapter->mac_regs_base->mac_10g.mdio_cmd, + mdio_cmd); + + // send address frame + al_reg_write16(&adapter->mac_regs_base->mac_10g.mdio_regaddr, reg); + //wait for the busy to clear + rc = al_eth_mdio_10g_mac_wait_busy(adapter); + if (rc) { + al_err(" %s mdio %s (address frame) failed on timeout\n", adapter->name, op); + return rc; + } + + // if read, write again to the command register with READ bit set + if (read) { + mdio_cmd |= AL_BIT(15); //READ command + al_reg_write16( + (uint16_t *)&adapter->mac_regs_base->mac_10g.mdio_cmd, + mdio_cmd); + } else { + al_reg_write16( + (uint16_t *)&adapter->mac_regs_base->mac_10g.mdio_data, + *val); + } + //wait for the busy to clear + rc = al_eth_mdio_10g_mac_wait_busy(adapter); + if (rc) { + al_err(" %s mdio %s failed on timeout\n", adapter->name, op); + return rc; + } + + mdio_cfg_status = al_reg_read32(&adapter->mac_regs_base->mac_10g.mdio_cfg_status); + + if (mdio_cfg_status & AL_BIT(1)){ //error + al_err(" %s mdio %s failed on error. port 0x%x, device 0x%x reg 0x%x\n", + adapter->name, op, port_addr, device, reg); + return -EIO; + } + if (read) + *val = al_reg_read16( + (uint16_t *)&adapter->mac_regs_base->mac_10g.mdio_data); + return 0; +} + +/** + * acquire mdio interface ownership + * when mdio interface shared between multiple eth controllers, this function waits until the ownership granted for this controller. + * this function does nothing when the mdio interface is used only by this controller. + * + * @param adapter + * @return 0 on success, -ETIMEDOUT on timeout. + */ +static int al_eth_mdio_lock(struct al_hal_eth_adapter *adapter) +{ + int count = 0; + uint32_t mdio_ctrl_1; + + if (adapter->shared_mdio_if == AL_FALSE) + return 0; /* nothing to do when interface is not shared */ + + do { + mdio_ctrl_1 = al_reg_read32(&adapter->mac_regs_base->gen.mdio_ctrl_1); +/* + if (mdio_cfg_status & AL_BIT(1)){ //error + al_err(" %s mdio read failed on error. phy_addr 0x%x reg 0x%x\n", + udma_params.name, phy_addr, reg); + return -EIO; + }*/ + if (mdio_ctrl_1 & AL_BIT(0)){ + if (count > 0) + al_dbg("eth %s mdio interface still busy!\n", adapter->name); + }else{ + return 0; + } + al_udelay(AL_ETH_MDIO_DELAY_PERIOD); + }while(count++ < (AL_ETH_MDIO_DELAY_COUNT * 4)); + al_err(" %s mdio failed to take ownership. MDIO info reg: 0x%08x\n", + adapter->name, al_reg_read32(&adapter->mac_regs_base->gen.mdio_1)); + + return -ETIMEDOUT; +} + +/** + * free mdio interface ownership + * when mdio interface shared between multiple eth controllers, this function releases the ownership granted for this controller. + * this function does nothing when the mdio interface is used only by this controller. + * + * @param adapter + * @return 0. + */ +static int al_eth_mdio_free(struct al_hal_eth_adapter *adapter) +{ + if (adapter->shared_mdio_if == AL_FALSE) + return 0; /* nothing to do when interface is not shared */ + + al_reg_write32(&adapter->mac_regs_base->gen.mdio_ctrl_1, 0); + + /* + * Addressing RMN: 2917 + * + * RMN description: + * The HW spin-lock is stateless and doesn't maintain any scheduling + * policy. + * + * Software flow: + * After getting the lock wait 2 times the delay period in order to give + * the other port chance to take the lock and prevent starvation. + * This is not scalable to more than two ports. + */ + al_udelay(2 * AL_ETH_MDIO_DELAY_PERIOD); + + return 0; +} + +int al_eth_mdio_read(struct al_hal_eth_adapter *adapter, uint32_t phy_addr, uint32_t device, uint32_t reg, uint16_t *val) +{ + int rc; + rc = al_eth_mdio_lock(adapter); + + /*"interface ownership taken"*/ + if (rc) + return rc; + + if (adapter->mdio_if == AL_ETH_MDIO_IF_1G_MAC) + rc = al_eth_mdio_1g_mac_read(adapter, phy_addr, reg, val); + else + if (adapter->mdio_type == AL_ETH_MDIO_TYPE_CLAUSE_22) + rc = al_eth_mdio_10g_mac_type22(adapter, 1, phy_addr, reg, val); + else + rc = al_eth_mdio_10g_mac_type45(adapter, 1, phy_addr, device, reg, val); + + al_eth_mdio_free(adapter); + al_dbg("eth mdio read: phy_addr %x, device %x, reg %x val %x\n", phy_addr, device, reg, *val); + return rc; +} + +int al_eth_mdio_write(struct al_hal_eth_adapter *adapter, uint32_t phy_addr, uint32_t device, uint32_t reg, uint16_t val) +{ + int rc; + al_dbg("eth mdio write: phy_addr %x, device %x, reg %x, val %x\n", phy_addr, device, reg, val); + rc = al_eth_mdio_lock(adapter); + /* interface ownership taken */ + if (rc) + return rc; + + if (adapter->mdio_if == AL_ETH_MDIO_IF_1G_MAC) + rc = al_eth_mdio_1g_mac_write(adapter, phy_addr, reg, val); + else + if (adapter->mdio_type == AL_ETH_MDIO_TYPE_CLAUSE_22) + rc = al_eth_mdio_10g_mac_type22(adapter, 0, phy_addr, reg, &val); + else + rc = al_eth_mdio_10g_mac_type45(adapter, 0, phy_addr, device, reg, &val); + + al_eth_mdio_free(adapter); + return rc; +} + +static void al_dump_tx_desc(union al_udma_desc *tx_desc) +{ + uint32_t *ptr = (uint32_t *)tx_desc; + al_dbg("eth tx desc:\n"); + al_dbg("0x%08x\n", *(ptr++)); + al_dbg("0x%08x\n", *(ptr++)); + al_dbg("0x%08x\n", *(ptr++)); + al_dbg("0x%08x\n", *(ptr++)); +} + +static void +al_dump_tx_pkt(struct al_udma_q *tx_dma_q, struct al_eth_pkt *pkt) +{ + const char *tso = (pkt->flags & AL_ETH_TX_FLAGS_TSO) ? "TSO" : ""; + const char *l3_csum = (pkt->flags & AL_ETH_TX_FLAGS_IPV4_L3_CSUM) ? "L3 CSUM" : ""; + const char *l4_csum = (pkt->flags & AL_ETH_TX_FLAGS_L4_CSUM) ? + ((pkt->flags & AL_ETH_TX_FLAGS_L4_PARTIAL_CSUM) ? "L4 PARTIAL CSUM" : "L4 FULL CSUM") : ""; + const char *fcs = (pkt->flags & AL_ETH_TX_FLAGS_L2_DIS_FCS) ? "Disable FCS" : ""; + const char *ptp = (pkt->flags & AL_ETH_TX_FLAGS_TS) ? "TX_PTP" : ""; + const char *l3_proto_name = "unknown"; + const char *l4_proto_name = "unknown"; + const char *outer_l3_proto_name = "N/A"; + const char *tunnel_mode = ((pkt->tunnel_mode & AL_ETH_TUNNEL_WITH_UDP) == + AL_ETH_TUNNEL_WITH_UDP) ? + "TUNNEL_WITH_UDP" : + ((pkt->tunnel_mode & AL_ETH_TUNNEL_NO_UDP) == + AL_ETH_TUNNEL_NO_UDP) ? + "TUNNEL_NO_UDP" : ""; + uint32_t total_len = 0; + int i; + + al_dbg("[%s %d]: flags: %s %s %s %s %s %s\n", tx_dma_q->udma->name, tx_dma_q->qid, + tso, l3_csum, l4_csum, fcs, ptp, tunnel_mode); + + switch (pkt->l3_proto_idx) { + case AL_ETH_PROTO_ID_IPv4: + l3_proto_name = "IPv4"; + break; + case AL_ETH_PROTO_ID_IPv6: + l3_proto_name = "IPv6"; + break; + default: + l3_proto_name = "unknown"; + break; + } + + switch (pkt->l4_proto_idx) { + case AL_ETH_PROTO_ID_TCP: + l4_proto_name = "TCP"; + break; + case AL_ETH_PROTO_ID_UDP: + l4_proto_name = "UDP"; + break; + default: + l4_proto_name = "unknown"; + break; + } + + switch (pkt->outer_l3_proto_idx) { + case AL_ETH_PROTO_ID_IPv4: + outer_l3_proto_name = "IPv4"; + break; + case AL_ETH_PROTO_ID_IPv6: + outer_l3_proto_name = "IPv6"; + break; + default: + outer_l3_proto_name = "N/A"; + break; + } + + al_dbg("[%s %d]: L3 proto: %d (%s). L4 proto: %d (%s). Outer_L3 proto: %d (%s). vlan source count %d. mod add %d. mod del %d\n", + tx_dma_q->udma->name, tx_dma_q->qid, pkt->l3_proto_idx, + l3_proto_name, pkt->l4_proto_idx, l4_proto_name, + pkt->outer_l3_proto_idx, outer_l3_proto_name, + pkt->source_vlan_count, pkt->vlan_mod_add_count, + pkt->vlan_mod_del_count); + + if (pkt->meta) { + const char * store = pkt->meta->store ? "Yes" : "No"; + + al_dbg("[%s %d]: tx pkt with meta data. words valid %x\n", + tx_dma_q->udma->name, tx_dma_q->qid, + pkt->meta->words_valid); + if (tx_dma_q->adapter_rev_id == AL_ETH_REV_ID_0) + al_dbg("[%s %d]: meta: store to cache %s. l3 hdr len %d. l3 hdr offset %d. l4 hdr len %d. mss sel %d\n" + , tx_dma_q->udma->name, tx_dma_q->qid, store, + pkt->meta->l3_header_len, pkt->meta->l3_header_offset, + pkt->meta->l4_header_len, + pkt->meta->mss_idx_sel); + else { + const char *ptp_val = (pkt->flags & AL_ETH_TX_FLAGS_TS) ? "Yes" : "No"; + al_dbg("[%s %d]: meta: store to cache %s. l3 hdr len %d. l3 hdr offset %d. l4 hdr len %d. mss val %d ts_index %d ts_val:%s\n" + , tx_dma_q->udma->name, tx_dma_q->qid, store, + pkt->meta->l3_header_len, pkt->meta->l3_header_offset, + pkt->meta->l4_header_len, pkt->meta->mss_val, + pkt->meta->ts_index, ptp_val); + al_dbg("outer_l3_hdr_offset %d. outer_l3_len %d.\n", + pkt->meta->outer_l3_offset, pkt->meta->outer_l3_len); + } + } + + al_dbg("[%s %d]: num of bufs: %d\n", tx_dma_q->udma->name, tx_dma_q->qid, + pkt->num_of_bufs); + for (i = 0; i < pkt->num_of_bufs; i++) { + al_dbg("eth [%s %d]: buf[%d]: len 0x%08x. address 0x%016llx\n", tx_dma_q->udma->name, tx_dma_q->qid, + i, pkt->bufs[i].len, (unsigned long long)pkt->bufs[i].addr); + total_len += pkt->bufs[i].len; + } + al_dbg("[%s %d]: total len: 0x%08x\n", tx_dma_q->udma->name, tx_dma_q->qid, total_len); + +} + +/* TX */ +/** + * add packet to transmission queue + */ +int al_eth_tx_pkt_prepare(struct al_udma_q *tx_dma_q, struct al_eth_pkt *pkt) +{ + union al_udma_desc *tx_desc; + uint32_t tx_descs; + uint32_t flags = AL_M2S_DESC_FIRST | + AL_M2S_DESC_CONCAT | + (pkt->flags & AL_ETH_TX_FLAGS_INT); + uint64_t vmid = ((uint64_t)pkt->vmid) << AL_UDMA_DESC_VMID_SHIFT; + uint32_t meta_ctrl; + uint32_t ring_id; + int buf_idx; + + al_dbg("[%s %d]: new tx pkt\n", tx_dma_q->udma->name, tx_dma_q->qid); + + al_dump_tx_pkt(tx_dma_q, pkt); + + tx_descs = pkt->num_of_bufs; + if (pkt->meta) { + tx_descs += 1; + } +#ifdef AL_ETH_EX + al_assert((pkt->ext_meta_data == NULL) || (tx_dma_q->adapter_rev_id > AL_ETH_REV_ID_2)); + + tx_descs += al_eth_ext_metadata_needed_descs(pkt->ext_meta_data); + al_dbg("[%s %d]: %d Descriptors: ext_meta (%d). meta (%d). buffer (%d) ", + tx_dma_q->udma->name, tx_dma_q->qid, tx_descs, + al_eth_ext_metadata_needed_descs(pkt->ext_meta_data), + (pkt->meta != NULL), pkt->num_of_bufs); +#endif + + if (unlikely(al_udma_available_get(tx_dma_q) < tx_descs)) { + al_dbg("[%s %d]: failed to allocate (%d) descriptors", + tx_dma_q->udma->name, tx_dma_q->qid, tx_descs); + return 0; + } + +#ifdef AL_ETH_EX + if (pkt->ext_meta_data != NULL) { + al_eth_ext_metadata_create(tx_dma_q, &flags, pkt->ext_meta_data); + flags &= ~(AL_M2S_DESC_FIRST | AL_ETH_TX_FLAGS_INT); + } +#endif + + if (pkt->meta) { + uint32_t meta_word_0 = 0; + uint32_t meta_word_1 = 0; + uint32_t meta_word_2 = 0; + uint32_t meta_word_3 = 0; + + meta_word_0 |= flags | AL_M2S_DESC_META_DATA; + meta_word_0 &= ~AL_M2S_DESC_CONCAT; + flags &= ~(AL_M2S_DESC_FIRST | AL_ETH_TX_FLAGS_INT); + + tx_desc = al_udma_desc_get(tx_dma_q); + /* get ring id, and clear FIRST and Int flags */ + ring_id = al_udma_ring_id_get(tx_dma_q) << + AL_M2S_DESC_RING_ID_SHIFT; + + meta_word_0 |= ring_id; + meta_word_0 |= pkt->meta->words_valid << 12; + + if (pkt->meta->store) + meta_word_0 |= AL_ETH_TX_META_STORE; + + if (pkt->meta->words_valid & 1) { + meta_word_0 |= pkt->meta->vlan1_cfi_sel; + meta_word_0 |= pkt->meta->vlan2_vid_sel << 2; + meta_word_0 |= pkt->meta->vlan2_cfi_sel << 4; + meta_word_0 |= pkt->meta->vlan2_pbits_sel << 6; + meta_word_0 |= pkt->meta->vlan2_ether_sel << 8; + } + + if (pkt->meta->words_valid & 2) { + meta_word_1 = pkt->meta->vlan1_new_vid; + meta_word_1 |= pkt->meta->vlan1_new_cfi << 12; + meta_word_1 |= pkt->meta->vlan1_new_pbits << 13; + meta_word_1 |= pkt->meta->vlan2_new_vid << 16; + meta_word_1 |= pkt->meta->vlan2_new_cfi << 28; + meta_word_1 |= pkt->meta->vlan2_new_pbits << 29; + } + + if (pkt->meta->words_valid & 4) { + meta_word_2 = pkt->meta->l3_header_len & AL_ETH_TX_META_L3_LEN_MASK; + meta_word_2 |= (pkt->meta->l3_header_offset & AL_ETH_TX_META_L3_OFF_MASK) << + AL_ETH_TX_META_L3_OFF_SHIFT; + meta_word_2 |= (pkt->meta->l4_header_len & 0x3f) << 16; + + if (tx_dma_q->adapter_rev_id == AL_ETH_REV_ID_0) { + meta_word_2 |= (pkt->meta->mss_idx_sel & 7) << 24; + } else { + uint32_t l3_offset; + + if (unlikely(pkt->flags & AL_ETH_TX_FLAGS_TS)) + meta_word_0 |= pkt->meta->ts_index << AL_ETH_TX_META_MSS_MSB_TS_VAL_SHIFT; + else + meta_word_0 |= (((pkt->meta->mss_val & 0x3c00) >> 10) + << AL_ETH_TX_META_MSS_MSB_TS_VAL_SHIFT); + meta_word_2 |= ((pkt->meta->mss_val & 0x03ff) + << AL_ETH_TX_META_MSS_LSB_VAL_SHIFT); + + /* + * move from bytes to multiplication of 2 as the HW + * expect to get it + */ + l3_offset = (pkt->meta->outer_l3_offset >> 1); + + meta_word_0 |= + (((l3_offset & + AL_ETH_TX_META_OUTER_L3_OFF_HIGH_MASK) >> 3) + << AL_ETH_TX_META_OUTER_L3_OFF_HIGH_SHIFT); + + meta_word_3 |= + ((l3_offset & + AL_ETH_TX_META_OUTER_L3_OFF_LOW_MASK) + << AL_ETH_TX_META_OUTER_L3_OFF_LOW_SHIFT); + + /* + * shift right 2 bits to work in multiplication of 4 + * as the HW expect to get it + */ + meta_word_3 |= + (((pkt->meta->outer_l3_len >> 2) & + AL_ETH_TX_META_OUTER_L3_LEN_MASK) + << AL_ETH_TX_META_OUTER_L3_LEN_SHIFT); + } + } + + tx_desc->tx_meta.len_ctrl = swap32_to_le(meta_word_0); + tx_desc->tx_meta.meta_ctrl = swap32_to_le(meta_word_1); + tx_desc->tx_meta.meta1 = swap32_to_le(meta_word_2); + tx_desc->tx_meta.meta2 = swap32_to_le(meta_word_3); + al_dump_tx_desc(tx_desc); + } + + meta_ctrl = pkt->flags & AL_ETH_TX_PKT_META_FLAGS; + + /* L4_PARTIAL_CSUM without L4_CSUM is invalid option */ + al_assert((pkt->flags & (AL_ETH_TX_FLAGS_L4_CSUM|AL_ETH_TX_FLAGS_L4_PARTIAL_CSUM)) != + AL_ETH_TX_FLAGS_L4_PARTIAL_CSUM); + + /* TSO packets can't have Timestamp enabled */ + al_assert((pkt->flags & (AL_ETH_TX_FLAGS_TSO|AL_ETH_TX_FLAGS_TS)) != + (AL_ETH_TX_FLAGS_TSO|AL_ETH_TX_FLAGS_TS)); + + meta_ctrl |= pkt->l3_proto_idx; + meta_ctrl |= pkt->l4_proto_idx << AL_ETH_TX_L4_PROTO_IDX_SHIFT; + meta_ctrl |= pkt->source_vlan_count << AL_ETH_TX_SRC_VLAN_CNT_SHIFT; + meta_ctrl |= pkt->vlan_mod_add_count << AL_ETH_TX_VLAN_MOD_ADD_SHIFT; + meta_ctrl |= pkt->vlan_mod_del_count << AL_ETH_TX_VLAN_MOD_DEL_SHIFT; + meta_ctrl |= pkt->vlan_mod_v1_ether_sel << AL_ETH_TX_VLAN_MOD_E_SEL_SHIFT; + meta_ctrl |= pkt->vlan_mod_v1_vid_sel << AL_ETH_TX_VLAN_MOD_VID_SEL_SHIFT; + meta_ctrl |= pkt->vlan_mod_v1_pbits_sel << AL_ETH_TX_VLAN_MOD_PBIT_SEL_SHIFT; + +#ifdef AL_ETH_EX + if ((pkt->ext_meta_data != NULL) && (pkt->ext_meta_data->tx_crypto_data != NULL)) + meta_ctrl |= AL_ETH_TX_FLAGS_ENCRYPT; +#endif + + if (tx_dma_q->adapter_rev_id > AL_ETH_REV_ID_0) { + meta_ctrl |= pkt->tunnel_mode << AL_ETH_TX_TUNNEL_MODE_SHIFT; + if (pkt->outer_l3_proto_idx == AL_ETH_PROTO_ID_IPv4) + meta_ctrl |= 1 << AL_ETH_TX_OUTER_L3_PROTO_SHIFT; + } + + flags |= pkt->flags & AL_ETH_TX_PKT_UDMA_FLAGS; + for(buf_idx = 0; buf_idx < pkt->num_of_bufs; buf_idx++ ) { + uint32_t flags_len = flags; + + tx_desc = al_udma_desc_get(tx_dma_q); + /* get ring id, and clear FIRST and Int flags */ + ring_id = al_udma_ring_id_get(tx_dma_q) << + AL_M2S_DESC_RING_ID_SHIFT; + + flags_len |= ring_id; + + if (buf_idx == (pkt->num_of_bufs - 1)) + flags_len |= AL_M2S_DESC_LAST; + + /* clear First and Int flags */ + flags &= AL_ETH_TX_FLAGS_NO_SNOOP; + flags |= AL_M2S_DESC_CONCAT; + + flags_len |= pkt->bufs[buf_idx].len & AL_M2S_DESC_LEN_MASK; + tx_desc->tx.len_ctrl = swap32_to_le(flags_len); + if (buf_idx == 0) + tx_desc->tx.meta_ctrl = swap32_to_le(meta_ctrl); + tx_desc->tx.buf_ptr = swap64_to_le( + pkt->bufs[buf_idx].addr | vmid); + al_dump_tx_desc(tx_desc); + } + + al_dbg("[%s %d]: pkt descriptors written into the tx queue. descs num (%d)\n", + tx_dma_q->udma->name, tx_dma_q->qid, tx_descs); + + return tx_descs; +} + + +void al_eth_tx_dma_action(struct al_udma_q *tx_dma_q, uint32_t tx_descs) +{ + /* add tx descriptors */ + al_udma_desc_action_add(tx_dma_q, tx_descs); +} + +/** + * get number of completed tx descriptors, upper layer should derive from + */ +int al_eth_comp_tx_get(struct al_udma_q *tx_dma_q) +{ + int rc; + + rc = al_udma_cdesc_get_all(tx_dma_q, NULL); + if (rc != 0) { + al_udma_cdesc_ack(tx_dma_q, rc); + al_dbg("[%s %d]: tx completion: descs (%d)\n", + tx_dma_q->udma->name, tx_dma_q->qid, rc); + } + + return rc; +} + +/** + * configure the TSO MSS val + */ +int al_eth_tso_mss_config(struct al_hal_eth_adapter *adapter, uint8_t idx, uint32_t mss_val) +{ + + al_assert(idx <= 8); /*valid MSS index*/ + al_assert(mss_val <= AL_ETH_TSO_MSS_MAX_VAL); /*valid MSS val*/ + al_assert(mss_val >= AL_ETH_TSO_MSS_MIN_VAL); /*valid MSS val*/ + + al_reg_write32(&adapter->ec_regs_base->tso_sel[idx].mss, mss_val); + return 0; +} + + +/* RX */ +/** + * config the rx descriptor fields + */ +void al_eth_rx_desc_config( + struct al_hal_eth_adapter *adapter, + enum al_eth_rx_desc_lro_context_val_res lro_sel, + enum al_eth_rx_desc_l4_offset_sel l4_offset_sel, + enum al_eth_rx_desc_l3_offset_sel l3_offset_sel, + enum al_eth_rx_desc_l4_chk_res_sel l4_sel, + enum al_eth_rx_desc_l3_chk_res_sel l3_sel, + enum al_eth_rx_desc_l3_proto_idx_sel l3_proto_sel, + enum al_eth_rx_desc_l4_proto_idx_sel l4_proto_sel, + enum al_eth_rx_desc_frag_sel frag_sel) +{ + uint32_t reg_val = 0; + + reg_val |= (lro_sel == AL_ETH_L4_OFFSET) ? + EC_RFW_CFG_A_0_LRO_CONTEXT_SEL : 0; + + reg_val |= (l4_sel == AL_ETH_L4_INNER_OUTER_CHK) ? + EC_RFW_CFG_A_0_META_L4_CHK_RES_SEL : 0; + + reg_val |= l3_sel << EC_RFW_CFG_A_0_META_L3_CHK_RES_SEL_SHIFT; + + al_reg_write32(&adapter->ec_regs_base->rfw.cfg_a_0, reg_val); + + reg_val = al_reg_read32(&adapter->ec_regs_base->rfw.meta); + if (l3_proto_sel == AL_ETH_L3_PROTO_IDX_INNER) + reg_val |= EC_RFW_META_L3_PROT_SEL; + else + reg_val &= ~EC_RFW_META_L3_PROT_SEL; + + if (l4_proto_sel == AL_ETH_L4_PROTO_IDX_INNER) + reg_val |= EC_RFW_META_L4_PROT_SEL; + else + reg_val &= ~EC_RFW_META_L4_PROT_SEL; + + if (l4_offset_sel == AL_ETH_L4_OFFSET_INNER) + reg_val |= EC_RFW_META_L4_OFFSET_SEL; + else + reg_val &= ~EC_RFW_META_L4_OFFSET_SEL; + + if (l3_offset_sel == AL_ETH_L3_OFFSET_INNER) + reg_val |= EC_RFW_META_L3_OFFSET_SEL; + else + reg_val &= ~EC_RFW_META_L3_OFFSET_SEL; + + if (frag_sel == AL_ETH_FRAG_INNER) + reg_val |= EC_RFW_META_FRAG_SEL; + else + reg_val &= ~EC_RFW_META_FRAG_SEL; + + + al_reg_write32(&adapter->ec_regs_base->rfw.meta, reg_val); +} + +/** + * Configure RX header split + */ +int al_eth_rx_header_split_config(struct al_hal_eth_adapter *adapter, al_bool enable, uint32_t header_len) +{ + uint32_t reg; + + if (adapter->rev_id < AL_ETH_REV_ID_1) { + al_err("[%s]: header split feature not supported by this revision\n", adapter->name); + return -EINVAL; + } + reg = al_reg_read32(&adapter->ec_regs_base->rfw.hdr_split); + if (enable == AL_TRUE) + reg |= EC_RFW_HDR_SPLIT_EN; + else + reg &= ~EC_RFW_HDR_SPLIT_EN; + + AL_REG_FIELD_SET(reg, EC_RFW_HDR_SPLIT_DEF_LEN_MASK, EC_RFW_HDR_SPLIT_DEF_LEN_SHIFT, header_len); + al_reg_write32(&adapter->ec_regs_base->rfw.hdr_split, reg); + return 0; +} + + +/** + * enable / disable header split in the udma queue. + * length will be taken from the udma configuration to enable different length per queue. + */ +int al_eth_rx_header_split_force_len_config(struct al_hal_eth_adapter *adapter, + al_bool enable, + uint32_t qid, + uint32_t header_len) +{ + al_udma_s2m_q_compl_hdr_split_config(&(adapter->rx_udma.udma_q[qid]), enable, + AL_TRUE, header_len); + + return 0; +} + + +/** + * add buffer to receive queue + */ +int al_eth_rx_buffer_add(struct al_udma_q *rx_dma_q, + struct al_buf *buf, uint32_t flags, + struct al_buf *header_buf) +{ + uint64_t vmid = ((uint64_t)flags & AL_ETH_RX_FLAGS_VMID_MASK) << + AL_UDMA_DESC_VMID_SHIFT; + uint32_t flags_len = flags & ~AL_ETH_RX_FLAGS_VMID_MASK; + union al_udma_desc *rx_desc; + + al_dbg("[%s %d]: add rx buffer.\n", rx_dma_q->udma->name, rx_dma_q->qid); + +#if 1 + if (unlikely(al_udma_available_get(rx_dma_q) < 1)) { + al_dbg("[%s]: rx q (%d) has no enough free descriptor", + rx_dma_q->udma->name, rx_dma_q->qid); + return -ENOSPC; + } +#endif + rx_desc = al_udma_desc_get(rx_dma_q); + + flags_len |= al_udma_ring_id_get(rx_dma_q) << AL_S2M_DESC_RING_ID_SHIFT; + flags_len |= buf->len & AL_S2M_DESC_LEN_MASK; + + if (flags & AL_S2M_DESC_DUAL_BUF) { + al_assert(header_buf != NULL); /*header valid in dual buf */ + al_assert((rx_dma_q->udma->rev_id >= AL_UDMA_REV_ID_2) || + (AL_ADDR_HIGH(buf->addr) == AL_ADDR_HIGH(header_buf->addr))); + + flags_len |= ((header_buf->len >> AL_S2M_DESC_LEN2_GRANULARITY_SHIFT) + << AL_S2M_DESC_LEN2_SHIFT) & AL_S2M_DESC_LEN2_MASK; + rx_desc->rx.buf2_ptr_lo = swap32_to_le(AL_ADDR_LOW(header_buf->addr)); + } + rx_desc->rx.len_ctrl = swap32_to_le(flags_len); + rx_desc->rx.buf1_ptr = swap64_to_le(buf->addr | vmid); + + return 0; +} + +/** + * notify the hw engine about rx descriptors that were added to the receive queue + */ +void al_eth_rx_buffer_action(struct al_udma_q *rx_dma_q, uint32_t descs_num) +{ + al_dbg("[%s]: update the rx engine tail pointer: queue %d. descs %d\n", + rx_dma_q->udma->name, rx_dma_q->qid, descs_num); + + /* add rx descriptor */ + al_udma_desc_action_add(rx_dma_q, descs_num); +} + +/** + * get packet from RX completion ring + */ +uint32_t al_eth_pkt_rx(struct al_udma_q *rx_dma_q, + struct al_eth_pkt *pkt) +{ + volatile union al_udma_cdesc *cdesc; + volatile al_eth_rx_cdesc *rx_desc; + uint32_t i; + uint32_t rc; + + rc = al_udma_cdesc_packet_get(rx_dma_q, &cdesc); + if (rc == 0) + return 0; + + al_assert(rc <= AL_ETH_PKT_MAX_BUFS); + + al_dbg("[%s]: fetch rx packet: queue %d.\n", + rx_dma_q->udma->name, rx_dma_q->qid); + + pkt->rx_header_len = 0; + for (i = 0; i < rc; i++) { + uint32_t buf1_len, buf2_len; + + /* get next descriptor */ + rx_desc = (volatile al_eth_rx_cdesc *)al_cdesc_next(rx_dma_q, cdesc, i); + + buf1_len = swap32_from_le(rx_desc->len); + + if ((i == 0) && (swap32_from_le(rx_desc->word2) & + AL_UDMA_CDESC_BUF2_USED)) { + buf2_len = swap32_from_le(rx_desc->word2); + pkt->rx_header_len = (buf2_len & AL_S2M_DESC_LEN2_MASK) >> + AL_S2M_DESC_LEN2_SHIFT; + } + if ((swap32_from_le(rx_desc->ctrl_meta) & AL_UDMA_CDESC_BUF1_USED) && + ((swap32_from_le(rx_desc->ctrl_meta) & AL_UDMA_CDESC_DDP) == 0)) + pkt->bufs[i].len = buf1_len & AL_S2M_DESC_LEN_MASK; + else + pkt->bufs[i].len = 0; + } + /* get flags from last desc */ + pkt->flags = swap32_from_le(rx_desc->ctrl_meta); +#ifdef AL_ETH_RX_DESC_RAW_GET + pkt->rx_desc_raw[0] = pkt->flags; + pkt->rx_desc_raw[1] = swap32_from_le(rx_desc->len); + pkt->rx_desc_raw[2] = swap32_from_le(rx_desc->word2); + pkt->rx_desc_raw[3] = swap32_from_le(rx_desc->word3); +#endif + /* update L3/L4 proto index */ + pkt->l3_proto_idx = pkt->flags & AL_ETH_RX_L3_PROTO_IDX_MASK; + pkt->l4_proto_idx = (pkt->flags >> AL_ETH_RX_L4_PROTO_IDX_SHIFT) & + AL_ETH_RX_L4_PROTO_IDX_MASK; + pkt->rxhash = (swap32_from_le(rx_desc->len) & AL_ETH_RX_HASH_MASK) >> + AL_ETH_RX_HASH_SHIFT; + pkt->l3_offset = (swap32_from_le(rx_desc->word2) & AL_ETH_RX_L3_OFFSET_MASK) >> AL_ETH_RX_L3_OFFSET_SHIFT; + + al_udma_cdesc_ack(rx_dma_q, rc); + return rc; +} + + +int al_eth_rx_parser_entry_update(struct al_hal_eth_adapter *adapter, uint32_t idx, + struct al_eth_epe_p_reg_entry *reg_entry, + struct al_eth_epe_control_entry *control_entry) +{ + al_eth_epe_entry_set(adapter, idx, reg_entry, control_entry); + return 0; +} + +#define AL_ETH_THASH_UDMA_SHIFT 0 +#define AL_ETH_THASH_UDMA_MASK (0xF << AL_ETH_THASH_UDMA_SHIFT) + +#define AL_ETH_THASH_Q_SHIFT 4 +#define AL_ETH_THASH_Q_MASK (0x3 << AL_ETH_THASH_Q_SHIFT) + +int al_eth_thash_table_set(struct al_hal_eth_adapter *adapter, uint32_t idx, uint8_t udma, uint32_t queue) +{ + uint32_t entry; + al_assert(idx < AL_ETH_RX_THASH_TABLE_SIZE); /*valid THASH index*/ + + entry = (udma << AL_ETH_THASH_UDMA_SHIFT) & AL_ETH_THASH_UDMA_MASK; + entry |= (queue << AL_ETH_THASH_Q_SHIFT) & AL_ETH_THASH_Q_MASK; + + al_reg_write32(&adapter->ec_regs_base->rfw.thash_table_addr, idx); + al_reg_write32(&adapter->ec_regs_base->rfw.thash_table_data, entry); + return 0; +} + +int al_eth_fsm_table_set(struct al_hal_eth_adapter *adapter, uint32_t idx, uint32_t entry) +{ + + al_assert(idx < AL_ETH_RX_FSM_TABLE_SIZE); /*valid FSM index*/ + + + al_reg_write32(&adapter->ec_regs_base->rfw.fsm_table_addr, idx); + al_reg_write32(&adapter->ec_regs_base->rfw.fsm_table_data, entry); + return 0; +} + +static uint32_t al_eth_fwd_ctrl_entry_to_val(struct al_eth_fwd_ctrl_table_entry *entry) +{ + uint32_t val = 0; + AL_REG_FIELD_SET(val, AL_FIELD_MASK(3,0), 0, entry->prio_sel); + AL_REG_FIELD_SET(val, AL_FIELD_MASK(7,4), 4, entry->queue_sel_1); + AL_REG_FIELD_SET(val, AL_FIELD_MASK(9,8), 8, entry->queue_sel_2); + AL_REG_FIELD_SET(val, AL_FIELD_MASK(13,10), 10, entry->udma_sel); + AL_REG_FIELD_SET(val, AL_FIELD_MASK(17,15), 15, entry->hdr_split_len_sel); + if (entry->hdr_split_len_sel != AL_ETH_CTRL_TABLE_HDR_SPLIT_LEN_SEL_0) + val |= AL_BIT(18); + AL_REG_BIT_VAL_SET(val, 19, !!(entry->filter == AL_TRUE)); + + return val; +} + +static int al_eth_ctrl_index_match(struct al_eth_fwd_ctrl_table_index *index, uint32_t i) { + if ((index->vlan_table_out != AL_ETH_FWD_CTRL_IDX_VLAN_TABLE_OUT_ANY) + && (index->vlan_table_out != AL_REG_BIT_GET(i, 0))) + return 0; + if ((index->tunnel_exist != AL_ETH_FWD_CTRL_IDX_TUNNEL_ANY) + && (index->tunnel_exist != AL_REG_BIT_GET(i, 1))) + return 0; + if ((index->vlan_exist != AL_ETH_FWD_CTRL_IDX_VLAN_ANY) + && (index->vlan_exist != AL_REG_BIT_GET(i, 2))) + return 0; + if ((index->mac_table_match != AL_ETH_FWD_CTRL_IDX_MAC_TABLE_ANY) + && (index->mac_table_match != AL_REG_BIT_GET(i, 3))) + return 0; + if ((index->protocol_id != AL_ETH_PROTO_ID_ANY) + && (index->protocol_id != AL_REG_FIELD_GET(i, AL_FIELD_MASK(8,4),4))) + return 0; + if ((index->mac_type != AL_ETH_FWD_CTRL_IDX_MAC_DA_TYPE_ANY) + && (index->mac_type != AL_REG_FIELD_GET(i, AL_FIELD_MASK(10,9),9))) + return 0; + return 1; +} + +int al_eth_ctrl_table_set(struct al_hal_eth_adapter *adapter, + struct al_eth_fwd_ctrl_table_index *index, + struct al_eth_fwd_ctrl_table_entry *entry) +{ + uint32_t val = al_eth_fwd_ctrl_entry_to_val(entry); + uint32_t i; + + for (i = 0; i < AL_ETH_RX_CTRL_TABLE_SIZE; i++) { + if (al_eth_ctrl_index_match(index, i)) { + al_reg_write32(&adapter->ec_regs_base->rfw.ctrl_table_addr, i); + al_reg_write32(&adapter->ec_regs_base->rfw.ctrl_table_data, val); + } + } + return 0; +} + +int al_eth_ctrl_table_def_set(struct al_hal_eth_adapter *adapter, + al_bool use_table, + struct al_eth_fwd_ctrl_table_entry *entry) +{ + uint32_t val = al_eth_fwd_ctrl_entry_to_val(entry); + + if (use_table) + val |= EC_RFW_CTRL_TABLE_DEF_SEL; + + al_reg_write32(&adapter->ec_regs_base->rfw.ctrl_table_def, val); + + return 0; +} + +int al_eth_ctrl_table_raw_set(struct al_hal_eth_adapter *adapter, uint32_t idx, uint32_t entry) +{ + + al_assert(idx < AL_ETH_RX_CTRL_TABLE_SIZE); /* valid CTRL index */ + + + al_reg_write32(&adapter->ec_regs_base->rfw.ctrl_table_addr, idx); + al_reg_write32(&adapter->ec_regs_base->rfw.ctrl_table_data, entry); + return 0; +} + +int al_eth_ctrl_table_def_raw_set(struct al_hal_eth_adapter *adapter, uint32_t val) +{ + al_reg_write32(&adapter->ec_regs_base->rfw.ctrl_table_def, val); + + return 0; +} + +int al_eth_hash_key_set(struct al_hal_eth_adapter *adapter, uint32_t idx, uint32_t val) +{ + + al_assert(idx < AL_ETH_RX_HASH_KEY_NUM); /*valid CTRL index*/ + + al_reg_write32(&adapter->ec_regs_base->rfw_hash[idx].key, val); + + return 0; +} + +static uint32_t al_eth_fwd_mac_table_entry_to_val(struct al_eth_fwd_mac_table_entry *entry) +{ + uint32_t val = 0; + + val |= (entry->filter == AL_TRUE) ? EC_FWD_MAC_CTRL_RX_VAL_DROP : 0; + val |= ((entry->udma_mask << EC_FWD_MAC_CTRL_RX_VAL_UDMA_SHIFT) & + EC_FWD_MAC_CTRL_RX_VAL_UDMA_MASK); + + val |= ((entry->qid << EC_FWD_MAC_CTRL_RX_VAL_QID_SHIFT) & + EC_FWD_MAC_CTRL_RX_VAL_QID_MASK); + + val |= (entry->rx_valid == AL_TRUE) ? EC_FWD_MAC_CTRL_RX_VALID : 0; + + val |= ((entry->tx_target << EC_FWD_MAC_CTRL_TX_VAL_SHIFT) & + EC_FWD_MAC_CTRL_TX_VAL_MASK); + + val |= (entry->tx_valid == AL_TRUE) ? EC_FWD_MAC_CTRL_TX_VALID : 0; + + return val; +} + +int al_eth_fwd_mac_table_set(struct al_hal_eth_adapter *adapter, uint32_t idx, + struct al_eth_fwd_mac_table_entry *entry) +{ + uint32_t val; + + al_assert(idx < AL_ETH_FWD_MAC_NUM); /*valid FWD MAC index */ + + val = (entry->addr[2] << 24) | (entry->addr[3] << 16) | + (entry->addr[4] << 8) | entry->addr[5]; + al_reg_write32(&adapter->ec_regs_base->fwd_mac[idx].data_l, val); + val = (entry->addr[0] << 8) | entry->addr[1]; + al_reg_write32(&adapter->ec_regs_base->fwd_mac[idx].data_h, val); + val = (entry->mask[2] << 24) | (entry->mask[3] << 16) | + (entry->mask[4] << 8) | entry->mask[5]; + al_reg_write32(&adapter->ec_regs_base->fwd_mac[idx].mask_l, val); + val = (entry->mask[0] << 8) | entry->mask[1]; + al_reg_write32(&adapter->ec_regs_base->fwd_mac[idx].mask_h, val); + + val = al_eth_fwd_mac_table_entry_to_val(entry); + al_reg_write32(&adapter->ec_regs_base->fwd_mac[idx].ctrl, val); + return 0; +} + + + +int al_eth_fwd_mac_addr_raw_set(struct al_hal_eth_adapter *adapter, uint32_t idx, uint32_t addr_lo, uint32_t addr_hi, uint32_t mask_lo, uint32_t mask_hi) +{ + al_assert(idx < AL_ETH_FWD_MAC_NUM); /*valid FWD MAC index */ + + al_reg_write32(&adapter->ec_regs_base->fwd_mac[idx].data_l, addr_lo); + al_reg_write32(&adapter->ec_regs_base->fwd_mac[idx].data_h, addr_hi); + al_reg_write32(&adapter->ec_regs_base->fwd_mac[idx].mask_l, mask_lo); + al_reg_write32(&adapter->ec_regs_base->fwd_mac[idx].mask_h, mask_hi); + + return 0; +} + +int al_eth_fwd_mac_ctrl_raw_set(struct al_hal_eth_adapter *adapter, uint32_t idx, uint32_t ctrl) +{ + al_assert(idx < AL_ETH_FWD_MAC_NUM); /*valid FWD MAC index */ + + al_reg_write32(&adapter->ec_regs_base->fwd_mac[idx].ctrl, ctrl); + + return 0; +} + +int al_eth_mac_addr_store(void * __iomem ec_base, uint32_t idx, uint8_t *addr) +{ + struct al_ec_regs __iomem *ec_regs_base = (struct al_ec_regs __iomem*)ec_base; + uint32_t val; + + al_assert(idx < AL_ETH_FWD_MAC_NUM); /*valid FWD MAC index */ + + val = (addr[2] << 24) | (addr[3] << 16) | (addr[4] << 8) | addr[5]; + al_reg_write32(&ec_regs_base->fwd_mac[idx].data_l, val); + val = (addr[0] << 8) | addr[1]; + al_reg_write32(&ec_regs_base->fwd_mac[idx].data_h, val); + return 0; +} + +int al_eth_mac_addr_read(void * __iomem ec_base, uint32_t idx, uint8_t *addr) +{ + struct al_ec_regs __iomem *ec_regs_base = (struct al_ec_regs __iomem*)ec_base; + uint32_t addr_lo = al_reg_read32(&ec_regs_base->fwd_mac[idx].data_l); + uint16_t addr_hi = al_reg_read32(&ec_regs_base->fwd_mac[idx].data_h); + + addr[5] = addr_lo & 0xff; + addr[4] = (addr_lo >> 8) & 0xff; + addr[3] = (addr_lo >> 16) & 0xff; + addr[2] = (addr_lo >> 24) & 0xff; + addr[1] = addr_hi & 0xff; + addr[0] = (addr_hi >> 8) & 0xff; + return 0; +} + +int al_eth_fwd_mhash_table_set(struct al_hal_eth_adapter *adapter, uint32_t idx, uint8_t udma_mask, uint8_t qid) +{ + uint32_t val = 0; + al_assert(idx < AL_ETH_FWD_MAC_HASH_NUM); /* valid MHASH index */ + + AL_REG_FIELD_SET(val, AL_FIELD_MASK(3,0), 0, udma_mask); + AL_REG_FIELD_SET(val, AL_FIELD_MASK(5,4), 4, qid); + + al_reg_write32(&adapter->ec_regs_base->rfw.mhash_table_addr, idx); + al_reg_write32(&adapter->ec_regs_base->rfw.mhash_table_data, val); + return 0; +} +static uint32_t al_eth_fwd_vid_entry_to_val(struct al_eth_fwd_vid_table_entry *entry) +{ + uint32_t val = 0; + AL_REG_BIT_VAL_SET(val, 0, entry->control); + AL_REG_BIT_VAL_SET(val, 1, entry->filter); + AL_REG_FIELD_SET(val, AL_FIELD_MASK(5,2), 2, entry->udma_mask); + + return val; +} + +int al_eth_fwd_vid_config_set(struct al_hal_eth_adapter *adapter, al_bool use_table, + struct al_eth_fwd_vid_table_entry *default_entry, + uint32_t default_vlan) +{ + uint32_t reg; + + reg = al_eth_fwd_vid_entry_to_val(default_entry); + if (use_table) + reg |= EC_RFW_VID_TABLE_DEF_SEL; + else + reg &= ~EC_RFW_VID_TABLE_DEF_SEL; + al_reg_write32(&adapter->ec_regs_base->rfw.vid_table_def, reg); + al_reg_write32(&adapter->ec_regs_base->rfw.default_vlan, default_vlan); + + return 0; +} + +int al_eth_fwd_vid_table_set(struct al_hal_eth_adapter *adapter, uint32_t idx, + struct al_eth_fwd_vid_table_entry *entry) +{ + uint32_t val; + al_assert(idx < AL_ETH_FWD_VID_TABLE_NUM); /* valid VID index */ + + val = al_eth_fwd_vid_entry_to_val(entry); + al_reg_write32(&adapter->ec_regs_base->rfw.vid_table_addr, idx); + al_reg_write32(&adapter->ec_regs_base->rfw.vid_table_data, val); + return 0; +} + +int al_eth_fwd_pbits_table_set(struct al_hal_eth_adapter *adapter, uint32_t idx, uint8_t prio) +{ + + al_assert(idx < AL_ETH_FWD_PBITS_TABLE_NUM); /* valid PBIT index */ + al_assert(prio < AL_ETH_FWD_PRIO_TABLE_NUM); /* valid PRIO index */ + al_reg_write32(&adapter->ec_regs_base->rfw.pbits_table_addr, idx); + al_reg_write32(&adapter->ec_regs_base->rfw.pbits_table_data, prio); + return 0; +} + +int al_eth_fwd_priority_table_set(struct al_hal_eth_adapter *adapter, uint8_t prio, uint8_t qid) +{ + al_assert(prio < AL_ETH_FWD_PRIO_TABLE_NUM); /* valid PRIO index */ + + al_reg_write32(&adapter->ec_regs_base->rfw_priority[prio].queue, qid); + return 0; +} + + +int al_eth_fwd_dscp_table_set(struct al_hal_eth_adapter *adapter, uint32_t idx, uint8_t prio) +{ + + al_assert(idx < AL_ETH_FWD_DSCP_TABLE_NUM); /* valid DSCP index */ + + + al_reg_write32(&adapter->ec_regs_base->rfw.dscp_table_addr, idx); + al_reg_write32(&adapter->ec_regs_base->rfw.dscp_table_data, prio); + return 0; +} + +int al_eth_fwd_tc_table_set(struct al_hal_eth_adapter *adapter, uint32_t idx, uint8_t prio) +{ + + al_assert(idx < AL_ETH_FWD_TC_TABLE_NUM); /* valid TC index */ + + + al_reg_write32(&adapter->ec_regs_base->rfw.tc_table_addr, idx); + al_reg_write32(&adapter->ec_regs_base->rfw.tc_table_data, prio); + return 0; +} + +/** Configure default UDMA register */ +int al_eth_fwd_default_udma_config(struct al_hal_eth_adapter *adapter, uint32_t idx, + uint8_t udma_mask) +{ + al_reg_write32_masked(&adapter->ec_regs_base->rfw_default[idx].opt_1, + EC_RFW_DEFAULT_OPT_1_UDMA_MASK, + udma_mask << EC_RFW_DEFAULT_OPT_1_UDMA_SHIFT); + return 0; +} + +/** Configure default queue register */ +int al_eth_fwd_default_queue_config(struct al_hal_eth_adapter *adapter, uint32_t idx, + uint8_t qid) +{ + al_reg_write32_masked(&adapter->ec_regs_base->rfw_default[idx].opt_1, + EC_RFW_DEFAULT_OPT_1_QUEUE_MASK, + qid << EC_RFW_DEFAULT_OPT_1_QUEUE_SHIFT); + return 0; +} + +/** Configure default priority register */ +int al_eth_fwd_default_priority_config(struct al_hal_eth_adapter *adapter, uint32_t idx, + uint8_t prio) +{ + al_reg_write32_masked(&adapter->ec_regs_base->rfw_default[idx].opt_1, + EC_RFW_DEFAULT_OPT_1_PRIORITY_MASK, + prio << EC_RFW_DEFAULT_OPT_1_PRIORITY_SHIFT); + return 0; +} + +int al_eth_switching_config_set(struct al_hal_eth_adapter *adapter, uint8_t udma_id, uint8_t forward_all_to_mac, uint8_t enable_int_switching, + enum al_eth_tx_switch_vid_sel_type vid_sel_type, + enum al_eth_tx_switch_dec_type uc_dec, + enum al_eth_tx_switch_dec_type mc_dec, + enum al_eth_tx_switch_dec_type bc_dec) +{ + uint32_t reg; + + if (udma_id == 0) { + reg = al_reg_read32(&adapter->ec_regs_base->tfw.tx_gen); + if (forward_all_to_mac) + reg |= EC_TFW_TX_GEN_FWD_ALL_TO_MAC; + else + reg &= ~EC_TFW_TX_GEN_FWD_ALL_TO_MAC; + al_reg_write32(&adapter->ec_regs_base->tfw.tx_gen, reg); + } + + reg = enable_int_switching; + reg |= (vid_sel_type & 7) << 1; + reg |= (bc_dec & 3) << 4; + reg |= (mc_dec & 3) << 6; + reg |= (uc_dec & 3) << 8; + al_reg_write32(&adapter->ec_regs_base->tfw_udma[udma_id].fwd_dec, reg); + + return 0; +} + +#define AL_ETH_RFW_FILTER_SUPPORTED(rev_id) \ + (AL_ETH_RFW_FILTER_UNDET_MAC | \ + AL_ETH_RFW_FILTER_DET_MAC | \ + AL_ETH_RFW_FILTER_TAGGED | \ + AL_ETH_RFW_FILTER_UNTAGGED | \ + AL_ETH_RFW_FILTER_BC | \ + AL_ETH_RFW_FILTER_MC | \ + AL_ETH_RFW_FILTER_VLAN_VID | \ + AL_ETH_RFW_FILTER_CTRL_TABLE | \ + AL_ETH_RFW_FILTER_PROT_INDEX | \ + ((rev_id > AL_ETH_REV_ID_0) ? ((AL_ETH_RFW_FILTER_WOL) | (AL_ETH_RFW_FILTER_PARSE)) : 0)) + +/* Configure the receive filters */ +int al_eth_filter_config(struct al_hal_eth_adapter *adapter, struct al_eth_filter_params *params) +{ + uint32_t reg; + + al_assert(params); /* valid params pointer */ + + if (params->filters & ~(AL_ETH_RFW_FILTER_SUPPORTED(adapter->rev_id))) { + al_err("[%s]: unsupported filter options (0x%08x)\n", adapter->name, params->filters); + return -EINVAL; + } + + reg = al_reg_read32(&adapter->ec_regs_base->rfw.out_cfg); + if (params->enable == AL_TRUE) + AL_REG_MASK_SET(reg, EC_RFW_OUT_CFG_DROP_EN); + else + AL_REG_MASK_CLEAR(reg, EC_RFW_OUT_CFG_DROP_EN); + al_reg_write32(&adapter->ec_regs_base->rfw.out_cfg, reg); + + al_reg_write32_masked( + &adapter->ec_regs_base->rfw.filter, + AL_ETH_RFW_FILTER_SUPPORTED(adapter->rev_id), + params->filters); + if (params->filters & AL_ETH_RFW_FILTER_PROT_INDEX) { + int i; + for (i = 0; i < AL_ETH_PROTOCOLS_NUM; i++) { + reg = al_reg_read32(&adapter->ec_regs_base->epe_a[i].prot_act); + if (params->filter_proto[i] == AL_TRUE) + AL_REG_MASK_SET(reg, EC_EPE_A_PROT_ACT_DROP); + else + AL_REG_MASK_CLEAR(reg, EC_EPE_A_PROT_ACT_DROP); + al_reg_write32(&adapter->ec_regs_base->epe_a[i].prot_act, reg); + } + } + return 0; +} + +/* Configure the receive override filters */ +int al_eth_filter_override_config(struct al_hal_eth_adapter *adapter, + struct al_eth_filter_override_params *params) +{ + uint32_t reg; + + al_assert(params); /* valid params pointer */ + + if (params->filters & ~(AL_ETH_RFW_FILTER_SUPPORTED(adapter->rev_id))) { + al_err("[%s]: unsupported override filter options (0x%08x)\n", adapter->name, params->filters); + return -EINVAL; + } + + al_reg_write32_masked( + &adapter->ec_regs_base->rfw.filter, + AL_ETH_RFW_FILTER_SUPPORTED(adapter->rev_id) << 16, + params->filters << 16); + + reg = al_reg_read32(&adapter->ec_regs_base->rfw.default_or); + AL_REG_FIELD_SET(reg, EC_RFW_DEFAULT_OR_UDMA_MASK, EC_RFW_DEFAULT_OR_UDMA_SHIFT, params->udma); + AL_REG_FIELD_SET(reg, EC_RFW_DEFAULT_OR_QUEUE_MASK, EC_RFW_DEFAULT_OR_QUEUE_SHIFT, params->qid); + al_reg_write32(&adapter->ec_regs_base->rfw.default_or, reg); + return 0; +} + + + +int al_eth_switching_default_bitmap_set(struct al_hal_eth_adapter *adapter, uint8_t udma_id, uint8_t udma_uc_bitmask, + uint8_t udma_mc_bitmask,uint8_t udma_bc_bitmask) +{ + al_reg_write32(&adapter->ec_regs_base->tfw_udma[udma_id].uc_udma, udma_uc_bitmask); + al_reg_write32(&adapter->ec_regs_base->tfw_udma[udma_id].mc_udma, udma_mc_bitmask); + al_reg_write32(&adapter->ec_regs_base->tfw_udma[udma_id].bc_udma, udma_bc_bitmask); + + return 0; +} + +int al_eth_flow_control_config(struct al_hal_eth_adapter *adapter, struct al_eth_flow_control_params *params) +{ + uint32_t reg; + int i; + al_assert(params); /* valid params pointer */ + + switch(params->type){ + case AL_ETH_FLOW_CONTROL_TYPE_LINK_PAUSE: + al_dbg("[%s]: config flow control to link pause mode.\n", adapter->name); + + /* config the mac */ + if (AL_ETH_IS_1G_MAC(adapter->mac_mode)) { + /* set quanta value */ + al_reg_write32( + &adapter->mac_regs_base->mac_1g.pause_quant, + params->quanta); + al_reg_write32( + &adapter->ec_regs_base->efc.xoff_timer_1g, + params->quanta_th); + + } else if (AL_ETH_IS_10G_MAC(adapter->mac_mode) || AL_ETH_IS_25G_MAC(adapter->mac_mode)) { + /* set quanta value */ + al_reg_write32( + &adapter->mac_regs_base->mac_10g.cl01_pause_quanta, + params->quanta); + /* set quanta threshold value */ + al_reg_write32( + &adapter->mac_regs_base->mac_10g.cl01_quanta_thresh, + params->quanta_th); + } else { + /* set quanta value */ + al_eth_40g_mac_reg_write(adapter, + ETH_MAC_GEN_V3_MAC_40G_CL01_PAUSE_QUANTA_ADDR, + params->quanta); + /* set quanta threshold value */ + al_eth_40g_mac_reg_write(adapter, + ETH_MAC_GEN_V3_MAC_40G_CL01_QUANTA_THRESH_ADDR, + params->quanta_th); + } + + if (params->obay_enable == AL_TRUE) + /* Tx path FIFO, unmask pause_on from MAC when PAUSE packet received */ + al_reg_write32(&adapter->ec_regs_base->efc.ec_pause, 1); + else + al_reg_write32(&adapter->ec_regs_base->efc.ec_pause, 0); + + + /* Rx path */ + if (params->gen_enable == AL_TRUE) + /* enable generating xoff from ec fifo almost full indication in hysteresis mode */ + al_reg_write32(&adapter->ec_regs_base->efc.ec_xoff, 1 << EC_EFC_EC_XOFF_MASK_2_SHIFT); + else + al_reg_write32(&adapter->ec_regs_base->efc.ec_xoff, 0); + + if (AL_ETH_IS_1G_MAC(adapter->mac_mode)) + /* in 1G mode, enable generating xon from ec fifo in hysteresis mode*/ + al_reg_write32(&adapter->ec_regs_base->efc.xon, EC_EFC_XON_MASK_2 | EC_EFC_XON_MASK_1); + + /* set hysteresis mode thresholds */ + al_reg_write32(&adapter->ec_regs_base->efc.rx_fifo_hyst, params->rx_fifo_th_low | (params->rx_fifo_th_high << EC_EFC_RX_FIFO_HYST_TH_HIGH_SHIFT)); + + for (i = 0; i < 4; i++) { + if (params->obay_enable == AL_TRUE) + /* Tx path UDMA, unmask pause_on for all queues */ + al_reg_write32(&adapter->ec_regs_base->fc_udma[i].q_pause_0, + params->prio_q_map[i][0]); + else + al_reg_write32(&adapter->ec_regs_base->fc_udma[i].q_pause_0, 0); + + if (params->gen_enable == AL_TRUE) + /* Rx path UDMA, enable generating xoff from UDMA queue almost full indication */ + al_reg_write32(&adapter->ec_regs_base->fc_udma[i].q_xoff_0, params->prio_q_map[i][0]); + else + al_reg_write32(&adapter->ec_regs_base->fc_udma[i].q_xoff_0, 0); + } + break; + case AL_ETH_FLOW_CONTROL_TYPE_PFC: + al_dbg("[%s]: config flow control to PFC mode.\n", adapter->name); + al_assert(!AL_ETH_IS_1G_MAC(adapter->mac_mode)); /* pfc not available for RGMII mode */; + + for (i = 0; i < 4; i++) { + int prio; + for (prio = 0; prio < 8; prio++) { + if (params->obay_enable == AL_TRUE) + /* Tx path UDMA, unmask pause_on for all queues */ + al_reg_write32(&adapter->ec_regs_base->fc_udma[i].q_pause_0 + prio, + params->prio_q_map[i][prio]); + else + al_reg_write32(&adapter->ec_regs_base->fc_udma[i].q_pause_0 + prio, + 0); + + if (params->gen_enable == AL_TRUE) + al_reg_write32(&adapter->ec_regs_base->fc_udma[i].q_xoff_0 + prio, + params->prio_q_map[i][prio]); + else + al_reg_write32(&adapter->ec_regs_base->fc_udma[i].q_xoff_0 + prio, + 0); + } + } + + /* Rx path */ + /* enable generating xoff from ec fifo almost full indication in hysteresis mode */ + if (params->gen_enable == AL_TRUE) + al_reg_write32(&adapter->ec_regs_base->efc.ec_xoff, 0xFF << EC_EFC_EC_XOFF_MASK_2_SHIFT); + else + al_reg_write32(&adapter->ec_regs_base->efc.ec_xoff, 0); + + /* set hysteresis mode thresholds */ + al_reg_write32(&adapter->ec_regs_base->efc.rx_fifo_hyst, params->rx_fifo_th_low | (params->rx_fifo_th_high << EC_EFC_RX_FIFO_HYST_TH_HIGH_SHIFT)); + + if (AL_ETH_IS_10G_MAC(adapter->mac_mode) || AL_ETH_IS_25G_MAC(adapter->mac_mode)) { + /* config the 10g_mac */ + /* set quanta value (same value for all prios) */ + reg = params->quanta | (params->quanta << 16); + al_reg_write32( + &adapter->mac_regs_base->mac_10g.cl01_pause_quanta, reg); + al_reg_write32( + &adapter->mac_regs_base->mac_10g.cl23_pause_quanta, reg); + al_reg_write32( + &adapter->mac_regs_base->mac_10g.cl45_pause_quanta, reg); + al_reg_write32( + &adapter->mac_regs_base->mac_10g.cl67_pause_quanta, reg); + /* set quanta threshold value (same value for all prios) */ + reg = params->quanta_th | (params->quanta_th << 16); + al_reg_write32( + &adapter->mac_regs_base->mac_10g.cl01_quanta_thresh, reg); + al_reg_write32( + &adapter->mac_regs_base->mac_10g.cl23_quanta_thresh, reg); + al_reg_write32( + &adapter->mac_regs_base->mac_10g.cl45_quanta_thresh, reg); + al_reg_write32( + &adapter->mac_regs_base->mac_10g.cl67_quanta_thresh, reg); + + /* enable PFC in the 10g_MAC */ + reg = al_reg_read32(&adapter->mac_regs_base->mac_10g.cmd_cfg); + reg |= 1 << 19; + al_reg_write32(&adapter->mac_regs_base->mac_10g.cmd_cfg, reg); + } else { + /* config the 40g_mac */ + /* set quanta value (same value for all prios) */ + reg = params->quanta | (params->quanta << 16); + al_eth_40g_mac_reg_write(adapter, + ETH_MAC_GEN_V3_MAC_40G_CL01_PAUSE_QUANTA_ADDR, reg); + al_eth_40g_mac_reg_write(adapter, + ETH_MAC_GEN_V3_MAC_40G_CL23_PAUSE_QUANTA_ADDR, reg); + al_eth_40g_mac_reg_write(adapter, + ETH_MAC_GEN_V3_MAC_40G_CL45_PAUSE_QUANTA_ADDR, reg); + al_eth_40g_mac_reg_write(adapter, + ETH_MAC_GEN_V3_MAC_40G_CL67_PAUSE_QUANTA_ADDR, reg); + /* set quanta threshold value (same value for all prios) */ + reg = params->quanta_th | (params->quanta_th << 16); + al_eth_40g_mac_reg_write(adapter, + ETH_MAC_GEN_V3_MAC_40G_CL01_QUANTA_THRESH_ADDR, reg); + al_eth_40g_mac_reg_write(adapter, + ETH_MAC_GEN_V3_MAC_40G_CL23_QUANTA_THRESH_ADDR, reg); + al_eth_40g_mac_reg_write(adapter, + ETH_MAC_GEN_V3_MAC_40G_CL45_QUANTA_THRESH_ADDR, reg); + al_eth_40g_mac_reg_write(adapter, + ETH_MAC_GEN_V3_MAC_40G_CL67_QUANTA_THRESH_ADDR, reg); + + /* enable PFC in the 40g_MAC */ + reg = al_reg_read32(&adapter->mac_regs_base->mac_10g.cmd_cfg); + reg |= 1 << 19; + al_reg_write32(&adapter->mac_regs_base->mac_10g.cmd_cfg, reg); + reg = al_eth_40g_mac_reg_read(adapter, ETH_MAC_GEN_V3_MAC_40G_COMMAND_CONFIG_ADDR); + + reg |= ETH_MAC_GEN_V3_MAC_40G_COMMAND_CONFIG_PFC_MODE; + + al_eth_40g_mac_reg_write(adapter, ETH_MAC_GEN_V3_MAC_40G_COMMAND_CONFIG_ADDR, reg); + } + + break; + default: + al_err("[%s]: unsupported flow control type %d\n", adapter->name, params->type); + return -EINVAL; + + } + return 0; +} + +int al_eth_vlan_mod_config(struct al_hal_eth_adapter *adapter, uint8_t udma_id, uint16_t udma_etype, uint16_t vlan1_data, uint16_t vlan2_data) +{ + al_dbg("[%s]: config vlan modification registers. udma id %d.\n", adapter->name, udma_id); + + al_reg_write32(&adapter->ec_regs_base->tpm_sel[udma_id].etype, udma_etype); + al_reg_write32(&adapter->ec_regs_base->tpm_udma[udma_id].vlan_data, vlan1_data | (vlan2_data << 16)); + + return 0; +} + +int al_eth_eee_get(struct al_hal_eth_adapter *adapter, struct al_eth_eee_params *params) +{ + uint32_t reg; + + al_dbg("[%s]: getting eee.\n", adapter->name); + + reg = al_reg_read32(&adapter->ec_regs_base->eee.cfg_e); + params->enable = (reg & EC_EEE_CFG_E_ENABLE) ? AL_TRUE : AL_FALSE; + + params->tx_eee_timer = al_reg_read32(&adapter->ec_regs_base->eee.pre_cnt); + params->min_interval = al_reg_read32(&adapter->ec_regs_base->eee.post_cnt); + params->stop_cnt = al_reg_read32(&adapter->ec_regs_base->eee.stop_cnt); + + return 0; +} + + +int al_eth_eee_config(struct al_hal_eth_adapter *adapter, struct al_eth_eee_params *params) +{ + uint32_t reg; + al_dbg("[%s]: config eee.\n", adapter->name); + + if (params->enable == 0) { + al_dbg("[%s]: disable eee.\n", adapter->name); + al_reg_write32(&adapter->ec_regs_base->eee.cfg_e, 0); + return 0; + } + if (AL_ETH_IS_10G_MAC(adapter->mac_mode)) { + reg = ETH_MAC_KR_PCS_CFG_EEE_TIMER_VAL << ETH_MAC_KR_PCS_CFG_EEE_TIMER_VAL_SHIFT; + al_reg_write32_masked( + &adapter->mac_regs_base->kr.pcs_cfg, + ETH_MAC_KR_PCS_CFG_EEE_TIMER_VAL_MASK, reg); + } + + al_reg_write32(&adapter->ec_regs_base->eee.pre_cnt, params->tx_eee_timer); + al_reg_write32(&adapter->ec_regs_base->eee.post_cnt, params->min_interval); + al_reg_write32(&adapter->ec_regs_base->eee.stop_cnt, params->stop_cnt); + + reg = EC_EEE_CFG_E_MASK_EC_TMI_STOP | EC_EEE_CFG_E_MASK_MAC_EEE | + EC_EEE_CFG_E_ENABLE | + EC_EEE_CFG_E_USE_EC_TX_FIFO | EC_EEE_CFG_E_USE_EC_RX_FIFO; + + /* + * Addressing RMN: 3732 + * + * RMN description: + * When the HW get into eee mode, it can't transmit any pause packet + * (when flow control policy is enabled). + * In such case, the HW has no way to handle extreme pushback from + * the Rx_path fifos. + * + * Software flow: + * Configure RX_FIFO empty as eee mode term. + * That way, nothing will prevent pause packet transmittion in + * case of extreme pushback from the Rx_path fifos. + * + */ + + al_reg_write32(&adapter->ec_regs_base->eee.cfg_e, reg); + + return 0; +} + +/* Timestamp */ +/* prepare the adapter for doing Timestamps for Rx packets. */ +int al_eth_ts_init(struct al_hal_eth_adapter *adapter) +{ + uint32_t reg; + + /*TODO: + * return error when: + * - working in 1G mode and MACSEC enabled + * - RX completion descriptor is not 8 words + */ + reg = al_reg_read32(&adapter->ec_regs_base->gen.en_ext); + if (AL_ETH_IS_1G_MAC(adapter->mac_mode)) + reg &= ~EC_GEN_EN_EXT_PTH_1_10_SEL; + else + reg |= EC_GEN_EN_EXT_PTH_1_10_SEL; + /* + * set completion bypass so tx timestamps won't be inserted to tx cmpl + * (in order to disable unverified flow) + */ + reg |= EC_GEN_EN_EXT_PTH_COMPLETION_BYPASS; + al_reg_write32(&adapter->ec_regs_base->gen.en_ext, reg); + + /*TODO: add the following when we have updated regs file: + * reg_rfw_out_cfg_timestamp_sample_out + 0 (default) – use the timestamp from the SOP info (10G MAC) + 1 – use the timestamp from the EOP (1G MAC) (noly when MACSEC is disabled) + */ + return 0; +} + +/* read Timestamp sample value of previously transmitted packet. */ +int al_eth_tx_ts_val_get(struct al_hal_eth_adapter *adapter, uint8_t ts_index, + uint32_t *timestamp) +{ + al_assert(ts_index < AL_ETH_PTH_TX_SAMPLES_NUM); + + /* in 1G mode, only indexes 1-7 are allowed*/ + if (AL_ETH_IS_1G_MAC(adapter->mac_mode)) { + al_assert(ts_index <= 7); + al_assert(ts_index >= 1); + } + + /*TODO: check if sample is valid */ + *timestamp = al_reg_read32(&adapter->ec_regs_base->pth_db[ts_index].ts); + return 0; +} + +/* Read the systime value */ +int al_eth_pth_systime_read(struct al_hal_eth_adapter *adapter, + struct al_eth_pth_time *systime) +{ + uint32_t reg; + + /* first we must read the subseconds MSB so the seconds register will be + * shadowed + */ + reg = al_reg_read32(&adapter->ec_regs_base->pth.system_time_subseconds_msb); + systime->femto = (uint64_t)reg << 18; + reg = al_reg_read32(&adapter->ec_regs_base->pth.system_time_seconds); + systime->seconds = reg; + + return 0; +} + +/* Set the clock period to a given value. */ +int al_eth_pth_clk_period_write(struct al_hal_eth_adapter *adapter, + uint64_t clk_period) +{ + uint32_t reg; + /* first write the LSB so it will be shadowed */ + /* bits 31:14 of the clock period lsb register contains bits 17:0 of the + * period. + */ + reg = (clk_period & AL_BIT_MASK(18)) << EC_PTH_CLOCK_PERIOD_LSB_VAL_SHIFT; + al_reg_write32(&adapter->ec_regs_base->pth.clock_period_lsb, reg); + reg = clk_period >> 18; + al_reg_write32(&adapter->ec_regs_base->pth.clock_period_msb, reg); + + return 0; +} + +/* Configure the systime internal update */ +int al_eth_pth_int_update_config(struct al_hal_eth_adapter *adapter, + struct al_eth_pth_int_update_params *params) +{ + uint32_t reg; + + reg = al_reg_read32(&adapter->ec_regs_base->pth.int_update_ctrl); + if (params->enable == AL_FALSE) { + reg &= ~EC_PTH_INT_UPDATE_CTRL_INT_TRIG_EN; + } else { + reg |= EC_PTH_INT_UPDATE_CTRL_INT_TRIG_EN; + AL_REG_FIELD_SET(reg, EC_PTH_INT_UPDATE_CTRL_UPDATE_METHOD_MASK, + EC_PTH_INT_UPDATE_CTRL_UPDATE_METHOD_SHIFT, + params->method); + if (params->trigger == AL_ETH_PTH_INT_TRIG_REG_WRITE) + reg |= EC_PTH_INT_UPDATE_CTRL_UPDATE_TRIG; + else + reg &= ~EC_PTH_INT_UPDATE_CTRL_UPDATE_TRIG; + } + al_reg_write32(&adapter->ec_regs_base->pth.int_update_ctrl, reg); + return 0; +} +/* set internal update time */ +int al_eth_pth_int_update_time_set(struct al_hal_eth_adapter *adapter, + struct al_eth_pth_time *time) +{ + uint32_t reg; + + al_reg_write32(&adapter->ec_regs_base->pth.int_update_seconds, + time->seconds); + reg = time->femto & AL_BIT_MASK(18); + reg = reg << EC_PTH_INT_UPDATE_SUBSECONDS_LSB_VAL_SHIFT; + al_reg_write32(&adapter->ec_regs_base->pth.int_update_subseconds_lsb, + reg); + reg = time->femto >> 18; + al_reg_write32(&adapter->ec_regs_base->pth.int_update_subseconds_msb, + reg); + + return 0; +} + +/* Configure the systime external update */ +int al_eth_pth_ext_update_config(struct al_hal_eth_adapter *adapter, + struct al_eth_pth_ext_update_params * params) +{ + uint32_t reg; + + reg = al_reg_read32(&adapter->ec_regs_base->pth.int_update_ctrl); + AL_REG_FIELD_SET(reg, EC_PTH_INT_UPDATE_CTRL_UPDATE_METHOD_MASK, + EC_PTH_INT_UPDATE_CTRL_UPDATE_METHOD_SHIFT, + params->method); + + AL_REG_FIELD_SET(reg, EC_PTH_EXT_UPDATE_CTRL_EXT_TRIG_EN_MASK, + EC_PTH_EXT_UPDATE_CTRL_EXT_TRIG_EN_SHIFT, + params->triggers); + al_reg_write32(&adapter->ec_regs_base->pth.int_update_ctrl, reg); + return 0; +} + +/* set external update time */ +int al_eth_pth_ext_update_time_set(struct al_hal_eth_adapter *adapter, + struct al_eth_pth_time *time) +{ + uint32_t reg; + + al_reg_write32(&adapter->ec_regs_base->pth.ext_update_seconds, + time->seconds); + reg = time->femto & AL_BIT_MASK(18); + reg = reg << EC_PTH_EXT_UPDATE_SUBSECONDS_LSB_VAL_SHIFT; + al_reg_write32(&adapter->ec_regs_base->pth.ext_update_subseconds_lsb, + reg); + reg = time->femto >> 18; + al_reg_write32(&adapter->ec_regs_base->pth.ext_update_subseconds_msb, + reg); + + return 0; +}; + +/* set the read compensation delay */ +int al_eth_pth_read_compensation_set(struct al_hal_eth_adapter *adapter, + uint64_t subseconds) +{ + uint32_t reg; + + /* first write to lsb to ensure atomicity */ + reg = (subseconds & AL_BIT_MASK(18)) << EC_PTH_READ_COMPENSATION_SUBSECONDS_LSB_VAL_SHIFT; + al_reg_write32(&adapter->ec_regs_base->pth.read_compensation_subseconds_lsb, reg); + + reg = subseconds >> 18; + al_reg_write32(&adapter->ec_regs_base->pth.read_compensation_subseconds_msb, reg); + return 0; +} + +/* set the internal write compensation delay */ +int al_eth_pth_int_write_compensation_set(struct al_hal_eth_adapter *adapter, + uint64_t subseconds) +{ + uint32_t reg; + + /* first write to lsb to ensure atomicity */ + reg = (subseconds & AL_BIT_MASK(18)) << EC_PTH_INT_WRITE_COMPENSATION_SUBSECONDS_LSB_VAL_SHIFT; + al_reg_write32(&adapter->ec_regs_base->pth.int_write_compensation_subseconds_lsb, reg); + + reg = subseconds >> 18; + al_reg_write32(&adapter->ec_regs_base->pth.int_write_compensation_subseconds_msb, reg); + return 0; +} + +/* set the external write compensation delay */ +int al_eth_pth_ext_write_compensation_set(struct al_hal_eth_adapter *adapter, + uint64_t subseconds) +{ + uint32_t reg; + + /* first write to lsb to ensure atomicity */ + reg = (subseconds & AL_BIT_MASK(18)) << EC_PTH_EXT_WRITE_COMPENSATION_SUBSECONDS_LSB_VAL_SHIFT; + al_reg_write32(&adapter->ec_regs_base->pth.ext_write_compensation_subseconds_lsb, reg); + + reg = subseconds >> 18; + al_reg_write32(&adapter->ec_regs_base->pth.ext_write_compensation_subseconds_msb, reg); + return 0; +} + +/* set the sync compensation delay */ +int al_eth_pth_sync_compensation_set(struct al_hal_eth_adapter *adapter, + uint64_t subseconds) +{ + uint32_t reg; + + /* first write to lsb to ensure atomicity */ + reg = (subseconds & AL_BIT_MASK(18)) << EC_PTH_SYNC_COMPENSATION_SUBSECONDS_LSB_VAL_SHIFT; + al_reg_write32(&adapter->ec_regs_base->pth.sync_compensation_subseconds_lsb, reg); + + reg = subseconds >> 18; + al_reg_write32(&adapter->ec_regs_base->pth.sync_compensation_subseconds_msb, reg); + return 0; +} + +/* Configure an output pulse */ +int al_eth_pth_pulse_out_config(struct al_hal_eth_adapter *adapter, + struct al_eth_pth_pulse_out_params *params) +{ + uint32_t reg; + + if (params->index >= AL_ETH_PTH_PULSE_OUT_NUM) { + al_err("eth [%s] PTH out pulse index out of range\n", + adapter->name); + return -EINVAL; + } + reg = al_reg_read32(&adapter->ec_regs_base->pth_egress[params->index].trigger_ctrl); + if (params->enable == AL_FALSE) { + reg &= ~EC_PTH_EGRESS_TRIGGER_CTRL_EN; + } else { + reg |= EC_PTH_EGRESS_TRIGGER_CTRL_EN; + if (params->periodic == AL_FALSE) + reg &= ~EC_PTH_EGRESS_TRIGGER_CTRL_PERIODIC; + else + reg |= EC_PTH_EGRESS_TRIGGER_CTRL_PERIODIC; + + AL_REG_FIELD_SET(reg, EC_PTH_EGRESS_TRIGGER_CTRL_PERIOD_SUBSEC_MASK, + EC_PTH_EGRESS_TRIGGER_CTRL_PERIOD_SUBSEC_SHIFT, + params->period_us); + AL_REG_FIELD_SET(reg, EC_PTH_EGRESS_TRIGGER_CTRL_PERIOD_SEC_MASK, + EC_PTH_EGRESS_TRIGGER_CTRL_PERIOD_SEC_SHIFT, + params->period_sec); + } + al_reg_write32(&adapter->ec_regs_base->pth_egress[params->index].trigger_ctrl, reg); + + /* set trigger time */ + al_reg_write32(&adapter->ec_regs_base->pth_egress[params->index].trigger_seconds, + params->start_time.seconds); + reg = params->start_time.femto & AL_BIT_MASK(18); + reg = reg << EC_PTH_EGRESS_TRIGGER_SUBSECONDS_LSB_VAL_SHIFT; + al_reg_write32(&adapter->ec_regs_base->pth_egress[params->index].trigger_subseconds_lsb, + reg); + reg = params->start_time.femto >> 18; + al_reg_write32(&adapter->ec_regs_base->pth_egress[params->index].trigger_subseconds_msb, + reg); + + /* set pulse width */ + reg = params->pulse_width & AL_BIT_MASK(18); + reg = reg << EC_PTH_EGRESS_PULSE_WIDTH_SUBSECONDS_LSB_VAL_SHIFT; + al_reg_write32(&adapter->ec_regs_base->pth_egress[params->index].pulse_width_subseconds_lsb, reg); + + reg = params->pulse_width >> 18; + al_reg_write32(&adapter->ec_regs_base->pth_egress[params->index].pulse_width_subseconds_msb, reg); + + return 0; +} + +/** get link status */ +int al_eth_link_status_get(struct al_hal_eth_adapter *adapter, + struct al_eth_link_status *status) +{ + uint32_t reg; + + if (AL_ETH_IS_10G_MAC(adapter->mac_mode) || AL_ETH_IS_25G_MAC(adapter->mac_mode)) { + reg = al_reg_read32(&adapter->mac_regs_base->gen.mac_10g_stat); + + status->link_up = AL_TRUE; + + if (reg & (ETH_MAC_GEN_MAC_10G_STAT_LOC_FAULT | + ETH_MAC_GEN_MAC_10G_STAT_REM_FAULT)) + status->link_up = AL_FALSE; + + } else if (adapter->mac_mode == AL_ETH_MAC_MODE_SGMII) { + al_reg_write32(&adapter->mac_regs_base->sgmii.reg_addr, 1); + /* + * This register is latched low so need to read twice to get + * the current link status + */ + reg = al_reg_read32(&adapter->mac_regs_base->sgmii.reg_data); + reg = al_reg_read32(&adapter->mac_regs_base->sgmii.reg_data); + + status->link_up = AL_FALSE; + + if (reg & AL_BIT(2)) + status->link_up = AL_TRUE; + + reg = al_reg_read32(&adapter->mac_regs_base->sgmii.link_stat); + + if ((reg & AL_BIT(3)) == 0) + status->link_up = AL_FALSE; + + } else if (adapter->mac_mode == AL_ETH_MAC_MODE_RGMII) { + reg = al_reg_read32(&adapter->mac_regs_base->gen.rgmii_stat); + + status->link_up = AL_FALSE; + + if (reg & AL_BIT(4)) + status->link_up = AL_TRUE; + + } else if ((adapter->mac_mode == AL_ETH_MAC_MODE_XLG_LL_40G) || + (adapter->mac_mode == AL_ETH_MAC_MODE_XLG_LL_50G)) { + reg = al_reg_read32(&adapter->mac_regs_base->gen_v3.pcs_40g_ll_status); + + status->link_up = AL_FALSE; + + if ((reg & 0x1F) == 0x1F) { + reg = al_reg_read32(&adapter->mac_regs_base->gen_v3.mac_40g_ll_status); + if ((reg & (ETH_MAC_GEN_V3_MAC_40G_LL_STATUS_REM_FAULT | +ETH_MAC_GEN_V3_MAC_40G_LL_STATUS_LOC_FAULT)) == 0) + status->link_up = AL_TRUE; + } + + } else { + /* not implemented yet */ + return -EPERM; + } + + al_dbg("[%s]: mac %s port. link_status: %s.\n", adapter->name, + al_eth_mac_mode_str(adapter->mac_mode), + (status->link_up == AL_TRUE) ? "LINK_UP" : "LINK_DOWN"); + + return 0; +} + +/** set LED mode and value */ +int al_eth_led_set(struct al_hal_eth_adapter *adapter, al_bool link_is_up) +{ + uint32_t reg = 0; + uint32_t mode = ETH_MAC_GEN_LED_CFG_SEL_DEFAULT_REG; + + if (link_is_up) + mode = ETH_MAC_GEN_LED_CFG_SEL_LINK_ACTIVITY; + + AL_REG_FIELD_SET(reg, ETH_MAC_GEN_LED_CFG_SEL_MASK, + ETH_MAC_GEN_LED_CFG_SEL_SHIFT, mode); + + AL_REG_FIELD_SET(reg, ETH_MAC_GEN_LED_CFG_BLINK_TIMER_MASK, + ETH_MAC_GEN_LED_CFG_BLINK_TIMER_SHIFT, + ETH_MAC_GEN_LED_CFG_BLINK_TIMER_VAL); + + AL_REG_FIELD_SET(reg, ETH_MAC_GEN_LED_CFG_ACT_TIMER_MASK, + ETH_MAC_GEN_LED_CFG_ACT_TIMER_SHIFT, + ETH_MAC_GEN_LED_CFG_ACT_TIMER_VAL); + + al_reg_write32(&adapter->mac_regs_base->gen.led_cfg, reg); + + return 0; +} + +/* get statistics */ +int al_eth_mac_stats_get(struct al_hal_eth_adapter *adapter, struct al_eth_mac_stats *stats) +{ + al_assert(stats); + + if (AL_ETH_IS_1G_MAC(adapter->mac_mode)) { + void __iomem *mac_1g_regs_base = &adapter->mac_regs_base->mac_1g; + + stats->ifInUcastPkts = al_reg_read32((void *)((uint32_t)mac_1g_regs_base + 0x90)); + stats->ifInMulticastPkts = al_reg_read32((void *)((uint32_t)mac_1g_regs_base + 0x94)); + stats->ifInBroadcastPkts = al_reg_read32((void *)((uint32_t)mac_1g_regs_base + 0x98)); + stats->etherStatsPkts = al_reg_read32((void *)((uint32_t)mac_1g_regs_base + 0xb4)); + stats->ifOutUcastPkts = al_reg_read32((void *)((uint32_t)mac_1g_regs_base + 0xa0)); + stats->ifOutMulticastPkts = al_reg_read32((void *)((uint32_t)mac_1g_regs_base + 0xa4)); + stats->ifOutBroadcastPkts = al_reg_read32((void *)((uint32_t)mac_1g_regs_base + 0xa8)); + stats->ifInErrors = al_reg_read32((void *)((uint32_t)mac_1g_regs_base + 0x88)); + stats->ifOutErrors = al_reg_read32((void *)((uint32_t)mac_1g_regs_base + 0x8c)); + + stats->aFramesReceivedOK = al_reg_read32((void *)((uint32_t)mac_1g_regs_base + 0x6c)); + stats->aFramesTransmittedOK = al_reg_read32((void *)((uint32_t)mac_1g_regs_base + 0x68)); + + stats->aOctetsReceivedOK = al_reg_read32((void *)((uint32_t)mac_1g_regs_base + 0x7c)); + stats->aOctetsTransmittedOK = al_reg_read32((void *)((uint32_t)mac_1g_regs_base + 0x78)); + + stats->etherStatsUndersizePkts = al_reg_read32((void *)((uint32_t)mac_1g_regs_base + 0xB8)); + stats->etherStatsFragments = al_reg_read32((void *)((uint32_t)mac_1g_regs_base + 0xE0)); + stats->etherStatsJabbers = al_reg_read32((void *)((uint32_t)mac_1g_regs_base + 0xDC)); + stats->etherStatsOversizePkts = al_reg_read32((void *)((uint32_t)mac_1g_regs_base + 0xBC)); + + stats->aFrameCheckSequenceErrors = al_reg_read32((void *)((uint32_t)mac_1g_regs_base + 0x70)); + stats->aAlignmentErrors = al_reg_read32((void *)((uint32_t)mac_1g_regs_base + 0x74)); + stats->etherStatsDropEvents = al_reg_read32((void *)((uint32_t)mac_1g_regs_base + 0xAC)); + + stats->aPAUSEMACCtrlFramesTransmitted = al_reg_read32((void *)((uint32_t)mac_1g_regs_base + 0x80)); + stats->aPAUSEMACCtrlFramesReceived = al_reg_read32((void *)((uint32_t)mac_1g_regs_base + 0x84)); + stats->aFrameTooLongErrors = 0; /* N/A */ + stats->aInRangeLengthErrors = 0; /* N/A */ + stats->VLANTransmittedOK = 0; /* N/A */ + stats->VLANReceivedOK = 0; /* N/A */ + stats->etherStatsOctets = al_reg_read32((void *)((uint32_t)mac_1g_regs_base + 0xB0)); + + stats->etherStatsPkts64Octets = al_reg_read32((void *)((uint32_t)mac_1g_regs_base + 0xC0)); + stats->etherStatsPkts65to127Octets = al_reg_read32((void *)((uint32_t)mac_1g_regs_base + 0xC4)); + stats->etherStatsPkts128to255Octets = al_reg_read32((void *)((uint32_t)mac_1g_regs_base + 0xC8)); + stats->etherStatsPkts256to511Octets = al_reg_read32((void *)((uint32_t)mac_1g_regs_base + 0xCC)); + stats->etherStatsPkts512to1023Octets = al_reg_read32((void *)((uint32_t)mac_1g_regs_base + 0xD0)); + stats->etherStatsPkts1024to1518Octets = al_reg_read32((void *)((uint32_t)mac_1g_regs_base + 0xD4)); + stats->etherStatsPkts1519toX = al_reg_read32((void *)((uint32_t)mac_1g_regs_base + 0xD8)); + } else if (AL_ETH_IS_10G_MAC(adapter->mac_mode) || AL_ETH_IS_25G_MAC(adapter->mac_mode)) { + if (adapter->rev_id < AL_ETH_REV_ID_3) { + void __iomem *mac_10g_regs_base = &adapter->mac_regs_base->mac_10g; + uint64_t octets; + + stats->ifInUcastPkts = al_reg_read32((void *)((uint32_t)mac_10g_regs_base + 0xE0)); + stats->ifInMulticastPkts = al_reg_read32((void *)((uint32_t)mac_10g_regs_base + 0xE8)); + stats->ifInBroadcastPkts = al_reg_read32((void *)((uint32_t)mac_10g_regs_base + 0xF0)); + stats->etherStatsPkts = al_reg_read32((void *)((uint32_t)mac_10g_regs_base + 0x130)); + stats->ifOutUcastPkts = al_reg_read32((void *)((uint32_t)mac_10g_regs_base + 0x108)); + stats->ifOutMulticastPkts = al_reg_read32((void *)((uint32_t)mac_10g_regs_base + 0x110)); + stats->ifOutBroadcastPkts = al_reg_read32((void *)((uint32_t)mac_10g_regs_base + 0x118)); + stats->ifInErrors = al_reg_read32((void *)((uint32_t)mac_10g_regs_base + 0x190)); + stats->ifOutErrors = al_reg_read32((void *)((uint32_t)mac_10g_regs_base + 0xf8)); + + stats->aFramesReceivedOK = al_reg_read32((void *)((uint32_t)mac_10g_regs_base + 0x88)); + stats->aFramesTransmittedOK = al_reg_read32((void *)((uint32_t)mac_10g_regs_base + 0x80)); + /* aOctetsReceivedOK = ifInOctets - 18 * aFramesReceivedOK - 4 * VLANReceivedOK */ + octets = al_reg_read32((void *)((uint32_t)mac_10g_regs_base + 0xD8)); + octets |= (uint64_t)(al_reg_read32((void *)((uint32_t)mac_10g_regs_base + 0xDC))) << 32; + octets -= 18 * stats->aFramesReceivedOK; + octets -= 4 * al_reg_read32((void *)((uint32_t)mac_10g_regs_base + 0xC8)); + stats->aOctetsReceivedOK = octets; + + /* aOctetsTransmittedOK = ifOutOctets - 18 * aFramesTransmittedOK - 4 * VLANTransmittedOK */ + octets = al_reg_read32((void *)((uint32_t)mac_10g_regs_base + 0xD0)); + octets |= (uint64_t)(al_reg_read32((void *)((uint32_t)mac_10g_regs_base + 0xD4))) << 32; + octets -= 18 * stats->aFramesTransmittedOK; + octets -= 4 * al_reg_read32((void *)((uint32_t)mac_10g_regs_base + 0xC0)); + stats->aOctetsTransmittedOK = octets; + + stats->etherStatsUndersizePkts = al_reg_read32((void *)((uint32_t)mac_10g_regs_base + 0x138)); + stats->etherStatsFragments = al_reg_read32((void *)((uint32_t)mac_10g_regs_base + 0x188)); + stats->etherStatsJabbers = al_reg_read32((void *)((uint32_t)mac_10g_regs_base + 0x180)); + stats->etherStatsOversizePkts = al_reg_read32((void *)((uint32_t)mac_10g_regs_base + 0x178)); + + stats->aFrameCheckSequenceErrors = al_reg_read32((void *)((uint32_t)mac_10g_regs_base + 0x90)); + stats->aAlignmentErrors = al_reg_read32((void *)((uint32_t)mac_10g_regs_base + 0x98)); + stats->etherStatsDropEvents = al_reg_read32((void *)((uint32_t)mac_10g_regs_base + 0x120)); + + stats->aPAUSEMACCtrlFramesTransmitted = al_reg_read32((void *)((uint32_t)mac_10g_regs_base + 0xA0)); + stats->aPAUSEMACCtrlFramesReceived = al_reg_read32((void *)((uint32_t)mac_10g_regs_base + 0xA8)); + stats->aFrameTooLongErrors = al_reg_read32((void *)((uint32_t)mac_10g_regs_base + 0xB0)); + stats->aInRangeLengthErrors = al_reg_read32((void *)((uint32_t)mac_10g_regs_base + 0xB8)); + stats->VLANTransmittedOK = al_reg_read32((void *)((uint32_t)mac_10g_regs_base + 0xC0)); + stats->VLANReceivedOK = al_reg_read32((void *)((uint32_t)mac_10g_regs_base + 0xC8)); + stats->etherStatsOctets = al_reg_read32((void *)((uint32_t)mac_10g_regs_base + 0x128)); + + stats->etherStatsPkts64Octets = al_reg_read32((void *)((uint32_t)mac_10g_regs_base + 0x140)); + stats->etherStatsPkts65to127Octets = al_reg_read32((void *)((uint32_t)mac_10g_regs_base + 0x148)); + stats->etherStatsPkts128to255Octets = al_reg_read32((void *)((uint32_t)mac_10g_regs_base + 0x150)); + stats->etherStatsPkts256to511Octets = al_reg_read32((void *)((uint32_t)mac_10g_regs_base + 0x158)); + stats->etherStatsPkts512to1023Octets = al_reg_read32((void *)((uint32_t)mac_10g_regs_base + 0x160)); + stats->etherStatsPkts1024to1518Octets = al_reg_read32((void *)((uint32_t)mac_10g_regs_base + 0x168)); + stats->etherStatsPkts1519toX = al_reg_read32((void *)((uint32_t)mac_10g_regs_base + 0x170)); + } else { + void __iomem *mac_10g_regs_base = &adapter->mac_regs_base->mac_10g; + uint64_t octets; + /* TODO - change to 64 bit */ + stats->ifInUcastPkts = al_reg_read32((void *)((uint32_t)mac_10g_regs_base + 0x140)); + stats->ifInMulticastPkts = al_reg_read32((void *)((uint32_t)mac_10g_regs_base + 0x148)); + stats->ifInBroadcastPkts = al_reg_read32((void *)((uint32_t)mac_10g_regs_base + 0x150)); + stats->etherStatsPkts = al_reg_read32((void *)((uint32_t)mac_10g_regs_base + 0x160)); + stats->ifOutUcastPkts = al_reg_read32((void *)((uint32_t)mac_10g_regs_base + 0x240)); + stats->ifOutMulticastPkts = al_reg_read32((void *)((uint32_t)mac_10g_regs_base + 0x248)); + stats->ifOutBroadcastPkts = al_reg_read32((void *)((uint32_t)mac_10g_regs_base + 0x250)); + stats->ifInErrors = al_reg_read32((void *)((uint32_t)mac_10g_regs_base + 0x138)); + stats->ifOutErrors = al_reg_read32((void *)((uint32_t)mac_10g_regs_base + 0x238)); + + stats->aFramesReceivedOK = al_reg_read32((void *)((uint32_t)mac_10g_regs_base + 0x120)); /*frames_ok*/ + stats->aFramesTransmittedOK = al_reg_read32((void *)((uint32_t)mac_10g_regs_base + 0x220)); /*frames_ok*/ + /* aOctetsReceivedOK = ifInOctets - 18 * aFramesReceivedOK - 4 * VLANReceivedOK */ + octets = al_reg_read32((void *)((uint32_t)mac_10g_regs_base + 0x108)); /*OctetsOK*/ + octets |= (uint64_t)(al_reg_read32((void *)((uint32_t)mac_10g_regs_base + 0x10C))) << 32; + octets -= 18 * stats->aFramesReceivedOK; + octets -= 4 * al_reg_read32((void *)((uint32_t)mac_10g_regs_base + 0x130)); /*VLANOK*/ + stats->aOctetsReceivedOK = octets; + + /* aOctetsTransmittedOK = ifOutOctets - 18 * aFramesTransmittedOK - 4 * VLANTransmittedOK */ + octets = al_reg_read32((void *)((uint32_t)mac_10g_regs_base + 0x208)); /*OctetsOK*/ + octets |= (uint64_t)(al_reg_read32((void *)((uint32_t)mac_10g_regs_base + 0x20c))) << 32; + octets -= 18 * stats->aFramesTransmittedOK; + octets -= 4 * al_reg_read32((void *)((uint32_t)mac_10g_regs_base + 0x230)); /*VLANOK*/ + stats->aOctetsTransmittedOK = octets; + + stats->etherStatsUndersizePkts = al_reg_read32((void *)((uint32_t)mac_10g_regs_base + 0x168)); + stats->etherStatsFragments = al_reg_read32((void *)((uint32_t)mac_10g_regs_base + 0x1b8)); + stats->etherStatsJabbers = al_reg_read32((void *)((uint32_t)mac_10g_regs_base + 0x1b0)); + stats->etherStatsOversizePkts = al_reg_read32((void *)((uint32_t)mac_10g_regs_base + 0x1a8)); + + stats->aFrameCheckSequenceErrors = al_reg_read32((void *)((uint32_t)mac_10g_regs_base + 0x128)); /* CRCErrors */ + /* stats->aAlignmentErrors = al_reg_read32((void *)((uint32_t)mac_10g_regs_base + 0x98)); */ /* not implemented */ + stats->etherStatsDropEvents = al_reg_read32((void *)((uint32_t)mac_10g_regs_base + 0x158)); + } + } else { + uint64_t octets; + /* TODO - change to 64 bit */ + stats->ifInUcastPkts = al_eth_40g_mac_reg_read(adapter, 0x140); + stats->ifInMulticastPkts = al_eth_40g_mac_reg_read(adapter, 0x148); + stats->ifInBroadcastPkts = al_eth_40g_mac_reg_read(adapter, 0x150); + stats->etherStatsPkts = al_eth_40g_mac_reg_read(adapter, 0x160); + stats->ifOutUcastPkts = al_eth_40g_mac_reg_read(adapter, 0x240); + stats->ifOutMulticastPkts = al_eth_40g_mac_reg_read(adapter, 0x248); + stats->ifOutBroadcastPkts = al_eth_40g_mac_reg_read(adapter, 0x250); + stats->ifInErrors = al_eth_40g_mac_reg_read(adapter, 0x138); + stats->ifOutErrors = al_eth_40g_mac_reg_read(adapter, 0x238); + stats->aFramesReceivedOK = al_eth_40g_mac_reg_read(adapter, 0x120); + stats->aFramesTransmittedOK = al_eth_40g_mac_reg_read(adapter, 0x220); + + /* aOctetsReceivedOK = ifInOctets - 18 * aFramesReceivedOK - 4 * VLANReceivedOK */ + octets = al_eth_40g_mac_reg_read(adapter, 0x100); + octets |= (uint64_t)(al_eth_40g_mac_reg_read(adapter, 0x104)) << 32; + octets -= 18 * stats->aFramesReceivedOK; + octets -= 4 * al_eth_40g_mac_reg_read(adapter, 0x130); /*VLANOK*/ + stats->aOctetsTransmittedOK = octets; + + /* aOctetsTransmittedOK = ifOutOctets - 18 * aFramesTransmittedOK - 4 * VLANTransmittedOK */ + octets = al_eth_40g_mac_reg_read(adapter, 0x200); + octets |= (uint64_t)(al_eth_40g_mac_reg_read(adapter, 0x204)) << 32; + octets -= 18 * stats->aFramesReceivedOK; + octets -= 4 * al_eth_40g_mac_reg_read(adapter, 0x230); /*VLANOK*/ + stats->aOctetsReceivedOK = octets; + + stats->etherStatsUndersizePkts = al_eth_40g_mac_reg_read(adapter, 0x168); + stats->etherStatsFragments = al_eth_40g_mac_reg_read(adapter, 0x1b8); + stats->etherStatsJabbers = al_eth_40g_mac_reg_read(adapter, 0x1b0); + stats->etherStatsOversizePkts = al_eth_40g_mac_reg_read(adapter, 0x1a8); + stats->aFrameCheckSequenceErrors = al_eth_40g_mac_reg_read(adapter, 0x128); + stats->aAlignmentErrors = al_eth_40g_mac_reg_read(adapter, 0x110); + stats->etherStatsDropEvents = al_eth_40g_mac_reg_read(adapter, 0x158); + } + + stats->eee_in = al_reg_read32(&adapter->mac_regs_base->stat.eee_in); + stats->eee_out = al_reg_read32(&adapter->mac_regs_base->stat.eee_out); + +/* stats->etherStatsPkts = 1; */ + return 0; +} + +/** +* read ec_stat_counters +*/ +int al_eth_ec_stats_get(struct al_hal_eth_adapter *adapter, struct al_eth_ec_stats *stats) +{ + al_assert(stats); + stats->faf_in_rx_pkt = al_reg_read32(&adapter->ec_regs_base->stat.faf_in_rx_pkt); + stats->faf_in_rx_short = al_reg_read32(&adapter->ec_regs_base->stat.faf_in_rx_short); + stats->faf_in_rx_long = al_reg_read32(&adapter->ec_regs_base->stat.faf_in_rx_long); + stats->faf_out_rx_pkt = al_reg_read32(&adapter->ec_regs_base->stat.faf_out_rx_pkt); + stats->faf_out_rx_short = al_reg_read32(&adapter->ec_regs_base->stat.faf_out_rx_short); + stats->faf_out_rx_long = al_reg_read32(&adapter->ec_regs_base->stat.faf_out_rx_long); + stats->faf_out_drop = al_reg_read32(&adapter->ec_regs_base->stat.faf_out_drop); + stats->rxf_in_rx_pkt = al_reg_read32(&adapter->ec_regs_base->stat.rxf_in_rx_pkt); + stats->rxf_in_fifo_err = al_reg_read32(&adapter->ec_regs_base->stat.rxf_in_fifo_err); + stats->lbf_in_rx_pkt = al_reg_read32(&adapter->ec_regs_base->stat.lbf_in_rx_pkt); + stats->lbf_in_fifo_err = al_reg_read32(&adapter->ec_regs_base->stat.lbf_in_fifo_err); + stats->rxf_out_rx_1_pkt = al_reg_read32(&adapter->ec_regs_base->stat.rxf_out_rx_1_pkt); + stats->rxf_out_rx_2_pkt = al_reg_read32(&adapter->ec_regs_base->stat.rxf_out_rx_2_pkt); + stats->rxf_out_drop_1_pkt = al_reg_read32(&adapter->ec_regs_base->stat.rxf_out_drop_1_pkt); + stats->rxf_out_drop_2_pkt = al_reg_read32(&adapter->ec_regs_base->stat.rxf_out_drop_2_pkt); + stats->rpe_1_in_rx_pkt = al_reg_read32(&adapter->ec_regs_base->stat.rpe_1_in_rx_pkt); + stats->rpe_1_out_rx_pkt = al_reg_read32(&adapter->ec_regs_base->stat.rpe_1_out_rx_pkt); + stats->rpe_2_in_rx_pkt = al_reg_read32(&adapter->ec_regs_base->stat.rpe_2_in_rx_pkt); + stats->rpe_2_out_rx_pkt = al_reg_read32(&adapter->ec_regs_base->stat.rpe_2_out_rx_pkt); + stats->rpe_3_in_rx_pkt = al_reg_read32(&adapter->ec_regs_base->stat.rpe_3_in_rx_pkt); + stats->rpe_3_out_rx_pkt = al_reg_read32(&adapter->ec_regs_base->stat.rpe_3_out_rx_pkt); + stats->tpe_in_tx_pkt = al_reg_read32(&adapter->ec_regs_base->stat.tpe_in_tx_pkt); + stats->tpe_out_tx_pkt = al_reg_read32(&adapter->ec_regs_base->stat.tpe_out_tx_pkt); + stats->tpm_tx_pkt = al_reg_read32(&adapter->ec_regs_base->stat.tpm_tx_pkt); + stats->tfw_in_tx_pkt = al_reg_read32(&adapter->ec_regs_base->stat.tfw_in_tx_pkt); + stats->tfw_out_tx_pkt = al_reg_read32(&adapter->ec_regs_base->stat.tfw_out_tx_pkt); + stats->rfw_in_rx_pkt = al_reg_read32(&adapter->ec_regs_base->stat.rfw_in_rx_pkt); + stats->rfw_in_vlan_drop = al_reg_read32(&adapter->ec_regs_base->stat.rfw_in_vlan_drop); + stats->rfw_in_parse_drop = al_reg_read32(&adapter->ec_regs_base->stat.rfw_in_parse_drop); + stats->rfw_in_mc = al_reg_read32(&adapter->ec_regs_base->stat.rfw_in_mc); + stats->rfw_in_bc = al_reg_read32(&adapter->ec_regs_base->stat.rfw_in_bc); + stats->rfw_in_vlan_exist = al_reg_read32(&adapter->ec_regs_base->stat.rfw_in_vlan_exist); + stats->rfw_in_vlan_nexist = al_reg_read32(&adapter->ec_regs_base->stat.rfw_in_vlan_nexist); + stats->rfw_in_mac_drop = al_reg_read32(&adapter->ec_regs_base->stat.rfw_in_mac_drop); + stats->rfw_in_mac_ndet_drop = al_reg_read32(&adapter->ec_regs_base->stat.rfw_in_mac_ndet_drop); + stats->rfw_in_ctrl_drop = al_reg_read32(&adapter->ec_regs_base->stat.rfw_in_ctrl_drop); + stats->rfw_in_prot_i_drop = al_reg_read32(&adapter->ec_regs_base->stat.rfw_in_prot_i_drop); + stats->eee_in = al_reg_read32(&adapter->ec_regs_base->stat.eee_in); + return 0; +} + +/** + * read per_udma_counters + */ +int al_eth_ec_stat_udma_get(struct al_hal_eth_adapter *adapter, uint8_t idx, struct al_eth_ec_stat_udma *stats) +{ + + al_assert(idx <= 3); /*valid udma_id*/ + al_assert(stats); + stats->rfw_out_rx_pkt = al_reg_read32(&adapter->ec_regs_base->stat_udma[idx].rfw_out_rx_pkt); + stats->rfw_out_drop = al_reg_read32(&adapter->ec_regs_base->stat_udma[idx].rfw_out_drop); + stats->msw_in_rx_pkt = al_reg_read32(&adapter->ec_regs_base->stat_udma[idx].msw_in_rx_pkt); + stats->msw_drop_q_full = al_reg_read32(&adapter->ec_regs_base->stat_udma[idx].msw_drop_q_full); + stats->msw_drop_sop = al_reg_read32(&adapter->ec_regs_base->stat_udma[idx].msw_drop_sop); + stats->msw_drop_eop = al_reg_read32(&adapter->ec_regs_base->stat_udma[idx].msw_drop_eop); + stats->msw_wr_eop = al_reg_read32(&adapter->ec_regs_base->stat_udma[idx].msw_wr_eop); + stats->msw_out_rx_pkt = al_reg_read32(&adapter->ec_regs_base->stat_udma[idx].msw_out_rx_pkt); + stats->tso_no_tso_pkt = al_reg_read32(&adapter->ec_regs_base->stat_udma[idx].tso_no_tso_pkt); + stats->tso_tso_pkt = al_reg_read32(&adapter->ec_regs_base->stat_udma[idx].tso_tso_pkt); + stats->tso_seg_pkt = al_reg_read32(&adapter->ec_regs_base->stat_udma[idx].tso_seg_pkt); + stats->tso_pad_pkt = al_reg_read32(&adapter->ec_regs_base->stat_udma[idx].tso_pad_pkt); + stats->tpm_tx_spoof = al_reg_read32(&adapter->ec_regs_base->stat_udma[idx].tpm_tx_spoof); + stats->tmi_in_tx_pkt = al_reg_read32(&adapter->ec_regs_base->stat_udma[idx].tmi_in_tx_pkt); + stats->tmi_out_to_mac = al_reg_read32(&adapter->ec_regs_base->stat_udma[idx].tmi_out_to_mac); + stats->tmi_out_to_rx = al_reg_read32(&adapter->ec_regs_base->stat_udma[idx].tmi_out_to_rx); + stats->tx_q0_bytes = al_reg_read32(&adapter->ec_regs_base->stat_udma[idx].tx_q0_bytes); + stats->tx_q1_bytes = al_reg_read32(&adapter->ec_regs_base->stat_udma[idx].tx_q1_bytes); + stats->tx_q2_bytes = al_reg_read32(&adapter->ec_regs_base->stat_udma[idx].tx_q2_bytes); + stats->tx_q3_bytes = al_reg_read32(&adapter->ec_regs_base->stat_udma[idx].tx_q3_bytes); + stats->tx_q0_pkts = al_reg_read32(&adapter->ec_regs_base->stat_udma[idx].tx_q0_pkts); + stats->tx_q1_pkts = al_reg_read32(&adapter->ec_regs_base->stat_udma[idx].tx_q1_pkts); + stats->tx_q2_pkts = al_reg_read32(&adapter->ec_regs_base->stat_udma[idx].tx_q2_pkts); + stats->tx_q3_pkts = al_reg_read32(&adapter->ec_regs_base->stat_udma[idx].tx_q3_pkts); + return 0; +} + +/* Traffic control */ + + +int al_eth_flr_rmn(int (* pci_read_config_u32)(void *handle, int where, uint32_t *val), + int (* pci_write_config_u32)(void *handle, int where, uint32_t val), + void *handle, + void __iomem *mac_base) +{ + struct al_eth_mac_regs __iomem *mac_regs_base = + (struct al_eth_mac_regs __iomem *)mac_base; + uint32_t cfg_reg_store[6]; + uint32_t reg; + uint32_t mux_sel; + int i = 0; + + (*pci_read_config_u32)(handle, AL_ADAPTER_GENERIC_CONTROL_0, ®); + + /* reset 1G mac */ + AL_REG_MASK_SET(reg, AL_ADAPTER_GENERIC_CONTROL_0_ETH_RESET_1GMAC); + (*pci_write_config_u32)(handle, AL_ADAPTER_GENERIC_CONTROL_0, reg); + al_udelay(1000); + /* don't reset 1G mac */ + AL_REG_MASK_CLEAR(reg, AL_ADAPTER_GENERIC_CONTROL_0_ETH_RESET_1GMAC); + /* prevent 1G mac reset on FLR */ + AL_REG_MASK_CLEAR(reg, AL_ADAPTER_GENERIC_CONTROL_0_ETH_RESET_1GMAC_ON_FLR); + /* prevent adapter reset */ + (*pci_write_config_u32)(handle, AL_ADAPTER_GENERIC_CONTROL_0, reg); + + mux_sel = al_reg_read32(&mac_regs_base->gen.mux_sel); + + /* save pci register that get reset due to flr*/ + (*pci_read_config_u32)(handle, AL_PCI_COMMAND, &cfg_reg_store[i++]); + (*pci_read_config_u32)(handle, 0xC, &cfg_reg_store[i++]); + (*pci_read_config_u32)(handle, 0x10, &cfg_reg_store[i++]); + (*pci_read_config_u32)(handle, 0x18, &cfg_reg_store[i++]); + (*pci_read_config_u32)(handle, 0x20, &cfg_reg_store[i++]); + (*pci_read_config_u32)(handle, 0x110, &cfg_reg_store[i++]); + + /* do flr */ + (*pci_write_config_u32)(handle, AL_PCI_EXP_CAP_BASE + AL_PCI_EXP_DEVCTL, AL_PCI_EXP_DEVCTL_BCR_FLR); + al_udelay(1000); + /* restore command */ + i = 0; + (*pci_write_config_u32)(handle, AL_PCI_COMMAND, cfg_reg_store[i++]); + (*pci_write_config_u32)(handle, 0xC, cfg_reg_store[i++]); + (*pci_write_config_u32)(handle, 0x10, cfg_reg_store[i++]); + (*pci_write_config_u32)(handle, 0x18, cfg_reg_store[i++]); + (*pci_write_config_u32)(handle, 0x20, cfg_reg_store[i++]); + (*pci_write_config_u32)(handle, 0x110, cfg_reg_store[i++]); + + al_reg_write32_masked(&mac_regs_base->gen.mux_sel, ETH_MAC_GEN_MUX_SEL_KR_IN_MASK, mux_sel); + + /* set SGMII clock to 125MHz */ + al_reg_write32(mac_base + 0xB08, 0x03320501); + + /* reset 1G mac */ + AL_REG_MASK_SET(reg, AL_ADAPTER_GENERIC_CONTROL_0_ETH_RESET_1GMAC); + (*pci_write_config_u32)(handle, AL_ADAPTER_GENERIC_CONTROL_0, reg); + + al_udelay(1000); + + /* clear 1G mac reset */ + AL_REG_MASK_CLEAR(reg, AL_ADAPTER_GENERIC_CONTROL_0_ETH_RESET_1GMAC); + (*pci_write_config_u32)(handle, AL_ADAPTER_GENERIC_CONTROL_0, reg); + + /* reset SGMII mac clock to default */ + al_reg_write32(mac_base + 0xB08, 0x00320501); + al_udelay(1000); + /* reset async fifo */ + reg = al_reg_read32((void*)((uint32_t)mac_base + 0x95c)); + AL_REG_MASK_SET(reg, 0xF0); + al_reg_write32((void*)((uint32_t)mac_base + 0x95c), reg); + reg = al_reg_read32((void*)((uint32_t)mac_base + 0x95c)); + AL_REG_MASK_CLEAR(reg, 0xF0); + al_reg_write32((void*)((uint32_t)mac_base + 0x95c), reg); + + return 0; +} + +int al_eth_flr_rmn_restore_params(int (* pci_read_config_u32)(void *handle, int where, uint32_t *val), + int (* pci_write_config_u32)(void *handle, int where, uint32_t val), + void *handle, + void __iomem *mac_base, + void __iomem *ec_base, + int mac_addresses_num + ) +{ + struct al_eth_board_params params = { .media_type = 0 }; + uint8_t mac_addr[6]; + int rc; + + /* not implemented yet */ + if (mac_addresses_num > 1) + return -EPERM; + + /* save board params so we restore it after reset */ + al_eth_board_params_get(mac_base, ¶ms); + al_eth_mac_addr_read(ec_base, 0, mac_addr); + + rc = al_eth_flr_rmn(pci_read_config_u32, pci_write_config_u32, handle, mac_base); + al_eth_board_params_set(mac_base, ¶ms); + al_eth_mac_addr_store(ec_base, 0, mac_addr); + + return rc; +} + +/* board params register 1 */ +#define AL_HAL_ETH_MEDIA_TYPE_MASK (AL_FIELD_MASK(3, 0)) +#define AL_HAL_ETH_MEDIA_TYPE_SHIFT 0 +#define AL_HAL_ETH_EXT_PHY_SHIFT 4 +#define AL_HAL_ETH_PHY_ADDR_MASK (AL_FIELD_MASK(9, 5)) +#define AL_HAL_ETH_PHY_ADDR_SHIFT 5 +#define AL_HAL_ETH_SFP_EXIST_SHIFT 10 +#define AL_HAL_ETH_AN_ENABLE_SHIFT 11 +#define AL_HAL_ETH_KR_LT_ENABLE_SHIFT 12 +#define AL_HAL_ETH_KR_FEC_ENABLE_SHIFT 13 +#define AL_HAL_ETH_MDIO_FREQ_MASK (AL_FIELD_MASK(15, 14)) +#define AL_HAL_ETH_MDIO_FREQ_SHIFT 14 +#define AL_HAL_ETH_I2C_ADAPTER_ID_MASK (AL_FIELD_MASK(19, 16)) +#define AL_HAL_ETH_I2C_ADAPTER_ID_SHIFT 16 +#define AL_HAL_ETH_EXT_PHY_IF_MASK (AL_FIELD_MASK(21, 20)) +#define AL_HAL_ETH_EXT_PHY_IF_SHIFT 20 +#define AL_HAL_ETH_AUTO_NEG_MODE_SHIFT 22 +#define AL_HAL_ETH_SERDES_GRP_MASK (AL_FIELD_MASK(26, 25)) +#define AL_HAL_ETH_SERDES_GRP_SHIFT 25 +#define AL_HAL_ETH_SERDES_LANE_MASK (AL_FIELD_MASK(28, 27)) +#define AL_HAL_ETH_SERDES_LANE_SHIFT 27 +#define AL_HAL_ETH_REF_CLK_FREQ_MASK (AL_FIELD_MASK(31, 29)) +#define AL_HAL_ETH_REF_CLK_FREQ_SHIFT 29 + +/* board params register 2 */ +#define AL_HAL_ETH_DONT_OVERRIDE_SERDES_SHIFT 0 +#define AL_HAL_ETH_1000_BASE_X_SHIFT 1 +#define AL_HAL_ETH_1G_AN_DISABLE_SHIFT 2 +#define AL_HAL_ETH_1G_SPEED_MASK (AL_FIELD_MASK(4, 3)) +#define AL_HAL_ETH_1G_SPEED_SHIFT 3 +#define AL_HAL_ETH_1G_HALF_DUPLEX_SHIFT 5 +#define AL_HAL_ETH_1G_FC_DISABLE_SHIFT 6 +#define AL_HAL_ETH_RETIMER_EXIST_SHIFT 7 +#define AL_HAL_ETH_RETIMER_BUS_ID_MASK (AL_FIELD_MASK(11, 8)) +#define AL_HAL_ETH_RETIMER_BUS_ID_SHIFT 8 +#define AL_HAL_ETH_RETIMER_I2C_ADDR_MASK (AL_FIELD_MASK(18, 12)) +#define AL_HAL_ETH_RETIMER_I2C_ADDR_SHIFT 12 +#define AL_HAL_ETH_RETIMER_CHANNEL_SHIFT 19 +#define AL_HAL_ETH_DAC_LENGTH_MASK (AL_FIELD_MASK(23, 20)) +#define AL_HAL_ETH_DAC_LENGTH_SHIFT 20 +#define AL_HAL_ETH_DAC_SHIFT 24 +#define AL_HAL_ETH_RETIMER_TYPE_MASK (AL_FIELD_MASK(26, 25)) +#define AL_HAL_ETH_RETIMER_TYPE_SHIFT 25 +#define AL_HAL_ETH_RETIMER_CHANNEL_2_SHIFT 27 + +int al_eth_board_params_set(void * __iomem mac_base, struct al_eth_board_params *params){ + uint32_t reg = 0; + + /* ************* Setting Board params register 1 **************** */ + AL_REG_FIELD_SET(reg, AL_HAL_ETH_MEDIA_TYPE_MASK, + AL_HAL_ETH_MEDIA_TYPE_SHIFT, params->media_type); + AL_REG_BIT_VAL_SET(reg, AL_HAL_ETH_EXT_PHY_SHIFT, params->phy_exist == AL_TRUE); + AL_REG_FIELD_SET(reg, AL_HAL_ETH_PHY_ADDR_MASK, + AL_HAL_ETH_PHY_ADDR_SHIFT, params->phy_mdio_addr); + + AL_REG_BIT_VAL_SET(reg, AL_HAL_ETH_SFP_EXIST_SHIFT, params->sfp_plus_module_exist == AL_TRUE); + + AL_REG_BIT_VAL_SET(reg, AL_HAL_ETH_AN_ENABLE_SHIFT, params->autoneg_enable == AL_TRUE); + AL_REG_BIT_VAL_SET(reg, AL_HAL_ETH_KR_LT_ENABLE_SHIFT, params->kr_lt_enable == AL_TRUE); + AL_REG_BIT_VAL_SET(reg, AL_HAL_ETH_KR_FEC_ENABLE_SHIFT, params->kr_fec_enable == AL_TRUE); + AL_REG_FIELD_SET(reg, AL_HAL_ETH_MDIO_FREQ_MASK, + AL_HAL_ETH_MDIO_FREQ_SHIFT, params->mdio_freq); + AL_REG_FIELD_SET(reg, AL_HAL_ETH_I2C_ADAPTER_ID_MASK, + AL_HAL_ETH_I2C_ADAPTER_ID_SHIFT, params->i2c_adapter_id); + AL_REG_FIELD_SET(reg, AL_HAL_ETH_EXT_PHY_IF_MASK, + AL_HAL_ETH_EXT_PHY_IF_SHIFT, params->phy_if); + + AL_REG_BIT_VAL_SET(reg, AL_HAL_ETH_AUTO_NEG_MODE_SHIFT, + params->an_mode == AL_ETH_BOARD_AUTONEG_IN_BAND); + + AL_REG_FIELD_SET(reg, AL_HAL_ETH_SERDES_GRP_MASK, + AL_HAL_ETH_SERDES_GRP_SHIFT, params->serdes_grp); + AL_REG_FIELD_SET(reg, AL_HAL_ETH_SERDES_LANE_MASK, + AL_HAL_ETH_SERDES_LANE_SHIFT, params->serdes_lane); + + AL_REG_FIELD_SET(reg, AL_HAL_ETH_REF_CLK_FREQ_MASK, + AL_HAL_ETH_REF_CLK_FREQ_SHIFT, params->ref_clk_freq); + + al_assert(reg != 0); + + al_reg_write32(mac_base + 0x4, reg); + + /* ************* Setting Board params register 2 **************** */ + reg = 0; + AL_REG_BIT_VAL_SET(reg, AL_HAL_ETH_DONT_OVERRIDE_SERDES_SHIFT, + params->dont_override_serdes == AL_TRUE); + + AL_REG_BIT_VAL_SET(reg, AL_HAL_ETH_1000_BASE_X_SHIFT, + params->force_1000_base_x == AL_TRUE); + + AL_REG_BIT_VAL_SET(reg, AL_HAL_ETH_1G_AN_DISABLE_SHIFT, + params->an_disable == AL_TRUE); + + AL_REG_FIELD_SET(reg, AL_HAL_ETH_1G_SPEED_MASK, + AL_HAL_ETH_1G_SPEED_SHIFT, params->speed); + + AL_REG_BIT_VAL_SET(reg, AL_HAL_ETH_1G_HALF_DUPLEX_SHIFT, + params->half_duplex == AL_TRUE); + + AL_REG_BIT_VAL_SET(reg, AL_HAL_ETH_1G_FC_DISABLE_SHIFT, + params->fc_disable == AL_TRUE); + + AL_REG_BIT_VAL_SET(reg, AL_HAL_ETH_RETIMER_EXIST_SHIFT, params->retimer_exist == AL_TRUE); + AL_REG_FIELD_SET(reg, AL_HAL_ETH_RETIMER_BUS_ID_MASK, + AL_HAL_ETH_RETIMER_BUS_ID_SHIFT, params->retimer_bus_id); + AL_REG_FIELD_SET(reg, AL_HAL_ETH_RETIMER_I2C_ADDR_MASK, + AL_HAL_ETH_RETIMER_I2C_ADDR_SHIFT, params->retimer_i2c_addr); + + AL_REG_BIT_VAL_SET(reg, AL_HAL_ETH_RETIMER_CHANNEL_SHIFT, + ((params->retimer_channel == AL_ETH_RETIMER_CHANNEL_B) || + (params->retimer_channel == AL_ETH_RETIMER_CHANNEL_D))); + + AL_REG_BIT_VAL_SET(reg, AL_HAL_ETH_RETIMER_CHANNEL_2_SHIFT, + ((params->retimer_channel == AL_ETH_RETIMER_CHANNEL_C) || + (params->retimer_channel == AL_ETH_RETIMER_CHANNEL_D))); + + AL_REG_FIELD_SET(reg, AL_HAL_ETH_DAC_LENGTH_MASK, + AL_HAL_ETH_DAC_LENGTH_SHIFT, params->dac_len); + AL_REG_BIT_VAL_SET(reg, AL_HAL_ETH_DAC_SHIFT, params->dac); + + AL_REG_FIELD_SET(reg, AL_HAL_ETH_RETIMER_TYPE_MASK, + AL_HAL_ETH_RETIMER_TYPE_SHIFT, params->retimer_type); + + al_reg_write32(mac_base + 0x404, reg); + return 0; +} + +int al_eth_board_params_get(void * __iomem mac_base, struct al_eth_board_params *params){ + uint32_t reg = al_reg_read32((void*)((uint32_t)mac_base + 0x4)); + + /* check if the register was initialized, 0 is not a valid value */ + if (reg == 0) + return -ENOENT; + + /* ************* Getting Board params register 1 **************** */ + params->media_type = AL_REG_FIELD_GET(reg, AL_HAL_ETH_MEDIA_TYPE_MASK, + AL_HAL_ETH_MEDIA_TYPE_SHIFT); + if (AL_REG_BIT_GET(reg, AL_HAL_ETH_EXT_PHY_SHIFT)) + params->phy_exist = AL_TRUE; + else + params->phy_exist = AL_FALSE; + + params->phy_mdio_addr = AL_REG_FIELD_GET(reg, AL_HAL_ETH_PHY_ADDR_MASK, + AL_HAL_ETH_PHY_ADDR_SHIFT); + + if (AL_REG_BIT_GET(reg, AL_HAL_ETH_SFP_EXIST_SHIFT)) + params->sfp_plus_module_exist = AL_TRUE; + else + params->sfp_plus_module_exist = AL_FALSE; + + if (AL_REG_BIT_GET(reg, AL_HAL_ETH_AN_ENABLE_SHIFT)) + params->autoneg_enable = AL_TRUE; + else + params->autoneg_enable = AL_FALSE; + + if (AL_REG_BIT_GET(reg, AL_HAL_ETH_KR_LT_ENABLE_SHIFT)) + params->kr_lt_enable = AL_TRUE; + else + params->kr_lt_enable = AL_FALSE; + + if (AL_REG_BIT_GET(reg, AL_HAL_ETH_KR_FEC_ENABLE_SHIFT)) + params->kr_fec_enable = AL_TRUE; + else + params->kr_fec_enable = AL_FALSE; + + params->mdio_freq = AL_REG_FIELD_GET(reg, + AL_HAL_ETH_MDIO_FREQ_MASK, + AL_HAL_ETH_MDIO_FREQ_SHIFT); + + params->i2c_adapter_id = AL_REG_FIELD_GET(reg, + AL_HAL_ETH_I2C_ADAPTER_ID_MASK, + AL_HAL_ETH_I2C_ADAPTER_ID_SHIFT); + + params->phy_if = AL_REG_FIELD_GET(reg, + AL_HAL_ETH_EXT_PHY_IF_MASK, + AL_HAL_ETH_EXT_PHY_IF_SHIFT); + + if (AL_REG_BIT_GET(reg, AL_HAL_ETH_AUTO_NEG_MODE_SHIFT)) + params->an_mode = AL_TRUE; + else + params->an_mode = AL_FALSE; + + params->serdes_grp = AL_REG_FIELD_GET(reg, + AL_HAL_ETH_SERDES_GRP_MASK, + AL_HAL_ETH_SERDES_GRP_SHIFT); + + params->serdes_lane = AL_REG_FIELD_GET(reg, + AL_HAL_ETH_SERDES_LANE_MASK, + AL_HAL_ETH_SERDES_LANE_SHIFT); + + params->ref_clk_freq = AL_REG_FIELD_GET(reg, + AL_HAL_ETH_REF_CLK_FREQ_MASK, + AL_HAL_ETH_REF_CLK_FREQ_SHIFT); + + /* ************* Getting Board params register 2 **************** */ + reg = al_reg_read32((void*)((uint32_t)mac_base + 0x404)); + if (AL_REG_BIT_GET(reg, AL_HAL_ETH_DONT_OVERRIDE_SERDES_SHIFT)) + params->dont_override_serdes = AL_TRUE; + else + params->dont_override_serdes = AL_FALSE; + + if (AL_REG_BIT_GET(reg, AL_HAL_ETH_1000_BASE_X_SHIFT)) + params->force_1000_base_x = AL_TRUE; + else + params->force_1000_base_x = AL_FALSE; + + if (AL_REG_BIT_GET(reg, AL_HAL_ETH_1G_AN_DISABLE_SHIFT)) + params->an_disable = AL_TRUE; + else + params->an_disable = AL_FALSE; + + params->speed = AL_REG_FIELD_GET(reg, + AL_HAL_ETH_1G_SPEED_MASK, + AL_HAL_ETH_1G_SPEED_SHIFT); + + if (AL_REG_BIT_GET(reg, AL_HAL_ETH_1G_HALF_DUPLEX_SHIFT)) + params->half_duplex = AL_TRUE; + else + params->half_duplex = AL_FALSE; + + if (AL_REG_BIT_GET(reg, AL_HAL_ETH_1G_FC_DISABLE_SHIFT)) + params->fc_disable = AL_TRUE; + else + params->fc_disable = AL_FALSE; + + if (AL_REG_BIT_GET(reg, AL_HAL_ETH_RETIMER_EXIST_SHIFT)) + params->retimer_exist = AL_TRUE; + else + params->retimer_exist = AL_FALSE; + + params->retimer_bus_id = AL_REG_FIELD_GET(reg, + AL_HAL_ETH_RETIMER_BUS_ID_MASK, + AL_HAL_ETH_RETIMER_BUS_ID_SHIFT); + params->retimer_i2c_addr = AL_REG_FIELD_GET(reg, + AL_HAL_ETH_RETIMER_I2C_ADDR_MASK, + AL_HAL_ETH_RETIMER_I2C_ADDR_SHIFT); + + params->retimer_channel = + ((AL_REG_BIT_GET(reg, AL_HAL_ETH_RETIMER_CHANNEL_SHIFT)) | + (AL_REG_BIT_GET(reg, AL_HAL_ETH_RETIMER_CHANNEL_2_SHIFT) << 1)); + + params->dac_len = AL_REG_FIELD_GET(reg, + AL_HAL_ETH_DAC_LENGTH_MASK, + AL_HAL_ETH_DAC_LENGTH_SHIFT); + + if (AL_REG_BIT_GET(reg, AL_HAL_ETH_DAC_SHIFT)) + params->dac = AL_TRUE; + else + params->dac = AL_FALSE; + + params->retimer_type = AL_REG_FIELD_GET(reg, + AL_HAL_ETH_RETIMER_TYPE_MASK, + AL_HAL_ETH_RETIMER_TYPE_SHIFT); + + return 0; +} + +/* Wake-On-Lan (WoL) */ +static inline void al_eth_byte_arr_to_reg( + uint32_t *reg, uint8_t *arr, unsigned int num_bytes) +{ + uint32_t mask = 0xff; + unsigned int i; + + al_assert(num_bytes <= 4); + + *reg = 0; + + for (i = 0 ; i < num_bytes ; i++) { + AL_REG_FIELD_SET(*reg, mask, (sizeof(uint8_t) * i), arr[i]); + mask = mask << sizeof(uint8_t); + } +} + +int al_eth_wol_enable( + struct al_hal_eth_adapter *adapter, + struct al_eth_wol_params *wol) +{ + uint32_t reg = 0; + + if (wol->int_mask & AL_ETH_WOL_INT_MAGIC_PSWD) { + al_assert(wol->pswd != NULL); + + al_eth_byte_arr_to_reg(®, &wol->pswd[0], 4); + al_reg_write32(&adapter->ec_regs_base->wol.magic_pswd_l, reg); + + al_eth_byte_arr_to_reg(®, &wol->pswd[4], 2); + al_reg_write32(&adapter->ec_regs_base->wol.magic_pswd_h, reg); + } + + if (wol->int_mask & AL_ETH_WOL_INT_IPV4) { + al_assert(wol->ipv4 != NULL); + + al_eth_byte_arr_to_reg(®, &wol->ipv4[0], 4); + al_reg_write32(&adapter->ec_regs_base->wol.ipv4_dip, reg); + } + + if (wol->int_mask & AL_ETH_WOL_INT_IPV6) { + al_assert(wol->ipv6 != NULL); + + al_eth_byte_arr_to_reg(®, &wol->ipv6[0], 4); + al_reg_write32(&adapter->ec_regs_base->wol.ipv6_dip_word0, reg); + + al_eth_byte_arr_to_reg(®, &wol->ipv6[4], 4); + al_reg_write32(&adapter->ec_regs_base->wol.ipv6_dip_word1, reg); + + al_eth_byte_arr_to_reg(®, &wol->ipv6[8], 4); + al_reg_write32(&adapter->ec_regs_base->wol.ipv6_dip_word2, reg); + + al_eth_byte_arr_to_reg(®, &wol->ipv6[12], 4); + al_reg_write32(&adapter->ec_regs_base->wol.ipv6_dip_word3, reg); + } + + if (wol->int_mask & + (AL_ETH_WOL_INT_ETHERTYPE_BC | AL_ETH_WOL_INT_ETHERTYPE_DA)) { + + reg = ((uint32_t)wol->ethr_type2 << 16); + reg |= wol->ethr_type1; + + al_reg_write32(&adapter->ec_regs_base->wol.ethertype, reg); + } + + /* make sure we dont forwarding packets without interrupt */ + al_assert((wol->forward_mask | wol->int_mask) == wol->int_mask); + + reg = ((uint32_t)wol->forward_mask << 16); + reg |= wol->int_mask; + al_reg_write32(&adapter->ec_regs_base->wol.wol_en, reg); + + return 0; +} + +int al_eth_wol_disable( + struct al_hal_eth_adapter *adapter) +{ + al_reg_write32(&adapter->ec_regs_base->wol.wol_en, 0); + + return 0; +} + +int al_eth_tx_fwd_vid_table_set(struct al_hal_eth_adapter *adapter, uint32_t idx, + uint8_t udma_mask, al_bool fwd_to_mac) +{ + uint32_t val = 0; + al_assert(idx < AL_ETH_FWD_VID_TABLE_NUM); /* valid VID index */ + AL_REG_FIELD_SET(val, AL_ETH_TX_VLAN_TABLE_UDMA_MASK, 0, udma_mask); + AL_REG_FIELD_SET(val, AL_ETH_TX_VLAN_TABLE_FWD_TO_MAC, 4, fwd_to_mac); + + al_reg_write32(&adapter->ec_regs_base->tfw.tx_vid_table_addr, idx); + al_reg_write32(&adapter->ec_regs_base->tfw.tx_vid_table_data, val); + return 0; +} + +int al_eth_tx_protocol_detect_table_entry_set(struct al_hal_eth_adapter *adapter, uint32_t idx, + struct al_eth_tx_gpd_cam_entry *tx_gpd_entry) +{ + uint64_t gpd_data; + uint64_t gpd_mask; + + gpd_data = ((uint64_t)tx_gpd_entry->l3_proto_idx & AL_ETH_TX_GPD_L3_PROTO_MASK) << + AL_ETH_TX_GPD_L3_PROTO_SHIFT; + gpd_data |= ((uint64_t)tx_gpd_entry->l4_proto_idx & AL_ETH_TX_GPD_L4_PROTO_MASK) << + AL_ETH_TX_GPD_L4_PROTO_SHIFT; + gpd_data |= ((uint64_t)tx_gpd_entry->tunnel_control & AL_ETH_TX_GPD_TUNNEL_CTRL_MASK) << + AL_ETH_TX_GPD_TUNNEL_CTRL_SHIFT; + gpd_data |= ((uint64_t)tx_gpd_entry->source_vlan_count & AL_ETH_TX_GPD_SRC_VLAN_CNT_MASK) << + AL_ETH_TX_GPD_SRC_VLAN_CNT_SHIFT; + gpd_mask = ((uint64_t)tx_gpd_entry->l3_proto_idx_mask & AL_ETH_TX_GPD_L3_PROTO_MASK) << + AL_ETH_TX_GPD_L3_PROTO_SHIFT; + gpd_mask |= ((uint64_t)tx_gpd_entry->l4_proto_idx_mask & AL_ETH_TX_GPD_L4_PROTO_MASK) << + AL_ETH_TX_GPD_L4_PROTO_SHIFT; + gpd_mask |= ((uint64_t)tx_gpd_entry->tunnel_control_mask & AL_ETH_TX_GPD_TUNNEL_CTRL_MASK) << + AL_ETH_TX_GPD_TUNNEL_CTRL_SHIFT; + gpd_mask |= ((uint64_t)tx_gpd_entry->source_vlan_count_mask & AL_ETH_TX_GPD_SRC_VLAN_CNT_MASK) << + AL_ETH_TX_GPD_SRC_VLAN_CNT_SHIFT; + + /* Tx Generic protocol detect Cam compare table */ + al_reg_write32(&adapter->ec_regs_base->tfw_v3.tx_gpd_cam_addr, idx); + al_reg_write32(&adapter->ec_regs_base->tfw_v3.tx_gpd_cam_ctrl, + (uint32_t)((tx_gpd_entry->tx_gpd_cam_ctrl) << AL_ETH_TX_GPD_CAM_CTRL_VALID_SHIFT)); + al_dbg("al_eth_tx_generic_crc_entry_set, line [%d], tx_gpd_cam_ctrl: %#x", idx, tx_gpd_entry->tx_gpd_cam_ctrl); + al_reg_write32(&adapter->ec_regs_base->tfw_v3.tx_gpd_cam_mask_2, + (uint32_t)(gpd_mask >> AL_ETH_TX_GPD_CAM_MASK_2_SHIFT)); + al_dbg("al_eth_tx_generic_crc_entry_set, line [%d], tx_gpd_cam_mask_2: %#x", idx, (uint32_t)(gpd_mask >> AL_ETH_TX_GPD_CAM_MASK_2_SHIFT)); + al_reg_write32(&adapter->ec_regs_base->tfw_v3.tx_gpd_cam_mask_1, + (uint32_t)(gpd_mask)); + al_dbg("al_eth_tx_generic_crc_entry_set, line [%d], tx_gpd_cam_mask_1: %#x", idx, (uint32_t)(gpd_mask)); + al_reg_write32(&adapter->ec_regs_base->tfw_v3.tx_gpd_cam_data_2, + (uint32_t)(gpd_data >> AL_ETH_TX_GPD_CAM_DATA_2_SHIFT)); + al_dbg("al_eth_tx_generic_crc_entry_set, line [%d], tx_gpd_cam_data_2: %#x", idx, (uint32_t)(gpd_data >> AL_ETH_TX_GPD_CAM_DATA_2_SHIFT)); + al_reg_write32(&adapter->ec_regs_base->tfw_v3.tx_gpd_cam_data_1, + (uint32_t)(gpd_data)); + al_dbg("al_eth_tx_generic_crc_entry_set, line [%d], tx_gpd_cam_data_1: %#x", idx, (uint32_t)(gpd_data)); + return 0; +} + +int al_eth_tx_generic_crc_table_entry_set(struct al_hal_eth_adapter *adapter, uint32_t idx, + struct al_eth_tx_gcp_table_entry *tx_gcp_entry) +{ + uint32_t gcp_table_gen; + uint32_t tx_alu_opcode; + uint32_t tx_alu_opsel; + + gcp_table_gen = (tx_gcp_entry->poly_sel & AL_ETH_TX_GCP_POLY_SEL_MASK) << + AL_ETH_TX_GCP_POLY_SEL_SHIFT; + gcp_table_gen |= (tx_gcp_entry->crc32_bit_comp & AL_ETH_TX_GCP_CRC32_BIT_COMP_MASK) << + AL_ETH_TX_GCP_CRC32_BIT_COMP_SHIFT; + gcp_table_gen |= (tx_gcp_entry->crc32_bit_swap & AL_ETH_TX_GCP_CRC32_BIT_SWAP_MASK) << + AL_ETH_TX_GCP_CRC32_BIT_SWAP_SHIFT; + gcp_table_gen |= (tx_gcp_entry->crc32_byte_swap & AL_ETH_TX_GCP_CRC32_BYTE_SWAP_MASK) << + AL_ETH_TX_GCP_CRC32_BYTE_SWAP_SHIFT; + gcp_table_gen |= (tx_gcp_entry->data_bit_swap & AL_ETH_TX_GCP_DATA_BIT_SWAP_MASK) << + AL_ETH_TX_GCP_DATA_BIT_SWAP_SHIFT; + gcp_table_gen |= (tx_gcp_entry->data_byte_swap & AL_ETH_TX_GCP_DATA_BYTE_SWAP_MASK) << + AL_ETH_TX_GCP_DATA_BYTE_SWAP_SHIFT; + gcp_table_gen |= (tx_gcp_entry->trail_size & AL_ETH_TX_GCP_TRAIL_SIZE_MASK) << + AL_ETH_TX_GCP_TRAIL_SIZE_SHIFT; + gcp_table_gen |= (tx_gcp_entry->head_size & AL_ETH_TX_GCP_HEAD_SIZE_MASK) << + AL_ETH_TX_GCP_HEAD_SIZE_SHIFT; + gcp_table_gen |= (tx_gcp_entry->head_calc & AL_ETH_TX_GCP_HEAD_CALC_MASK) << + AL_ETH_TX_GCP_HEAD_CALC_SHIFT; + gcp_table_gen |= (tx_gcp_entry->mask_polarity & AL_ETH_TX_GCP_MASK_POLARITY_MASK) << + AL_ETH_TX_GCP_MASK_POLARITY_SHIFT; + al_dbg("al_eth_tx_generic_crc_entry_set, line [%d], gcp_table_gen: %#x", idx, gcp_table_gen); + + tx_alu_opcode = (tx_gcp_entry->tx_alu_opcode_1 & AL_ETH_TX_GCP_OPCODE_1_MASK) << + AL_ETH_TX_GCP_OPCODE_1_SHIFT; + tx_alu_opcode |= (tx_gcp_entry->tx_alu_opcode_2 & AL_ETH_TX_GCP_OPCODE_2_MASK) << + AL_ETH_TX_GCP_OPCODE_2_SHIFT; + tx_alu_opcode |= (tx_gcp_entry->tx_alu_opcode_3 & AL_ETH_TX_GCP_OPCODE_3_MASK) << + AL_ETH_TX_GCP_OPCODE_3_SHIFT; + tx_alu_opsel = (tx_gcp_entry->tx_alu_opsel_1 & AL_ETH_TX_GCP_OPSEL_1_MASK) << + AL_ETH_TX_GCP_OPSEL_1_SHIFT; + tx_alu_opsel |= (tx_gcp_entry->tx_alu_opsel_2 & AL_ETH_TX_GCP_OPSEL_2_MASK) << + AL_ETH_TX_GCP_OPSEL_2_SHIFT; + tx_alu_opsel |= (tx_gcp_entry->tx_alu_opsel_3 & AL_ETH_TX_GCP_OPSEL_3_MASK) << + AL_ETH_TX_GCP_OPSEL_3_SHIFT; + tx_alu_opsel |= (tx_gcp_entry->tx_alu_opsel_4 & AL_ETH_TX_GCP_OPSEL_4_MASK) << + AL_ETH_TX_GCP_OPSEL_4_SHIFT; + + /* Tx Generic crc prameters table general */ + al_reg_write32(&adapter->ec_regs_base->tfw_v3.tx_gcp_table_addr, idx); + al_reg_write32(&adapter->ec_regs_base->tfw_v3.tx_gcp_table_gen, + gcp_table_gen); + al_reg_write32(&adapter->ec_regs_base->tfw_v3.tx_gcp_table_mask_1, + tx_gcp_entry->gcp_mask[0]); + al_reg_write32(&adapter->ec_regs_base->tfw_v3.tx_gcp_table_mask_2, + tx_gcp_entry->gcp_mask[1]); + al_reg_write32(&adapter->ec_regs_base->tfw_v3.tx_gcp_table_mask_3, + tx_gcp_entry->gcp_mask[2]); + al_reg_write32(&adapter->ec_regs_base->tfw_v3.tx_gcp_table_mask_4, + tx_gcp_entry->gcp_mask[3]); + al_reg_write32(&adapter->ec_regs_base->tfw_v3.tx_gcp_table_mask_5, + tx_gcp_entry->gcp_mask[4]); + al_reg_write32(&adapter->ec_regs_base->tfw_v3.tx_gcp_table_mask_6, + tx_gcp_entry->gcp_mask[5]); + al_reg_write32(&adapter->ec_regs_base->tfw_v3.tx_gcp_table_crc_init, + tx_gcp_entry->crc_init); + al_reg_write32(&adapter->ec_regs_base->tfw_v3.tx_gcp_table_res, + tx_gcp_entry->gcp_table_res); + al_reg_write32(&adapter->ec_regs_base->tfw_v3.tx_gcp_table_alu_opcode, + tx_alu_opcode); + al_reg_write32(&adapter->ec_regs_base->tfw_v3.tx_gcp_table_alu_opsel, + tx_alu_opsel); + al_reg_write32(&adapter->ec_regs_base->tfw_v3.tx_gcp_table_alu_val, + tx_gcp_entry->alu_val); + return 0; +} + +int al_eth_tx_crc_chksum_replace_cmd_entry_set(struct al_hal_eth_adapter *adapter, uint32_t idx, + struct al_eth_tx_crc_chksum_replace_cmd_for_protocol_num_entry *tx_replace_entry) +{ + uint32_t replace_table_address; + uint32_t tx_replace_cmd; + + /* Tx crc_chksum_replace_cmd */ + replace_table_address = L4_CHECKSUM_DIS_AND_L3_CHECKSUM_DIS | idx; + tx_replace_cmd = (uint32_t)(tx_replace_entry->l3_csum_en_00) << 0; + tx_replace_cmd |= (uint32_t)(tx_replace_entry->l4_csum_en_00) << 1; + tx_replace_cmd |= (uint32_t)(tx_replace_entry->crc_en_00) << 2; + al_reg_write32(&adapter->ec_regs_base->tfw_v3.crc_csum_replace_table_addr, replace_table_address); + al_reg_write32(&adapter->ec_regs_base->tfw_v3.crc_csum_replace_table, + tx_replace_cmd); + replace_table_address = L4_CHECKSUM_DIS_AND_L3_CHECKSUM_EN | idx; + tx_replace_cmd = (uint32_t)(tx_replace_entry->l3_csum_en_01) << 0; + tx_replace_cmd |= (uint32_t)(tx_replace_entry->l4_csum_en_01) << 1; + tx_replace_cmd |= (uint32_t)(tx_replace_entry->crc_en_01) << 2; + al_reg_write32(&adapter->ec_regs_base->tfw_v3.crc_csum_replace_table_addr, replace_table_address); + al_reg_write32(&adapter->ec_regs_base->tfw_v3.crc_csum_replace_table, + tx_replace_cmd); + replace_table_address = L4_CHECKSUM_EN_AND_L3_CHECKSUM_DIS | idx; + tx_replace_cmd = (uint32_t)(tx_replace_entry->l3_csum_en_10) << 0; + tx_replace_cmd |= (uint32_t)(tx_replace_entry->l4_csum_en_10) << 1; + tx_replace_cmd |= (uint32_t)(tx_replace_entry->crc_en_10) << 2; + al_reg_write32(&adapter->ec_regs_base->tfw_v3.crc_csum_replace_table_addr, replace_table_address); + al_reg_write32(&adapter->ec_regs_base->tfw_v3.crc_csum_replace_table, + tx_replace_cmd); + replace_table_address = L4_CHECKSUM_EN_AND_L3_CHECKSUM_EN | idx; + tx_replace_cmd = (uint32_t)(tx_replace_entry->l3_csum_en_11) << 0; + tx_replace_cmd |= (uint32_t)(tx_replace_entry->l4_csum_en_11) << 1; + tx_replace_cmd |= (uint32_t)(tx_replace_entry->crc_en_11) << 2; + al_reg_write32(&adapter->ec_regs_base->tfw_v3.crc_csum_replace_table_addr, replace_table_address); + al_reg_write32(&adapter->ec_regs_base->tfw_v3.crc_csum_replace_table, + tx_replace_cmd); + + return 0; +} + +int al_eth_rx_protocol_detect_table_entry_set(struct al_hal_eth_adapter *adapter, uint32_t idx, + struct al_eth_rx_gpd_cam_entry *rx_gpd_entry) +{ + uint64_t gpd_data; + uint64_t gpd_mask; + + gpd_data = ((uint64_t)rx_gpd_entry->outer_l3_proto_idx & AL_ETH_RX_GPD_OUTER_L3_PROTO_MASK) << + AL_ETH_RX_GPD_OUTER_L3_PROTO_SHIFT; + gpd_data |= ((uint64_t)rx_gpd_entry->outer_l4_proto_idx & AL_ETH_RX_GPD_OUTER_L4_PROTO_MASK) << + AL_ETH_RX_GPD_OUTER_L4_PROTO_SHIFT; + gpd_data |= ((uint64_t)rx_gpd_entry->inner_l3_proto_idx & AL_ETH_RX_GPD_INNER_L3_PROTO_MASK) << + AL_ETH_RX_GPD_INNER_L3_PROTO_SHIFT; + gpd_data |= ((uint64_t)rx_gpd_entry->inner_l4_proto_idx & AL_ETH_RX_GPD_INNER_L4_PROTO_MASK) << + AL_ETH_RX_GPD_INNER_L4_PROTO_SHIFT; + gpd_data |= ((uint64_t)rx_gpd_entry->parse_ctrl & AL_ETH_RX_GPD_OUTER_PARSE_CTRL_MASK) << + AL_ETH_RX_GPD_OUTER_PARSE_CTRL_SHIFT; + gpd_data |= ((uint64_t)rx_gpd_entry->outer_l3_len & AL_ETH_RX_GPD_INNER_PARSE_CTRL_MASK) << + AL_ETH_RX_GPD_INNER_PARSE_CTRL_SHIFT; + gpd_data |= ((uint64_t)rx_gpd_entry->l3_priority & AL_ETH_RX_GPD_L3_PRIORITY_MASK) << + AL_ETH_RX_GPD_L3_PRIORITY_SHIFT; + gpd_data |= ((uint64_t)rx_gpd_entry->l4_dst_port_lsb & AL_ETH_RX_GPD_L4_DST_PORT_LSB_MASK) << + AL_ETH_RX_GPD_L4_DST_PORT_LSB_SHIFT; + + gpd_mask = ((uint64_t)rx_gpd_entry->outer_l3_proto_idx_mask & AL_ETH_RX_GPD_OUTER_L3_PROTO_MASK) << + AL_ETH_RX_GPD_OUTER_L3_PROTO_SHIFT; + gpd_mask |= ((uint64_t)rx_gpd_entry->outer_l4_proto_idx_mask & AL_ETH_RX_GPD_OUTER_L4_PROTO_MASK) << + AL_ETH_RX_GPD_OUTER_L4_PROTO_SHIFT; + gpd_mask |= ((uint64_t)rx_gpd_entry->inner_l3_proto_idx_mask & AL_ETH_RX_GPD_INNER_L3_PROTO_MASK) << + AL_ETH_RX_GPD_INNER_L3_PROTO_SHIFT; + gpd_mask |= ((uint64_t)rx_gpd_entry->inner_l4_proto_idx_mask & AL_ETH_RX_GPD_INNER_L4_PROTO_MASK) << + AL_ETH_RX_GPD_INNER_L4_PROTO_SHIFT; + gpd_mask |= ((uint64_t)rx_gpd_entry->parse_ctrl_mask & AL_ETH_RX_GPD_OUTER_PARSE_CTRL_MASK) << + AL_ETH_RX_GPD_OUTER_PARSE_CTRL_SHIFT; + gpd_mask |= ((uint64_t)rx_gpd_entry->outer_l3_len_mask & AL_ETH_RX_GPD_INNER_PARSE_CTRL_MASK) << + AL_ETH_RX_GPD_INNER_PARSE_CTRL_SHIFT; + gpd_mask |= ((uint64_t)rx_gpd_entry->l3_priority_mask & AL_ETH_RX_GPD_L3_PRIORITY_MASK) << + AL_ETH_RX_GPD_L3_PRIORITY_SHIFT; + gpd_mask |= ((uint64_t)rx_gpd_entry->l4_dst_port_lsb_mask & AL_ETH_RX_GPD_L4_DST_PORT_LSB_MASK) << + AL_ETH_RX_GPD_L4_DST_PORT_LSB_SHIFT; + + /* Rx Generic protocol detect Cam compare table */ + al_reg_write32(&adapter->ec_regs_base->rfw_v3.rx_gpd_cam_addr, idx); + al_reg_write32(&adapter->ec_regs_base->rfw_v3.rx_gpd_cam_ctrl, + (uint32_t)((rx_gpd_entry->rx_gpd_cam_ctrl) << AL_ETH_RX_GPD_CAM_CTRL_VALID_SHIFT)); + al_reg_write32(&adapter->ec_regs_base->rfw_v3.rx_gpd_cam_mask_2, + (uint32_t)(gpd_mask >> AL_ETH_RX_GPD_CAM_MASK_2_SHIFT)); + al_reg_write32(&adapter->ec_regs_base->rfw_v3.rx_gpd_cam_mask_1, + (uint32_t)(gpd_mask)); + al_reg_write32(&adapter->ec_regs_base->rfw_v3.rx_gpd_cam_data_2, + (uint32_t)(gpd_data >> AL_ETH_RX_GPD_CAM_DATA_2_SHIFT)); + al_reg_write32(&adapter->ec_regs_base->rfw_v3.rx_gpd_cam_data_1, + (uint32_t)(gpd_data)); + return 0; +} + +int al_eth_rx_generic_crc_table_entry_set(struct al_hal_eth_adapter *adapter, uint32_t idx, + struct al_eth_rx_gcp_table_entry *rx_gcp_entry) +{ + uint32_t gcp_table_gen; + uint32_t rx_alu_opcode; + uint32_t rx_alu_opsel; + + gcp_table_gen = (rx_gcp_entry->poly_sel & AL_ETH_RX_GCP_POLY_SEL_MASK) << + AL_ETH_RX_GCP_POLY_SEL_SHIFT; + gcp_table_gen |= (rx_gcp_entry->crc32_bit_comp & AL_ETH_RX_GCP_CRC32_BIT_COMP_MASK) << + AL_ETH_RX_GCP_CRC32_BIT_COMP_SHIFT; + gcp_table_gen |= (rx_gcp_entry->crc32_bit_swap & AL_ETH_RX_GCP_CRC32_BIT_SWAP_MASK) << + AL_ETH_RX_GCP_CRC32_BIT_SWAP_SHIFT; + gcp_table_gen |= (rx_gcp_entry->crc32_byte_swap & AL_ETH_RX_GCP_CRC32_BYTE_SWAP_MASK) << + AL_ETH_RX_GCP_CRC32_BYTE_SWAP_SHIFT; + gcp_table_gen |= (rx_gcp_entry->data_bit_swap & AL_ETH_RX_GCP_DATA_BIT_SWAP_MASK) << + AL_ETH_RX_GCP_DATA_BIT_SWAP_SHIFT; + gcp_table_gen |= (rx_gcp_entry->data_byte_swap & AL_ETH_RX_GCP_DATA_BYTE_SWAP_MASK) << + AL_ETH_RX_GCP_DATA_BYTE_SWAP_SHIFT; + gcp_table_gen |= (rx_gcp_entry->trail_size & AL_ETH_RX_GCP_TRAIL_SIZE_MASK) << + AL_ETH_RX_GCP_TRAIL_SIZE_SHIFT; + gcp_table_gen |= (rx_gcp_entry->head_size & AL_ETH_RX_GCP_HEAD_SIZE_MASK) << + AL_ETH_RX_GCP_HEAD_SIZE_SHIFT; + gcp_table_gen |= (rx_gcp_entry->head_calc & AL_ETH_RX_GCP_HEAD_CALC_MASK) << + AL_ETH_RX_GCP_HEAD_CALC_SHIFT; + gcp_table_gen |= (rx_gcp_entry->mask_polarity & AL_ETH_RX_GCP_MASK_POLARITY_MASK) << + AL_ETH_RX_GCP_MASK_POLARITY_SHIFT; + + rx_alu_opcode = (rx_gcp_entry->rx_alu_opcode_1 & AL_ETH_RX_GCP_OPCODE_1_MASK) << + AL_ETH_RX_GCP_OPCODE_1_SHIFT; + rx_alu_opcode |= (rx_gcp_entry->rx_alu_opcode_2 & AL_ETH_RX_GCP_OPCODE_2_MASK) << + AL_ETH_RX_GCP_OPCODE_2_SHIFT; + rx_alu_opcode |= (rx_gcp_entry->rx_alu_opcode_3 & AL_ETH_RX_GCP_OPCODE_3_MASK) << + AL_ETH_RX_GCP_OPCODE_3_SHIFT; + rx_alu_opsel = (rx_gcp_entry->rx_alu_opsel_1 & AL_ETH_RX_GCP_OPSEL_1_MASK) << + AL_ETH_RX_GCP_OPSEL_1_SHIFT; + rx_alu_opsel |= (rx_gcp_entry->rx_alu_opsel_2 & AL_ETH_RX_GCP_OPSEL_2_MASK) << + AL_ETH_RX_GCP_OPSEL_2_SHIFT; + rx_alu_opsel |= (rx_gcp_entry->rx_alu_opsel_3 & AL_ETH_RX_GCP_OPSEL_3_MASK) << + AL_ETH_RX_GCP_OPSEL_3_SHIFT; + rx_alu_opsel |= (rx_gcp_entry->rx_alu_opsel_4 & AL_ETH_RX_GCP_OPSEL_4_MASK) << + AL_ETH_RX_GCP_OPSEL_4_SHIFT; + + /* Rx Generic crc prameters table general */ + al_reg_write32(&adapter->ec_regs_base->rfw_v3.rx_gcp_table_addr, idx); + al_reg_write32(&adapter->ec_regs_base->rfw_v3.rx_gcp_table_gen, + gcp_table_gen); + al_reg_write32(&adapter->ec_regs_base->rfw_v3.rx_gcp_table_mask_1, + rx_gcp_entry->gcp_mask[0]); + al_reg_write32(&adapter->ec_regs_base->rfw_v3.rx_gcp_table_mask_2, + rx_gcp_entry->gcp_mask[1]); + al_reg_write32(&adapter->ec_regs_base->rfw_v3.rx_gcp_table_mask_3, + rx_gcp_entry->gcp_mask[2]); + al_reg_write32(&adapter->ec_regs_base->rfw_v3.rx_gcp_table_mask_4, + rx_gcp_entry->gcp_mask[3]); + al_reg_write32(&adapter->ec_regs_base->rfw_v3.rx_gcp_table_mask_5, + rx_gcp_entry->gcp_mask[4]); + al_reg_write32(&adapter->ec_regs_base->rfw_v3.rx_gcp_table_mask_6, + rx_gcp_entry->gcp_mask[5]); + al_reg_write32(&adapter->ec_regs_base->rfw_v3.rx_gcp_table_crc_init, + rx_gcp_entry->crc_init); + al_reg_write32(&adapter->ec_regs_base->rfw_v3.rx_gcp_table_res, + rx_gcp_entry->gcp_table_res); + al_reg_write32(&adapter->ec_regs_base->rfw_v3.rx_gcp_table_alu_opcode, + rx_alu_opcode); + al_reg_write32(&adapter->ec_regs_base->rfw_v3.rx_gcp_table_alu_opsel, + rx_alu_opsel); + al_reg_write32(&adapter->ec_regs_base->rfw_v3.rx_gcp_table_alu_val, + rx_gcp_entry->alu_val); + return 0; +} + + +#define AL_ETH_TX_GENERIC_CRC_ENTRIES_NUM 9 +#define AL_ETH_RX_PROTOCOL_DETECT_ENTRIES_NUM 32 + +static struct al_eth_tx_gpd_cam_entry +al_eth_generic_tx_crc_gpd[AL_ETH_TX_GENERIC_CRC_ENTRIES_NUM] = { + + /* [0] roce (with grh, bth) */ + {22, 0, 0, 0, 1, + 0x1f, 0x0, 0x0, 0x0, }, + /* [1] fcoe */ + {21, 0, 0, 0, 1, + 0x1f, 0x0, 0x0, 0x0, }, + /* [2] routable_roce that is refered as l4_protocol, over IPV4 (and udp) */ + {8, 23, 0, 0, 1, + 0x1f, 0x1f, 0x0, 0x0, }, + /* [3] routable_roce that is refered as l4_protocol, over IPV6 (and udp) */ + {11, 23, 0, 0, 1, + 0x1f, 0x1f, 0x0, 0x0, }, + /* [4] routable_roce that is refered as tunneled_packet, over outer IPV4 and udp */ + {23, 0, 5, 0, 1, + 0x1f, 0x0, 0x5, 0x0, }, + /* [5] routable_roce that is refered as tunneled_packet, over outer IPV6 and udp */ + {23, 0, 3, 0, 1, + 0x1f, 0x0, 0x5, 0x0 }, + /* [6] GENERIC_STORAGE_READ over IPV4 (and udp) */ + {8, 2, 0, 0, 1, + 0x1f, 0x1f, 0x0, 0x0, }, + /* [7] GENERIC_STORAGE_READ over IPV6 (and udp) */ + {11, 2, 0, 0, 1, + 0x1f, 0x1f, 0x0, 0x0, }, + /* [8] default match */ + {0, 0, 0, 0, 1, + 0x0, 0x0, 0x0, 0x0 } +}; + +static struct al_eth_tx_gcp_table_entry +al_eth_generic_tx_crc_gcp[AL_ETH_TX_GENERIC_CRC_ENTRIES_NUM] = { + + /* [0] roce (with grh, bth) */ + {0, 1, 1, 0, 1, + 0, 4, 8, 0, 1, + 0, 0, 0, 0, 0, + 0, 0, {0xffff7f03, 0x00000000, 0x00000000, + 0x00c00000, 0x00000000, 0x00000000}, 0xffffffff, 0x0, + 0}, + /* [1] fcoe */ + {0, 1, 0, 0, 1, + 0, 8, 14, 1, 1, + 0, 0, 0, 0, 0, + 0, 0, {0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000}, 0xffffffff, 0x0, + 0}, + /* [2] routable_roce that is refered as l4_protocol, over IPV4 (and udp) */ + {0, 1, 1, 0, 1, + 0, 4, 0, 0, 1, + 0, 0, 0, 0, 0, + 0, 0, {0x3000cf00, 0x00000f00, 0xc0000000, + 0x00000000, 0x00000000, 0x00000000}, 0xffffffff, 0x0, + 0}, + /* [3] routable_roce that is refered as l4_protocol, over IPV6 (and udp) */ + {0, 1, 1, 0, 1, + 0, 4, 0, 0, 1, + 0, 0, 0, 0, 0, + 0, 0, {0x7f030000, 0x00000000, 0x00000003, + 0x00c00000, 0x00000000, 0x00000000}, 0xffffffff, 0x0, + 0}, + /* [4] routable_roce that is refered as tunneled_packet, over outer IPV4 and udp */ + {0, 1, 1, 0, 1, + 0, 4, 0, 0, 1, + 2, 0, 0, 0, 10, + 0, 0, {0x3000cf00, 0x00000f00, 0xc0000000, + 0x00000000, 0x00000000, 0x00000000}, 0xffffffff, 0x0, + 28}, + /* [5] routable_roce that is refered as tunneled_packet, over outer IPV6 and udp */ + {0, 1, 1, 0, 1, + 0, 4, 0, 0, 1, + 2, 0, 0, 0, 10, + 0, 0, {0x7f030000, 0x00000000, 0x00000003, + 0x00c00000, 0x00000000, 0x00000000}, 0xffffffff, 0x0, + 48}, + /* [6] GENERIC_STORAGE_READ over IPV4 (and udp) */ + {1, 1, 1, 0, 1, + 0, 4, 0, 0, 1, + 1, 0, 1, 0, 2, + 10, 0, {0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000}, 0xffffffff, 0x0, + 8}, + /* [7] GENERIC_STORAGE_READ over IPV6 (and udp) */ + {1, 1, 1, 0, 1, + 0, 4, 0, 0, 1, + 1, 0, 1, 0, 2, + 10, 0, {0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000}, 0xffffffff, 0x0, + 8}, + /* [8] default match */ + {0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, + 0, 0, {0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000}, 0x00000000, 0x0, + 0} +}; + +static struct al_eth_tx_crc_chksum_replace_cmd_for_protocol_num_entry +al_eth_tx_crc_chksum_replace_cmd[AL_ETH_TX_GENERIC_CRC_ENTRIES_NUM] = { + + /* [0] roce (with grh, bth) */ + {0,1,0,1, 0,0,0,0, 0,0,0,0}, + /* [1] fcoe */ + {0,1,0,1, 0,0,0,0, 0,0,0,0}, + /* [2] routable_roce that is refered as l4_protocol, over IPV4 (and udp) */ + {0,0,1,1, 0,0,0,0, 0,1,0,1}, + /* [3] routable_roce that is refered as l4_protocol, over IPV6 (and udp) */ + {0,0,1,1, 0,0,0,0, 0,0,0,0}, + /* [4] routable_roce that is refered as tunneled_packet, over outer IPV4 and udp */ + {0,1,0,1, 0,0,0,0, 0,0,0,0}, + /* [5] routable_roce that is refered as tunneled_packet, over outer IPV6 and udp */ + {0,1,0,1, 0,0,0,0, 0,0,0,0}, + /* [6] GENERIC_STORAGE_READ over IPV4 (and udp) */ + {0,0,1,1, 0,0,0,0, 0,1,0,1}, + /* [7] GENERIC_STORAGE_READ over IPV6 (and udp) */ + {0,0,1,1, 0,0,0,0, 0,0,0,0}, + /* [8] default match */ + {0,0,0,0, 0,0,1,1, 0,1,0,1} +}; + +static struct al_eth_rx_gpd_cam_entry +al_eth_generic_rx_crc_gpd[AL_ETH_RX_PROTOCOL_DETECT_ENTRIES_NUM] = { + + /* [0] roce (with grh, bth) */ + {22, 0, 0, 0, + 0, 0, 0, 0, 1, + 0x1f, 0x0, 0x0, 0x0, + 0x4, 0x0, 0x0, 0x0}, + /* [1] fcoe */ + {21, 0, 0, 0, + 0, 0, 0, 0, 1, + 0x1f, 0x0, 0x0, 0x0, + 0x4, 0x0, 0x0, 0x0}, + /* [2] routable_roce that is refered as l4_protocol, over IPV4 (and udp) */ + {8, 23, 0, 0, + 0, 0, 0, 0, 1, + 0x1f, 0x1f, 0x0, 0x0, + 0x4, 0x0, 0x0, 0x0}, + /* [3] routable_roce that is refered as l4_protocol, over IPV6 (and udp) */ + {11, 23, 0, 0, + 0, 0, 0, 0, 1, + 0x1f, 0x1f, 0x0, 0x0, + 0x4, 0x0, 0x0, 0x0}, + /* [4] routable_roce that is refered as tunneled_packet, over outer IPV4 and udp */ + {8, 13, 23, 0, + 0, 0, 0, 0, 1, + 0x1f, 0x1f, 0x1f, 0x0, + 0x4, 0x0, 0x0, 0x0}, + /* [5] routable_roce that is refered as tunneled_packet, over outer IPV6 and udp */ + {11, 13, 23, 0, + 0, 0, 0, 0, 1, + 0x1f, 0x1f, 0x1f, 0x0, + 0x4, 0x0, 0x0, 0x0}, + /* [6] tunneled roce (with grh, bth) over GRE over IPV4 */ + {8, 0, 22, 0, + 4, 0, 0, 0, 1, + 0x1f, 0x0, 0x1f, 0x0, + 0x4, 0x0, 0x0, 0x0}, + /* [7] tunneled roce (with grh, bth) over GRE over IPV6 */ + {11, 0, 22, 0, + 4, 0, 0, 0, 1, + 0x1f, 0x0, 0x1f, 0x0, + 0x4, 0x0, 0x0, 0x0}, + /* [8] tunneled fcoe over IPV4 */ + {8, 0, 21, 0, + 4, 0, 0, 0, 1, + 0x1f, 0x0, 0x1f, 0x0, + 0x4, 0x0, 0x0, 0x0}, + /* [9] tunneled fcoe over IPV6 */ + {11, 0, 21, 0, + 4, 0, 0, 0, 1, + 0x1f, 0x0, 0x1f, 0x0, + 0x4, 0x0, 0x0, 0x0}, + /* [10] tunneled routable_roce that is refered as l4_protocol, over IPV4 (and udp) over IPV4 */ + {8, 0, 8, 23, + 4, 0, 0, 0, 1, + 0x1f, 0x0, 0x1f, 0x1f, + 0x4, 0x0, 0x0, 0x0}, + /* [11] tunneled routable_roce that is refered as l4_protocol, over IPV4 (and udp) over IPV6 */ + {11, 0, 8, 23, + 4, 0, 0, 0, 1, + 0x1f, 0x0, 0x1f, 0x1f, + 0x4, 0x0, 0x0, 0x0}, + /* [12] tunneled routable_roce that is refered as l4_protocol, over IPV6 (and udp) over IPV4 */ + {8, 0, 11, 23, + 4, 0, 0, 0, 1, + 0x1f, 0x0, 0x1f, 0x1f, + 0x4, 0x0, 0x0, 0x0}, + /* [13] tunneled routable_roce that is refered as l4_protocol, over IPV6 (and udp) over IPV6 */ + {11, 0, 11, 23, + 4, 0, 0, 0, 1, + 0x1f, 0x0, 0x1f, 0x1f, + 0x4, 0x0, 0x0, 0x0}, + /* [14] l3_pkt - IPV4 */ + {8, 0, 0, 0, + 0, 0, 0, 0, 1, + 0x1f, 0x1f, 0x0, 0x0, + 0x4, 0x0, 0x0, 0x0}, + /* [15] l4_hdr over IPV4 */ + {8, 12, 0, 0, + 0, 0, 0, 0, 1, + 0x1f, 0x1e, 0x0, 0x0, + 0x4, 0x0, 0x0, 0x0}, + /* [16] l3_pkt - IPV6 */ + {11, 0, 0, 0, + 0, 0, 0, 0, 1, + 0x1f, 0x1f, 0x0, 0x0, + 0x4, 0x0, 0x0, 0x0}, + /* [17] l4_hdr over IPV6 */ + {11, 12, 0, 0, + 0, 0, 0, 0, 1, + 0x1f, 0x1e, 0x0, 0x0, + 0x4, 0x0, 0x0, 0x0}, + /* [18] IPV4 over IPV4 */ + {8, 0, 8, 0, + 4, 0, 0, 0, 1, + 0x1f, 0x0, 0x1f, 0x1f, + 0x4, 0x0, 0x0, 0x0}, + /* [19] l4_hdr over IPV4 over IPV4 */ + {8, 0, 8, 12, + 4, 0, 0, 0, 1, + 0x1f, 0x0, 0x1f, 0x1e, + 0x4, 0x0, 0x0, 0x0}, + /* [20] IPV4 over IPV6 */ + {11, 0, 8, 0, + 4, 0, 0, 0, 1, + 0x1f, 0x0, 0x1f, 0x1f, + 0x4, 0x0, 0x0, 0x0}, + /* [21] l4_hdr over IPV4 over IPV6 */ + {11, 0, 8, 12, + 4, 0, 0, 0, 1, + 0x1f, 0x0, 0x1f, 0x1e, + 0x4, 0x0, 0x0, 0x0}, + /* [22] IPV6 over IPV4 */ + {8, 0, 11, 0, + 4, 0, 0, 0, 1, + 0x1f, 0x0, 0x1f, 0x1f, + 0x4, 0x0, 0x0, 0x0}, + /* [23] l4_hdr over IPV6 over IPV4 */ + {8, 0, 11, 12, + 4, 0, 0, 0, 1, + 0x1f, 0x0, 0x1f, 0x1e, + 0x4, 0x0, 0x0, 0x0}, + /* [24] IPV6 over IPV6 */ + {11, 0, 11, 0, + 4, 0, 0, 0, 1, + 0x1f, 0x0, 0x1f, 0x1f, + 0x4, 0x0, 0x0, 0x0}, + /* [25] l4_hdr over IPV6 over IPV6 */ + {11, 0, 11, 12, + 4, 0, 0, 0, 1, + 0x1f, 0x0, 0x1f, 0x1e, + 0x4, 0x0, 0x0, 0x0}, + /* [26] GENERIC_STORAGE_READ, over IPV4 (and udp) */ + {8, 2, 0, 0, + 0, 0, 0, 0, 1, + 0x1f, 0x1f, 0x0, 0x0, + 0x4, 0x0, 0x0, 0x0}, + /* [27] GENERIC_STORAGE_READ, over IPV6 (and udp) */ + {11, 2, 0, 0, + 0, 0, 0, 0, 1, + 0x1f, 0x1f, 0x0, 0x0, + 0x4, 0x0, 0x0, 0x0}, + /* [28] tunneled GENERIC_STORAGE_READ over IPV4 (and udp) over IPV4/IPV6 */ + {8, 0, 8, 2, + 4, 0, 0, 0, 1, + 0x18, 0x0, 0x1f, 0x1f, + 0x4, 0x0, 0x0, 0x0}, + /* [29] tunneled GENERIC_STORAGE_READ over IPV6 (and udp) over IPV4/IPV6 */ + {8, 0, 11, 2, + 4, 0, 0, 0, 1, + 0x18, 0x0, 0x1f, 0x1f, + 0x4, 0x0, 0x0, 0x0}, + /* [30] tunneled L2 over GRE over IPV4 */ + {8, 0, 0, 0, + 4, 0, 0, 0, 1, + 0x1f, 0x0, 0x1f, 0x0, + 0x4, 0x0, 0x0, 0x0}, + /* [31] default match */ + {0, 0, 0, 0, + 0, 0, 0, 0, 1, + 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0} +}; + +static struct al_eth_rx_gcp_table_entry +al_eth_generic_rx_crc_gcp[AL_ETH_RX_PROTOCOL_DETECT_ENTRIES_NUM] = { + + /* [0] roce (with grh, bth) */ + {0, 1, 1, 0, 1, + 0, 4, 8, 0, 1, + 0, 0, 0, 0, 0, + 0, 0, {0xffff7f03, 0x00000000, 0x00000000, + 0x00c00000, 0x00000000, 0x00000000}, 0xffffffff, 0x03000010, + 0}, + /* [1] fcoe */ + {0, 1, 0, 0, 1, + 0, 8, 14, 1, 1, + 0, 0, 0, 0, 0, + 0, 0, {0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000}, 0xffffffff, 0x03000010, + 0}, + /* [2] routable_roce that is refered as l4_protocol, over IPV4 (and udp) */ + {0, 1, 1, 0, 1, + 0, 4, 0, 0, 1, + 0, 0, 0, 0, 0, + 0, 0, {0x3000cf00, 0x00000f00, 0xc0000000, + 0x00000000, 0x00000000, 0x00000000}, 0xffffffff, 0x03000011, + 0}, + /* [3] routable_roce that is refered as l4_protocol, over IPV6 (and udp) */ + {0, 1, 1, 0, 1, + 0, 4, 0, 0, 1, + 0, 0, 0, 0, 0, + 0, 0, {0x7f030000, 0x00000000, 0x00000003, + 0x00c00000, 0x00000000, 0x00000000}, 0xffffffff, 0x03000010, + 0}, + /* [4] routable_roce that is refered as tunneled_packet, over outer IPV4 and udp */ + {0, 1, 1, 0, 1, + 0, 4, 0, 0, 1, + 2, 0, 0, 0, 10, + 0, 0, {0x3000cf00, 0x00000f00, 0xc0000000, + 0x00000000, 0x00000000, 0x00000000}, 0xffffffff, 0x0302201c, + 28}, + /* [5] routable_roce that is refered as tunneled_packet, over outer IPV6 and udp */ + {0, 1, 1, 0, 1, + 0, 4, 0, 0, 1, + 2, 0, 0, 0, 10, + 0, 0, {0x7f030000, 0x00000000, 0x00000003, + 0x00c00000, 0x00000000, 0x00000000}, 0xffffffff, 0x03002018, + 48}, + /* [6] tunneled roce (with grh, bth) over IPV4 */ + {0, 1, 1, 0, 1, + 0, 4, 8, 0, 1, + 0, 0, 0, 1, 0, + 0, 0, {0xffff7f03, 0x00000000, 0x00000000, + 0x00c00000, 0x00000000, 0x00000000}, 0xffffffff, 0x03020014, + 0}, + /* [7] tunneled roce (with grh, bth) over IPV6 */ + {0, 1, 1, 0, 1, + 0, 4, 8, 0, 1, + 0, 0, 0, 1, 0, + 0, 0, {0xffff7f03, 0x00000000, 0x00000000, + 0x00c00000, 0x00000000, 0x00000000}, 0xffffffff, 0x03000010, + 0}, + /* [8] tunneled fcoe over IPV4 */ + {0, 1, 0, 0, 1, + 0, 8, 14, 1, 1, + 0, 0, 0, 1, 0, + 0, 0, {0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000}, 0xffffffff, 0x03020014, + 0}, + /* [9] tunneled fcoe over IPV6 */ + {0, 1, 0, 0, 1, + 0, 8, 14, 1, 1, + 0, 0, 0, 1, 0, + 0, 0, {0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000}, 0xffffffff, 0x03000010, + 0}, + /* [10] tunneled routable_roce that is refered as l4_protocol, over IPV4 (and udp) over IPV4 */ + {0, 1, 1, 0, 1, + 0, 4, 0, 0, 1, + 0, 0, 0, 1, 0, + 0, 0, {0x3000cf00, 0x00000f00, 0xc0000000, + 0x00000000, 0x00000000, 0x00000000}, 0xffffffff, 0x03020015, + 0}, + /* [11] tunneled routable_roce that is refered as l4_protocol, over IPV4 (and udp) over IPV6 */ + {0, 1, 1, 0, 1, + 0, 4, 0, 0, 1, + 0, 0, 0, 1, 0, + 0, 0, {0x3000cf00, 0x00000f00, 0xc0000000, + 0x00000000, 0x00000000, 0x00000000}, 0xffffffff, 0x03000011, + 0}, + /* [12] tunneled routable_roce that is refered as l4_protocol, over IPV6 (and udp) over IPV4 */ + {0, 1, 1, 0, 1, + 0, 4, 0, 0, 1, + 0, 0, 0, 1, 0, + 0, 0, {0x7f030000, 0x00000000, 0x00000003, + 0x00c00000, 0x00000000, 0x00000000}, 0xffffffff, 0x03020014, + 0}, + /* [13] tunneled routable_roce that is refered as l4_protocol, over IPV6 (and udp) over IPV6 */ + {0, 1, 1, 0, 1, + 0, 4, 0, 0, 1, + 0, 0, 0, 1, 0, + 0, 0, {0x7f030000, 0x00000000, 0x00000003, + 0x00c00000, 0x00000000, 0x00000000}, 0xffffffff, 0x03000010, + 0}, + /* [14] l3_pkt - IPV4 */ + {0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, + 0, 0, {0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000}, 0x00000000, 0x00000001, + 0}, + /* [15] l4_hdr over IPV4 */ + {0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, + 0, 0, {0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000}, 0x00000000, 0x00000003, + 0}, + /* [16] l3_pkt - IPV6 */ + {0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, + 0, 0, {0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000}, 0x00000000, 0x00000000, + 0}, + /* [17] l4_hdr over IPV6 */ + {0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, + 0, 0, {0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000}, 0x00000000, 0x00000002, + 0}, + /* [18] IPV4 over IPV4 */ + {0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, + 0, 0, {0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000}, 0x00000000, 0x00020005, + 0}, + /* [19] l4_hdr over IPV4 over IPV4 */ + {0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, + 0, 0, {0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000}, 0x00000000, 0x00020007, + 0}, + /* [20] IPV4 over IPV6 */ + {0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, + 0, 0, {0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000}, 0x00000000, 0x00000001, + 0}, + /* [21] l4_hdr over IPV4 over IPV6 */ + {0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, + 0, 0, {0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000}, 0x00000000, 0x00000003, + 0}, + /* [22] IPV6 over IPV4 */ + {0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, + 0, 0, {0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000}, 0x00000000, 0x00020004, + 0}, + /* [23] l4_hdr over IPV6 over IPV4 */ + {0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, + 0, 0, {0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000}, 0x00000000, 0x00020006, + 0}, + /* [24] IPV6 over IPV6 */ + {0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, + 0, 0, {0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000}, 0x00000000, 0x00000000, + 0}, + /* [25] l4_hdr over IPV6 over IPV6 */ + {0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, + 0, 0, {0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000}, 0x00000000, 0x00000002, + 0}, + /* [26] GENERIC_STORAGE_READ, over IPV4 (and udp) */ + {1, 1, 1, 0, 1, + 0, 4, 0, 0, 1, + 0, 0, 0, 2, 0, + 0, 0, {0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000}, 0xffffffff, 0x03000011, + 0}, + /* [27] GENERIC_STORAGE_READ, over IPV6 (and udp) */ + {1, 1, 1, 0, 1, + 0, 4, 0, 0, 1, + 0, 0, 0, 2, 0, + 0, 0, {0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000}, 0xffffffff, 0x03000010, + 0}, + /* [28] tunneled GENERIC_STORAGE_READ over IPV4 (and udp) over IPV4/IPV6 */ + {1, 1, 1, 0, 1, + 0, 4, 0, 0, 1, + 0, 0, 0, 3, 0, + 0, 0, {0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000}, 0xffffffff, 0x03000011, + 0}, + /* [29] tunneled GENERIC_STORAGE_READ over IPV6 (and udp) over IPV4/IPV6 */ + {1, 1, 1, 0, 1, + 0, 4, 0, 0, 1, + 0, 0, 0, 3, 0, + 0, 0, {0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000}, 0xffffffff, 0x03000010, + 0}, + /* [30] tunneled L2 over GRE over IPV4 */ + {0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, + 0, 0, {0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000}, 0x00000000, 0x00020004, + 0}, + /* [31] default match */ + {0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, + 0, 0, {0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000}, 0x00000000, 0x0, + 0} +}; + +int al_eth_tx_protocol_detect_table_init(struct al_hal_eth_adapter *adapter) +{ + int idx; + al_assert((adapter->rev_id > AL_ETH_REV_ID_2)); + + for (idx = 0; idx < AL_ETH_TX_GENERIC_CRC_ENTRIES_NUM; idx++) + al_eth_tx_protocol_detect_table_entry_set(adapter, idx, + &al_eth_generic_tx_crc_gpd[idx]); + + return 0; +} + +int al_eth_tx_generic_crc_table_init(struct al_hal_eth_adapter *adapter) +{ + int idx; + al_assert((adapter->rev_id > AL_ETH_REV_ID_2)); + + al_dbg("eth [%s]: enable tx_generic_crc\n", adapter->name); + al_reg_write32(&adapter->ec_regs_base->tfw_v3.tx_gcp_legacy, 0x0); + al_reg_write32(&adapter->ec_regs_base->tfw_v3.crc_csum_replace, 0x0); + for (idx = 0; idx < AL_ETH_TX_GENERIC_CRC_ENTRIES_NUM; idx++) + al_eth_tx_generic_crc_table_entry_set(adapter, idx, + &al_eth_generic_tx_crc_gcp[idx]); + + return 0; +} + +int al_eth_tx_crc_chksum_replace_cmd_init(struct al_hal_eth_adapter *adapter) +{ + int idx; + al_assert((adapter->rev_id > AL_ETH_REV_ID_2)); + + for (idx = 0; idx < AL_ETH_TX_GENERIC_CRC_ENTRIES_NUM; idx++) + al_eth_tx_crc_chksum_replace_cmd_entry_set(adapter, idx, + &al_eth_tx_crc_chksum_replace_cmd[idx]); + + return 0; +} + +int al_eth_rx_protocol_detect_table_init(struct al_hal_eth_adapter *adapter) +{ + int idx; + al_assert((adapter->rev_id > AL_ETH_REV_ID_2)); + al_reg_write32(&adapter->ec_regs_base->rfw_v3.gpd_p1, + AL_ETH_RX_GPD_PARSE_RESULT_OUTER_L3_PROTO_IDX_OFFSET); + al_reg_write32(&adapter->ec_regs_base->rfw_v3.gpd_p2, + AL_ETH_RX_GPD_PARSE_RESULT_OUTER_L4_PROTO_IDX_OFFSET); + al_reg_write32(&adapter->ec_regs_base->rfw_v3.gpd_p3, + AL_ETH_RX_GPD_PARSE_RESULT_INNER_L3_PROTO_IDX_OFFSET); + al_reg_write32(&adapter->ec_regs_base->rfw_v3.gpd_p4, + AL_ETH_RX_GPD_PARSE_RESULT_INNER_L4_PROTO_IDX_OFFSET); + al_reg_write32(&adapter->ec_regs_base->rfw_v3.gpd_p5, + AL_ETH_RX_GPD_PARSE_RESULT_OUTER_PARSE_CTRL); + al_reg_write32(&adapter->ec_regs_base->rfw_v3.gpd_p6, + AL_ETH_RX_GPD_PARSE_RESULT_INNER_PARSE_CTRL); + al_reg_write32(&adapter->ec_regs_base->rfw_v3.gpd_p7, + AL_ETH_RX_GPD_PARSE_RESULT_L3_PRIORITY); + al_reg_write32(&adapter->ec_regs_base->rfw_v3.gpd_p8, + AL_ETH_RX_GPD_PARSE_RESULT_OUTER_L4_DST_PORT_LSB); + + for (idx = 0; idx < AL_ETH_RX_PROTOCOL_DETECT_ENTRIES_NUM; idx++) + al_eth_rx_protocol_detect_table_entry_set(adapter, idx, + &al_eth_generic_rx_crc_gpd[idx]); + return 0; +} + +int al_eth_rx_generic_crc_table_init(struct al_hal_eth_adapter *adapter) + { + int idx; + uint32_t val; + + al_assert((adapter->rev_id > AL_ETH_REV_ID_2)); + + al_dbg("eth [%s]: enable rx_generic_crc\n", adapter->name); + al_reg_write32(&adapter->ec_regs_base->rfw_v3.rx_gcp_legacy, 0x0); + + for (idx = 0; idx < AL_ETH_RX_PROTOCOL_DETECT_ENTRIES_NUM; idx++) + al_eth_rx_generic_crc_table_entry_set(adapter, idx, + &al_eth_generic_rx_crc_gcp[idx]); + + val = EC_GEN_V3_RX_COMP_DESC_W3_DEC_STAT_15_CRC_RES_SEL | + EC_GEN_V3_RX_COMP_DESC_W3_DEC_STAT_14_L3_CKS_RES_SEL | + EC_GEN_V3_RX_COMP_DESC_W3_DEC_STAT_13_L4_CKS_RES_SEL | + EC_GEN_V3_RX_COMP_DESC_W0_L3_CKS_RES_SEL; + al_reg_write32_masked(&adapter->ec_regs_base->gen_v3.rx_comp_desc, + val, val); + return 0; +} + +/** @} end of Ethernet group */ + From 25208b899945183857da501a98d924798de07b26 Mon Sep 17 00:00:00 2001 From: Wojciech Macek Date: Tue, 6 Sep 2016 14:26:41 +0000 Subject: [PATCH 2/2] Update Annapurna Alpine HAL to a newer version. HAL version: 2.7a --- al_hal_iofic.c | 18 +- al_hal_iofic.h | 10 +- al_hal_iofic_regs.h | 14 +- al_hal_nb_regs.h | 33 +- al_hal_pbs_regs.h | 133 +- al_hal_pcie.c | 606 ++-- al_hal_pcie.h | 417 ++- al_hal_pcie_axi_reg.h | 60 +- al_hal_pcie_interrupts.h | 10 +- al_hal_pcie_regs.h | 36 +- al_hal_pcie_w_reg.h | 2 +- al_hal_plat_services.h | 138 +- al_hal_plat_types.h | 18 - al_hal_reg_utils.h | 1 + al_hal_serdes.c | 1864 ++++++------ al_hal_serdes.h | 1125 -------- al_hal_serdes_25g.c | 1951 +++++++++++++ al_hal_serdes_25g.h | 74 + al_hal_serdes_25g_internal_regs.h | 4205 ++++++++++++++++++++++++++++ al_hal_serdes_25g_regs.h | 434 +++ al_hal_serdes_hssp.h | 87 + al_hal_serdes_hssp_internal_regs.h | 749 +++++ al_hal_serdes_hssp_regs.h | 494 ++++ al_hal_serdes_interface.h | 875 ++++++ al_hal_udma.h | 11 +- al_hal_udma_config.c | 333 +-- al_hal_udma_config.h | 265 +- al_hal_udma_debug.c | 8 +- al_hal_udma_iofic.h | 18 + al_hal_udma_main.c | 26 +- al_hal_udma_regs_gen.h | 319 +-- al_hal_unit_adapter_regs.h | 14 +- al_serdes.c | 59 + al_serdes.h | 78 + eth/al_hal_eth.h | 82 +- eth/al_hal_eth_mac_regs.h | 295 +- eth/al_hal_eth_main.c | 1004 +++++-- 37 files changed, 12326 insertions(+), 3540 deletions(-) create mode 100644 al_hal_serdes_25g.c create mode 100644 al_hal_serdes_25g.h create mode 100644 al_hal_serdes_25g_internal_regs.h create mode 100644 al_hal_serdes_25g_regs.h create mode 100644 al_hal_serdes_hssp.h create mode 100644 al_hal_serdes_hssp_internal_regs.h create mode 100644 al_hal_serdes_hssp_regs.h create mode 100644 al_hal_serdes_interface.h create mode 100644 al_serdes.c create mode 100644 al_serdes.h diff --git a/al_hal_iofic.c b/al_hal_iofic.c index 28467f2e3b8..b60a45f3002 100644 --- a/al_hal_iofic.c +++ b/al_hal_iofic.c @@ -129,10 +129,10 @@ int al_iofic_msix_moder_interval_config(void __iomem *regs_base, int group, } /* - * configure the vmid attributes for a given msix vector. + * configure the target-id attributes for a given msix vector. */ -int al_iofic_msix_vmid_attributes_config(void __iomem *regs_base, int group, - uint8_t vector, uint32_t vmid, uint8_t vmid_en) +int al_iofic_msix_tgtid_attributes_config(void __iomem *regs_base, int group, + uint8_t vector, uint32_t tgtid, uint8_t tgtid_en) { struct al_iofic_regs __iomem *regs = (struct al_iofic_regs __iomem *)(regs_base); uint32_t reg = 0; @@ -141,14 +141,14 @@ int al_iofic_msix_vmid_attributes_config(void __iomem *regs_base, int group, al_assert(group < AL_IOFIC_MAX_GROUPS); AL_REG_FIELD_SET(reg, - INT_MSIX_VMID_MASK, - INT_MSIX_VMID_SHIFT, - vmid); + INT_MSIX_TGTID_MASK, + INT_MSIX_TGTID_SHIFT, + tgtid); AL_REG_BIT_VAL_SET(reg, - INT_MSIX_VMID_EN_SHIFT, - vmid_en); + INT_MSIX_TGTID_EN_SHIFT, + tgtid_en); - al_reg_write32(®s->grp_int_mod[group][vector].grp_int_vmid_reg, reg); + al_reg_write32(®s->grp_int_mod[group][vector].grp_int_tgtid_reg, reg); return 0; } diff --git a/al_hal_iofic.h b/al_hal_iofic.h index 5c19e0a1260..5b4a1dffb0e 100644 --- a/al_hal_iofic.h +++ b/al_hal_iofic.h @@ -117,17 +117,17 @@ int al_iofic_msix_moder_interval_config(void __iomem *regs_base, int group, uint8_t vector, uint8_t interval); /** -* configure the vmid attributes for a given msix vector. +* configure the tgtid attributes for a given msix vector. * * @param group the interrupt group * @param vector index -* @param vmid the vmid value -* @param vmid_en take vmid from the intc +* @param tgtid the target-id value +* @param tgtid_en take target-id from the intc * * @return 0 on success. -EINVAL otherwise. */ -int al_iofic_msix_vmid_attributes_config(void __iomem *regs_base, int group, - uint8_t vector, uint32_t vmid, uint8_t vmid_en); +int al_iofic_msix_tgtid_attributes_config(void __iomem *regs_base, int group, + uint8_t vector, uint32_t tgtid, uint8_t tgtid_en); /** * return the offset of the unmask register for a given group. diff --git a/al_hal_iofic_regs.h b/al_hal_iofic_regs.h index 81ba20fc967..3f1b5f88660 100644 --- a/al_hal_iofic_regs.h +++ b/al_hal_iofic_regs.h @@ -66,7 +66,7 @@ struct al_iofic_grp_ctrl { struct al_iofic_grp_mod { uint32_t grp_int_mod_reg; /* Interrupt moderation registerDedicated moderation in ... */ - uint32_t grp_int_vmid_reg; + uint32_t grp_int_tgtid_reg; }; struct al_iofic_regs { @@ -109,12 +109,12 @@ struct al_iofic_regs { #define INT_MOD_INTV_MASK 0x000000FF #define INT_MOD_INTV_SHIFT 0 -/**** grp_int_vmid_reg register ****/ -/* Interrupt vmid value registerDedicated reg ... */ -#define INT_MSIX_VMID_MASK 0x0000FFFF -#define INT_MSIX_VMID_SHIFT 0 -/* Interrupt vmid_en value registerDedicated reg ... */ -#define INT_MSIX_VMID_EN_SHIFT 31 +/**** grp_int_tgtid_reg register ****/ +/* Interrupt tgtid value registerDedicated reg ... */ +#define INT_MSIX_TGTID_MASK 0x0000FFFF +#define INT_MSIX_TGTID_SHIFT 0 +/* Interrupt tgtid_en value registerDedicated reg ... */ +#define INT_MSIX_TGTID_EN_SHIFT 31 #ifdef __cplusplus } diff --git a/al_hal_nb_regs.h b/al_hal_nb_regs.h index 9de3bd24686..29c5060d007 100644 --- a/al_hal_nb_regs.h +++ b/al_hal_nb_regs.h @@ -355,7 +355,7 @@ struct al_nb_nb_version { }; struct al_nb_sriov { /* [0x0] */ - uint32_t cpu_vmid[4]; + uint32_t cpu_tgtid[4]; uint32_t rsrvd[4]; }; struct al_nb_dram_channels { @@ -403,7 +403,7 @@ struct al_nb_push_packet { uint32_t pp_config; uint32_t rsrvd_0[3]; /* [0x10] */ - uint32_t pp_ext_awuser; + uint32_t pp_ext_attr; uint32_t rsrvd_1[3]; /* [0x20] */ uint32_t pp_base_low; @@ -411,7 +411,7 @@ struct al_nb_push_packet { uint32_t pp_base_high; uint32_t rsrvd_2[2]; /* [0x30] */ - uint32_t pp_sel_awuser; + uint32_t pp_sel_attr; uint32_t rsrvd[51]; }; @@ -853,8 +853,8 @@ Enables 4k hazard of post-barrier vs pre-barrier transactions. Otherwise, 64B ha This value is sampled into the CP15 Configuration Base Address Register (CBAR) at reset. */ #define NB_GLOBAL_LGIC_BASE_HIGH_BASE_39_32_MASK 0x000000FF #define NB_GLOBAL_LGIC_BASE_HIGH_BASE_39_32_SHIFT 0 -#define NB_GLOBAL_LGIC_BASE_HIGH_BASE_43_32_MASK_PKR 0x00000FFF -#define NB_GLOBAL_LGIC_BASE_HIGH_BASE_43_32_SHIFT_PKR 0 +#define NB_GLOBAL_LGIC_BASE_HIGH_BASE_43_32_MASK_ALPINE_V2 0x00000FFF +#define NB_GLOBAL_LGIC_BASE_HIGH_BASE_43_32_SHIFT_ALPINE_V2 0 /* GIC registers base [31:15]. This value is sampled into the CP15 Configuration Base Address Register (CBAR) at reset */ #define NB_GLOBAL_LGIC_BASE_LOW_BASED_31_15_MASK 0xFFFF8000 @@ -1055,9 +1055,9 @@ Other access types are hazard check against the pre-barrier requests. */ /* Disable counter (wait 1000 NB cycles) before applying PoS enable/disable configuration */ #define NB_GLOBAL_ACF_MISC_POS_CONFIG_CNT_DIS (1 << 14) /* Disable wr spliter A0 bug fixes */ -#define NB_GLOBAL_ACF_MISC_WRSPLT_ALPINE_M0_MODE (1 << 16) -/* Disable wr spliter PKR bug fixes */ -#define NB_GLOBAL_ACF_MISC_WRSPLT_ALPINE_A0_MODE (1 << 17) +#define NB_GLOBAL_ACF_MISC_WRSPLT_ALPINE_V1_M0_MODE (1 << 16) +/* Disable wr spliter ALPINE_V2 bug fixes */ +#define NB_GLOBAL_ACF_MISC_WRSPLT_ALPINE_V1_A0_MODE (1 << 17) /* Override the address parity calucation for write transactions going to IO-fabric */ #define NB_GLOBAL_ACF_MISC_NB_NIC_AWADDR_PAR_OVRD (1 << 18) /* Override the data parity calucation for write transactions going to IO-fabric */ @@ -1074,7 +1074,7 @@ Other access types are hazard check against the pre-barrier requests. */ #define NB_GLOBAL_ACF_MISC_CPU_DSB_FLUSH_DIS (1 << 26) /* Enable DMB flush request to NB to SB PoS when barrier is terminted inside the processor cluster */ #define NB_GLOBAL_ACF_MISC_CPU_DMB_FLUSH_DIS (1 << 27) -/* Peakrock only: remap CPU address above 40 bits to Slave Error +/* Alpine V2 only: remap CPU address above 40 bits to Slave Error INTERNAL */ #define NB_GLOBAL_ACF_MISC_ADDR43_40_REMAP_DIS (1 << 28) /* Enable CPU WriteUnique to WriteNoSnoop trasform */ @@ -1586,7 +1586,7 @@ enable - 0x1: Enable interrupt on overflow. */ /* Number of monitored events supported by the PMU. */ #define NB_MC_PMU_PMU_CONTROL_NUM_OF_EVENTS_MASK 0x00FC0000 #define NB_MC_PMU_PMU_CONTROL_NUM_OF_EVENTS_SHIFT 18 -#define NB_MC_PMU_PMU_CONTROL_NUM_OF_EVENTS_SHIFT_ALPINE 19 +#define NB_MC_PMU_PMU_CONTROL_NUM_OF_EVENTS_SHIFT_ALPINE_V1 19 /* Number of counters implemented by PMU. */ #define NB_MC_PMU_PMU_CONTROL_NUM_OF_CNTS_MASK 0x0F000000 #define NB_MC_PMU_PMU_CONTROL_NUM_OF_CNTS_SHIFT 24 @@ -1659,6 +1659,9 @@ Note: This field must be changed for larger counters. */ /* Revision number (Major) */ #define NB_NB_VERSION_VERSION_RELEASE_NUM_MAJOR_MASK 0x0000FF00 #define NB_NB_VERSION_VERSION_RELEASE_NUM_MAJOR_SHIFT 8 +#define NB_NB_VERSION_VERSION_RELEASE_NUM_MAJOR_VAL_ALPINE_V1 2 +#define NB_NB_VERSION_VERSION_RELEASE_NUM_MAJOR_VAL_ALPINE_V2 3 +#define NB_NB_VERSION_VERSION_RELEASE_NUM_MAJOR_VAL_ALPINE_V3 4 /* Date of release */ #define NB_NB_VERSION_VERSION_DATE_DAY_MASK 0x001F0000 #define NB_NB_VERSION_VERSION_DATE_DAY_SHIFT 16 @@ -1672,10 +1675,10 @@ Note: This field must be changed for larger counters. */ #define NB_NB_VERSION_VERSION_RESERVED_MASK 0xC0000000 #define NB_NB_VERSION_VERSION_RESERVED_SHIFT 30 -/**** cpu_vmid register ****/ -/* Target VMID */ -#define NB_SRIOV_CPU_VMID_VAL_MASK 0x000000FF -#define NB_SRIOV_CPU_VMID_VAL_SHIFT 0 +/**** cpu_tgtid register ****/ +/* Target-ID */ +#define NB_SRIOV_CPU_TGTID_VAL_MASK 0x000000FF +#define NB_SRIOV_CPU_TGTID_VAL_SHIFT 0 /**** DRAM_0_Control register ****/ /* Controller Idle @@ -1807,7 +1810,7 @@ Parity bits are still generated per transaction */ #define NB_PUSH_PACKET_PP_EXT_AWUSER_AWUSER_SHIFT 0 /**** pp_sel_awuser register ****/ -/* Select whether to use addr[63:48] or PP awmisc as vmid. +/* Select whether to use addr[63:48] or PP awmisc as tgtid. Each bit if set to 1 selects the corresponding address bit. Otherwise, selects the corersponding awmis bit. */ #define NB_PUSH_PACKET_PP_SEL_AWUSER_SEL_MASK 0x0000FFFF #define NB_PUSH_PACKET_PP_SEL_AWUSER_SEL_SHIFT 0 diff --git a/al_hal_pbs_regs.h b/al_hal_pbs_regs.h index b1f9c4f44d9..c8100e1ff1e 100644 --- a/al_hal_pbs_regs.h +++ b/al_hal_pbs_regs.h @@ -447,11 +447,12 @@ struct al_pbs_target_id_enforcement { }; struct al_pbs_regs { - struct al_pbs_unit unit; /* [0x0] */ -struct al_pbs_low_latency_sram_remap low_latency_sram_remap; -/* [0x250] */ - uint32_t rsrvd_0[88]; - struct al_pbs_target_id_enforcement target_id_enforcement; /* [0x400] */ + struct al_pbs_unit unit; /* [0x0] */ + struct al_pbs_low_latency_sram_remap low_latency_sram_remap; /* [0x250] */ + uint32_t rsrvd_0[24]; + uint32_t iofic_base; /* [0x300] */ + uint32_t rsrvd_1[63]; + struct al_pbs_target_id_enforcement target_id_enforcement; /* [0x400] */ }; @@ -849,50 +850,50 @@ struct al_pbs_low_latency_sram_remap low_latency_sram_remap; * 2'b01 - select pcie_b[0] * 2'b10 - select pcie_a[2] */ -#define PBS_UNIT_SERDES_MUX_PIPE_PKR_SELECT_OH_SERDES_2_MASK 0x00000003 -#define PBS_UNIT_SERDES_MUX_PIPE_PKR_SELECT_OH_SERDES_2_SHIFT 0 +#define PBS_UNIT_SERDES_MUX_PIPE_ALPINE_V2_SELECT_OH_SERDES_2_MASK 0x00000003 +#define PBS_UNIT_SERDES_MUX_PIPE_ALPINE_V2_SELECT_OH_SERDES_2_SHIFT 0 /* * 2'b01 - select pcie_b[1] * 2'b10 - select pcie_a[3] */ -#define PBS_UNIT_SERDES_MUX_PIPE_PKR_SELECT_OH_SERDES_3_MASK 0x00000030 -#define PBS_UNIT_SERDES_MUX_PIPE_PKR_SELECT_OH_SERDES_3_SHIFT 4 +#define PBS_UNIT_SERDES_MUX_PIPE_ALPINE_V2_SELECT_OH_SERDES_3_MASK 0x00000030 +#define PBS_UNIT_SERDES_MUX_PIPE_ALPINE_V2_SELECT_OH_SERDES_3_SHIFT 4 /* * 2'b01 - select pcie_b[0] * 2'b10 - select pcie_a[4] */ -#define PBS_UNIT_SERDES_MUX_PIPE_PKR_SELECT_OH_SERDES_4_MASK 0x00000300 -#define PBS_UNIT_SERDES_MUX_PIPE_PKR_SELECT_OH_SERDES_4_SHIFT 8 +#define PBS_UNIT_SERDES_MUX_PIPE_ALPINE_V2_SELECT_OH_SERDES_4_MASK 0x00000300 +#define PBS_UNIT_SERDES_MUX_PIPE_ALPINE_V2_SELECT_OH_SERDES_4_SHIFT 8 /* * 2'b01 - select pcie_b[1] * 2'b10 - select pcie_a[5] */ -#define PBS_UNIT_SERDES_MUX_PIPE_PKR_SELECT_OH_SERDES_5_MASK 0x00003000 -#define PBS_UNIT_SERDES_MUX_PIPE_PKR_SELECT_OH_SERDES_5_SHIFT 12 +#define PBS_UNIT_SERDES_MUX_PIPE_ALPINE_V2_SELECT_OH_SERDES_5_MASK 0x00003000 +#define PBS_UNIT_SERDES_MUX_PIPE_ALPINE_V2_SELECT_OH_SERDES_5_SHIFT 12 /* * 2'b01 - select pcie_b[2] * 2'b10 - select pcie_a[6] */ -#define PBS_UNIT_SERDES_MUX_PIPE_PKR_SELECT_OH_SERDES_6_MASK 0x00030000 -#define PBS_UNIT_SERDES_MUX_PIPE_PKR_SELECT_OH_SERDES_6_SHIFT 16 +#define PBS_UNIT_SERDES_MUX_PIPE_ALPINE_V2_SELECT_OH_SERDES_6_MASK 0x00030000 +#define PBS_UNIT_SERDES_MUX_PIPE_ALPINE_V2_SELECT_OH_SERDES_6_SHIFT 16 /* * 2'b01 - select pcie_b[3] * 2'b10 - select pcie_a[7] */ -#define PBS_UNIT_SERDES_MUX_PIPE_PKR_SELECT_OH_SERDES_7_MASK 0x00300000 -#define PBS_UNIT_SERDES_MUX_PIPE_PKR_SELECT_OH_SERDES_7_SHIFT 20 +#define PBS_UNIT_SERDES_MUX_PIPE_ALPINE_V2_SELECT_OH_SERDES_7_MASK 0x00300000 +#define PBS_UNIT_SERDES_MUX_PIPE_ALPINE_V2_SELECT_OH_SERDES_7_SHIFT 20 /* * 2'b01 - select pcie_d[0] * 2'b10 - select pcie_c[2] */ -#define PBS_UNIT_SERDES_MUX_PIPE_PKR_SELECT_OH_SERDES_10_MASK 0x03000000 -#define PBS_UNIT_SERDES_MUX_PIPE_PKR_SELECT_OH_SERDES_10_SHIFT 24 +#define PBS_UNIT_SERDES_MUX_PIPE_ALPINE_V2_SELECT_OH_SERDES_10_MASK 0x03000000 +#define PBS_UNIT_SERDES_MUX_PIPE_ALPINE_V2_SELECT_OH_SERDES_10_SHIFT 24 /* * 2'b01 - select pcie_d[1] * 2'b10 - select pcie_c[3] */ -#define PBS_UNIT_SERDES_MUX_PIPE_PKR_SELECT_OH_SERDES_11_MASK 0x30000000 -#define PBS_UNIT_SERDES_MUX_PIPE_PKR_SELECT_OH_SERDES_11_SHIFT 28 +#define PBS_UNIT_SERDES_MUX_PIPE_ALPINE_V2_SELECT_OH_SERDES_11_MASK 0x30000000 +#define PBS_UNIT_SERDES_MUX_PIPE_ALPINE_V2_SELECT_OH_SERDES_11_SHIFT 28 /**** dma_io_master_map register ****/ /* @@ -978,6 +979,14 @@ struct al_pbs_low_latency_sram_remap low_latency_sram_remap; #define PBS_UNIT_CFG_AXI_CONF_2_DBG_AWQOS_MASK 0x3C000000 #define PBS_UNIT_CFG_AXI_CONF_2_DBG_AWQOS_SHIFT 26 +/**** cfg_axi_conf_3 register ****/ +#define PBS_UNIT_CFG_AXI_CONF_3_TIMEOUT_LOW_MASK 0xFFFF +#define PBS_UNIT_CFG_AXI_CONF_3_TIMEOUT_LOW_SHIFT 0 +#define PBS_UNIT_CFG_AXI_CONF_3_TIMEOUT_HI_MASK 0xFF0000 +#define PBS_UNIT_CFG_AXI_CONF_3_TIMEOUT_HI_SHIFT 16 +#define PBS_UNIT_CFG_AXI_CONF_3_TIMEOUT_SPI_HI_MASK 0xFF000000 +#define PBS_UNIT_CFG_AXI_CONF_3_TIMEOUT_SPI_HI_SHIFT 24 + /**** spi_mst_conf_0 register ****/ /* * Sets the SPI master Configuration. For details see the SPI section in the @@ -1137,9 +1146,9 @@ struct al_pbs_low_latency_sram_remap low_latency_sram_remap; #define PBS_UNIT_CHIP_ID_DEV_ID_MASK 0xFFFF0000 #define PBS_UNIT_CHIP_ID_DEV_ID_SHIFT 16 -#define PBS_UNIT_CHIP_ID_DEV_ID_ALPINE 0 -#define PBS_UNIT_CHIP_ID_DEV_ID_PEAKROCK 1 -#define PBS_UNIT_CHIP_ID_DEV_ID_COYOTE 2 +#define PBS_UNIT_CHIP_ID_DEV_ID_ALPINE_V1 0 +#define PBS_UNIT_CHIP_ID_DEV_ID_ALPINE_V2 1 +#define PBS_UNIT_CHIP_ID_DEV_ID_ALPINE_V3 2 /**** uart0_conf_status register ****/ /* @@ -1420,56 +1429,56 @@ struct al_pbs_low_latency_sram_remap low_latency_sram_remap; * 2'b01 - select sata_b[0] * 2'b10 - select eth_a[0] */ -#define PBS_UNIT_SERDES_MUX_MULTI_0_PKR_SELECT_OH_SERDES_8_MASK 0x00000003 -#define PBS_UNIT_SERDES_MUX_MULTI_0_PKR_SELECT_OH_SERDES_8_SHIFT 0 +#define PBS_UNIT_SERDES_MUX_MULTI_0_ALPINE_V2_SELECT_OH_SERDES_8_MASK 0x00000003 +#define PBS_UNIT_SERDES_MUX_MULTI_0_ALPINE_V2_SELECT_OH_SERDES_8_SHIFT 0 /* * 3'b001 - select sata_b[1] * 3'b010 - select eth_b[0] * 3'b100 - select eth_a[1] */ -#define PBS_UNIT_SERDES_MUX_MULTI_0_PKR_SELECT_OH_SERDES_9_MASK 0x00000070 -#define PBS_UNIT_SERDES_MUX_MULTI_0_PKR_SELECT_OH_SERDES_9_SHIFT 4 +#define PBS_UNIT_SERDES_MUX_MULTI_0_ALPINE_V2_SELECT_OH_SERDES_9_MASK 0x00000070 +#define PBS_UNIT_SERDES_MUX_MULTI_0_ALPINE_V2_SELECT_OH_SERDES_9_SHIFT 4 /* * 3'b001 - select sata_b[2] * 3'b010 - select eth_c[0] * 3'b100 - select eth_a[2] */ -#define PBS_UNIT_SERDES_MUX_MULTI_0_PKR_SELECT_OH_SERDES_10_MASK 0x00000700 -#define PBS_UNIT_SERDES_MUX_MULTI_0_PKR_SELECT_OH_SERDES_10_SHIFT 8 +#define PBS_UNIT_SERDES_MUX_MULTI_0_ALPINE_V2_SELECT_OH_SERDES_10_MASK 0x00000700 +#define PBS_UNIT_SERDES_MUX_MULTI_0_ALPINE_V2_SELECT_OH_SERDES_10_SHIFT 8 /* * 3'b001 - select sata_b[3] * 3'b010 - select eth_d[0] * 3'b100 - select eth_a[3] */ -#define PBS_UNIT_SERDES_MUX_MULTI_0_PKR_SELECT_OH_SERDES_11_MASK 0x00007000 -#define PBS_UNIT_SERDES_MUX_MULTI_0_PKR_SELECT_OH_SERDES_11_SHIFT 12 +#define PBS_UNIT_SERDES_MUX_MULTI_0_ALPINE_V2_SELECT_OH_SERDES_11_MASK 0x00007000 +#define PBS_UNIT_SERDES_MUX_MULTI_0_ALPINE_V2_SELECT_OH_SERDES_11_SHIFT 12 /* * 2'b01 - select eth_a[0] * 2'b10 - select sata_a[0] */ -#define PBS_UNIT_SERDES_MUX_MULTI_0_PKR_SELECT_OH_SERDES_12_MASK 0x00030000 -#define PBS_UNIT_SERDES_MUX_MULTI_0_PKR_SELECT_OH_SERDES_12_SHIFT 16 +#define PBS_UNIT_SERDES_MUX_MULTI_0_ALPINE_V2_SELECT_OH_SERDES_12_MASK 0x00030000 +#define PBS_UNIT_SERDES_MUX_MULTI_0_ALPINE_V2_SELECT_OH_SERDES_12_SHIFT 16 /* * 3'b001 - select eth_b[0] * 3'b010 - select eth_c[1] * 3'b100 - select sata_a[1] */ -#define PBS_UNIT_SERDES_MUX_MULTI_0_PKR_SELECT_OH_SERDES_13_MASK 0x00700000 -#define PBS_UNIT_SERDES_MUX_MULTI_0_PKR_SELECT_OH_SERDES_13_SHIFT 20 +#define PBS_UNIT_SERDES_MUX_MULTI_0_ALPINE_V2_SELECT_OH_SERDES_13_MASK 0x00700000 +#define PBS_UNIT_SERDES_MUX_MULTI_0_ALPINE_V2_SELECT_OH_SERDES_13_SHIFT 20 /* * 3'b001 - select eth_a[0] * 3'b010 - select eth_c[2] * 3'b100 - select sata_a[2] */ -#define PBS_UNIT_SERDES_MUX_MULTI_0_PKR_SELECT_OH_SERDES_14_MASK 0x07000000 -#define PBS_UNIT_SERDES_MUX_MULTI_0_PKR_SELECT_OH_SERDES_14_SHIFT 24 +#define PBS_UNIT_SERDES_MUX_MULTI_0_ALPINE_V2_SELECT_OH_SERDES_14_MASK 0x07000000 +#define PBS_UNIT_SERDES_MUX_MULTI_0_ALPINE_V2_SELECT_OH_SERDES_14_SHIFT 24 /* * 3'b001 - select eth_d[0] * 3'b010 - select eth_c[3] * 3'b100 - select sata_a[3] */ -#define PBS_UNIT_SERDES_MUX_MULTI_0_PKR_SELECT_OH_SERDES_15_MASK 0x70000000 -#define PBS_UNIT_SERDES_MUX_MULTI_0_PKR_SELECT_OH_SERDES_15_SHIFT 28 +#define PBS_UNIT_SERDES_MUX_MULTI_0_ALPINE_V2_SELECT_OH_SERDES_15_MASK 0x70000000 +#define PBS_UNIT_SERDES_MUX_MULTI_0_ALPINE_V2_SELECT_OH_SERDES_15_SHIFT 28 /**** serdes_mux_multi_1 register ****/ /* SerDes one hot mux control. For details see datasheet. */ @@ -1632,62 +1641,62 @@ struct al_pbs_low_latency_sram_remap low_latency_sram_remap; * 2'b01 - eth_a[0] from serdes_8 * 2'b10 - eth_a[0] from serdes_14 */ -#define PBS_UNIT_SERDES_MUX_ETH_PKR_SELECT_OH_ETH_A_0_MASK 0x00000003 -#define PBS_UNIT_SERDES_MUX_ETH_PKR_SELECT_OH_ETH_A_0_SHIFT 0 +#define PBS_UNIT_SERDES_MUX_ETH_ALPINE_V2_SELECT_OH_ETH_A_0_MASK 0x00000003 +#define PBS_UNIT_SERDES_MUX_ETH_ALPINE_V2_SELECT_OH_ETH_A_0_SHIFT 0 /* * 2'b01 - eth_b[0] from serdes_9 * 2'b10 - eth_b[0] from serdes_13 */ -#define PBS_UNIT_SERDES_MUX_ETH_PKR_SELECT_OH_ETH_B_0_MASK 0x00000030 -#define PBS_UNIT_SERDES_MUX_ETH_PKR_SELECT_OH_ETH_B_0_SHIFT 4 +#define PBS_UNIT_SERDES_MUX_ETH_ALPINE_V2_SELECT_OH_ETH_B_0_MASK 0x00000030 +#define PBS_UNIT_SERDES_MUX_ETH_ALPINE_V2_SELECT_OH_ETH_B_0_SHIFT 4 /* * 2'b01 - eth_c[0] from serdes_10 * 2'b10 - eth_c[0] from serdes_12 */ -#define PBS_UNIT_SERDES_MUX_ETH_PKR_SELECT_OH_ETH_C_0_MASK 0x00000300 -#define PBS_UNIT_SERDES_MUX_ETH_PKR_SELECT_OH_ETH_C_0_SHIFT 8 +#define PBS_UNIT_SERDES_MUX_ETH_ALPINE_V2_SELECT_OH_ETH_C_0_MASK 0x00000300 +#define PBS_UNIT_SERDES_MUX_ETH_ALPINE_V2_SELECT_OH_ETH_C_0_SHIFT 8 /* * 2'b01 - eth_d[0] from serdes_11 * 2'b10 - eth_d[0] from serdes_15 */ -#define PBS_UNIT_SERDES_MUX_ETH_PKR_SELECT_OH_ETH_D_0_MASK 0x00003000 -#define PBS_UNIT_SERDES_MUX_ETH_PKR_SELECT_OH_ETH_D_0_SHIFT 12 +#define PBS_UNIT_SERDES_MUX_ETH_ALPINE_V2_SELECT_OH_ETH_D_0_MASK 0x00003000 +#define PBS_UNIT_SERDES_MUX_ETH_ALPINE_V2_SELECT_OH_ETH_D_0_SHIFT 12 /* which lane's is master clk */ -#define PBS_UNIT_SERDES_MUX_ETH_PKR_SELECT_OH_ETH_A_ICK_MASTER_MASK 0x00030000 -#define PBS_UNIT_SERDES_MUX_ETH_PKR_SELECT_OH_ETH_A_ICK_MASTER_SHIFT 16 +#define PBS_UNIT_SERDES_MUX_ETH_ALPINE_V2_SELECT_OH_ETH_A_ICK_MASTER_MASK 0x00030000 +#define PBS_UNIT_SERDES_MUX_ETH_ALPINE_V2_SELECT_OH_ETH_A_ICK_MASTER_SHIFT 16 /* which lane's is master clk */ -#define PBS_UNIT_SERDES_MUX_ETH_PKR_SELECT_OH_ETH_C_ICK_MASTER_MASK 0x00300000 -#define PBS_UNIT_SERDES_MUX_ETH_PKR_SELECT_OH_ETH_C_ICK_MASTER_SHIFT 20 +#define PBS_UNIT_SERDES_MUX_ETH_ALPINE_V2_SELECT_OH_ETH_C_ICK_MASTER_MASK 0x00300000 +#define PBS_UNIT_SERDES_MUX_ETH_ALPINE_V2_SELECT_OH_ETH_C_ICK_MASTER_SHIFT 20 /* enable xlaui on eth a */ -#define PBS_UNIT_SERDES_MUX_ETH_PKR_SELECT_OH_ETH_A_XLAUI_ENABLE (1 << 24) +#define PBS_UNIT_SERDES_MUX_ETH_ALPINE_V2_SELECT_OH_ETH_A_XLAUI_ENABLE (1 << 24) /* enable xlaui on eth c */ -#define PBS_UNIT_SERDES_MUX_ETH_PKR_SELECT_OH_ETH_C_XLAUI_ENABLE (1 << 28) +#define PBS_UNIT_SERDES_MUX_ETH_ALPINE_V2_SELECT_OH_ETH_C_XLAUI_ENABLE (1 << 28) /**** serdes_mux_pcie register ****/ /* * 2'b01 - select pcie_b[0] from serdes 2 * 2'b10 - select pcie_b[0] from serdes 4 */ -#define PBS_UNIT_SERDES_MUX_PCIE_PKR_SELECT_OH_PCIE_B_0_MASK 0x00000003 -#define PBS_UNIT_SERDES_MUX_PCIE_PKR_SELECT_OH_PCIE_B_0_SHIFT 0 +#define PBS_UNIT_SERDES_MUX_PCIE_ALPINE_V2_SELECT_OH_PCIE_B_0_MASK 0x00000003 +#define PBS_UNIT_SERDES_MUX_PCIE_ALPINE_V2_SELECT_OH_PCIE_B_0_SHIFT 0 /* * 2'b01 - select pcie_b[1] from serdes 3 * 2'b10 - select pcie_b[1] from serdes 5 */ -#define PBS_UNIT_SERDES_MUX_PCIE_PKR_SELECT_OH_PCIE_B_1_MASK 0x00000030 -#define PBS_UNIT_SERDES_MUX_PCIE_PKR_SELECT_OH_PCIE_B_1_SHIFT 4 +#define PBS_UNIT_SERDES_MUX_PCIE_ALPINE_V2_SELECT_OH_PCIE_B_1_MASK 0x00000030 +#define PBS_UNIT_SERDES_MUX_PCIE_ALPINE_V2_SELECT_OH_PCIE_B_1_SHIFT 4 /* * 2'b01 - select pcie_d[0] from serdes 10 * 2'b10 - select pcie_d[0] from serdes 12 */ -#define PBS_UNIT_SERDES_MUX_PCIE_PKR_SELECT_OH_PCIE_D_0_MASK 0x00000300 -#define PBS_UNIT_SERDES_MUX_PCIE_PKR_SELECT_OH_PCIE_D_0_SHIFT 8 +#define PBS_UNIT_SERDES_MUX_PCIE_ALPINE_V2_SELECT_OH_PCIE_D_0_MASK 0x00000300 +#define PBS_UNIT_SERDES_MUX_PCIE_ALPINE_V2_SELECT_OH_PCIE_D_0_SHIFT 8 /* * 2'b01 - select pcie_d[1] from serdes 11 * 2'b10 - select pcie_d[1] from serdes 13 */ -#define PBS_UNIT_SERDES_MUX_PCIE_PKR_SELECT_OH_PCIE_D_1_MASK 0x00003000 -#define PBS_UNIT_SERDES_MUX_PCIE_PKR_SELECT_OH_PCIE_D_1_SHIFT 12 +#define PBS_UNIT_SERDES_MUX_PCIE_ALPINE_V2_SELECT_OH_PCIE_D_1_MASK 0x00003000 +#define PBS_UNIT_SERDES_MUX_PCIE_ALPINE_V2_SELECT_OH_PCIE_D_1_SHIFT 12 /**** serdes_mux_sata register ****/ /* diff --git a/al_hal_pcie.c b/al_hal_pcie.c index 3a221d36573..0ef7bc01d76 100644 --- a/al_hal_pcie.c +++ b/al_hal_pcie.c @@ -96,6 +96,8 @@ __FBSDID("$FreeBSD$"); #define AL_PCIE_PARSE_LANES(v) (((1 << v) - 1) << \ PCIE_REVX_AXI_MISC_PCIE_GLOBAL_CONF_NOF_ACT_LANES_SHIFT) +#define AL_PCIE_FLR_DONE_INTERVAL 10 + /** * Static functions */ @@ -183,10 +185,6 @@ al_pcie_port_link_config( return -EINVAL; } - al_dbg("PCIe %d: link config: max speed gen %d, max lanes %d, reversal %s\n", - pcie_port->port_id, link_params->max_speed, - pcie_port->max_lanes, link_params->enable_reversal? "enable" : "disable"); - al_pcie_port_link_speed_ctrl_set(pcie_port, link_params->max_speed); /* Change Max Payload Size, if needed. @@ -220,12 +218,6 @@ al_pcie_port_link_config( (max_lanes + (max_lanes-1)) << PCIE_PORT_LINK_CTRL_LINK_CAPABLE_SHIFT); - /* TODO: add support for reversal mode */ - if (link_params->enable_reversal) { - al_err("PCIe %d: enabling reversal mode not implemented\n", - pcie_port->port_id); - return -ENOSYS; - } return 0; } @@ -364,12 +356,9 @@ al_pcie_rev_id_get( PBS_UNIT_CHIP_ID_DEV_ID_MASK, PBS_UNIT_CHIP_ID_DEV_ID_SHIFT); - if (chip_id_dev == PBS_UNIT_CHIP_ID_DEV_ID_ALPINE) { - rev_id = AL_REG_FIELD_GET( - chip_id, - PBS_UNIT_CHIP_ID_DEV_REV_ID_MASK, - PBS_UNIT_CHIP_ID_DEV_REV_ID_SHIFT); - } else if (chip_id_dev == PBS_UNIT_CHIP_ID_DEV_ID_PEAKROCK) { + if (chip_id_dev == PBS_UNIT_CHIP_ID_DEV_ID_ALPINE_V1) { + rev_id = AL_PCIE_REV_ID_1; + } else if (chip_id_dev == PBS_UNIT_CHIP_ID_DEV_ID_ALPINE_V2) { struct al_pcie_revx_regs __iomem *regs = (struct al_pcie_revx_regs __iomem *)pcie_reg_base; uint32_t dev_id; @@ -469,20 +458,6 @@ al_pcie_ib_hcrd_os_ob_reads_config_default( al_pcie_port_ib_hcrd_os_ob_reads_config(pcie_port, &ib_hcrd_os_ob_reads_config); }; -/** return AL_TRUE is link started (LTSSM enabled) and AL_FALSE otherwise */ -static al_bool -al_pcie_is_link_started(struct al_pcie_port *pcie_port) -{ - struct al_pcie_regs *regs = (struct al_pcie_regs *)pcie_port->regs; - - uint32_t port_init = al_reg_read32(regs->app.global_ctrl.port_init); - uint8_t ltssm_en = AL_REG_FIELD_GET(port_init, - PCIE_W_GLOBAL_CTRL_PORT_INIT_APP_LTSSM_EN_MASK, - PCIE_W_GLOBAL_CTRL_PORT_INIT_APP_LTSSM_EN_SHIFT); - - return ltssm_en; -} - /** return AL_TRUE if link is up, AL_FALSE otherwise */ static al_bool al_pcie_check_link( @@ -650,18 +625,6 @@ al_pcie_port_gen3_params_config(struct al_pcie_port *pcie_port, return 0; } -static int -al_pcie_port_tl_credits_config( - struct al_pcie_port *pcie_port, - const struct al_pcie_tl_credits_params *tl_credits __attribute__((__unused__))) -{ - al_err("PCIe %d: transport layer credits config not implemented\n", - pcie_port->port_id); - - return -ENOSYS; - -} - static int al_pcie_port_pf_params_config(struct al_pcie_pf *pcie_pf, const struct al_pcie_pf_config_params *pf_params) @@ -680,22 +643,21 @@ al_pcie_port_pf_params_config(struct al_pcie_pf *pcie_pf, regs->core_space[pf_num].pcie_pm_cap_base, AL_FIELD_MASK(26, 25) | AL_FIELD_MASK(31, 28), 0); - /* Disable FLR capability */ + /* Set/Clear FLR bit */ if (pf_params->cap_flr_dis) al_reg_write32_masked( regs->core_space[pf_num].pcie_dev_cap_base, - AL_BIT(28), 0); + AL_PCI_EXP_DEVCAP_FLR, 0); + else + al_reg_write32_masked( + regs->core_space[pcie_pf->pf_num].pcie_dev_cap_base, + AL_PCI_EXP_DEVCAP_FLR, AL_PCI_EXP_DEVCAP_FLR); /* Disable ASPM capability */ if (pf_params->cap_aspm_dis) { al_reg_write32_masked( regs->core_space[pf_num].pcie_cap_base + (AL_PCI_EXP_LNKCAP >> 2), AL_PCI_EXP_LNKCAP_ASPMS, 0); - } else if (pcie_port->rev_id == AL_PCIE_REV_ID_0) { - al_warn("%s: ASPM support is enabled, please disable it\n", - __func__); - ret = -EINVAL; - goto done; } if (!pf_params->bar_params_valid) { @@ -743,8 +705,9 @@ al_pcie_port_pf_params_config(struct al_pcie_pf *pcie_pf, if (params->memory_space) { if (size < AL_PCIE_MIN_MEMORY_BAR_SIZE) { - al_err("PCIe %d: memory BAR %d: size (0x%llx) less that minimal allowed value\n", - pcie_port->port_id, bar_idx, size); + al_err("PCIe %d: memory BAR %d: size (0x%jx) less that minimal allowed value\n", + pcie_port->port_id, bar_idx, + (uintmax_t)size); ret = -EINVAL; goto done; } @@ -756,8 +719,9 @@ al_pcie_port_pf_params_config(struct al_pcie_pf *pcie_pf, } if (size < AL_PCIE_MIN_IO_BAR_SIZE) { - al_err("PCIe %d: IO BAR %d: size (0x%llx) less that minimal allowed value\n", - pcie_port->port_id, bar_idx, size); + al_err("PCIe %d: IO BAR %d: size (0x%jx) less that minimal allowed value\n", + pcie_port->port_id, bar_idx, + (uintmax_t)size); ret = -EINVAL; goto done; } @@ -765,9 +729,9 @@ al_pcie_port_pf_params_config(struct al_pcie_pf *pcie_pf, /* size must be power of 2 */ if (size & (size - 1)) { - al_err("PCIe %d: BAR %d:size (0x%llx) must be " + al_err("PCIe %d: BAR %d:size (0x%jx) must be " "power of 2\n", - pcie_port->port_id, bar_idx, size); + pcie_port->port_id, bar_idx, (uintmax_t)size); ret = -EINVAL; goto done; } @@ -826,8 +790,7 @@ al_pcie_port_pf_params_config(struct al_pcie_pf *pcie_pf, } /* Open CPU generated msi and legacy interrupts in pcie wrapper logic */ - if ((pcie_port->rev_id == AL_PCIE_REV_ID_0) || - (pcie_port->rev_id == AL_PCIE_REV_ID_1)) { + if (pcie_port->rev_id == AL_PCIE_REV_ID_1) { al_reg_write32(regs->app.soc_int[pf_num].mask_inta_leg_0, (1 << 21)); } else if ((pcie_port->rev_id == AL_PCIE_REV_ID_2) || (pcie_port->rev_id == AL_PCIE_REV_ID_3)) { @@ -853,13 +816,7 @@ al_pcie_port_pf_params_config(struct al_pcie_pf *pcie_pf, * Restore the original value after the write to app.soc.mask_msi_leg_0 * register. */ - if (pcie_port->rev_id == AL_PCIE_REV_ID_0) { - uint32_t backup; - - backup = al_reg_read32(®s->app.int_grp_a->mask); - al_reg_write32(regs->app.soc_int[pf_num].mask_msi_leg_0, (1 << 22)); - al_reg_write32(®s->app.int_grp_a->mask, backup); - } else if (pcie_port->rev_id == AL_PCIE_REV_ID_1) { + if (pcie_port->rev_id == AL_PCIE_REV_ID_1) { al_reg_write32(regs->app.soc_int[pf_num].mask_msi_leg_0, (1 << 22)); } else if ((pcie_port->rev_id == AL_PCIE_REV_ID_2) || (pcie_port->rev_id == AL_PCIE_REV_ID_3)) { @@ -878,22 +835,6 @@ done: return ret; } -static void -al_pcie_port_features_config( - struct al_pcie_port *pcie_port, - const struct al_pcie_features *features) -{ - struct al_pcie_regs *regs = pcie_port->regs; - - al_assert(pcie_port->rev_id > AL_PCIE_REV_ID_0); - - al_reg_write32_masked( - ®s->app.ctrl_gen->features, - PCIE_W_CTRL_GEN_FEATURES_SATA_EP_MSI_FIX, - features->sata_ep_msi_fix ? - PCIE_W_CTRL_GEN_FEATURES_SATA_EP_MSI_FIX : 0); -} - static int al_pcie_port_sris_config( struct al_pcie_port *pcie_port, @@ -916,6 +857,9 @@ al_pcie_port_sris_config( switch (pcie_port->rev_id) { case AL_PCIE_REV_ID_3: + al_reg_write32_masked(®s->app.cfg_func_ext->cfg, + PCIE_W_CFG_FUNC_EXT_CFG_APP_SRIS_MODE, + PCIE_W_CFG_FUNC_EXT_CFG_APP_SRIS_MODE); case AL_PCIE_REV_ID_2: al_reg_write32_masked(regs->app.global_ctrl.sris_kp_counter, PCIE_W_GLOBAL_CTRL_SRIS_KP_COUNTER_VALUE_GEN3_SRIS_MASK | @@ -989,6 +933,34 @@ al_pcie_port_max_num_of_pfs_get(struct al_pcie_port *pcie_port) return 1; } +/** Enable ecrc generation in outbound atu (Addressing RMN: 5119) */ +static void al_pcie_ecrc_gen_ob_atu_enable(struct al_pcie_port *pcie_port, unsigned int pf_num) +{ + struct al_pcie_regs *regs = pcie_port->regs; + int max_ob_atu = (pcie_port->rev_id == AL_PCIE_REV_ID_3) ? + AL_PCIE_REV_3_ATU_NUM_OUTBOUND_REGIONS : AL_PCIE_REV_1_2_ATU_NUM_OUTBOUND_REGIONS; + int i; + for (i = 0; i < max_ob_atu; i++) { + al_bool enable = 0; + uint32_t reg = 0; + unsigned int func_num; + AL_REG_FIELD_SET(reg, 0xF, 0, i); + AL_REG_BIT_VAL_SET(reg, 31, AL_PCIE_ATU_DIR_OUTBOUND); + al_reg_write32(®s->port_regs->iatu.index, reg); + reg = al_reg_read32(®s->port_regs->iatu.cr2); + enable = AL_REG_BIT_GET(reg, 31) ? AL_TRUE : AL_FALSE; + reg = al_reg_read32(®s->port_regs->iatu.cr1); + func_num = AL_REG_FIELD_GET(reg, + PCIE_IATU_CR1_FUNC_NUM_MASK, + PCIE_IATU_CR1_FUNC_NUM_SHIFT); + if ((enable == AL_TRUE) && (pf_num == func_num)) { + /* Set TD bit */ + AL_REG_BIT_SET(reg, 8); + al_reg_write32(®s->port_regs->iatu.cr1, reg); + } + } +} + /******************************************************************************/ /***************************** API Implementation *****************************/ /******************************************************************************/ @@ -1025,12 +997,13 @@ al_pcie_port_handle_init( /* Zero all regs */ al_memset(pcie_port->regs, 0, sizeof(struct al_pcie_regs)); - if ((pcie_port->rev_id == AL_PCIE_REV_ID_0) || - (pcie_port->rev_id == AL_PCIE_REV_ID_1)) { + if (pcie_port->rev_id == AL_PCIE_REV_ID_1) { struct al_pcie_rev1_regs __iomem *regs = (struct al_pcie_rev1_regs __iomem *)pcie_reg_base; pcie_port->regs->axi.ctrl.global = ®s->axi.ctrl.global; + pcie_port->regs->axi.ctrl.master_rctl = ®s->axi.ctrl.master_rctl; + pcie_port->regs->axi.ctrl.master_ctl = ®s->axi.ctrl.master_ctl; pcie_port->regs->axi.ctrl.master_arctl = ®s->axi.ctrl.master_arctl; pcie_port->regs->axi.ctrl.master_awctl = ®s->axi.ctrl.master_awctl; pcie_port->regs->axi.ctrl.slv_ctl = ®s->axi.ctrl.slv_ctl; @@ -1059,20 +1032,21 @@ al_pcie_port_handle_init( pcie_port->regs->app.global_ctrl.pm_control = ®s->app.global_ctrl.pm_control; pcie_port->regs->app.global_ctrl.events_gen[0] = ®s->app.global_ctrl.events_gen; pcie_port->regs->app.debug = ®s->app.debug; + pcie_port->regs->app.soc_int[0].status_0 = ®s->app.soc_int.status_0; + pcie_port->regs->app.soc_int[0].status_1 = ®s->app.soc_int.status_1; + pcie_port->regs->app.soc_int[0].status_2 = ®s->app.soc_int.status_2; pcie_port->regs->app.soc_int[0].mask_inta_leg_0 = ®s->app.soc_int.mask_inta_leg_0; + pcie_port->regs->app.soc_int[0].mask_inta_leg_1 = ®s->app.soc_int.mask_inta_leg_1; + pcie_port->regs->app.soc_int[0].mask_inta_leg_2 = ®s->app.soc_int.mask_inta_leg_2; pcie_port->regs->app.soc_int[0].mask_msi_leg_0 = ®s->app.soc_int.mask_msi_leg_0; + pcie_port->regs->app.soc_int[0].mask_msi_leg_1 = ®s->app.soc_int.mask_msi_leg_1; + pcie_port->regs->app.soc_int[0].mask_msi_leg_2 = ®s->app.soc_int.mask_msi_leg_2; pcie_port->regs->app.ctrl_gen = ®s->app.ctrl_gen; pcie_port->regs->app.parity = ®s->app.parity; pcie_port->regs->app.atu.in_mask_pair = regs->app.atu.in_mask_pair; pcie_port->regs->app.atu.out_mask_pair = regs->app.atu.out_mask_pair; - - if (pcie_port->rev_id == AL_PCIE_REV_ID_0) { - pcie_port->regs->app.int_grp_a = ®s->app.int_grp_a_m0; - pcie_port->regs->app.int_grp_b = ®s->app.int_grp_b_m0; - } else { - pcie_port->regs->app.int_grp_a = ®s->app.int_grp_a; - pcie_port->regs->app.int_grp_b = ®s->app.int_grp_b; - } + pcie_port->regs->app.int_grp_a = ®s->app.int_grp_a; + pcie_port->regs->app.int_grp_b = ®s->app.int_grp_b; pcie_port->regs->core_space[0].config_header = regs->core_space.config_header; pcie_port->regs->core_space[0].pcie_pm_cap_base = ®s->core_space.pcie_pm_cap_base; @@ -1091,6 +1065,8 @@ al_pcie_port_handle_init( (struct al_pcie_rev2_regs __iomem *)pcie_reg_base; pcie_port->regs->axi.ctrl.global = ®s->axi.ctrl.global; + pcie_port->regs->axi.ctrl.master_rctl = ®s->axi.ctrl.master_rctl; + pcie_port->regs->axi.ctrl.master_ctl = ®s->axi.ctrl.master_ctl; pcie_port->regs->axi.ctrl.master_arctl = ®s->axi.ctrl.master_arctl; pcie_port->regs->axi.ctrl.master_awctl = ®s->axi.ctrl.master_awctl; pcie_port->regs->axi.ctrl.slv_ctl = ®s->axi.ctrl.slv_ctl; @@ -1100,6 +1076,10 @@ al_pcie_port_handle_init( pcie_port->regs->axi.ob_ctrl.io_start_h = ®s->axi.ob_ctrl.io_start_h; pcie_port->regs->axi.ob_ctrl.io_limit_l = ®s->axi.ob_ctrl.io_limit_l; pcie_port->regs->axi.ob_ctrl.io_limit_h = ®s->axi.ob_ctrl.io_limit_h; + pcie_port->regs->axi.ob_ctrl.tgtid_reg_ovrd = ®s->axi.ob_ctrl.tgtid_reg_ovrd; + pcie_port->regs->axi.ob_ctrl.addr_high_reg_ovrd_sel = ®s->axi.ob_ctrl.addr_high_reg_ovrd_sel; + pcie_port->regs->axi.ob_ctrl.addr_high_reg_ovrd_value = ®s->axi.ob_ctrl.addr_high_reg_ovrd_value; + pcie_port->regs->axi.ob_ctrl.addr_size_replace = ®s->axi.ob_ctrl.addr_size_replace; pcie_port->regs->axi.pcie_global.conf = ®s->axi.pcie_global.conf; pcie_port->regs->axi.conf.zero_lane0 = ®s->axi.conf.zero_lane0; pcie_port->regs->axi.conf.zero_lane1 = ®s->axi.conf.zero_lane1; @@ -1120,11 +1100,20 @@ al_pcie_port_handle_init( pcie_port->regs->app.global_ctrl.events_gen[0] = ®s->app.global_ctrl.events_gen; pcie_port->regs->app.global_ctrl.corr_err_sts_int = ®s->app.global_ctrl.pended_corr_err_sts_int; pcie_port->regs->app.global_ctrl.uncorr_err_sts_int = ®s->app.global_ctrl.pended_uncorr_err_sts_int; + pcie_port->regs->app.global_ctrl.sris_kp_counter = ®s->app.global_ctrl.sris_kp_counter_value; pcie_port->regs->app.debug = ®s->app.debug; pcie_port->regs->app.ap_user_send_msg = ®s->app.ap_user_send_msg; + pcie_port->regs->app.soc_int[0].status_0 = ®s->app.soc_int.status_0; + pcie_port->regs->app.soc_int[0].status_1 = ®s->app.soc_int.status_1; + pcie_port->regs->app.soc_int[0].status_2 = ®s->app.soc_int.status_2; + pcie_port->regs->app.soc_int[0].status_3 = ®s->app.soc_int.status_3; pcie_port->regs->app.soc_int[0].mask_inta_leg_0 = ®s->app.soc_int.mask_inta_leg_0; + pcie_port->regs->app.soc_int[0].mask_inta_leg_1 = ®s->app.soc_int.mask_inta_leg_1; + pcie_port->regs->app.soc_int[0].mask_inta_leg_2 = ®s->app.soc_int.mask_inta_leg_2; pcie_port->regs->app.soc_int[0].mask_inta_leg_3 = ®s->app.soc_int.mask_inta_leg_3; pcie_port->regs->app.soc_int[0].mask_msi_leg_0 = ®s->app.soc_int.mask_msi_leg_0; + pcie_port->regs->app.soc_int[0].mask_msi_leg_1 = ®s->app.soc_int.mask_msi_leg_1; + pcie_port->regs->app.soc_int[0].mask_msi_leg_2 = ®s->app.soc_int.mask_msi_leg_2; pcie_port->regs->app.soc_int[0].mask_msi_leg_3 = ®s->app.soc_int.mask_msi_leg_3; pcie_port->regs->app.ctrl_gen = ®s->app.ctrl_gen; pcie_port->regs->app.parity = ®s->app.parity; @@ -1150,6 +1139,8 @@ al_pcie_port_handle_init( struct al_pcie_rev3_regs __iomem *regs = (struct al_pcie_rev3_regs __iomem *)pcie_reg_base; pcie_port->regs->axi.ctrl.global = ®s->axi.ctrl.global; + pcie_port->regs->axi.ctrl.master_rctl = ®s->axi.ctrl.master_rctl; + pcie_port->regs->axi.ctrl.master_ctl = ®s->axi.ctrl.master_ctl; pcie_port->regs->axi.ctrl.master_arctl = ®s->axi.ctrl.master_arctl; pcie_port->regs->axi.ctrl.master_awctl = ®s->axi.ctrl.master_awctl; pcie_port->regs->axi.ctrl.slv_ctl = ®s->axi.ctrl.slv_ctl; @@ -1159,6 +1150,13 @@ al_pcie_port_handle_init( pcie_port->regs->axi.ob_ctrl.io_start_h = ®s->axi.ob_ctrl.io_start_h; pcie_port->regs->axi.ob_ctrl.io_limit_l = ®s->axi.ob_ctrl.io_limit_l; pcie_port->regs->axi.ob_ctrl.io_limit_h = ®s->axi.ob_ctrl.io_limit_h; + pcie_port->regs->axi.ob_ctrl.io_addr_mask_h = ®s->axi.ob_ctrl.io_addr_mask_h; + pcie_port->regs->axi.ob_ctrl.ar_msg_addr_mask_h = ®s->axi.ob_ctrl.ar_msg_addr_mask_h; + pcie_port->regs->axi.ob_ctrl.aw_msg_addr_mask_h = ®s->axi.ob_ctrl.aw_msg_addr_mask_h; + pcie_port->regs->axi.ob_ctrl.tgtid_reg_ovrd = ®s->axi.ob_ctrl.tgtid_reg_ovrd; + pcie_port->regs->axi.ob_ctrl.addr_high_reg_ovrd_sel = ®s->axi.ob_ctrl.addr_high_reg_ovrd_sel; + pcie_port->regs->axi.ob_ctrl.addr_high_reg_ovrd_value = ®s->axi.ob_ctrl.addr_high_reg_ovrd_value; + pcie_port->regs->axi.ob_ctrl.addr_size_replace = ®s->axi.ob_ctrl.addr_size_replace; pcie_port->regs->axi.pcie_global.conf = ®s->axi.pcie_global.conf; pcie_port->regs->axi.conf.zero_lane0 = ®s->axi.conf.zero_lane0; pcie_port->regs->axi.conf.zero_lane1 = ®s->axi.conf.zero_lane1; @@ -1213,9 +1211,17 @@ al_pcie_port_handle_init( pcie_port->regs->app.debug = ®s->app.debug; for (i = 0; i < AL_MAX_NUM_OF_PFS; i++) { + pcie_port->regs->app.soc_int[i].status_0 = ®s->app.soc_int_per_func[i].status_0; + pcie_port->regs->app.soc_int[i].status_1 = ®s->app.soc_int_per_func[i].status_1; + pcie_port->regs->app.soc_int[i].status_2 = ®s->app.soc_int_per_func[i].status_2; + pcie_port->regs->app.soc_int[i].status_3 = ®s->app.soc_int_per_func[i].status_3; pcie_port->regs->app.soc_int[i].mask_inta_leg_0 = ®s->app.soc_int_per_func[i].mask_inta_leg_0; + pcie_port->regs->app.soc_int[i].mask_inta_leg_1 = ®s->app.soc_int_per_func[i].mask_inta_leg_1; + pcie_port->regs->app.soc_int[i].mask_inta_leg_2 = ®s->app.soc_int_per_func[i].mask_inta_leg_2; pcie_port->regs->app.soc_int[i].mask_inta_leg_3 = ®s->app.soc_int_per_func[i].mask_inta_leg_3; pcie_port->regs->app.soc_int[i].mask_msi_leg_0 = ®s->app.soc_int_per_func[i].mask_msi_leg_0; + pcie_port->regs->app.soc_int[i].mask_msi_leg_1 = ®s->app.soc_int_per_func[i].mask_msi_leg_1; + pcie_port->regs->app.soc_int[i].mask_msi_leg_2 = ®s->app.soc_int_per_func[i].mask_msi_leg_2; pcie_port->regs->app.soc_int[i].mask_msi_leg_3 = ®s->app.soc_int_per_func[i].mask_msi_leg_3; } @@ -1224,6 +1230,7 @@ al_pcie_port_handle_init( pcie_port->regs->app.parity = ®s->app.parity; pcie_port->regs->app.atu.in_mask_pair = regs->app.atu.in_mask_pair; pcie_port->regs->app.atu.out_mask_pair = regs->app.atu.out_mask_pair; + pcie_port->regs->app.cfg_func_ext = ®s->app.cfg_func_ext; for (i = 0; i < AL_MAX_NUM_OF_PFS; i++) pcie_port->regs->app.status_per_func[i] = ®s->app.status_per_func[i]; @@ -1260,6 +1267,10 @@ al_pcie_port_handle_init( /* set maximum number of physical functions */ pcie_port->max_num_of_pfs = al_pcie_port_max_num_of_pfs_get(pcie_port); + /* Clear 'nof_p_hdr' & 'nof_np_hdr' to later know if they where changed by the user */ + pcie_port->ib_hcrd_config.nof_np_hdr = 0; + pcie_port->ib_hcrd_config.nof_p_hdr = 0; + al_dbg("pcie port handle initialized. port id: %d, rev_id %d, regs base %p\n", port_id, pcie_port->rev_id, pcie_reg_base); return 0; @@ -1294,6 +1305,12 @@ al_pcie_pf_handle_init( return 0; } +/** Get port revision ID */ +int al_pcie_port_rev_id_get(struct al_pcie_port *pcie_port) +{ + return pcie_port->rev_id; +} + /************************** Pre PCIe Port Enable API **************************/ /** configure pcie operating mode (root complex or endpoint) */ @@ -1346,7 +1363,7 @@ al_pcie_port_operating_mode_config( "EndPoint" : "Root Complex"); return 0; } - al_info("PCIe %d: set operating mode to %s\n", + al_dbg("PCIe %d: set operating mode to %s\n", pcie_port->port_id, (mode == AL_PCIE_OPERATING_MODE_EP) ? "EndPoint" : "Root Complex"); AL_REG_FIELD_SET(reg, PCIE_AXI_MISC_PCIE_GLOBAL_CONF_DEV_TYPE_MASK, @@ -1362,6 +1379,7 @@ int al_pcie_port_max_lanes_set(struct al_pcie_port *pcie_port, uint8_t lanes) { struct al_pcie_regs *regs = pcie_port->regs; + uint32_t active_lanes_val; if (al_pcie_port_is_enabled(pcie_port)) { al_err("PCIe %d: already enabled, cannot set max lanes\n", @@ -1370,7 +1388,7 @@ al_pcie_port_max_lanes_set(struct al_pcie_port *pcie_port, uint8_t lanes) } /* convert to bitmask format (4 ->'b1111, 2 ->'b11, 1 -> 'b1) */ - uint32_t active_lanes_val = AL_PCIE_PARSE_LANES(lanes); + active_lanes_val = AL_PCIE_PARSE_LANES(lanes); al_reg_write32_masked(regs->axi.pcie_global.conf, (pcie_port->rev_id == AL_PCIE_REV_ID_3) ? @@ -1387,11 +1405,7 @@ al_pcie_port_max_num_of_pfs_set( struct al_pcie_port *pcie_port, uint8_t max_num_of_pfs) { - if (al_pcie_port_is_enabled(pcie_port)) { - al_err("PCIe %d: already enabled, cannot set max num of PFs\n", - pcie_port->port_id); - return -EINVAL; - } + struct al_pcie_regs *regs = pcie_port->regs; if (pcie_port->rev_id == AL_PCIE_REV_ID_3) al_assert(max_num_of_pfs <= REV3_MAX_NUM_OF_PFS); @@ -1400,6 +1414,33 @@ al_pcie_port_max_num_of_pfs_set( pcie_port->max_num_of_pfs = max_num_of_pfs; + if (al_pcie_port_is_enabled(pcie_port) && (pcie_port->rev_id == AL_PCIE_REV_ID_3)) { + enum al_pcie_operating_mode op_mode = al_pcie_operating_mode_get(pcie_port); + + al_bool is_multi_pf = + ((op_mode == AL_PCIE_OPERATING_MODE_EP) && (pcie_port->max_num_of_pfs > 1)); + + /* Set maximum physical function numbers */ + al_reg_write32_masked( + ®s->port_regs->timer_ctrl_max_func_num, + PCIE_PORT_GEN3_MAX_FUNC_NUM, + pcie_port->max_num_of_pfs - 1); + + al_pcie_port_wr_to_ro_set(pcie_port, AL_TRUE); + + /** + * in EP mode, when we have more than 1 PF we need to assert + * multi-pf support so the host scan all PFs + */ + al_reg_write32_masked((uint32_t __iomem *) + (®s->core_space[0].config_header[0] + + (PCIE_BIST_HEADER_TYPE_BASE >> 2)), + PCIE_BIST_HEADER_TYPE_MULTI_FUNC_MASK, + is_multi_pf ? PCIE_BIST_HEADER_TYPE_MULTI_FUNC_MASK : 0); + + al_pcie_port_wr_to_ro_set(pcie_port, AL_FALSE); + } + return 0; } @@ -1503,6 +1544,28 @@ al_pcie_operating_mode_get( return AL_PCIE_OPERATING_MODE_UNKNOWN; } +/* PCIe AXI quality of service configuration */ +void al_pcie_axi_qos_config( + struct al_pcie_port *pcie_port, + unsigned int arqos, + unsigned int awqos) +{ + struct al_pcie_regs *regs = pcie_port->regs; + + al_assert(pcie_port); + al_assert(arqos <= PCIE_AXI_CTRL_MASTER_ARCTL_ARQOS_VAL_MAX); + al_assert(awqos <= PCIE_AXI_CTRL_MASTER_AWCTL_AWQOS_VAL_MAX); + + al_reg_write32_masked( + regs->axi.ctrl.master_arctl, + PCIE_AXI_CTRL_MASTER_ARCTL_ARQOS_MASK, + arqos << PCIE_AXI_CTRL_MASTER_ARCTL_ARQOS_SHIFT); + al_reg_write32_masked( + regs->axi.ctrl.master_awctl, + PCIE_AXI_CTRL_MASTER_AWCTL_AWQOS_MASK, + awqos << PCIE_AXI_CTRL_MASTER_AWCTL_AWQOS_SHIFT); +} + /**************************** PCIe Port Enable API ****************************/ /** Enable PCIe port (deassert reset) */ @@ -1518,17 +1581,19 @@ al_pcie_port_enable(struct al_pcie_port *pcie_port) /** * Set inbound header credit and outstanding outbound reads defaults + * if the port initiator doesn't set it. * Must be called before port enable (PCIE_EXIST) */ - al_pcie_ib_hcrd_os_ob_reads_config_default(pcie_port); + if ((pcie_port->ib_hcrd_config.nof_np_hdr == 0) || + (pcie_port->ib_hcrd_config.nof_p_hdr == 0)) + al_pcie_ib_hcrd_os_ob_reads_config_default(pcie_port); /* * Disable ATS capability * - must be done before core reset deasserted * - rev_id 0 - no effect, but no harm */ - if ((pcie_port->rev_id == AL_PCIE_REV_ID_0) || - (pcie_port->rev_id == AL_PCIE_REV_ID_1) || + if ((pcie_port->rev_id == AL_PCIE_REV_ID_1) || (pcie_port->rev_id == AL_PCIE_REV_ID_2)) { al_reg_write32_masked( regs->axi.ordering.pos_cntl, @@ -1679,26 +1744,8 @@ al_pcie_port_config(struct al_pcie_port *pcie_port, } if (pcie_port->rev_id == AL_PCIE_REV_ID_3) { - /* Set maximum physical function numbers */ - al_reg_write32_masked( - ®s->port_regs->timer_ctrl_max_func_num, - PCIE_PORT_GEN3_MAX_FUNC_NUM, - pcie_port->max_num_of_pfs - 1); - al_pcie_port_wr_to_ro_set(pcie_port, AL_TRUE); - /** - * in EP mode, when we have more than 1 PF we need to assert - * multi-pf support so the host scan all PFs - */ - if ((op_mode == AL_PCIE_OPERATING_MODE_EP) && (pcie_port->max_num_of_pfs > 1)) { - al_reg_write32_masked((uint32_t __iomem *) - (®s->core_space[0].config_header[0] + - (PCIE_BIST_HEADER_TYPE_BASE >> 2)), - PCIE_BIST_HEADER_TYPE_MULTI_FUNC_MASK, - PCIE_BIST_HEADER_TYPE_MULTI_FUNC_MASK); - } - /* Disable TPH next pointer */ for (i = 0; i < AL_MAX_NUM_OF_PFS; i++) { al_reg_write32_masked(regs->core_space[i].tph_cap_base, @@ -1713,6 +1760,8 @@ al_pcie_port_config(struct al_pcie_port *pcie_port, if (status) goto done; + al_pcie_port_max_num_of_pfs_set(pcie_port, pcie_port->max_num_of_pfs); + al_pcie_port_ram_parity_int_config(pcie_port, params->enable_ram_parity_int); al_pcie_port_axi_parity_int_config(pcie_port, params->enable_axi_parity_int); @@ -1734,14 +1783,6 @@ al_pcie_port_config(struct al_pcie_port *pcie_port, if (status) goto done; - if (params->tl_credits) - status = al_pcie_port_tl_credits_config(pcie_port, params->tl_credits); - if (status) - goto done; - - if (params->features) - al_pcie_port_features_config(pcie_port, params->features); - if (params->sris_params) status = al_pcie_port_sris_config(pcie_port, params->sris_params, params->link_params->max_speed); @@ -1904,6 +1945,19 @@ al_pcie_link_stop(struct al_pcie_port *pcie_port) return 0; } +/** return AL_TRUE is link started (LTSSM enabled) and AL_FALSE otherwise */ +al_bool al_pcie_is_link_started(struct al_pcie_port *pcie_port) +{ + struct al_pcie_regs *regs = (struct al_pcie_regs *)pcie_port->regs; + + uint32_t port_init = al_reg_read32(regs->app.global_ctrl.port_init); + uint8_t ltssm_en = AL_REG_FIELD_GET(port_init, + PCIE_W_GLOBAL_CTRL_PORT_INIT_APP_LTSSM_EN_MASK, + PCIE_W_GLOBAL_CTRL_PORT_INIT_APP_LTSSM_EN_SHIFT); + + return ltssm_en; +} + /* wait for link up indication */ int al_pcie_link_up_wait(struct al_pcie_port *pcie_port, uint32_t timeout_ms) @@ -1912,7 +1966,7 @@ al_pcie_link_up_wait(struct al_pcie_port *pcie_port, uint32_t timeout_ms) while (wait_count-- > 0) { if (al_pcie_check_link(pcie_port, NULL)) { - al_info("PCIe_%d: <<<<<<<<< Link up >>>>>>>>>\n", pcie_port->port_id); + al_dbg("PCIe_%d: <<<<<<<<< Link up >>>>>>>>>\n", pcie_port->port_id); return 0; } else al_dbg("PCIe_%d: No link up, %d attempts remaining\n", @@ -1920,7 +1974,7 @@ al_pcie_link_up_wait(struct al_pcie_port *pcie_port, uint32_t timeout_ms) al_udelay(AL_PCIE_LINKUP_WAIT_INTERVAL); } - al_info("PCIE_%d: link is not established in time\n", + al_dbg("PCIE_%d: link is not established in time\n", pcie_port->port_id); return ETIMEDOUT; @@ -1936,6 +1990,15 @@ al_pcie_link_status(struct al_pcie_port *pcie_port, al_assert(status); + if (!al_pcie_port_is_enabled(pcie_port)) { + al_dbg("PCIe %d: port not enabled, no link.\n", pcie_port->port_id); + status->link_up = AL_FALSE; + status->speed = AL_PCIE_LINK_SPEED_DEFAULT; + status->lanes = 0; + status->ltssm_state = 0; + return 0; + } + status->link_up = al_pcie_check_link(pcie_port, &status->ltssm_state); if (!status->link_up) { @@ -1962,7 +2025,7 @@ al_pcie_link_status(struct al_pcie_port *pcie_port, pcie_port->port_id, pcie_lnksta); } status->lanes = (pcie_lnksta & AL_PCI_EXP_LNKSTA_NLW) >> AL_PCI_EXP_LNKSTA_NLW_SHIFT; - al_info("PCIe %d: Link up. speed gen%d negotiated width %d\n", + al_dbg("PCIe %d: Link up. speed gen%d negotiated width %d\n", pcie_port->port_id, status->speed, status->lanes); return 0; @@ -2143,7 +2206,7 @@ al_pcie_port_snoop_config(struct al_pcie_port *pcie_port, al_bool enable_axi_sno struct al_pcie_regs *regs = pcie_port->regs; /* Set snoop mode */ - al_info("PCIE_%d: snoop mode %s\n", + al_dbg("PCIE_%d: snoop mode %s\n", pcie_port->port_id, enable_axi_snoop ? "enable" : "disable"); if (enable_axi_snoop) { @@ -2311,6 +2374,19 @@ al_pcie_app_req_retry_set( mask, (en == AL_TRUE) ? mask : 0); } +/* Check if deferring incoming configuration requests is enabled or not */ +al_bool al_pcie_app_req_retry_get_status(struct al_pcie_port *pcie_port) +{ + struct al_pcie_regs *regs = pcie_port->regs; + uint32_t pm_control; + uint32_t mask = (pcie_port->rev_id == AL_PCIE_REV_ID_3) ? + PCIE_W_REV3_GLOBAL_CTRL_PM_CONTROL_APP_REQ_RETRY_EN : + PCIE_W_REV1_2_GLOBAL_CTRL_PM_CONTROL_APP_REQ_RETRY_EN; + + pm_control = al_reg_read32(regs->app.global_ctrl.pm_control); + return (pm_control & mask) ? AL_TRUE : AL_FALSE; +} + /*************** Internal Address Translation Unit (ATU) API ******************/ /** program internal ATU region entry */ @@ -2345,6 +2421,7 @@ al_pcie_atu_region_set( if (!atu_region->enforce_ob_atu_region_set) { al_err("PCIe %d: setting OB iATU after link is started is not allowed\n", pcie_port->port_id); + al_assert(AL_FALSE); return -EINVAL; } else { al_info("PCIe %d: setting OB iATU even after link is started\n", @@ -2369,7 +2446,63 @@ al_pcie_atu_region_set( /* configure the limit, not needed when working in BAR match mode */ if (atu_region->match_mode == 0) { uint32_t limit_reg_val; - if (pcie_port->rev_id > AL_PCIE_REV_ID_0) { + uint32_t *limit_ext_reg = + (atu_region->direction == AL_PCIE_ATU_DIR_OUTBOUND) ? + ®s->app.atu.out_mask_pair[atu_region->index / 2] : + ®s->app.atu.in_mask_pair[atu_region->index / 2]; + uint32_t limit_ext_reg_mask = + (atu_region->index % 2) ? + PCIE_W_ATU_MASK_EVEN_ODD_ATU_MASK_40_32_ODD_MASK : + PCIE_W_ATU_MASK_EVEN_ODD_ATU_MASK_40_32_EVEN_MASK; + unsigned int limit_ext_reg_shift = + (atu_region->index % 2) ? + PCIE_W_ATU_MASK_EVEN_ODD_ATU_MASK_40_32_ODD_SHIFT : + PCIE_W_ATU_MASK_EVEN_ODD_ATU_MASK_40_32_EVEN_SHIFT; + uint64_t limit_sz_msk = + atu_region->limit - atu_region->base_addr; + uint32_t limit_ext_reg_val = (uint32_t)(((limit_sz_msk) >> + 32) & 0xFFFFFFFF); + + if (limit_ext_reg_val) { + limit_reg_val = (uint32_t)((limit_sz_msk) & 0xFFFFFFFF); + al_assert(limit_reg_val == 0xFFFFFFFF); + } else { + limit_reg_val = (uint32_t)(atu_region->limit & + 0xFFFFFFFF); + } + + al_reg_write32_masked( + limit_ext_reg, + limit_ext_reg_mask, + limit_ext_reg_val << limit_ext_reg_shift); + + al_reg_write32(®s->port_regs->iatu.limit_addr, + limit_reg_val); + } + + + /** + * Addressing RMN: 3186 + * + * RMN description: + * Bug in SNPS IP (versions 4.21 , 4.10a-ea02) + * In CFG request created via outbound atu (shift mode) bits [27:12] go to + * [31:16] , the shifting is correct , however the ATU leaves bit [15:12] + * to their original values, this is then transmited in the tlp . + * Those bits are currently reserved ,bit might be non-resv. in future generations . + * + * Software flow: + * Enable HW fix + * rev=REV1,REV2 set bit 15 in corresponding app_reg.atu.out_mask + * rev>REV2 set corresponding bit is app_reg.atu.reg_out_mask + */ + if ((atu_region->cfg_shift_mode == AL_TRUE) && + (atu_region->direction == AL_PCIE_ATU_DIR_OUTBOUND)) { + if (pcie_port->rev_id > AL_PCIE_REV_ID_2) { + al_reg_write32_masked(regs->app.atu.reg_out_mask, + 1 << (atu_region->index) , + 1 << (atu_region->index)); + } else { uint32_t *limit_ext_reg = (atu_region->direction == AL_PCIE_ATU_DIR_OUTBOUND) ? ®s->app.atu.out_mask_pair[atu_region->index / 2] : @@ -2382,29 +2515,12 @@ al_pcie_atu_region_set( (atu_region->index % 2) ? PCIE_W_ATU_MASK_EVEN_ODD_ATU_MASK_40_32_ODD_SHIFT : PCIE_W_ATU_MASK_EVEN_ODD_ATU_MASK_40_32_EVEN_SHIFT; - uint64_t limit_sz_msk = - atu_region->limit - atu_region->base_addr; - uint32_t limit_ext_reg_val = (uint32_t)(((limit_sz_msk) >> - 32) & 0xFFFFFFFF); - - if (limit_ext_reg_val) { - limit_reg_val = (uint32_t)((limit_sz_msk) & 0xFFFFFFFF); - al_assert(limit_reg_val == 0xFFFFFFFF); - } else { - limit_reg_val = (uint32_t)(atu_region->limit & - 0xFFFFFFFF); - } al_reg_write32_masked( - limit_ext_reg, - limit_ext_reg_mask, - limit_ext_reg_val << limit_ext_reg_shift); - } else { - limit_reg_val = (uint32_t)(atu_region->limit & 0xFFFFFFFF); + limit_ext_reg, + limit_ext_reg_mask, + (AL_BIT(15)) << limit_ext_reg_shift); } - - al_reg_write32(®s->port_regs->iatu.limit_addr, - limit_reg_val); } reg = 0; @@ -2505,7 +2621,22 @@ al_pcie_axi_io_config( PCIE_AXI_CTRL_SLV_CTRL_IO_BAR_EN); } -/************** Interrupt generation (Endpoint mode Only) API *****************/ +/************** Interrupt and Event generation (Endpoint mode Only) API *****************/ + +int al_pcie_pf_flr_done_gen(struct al_pcie_pf *pcie_pf) +{ + struct al_pcie_regs *regs = pcie_pf->pcie_port->regs; + unsigned int pf_num = pcie_pf->pf_num; + + al_reg_write32_masked(regs->app.global_ctrl.events_gen[pf_num], + PCIE_W_GLOBAL_CTRL_EVENTS_GEN_FLR_PF_DONE, + PCIE_W_GLOBAL_CTRL_EVENTS_GEN_FLR_PF_DONE); + al_udelay(AL_PCIE_FLR_DONE_INTERVAL); + al_reg_write32_masked(regs->app.global_ctrl.events_gen[pf_num], + PCIE_W_GLOBAL_CTRL_EVENTS_GEN_FLR_PF_DONE, 0); + return 0; +} + /** generate INTx Assert/DeAssert Message */ int @@ -2607,15 +2738,16 @@ al_pcie_msix_masked(struct al_pcie_pf *pcie_pf) } /******************** Advanced Error Reporting (AER) API **********************/ - -/** configure AER capability */ -int -al_pcie_aer_config( - struct al_pcie_pf *pcie_pf, - struct al_pcie_aer_params *params) +/************************* Auxiliary functions ********************************/ +/* configure AER capability */ +static int +al_pcie_aer_config_aux( + struct al_pcie_port *pcie_port, + unsigned int pf_num, + struct al_pcie_aer_params *params) { - struct al_pcie_regs *regs = pcie_pf->pcie_port->regs; - struct al_pcie_core_aer_regs *aer_regs = regs->core_space[pcie_pf->pf_num].aer; + struct al_pcie_regs *regs = pcie_port->regs; + struct al_pcie_core_aer_regs *aer_regs = regs->core_space[pf_num].aer; uint32_t reg_val; reg_val = al_reg_read32(&aer_regs->header); @@ -2641,8 +2773,22 @@ al_pcie_aer_config( (params->ecrc_gen_en ? PCIE_AER_CTRL_STAT_ECRC_GEN_EN : 0) | (params->ecrc_chk_en ? PCIE_AER_CTRL_STAT_ECRC_CHK_EN : 0)); + /** + * Addressing RMN: 5119 + * + * RMN description: + * ECRC generation for outbound request translated by iATU is effected + * by iATU setting instead of ecrc_gen_bit in AER + * + * Software flow: + * When enabling ECRC generation, set the outbound iATU to generate ECRC + */ + if (params->ecrc_gen_en == AL_TRUE) { + al_pcie_ecrc_gen_ob_atu_enable(pcie_port, pf_num); + } + al_reg_write32_masked( - regs->core_space[pcie_pf->pf_num].pcie_dev_ctrl_status, + regs->core_space[pf_num].pcie_dev_ctrl_status, PCIE_PORT_DEV_CTRL_STATUS_CORR_ERR_REPORT_EN | PCIE_PORT_DEV_CTRL_STATUS_NON_FTL_ERR_REPORT_EN | PCIE_PORT_DEV_CTRL_STATUS_FTL_ERR_REPORT_EN | @@ -2663,12 +2809,14 @@ al_pcie_aer_config( return 0; } -/** AER uncorretable errors get and clear */ -unsigned int -al_pcie_aer_uncorr_get_and_clear(struct al_pcie_pf *pcie_pf) +/** AER uncorrectable errors get and clear */ +static unsigned int +al_pcie_aer_uncorr_get_and_clear_aux( + struct al_pcie_port *pcie_port, + unsigned int pf_num) { - struct al_pcie_regs *regs = pcie_pf->pcie_port->regs; - struct al_pcie_core_aer_regs *aer_regs = regs->core_space[pcie_pf->pf_num].aer; + struct al_pcie_regs *regs = pcie_port->regs; + struct al_pcie_core_aer_regs *aer_regs = regs->core_space[pf_num].aer; uint32_t reg_val; reg_val = al_reg_read32(&aer_regs->uncorr_err_stat); @@ -2677,12 +2825,14 @@ al_pcie_aer_uncorr_get_and_clear(struct al_pcie_pf *pcie_pf) return reg_val; } -/** AER corretable errors get and clear */ -unsigned int -al_pcie_aer_corr_get_and_clear(struct al_pcie_pf *pcie_pf) +/** AER correctable errors get and clear */ +static unsigned int +al_pcie_aer_corr_get_and_clear_aux( + struct al_pcie_port *pcie_port, + unsigned int pf_num) { - struct al_pcie_regs *regs = pcie_pf->pcie_port->regs; - struct al_pcie_core_aer_regs *aer_regs = regs->core_space[pcie_pf->pf_num].aer; + struct al_pcie_regs *regs = pcie_port->regs; + struct al_pcie_core_aer_regs *aer_regs = regs->core_space[pf_num].aer; uint32_t reg_val; reg_val = al_reg_read32(&aer_regs->corr_err_stat); @@ -2696,19 +2846,123 @@ al_pcie_aer_corr_get_and_clear(struct al_pcie_pf *pcie_pf) #endif /** AER get the header for the TLP corresponding to a detected error */ -void -al_pcie_aer_err_tlp_hdr_get( - struct al_pcie_pf *pcie_pf, +static void +al_pcie_aer_err_tlp_hdr_get_aux( + struct al_pcie_port *pcie_port, + unsigned int pf_num, uint32_t hdr[AL_PCIE_AER_ERR_TLP_HDR_NUM_DWORDS]) { - struct al_pcie_regs *regs = pcie_pf->pcie_port->regs; - struct al_pcie_core_aer_regs *aer_regs = regs->core_space[pcie_pf->pf_num].aer; + struct al_pcie_regs *regs = pcie_port->regs; + struct al_pcie_core_aer_regs *aer_regs = regs->core_space[pf_num].aer; int i; for (i = 0; i < AL_PCIE_AER_ERR_TLP_HDR_NUM_DWORDS; i++) hdr[i] = al_reg_read32(&aer_regs->header_log[i]); } +/******************** EP AER functions **********************/ +/** configure EP physical function AER capability */ +int al_pcie_aer_config( + struct al_pcie_pf *pcie_pf, + struct al_pcie_aer_params *params) +{ + al_assert(pcie_pf); + al_assert(params); + + return al_pcie_aer_config_aux( + pcie_pf->pcie_port, pcie_pf->pf_num, params); +} + +/** EP physical function AER uncorrectable errors get and clear */ +unsigned int al_pcie_aer_uncorr_get_and_clear(struct al_pcie_pf *pcie_pf) +{ + al_assert(pcie_pf); + + return al_pcie_aer_uncorr_get_and_clear_aux( + pcie_pf->pcie_port, pcie_pf->pf_num); +} + +/** EP physical function AER correctable errors get and clear */ +unsigned int al_pcie_aer_corr_get_and_clear(struct al_pcie_pf *pcie_pf) +{ + al_assert(pcie_pf); + + return al_pcie_aer_corr_get_and_clear_aux( + pcie_pf->pcie_port, pcie_pf->pf_num); +} + +/** + * EP physical function AER get the header for + * the TLP corresponding to a detected error + * */ +void al_pcie_aer_err_tlp_hdr_get( + struct al_pcie_pf *pcie_pf, + uint32_t hdr[AL_PCIE_AER_ERR_TLP_HDR_NUM_DWORDS]) +{ + al_assert(pcie_pf); + al_assert(hdr); + + al_pcie_aer_err_tlp_hdr_get_aux( + pcie_pf->pcie_port, pcie_pf->pf_num, hdr); +} + +/******************** RC AER functions **********************/ +/** configure RC port AER capability */ +int al_pcie_port_aer_config( + struct al_pcie_port *pcie_port, + struct al_pcie_aer_params *params) +{ + al_assert(pcie_port); + al_assert(params); + + /** + * For RC mode there's no PFs (neither PF handles), + * therefore PF#0 is used + * */ + return al_pcie_aer_config_aux(pcie_port, 0, params); +} + +/** RC port AER uncorrectable errors get and clear */ +unsigned int al_pcie_port_aer_uncorr_get_and_clear( + struct al_pcie_port *pcie_port) +{ + al_assert(pcie_port); + + /** + * For RC mode there's no PFs (neither PF handles), + * therefore PF#0 is used + * */ + return al_pcie_aer_uncorr_get_and_clear_aux(pcie_port, 0); +} + +/** RC port AER correctable errors get and clear */ +unsigned int al_pcie_port_aer_corr_get_and_clear( + struct al_pcie_port *pcie_port) +{ + al_assert(pcie_port); + + /** + * For RC mode there's no PFs (neither PF handles), + * therefore PF#0 is used + * */ + return al_pcie_aer_corr_get_and_clear_aux(pcie_port, 0); +} + +/** RC port AER get the header for the TLP corresponding to a detected error */ +void al_pcie_port_aer_err_tlp_hdr_get( + struct al_pcie_port *pcie_port, + uint32_t hdr[AL_PCIE_AER_ERR_TLP_HDR_NUM_DWORDS]) +{ + al_assert(pcie_port); + al_assert(hdr); + + /** + * For RC mode there's no PFs (neither PF handles), + * therefore PF#0 is used + * */ + al_pcie_aer_err_tlp_hdr_get_aux(pcie_port, 0, hdr); +} + /********************** Loopback mode (RC and Endpoint modes) ************/ /** enter local pipe loopback mode */ diff --git a/al_hal_pcie.h b/al_hal_pcie.h index 1ddc8eb7074..a5db654e182 100644 --- a/al_hal_pcie.h +++ b/al_hal_pcie.h @@ -85,7 +85,6 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * - Root Complex mode * - Set the Max Link Speed to Gen2 * - Set the max lanes width to 2 (x2) - * - Disable reversal mode * - Enable Snoops to support I/O Hardware cache coherency * - Enable pcie core RAM parity * - Enable pcie core AXI parity @@ -97,7 +96,6 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * @code * - struct al_pcie_link_params link_params = { * AL_PCIE_LINK_SPEED_GEN2, - * AL_FALSE, // disable reversal mode * AL_PCIE_MPS_DEFAULT}; * * - struct al_pcie_port_config_params config_params = { @@ -162,14 +160,29 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. /********************************* Constants **********************************/ /******************************************************************************/ -/** Inbound header credits sum - rev 0/1/2 */ -#define AL_PCIE_REV_1_2_IB_HCRD_SUM 97 -/** Inbound header credits sum - rev 3 */ -#define AL_PCIE_REV3_IB_HCRD_SUM 259 +/** + * PCIe Core revision IDs: + * ID_1: Alpine V1 + * ID_2: Alpine V2 x4 + * ID_3: Alpine V2 x8 + */ +#define AL_PCIE_REV_ID_1 1 +#define AL_PCIE_REV_ID_2 2 +#define AL_PCIE_REV_ID_3 3 /** Number of extended registers */ #define AL_PCIE_EX_REGS_NUM 40 +/******************************************************************************* + * The inbound flow control for headers is programmable per P, NP and CPL + * transactions types. The following parameters define the total number of + * available header flow controls for all types. + ******************************************************************************/ +/** Inbound header credits sum - rev1/2 */ +#define AL_PCIE_REV_1_2_IB_HCRD_SUM 97 +/** Inbound header credits sum - rev3 */ +#define AL_PCIE_REV3_IB_HCRD_SUM 259 + /******************************************************************************* * PCIe AER uncorrectable error bits * To be used with the following functions: @@ -232,9 +245,8 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. /** * al_pcie_ib_hcrd_config: data structure internally used in order to config * inbound posted/non-posted parameters. - * Note: it's required to have this structure in pcie_port handle since it has - * a state (required/not-required) which is determined by outbound - * outstanding configuration + * Note: this is a private member in pcie_port handle and MUST NOT be modified + * by the user. */ struct al_pcie_ib_hcrd_config { /* Internally used - see 'al_pcie_ib_hcrd_os_ob_reads_config' */ @@ -251,10 +263,6 @@ enum al_pcie_max_payload_size { AL_PCIE_MPS_DEFAULT, AL_PCIE_MPS_128 = 0, AL_PCIE_MPS_256 = 1, - AL_PCIE_MPS_512 = 2, - AL_PCIE_MPS_1024 = 3, - AL_PCIE_MPS_2048 = 4, - AL_PCIE_MPS_4096 = 5, }; /** @@ -271,10 +279,12 @@ struct al_pcie_port { void *ex_regs; void __iomem *pbs_regs; - /* Revision ID */ + /* Rev ID */ uint8_t rev_id; unsigned int port_id; uint8_t max_lanes; + + /* For EP mode only */ uint8_t max_num_of_pfs; /* Internally used */ @@ -284,6 +294,8 @@ struct al_pcie_port { /** * al_pcie_pf: the pf handle, a data structure used to handle PF specific * functionality. Initialized using "al_pcie_pf_handle_init()" + * + * Note: This structure should be used for EP mode only */ struct al_pcie_pf { unsigned int pf_num; @@ -318,15 +330,13 @@ struct al_pcie_max_capability { al_bool root_complex_mode_supported; enum al_pcie_link_speed max_speed; uint8_t max_lanes; - al_bool reversal_supported; uint8_t atu_regions_num; - uint32_t atu_min_size; + uint32_t atu_min_size; /* Size granularity: 4 Kbytes */ }; /** PCIe link related parameters */ struct al_pcie_link_params { - enum al_pcie_link_speed max_speed; - al_bool enable_reversal; + enum al_pcie_link_speed max_speed; enum al_pcie_max_payload_size max_payload_size; }; @@ -362,22 +372,22 @@ struct al_pcie_gen3_params { uint8_t local_fs; /* Low Frequency (LF) Value for Gen3 Transmit Equalization */ }; -/** Transport Layer credits parameters */ -struct al_pcie_tl_credits_params { -}; - -/** Various configuration features */ -struct al_pcie_features { - /** - * Enable MSI fix from the SATA to the PCIe EP - * Only valid for port 0, when enabled as EP - */ - al_bool sata_ep_msi_fix; -}; - /** * Inbound posted/non-posted header credits and outstanding outbound reads - * completion header configuration + * completion header configuration. + * + * This structure controls the resource partitioning of an important resource in + * the PCIe port. This resource includes the PCIe TLP headers coming on the PCIe + * port, and is shared between three types: + * - Inbound Non-posted, which are PCIe Reads as well as PCIe Config Cycles + * - Inbound Posted, i.e. PCIe Writes + * - Inbound Read-completion, which are the completions matching and outbound + * reads issued previously by the same core. + * The programmer need to take into consideration that a given outbound read + * request could be split on the return path into Ceiling[MPS_Size / 64] + 1 + * of Read Completions. + * Programmers are not expected to modify these setting except for rare cases, + * where a different ratio between Posted-Writes and Read-Completions is desired * * Constraints: * - nof_cpl_hdr + nof_np_hdr + nof_p_hdr == @@ -411,13 +421,26 @@ struct al_pcie_ib_hcrd_os_ob_reads_config { unsigned int nof_p_hdr; }; -/** PCIe Ack/Nak Latency and Replay timers */ +/** + * PCIe Ack/Nak Latency and Replay timers + * + * Note: Programmer is not expected to modify these values unless working in + * very slow external devices like low-end FPGA or hardware devices + * emulated in software + */ struct al_pcie_latency_replay_timers { uint16_t round_trip_lat_limit; uint16_t replay_timer_limit; }; -/* SRIS KP counter values */ +/** + * SRIS KP counter values + * + * Description: SRIS is PCI SIG ECN, that enables the two peers on a given PCIe + * link to run with Separate Reference clock with Independent Spread spectrum + * clock and requires inserting PCIe SKP symbols on the link in faster frequency + * that original PCIe spec + */ struct al_pcie_sris_params { /** set to AL_TRUE to use defaults and ignore the other parameters */ al_bool use_defaults; @@ -425,7 +448,23 @@ struct al_pcie_sris_params { uint16_t kp_counter_gen21; }; -/** Relaxed ordering params */ +/** + * Relaxed ordering params + * Enable ordering relaxations for applications that does not require + * enforcement of 'completion must not bypass posted' ordering rule. + * + * Recommendation: + * - For downstream port, set enable_tx_relaxed_ordering + * - For upstream port + * - set enable_rx_relaxed_ordering + * - set enable tx_relaxed_ordering for emulated EP. + * + * Defaults: + * - For Root-Complex: + * - tx_relaxed_ordering = AL_FALSE, rx_relaxed_ordering = AL_TRUE + * - For End-Point: + * - tx_relaxed_ordering = AL_TRUE, rx_relaxed_ordering = AL_FALSE + */ struct al_pcie_relaxed_ordering_params { al_bool enable_tx_relaxed_ordering; al_bool enable_rx_relaxed_ordering; @@ -445,20 +484,26 @@ struct al_pcie_port_config_params { struct al_pcie_latency_replay_timers *lat_rply_timers; struct al_pcie_gen2_params *gen2_params; struct al_pcie_gen3_params *gen3_params; - struct al_pcie_tl_credits_params *tl_credits; - struct al_pcie_features *features; - /* Sets all internal timers to Fast Mode for speeding up simulation.*/ + /* + * Sets all internal timers to Fast Mode for speeding up simulation. + * this varible should be set always to AL_FALSE unless user is running + * on simulation setup + */ al_bool fast_link_mode; /* - * when true, the PCI unit will return Slave Error/Decoding Error to the master unit in case - * of error. when false, the value 0xFFFFFFFF will be returned without error indication. + * when true, the PCI unit will return Slave Error/Decoding Error to any + * I/O Fabric master or Internal Processors in case of error. + * when false, the value 0xFFFFFFFF will be returned without error indication. */ al_bool enable_axi_slave_err_resp; struct al_pcie_sris_params *sris_params; struct al_pcie_relaxed_ordering_params *relaxed_ordering_params; }; -/** BAR register configuration parameters (Endpoint Mode only) */ +/** + * BAR register configuration parameters + * Note: This structure should be used for EP mode only + */ struct al_pcie_ep_bar_params { al_bool enable; al_bool memory_space; /**< memory or io */ @@ -467,12 +512,30 @@ struct al_pcie_ep_bar_params { uint64_t size; /* the bar size in bytes */ }; -/** PF config params (EP mode only) */ +/** + * PF config params (EP mode only) + * Note: This structure should be used for EP mode only + */ struct al_pcie_pf_config_params { + /** + * disable advertising D1 and D3hot state + * Recommended to be AL_TRUE + */ al_bool cap_d1_d3hot_dis; + /** + * disable advertising support for Function-Level-Reset + * Recommended to be AL_FALSE + */ al_bool cap_flr_dis; + /* + * disable advertising Advanced power management states + */ al_bool cap_aspm_dis; al_bool bar_params_valid; + /* + * Note: only bar_params[0], [2] and [4] can have memory_64_bit enabled + * and in such case, the next bar ([1], [3], or [5] respectively) is not used + */ struct al_pcie_ep_bar_params bar_params[6]; struct al_pcie_ep_bar_params exp_bar_params;/* expansion ROM BAR*/ }; @@ -481,7 +544,7 @@ struct al_pcie_pf_config_params { struct al_pcie_link_status { al_bool link_up; enum al_pcie_link_speed speed; - uint8_t lanes; + uint8_t lanes; /* Number of lanes */ uint8_t ltssm_state; }; @@ -491,18 +554,26 @@ struct al_pcie_lane_status { enum al_pcie_link_speed requested_speed; }; -/** PCIe MSIX capability configuration parameters */ +/** + * PCIe MSIX capability configuration parameters + * Note: This structure should be used for EP mode only + */ struct al_pcie_msix_params { + /* Number of entries - size can be up to: 2024 */ uint16_t table_size; uint16_t table_offset; uint8_t table_bar; uint16_t pba_offset; + /* which bar to use when calculating the PBA table address and adding offset to */ uint16_t pba_bar; }; /** PCIE AER capability parameters */ struct al_pcie_aer_params { - /** ECRC Generation Enable */ + /** ECRC Generation Enable + * while this feature is powerful, all known Chip-sets and processors + * do not support it as of 2015 + */ al_bool ecrc_gen_en; /** ECRC Check Enable */ al_bool ecrc_chk_en; @@ -562,6 +633,13 @@ int al_pcie_pf_handle_init( struct al_pcie_port *pcie_port, unsigned int pf_num); +/** + * Get port revision ID + * @param pcie_port pcie port handle + * @return Port rev_id + */ +int al_pcie_port_rev_id_get(struct al_pcie_port *pcie_port); + /************************** Pre PCIe Port Enable API **************************/ /** @@ -582,7 +660,8 @@ int al_pcie_port_operating_mode_config(struct al_pcie_port *pcie_port, * This function can be called only before enabling the controller using al_pcie_port_enable(). * * @param pcie_port pcie port handle - * @param lanes number of lanes + * @param lanes number of lanes (must be 1,2,4,8,16 and not any other value) + * * Note: this function must be called before any al_pcie_port_config() calls * * @return 0 if no error found. @@ -593,7 +672,12 @@ int al_pcie_port_max_lanes_set(struct al_pcie_port *pcie_port, uint8_t lanes); * Set maximum physical function numbers * @param pcie_port pcie port handle * @param max_num_of_pfs number of physical functions - * Note: this function must be called before any al_pcie_pf_config() calls + * + * Notes: + * - this function must be called before any al_pcie_pf_config() calls + * - exposed on a given PCIe Endpoint port + * - PCIe rev1/rev2 supports only single Endpoint + * - PCIe rev3 can support up to 4 */ int al_pcie_port_max_num_of_pfs_set( struct al_pcie_port *pcie_port, @@ -619,9 +703,27 @@ int al_pcie_port_ib_hcrd_os_ob_reads_config( enum al_pcie_operating_mode al_pcie_operating_mode_get( struct al_pcie_port *pcie_port); +/** + * PCIe AXI quality of service configuration + * + * @param pcie_port + * Initialized PCIe port handle + * @param arqos + * AXI read quality of service (0 - 15) + * @param awqos + * AXI write quality of service (0 - 15) + */ +void al_pcie_axi_qos_config( + struct al_pcie_port *pcie_port, + unsigned int arqos, + unsigned int awqos); + /**************************** PCIe Port Enable API ****************************/ -/** Enable PCIe unit (deassert reset) +/** + * Enable PCIe unit (deassert reset) + * This function only enables the port, without any configuration/link + * functionality. Should be called before starting any configuration/link API * * @param pcie_port pcie port handle * @@ -637,6 +739,8 @@ void al_pcie_port_disable(struct al_pcie_port *pcie_port); /** * Port memory shutdown/up + * Memory shutdown should be called for an unused ports for power-saving + * * Caution: This function can be called only when the controller is disabled * * @param pcie_port pcie port handle @@ -669,7 +773,7 @@ int al_pcie_port_config(struct al_pcie_port *pcie_port, const struct al_pcie_port_config_params *params); /** - * @brief Configure a specific PF (EP params, sriov params, ...) + * @brief Configure a specific PF * this function must be called before any datapath transactions * * @param pcie_pf pcie pf handle @@ -685,7 +789,8 @@ int al_pcie_pf_config( /** * @brief start pcie link - * + * This function starts the link and should be called only after port is enabled + * and pre port-enable and configurations are done * @param pcie_port pcie port handle * * @return 0 if no error found @@ -701,6 +806,14 @@ int al_pcie_link_start(struct al_pcie_port *pcie_port); */ int al_pcie_link_stop(struct al_pcie_port *pcie_port); +/** + * @brief check if pcie link is started + * Note that this function checks if link is started rather than link is up + * @param pcie_port pcie port handle + * @return AL_TRUE if link is started and AL_FALSE otherwise + */ +al_bool al_pcie_is_link_started(struct al_pcie_port *pcie_port); + /** * @brief trigger link-disable * @@ -753,6 +866,10 @@ void al_pcie_lane_status_get( /** * @brief trigger hot reset + * this function initiates In-Band reset while link is up. + * to initiate hot reset: call this function with AL_TRUE + * to exit from hos reset: call this function with AL_FALSE + * Note: This function should be called in RC mode only * * @param pcie_port pcie port handle * @param enable AL_TRUE to enable hot-reset and AL_FALSE to disable it @@ -766,6 +883,7 @@ int al_pcie_link_hot_reset(struct al_pcie_port *pcie_port, al_bool enable); * this function initiates Link retraining by directing the Physical Layer LTSSM * to the Recovery state. If the LTSSM is already in Recovery or Configuration, * re-entering Recovery is permitted but not required. + * Note: This function should be called in RC mode only * @param pcie_port pcie port handle * @@ -793,7 +911,9 @@ int al_pcie_link_change_width(struct al_pcie_port *pcie_port, uint8_t width); /************************** Snoop Configuration API ***************************/ /** - * @brief configure pcie port axi snoop + * @brief configure pcie port axi snoop + * This enable the inbound PCIe posted write data or the Read completion data to + * snoop the internal processor caches for I/O cache coherency * * @param pcie_port pcie port handle * @param enable_axi_snoop enable snoop. @@ -807,7 +927,10 @@ int al_pcie_port_snoop_config(struct al_pcie_port *pcie_port, /************************** Configuration Space API ***************************/ /** - * Configuration Space Access Through PCI-E_ECAM_Ext PASW (RC mode only) + * Configuration Space Access Through PCI-E_ECAM_Ext PASW + * This feature enables the internal processors to generate configuration cycles + * on the PCIe ports by writing to part of the processor memory space marked by + * the PCI-E_EXCAM_Ext address window */ /** @@ -852,6 +975,11 @@ void al_pcie_local_cfg_space_write( /** * @brief set target_bus and mask_target_bus + * + * Call this function with target_bus set to the required bus of the next + * outbound config access to be issued. No need to call that function if the + * next config access bus equals to the last one. + * * @param pcie_port pcie port handle * @param target_bus * @param mask_target_bus @@ -875,6 +1003,8 @@ int al_pcie_target_bus_get(struct al_pcie_port *pcie_port, /** * Set secondary bus number * + * Same as al_pcie_target_bus_set but with secondary bus + * * @param pcie_port pcie port handle * @param secbus pci secondary bus number * @@ -885,6 +1015,8 @@ int al_pcie_secondary_bus_set(struct al_pcie_port *pcie_port, uint8_t secbus); /** * Set subordinary bus number * + * Same as al_pcie_target_bus_set but with subordinary bus + * * @param pcie_port pcie port handle * @param subbus the highest bus number of all of the buses that can be reached * downstream of the PCIE instance. @@ -897,13 +1029,22 @@ int al_pcie_subordinary_bus_set(struct al_pcie_port *pcie_port,uint8_t subbus); * @brief Enable/disable deferring incoming configuration requests until * initialization is complete. When enabled, the core completes incoming * configuration requests with a Configuration Request Retry Status. - * Other incoming Requests complete with Unsupported Request status. + * Other incoming non-configuration Requests complete with Unsupported Request status. + * + * Note: This function should be used for EP mode only * * @param pcie_port pcie port handle * @param en enable/disable */ void al_pcie_app_req_retry_set(struct al_pcie_port *pcie_port, al_bool en); +/** + * @brief Check if deferring incoming configuration requests is enabled or not + * @param pcie_port pcie port handle + * @return AL_TRUE is it's enabled and AL_FALSE otherwise + */ +al_bool al_pcie_app_req_retry_get_status(struct al_pcie_port *pcie_port); + /*************** Internal Address Translation Unit (ATU) API ******************/ enum al_pcie_atu_dir { @@ -911,6 +1052,7 @@ enum al_pcie_atu_dir { AL_PCIE_ATU_DIR_INBOUND = 1, }; +/** decoding of the PCIe TLP Type as appears on the wire */ enum al_pcie_atu_tlp { AL_PCIE_TLP_TYPE_MEM = 0, AL_PCIE_TLP_TYPE_IO = 2, @@ -920,57 +1062,134 @@ enum al_pcie_atu_tlp { AL_PCIE_TLP_TYPE_RESERVED = 0x1f }; +/** default response types */ enum al_pcie_atu_response { AL_PCIE_RESPONSE_NORMAL = 0, - AL_PCIE_RESPONSE_UR = 1, - AL_PCIE_RESPONSE_CA = 2 + AL_PCIE_RESPONSE_UR = 1, /* UR == Unsupported Request */ + AL_PCIE_RESPONSE_CA = 2 /* CA == Completion Abort */ }; struct al_pcie_atu_region { + + /********************************************************************** + * General Parameters * + **********************************************************************/ + al_bool enable; /* outbound or inbound */ enum al_pcie_atu_dir direction; /* region index */ uint8_t index; + /* the 64-bit address that get matched with the 64-bit address incoming + * on the PCIe TLP + */ uint64_t base_addr; - /** limit marks the region's end address. only bits [39:0] are valid - * given the Alpine PoC maximum physical address space + /** + * limit marks the region's end address. + * For Alpine V1 (PCIe rev1): only bits [39:0] are valid + * For Alpine V2 (PCIe rev2/rev3): only bits [47:0] are valid + * an access is a hit in iATU if the: + * - address >= base_addr + * - address <= base_addr + limit */ uint64_t limit; - /** the address that matches will be translated to this address + offset + /** + * the address that matches (hit) will be translated to: + * target_addr + offset + * + * Exmaple: accessing (base_addr + 0x1000) will be translated to: + * (target_addr + 0x1000) in case limit >= 0x1000 */ uint64_t target_addr; + /** + * When the Invert feature is activated, an address match occurs when + * the untranslated address is not in the region bounded by the Base + * address and Limit address. Match occurs when the untranslated address + * is not in the region bounded by the base address and limit address + */ al_bool invert_matching; - /* pcie tlp type*/ + /** + * PCIe TLP type + * Can be: Mem, IO, CGF0, CFG1 or MSG + */ enum al_pcie_atu_tlp tlp_type; - /* pcie frame header attr field*/ + /** + * PCIe frame header attr field. + * When the address of a TLP is matched to this region, then the ATTR + * field of the TLP is changed to the value in this register. + */ uint8_t attr; + + /********************************************************************** + * Outbound specific Parameters * + **********************************************************************/ + /** - * outbound specific params + * PCIe Message code + * MSG TLPs (Message Code). When the address of an outbound TLP is + * matched to this region, and the translated TLP TYPE field is Msg + * then the message field of the TLP is changed to the value in this + * register. */ - /* pcie message code */ uint8_t msg_code; - al_bool cfg_shift_mode; /** - * inbound specific params + * CFG Shift Mode. This is useful for CFG transactions where the PCIe + * configuration mechanism maps bits [27:12] of the address to the + * bus/device and function number. This allows a CFG configuration space + * to be located in any 256MB window of your application memory space + * using a 28-bit effective address.Shifts bits [27:12] of the + * untranslated address to form bits [31:16] of the translated address. */ + al_bool cfg_shift_mode; + + /********************************************************************** + * Inbound specific Parameters * + **********************************************************************/ + uint8_t bar_number; - /* BAR match mode, used in EP for MEM and IO tlps*/ + /** + * Match Mode. Determines Inbound matching mode for TLPs. The mode + * depends on the type of TLP that is received as follows: + * MEM-I/O: 0 = Address Match Mode + * 1 = BAR Match Mode + * CFG0 : 0 = Routing ID Match Mode + * 1 = Accept Mode + * MSG : 0 = Address Match Mode + * 1 = Vendor ID Match Mode + */ uint8_t match_mode; /** - * For outbound: enables taking the function number of the translated - * TLP from the PCIe core. For inbound: enables ATU function match mode + * For outbound: + * - AL_TRUE : enables taking the function number of the translated TLP + * from the PCIe core + * - AL_FALSE: no function number is taken from PCIe core + * For inbound: + * - AL_TRUE : enables ATU function match mode + * - AL_FALSE: no function match mode applied to transactions + * * Note: this boolean is ignored in RC mode */ al_bool function_match_bypass_mode; /** * The function number to match/bypass (see previous parameter) - * Note: this parameter is ignored when previous param is FALSE + * Note: this parameter is ignored when previous parameter is AL_FALSE */ uint8_t function_match_bypass_mode_number; - /* response code */ + /** + * setting up what is the default response for an inbound transaction + * that matches the iATU + */ enum al_pcie_atu_response response; + /** + * Attr Match Enable. Ensures that a successful AT TLP field comparison + * match (see attr above) occurs for address translation to proceed + */ al_bool enable_attr_match_mode; + /** + * Message Code Match Enable(Msg TLPS). Ensures that a successful + * message Code TLP field comparison match (see Message msg_code)occurs + * (in MSG transactions) for address translation to proceed. + */ al_bool enable_msg_match_mode; /** * USE WITH CAUTION: setting this boolean to AL_TRUE allows setting the @@ -1008,7 +1227,11 @@ void al_pcie_atu_region_get_fields( /** * @brief Configure axi io bar. - * every hit to this bar will override size to 4 bytes. + * + * This is an EP feature, enabling PCIe IO transaction to be captured if it fits + * within start and end address, and then mapped to internal 4-byte + * memRead/memWrite. Every hit to this bar will override size to 4 bytes. + * * @param pcie_port pcie port handle * @param start the first address of the memory * @param end the last address of the memory @@ -1028,6 +1251,13 @@ enum al_pcie_legacy_int_type{ AL_PCIE_LEGACY_INTD }; + +/* @brief generate FLR_PF_DONE message + * @param pcie_pf pcie pf handle + * @return 0 if no error found + */ +int al_pcie_pf_flr_done_gen(struct al_pcie_pf *pcie_pf); + /** * @brief generate INTx Assert/DeAssert Message * @param pcie_pf pcie pf handle @@ -1075,7 +1305,7 @@ al_bool al_pcie_msix_masked(struct al_pcie_pf *pcie_pf); /******************** Advanced Error Reporting (AER) API **********************/ /** - * @brief configure AER capability + * @brief configure EP physical function AER capability * @param pcie_pf pcie pf handle * @param params AER capability configuration parameters * @return 0 if no error found @@ -1085,7 +1315,7 @@ int al_pcie_aer_config( struct al_pcie_aer_params *params); /** - * @brief AER uncorretable errors get and clear + * @brief EP physical function AER uncorrectable errors get and clear * @param pcie_pf pcie pf handle * @return bit mask of uncorrectable errors - see 'AL_PCIE_AER_UNCORR_*' for * details @@ -1093,7 +1323,7 @@ int al_pcie_aer_config( unsigned int al_pcie_aer_uncorr_get_and_clear(struct al_pcie_pf *pcie_pf); /** - * @brief AER corretable errors get and clear + * @brief EP physical function AER correctable errors get and clear * @param pcie_pf pcie pf handle * @return bit mask of correctable errors - see 'AL_PCIE_AER_CORR_*' for * details @@ -1101,7 +1331,8 @@ unsigned int al_pcie_aer_uncorr_get_and_clear(struct al_pcie_pf *pcie_pf); unsigned int al_pcie_aer_corr_get_and_clear(struct al_pcie_pf *pcie_pf); /** - * @brief AER get the header for the TLP corresponding to a detected error + * @brief EP physical function AER get the header for + * the TLP corresponding to a detected error * @param pcie_pf pcie pf handle * @param hdr pointer to an array for getting the header */ @@ -1109,6 +1340,44 @@ void al_pcie_aer_err_tlp_hdr_get( struct al_pcie_pf *pcie_pf, uint32_t hdr[AL_PCIE_AER_ERR_TLP_HDR_NUM_DWORDS]); +/** + * @brief configure RC port AER capability + * @param pcie_port pcie port handle + * @param params AER capability configuration parameters + * @return 0 if no error found + */ +int al_pcie_port_aer_config( + struct al_pcie_port *pcie_port, + struct al_pcie_aer_params *params); + +/** + * @brief RC port AER uncorrectable errors get and clear + * @param pcie_port pcie port handle + * @return bit mask of uncorrectable errors - see 'AL_PCIE_AER_UNCORR_*' for + * details + */ +unsigned int al_pcie_port_aer_uncorr_get_and_clear( + struct al_pcie_port *pcie_port); + +/** + * @brief RC port AER correctable errors get and clear + * @param pcie_port pcie port handle + * @return bit mask of correctable errors - see 'AL_PCIE_AER_CORR_*' for + * details + */ +unsigned int al_pcie_port_aer_corr_get_and_clear( + struct al_pcie_port *pcie_port); + +/** + * @brief RC port AER get the header for + * the TLP corresponding to a detected error + * @param pcie_port pcie port handle + * @param hdr pointer to an array for getting the header + */ +void al_pcie_port_aer_err_tlp_hdr_get( + struct al_pcie_port *pcie_port, + uint32_t hdr[AL_PCIE_AER_ERR_TLP_HDR_NUM_DWORDS]); + /******************** Loop-Back mode (RC and Endpoint modes) ******************/ /** diff --git a/al_hal_pcie_axi_reg.h b/al_hal_pcie_axi_reg.h index 04d4bfdbca3..b8e11645edd 100644 --- a/al_hal_pcie_axi_reg.h +++ b/al_hal_pcie_axi_reg.h @@ -72,7 +72,7 @@ struct al_pcie_rev1_2_axi_ctrl { /* [0x28] */ uint32_t dbi_ctl; /* [0x2c] */ - uint32_t vmid_mask; + uint32_t tgtid_mask; uint32_t rsrvd[4]; }; struct al_pcie_rev3_axi_ctrl { @@ -98,7 +98,7 @@ struct al_pcie_rev3_axi_ctrl { /* [0x28] */ uint32_t dbi_ctl; /* [0x2c] */ - uint32_t vmid_mask; + uint32_t tgtid_mask; }; struct al_pcie_rev1_axi_ob_ctrl { /* [0x0] */ @@ -145,10 +145,10 @@ struct al_pcie_rev2_axi_ob_ctrl { /* [0x24] */ uint32_t msg_limit_h; /* - * [0x28] this register override the VMID field in the AXUSER [19:4], + * [0x28] this register override the Target-ID field in the AXUSER [19:4], * for the AXI master port. */ - uint32_t vmid_reg_ovrd; + uint32_t tgtid_reg_ovrd; /* [0x2c] this register override the ADDR[63:32] AXI master port. */ uint32_t addr_high_reg_ovrd_value; /* [0x30] this register override the ADDR[63:32] AXI master port. */ @@ -196,10 +196,10 @@ struct al_pcie_rev3_axi_ob_ctrl { /* [0x40] */ uint32_t aw_msg_addr_mask_h; /* - * [0x44] this register override the VMID field in the AXUSER [19:4], + * [0x44] this register override the Target-ID field in the AXUSER [19:4], * for the AXI master port. */ - uint32_t vmid_reg_ovrd; + uint32_t tgtid_reg_ovrd; /* [0x48] this register override the ADDR[63:32] AXI master port. */ uint32_t addr_high_reg_ovrd_value; /* [0x4c] this register override the ADDR[63:32] AXI master port. */ @@ -783,9 +783,9 @@ struct al_pcie_rev3_axi_regs { /* arprot value */ #define PCIE_AXI_CTRL_MASTER_ARCTL_ARPROT_VALUE_MASK 0x000001C0 #define PCIE_AXI_CTRL_MASTER_ARCTL_ARPROT_VALUE_SHIFT 6 -/* vmid val */ -#define PCIE_AXI_CTRL_MASTER_ARCTL_VMID_VAL_MASK 0x01FFFE00 -#define PCIE_AXI_CTRL_MASTER_ARCTL_VMID_VAL_SHIFT 9 +/* tgtid val */ +#define PCIE_AXI_CTRL_MASTER_ARCTL_TGTID_VAL_MASK 0x01FFFE00 +#define PCIE_AXI_CTRL_MASTER_ARCTL_TGTID_VAL_SHIFT 9 /* IPA value */ #define PCIE_AXI_CTRL_MASTER_ARCTL_IPA_VAL (1 << 25) /* overide snoop inidcation, if not set take it from mstr_armisc ... */ @@ -797,6 +797,7 @@ snoop indication value when override */ arqos value */ #define PCIE_AXI_CTRL_MASTER_ARCTL_ARQOS_MASK 0xF0000000 #define PCIE_AXI_CTRL_MASTER_ARCTL_ARQOS_SHIFT 28 +#define PCIE_AXI_CTRL_MASTER_ARCTL_ARQOS_VAL_MAX 15 /**** Master_Awctl register ****/ /* override arcache */ @@ -809,9 +810,9 @@ arqos value */ /* awprot value */ #define PCIE_AXI_CTRL_MASTER_AWCTL_AWPROT_VALUE_MASK 0x000001C0 #define PCIE_AXI_CTRL_MASTER_AWCTL_AWPROT_VALUE_SHIFT 6 -/* vmid val */ -#define PCIE_AXI_CTRL_MASTER_AWCTL_VMID_VAL_MASK 0x01FFFE00 -#define PCIE_AXI_CTRL_MASTER_AWCTL_VMID_VAL_SHIFT 9 +/* tgtid val */ +#define PCIE_AXI_CTRL_MASTER_AWCTL_TGTID_VAL_MASK 0x01FFFE00 +#define PCIE_AXI_CTRL_MASTER_AWCTL_TGTID_VAL_SHIFT 9 /* IPA value */ #define PCIE_AXI_CTRL_MASTER_AWCTL_IPA_VAL (1 << 25) /* overide snoop inidcation, if not set take it from mstr_armisc ... */ @@ -823,6 +824,7 @@ snoop indication value when override */ awqos value */ #define PCIE_AXI_CTRL_MASTER_AWCTL_AWQOS_MASK 0xF0000000 #define PCIE_AXI_CTRL_MASTER_AWCTL_AWQOS_SHIFT 28 +#define PCIE_AXI_CTRL_MASTER_AWCTL_AWQOS_VAL_MAX 15 /**** slv_ctl register ****/ #define PCIE_AXI_CTRL_SLV_CTRL_IO_BAR_EN (1 << 6) @@ -888,17 +890,17 @@ awqos value */ #define PCIE_AXI_MISC_OB_CTRL_MSG_LIMIT_H_ADDR_MASK 0x000003FF #define PCIE_AXI_MISC_OB_CTRL_MSG_LIMIT_H_ADDR_SHIFT 0 -/**** vmid_reg_ovrd register ****/ +/**** tgtid_reg_ovrd register ****/ /* * select if to take the value from register or from address[63:48]: * 1'b1: register value. * 1'b0: from address[63:48] */ -#define PCIE_AXI_MISC_OB_CTRL_VMID_REG_OVRD_SEL_MASK 0x0000FFFF -#define PCIE_AXI_MISC_OB_CTRL_VMID_REG_OVRD_SEL_SHIFT 0 -/* vmid override value. */ -#define PCIE_AXI_MISC_OB_CTRL_VMID_REG_OVRD_VALUE_MASK 0xFFFF0000 -#define PCIE_AXI_MISC_OB_CTRL_VMID_REG_OVRD_VALUE_SHIFT 16 +#define PCIE_AXI_MISC_OB_CTRL_TGTID_REG_OVRD_SEL_MASK 0x0000FFFF +#define PCIE_AXI_MISC_OB_CTRL_TGTID_REG_OVRD_SEL_SHIFT 0 +/* tgtid override value. */ +#define PCIE_AXI_MISC_OB_CTRL_TGTID_REG_OVRD_VALUE_MASK 0xFFFF0000 +#define PCIE_AXI_MISC_OB_CTRL_TGTID_REG_OVRD_VALUE_SHIFT 16 /**** addr_size_replace register ****/ /* @@ -1255,17 +1257,17 @@ awqos value */ #define PCIE_AXI_PF_AXI_ATTR_OVRD_FUNC_CTRL_2_RSRVD_14_15_MASK 0x0000C000 #define PCIE_AXI_PF_AXI_ATTR_OVRD_FUNC_CTRL_2_RSRVD_14_15_SHIFT 14 /* choose the field from the axuser */ -#define PCIE_AXI_PF_AXI_ATTR_OVRD_FUNC_CTRL_2_PF_VEC_VMID89_VEC_OVRD_FROM_AXUSER_MASK 0x00030000 -#define PCIE_AXI_PF_AXI_ATTR_OVRD_FUNC_CTRL_2_PF_VEC_VMID89_VEC_OVRD_FROM_AXUSER_SHIFT 16 +#define PCIE_AXI_PF_AXI_ATTR_OVRD_FUNC_CTRL_2_PF_VEC_TGTID89_VEC_OVRD_FROM_AXUSER_MASK 0x00030000 +#define PCIE_AXI_PF_AXI_ATTR_OVRD_FUNC_CTRL_2_PF_VEC_TGTID89_VEC_OVRD_FROM_AXUSER_SHIFT 16 /* choose the field from register */ -#define PCIE_AXI_PF_AXI_ATTR_OVRD_FUNC_CTRL_2_PF_VEC_VMID89_VEC_OVRD_FROM_REG_MASK 0x000C0000 -#define PCIE_AXI_PF_AXI_ATTR_OVRD_FUNC_CTRL_2_PF_VEC_VMID89_VEC_OVRD_FROM_REG_SHIFT 18 +#define PCIE_AXI_PF_AXI_ATTR_OVRD_FUNC_CTRL_2_PF_VEC_TGTID89_VEC_OVRD_FROM_REG_MASK 0x000C0000 +#define PCIE_AXI_PF_AXI_ATTR_OVRD_FUNC_CTRL_2_PF_VEC_TGTID89_VEC_OVRD_FROM_REG_SHIFT 18 /* in case the field take from the address, offset field for each bit. */ -#define PCIE_AXI_PF_AXI_ATTR_OVRD_FUNC_CTRL_2_PF_VEC_VMID89_VEC_ADDR_OFFSET_MASK 0x0FF00000 -#define PCIE_AXI_PF_AXI_ATTR_OVRD_FUNC_CTRL_2_PF_VEC_VMID89_VEC_ADDR_OFFSET_SHIFT 20 +#define PCIE_AXI_PF_AXI_ATTR_OVRD_FUNC_CTRL_2_PF_VEC_TGTID89_VEC_ADDR_OFFSET_MASK 0x0FF00000 +#define PCIE_AXI_PF_AXI_ATTR_OVRD_FUNC_CTRL_2_PF_VEC_TGTID89_VEC_ADDR_OFFSET_SHIFT 20 /* register value override */ -#define PCIE_AXI_PF_AXI_ATTR_OVRD_FUNC_CTRL_2_CFG_VMID89_VEC_OVRD_MASK 0x30000000 -#define PCIE_AXI_PF_AXI_ATTR_OVRD_FUNC_CTRL_2_CFG_VMID89_VEC_OVRD_SHIFT 28 +#define PCIE_AXI_PF_AXI_ATTR_OVRD_FUNC_CTRL_2_CFG_TGTID89_VEC_OVRD_MASK 0x30000000 +#define PCIE_AXI_PF_AXI_ATTR_OVRD_FUNC_CTRL_2_CFG_TGTID89_VEC_OVRD_SHIFT 28 /* Rsrvd */ #define PCIE_AXI_PF_AXI_ATTR_OVRD_FUNC_CTRL_2_RSRVD_MASK 0xC0000000 #define PCIE_AXI_PF_AXI_ATTR_OVRD_FUNC_CTRL_2_RSRVD_SHIFT 30 @@ -1291,9 +1293,9 @@ awqos value */ #define PCIE_AXI_PF_AXI_ATTR_OVRD_FUNC_CTRL_3_RSRVD_SHIFT 30 /**** func_ctrl_4 register ****/ -/* When set take the corresponding bit address from vmid value. */ -#define PCIE_AXI_PF_AXI_ATTR_OVRD_FUNC_CTRL_4_PF_VEC_MEM_ADDR54_63_SEL_VMID_MASK 0x000003FF -#define PCIE_AXI_PF_AXI_ATTR_OVRD_FUNC_CTRL_4_PF_VEC_MEM_ADDR54_63_SEL_VMID_SHIFT 0 +/* When set take the corresponding bit address from tgtid value. */ +#define PCIE_AXI_PF_AXI_ATTR_OVRD_FUNC_CTRL_4_PF_VEC_MEM_ADDR54_63_SEL_TGTID_MASK 0x000003FF +#define PCIE_AXI_PF_AXI_ATTR_OVRD_FUNC_CTRL_4_PF_VEC_MEM_ADDR54_63_SEL_TGTID_SHIFT 0 /* override value. */ #define PCIE_AXI_PF_AXI_ATTR_OVRD_FUNC_CTRL_4_PF_VEC_MEM_ADDR54_63_OVRD_MASK 0x000FFC00 #define PCIE_AXI_PF_AXI_ATTR_OVRD_FUNC_CTRL_4_PF_VEC_MEM_ADDR54_63_OVRD_SHIFT 10 diff --git a/al_hal_pcie_interrupts.h b/al_hal_pcie_interrupts.h index 357971ca63c..41e6496d2fe 100644 --- a/al_hal_pcie_interrupts.h +++ b/al_hal_pcie_interrupts.h @@ -81,7 +81,7 @@ enum al_pcie_app_int_grp_a { /** [RC only] Deassert_INTB received */ AL_PCIE_APP_INT_DEASSERT_INTB = AL_BIT(2), /** - * [RC only] Deassert_INTA received - there's a didcated GIC interrupt + * [RC only] Deassert_INTA received - there's a dedicated GIC interrupt * line that reflects the status of ASSERT/DEASSERT of INTA */ AL_PCIE_APP_INT_DEASSERT_INTA = AL_BIT(3), @@ -92,7 +92,7 @@ enum al_pcie_app_int_grp_a { /** [RC only] Assert_INTB received */ AL_PCIE_APP_INT_ASSERT_INTB = AL_BIT(6), /** - * [RC only] Assert_INTA received - there's a didcated GIC interrupt + * [RC only] Assert_INTA received - there's a dedicated GIC interrupt * line that reflects the status of ASSERT/DEASSERT of INTA */ AL_PCIE_APP_INT_ASSERT_INTA = AL_BIT(7), @@ -150,13 +150,13 @@ enum al_pcie_app_int_grp_b { AL_PCIE_APP_INT_GRP_B_FTL_ERR_MSG_RCVD = AL_BIT(5), /** * [RC/EP] Vendor Defined Message received - * Asserted when a vevdor message is received (with no data), buffers 2 + * Asserted when a vendor message is received (with no data), buffers 2 * messages only, and latch the headers in registers */ AL_PCIE_APP_INT_GRP_B_VNDR_MSG_A_RCVD = AL_BIT(6), /** * [RC/EP] Vendor Defined Message received - * Asserted when a vevdor message is received (with no data), buffers 2 + * Asserted when a vendor message is received (with no data), buffers 2 * messages only, and latch the headers in registers */ AL_PCIE_APP_INT_GRP_B_VNDR_MSG_B_RCVD = AL_BIT(7), @@ -166,7 +166,7 @@ enum al_pcie_app_int_grp_b { AL_PCIE_APP_INT_GRP_B_LNK_EQ_REQ = AL_BIT(13), /** [RC/EP] OB Vendor message request is granted by the PCIe core */ AL_PCIE_APP_INT_GRP_B_OB_VNDR_MSG_REQ_GRNT = AL_BIT(14), - /** [RC only] CPL timeout from the PCIe core indiication */ + /** [RC only] CPL timeout from the PCIe core indication */ AL_PCIE_APP_INT_GRP_B_CPL_TO = AL_BIT(15), /** [RC/EP] Slave Response Composer Lookup Error */ AL_PCIE_APP_INT_GRP_B_SLV_RESP_COMP_LKUP_ERR = AL_BIT(16), diff --git a/al_hal_pcie_regs.h b/al_hal_pcie_regs.h index 15c5735e279..09b99c5b905 100644 --- a/al_hal_pcie_regs.h +++ b/al_hal_pcie_regs.h @@ -51,18 +51,6 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include "al_hal_pcie_w_reg_ex.h" #endif -/** - * Revision IDs: - * ID_0: SlickRock M0 - * ID_1: SlickRock A0 - * ID_2: PeakRock x4 - * ID_3: PeakRock x8 - */ -#define AL_PCIE_REV_ID_0 0 -#define AL_PCIE_REV_ID_1 1 -#define AL_PCIE_REV_ID_2 2 -#define AL_PCIE_REV_ID_3 3 - #define AL_PCIE_AXI_REGS_OFFSET 0x0 #define AL_PCIE_REV_1_2_APP_REGS_OFFSET 0x1000 #define AL_PCIE_REV_3_APP_REGS_OFFSET 0x2000 @@ -74,6 +62,11 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #define REV3_MAX_NUM_LANES 8 #define AL_MAX_NUM_OF_LANES 8 /* the maximum between all Revisions */ +/** Number of outbound atu regions - rev 1/2 */ +#define AL_PCIE_REV_1_2_ATU_NUM_OUTBOUND_REGIONS 12 +/** Number of outbound atu regions - rev 3 */ +#define AL_PCIE_REV_3_ATU_NUM_OUTBOUND_REGIONS 16 + struct al_pcie_core_iatu_regs { uint32_t index; uint32_t cr1; @@ -253,8 +246,10 @@ struct al_pcie_rev3_regs { struct al_pcie_axi_ctrl { uint32_t *global; + uint32_t *master_rctl; uint32_t *master_arctl; uint32_t *master_awctl; + uint32_t *master_ctl; uint32_t *slv_ctl; }; @@ -265,6 +260,13 @@ struct al_pcie_axi_ob_ctrl { uint32_t *io_start_h; uint32_t *io_limit_l; uint32_t *io_limit_h; + uint32_t *io_addr_mask_h; /* Rev 3 only */ + uint32_t *ar_msg_addr_mask_h; /* Rev 3 only */ + uint32_t *aw_msg_addr_mask_h; /* Rev 3 only */ + uint32_t *tgtid_reg_ovrd; /* Rev 2/3 only */ + uint32_t *addr_high_reg_ovrd_value; /* Rev 2/3 only */ + uint32_t *addr_high_reg_ovrd_sel; /* Rev 2/3 only */ + uint32_t *addr_size_replace; /* Rev 2/3 only */ }; struct al_pcie_axi_pcie_global { @@ -352,14 +354,23 @@ struct al_pcie_w_global_ctrl { }; struct al_pcie_w_soc_int { + uint32_t *status_0; + uint32_t *status_1; + uint32_t *status_2; + uint32_t *status_3; /* Rev 2/3 only */ uint32_t *mask_inta_leg_0; + uint32_t *mask_inta_leg_1; + uint32_t *mask_inta_leg_2; uint32_t *mask_inta_leg_3; /* Rev 2/3 only */ uint32_t *mask_msi_leg_0; + uint32_t *mask_msi_leg_1; + uint32_t *mask_msi_leg_2; uint32_t *mask_msi_leg_3; /* Rev 2/3 only */ }; struct al_pcie_w_atu { uint32_t *in_mask_pair; uint32_t *out_mask_pair; + uint32_t *reg_out_mask; /* Rev 3 only */ }; struct al_pcie_w_regs { @@ -375,6 +386,7 @@ struct al_pcie_w_regs { struct al_pcie_revx_w_int_grp *int_grp_b; struct al_pcie_revx_w_int_grp *int_grp_c; struct al_pcie_revx_w_int_grp *int_grp_d; + struct al_pcie_rev3_w_cfg_func_ext *cfg_func_ext; /* Rev 3 only */ }; struct al_pcie_regs { diff --git a/al_hal_pcie_w_reg.h b/al_hal_pcie_w_reg.h index 44e9d952655..137dfbde13e 100644 --- a/al_hal_pcie_w_reg.h +++ b/al_hal_pcie_w_reg.h @@ -1498,7 +1498,7 @@ struct al_pcie_rev3_w_regs { } #endif -#endif /* __AL_HAL_PCIE_W_REG_H */ +#endif /* __AL_HAL_pcie_w_REG_H */ /** @} end of ... group */ diff --git a/al_hal_plat_services.h b/al_hal_plat_services.h index 217bb927f69..278a8fa71dd 100644 --- a/al_hal_plat_services.h +++ b/al_hal_plat_services.h @@ -66,10 +66,29 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include /* Prototypes for all the bus_space structure functions */ -bs_protos(generic); -bs_protos(generic_armv4); +uint8_t generic_bs_r_1(bus_space_tag_t t, bus_space_handle_t bsh, + bus_size_t offset); + +uint16_t generic_bs_r_2(bus_space_tag_t t, bus_space_handle_t bsh, + bus_size_t offset); + +uint32_t generic_bs_r_4(bus_space_tag_t t, bus_space_handle_t bsh, + bus_size_t offset); + +void generic_bs_w_1(bus_space_tag_t t, bus_space_handle_t bsh, + bus_size_t offset, uint8_t value); + +void generic_bs_w_2(bus_space_tag_t t, bus_space_handle_t bsh, + bus_size_t offset, uint16_t value); + +void generic_bs_w_4(bus_space_tag_t t, bus_space_handle_t bsh, + bus_size_t offset, uint32_t value); + +void generic_bs_w_8(bus_space_tag_t t, bus_space_handle_t bsh, + bus_size_t offset, uint64_t value); #define __UNUSED __attribute__((unused)) @@ -79,6 +98,52 @@ extern "C" { #endif /* *INDENT-ON* */ +/** + * Make sure data will be visible by other masters (other CPUS and DMA). + * usually this is achieved by the ARM DMB instruction. + */ +static void al_data_memory_barrier(void); +static void al_smp_data_memory_barrier(void); + +/** + * Make sure data will be visible by DMA masters, no restriction for other cpus + */ +static inline void +al_data_memory_barrier(void) +{ +#ifndef __aarch64__ + dsb(); +#else + dsb(sy); +#endif +} + +/** + * Make sure data will be visible in order by other cpus masters. + */ +static inline void +al_smp_data_memory_barrier(void) +{ +#ifndef __aarch64__ + dmb(); +#else + dmb(ish); +#endif +} + +/** + * Make sure write data will be visible in order by other cpus masters. + */ +static inline void +al_local_data_memory_barrier(void) +{ +#ifndef __aarch64__ + dsb(); +#else + dsb(sy); +#endif +} + /* * WMA: This is a hack which allows not modifying the __iomem accessing HAL code. * On ARMv7, bus_handle holds the information about VA of accessed memory. It @@ -168,50 +233,66 @@ uint64_t al_reg_read64(uint64_t * offset); * @param offset register offset * @param val value to write to the register */ -#define al_reg_write8(l,v) do { dsb(); generic_bs_w_1(NULL, (bus_space_handle_t)l, 0, v); dmb(); } while (0) +#define al_reg_write8(l, v) do { \ + al_data_memory_barrier(); \ + generic_bs_w_1(NULL, (bus_space_handle_t)l, 0, v); \ + al_smp_data_memory_barrier(); \ +} while (0) /** * Write to MMIO 16 bits register * @param offset register offset * @param val value to write to the register */ -#define al_reg_write16(l,v) do { dsb(); generic_bs_w_2(NULL, (bus_space_handle_t)l, 0, v); dmb(); } while (0) +#define al_reg_write16(l, v) do { \ + al_data_memory_barrier(); \ + generic_bs_w_2(NULL, (bus_space_handle_t)l, 0, v); \ + al_smp_data_memory_barrier(); \ +} while (0) /** * Write to MMIO 32 bits register * @param offset register offset * @param val value to write to the register */ -#define al_reg_write32(l,v) do { dsb(); generic_bs_w_4(NULL, (bus_space_handle_t)l, 0, v); dmb(); } while (0) +#define al_reg_write32(l, v) do { \ + al_data_memory_barrier(); \ + generic_bs_w_4(NULL, (bus_space_handle_t)l, 0, v); \ + al_smp_data_memory_barrier(); \ +} while (0) /** * Write to MMIO 64 bits register * @param offset register offset * @param val value to write to the register */ -#define al_reg_write64(l,v) do { dsb(); generic_bs_w_8(NULL, (bus_space_handle_t)l, 0, v); dmb(); } while (0) +#define al_reg_write64(l, v) do { \ + al_data_memory_barrier(); \ + generic_bs_w_8(NULL, (bus_space_handle_t)l, 0, v); \ + al_smp_data_memory_barrier(); \ +} while (0) static inline uint8_t al_reg_read8(uint8_t *l) { - dsb(); + al_data_memory_barrier(); return (generic_bs_r_1(NULL, (bus_space_handle_t)l, 0)); } static inline uint16_t al_reg_read16(uint16_t *l) { - dsb(); + al_data_memory_barrier(); return (generic_bs_r_2(NULL, (bus_space_handle_t)l, 0)); } static inline uint32_t al_reg_read32(uint32_t *l) { - dsb(); + al_data_memory_barrier(); return (generic_bs_r_4(NULL, (bus_space_handle_t)l, 0)); } @@ -223,10 +304,8 @@ al_reg_read32(uint32_t *l) #define AL_DBG_LEVEL AL_DBG_LEVEL_ERR -extern struct mtx al_dbg_lock; - -#define AL_DBG_LOCK() mtx_lock_spin(&al_dbg_lock) -#define AL_DBG_UNLOCK() mtx_unlock_spin(&al_dbg_lock) +#define AL_DBG_LOCK() +#define AL_DBG_UNLOCK() /** * print message @@ -277,39 +356,6 @@ extern struct mtx al_dbg_lock; __FILE__, __LINE__, __func__, #COND); \ } while(AL_FALSE) -/** - * Make sure data will be visible by other masters (other CPUS and DMA). - * usually this is achieved by the ARM DMB instruction. - */ -static void al_data_memory_barrier(void); - -/** - * Make sure data will be visible by DMA masters, no restriction for other cpus - */ -static inline void -al_data_memory_barrier(void) -{ - dsb(); -} - -/** - * Make sure data will be visible in order by other cpus masters. - */ -static inline void -al_smp_data_memory_barrier(void) -{ - dsb(); -} - -/** - * Make sure write data will be visible in order by other cpus masters. - */ -static inline void -al_local_data_memory_barrier(void) -{ - dsb(); -} - /** * al_udelay - micro sec delay */ diff --git a/al_hal_plat_types.h b/al_hal_plat_types.h index 43896ae08f7..293fc3d703d 100644 --- a/al_hal_plat_types.h +++ b/al_hal_plat_types.h @@ -60,24 +60,6 @@ typedef int al_bool; /** boolean */ #define AL_TRUE 1 #define AL_FALSE 0 - -/* define types */ -#ifndef AL_HAVE_TYPES -typedef unsigned char uint8_t; /** unsigned 8 bits */ -typedef unsigned short uint16_t; /** unsigned 16 bits */ -typedef unsigned int uint32_t; /** unsigned 32 bits */ -typedef unsigned long long uint64_t; /** unsigned 64 bits */ - -typedef signed char int8_t; /** signed 8 bits */ -typedef short int int16_t; /** signed 16 bits */ -typedef signed int int32_t; /** signed 32 bits */ - -/** An unsigned int that is guaranteed to be the same size as a pointer */ -/** C99 standard */ -typedef unsigned long uintptr_t; -#endif - - /** in LPAE mode, the address address is 40 bit, we extend it to 64 bit */ typedef uint64_t al_phys_addr_t; diff --git a/al_hal_reg_utils.h b/al_hal_reg_utils.h index f29c3c5247b..42934ad35f4 100644 --- a/al_hal_reg_utils.h +++ b/al_hal_reg_utils.h @@ -57,6 +57,7 @@ extern "C" { /* *INDENT-ON* */ #define AL_BIT(b) (1UL << (b)) +#define AL_BIT_64(b) (1ULL << (b)) #define AL_ADDR_LOW(x) ((uint32_t)((al_phys_addr_t)(x))) #define AL_ADDR_HIGH(x) ((uint32_t)((((al_phys_addr_t)(x)) >> 16) >> 16)) diff --git a/al_hal_serdes.c b/al_hal_serdes.c index bb34d13c765..d45a9438eeb 100644 --- a/al_hal_serdes.c +++ b/al_hal_serdes.c @@ -1,5 +1,4 @@ -/*- -******************************************************************************* +/******************************************************************************* Copyright (C) 2015 Annapurna Labs Ltd. This file may be licensed under the terms of the Annapurna Labs Commercial @@ -34,9 +33,9 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. *******************************************************************************/ -#include "al_hal_serdes.h" -#include "al_hal_serdes_regs.h" -#include "al_hal_serdes_internal_regs.h" +#include "al_hal_serdes_hssp.h" +#include "al_hal_serdes_hssp_regs.h" +#include "al_hal_serdes_hssp_internal_regs.h" #define SRDS_CORE_REG_ADDR(page, type, offset)\ (((page) << 13) | ((type) << 12) | (offset)) @@ -67,64 +66,41 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #define AL_SERDES_RX_EYE_CAL_MDELAY 50 #define AL_SERDES_RX_EYE_CAL_TRIES 70 +#if (!defined(AL_SERDES_BASIC_SERVICES_ONLY)) || (AL_SERDES_BASIC_SERVICES_ONLY == 0) +#define AL_SRDS_ADV_SRVC(func) func +#else +static void al_serdes_hssp_stub_func(void) +{ + al_err("%s: not implemented service called!\n", __func__); +} + +#define AL_SRDS_ADV_SRVC(func) ((typeof(func) *)al_serdes_hssp_stub_func) +#endif /** - * Prototypes for _lane_ compatibility - */ -int al_serdes_lane_read( - struct al_serdes_obj *obj, - enum al_serdes_group grp, - enum al_serdes_lane lane, - enum al_serdes_reg_type type, - uint16_t offset, - uint8_t *data); - -int al_serdes_lane_write( - struct al_serdes_obj *obj, - enum al_serdes_group grp, - enum al_serdes_lane lane, - enum al_serdes_reg_type type, - uint16_t offset, - uint8_t data); - - -/** - * SERDES core reg/lane read + * SERDES core reg read */ static inline uint8_t al_serdes_grp_reg_read( - struct al_serdes_group_info *grp_info, + struct al_serdes_grp_obj *obj, enum al_serdes_reg_page page, enum al_serdes_reg_type type, uint16_t offset); -static inline uint8_t al_serdes_grp_lane_read( - struct al_serdes_group_info *grp_info, - enum al_serdes_lane page, - enum al_serdes_reg_type type, - uint16_t offset); - /** - * SERDES core reg/lane write + * SERDES core reg write */ static inline void al_serdes_grp_reg_write( - struct al_serdes_group_info *grp_info, + struct al_serdes_grp_obj *obj, enum al_serdes_reg_page page, enum al_serdes_reg_type type, uint16_t offset, uint8_t data); -static inline void al_serdes_grp_lane_write( - struct al_serdes_group_info *grp_info, - enum al_serdes_lane lane, - enum al_serdes_reg_type type, - uint16_t offset, - uint8_t data); - /** - * SERDES core masked reg/lane write + * SERDES core masked reg write */ static inline void al_serdes_grp_reg_masked_write( - struct al_serdes_group_info *grp_info, + struct al_serdes_grp_obj *obj, enum al_serdes_reg_page page, enum al_serdes_reg_type type, uint16_t offset, @@ -135,95 +111,63 @@ static inline void al_serdes_grp_reg_masked_write( * Lane Rx rate change software flow disable */ static void _al_serdes_lane_rx_rate_change_sw_flow_dis( - struct al_serdes_group_info *grp_info, + struct al_serdes_grp_obj *obj, enum al_serdes_lane lane); /** * Group Rx rate change software flow enable if all conditions met */ static void al_serdes_group_rx_rate_change_sw_flow_dis( - struct al_serdes_group_info *grp_info); + struct al_serdes_grp_obj *obj); /** * Lane Rx rate change software flow enable if all conditions met */ static void _al_serdes_lane_rx_rate_change_sw_flow_en_cond( - struct al_serdes_group_info *grp_info, + struct al_serdes_grp_obj *obj, enum al_serdes_lane lane); /** * Group Rx rate change software flow enable if all conditions met */ static void al_serdes_group_rx_rate_change_sw_flow_en_cond( - struct al_serdes_group_info *grp_info); - - -static inline void al_serdes_grp_lane_masked_write( - struct al_serdes_group_info *grp_info, - enum al_serdes_lane lane, - enum al_serdes_reg_type type, - uint16_t offset, - uint8_t mask, - uint8_t data); + struct al_serdes_grp_obj *obj); /******************************************************************************/ /******************************************************************************/ -int al_serdes_handle_init( - void __iomem *serdes_regs_base, - struct al_serdes_obj *obj) +static enum al_serdes_type al_serdes_hssp_type_get(void) { - int i; - - al_dbg( - "%s(%p, %p)\n", - __func__, - serdes_regs_base, - obj); - - al_assert(serdes_regs_base); - - for (i = 0; i < AL_SRDS_NUM_GROUPS; i++) { - obj->grp_info[i].pobj = obj; - - obj->grp_info[i].regs_base = - &((struct al_serdes_regs *)serdes_regs_base)[i]; - } - - return 0; + return AL_SRDS_TYPE_HSSP; } /******************************************************************************/ /******************************************************************************/ -int al_serdes_reg_read( - struct al_serdes_obj *obj, - enum al_serdes_group grp, - enum al_serdes_reg_page page, - enum al_serdes_reg_type type, - uint16_t offset, - uint8_t *data) +static int al_serdes_reg_read( + struct al_serdes_grp_obj *obj, + enum al_serdes_reg_page page, + enum al_serdes_reg_type type, + uint16_t offset, + uint8_t *data) { int status = 0; al_dbg( - "%s(%p, %d, %d, %d, %u)\n", + "%s(%p, %d, %d, %u)\n", __func__, obj, - grp, page, type, offset); al_assert(obj); al_assert(data); - al_assert(((int)grp) >= AL_SRDS_GRP_A); - al_assert(((int)grp) <= AL_SRDS_GRP_D); al_assert(((int)page) >= AL_SRDS_REG_PAGE_0_LANE_0); al_assert(((int)page) <= AL_SRDS_REG_PAGE_4_COMMON); al_assert(((int)type) >= AL_SRDS_REG_TYPE_PMA); al_assert(((int)type) <= AL_SRDS_REG_TYPE_PCS); *data = al_serdes_grp_reg_read( - &obj->grp_info[grp], + obj, page, type, offset); @@ -236,49 +180,34 @@ int al_serdes_reg_read( return status; } -int al_serdes_lane_read( - struct al_serdes_obj *obj, - enum al_serdes_group grp, - enum al_serdes_lane lane, - enum al_serdes_reg_type type, - uint16_t offset, - uint8_t *data) -{ - return al_serdes_reg_read(obj, grp, (enum al_serdes_reg_page)lane, type, - offset, data); -} /******************************************************************************/ /******************************************************************************/ -int al_serdes_reg_write( - struct al_serdes_obj *obj, - enum al_serdes_group grp, - enum al_serdes_reg_page page, - enum al_serdes_reg_type type, - uint16_t offset, - uint8_t data) +static int al_serdes_reg_write( + struct al_serdes_grp_obj *obj, + enum al_serdes_reg_page page, + enum al_serdes_reg_type type, + uint16_t offset, + uint8_t data) { int status = 0; al_dbg( - "%s(%p, %d, %d, %d, %u, %u)\n", + "%s(%p, %d, %d, %u, %u)\n", __func__, obj, - grp, page, type, offset, data); al_assert(obj); - al_assert(((int)grp) >= AL_SRDS_GRP_A); - al_assert(((int)grp) <= AL_SRDS_GRP_D); al_assert(((int)page) >= AL_SRDS_REG_PAGE_0_LANE_0); al_assert(((int)page) <= AL_SRDS_REG_PAGE_0123_LANES_0123); al_assert(((int)type) >= AL_SRDS_REG_TYPE_PMA); al_assert(((int)type) <= AL_SRDS_REG_TYPE_PCS); al_serdes_grp_reg_write( - &obj->grp_info[grp], + obj, page, type, offset, @@ -287,17 +216,6 @@ int al_serdes_reg_write( return status; } -int al_serdes_lane_write( - struct al_serdes_obj *obj, - enum al_serdes_group grp, - enum al_serdes_lane lane, - enum al_serdes_reg_type type, - uint16_t offset, - uint8_t data) -{ - return al_serdes_reg_write(obj, grp, (enum al_serdes_reg_page)lane, - type, offset, data); -} /******************************************************************************/ /******************************************************************************/ #if (SERDES_IREG_FLD_PCSRX_DATAWIDTH_REG_NUM != SERDES_IREG_FLD_PCSTX_DATAWIDTH_REG_NUM) @@ -330,12 +248,10 @@ int al_serdes_lane_write( #if (SERDES_IREG_FLD_LANEPCSPSTATE_LOCWREN_REG_NUM != SERDES_IREG_FLD_PCSTX_LOCWREN_REG_NUM) #error "Wrong assumption!" #endif -void al_serdes_bist_overrides_enable( - struct al_serdes_obj *obj, - enum al_serdes_group grp, - enum al_serdes_rate rate) +static void al_serdes_bist_overrides_enable( + struct al_serdes_grp_obj *obj, + enum al_serdes_rate rate) { - struct al_serdes_group_info *grp_info = &obj->grp_info[grp]; int i; uint8_t rx_rate_val; @@ -367,7 +283,7 @@ void al_serdes_bist_overrides_enable( for (i = 0; i < AL_SRDS_NUM_LANES; i++) { al_serdes_grp_reg_masked_write( - grp_info, + obj, (enum al_serdes_reg_page)i, AL_SRDS_REG_TYPE_PMA, SERDES_IREG_FLD_PCSRX_DATAWIDTH_REG_NUM, @@ -377,7 +293,7 @@ void al_serdes_bist_overrides_enable( SERDES_IREG_FLD_PCSTX_DATAWIDTH_VAL_20); al_serdes_grp_reg_masked_write( - grp_info, + obj, (enum al_serdes_reg_page)i, AL_SRDS_REG_TYPE_PMA, SERDES_IREG_FLD_PCSRX_DIVRATE_REG_NUM, @@ -387,7 +303,7 @@ void al_serdes_bist_overrides_enable( } al_serdes_grp_reg_masked_write( - grp_info, + obj, AL_SRDS_REG_PAGE_4_COMMON, AL_SRDS_REG_TYPE_PMA, SERDES_IREG_FLD_CMNPCIEGEN3_LOCWREN_REG_NUM, @@ -398,7 +314,7 @@ void al_serdes_bist_overrides_enable( 0); al_serdes_grp_reg_masked_write( - grp_info, + obj, AL_SRDS_REG_PAGE_4_COMMON, AL_SRDS_REG_TYPE_PMA, SERDES_IREG_FLD_CMNPCIEGEN3_LOCWREN_REG_NUM, @@ -409,7 +325,7 @@ void al_serdes_bist_overrides_enable( 0); al_serdes_grp_reg_masked_write( - grp_info, + obj, AL_SRDS_REG_PAGE_4_COMMON, AL_SRDS_REG_TYPE_PMA, SERDES_IREG_FLD_PCS_LOCWREN_REG_NUM, @@ -417,7 +333,7 @@ void al_serdes_bist_overrides_enable( 0); al_serdes_grp_reg_masked_write( - grp_info, + obj, AL_SRDS_REG_PAGE_4_COMMON, AL_SRDS_REG_TYPE_PMA, SERDES_IREG_FLD_CMNPCS_TXENABLE_REG_NUM, @@ -426,7 +342,7 @@ void al_serdes_bist_overrides_enable( for (i = 0; i < AL_SRDS_NUM_LANES; i++) { al_serdes_grp_reg_masked_write( - grp_info, + obj, (enum al_serdes_reg_page)i, AL_SRDS_REG_TYPE_PMA, SERDES_IREG_FLD_LANEPCSPSTATE_LOCWREN_REG_NUM, @@ -439,7 +355,7 @@ void al_serdes_bist_overrides_enable( 0); al_serdes_grp_reg_masked_write( - grp_info, + obj, (enum al_serdes_reg_page)i, AL_SRDS_REG_TYPE_PMA, SERDES_IREG_FLD_PCSTXBIST_LOCWREN_REG_NUM, @@ -447,7 +363,7 @@ void al_serdes_bist_overrides_enable( 0); al_serdes_grp_reg_masked_write( - grp_info, + obj, (enum al_serdes_reg_page)i, AL_SRDS_REG_TYPE_PMA, SERDES_IREG_FLD_TX_DRV_OVERRIDE_EN_REG_NUM, @@ -455,7 +371,7 @@ void al_serdes_bist_overrides_enable( 0); al_serdes_grp_reg_masked_write( - grp_info, + obj, (enum al_serdes_reg_page)i, AL_SRDS_REG_TYPE_PMA, SERDES_IREG_FLD_RXLOCK2REF_OVREN_REG_NUM, @@ -466,15 +382,13 @@ void al_serdes_bist_overrides_enable( /******************************************************************************/ /******************************************************************************/ -void al_serdes_bist_overrides_disable( - struct al_serdes_obj *obj, - enum al_serdes_group grp) +static void al_serdes_bist_overrides_disable( + struct al_serdes_grp_obj *obj) { - struct al_serdes_group_info *grp_info = &obj->grp_info[grp]; int i; al_serdes_grp_reg_masked_write( - grp_info, + obj, AL_SRDS_REG_PAGE_4_COMMON, AL_SRDS_REG_TYPE_PMA, SERDES_IREG_FLD_CMNPCIEGEN3_LOCWREN_REG_NUM, @@ -483,7 +397,7 @@ void al_serdes_bist_overrides_disable( for (i = 0; i < AL_SRDS_NUM_LANES; i++) { al_serdes_grp_reg_masked_write( - grp_info, + obj, (enum al_serdes_reg_page)i, AL_SRDS_REG_TYPE_PMA, SERDES_IREG_FLD_LANEPCSPSTATE_LOCWREN_REG_NUM, @@ -493,7 +407,7 @@ void al_serdes_bist_overrides_disable( SERDES_IREG_FLD_PCSRXBIST_LOCWREN); al_serdes_grp_reg_masked_write( - grp_info, + obj, (enum al_serdes_reg_page)i, AL_SRDS_REG_TYPE_PMA, SERDES_IREG_FLD_PCSTXBIST_LOCWREN_REG_NUM, @@ -504,12 +418,10 @@ void al_serdes_bist_overrides_disable( /******************************************************************************/ /******************************************************************************/ -void al_serdes_rx_rate_change( - struct al_serdes_obj *obj, - enum al_serdes_group grp, - enum al_serdes_rate rate) +static void al_serdes_rx_rate_change( + struct al_serdes_grp_obj *obj, + enum al_serdes_rate rate) { - struct al_serdes_group_info *grp_info = &obj->grp_info[grp]; int i; uint8_t rx_rate_val; @@ -535,7 +447,7 @@ void al_serdes_rx_rate_change( for (i = 0; i < AL_SRDS_NUM_LANES; i++) { al_serdes_grp_reg_masked_write( - grp_info, + obj, (enum al_serdes_reg_page)i, AL_SRDS_REG_TYPE_PMA, SERDES_IREG_FLD_PCSRX_DIVRATE_REG_NUM, @@ -546,13 +458,10 @@ void al_serdes_rx_rate_change( /******************************************************************************/ /******************************************************************************/ -void al_serdes_group_pm_set( - struct al_serdes_obj *obj, - enum al_serdes_group grp, - enum al_serdes_pm pm) +static void al_serdes_group_pm_set( + struct al_serdes_grp_obj *obj, + enum al_serdes_pm pm) { - struct al_serdes_group_info *grp_info = &obj->grp_info[grp]; - uint8_t pm_val; switch (pm) { @@ -578,10 +487,10 @@ void al_serdes_group_pm_set( } if (pm == AL_SRDS_PM_PD) - al_serdes_group_rx_rate_change_sw_flow_dis(grp_info); + al_serdes_group_rx_rate_change_sw_flow_dis(obj); al_serdes_grp_reg_masked_write( - grp_info, + obj, AL_SRDS_REG_PAGE_4_COMMON, AL_SRDS_REG_TYPE_PMA, SERDES_IREG_FLD_CMNPCSPSTATE_SYNTH_REG_NUM, @@ -589,46 +498,41 @@ void al_serdes_group_pm_set( pm_val); if (pm != AL_SRDS_PM_PD) - al_serdes_group_rx_rate_change_sw_flow_en_cond(grp_info); + al_serdes_group_rx_rate_change_sw_flow_en_cond(obj); } /******************************************************************************/ /******************************************************************************/ -void al_serdes_lane_rx_rate_change_sw_flow_en( - struct al_serdes_obj *obj, - enum al_serdes_group grp, +static void al_serdes_lane_rx_rate_change_sw_flow_en( + struct al_serdes_grp_obj *obj, enum al_serdes_lane lane) { - al_serdes_lane_write(obj, grp, lane, AL_SRDS_REG_TYPE_PMA, 201, 0xfc); - al_serdes_lane_write(obj, grp, lane, AL_SRDS_REG_TYPE_PMA, 202, 0xff); - al_serdes_lane_write(obj, grp, lane, AL_SRDS_REG_TYPE_PMA, 203, 0xff); - al_serdes_lane_write(obj, grp, lane, AL_SRDS_REG_TYPE_PMA, 204, 0xff); - al_serdes_lane_write(obj, grp, lane, AL_SRDS_REG_TYPE_PMA, 205, 0x7f); - al_serdes_lane_write(obj, grp, lane, AL_SRDS_REG_TYPE_PMA, 205, 0xff); + al_serdes_reg_write(obj, (enum al_serdes_reg_page)lane, AL_SRDS_REG_TYPE_PMA, 201, 0xfc); + al_serdes_reg_write(obj, (enum al_serdes_reg_page)lane, AL_SRDS_REG_TYPE_PMA, 202, 0xff); + al_serdes_reg_write(obj, (enum al_serdes_reg_page)lane, AL_SRDS_REG_TYPE_PMA, 203, 0xff); + al_serdes_reg_write(obj, (enum al_serdes_reg_page)lane, AL_SRDS_REG_TYPE_PMA, 204, 0xff); + al_serdes_reg_write(obj, (enum al_serdes_reg_page)lane, AL_SRDS_REG_TYPE_PMA, 205, 0x7f); + al_serdes_reg_write(obj, (enum al_serdes_reg_page)lane, AL_SRDS_REG_TYPE_PMA, 205, 0xff); } /******************************************************************************/ /******************************************************************************/ -void al_serdes_lane_rx_rate_change_sw_flow_dis( - struct al_serdes_obj *obj, - enum al_serdes_group grp, - enum al_serdes_lane lane) +static void al_serdes_lane_rx_rate_change_sw_flow_dis( + struct al_serdes_grp_obj *obj, + enum al_serdes_lane lane) { - al_serdes_lane_write(obj, grp, lane, AL_SRDS_REG_TYPE_PMA, 205, 0x7f); + al_serdes_reg_write(obj, (enum al_serdes_reg_page)lane, AL_SRDS_REG_TYPE_PMA, 205, 0x7f); } /******************************************************************************/ /******************************************************************************/ -void al_serdes_lane_pcie_rate_override_enable_set( - struct al_serdes_obj *obj, - enum al_serdes_group grp, +static void al_serdes_lane_pcie_rate_override_enable_set( + struct al_serdes_grp_obj *obj, enum al_serdes_lane lane, al_bool en) { - struct al_serdes_group_info *grp_info = &obj->grp_info[grp]; - al_serdes_grp_reg_masked_write( - grp_info, + obj, (enum al_serdes_reg_page)lane, AL_SRDS_REG_TYPE_PCS, SERDES_IREG_FLD_PCS_VPCSIF_OVR_RATE_ENA_REG_NUM, @@ -638,16 +542,13 @@ void al_serdes_lane_pcie_rate_override_enable_set( /******************************************************************************/ /******************************************************************************/ -al_bool al_serdes_lane_pcie_rate_override_is_enabled( - struct al_serdes_obj *obj, - enum al_serdes_group grp, +static al_bool al_serdes_lane_pcie_rate_override_is_enabled( + struct al_serdes_grp_obj *obj, enum al_serdes_lane lane) { - struct al_serdes_group_info *grp_info = &obj->grp_info[grp]; - - return (al_serdes_grp_lane_read( - grp_info, - lane, + return (al_serdes_grp_reg_read( + obj, + (enum al_serdes_reg_page)lane, AL_SRDS_REG_TYPE_PCS, SERDES_IREG_FLD_PCS_VPCSIF_OVR_RATE_ENA_REG_NUM) & SERDES_IREG_FLD_PCS_VPCSIF_OVR_RATE_ENA) ? AL_TRUE : AL_FALSE; @@ -655,15 +556,12 @@ al_bool al_serdes_lane_pcie_rate_override_is_enabled( /******************************************************************************/ /******************************************************************************/ -enum al_serdes_pcie_rate al_serdes_lane_pcie_rate_get( - struct al_serdes_obj *obj, - enum al_serdes_group grp, - enum al_serdes_lane lane) +static enum al_serdes_pcie_rate al_serdes_lane_pcie_rate_get( + struct al_serdes_grp_obj *obj, + enum al_serdes_lane lane) { - struct al_serdes_group_info *grp_info = &obj->grp_info[grp]; - return (al_serdes_grp_reg_read( - grp_info, + obj, (enum al_serdes_reg_page)lane, AL_SRDS_REG_TYPE_PCS, SERDES_IREG_FLD_PCS_VPCSIF_OVR_RATE_REG_NUM) & @@ -673,16 +571,13 @@ enum al_serdes_pcie_rate al_serdes_lane_pcie_rate_get( /******************************************************************************/ /******************************************************************************/ -void al_serdes_lane_pcie_rate_set( - struct al_serdes_obj *obj, - enum al_serdes_group grp, +static void al_serdes_lane_pcie_rate_set( + struct al_serdes_grp_obj *obj, enum al_serdes_lane lane, enum al_serdes_pcie_rate rate) { - struct al_serdes_group_info *grp_info = &obj->grp_info[grp]; - al_serdes_grp_reg_masked_write( - grp_info, + obj, (enum al_serdes_reg_page)lane, AL_SRDS_REG_TYPE_PCS, SERDES_IREG_FLD_PCS_VPCSIF_OVR_RATE_REG_NUM, @@ -692,15 +587,12 @@ void al_serdes_lane_pcie_rate_set( /******************************************************************************/ /******************************************************************************/ -void al_serdes_lane_pm_set( - struct al_serdes_obj *obj, - enum al_serdes_group grp, - enum al_serdes_lane lane, - enum al_serdes_pm rx_pm, - enum al_serdes_pm tx_pm) +static void al_serdes_lane_pm_set( + struct al_serdes_grp_obj *obj, + enum al_serdes_lane lane, + enum al_serdes_pm rx_pm, + enum al_serdes_pm tx_pm) { - struct al_serdes_group_info *grp_info = &obj->grp_info[grp]; - uint8_t rx_pm_val; uint8_t tx_pm_val; @@ -749,10 +641,10 @@ void al_serdes_lane_pm_set( } if (rx_pm == AL_SRDS_PM_PD) - _al_serdes_lane_rx_rate_change_sw_flow_dis(grp_info, lane); + _al_serdes_lane_rx_rate_change_sw_flow_dis(obj, lane); al_serdes_grp_reg_masked_write( - grp_info, + obj, (enum al_serdes_reg_page)lane, AL_SRDS_REG_TYPE_PMA, SERDES_IREG_FLD_LANEPCSPSTATE_RX_REG_NUM, @@ -760,7 +652,7 @@ void al_serdes_lane_pm_set( rx_pm_val); al_serdes_grp_reg_masked_write( - grp_info, + obj, (enum al_serdes_reg_page)lane, AL_SRDS_REG_TYPE_PMA, SERDES_IREG_FLD_LANEPCSPSTATE_TX_REG_NUM, @@ -768,24 +660,21 @@ void al_serdes_lane_pm_set( tx_pm_val); if (rx_pm != AL_SRDS_PM_PD) - _al_serdes_lane_rx_rate_change_sw_flow_en_cond(grp_info, lane); + _al_serdes_lane_rx_rate_change_sw_flow_en_cond(obj, lane); } /******************************************************************************/ /******************************************************************************/ -void al_serdes_pma_hard_reset_group( - struct al_serdes_obj *obj, - enum al_serdes_group grp, - al_bool enable) +static void al_serdes_pma_hard_reset_group( + struct al_serdes_grp_obj *obj, + al_bool enable) { - struct al_serdes_group_info *grp_info = &obj->grp_info[grp]; - if (enable) - al_serdes_group_rx_rate_change_sw_flow_dis(grp_info); + al_serdes_group_rx_rate_change_sw_flow_dis(obj); /* Enable Hard Reset Override */ al_serdes_grp_reg_masked_write( - grp_info, + obj, AL_SRDS_REG_PAGE_4_COMMON, AL_SRDS_REG_TYPE_PMA, SERDES_IREG_FLD_CMNCTLPOR_HARDRSTBYPASSEN_SYNTH_REG_NUM, @@ -794,7 +683,7 @@ void al_serdes_pma_hard_reset_group( /* Assert/Deassert Hard Reset Override */ al_serdes_grp_reg_masked_write( - grp_info, + obj, AL_SRDS_REG_PAGE_4_COMMON, AL_SRDS_REG_TYPE_PMA, SERDES_IREG_FLD_CMNCTLPOR_HARDRSTBYPASS_SYNTH_REG_NUM, @@ -804,25 +693,22 @@ void al_serdes_pma_hard_reset_group( SERDES_IREG_FLD_CMNCTLPOR_HARDRSTBYPASS_SYNTH_VAL_DEASSERT); if (!enable) - al_serdes_group_rx_rate_change_sw_flow_en_cond(grp_info); + al_serdes_group_rx_rate_change_sw_flow_en_cond(obj); } /******************************************************************************/ /******************************************************************************/ -void al_serdes_pma_hard_reset_lane( - struct al_serdes_obj *obj, - enum al_serdes_group grp, - enum al_serdes_lane lane, - al_bool enable) +static void al_serdes_pma_hard_reset_lane( + struct al_serdes_grp_obj *obj, + enum al_serdes_lane lane, + al_bool enable) { - struct al_serdes_group_info *grp_info = &obj->grp_info[grp]; - if (enable) - _al_serdes_lane_rx_rate_change_sw_flow_dis(grp_info, lane); + _al_serdes_lane_rx_rate_change_sw_flow_dis(obj, lane); /* Enable Hard Reset Override */ al_serdes_grp_reg_masked_write( - grp_info, + obj, (enum al_serdes_reg_page)lane, AL_SRDS_REG_TYPE_PMA, SERDES_IREG_FLD_CMNCTLPOR_HARDRSTBYPASSEN_REG_NUM, @@ -831,7 +717,7 @@ void al_serdes_pma_hard_reset_lane( /* Assert/Deassert Hard Reset Override */ al_serdes_grp_reg_masked_write( - grp_info, + obj, (enum al_serdes_reg_page)lane, AL_SRDS_REG_TYPE_PMA, SERDES_IREG_FLD_CMNCTLPOR_HARDRSTBYPASS_REG_NUM, @@ -841,7 +727,7 @@ void al_serdes_pma_hard_reset_lane( SERDES_IREG_FLD_CMNCTLPOR_HARDRSTBYPASS_VAL_DEASSERT); if (!enable) - _al_serdes_lane_rx_rate_change_sw_flow_en_cond(grp_info, lane); + _al_serdes_lane_rx_rate_change_sw_flow_en_cond(obj, lane); } /******************************************************************************/ @@ -857,13 +743,11 @@ void al_serdes_pma_hard_reset_lane( #error Wrong assumption #endif -void al_serdes_loopback_control( - struct al_serdes_obj *obj, - enum al_serdes_group grp, - enum al_serdes_lane lane, - enum al_serdes_lb_mode mode) +static void al_serdes_loopback_control( + struct al_serdes_grp_obj *obj, + enum al_serdes_lane lane, + enum al_serdes_lb_mode mode) { - struct al_serdes_group_info *grp_info = &obj->grp_info[grp]; uint8_t val = 0; switch (mode) { @@ -888,7 +772,7 @@ void al_serdes_loopback_control( } al_serdes_grp_reg_masked_write( - grp_info, + obj, (enum al_serdes_reg_page)lane, AL_SRDS_REG_TYPE_PMA, SERDES_IREG_FLD_LB_RX2TXUNTIMEDEN_REG_NUM, @@ -902,13 +786,11 @@ void al_serdes_loopback_control( /******************************************************************************/ /******************************************************************************/ -void al_serdes_bist_pattern_select( - struct al_serdes_obj *obj, - enum al_serdes_group grp, +static void al_serdes_bist_pattern_select( + struct al_serdes_grp_obj *obj, enum al_serdes_bist_pattern pattern, uint8_t *user_data) { - struct al_serdes_group_info *grp_info = &obj->grp_info[grp]; uint8_t val = 0; switch (pattern) { @@ -938,7 +820,7 @@ void al_serdes_bist_pattern_select( for (i = 0; i < SERDES_IREG_FLD_TX_BIST_PAT_NUM_BYTES; i++) al_serdes_grp_reg_write( - grp_info, + obj, AL_SRDS_REG_PAGE_4_COMMON, AL_SRDS_REG_TYPE_PMA, SERDES_IREG_FLD_TX_BIST_PAT_REG_NUM(i), @@ -946,7 +828,7 @@ void al_serdes_bist_pattern_select( } al_serdes_grp_reg_masked_write( - grp_info, + obj, AL_SRDS_REG_PAGE_4_COMMON, AL_SRDS_REG_TYPE_PMA, SERDES_IREG_FLD_CMNPCSBIST_MODESEL_REG_NUM, @@ -956,16 +838,13 @@ void al_serdes_bist_pattern_select( /******************************************************************************/ /******************************************************************************/ -void al_serdes_bist_tx_enable( - struct al_serdes_obj *obj, - enum al_serdes_group grp, - enum al_serdes_lane lane, - al_bool enable) +static void al_serdes_bist_tx_enable( + struct al_serdes_grp_obj *obj, + enum al_serdes_lane lane, + al_bool enable) { - struct al_serdes_group_info *grp_info = &obj->grp_info[grp]; - al_serdes_grp_reg_masked_write( - grp_info, + obj, (enum al_serdes_reg_page)lane, AL_SRDS_REG_TYPE_PMA, SERDES_IREG_FLD_PCSTXBIST_EN_REG_NUM, @@ -975,14 +854,11 @@ void al_serdes_bist_tx_enable( /******************************************************************************/ /******************************************************************************/ -void al_serdes_bist_tx_err_inject( - struct al_serdes_obj *obj, - enum al_serdes_group grp) +static void al_serdes_bist_tx_err_inject( + struct al_serdes_grp_obj *obj) { - struct al_serdes_group_info *grp_info = &obj->grp_info[grp]; - al_serdes_grp_reg_masked_write( - grp_info, + obj, AL_SRDS_REG_PAGE_4_COMMON, AL_SRDS_REG_TYPE_PMA, SERDES_IREG_FLD_TXBIST_BITERROR_EN_REG_NUM, @@ -990,7 +866,7 @@ void al_serdes_bist_tx_err_inject( SERDES_IREG_FLD_TXBIST_BITERROR_EN); al_serdes_grp_reg_masked_write( - grp_info, + obj, AL_SRDS_REG_PAGE_4_COMMON, AL_SRDS_REG_TYPE_PMA, SERDES_IREG_FLD_TXBIST_BITERROR_EN_REG_NUM, @@ -1000,16 +876,13 @@ void al_serdes_bist_tx_err_inject( /******************************************************************************/ /******************************************************************************/ -void al_serdes_bist_rx_enable( - struct al_serdes_obj *obj, - enum al_serdes_group grp, - enum al_serdes_lane lane, - al_bool enable) +static void al_serdes_bist_rx_enable( + struct al_serdes_grp_obj *obj, + enum al_serdes_lane lane, + al_bool enable) { - struct al_serdes_group_info *grp_info = &obj->grp_info[grp]; - al_serdes_grp_reg_masked_write( - grp_info, + obj, (enum al_serdes_reg_page)lane, AL_SRDS_REG_TYPE_PMA, SERDES_IREG_FLD_PCSRXBIST_EN_REG_NUM, @@ -1024,33 +897,31 @@ void al_serdes_bist_rx_enable( #error Wrong assumption #endif -void al_serdes_bist_rx_status( - struct al_serdes_obj *obj, - enum al_serdes_group grp, - enum al_serdes_lane lane, - al_bool *is_locked, - al_bool *err_cnt_overflow, - uint16_t *err_cnt) +static void al_serdes_bist_rx_status( + struct al_serdes_grp_obj *obj, + enum al_serdes_lane lane, + al_bool *is_locked, + al_bool *err_cnt_overflow, + uint32_t *err_cnt) { - struct al_serdes_group_info *grp_info = &obj->grp_info[grp]; uint8_t status_reg_val; uint16_t err_cnt_msb_reg_val; uint16_t err_cnt_lsb_reg_val; status_reg_val = al_serdes_grp_reg_read( - grp_info, + obj, (enum al_serdes_reg_page)lane, AL_SRDS_REG_TYPE_PMA, SERDES_IREG_FLD_RXBIST_RXLOCKED_REG_NUM); err_cnt_msb_reg_val = al_serdes_grp_reg_read( - grp_info, + obj, (enum al_serdes_reg_page)lane, AL_SRDS_REG_TYPE_PMA, SERDES_IREG_FLD_RXBIST_ERRCOUNT_MSB_REG_NUM); err_cnt_lsb_reg_val = al_serdes_grp_reg_read( - grp_info, + obj, (enum al_serdes_reg_page)lane, AL_SRDS_REG_TYPE_PMA, SERDES_IREG_FLD_RXBIST_ERRCOUNT_LSB_REG_NUM); @@ -1069,54 +940,36 @@ void al_serdes_bist_rx_status( /******************************************************************************/ /******************************************************************************/ static inline uint8_t al_serdes_grp_reg_read( - struct al_serdes_group_info *grp_info, + struct al_serdes_grp_obj *obj, enum al_serdes_reg_page page, enum al_serdes_reg_type type, uint16_t offset) { + struct al_serdes_regs __iomem *regs_base = obj->regs_base; + al_reg_write32( - &grp_info->regs_base->gen.reg_addr, + ®s_base->gen.reg_addr, SRDS_CORE_REG_ADDR(page, type, offset)); - return al_reg_read32(&grp_info->regs_base->gen.reg_data); -} - -static inline uint8_t al_serdes_grp_lane_read( - struct al_serdes_group_info *grp_info, - enum al_serdes_lane page, - enum al_serdes_reg_type type, - uint16_t offset) -{ - return al_serdes_grp_reg_read(grp_info, (enum al_serdes_reg_page)page, - type, offset); + return al_reg_read32(®s_base->gen.reg_data); } /******************************************************************************/ /******************************************************************************/ static inline void al_serdes_grp_reg_write( - struct al_serdes_group_info *grp_info, + struct al_serdes_grp_obj *obj, enum al_serdes_reg_page page, enum al_serdes_reg_type type, uint16_t offset, uint8_t data) { + struct al_serdes_regs __iomem *regs_base = obj->regs_base; + al_reg_write32( - &grp_info->regs_base->gen.reg_addr, + ®s_base->gen.reg_addr, SRDS_CORE_REG_ADDR(page, type, offset)); - al_reg_write32(&grp_info->regs_base->gen.reg_data, data); -} - - -static inline void al_serdes_grp_lane_write( - struct al_serdes_group_info *grp_info, - enum al_serdes_lane lane, - enum al_serdes_reg_type type, - uint16_t offset, - uint8_t data) -{ - al_serdes_grp_reg_write(grp_info, (enum al_serdes_reg_page)lane, - type, offset, data); + al_reg_write32(®s_base->gen.reg_data, data); } /******************************************************************************/ @@ -1129,7 +982,7 @@ static inline void al_serdes_ns_delay(int cnt) /******************************************************************************/ /******************************************************************************/ static inline void al_serdes_grp_reg_masked_write( - struct al_serdes_group_info *grp_info, + struct al_serdes_grp_obj *obj, enum al_serdes_reg_page page, enum al_serdes_reg_type type, uint16_t offset, @@ -1146,30 +999,18 @@ static inline void al_serdes_grp_reg_masked_write( end_page = AL_SRDS_REG_PAGE_3_LANE_3; } - for(iter_page = start_page; iter_page <= end_page; ++iter_page) { - val = al_serdes_grp_reg_read(grp_info, iter_page, type, offset); + for (iter_page = start_page; iter_page <= end_page; ++iter_page) { + val = al_serdes_grp_reg_read(obj, iter_page, type, offset); val &= ~mask; val |= data; - al_serdes_grp_reg_write(grp_info, iter_page, type, offset, val); + al_serdes_grp_reg_write(obj, iter_page, type, offset, val); } } -static inline void al_serdes_grp_lane_masked_write( - struct al_serdes_group_info *grp_info, - enum al_serdes_lane lane, - enum al_serdes_reg_type type, - uint16_t offset, - uint8_t mask, - uint8_t data) -{ - al_serdes_grp_reg_masked_write(grp_info, (enum al_serdes_reg_page)lane, - type, offset, mask, data); -} - /******************************************************************************/ /******************************************************************************/ static void _al_serdes_lane_rx_rate_change_sw_flow_dis( - struct al_serdes_group_info *grp_info, + struct al_serdes_grp_obj *obj, enum al_serdes_lane lane) { al_bool lane_sw_flow_enabled; @@ -1177,15 +1018,15 @@ static void _al_serdes_lane_rx_rate_change_sw_flow_dis( al_assert(lane != AL_SRDS_LANES_0123); lane_sw_flow_enabled = - (al_serdes_grp_reg_read(grp_info, (enum al_serdes_reg_page)lane, + (al_serdes_grp_reg_read(obj, (enum al_serdes_reg_page)lane, AL_SRDS_REG_TYPE_PMA, 201) == 0xfc) && - (al_serdes_grp_reg_read(grp_info, (enum al_serdes_reg_page)lane, + (al_serdes_grp_reg_read(obj, (enum al_serdes_reg_page)lane, AL_SRDS_REG_TYPE_PMA, 202) == 0xff) && - (al_serdes_grp_reg_read(grp_info, (enum al_serdes_reg_page)lane, + (al_serdes_grp_reg_read(obj, (enum al_serdes_reg_page)lane, AL_SRDS_REG_TYPE_PMA, 203) == 0xff) && - (al_serdes_grp_reg_read(grp_info, (enum al_serdes_reg_page)lane, + (al_serdes_grp_reg_read(obj, (enum al_serdes_reg_page)lane, AL_SRDS_REG_TYPE_PMA, 204) == 0xff) && - (al_serdes_grp_reg_read(grp_info, (enum al_serdes_reg_page)lane, + (al_serdes_grp_reg_read(obj, (enum al_serdes_reg_page)lane, AL_SRDS_REG_TYPE_PMA, 205) == 0xff); /** @@ -1194,7 +1035,7 @@ static void _al_serdes_lane_rx_rate_change_sw_flow_dis( */ if (lane_sw_flow_enabled) { al_dbg("%s(%d): actually disabling\n", __func__, lane); - al_serdes_grp_reg_masked_write(grp_info, (enum al_serdes_reg_page)lane, + al_serdes_grp_reg_masked_write(obj, (enum al_serdes_reg_page)lane, AL_SRDS_REG_TYPE_PMA, 205, 0x80, 0x00); } } @@ -1202,18 +1043,18 @@ static void _al_serdes_lane_rx_rate_change_sw_flow_dis( /******************************************************************************/ /******************************************************************************/ static void al_serdes_group_rx_rate_change_sw_flow_dis( - struct al_serdes_group_info *grp_info) + struct al_serdes_grp_obj *obj) { int lane; for (lane = AL_SRDS_LANE_0; lane < AL_SRDS_NUM_LANES; lane++) - _al_serdes_lane_rx_rate_change_sw_flow_dis(grp_info, lane); + _al_serdes_lane_rx_rate_change_sw_flow_dis(obj, lane); } /******************************************************************************/ /******************************************************************************/ static void _al_serdes_lane_rx_rate_change_sw_flow_en_cond( - struct al_serdes_group_info *grp_info, + struct al_serdes_grp_obj *obj, enum al_serdes_lane lane) { al_bool lane_sw_flow_almost_enabled; @@ -1225,51 +1066,51 @@ static void _al_serdes_lane_rx_rate_change_sw_flow_en_cond( al_assert(lane != AL_SRDS_LANES_0123); lane_sw_flow_almost_enabled = - (al_serdes_grp_reg_read(grp_info, (enum al_serdes_reg_page)lane, + (al_serdes_grp_reg_read(obj, (enum al_serdes_reg_page)lane, AL_SRDS_REG_TYPE_PMA, 201) == 0xfc) && - (al_serdes_grp_reg_read(grp_info, (enum al_serdes_reg_page)lane, + (al_serdes_grp_reg_read(obj, (enum al_serdes_reg_page)lane, AL_SRDS_REG_TYPE_PMA, 202) == 0xff) && - (al_serdes_grp_reg_read(grp_info, (enum al_serdes_reg_page)lane, + (al_serdes_grp_reg_read(obj, (enum al_serdes_reg_page)lane, AL_SRDS_REG_TYPE_PMA, 203) == 0xff) && - (al_serdes_grp_reg_read(grp_info, (enum al_serdes_reg_page)lane, + (al_serdes_grp_reg_read(obj, (enum al_serdes_reg_page)lane, AL_SRDS_REG_TYPE_PMA, 204) == 0xff) && - (al_serdes_grp_reg_read(grp_info, (enum al_serdes_reg_page)lane, + (al_serdes_grp_reg_read(obj, (enum al_serdes_reg_page)lane, AL_SRDS_REG_TYPE_PMA, 205) == 0x7f); group_reset_enabled = ((al_serdes_grp_reg_read( - grp_info, AL_SRDS_REG_PAGE_4_COMMON, AL_SRDS_REG_TYPE_PMA, + obj, AL_SRDS_REG_PAGE_4_COMMON, AL_SRDS_REG_TYPE_PMA, SERDES_IREG_FLD_CMNCTLPOR_HARDRSTBYPASSEN_SYNTH_REG_NUM) & SERDES_IREG_FLD_CMNCTLPOR_HARDRSTBYPASSEN_SYNTH_MASK) == SERDES_IREG_FLD_CMNCTLPOR_HARDRSTBYPASSEN_SYNTH_VAL_REGS) && ((al_serdes_grp_reg_read( - grp_info, AL_SRDS_REG_PAGE_4_COMMON, AL_SRDS_REG_TYPE_PMA, + obj, AL_SRDS_REG_PAGE_4_COMMON, AL_SRDS_REG_TYPE_PMA, SERDES_IREG_FLD_CMNCTLPOR_HARDRSTBYPASS_SYNTH_REG_NUM) & SERDES_IREG_FLD_CMNCTLPOR_HARDRSTBYPASS_SYNTH_MASK) == SERDES_IREG_FLD_CMNCTLPOR_HARDRSTBYPASS_SYNTH_VAL_ASSERT); lane_reset_enabled = ((al_serdes_grp_reg_read( - grp_info, (enum al_serdes_reg_page)lane, AL_SRDS_REG_TYPE_PMA, + obj, (enum al_serdes_reg_page)lane, AL_SRDS_REG_TYPE_PMA, SERDES_IREG_FLD_CMNCTLPOR_HARDRSTBYPASSEN_REG_NUM) & SERDES_IREG_FLD_CMNCTLPOR_HARDRSTBYPASSEN_MASK) == SERDES_IREG_FLD_CMNCTLPOR_HARDRSTBYPASSEN_VAL_REGS) && ((al_serdes_grp_reg_read( - grp_info, (enum al_serdes_reg_page)lane, AL_SRDS_REG_TYPE_PMA, + obj, (enum al_serdes_reg_page)lane, AL_SRDS_REG_TYPE_PMA, SERDES_IREG_FLD_CMNCTLPOR_HARDRSTBYPASS_REG_NUM) & SERDES_IREG_FLD_CMNCTLPOR_HARDRSTBYPASS_MASK) == SERDES_IREG_FLD_CMNCTLPOR_HARDRSTBYPASS_VAL_ASSERT); group_pd_enabled = (al_serdes_grp_reg_read( - grp_info, AL_SRDS_REG_PAGE_4_COMMON, AL_SRDS_REG_TYPE_PMA, + obj, AL_SRDS_REG_PAGE_4_COMMON, AL_SRDS_REG_TYPE_PMA, SERDES_IREG_FLD_CMNPCSPSTATE_SYNTH_REG_NUM) & SERDES_IREG_FLD_CMNPCSPSTATE_SYNTH_MASK) == SERDES_IREG_FLD_CMNPCSPSTATE_SYNTH_VAL_PD; lane_pd_enabled = (al_serdes_grp_reg_read( - grp_info, (enum al_serdes_reg_page)lane, AL_SRDS_REG_TYPE_PMA, + obj, (enum al_serdes_reg_page)lane, AL_SRDS_REG_TYPE_PMA, SERDES_IREG_FLD_LANEPCSPSTATE_RX_REG_NUM) & SERDES_IREG_FLD_LANEPCSPSTATE_RX_MASK) == SERDES_IREG_FLD_LANEPCSPSTATE_RX_VAL_PD; @@ -1283,7 +1124,7 @@ static void _al_serdes_lane_rx_rate_change_sw_flow_en_cond( al_dbg("%s(%d): actually enabling\n", __func__, lane); al_serdes_ns_delay(500); - al_serdes_grp_reg_masked_write(grp_info, (enum al_serdes_reg_page)lane, + al_serdes_grp_reg_masked_write(obj, (enum al_serdes_reg_page)lane, AL_SRDS_REG_TYPE_PMA, 205, 0x80, 0x80); } } @@ -1291,33 +1132,34 @@ static void _al_serdes_lane_rx_rate_change_sw_flow_en_cond( /******************************************************************************/ /******************************************************************************/ static void al_serdes_group_rx_rate_change_sw_flow_en_cond( - struct al_serdes_group_info *grp_info) + struct al_serdes_grp_obj *obj) { int lane; for (lane = AL_SRDS_LANE_0; lane < AL_SRDS_NUM_LANES; lane++) - _al_serdes_lane_rx_rate_change_sw_flow_en_cond(grp_info, lane); + _al_serdes_lane_rx_rate_change_sw_flow_en_cond(obj, lane); } /******************************************************************************/ /******************************************************************************/ -int al_serdes_eye_measure_run( - struct al_serdes_obj *obj, - enum al_serdes_group grp, - enum al_serdes_lane lane, - uint32_t timeout, - unsigned int *value) +static int al_serdes_eye_measure_run( + struct al_serdes_grp_obj *obj, + enum al_serdes_lane lane, + uint32_t timeout, + unsigned int *value) { + struct al_serdes_grp_obj *grp_obj = obj; + struct al_serdes_regs __iomem *regs_base = grp_obj->regs_base; uint32_t reg = 0; uint32_t i; struct serdes_lane *lane_regs; - lane_regs = &obj->grp_info[grp].regs_base->lane[lane]; + lane_regs = ®s_base->lane[lane]; al_reg_write32(&lane_regs->ictl_multi_rxeq, SERDES_LANE_ICTL_MULTI_RXEQ_START_L_A); - for (i = 0 ; i < timeout ; i++) { + for (i = 0; i < timeout; i++) { reg = al_reg_read32(&lane_regs->octl_multi); if (reg & SERDES_LANE_OCTL_MULTI_RXEQ_DONE_L_A) @@ -1340,83 +1182,77 @@ int al_serdes_eye_measure_run( /******************************************************************************/ /******************************************************************************/ -int al_serdes_eye_diag_sample( - struct al_serdes_obj *obj, - enum al_serdes_group grp, - enum al_serdes_lane lane, - unsigned int x, - int y, - unsigned int timeout, - unsigned int *value) +static int al_serdes_eye_diag_sample( + struct al_serdes_grp_obj *obj, + enum al_serdes_lane lane, + unsigned int x, + int y, + unsigned int timeout, + unsigned int *value) { enum al_serdes_reg_page page = (enum al_serdes_reg_page)lane; - struct al_serdes_group_info *grp_info; uint32_t i; uint8_t sample_count_orig_msb; uint8_t sample_count_orig_lsb; al_assert(obj); - al_assert(((int)grp) >= AL_SRDS_GRP_A); - al_assert(((int)grp) <= AL_SRDS_GRP_D); al_assert(((int)page) >= AL_SRDS_REG_PAGE_0_LANE_0); al_assert(((int)page) <= AL_SRDS_REG_PAGE_0123_LANES_0123); - grp_info = &obj->grp_info[grp]; - /* Obtain sample count by reading RXCALROAMEYEMEAS_COUNT */ - sample_count_orig_msb = al_serdes_grp_reg_read(grp_info, + sample_count_orig_msb = al_serdes_grp_reg_read(obj, AL_SRDS_REG_PAGE_4_COMMON, AL_SRDS_REG_TYPE_PMA, SERDES_IREG_FLD_EYE_DIAG_SAMPLE_CNT_MSB_REG_NUM); - sample_count_orig_lsb = al_serdes_grp_reg_read(grp_info, + sample_count_orig_lsb = al_serdes_grp_reg_read(obj, AL_SRDS_REG_PAGE_4_COMMON, AL_SRDS_REG_TYPE_PMA, SERDES_IREG_FLD_EYE_DIAG_SAMPLE_CNT_LSB_REG_NUM); /* Set sample count to ~100000 samples */ - al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON, + al_serdes_grp_reg_write(obj, AL_SRDS_REG_PAGE_4_COMMON, AL_SRDS_REG_TYPE_PMA, SERDES_IREG_FLD_EYE_DIAG_SAMPLE_CNT_MSB_REG_NUM, 0x13); - al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON, + al_serdes_grp_reg_write(obj, AL_SRDS_REG_PAGE_4_COMMON, AL_SRDS_REG_TYPE_PMA, SERDES_IREG_FLD_EYE_DIAG_SAMPLE_CNT_LSB_REG_NUM, 0x88); /* BER Contour Overwrite */ - al_serdes_grp_reg_masked_write(grp_info, page, AL_SRDS_REG_TYPE_PMA, + al_serdes_grp_reg_masked_write(obj, page, AL_SRDS_REG_TYPE_PMA, SERDES_IREG_FLD_RXCALROAMEYEMEASIN_LOCWREN_REG_NUM, SERDES_IREG_FLD_RXCALROAMEYEMEASIN_LOCWREN, 0); - al_serdes_grp_reg_masked_write(grp_info, page, AL_SRDS_REG_TYPE_PMA, + al_serdes_grp_reg_masked_write(obj, page, AL_SRDS_REG_TYPE_PMA, SERDES_IREG_FLD_RXCALROAMXADJUST_LOCWREN_REG_NUM, SERDES_IREG_FLD_RXCALROAMXADJUST_LOCWREN, 0); - al_serdes_grp_reg_masked_write(grp_info, page, AL_SRDS_REG_TYPE_PMA, + al_serdes_grp_reg_masked_write(obj, page, AL_SRDS_REG_TYPE_PMA, SERDES_IREG_FLD_RXCALROAMYADJUST_LOCWREN_REG_NUM, SERDES_IREG_FLD_RXCALROAMYADJUST_LOCWREN, 0); /* RXROAM_XORBITSEL = 0x1 or 0x0 */ - al_serdes_grp_reg_masked_write(grp_info, page, AL_SRDS_REG_TYPE_PMA, + al_serdes_grp_reg_masked_write(obj, page, AL_SRDS_REG_TYPE_PMA, SERDES_IREG_FLD_RXROAM_XORBITSEL_REG_NUM, SERDES_IREG_FLD_RXROAM_XORBITSEL, SERDES_IREG_FLD_RXROAM_XORBITSEL_2ND); /* Set X */ - al_serdes_grp_reg_write(grp_info, page, AL_SRDS_REG_TYPE_PMA, + al_serdes_grp_reg_write(obj, page, AL_SRDS_REG_TYPE_PMA, SERDES_IREG_FLD_RXCALROAMXADJUST_REG_NUM, x); /* Set Y */ - al_serdes_grp_reg_write(grp_info, page, AL_SRDS_REG_TYPE_PMA, + al_serdes_grp_reg_write(obj, page, AL_SRDS_REG_TYPE_PMA, SERDES_IREG_FLD_RXCALROAMYADJUST_REG_NUM, y < 32 ? 31 - y : y + 1); /* Start Measurement by setting RXCALROAMEYEMEASIN_CYCLEEN = 0x1 */ - al_serdes_grp_reg_masked_write(grp_info, page, AL_SRDS_REG_TYPE_PMA, + al_serdes_grp_reg_masked_write(obj, page, AL_SRDS_REG_TYPE_PMA, SERDES_IREG_FLD_RXCALROAMEYEMEASIN_CYCLEEN_REG_NUM, SERDES_IREG_FLD_RXCALROAMEYEMEASIN_CYCLEEN_START, SERDES_IREG_FLD_RXCALROAMEYEMEASIN_CYCLEEN_START); /* Check RXCALROAMEYEMEASDONE Signal (Polling Until 0x1) */ - for (i = 0 ; i < timeout ; i++) { - if (al_serdes_grp_reg_read(grp_info, page, AL_SRDS_REG_TYPE_PMA, + for (i = 0; i < timeout; i++) { + if (al_serdes_grp_reg_read(obj, page, AL_SRDS_REG_TYPE_PMA, SERDES_IREG_FLD_RXCALROAMEYEMEASDONE_REG_NUM) & SERDES_IREG_FLD_RXCALROAMEYEMEASDONE) break; @@ -1428,38 +1264,38 @@ int al_serdes_eye_diag_sample( } /* Stop Measurement by setting RXCALROAMEYEMEASIN_CYCLEEN = 0x0 */ - al_serdes_grp_reg_masked_write(grp_info, page, AL_SRDS_REG_TYPE_PMA, + al_serdes_grp_reg_masked_write(obj, page, AL_SRDS_REG_TYPE_PMA, SERDES_IREG_FLD_RXCALROAMEYEMEASIN_CYCLEEN_REG_NUM, SERDES_IREG_FLD_RXCALROAMEYEMEASIN_CYCLEEN_START, 0); /* Obtain Error Counts by reading RXCALROAMEYEMEAS_ACC */ - *value = ((unsigned int)al_serdes_grp_reg_read(grp_info, page, + *value = ((unsigned int)al_serdes_grp_reg_read(obj, page, AL_SRDS_REG_TYPE_PMA, SERDES_IREG_FLD_RXCALROAMEYEMEAS_ACC_MSB_REG_NUM)) << 8 | - al_serdes_grp_reg_read(grp_info, page, AL_SRDS_REG_TYPE_PMA, + al_serdes_grp_reg_read(obj, page, AL_SRDS_REG_TYPE_PMA, SERDES_IREG_FLD_RXCALROAMEYEMEAS_ACC_LSB_REG_NUM); /* BER Contour Overwrite */ - al_serdes_grp_reg_masked_write(grp_info, page, AL_SRDS_REG_TYPE_PMA, + al_serdes_grp_reg_masked_write(obj, page, AL_SRDS_REG_TYPE_PMA, SERDES_IREG_FLD_RXCALROAMEYEMEASIN_LOCWREN_REG_NUM, SERDES_IREG_FLD_RXCALROAMEYEMEASIN_LOCWREN, SERDES_IREG_FLD_RXCALROAMEYEMEASIN_LOCWREN); - al_serdes_grp_reg_masked_write(grp_info, page, AL_SRDS_REG_TYPE_PMA, + al_serdes_grp_reg_masked_write(obj, page, AL_SRDS_REG_TYPE_PMA, SERDES_IREG_FLD_RXCALROAMXADJUST_LOCWREN_REG_NUM, SERDES_IREG_FLD_RXCALROAMXADJUST_LOCWREN, SERDES_IREG_FLD_RXCALROAMXADJUST_LOCWREN); - al_serdes_grp_reg_masked_write(grp_info, page, AL_SRDS_REG_TYPE_PMA, + al_serdes_grp_reg_masked_write(obj, page, AL_SRDS_REG_TYPE_PMA, SERDES_IREG_FLD_RXCALROAMYADJUST_LOCWREN_REG_NUM, SERDES_IREG_FLD_RXCALROAMYADJUST_LOCWREN, SERDES_IREG_FLD_RXCALROAMYADJUST_LOCWREN); /* Restore sample count */ - al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON, + al_serdes_grp_reg_write(obj, AL_SRDS_REG_PAGE_4_COMMON, AL_SRDS_REG_TYPE_PMA, SERDES_IREG_FLD_EYE_DIAG_SAMPLE_CNT_MSB_REG_NUM, sample_count_orig_msb); - al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON, + al_serdes_grp_reg_write(obj, AL_SRDS_REG_PAGE_4_COMMON, AL_SRDS_REG_TYPE_PMA, SERDES_IREG_FLD_EYE_DIAG_SAMPLE_CNT_LSB_REG_NUM, sample_count_orig_lsb); @@ -1470,33 +1306,32 @@ int al_serdes_eye_diag_sample( /******************************************************************************/ /******************************************************************************/ static void al_serdes_tx_deemph_set( - struct al_serdes_obj *obj, - enum al_serdes_group grp, - enum al_serdes_lane lane, - uint32_t c_zero, - uint32_t c_plus_1, - uint32_t c_minus_1) + struct al_serdes_grp_obj *obj, + enum al_serdes_lane lane, + uint32_t c_zero, + uint32_t c_plus_1, + uint32_t c_minus_1) { - al_serdes_grp_lane_masked_write( - &obj->grp_info[grp], - lane, + al_serdes_grp_reg_masked_write( + obj, + (enum al_serdes_reg_page)lane, AL_SRDS_REG_TYPE_PMA, SERDES_IREG_TX_DRV_1_REG_NUM, SERDES_IREG_TX_DRV_1_LEVN_MASK, ((c_zero + c_plus_1 + c_minus_1) << SERDES_IREG_TX_DRV_1_LEVN_SHIFT)); - al_serdes_grp_lane_masked_write( - &obj->grp_info[grp], - lane, + al_serdes_grp_reg_masked_write( + obj, + (enum al_serdes_reg_page)lane, AL_SRDS_REG_TYPE_PMA, SERDES_IREG_TX_DRV_2_REG_NUM, SERDES_IREG_TX_DRV_2_LEVNM1_MASK, (c_plus_1 << SERDES_IREG_TX_DRV_2_LEVNM1_SHIFT)); - al_serdes_grp_lane_masked_write( - &obj->grp_info[grp], - lane, + al_serdes_grp_reg_masked_write( + obj, + (enum al_serdes_reg_page)lane, AL_SRDS_REG_TYPE_PMA, SERDES_IREG_TX_DRV_3_REG_NUM, SERDES_IREG_TX_DRV_3_LEVNP1_MASK, @@ -1504,36 +1339,35 @@ static void al_serdes_tx_deemph_set( } static void al_serdes_tx_deemph_get( - struct al_serdes_obj *obj, - enum al_serdes_group grp, - enum al_serdes_lane lane, - uint32_t *c_zero, - uint32_t *c_plus_1, - uint32_t *c_minus_1) + struct al_serdes_grp_obj *obj, + enum al_serdes_lane lane, + uint32_t *c_zero, + uint32_t *c_plus_1, + uint32_t *c_minus_1) { uint32_t reg = 0; - reg = al_serdes_grp_lane_read( - &obj->grp_info[grp], - lane, + reg = al_serdes_grp_reg_read( + obj, + (enum al_serdes_reg_page)lane, AL_SRDS_REG_TYPE_PMA, SERDES_IREG_TX_DRV_2_REG_NUM); *c_plus_1 = ((reg & SERDES_IREG_TX_DRV_2_LEVNM1_MASK) >> SERDES_IREG_TX_DRV_2_LEVNM1_SHIFT); - reg = al_serdes_grp_lane_read( - &obj->grp_info[grp], - lane, + reg = al_serdes_grp_reg_read( + obj, + (enum al_serdes_reg_page)lane, AL_SRDS_REG_TYPE_PMA, SERDES_IREG_TX_DRV_3_REG_NUM); *c_minus_1 = ((reg & SERDES_IREG_TX_DRV_3_LEVNP1_MASK) >> SERDES_IREG_TX_DRV_3_LEVNP1_SHIFT); - reg = al_serdes_grp_lane_read( - &obj->grp_info[grp], - lane, + reg = al_serdes_grp_reg_read( + obj, + (enum al_serdes_reg_page)lane, AL_SRDS_REG_TYPE_PMA, SERDES_IREG_TX_DRV_1_REG_NUM); @@ -1541,18 +1375,17 @@ static void al_serdes_tx_deemph_get( SERDES_IREG_TX_DRV_1_LEVN_SHIFT) - *c_plus_1 - *c_minus_1); } -al_bool al_serdes_tx_deemph_inc( - struct al_serdes_obj *obj, - enum al_serdes_group grp, - enum al_serdes_lane lane, - enum al_serdes_tx_deemph_param param) +static al_bool al_serdes_tx_deemph_inc( + struct al_serdes_grp_obj *obj, + enum al_serdes_lane lane, + enum al_serdes_tx_deemph_param param) { al_bool ret = AL_TRUE; uint32_t c0; uint32_t c1; uint32_t c_1; - al_serdes_tx_deemph_get(obj, grp, lane, &c0, &c1, &c_1); + al_serdes_tx_deemph_get(obj, lane, &c0, &c1, &c_1); al_dbg("%s: current txdeemph: c0 = 0x%x c1 = 0x%x c-1 = 0x%x\n", __func__, c0, c1, c_1); @@ -1594,23 +1427,22 @@ al_bool al_serdes_tx_deemph_inc( al_dbg("%s: new txdeemph: c0 = 0x%x c1 = 0x%x c-1 = 0x%x\n", __func__, c0, c1, c_1); - al_serdes_tx_deemph_set(obj, grp, lane, c0, c1, c_1); + al_serdes_tx_deemph_set(obj, lane, c0, c1, c_1); return ret; } -al_bool al_serdes_tx_deemph_dec( - struct al_serdes_obj *obj, - enum al_serdes_group grp, - enum al_serdes_lane lane, - enum al_serdes_tx_deemph_param param) +static al_bool al_serdes_tx_deemph_dec( + struct al_serdes_grp_obj *obj, + enum al_serdes_lane lane, + enum al_serdes_tx_deemph_param param) { al_bool ret = AL_TRUE; uint32_t c0; uint32_t c1; uint32_t c_1; - al_serdes_tx_deemph_get(obj, grp, lane, &c0, &c1, &c_1); + al_serdes_tx_deemph_get(obj, lane, &c0, &c1, &c_1); al_dbg("%s: current txdeemph: c0 = 0x%x c1 = 0x%x c-1 = 0x%x\n", __func__, c0, c1, c_1); @@ -1645,15 +1477,14 @@ al_bool al_serdes_tx_deemph_dec( al_dbg("%s: new txdeemph: c0 = 0x%x c1 = 0x%x c-1 = 0x%x\n", __func__, c0, c1, c_1); - al_serdes_tx_deemph_set(obj, grp, lane, c0, c1, c_1); + al_serdes_tx_deemph_set(obj, lane, c0, c1, c_1); return ret; } -void al_serdes_tx_deemph_preset( - struct al_serdes_obj *obj, - enum al_serdes_group grp, - enum al_serdes_lane lane) +static void al_serdes_tx_deemph_preset( + struct al_serdes_grp_obj *obj, + enum al_serdes_lane lane) { uint32_t c0; uint32_t c1; @@ -1668,35 +1499,34 @@ void al_serdes_tx_deemph_preset( al_dbg("preset: new txdeemph: c0 = 0x%x c1 = 0x%x c-1 = 0x%x\n", c0, c1, c_1); - al_serdes_tx_deemph_set(obj, grp, lane, c0, c1, c_1); + al_serdes_tx_deemph_set(obj, lane, c0, c1, c_1); } -al_bool al_serdes_signal_is_detected( - struct al_serdes_obj *obj, - enum al_serdes_group grp, - enum al_serdes_lane lane) +static al_bool al_serdes_signal_is_detected( + struct al_serdes_grp_obj *obj, + enum al_serdes_lane lane) { uint32_t reg = 0; - reg = al_serdes_grp_lane_read( - &obj->grp_info[grp], - lane, + reg = al_serdes_grp_reg_read( + obj, + (enum al_serdes_reg_page)lane, AL_SRDS_REG_TYPE_PMA, SERDES_IREG_FLD_RXRANDET_REG_NUM); return ((reg & SERDES_IREG_FLD_RXRANDET_STAT) ? AL_TRUE : AL_FALSE); } -void al_serdes_tx_advanced_params_set(struct al_serdes_obj *obj, - enum al_serdes_group grp, +static void al_serdes_tx_advanced_params_set(struct al_serdes_grp_obj *obj, enum al_serdes_lane lane, - struct al_serdes_adv_tx_params *params) + void *tx_params) { uint8_t reg = 0; + struct al_serdes_adv_tx_params *params = tx_params; - if(!params->override) { - al_serdes_grp_lane_masked_write(&obj->grp_info[grp], - lane, + if (!params->override) { + al_serdes_grp_reg_masked_write(obj, + (enum al_serdes_reg_page)lane, AL_SRDS_REG_TYPE_PMA, SERDES_IREG_FLD_TX_DRV_OVERRIDE_EN_REG_NUM, SERDES_IREG_FLD_TX_DRV_OVERRIDE_EN, @@ -1705,8 +1535,8 @@ void al_serdes_tx_advanced_params_set(struct al_serdes_obj *obj, return; } - al_serdes_grp_lane_masked_write(&obj->grp_info[grp], - lane, + al_serdes_grp_reg_masked_write(obj, + (enum al_serdes_reg_page)lane, AL_SRDS_REG_TYPE_PMA, SERDES_IREG_FLD_TX_DRV_OVERRIDE_EN_REG_NUM, SERDES_IREG_FLD_TX_DRV_OVERRIDE_EN, @@ -1722,8 +1552,8 @@ void al_serdes_tx_advanced_params_set(struct al_serdes_obj *obj, SERDES_IREG_TX_DRV_1_LEVN_SHIFT, params->total_driver_units); - al_serdes_grp_lane_write(&obj->grp_info[grp], - lane, + al_serdes_grp_reg_write(obj, + (enum al_serdes_reg_page)lane, AL_SRDS_REG_TYPE_PMA, SERDES_IREG_TX_DRV_1_REG_NUM, reg); @@ -1739,8 +1569,8 @@ void al_serdes_tx_advanced_params_set(struct al_serdes_obj *obj, SERDES_IREG_TX_DRV_2_LEVNM2_SHIFT, params->c_plus_2); - al_serdes_grp_lane_write(&obj->grp_info[grp], - lane, + al_serdes_grp_reg_write(obj, + (enum al_serdes_reg_page)lane, AL_SRDS_REG_TYPE_PMA, SERDES_IREG_TX_DRV_2_REG_NUM, reg); @@ -1756,63 +1586,67 @@ void al_serdes_tx_advanced_params_set(struct al_serdes_obj *obj, SERDES_IREG_TX_DRV_3_SLEW_SHIFT, params->slew_rate); - al_serdes_grp_lane_write(&obj->grp_info[grp], - lane, + al_serdes_grp_reg_write(obj, + (enum al_serdes_reg_page)lane, AL_SRDS_REG_TYPE_PMA, SERDES_IREG_TX_DRV_3_REG_NUM, reg); } -void al_serdes_tx_advanced_params_get(struct al_serdes_obj *obj, - enum al_serdes_group grp, +static void al_serdes_tx_advanced_params_get(struct al_serdes_grp_obj *obj, enum al_serdes_lane lane, - struct al_serdes_adv_tx_params *tx_params) + void *tx_params) { + struct al_serdes_adv_tx_params *params = tx_params; uint8_t reg_val = 0; - al_serdes_lane_read(obj, grp, lane, AL_SRDS_REG_TYPE_PMA, + al_serdes_reg_read(obj, (enum al_serdes_reg_page)lane, + AL_SRDS_REG_TYPE_PMA, SERDES_IREG_TX_DRV_1_REG_NUM, ®_val); - tx_params->amp = (reg_val & SERDES_IREG_TX_DRV_1_HLEV_MASK) >> + params->amp = (reg_val & SERDES_IREG_TX_DRV_1_HLEV_MASK) >> SERDES_IREG_TX_DRV_1_HLEV_SHIFT; - tx_params->total_driver_units = (reg_val & + params->total_driver_units = (reg_val & SERDES_IREG_TX_DRV_1_LEVN_MASK) >> SERDES_IREG_TX_DRV_1_LEVN_SHIFT; - al_serdes_lane_read(obj, grp, lane, AL_SRDS_REG_TYPE_PMA, + al_serdes_reg_read(obj, (enum al_serdes_reg_page)lane, + AL_SRDS_REG_TYPE_PMA, SERDES_IREG_TX_DRV_2_REG_NUM, ®_val); - tx_params->c_plus_1 = (reg_val & SERDES_IREG_TX_DRV_2_LEVNM1_MASK) >> + params->c_plus_1 = (reg_val & SERDES_IREG_TX_DRV_2_LEVNM1_MASK) >> SERDES_IREG_TX_DRV_2_LEVNM1_SHIFT; - tx_params->c_plus_2 = (reg_val & SERDES_IREG_TX_DRV_2_LEVNM2_MASK) >> + params->c_plus_2 = (reg_val & SERDES_IREG_TX_DRV_2_LEVNM2_MASK) >> SERDES_IREG_TX_DRV_2_LEVNM2_SHIFT; - al_serdes_lane_read(obj, grp, lane, AL_SRDS_REG_TYPE_PMA, + al_serdes_reg_read(obj, (enum al_serdes_reg_page)lane, + AL_SRDS_REG_TYPE_PMA, SERDES_IREG_TX_DRV_3_REG_NUM, ®_val); - tx_params->c_minus_1 = (reg_val & SERDES_IREG_TX_DRV_3_LEVNP1_MASK) >> + params->c_minus_1 = (reg_val & SERDES_IREG_TX_DRV_3_LEVNP1_MASK) >> SERDES_IREG_TX_DRV_3_LEVNP1_SHIFT; - tx_params->slew_rate = (reg_val & SERDES_IREG_TX_DRV_3_SLEW_MASK) >> + params->slew_rate = (reg_val & SERDES_IREG_TX_DRV_3_SLEW_MASK) >> SERDES_IREG_TX_DRV_3_SLEW_SHIFT; - al_serdes_lane_read(obj, grp, lane, AL_SRDS_REG_TYPE_PMA, + al_serdes_reg_read(obj, (enum al_serdes_reg_page)lane, + AL_SRDS_REG_TYPE_PMA, SERDES_IREG_FLD_TX_DRV_OVERRIDE_EN_REG_NUM, ®_val); - tx_params->override = ((reg_val & SERDES_IREG_FLD_TX_DRV_OVERRIDE_EN) == 0); + params->override = ((reg_val & SERDES_IREG_FLD_TX_DRV_OVERRIDE_EN) == 0); } -void al_serdes_rx_advanced_params_set(struct al_serdes_obj *obj, - enum al_serdes_group grp, - enum al_serdes_lane lane, - struct al_serdes_adv_rx_params *params) +static void al_serdes_rx_advanced_params_set(struct al_serdes_grp_obj *obj, + enum al_serdes_lane lane, + void *rx_params) { + struct al_serdes_adv_rx_params *params = rx_params; uint8_t reg = 0; - if(!params->override) { - al_serdes_grp_lane_masked_write(&obj->grp_info[grp], - lane, + if (!params->override) { + al_serdes_grp_reg_masked_write(obj, + (enum al_serdes_reg_page)lane, AL_SRDS_REG_TYPE_PMA, SERDES_IREG_FLD_RX_DRV_OVERRIDE_EN_REG_NUM, SERDES_IREG_FLD_RX_DRV_OVERRIDE_EN, @@ -1821,8 +1655,8 @@ void al_serdes_rx_advanced_params_set(struct al_serdes_obj *obj, return; } - al_serdes_grp_lane_masked_write(&obj->grp_info[grp], - lane, + al_serdes_grp_reg_masked_write(obj, + (enum al_serdes_reg_page)lane, AL_SRDS_REG_TYPE_PMA, SERDES_IREG_FLD_RX_DRV_OVERRIDE_EN_REG_NUM, SERDES_IREG_FLD_RX_DRV_OVERRIDE_EN, @@ -1838,8 +1672,8 @@ void al_serdes_rx_advanced_params_set(struct al_serdes_obj *obj, SERDES_IREG_RX_CALEQ_1_DFEPSTAP3DB_SHIFT, params->dfe_3db_freq); - al_serdes_grp_lane_write(&obj->grp_info[grp], - lane, + al_serdes_grp_reg_write(obj, + (enum al_serdes_reg_page)lane, AL_SRDS_REG_TYPE_PMA, SERDES_IREG_RX_CALEQ_1_REG_NUM, reg); @@ -1855,8 +1689,8 @@ void al_serdes_rx_advanced_params_set(struct al_serdes_obj *obj, SERDES_IREG_RX_CALEQ_2_DFETAP1GAIN_SHIFT, params->dfe_first_tap_ctrl); - al_serdes_grp_lane_write(&obj->grp_info[grp], - lane, + al_serdes_grp_reg_write(obj, + (enum al_serdes_reg_page)lane, AL_SRDS_REG_TYPE_PMA, SERDES_IREG_RX_CALEQ_2_REG_NUM, reg); @@ -1872,8 +1706,8 @@ void al_serdes_rx_advanced_params_set(struct al_serdes_obj *obj, SERDES_IREG_RX_CALEQ_3_DFETAP3GAIN_SHIFT, params->dfe_third_tap_ctrl); - al_serdes_grp_lane_write(&obj->grp_info[grp], - lane, + al_serdes_grp_reg_write(obj, + (enum al_serdes_reg_page)lane, AL_SRDS_REG_TYPE_PMA, SERDES_IREG_RX_CALEQ_3_REG_NUM, reg); @@ -1889,8 +1723,8 @@ void al_serdes_rx_advanced_params_set(struct al_serdes_obj *obj, SERDES_IREG_RX_CALEQ_4_LOFREQAGCGAIN_SHIFT, params->low_freq_agc_gain); - al_serdes_grp_lane_write(&obj->grp_info[grp], - lane, + al_serdes_grp_reg_write(obj, + (enum al_serdes_reg_page)lane, AL_SRDS_REG_TYPE_PMA, SERDES_IREG_RX_CALEQ_4_REG_NUM, reg); @@ -1906,17 +1740,17 @@ void al_serdes_rx_advanced_params_set(struct al_serdes_obj *obj, SERDES_IREG_RX_CALEQ_5_HIFREQAGCCAP_SHIFT, params->high_freq_agc_boost); - al_serdes_grp_lane_write(&obj->grp_info[grp], - lane, + al_serdes_grp_reg_write(obj, + (enum al_serdes_reg_page)lane, AL_SRDS_REG_TYPE_PMA, SERDES_IREG_RX_CALEQ_5_REG_NUM, reg); } -static inline void al_serdes_common_cfg_eth(struct al_serdes_group_info *grp_info) +static inline void al_serdes_common_cfg_eth(struct al_serdes_grp_obj *obj) { al_serdes_grp_reg_masked_write( - grp_info, + obj, AL_SRDS_REG_PAGE_4_COMMON, AL_SRDS_REG_TYPE_PMA, SERDES_IREG_FLD_RXEQ_LOOKUP_CODE_EN_REG_NUM, @@ -1924,7 +1758,7 @@ static inline void al_serdes_common_cfg_eth(struct al_serdes_group_info *grp_inf (0x1 << SERDES_IREG_FLD_RXEQ_LOOKUP_CODE_EN_SHIFT)); al_serdes_grp_reg_masked_write( - grp_info, + obj, AL_SRDS_REG_PAGE_4_COMMON, AL_SRDS_REG_TYPE_PMA, SERDES_IREG_FLD_RXEQ_LOOKUP_LASTCODE_REG_NUM, @@ -1932,7 +1766,7 @@ static inline void al_serdes_common_cfg_eth(struct al_serdes_group_info *grp_inf (0 << SERDES_IREG_FLD_RXEQ_LOOKUP_LASTCODE_SHIFT)); al_serdes_grp_reg_masked_write( - grp_info, + obj, AL_SRDS_REG_PAGE_4_COMMON, AL_SRDS_REG_TYPE_PMA, SERDES_IREG_FLD_RXEQ_COARSE_RUN1_MASK_REG_NUM, @@ -1940,7 +1774,7 @@ static inline void al_serdes_common_cfg_eth(struct al_serdes_group_info *grp_inf (0x2 << SERDES_IREG_FLD_RXEQ_COARSE_RUN1_MASK_SHIFT)); al_serdes_grp_reg_masked_write( - grp_info, + obj, AL_SRDS_REG_PAGE_4_COMMON, AL_SRDS_REG_TYPE_PMA, SERDES_IREG_FLD_RXEQ_COARSE_RUN2_MASK_REG_NUM, @@ -1948,7 +1782,7 @@ static inline void al_serdes_common_cfg_eth(struct al_serdes_group_info *grp_inf (0 << SERDES_IREG_FLD_RXEQ_COARSE_RUN2_MASK_SHIFT)); al_serdes_grp_reg_masked_write( - grp_info, + obj, AL_SRDS_REG_PAGE_4_COMMON, AL_SRDS_REG_TYPE_PMA, SERDES_IREG_FLD_RXEQ_COARSE_STEP_REG_NUM, @@ -1956,7 +1790,7 @@ static inline void al_serdes_common_cfg_eth(struct al_serdes_group_info *grp_inf (0x1 << SERDES_IREG_FLD_RXEQ_COARSE_STEP_SHIFT)); al_serdes_grp_reg_masked_write( - grp_info, + obj, AL_SRDS_REG_PAGE_4_COMMON, AL_SRDS_REG_TYPE_PMA, SERDES_IREG_FLD_RXEQ_COARSE_ITER_NUM_REG_NUM, @@ -1964,7 +1798,7 @@ static inline void al_serdes_common_cfg_eth(struct al_serdes_group_info *grp_inf (0x1 << SERDES_IREG_FLD_RXEQ_COARSE_ITER_NUM_SHIFT)); al_serdes_grp_reg_masked_write( - grp_info, + obj, AL_SRDS_REG_PAGE_4_COMMON, AL_SRDS_REG_TYPE_PMA, SERDES_IREG_FLD_RXEQ_FINE_RUN1_MASK_REG_NUM, @@ -1972,7 +1806,7 @@ static inline void al_serdes_common_cfg_eth(struct al_serdes_group_info *grp_inf (0xf0 << SERDES_IREG_FLD_RXEQ_FINE_RUN1_MASK_SHIFT)); al_serdes_grp_reg_masked_write( - grp_info, + obj, AL_SRDS_REG_PAGE_4_COMMON, AL_SRDS_REG_TYPE_PMA, SERDES_IREG_FLD_RXEQ_FINE_RUN2_MASK_REG_NUM, @@ -1980,7 +1814,7 @@ static inline void al_serdes_common_cfg_eth(struct al_serdes_group_info *grp_inf (0 << SERDES_IREG_FLD_RXEQ_FINE_RUN2_MASK_SHIFT)); al_serdes_grp_reg_masked_write( - grp_info, + obj, AL_SRDS_REG_PAGE_4_COMMON, AL_SRDS_REG_TYPE_PMA, SERDES_IREG_FLD_RXEQ_FINE_STEP_REG_NUM, @@ -1988,7 +1822,7 @@ static inline void al_serdes_common_cfg_eth(struct al_serdes_group_info *grp_inf (1 << SERDES_IREG_FLD_RXEQ_FINE_STEP_SHIFT)); al_serdes_grp_reg_masked_write( - grp_info, + obj, AL_SRDS_REG_PAGE_4_COMMON, AL_SRDS_REG_TYPE_PMA, SERDES_IREG_FLD_RXEQ_FINE_ITER_NUM_REG_NUM, @@ -1996,7 +1830,7 @@ static inline void al_serdes_common_cfg_eth(struct al_serdes_group_info *grp_inf (0x8 << SERDES_IREG_FLD_RXEQ_FINE_ITER_NUM_SHIFT)); al_serdes_grp_reg_masked_write( - grp_info, + obj, AL_SRDS_REG_PAGE_4_COMMON, AL_SRDS_REG_TYPE_PMA, SERDES_IREG_FLD_RXCALEYEDIAGFSM_BERTHRESHOLD1_REG_NUM, @@ -2004,7 +1838,7 @@ static inline void al_serdes_common_cfg_eth(struct al_serdes_group_info *grp_inf (0 << SERDES_IREG_FLD_RXCALEYEDIAGFSM_BERTHRESHOLD1_SHIFT)); al_serdes_grp_reg_masked_write( - grp_info, + obj, AL_SRDS_REG_PAGE_4_COMMON, AL_SRDS_REG_TYPE_PMA, SERDES_IREG_FLD_RXCALEYEDIAGFSM_BERTHRESHOLD2_REG_NUM, @@ -2012,7 +1846,7 @@ static inline void al_serdes_common_cfg_eth(struct al_serdes_group_info *grp_inf (0x64 << SERDES_IREG_FLD_RXCALEYEDIAGFSM_BERTHRESHOLD2_SHIFT)); al_serdes_grp_reg_masked_write( - grp_info, + obj, AL_SRDS_REG_PAGE_4_COMMON, AL_SRDS_REG_TYPE_PMA, SERDES_IREG_FLD_RXCALEYEDIAGFSM_XVALCOARSE_REG_NUM, @@ -2020,7 +1854,7 @@ static inline void al_serdes_common_cfg_eth(struct al_serdes_group_info *grp_inf (0x3 << SERDES_IREG_FLD_RXCALEYEDIAGFSM_XVALCOARSE_SHIFT)); al_serdes_grp_reg_masked_write( - grp_info, + obj, AL_SRDS_REG_PAGE_4_COMMON, AL_SRDS_REG_TYPE_PMA, SERDES_IREG_FLD_RXCALEYEDIAGFSM_XVALFINE_REG_NUM, @@ -2028,7 +1862,7 @@ static inline void al_serdes_common_cfg_eth(struct al_serdes_group_info *grp_inf (0x1 << SERDES_IREG_FLD_RXCALEYEDIAGFSM_XVALFINE_SHIFT)); al_serdes_grp_reg_masked_write( - grp_info, + obj, AL_SRDS_REG_PAGE_4_COMMON, AL_SRDS_REG_TYPE_PMA, SERDES_IREG_FLD_RXCALEYEDIAGFSM_YVALCOARSE_REG_NUM, @@ -2036,7 +1870,7 @@ static inline void al_serdes_common_cfg_eth(struct al_serdes_group_info *grp_inf (3 << SERDES_IREG_FLD_RXCALEYEDIAGFSM_YVALCOARSE_SHIFT)); al_serdes_grp_reg_masked_write( - grp_info, + obj, AL_SRDS_REG_PAGE_4_COMMON, AL_SRDS_REG_TYPE_PMA, SERDES_IREG_FLD_RXCALEYEDIAGFSM_YVALFINE_REG_NUM, @@ -2044,7 +1878,7 @@ static inline void al_serdes_common_cfg_eth(struct al_serdes_group_info *grp_inf (1 << SERDES_IREG_FLD_RXCALEYEDIAGFSM_YVALFINE_SHIFT)); al_serdes_grp_reg_masked_write( - grp_info, + obj, AL_SRDS_REG_PAGE_4_COMMON, AL_SRDS_REG_TYPE_PMA, SERDES_IREG_FLD_EYE_DIAG_SAMPLE_CNT_MSB_REG_NUM, @@ -2052,7 +1886,7 @@ static inline void al_serdes_common_cfg_eth(struct al_serdes_group_info *grp_inf (0xc << SERDES_IREG_FLD_EYE_DIAG_SAMPLE_CNT_MSB_SHIFT)); al_serdes_grp_reg_masked_write( - grp_info, + obj, AL_SRDS_REG_PAGE_4_COMMON, AL_SRDS_REG_TYPE_PMA, SERDES_IREG_FLD_EYE_DIAG_SAMPLE_CNT_LSB_REG_NUM, @@ -2068,23 +1902,25 @@ struct al_serdes_mode_rx_tx_inv_state { }; static void al_serdes_mode_rx_tx_inv_state_save( - struct al_serdes_group_info *grp_info, + struct al_serdes_grp_obj *obj, struct al_serdes_mode_rx_tx_inv_state *state) { - if (al_reg_read32(&grp_info->regs_base->gen.irst) & SERDES_GEN_IRST_POR_B_A) { + struct al_serdes_regs __iomem *regs_base = obj->regs_base; + + if (al_reg_read32(®s_base->gen.irst) & SERDES_GEN_IRST_POR_B_A) { int i; state->restore = AL_TRUE; - state->pipe_rst = al_reg_read32(&grp_info->regs_base->gen.irst); + state->pipe_rst = al_reg_read32(®s_base->gen.irst); for (i = 0; i < AL_SRDS_NUM_LANES; i++) { state->inv_value[i] = al_serdes_grp_reg_read( - grp_info, + obj, i, AL_SRDS_REG_TYPE_PMA, SERDES_IREG_FLD_POLARITY_RX_REG_NUM); state->ipd_multi[i] = - al_reg_read32(&grp_info->regs_base->lane[i].ipd_multi); + al_reg_read32(®s_base->lane[i].ipd_multi); } } else { state->restore = AL_FALSE; @@ -2092,23 +1928,25 @@ static void al_serdes_mode_rx_tx_inv_state_save( } static void al_serdes_mode_rx_tx_inv_state_restore( - struct al_serdes_group_info *grp_info, + struct al_serdes_grp_obj *obj, struct al_serdes_mode_rx_tx_inv_state *state) { + struct al_serdes_regs __iomem *regs_base = obj->regs_base; + if (state->restore) { int i; for (i = 0; i < AL_SRDS_NUM_LANES; i++) { al_serdes_grp_reg_write( - grp_info, + obj, i, AL_SRDS_REG_TYPE_PMA, SERDES_IREG_FLD_POLARITY_RX_REG_NUM, state->inv_value[i]); al_reg_write32( - &grp_info->regs_base->lane[i].ipd_multi, state->ipd_multi[i]); + ®s_base->lane[i].ipd_multi, state->ipd_multi[i]); al_reg_write32_masked( - &grp_info->regs_base->gen.irst, + ®s_base->gen.irst, (SERDES_GEN_IRST_PIPE_RST_L0_B_A_SEL >> i) | (SERDES_GEN_IRST_PIPE_RST_L0_B_A >> i), state->pipe_rst); @@ -2116,543 +1954,539 @@ static void al_serdes_mode_rx_tx_inv_state_restore( } } -void al_serdes_mode_set_sgmii( - struct al_serdes_obj *obj, - enum al_serdes_group grp) +static void al_serdes_mode_set_sgmii( + struct al_serdes_grp_obj *obj) { - struct al_serdes_group_info *grp_info; + struct al_serdes_grp_obj *grp_obj = obj; + struct al_serdes_regs __iomem *regs_base = grp_obj->regs_base; struct al_serdes_mode_rx_tx_inv_state rx_tx_inv_state; al_assert(obj); - al_assert(((int)grp) >= AL_SRDS_GRP_A); - al_assert(((int)grp) <= AL_SRDS_GRP_D); - grp_info = &obj->grp_info[grp]; + al_serdes_mode_rx_tx_inv_state_save(grp_obj, &rx_tx_inv_state); - al_serdes_mode_rx_tx_inv_state_save(grp_info, &rx_tx_inv_state); - - al_reg_write32(&grp_info->regs_base->gen.irst, 0x000000); - al_reg_write32(&grp_info->regs_base->lane[0].ictl_multi, 0x10110010); - al_reg_write32(&grp_info->regs_base->lane[1].ictl_multi, 0x10110010); - al_reg_write32(&grp_info->regs_base->lane[2].ictl_multi, 0x10110010); - al_reg_write32(&grp_info->regs_base->lane[3].ictl_multi, 0x10110010); - al_reg_write32(&grp_info->regs_base->gen.ipd_multi_synth , 0x0001); - al_reg_write32(&grp_info->regs_base->lane[0].ipd_multi, 0x0003); - al_reg_write32(&grp_info->regs_base->lane[1].ipd_multi, 0x0003); - al_reg_write32(&grp_info->regs_base->lane[2].ipd_multi, 0x0003); - al_reg_write32(&grp_info->regs_base->lane[3].ipd_multi, 0x0003); - al_reg_write32(&grp_info->regs_base->gen.ictl_pcs , 0); - al_reg_write32(&grp_info->regs_base->gen.irst, 0x001000); + al_reg_write32(®s_base->gen.irst, 0x000000); + al_reg_write32(®s_base->lane[0].ictl_multi, 0x10110010); + al_reg_write32(®s_base->lane[1].ictl_multi, 0x10110010); + al_reg_write32(®s_base->lane[2].ictl_multi, 0x10110010); + al_reg_write32(®s_base->lane[3].ictl_multi, 0x10110010); + al_reg_write32(®s_base->gen.ipd_multi_synth , 0x0001); + al_reg_write32(®s_base->lane[0].ipd_multi, 0x0003); + al_reg_write32(®s_base->lane[1].ipd_multi, 0x0003); + al_reg_write32(®s_base->lane[2].ipd_multi, 0x0003); + al_reg_write32(®s_base->lane[3].ipd_multi, 0x0003); + al_reg_write32(®s_base->gen.ictl_pcs , 0); + al_reg_write32(®s_base->gen.irst, 0x001000); al_serdes_ns_delay(800); - al_reg_write32(&grp_info->regs_base->gen.irst, 0x000000); + al_reg_write32(®s_base->gen.irst, 0x000000); al_serdes_ns_delay(500); - al_reg_write32(&grp_info->regs_base->gen.irst, 0x001000); + al_reg_write32(®s_base->gen.irst, 0x001000); al_serdes_ns_delay(500); - al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_0123_LANES_0123, + al_serdes_grp_reg_write(obj, AL_SRDS_REG_PAGE_0123_LANES_0123, AL_SRDS_REG_TYPE_PMA, 101, 183); - al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_0123_LANES_0123, + al_serdes_grp_reg_write(obj, AL_SRDS_REG_PAGE_0123_LANES_0123, AL_SRDS_REG_TYPE_PMA, 102, 183); - al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_0123_LANES_0123, + al_serdes_grp_reg_write(obj, AL_SRDS_REG_PAGE_0123_LANES_0123, AL_SRDS_REG_TYPE_PMA, 103, 12); - al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_0123_LANES_0123, + al_serdes_grp_reg_write(obj, AL_SRDS_REG_PAGE_0123_LANES_0123, AL_SRDS_REG_TYPE_PMA, 104, 12); - al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_0123_LANES_0123, + al_serdes_grp_reg_write(obj, AL_SRDS_REG_PAGE_0123_LANES_0123, AL_SRDS_REG_TYPE_PMA, 105, 26); - al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_0123_LANES_0123, + al_serdes_grp_reg_write(obj, AL_SRDS_REG_PAGE_0123_LANES_0123, AL_SRDS_REG_TYPE_PMA, 106, 26); - al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_0123_LANES_0123, + al_serdes_grp_reg_write(obj, AL_SRDS_REG_PAGE_0123_LANES_0123, AL_SRDS_REG_TYPE_PMA, 107, 2); - al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_0123_LANES_0123, + al_serdes_grp_reg_write(obj, AL_SRDS_REG_PAGE_0123_LANES_0123, AL_SRDS_REG_TYPE_PMA, 108, 2); - al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_0123_LANES_0123, + al_serdes_grp_reg_write(obj, AL_SRDS_REG_PAGE_0123_LANES_0123, AL_SRDS_REG_TYPE_PMA, 109, 17); - al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_0123_LANES_0123, + al_serdes_grp_reg_write(obj, AL_SRDS_REG_PAGE_0123_LANES_0123, AL_SRDS_REG_TYPE_PMA, 110, 13); - al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON, + al_serdes_grp_reg_write(obj, AL_SRDS_REG_PAGE_4_COMMON, AL_SRDS_REG_TYPE_PMA, 101, 153); - al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON, + al_serdes_grp_reg_write(obj, AL_SRDS_REG_PAGE_4_COMMON, AL_SRDS_REG_TYPE_PMA, 102, 0); - al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON, + al_serdes_grp_reg_write(obj, AL_SRDS_REG_PAGE_4_COMMON, AL_SRDS_REG_TYPE_PMA, 103, 108); - al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON, + al_serdes_grp_reg_write(obj, AL_SRDS_REG_PAGE_4_COMMON, AL_SRDS_REG_TYPE_PMA, 104, 183); - al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON, + al_serdes_grp_reg_write(obj, AL_SRDS_REG_PAGE_4_COMMON, AL_SRDS_REG_TYPE_PMA, 105, 183); - al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON, + al_serdes_grp_reg_write(obj, AL_SRDS_REG_PAGE_4_COMMON, AL_SRDS_REG_TYPE_PMA, 106, 12); - al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON, + al_serdes_grp_reg_write(obj, AL_SRDS_REG_PAGE_4_COMMON, AL_SRDS_REG_TYPE_PMA, 107, 12); - al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON, + al_serdes_grp_reg_write(obj, AL_SRDS_REG_PAGE_4_COMMON, AL_SRDS_REG_TYPE_PMA, 108, 26); - al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON, + al_serdes_grp_reg_write(obj, AL_SRDS_REG_PAGE_4_COMMON, AL_SRDS_REG_TYPE_PMA, 109, 26); - al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON, + al_serdes_grp_reg_write(obj, AL_SRDS_REG_PAGE_4_COMMON, AL_SRDS_REG_TYPE_PMA, 110, 7); - al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON, + al_serdes_grp_reg_write(obj, AL_SRDS_REG_PAGE_4_COMMON, AL_SRDS_REG_TYPE_PMA, 111, 12); - al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON, + al_serdes_grp_reg_write(obj, AL_SRDS_REG_PAGE_4_COMMON, AL_SRDS_REG_TYPE_PMA, 112, 8); - al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON, + al_serdes_grp_reg_write(obj, AL_SRDS_REG_PAGE_4_COMMON, AL_SRDS_REG_TYPE_PMA, 113, 0); - al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON, + al_serdes_grp_reg_write(obj, AL_SRDS_REG_PAGE_4_COMMON, AL_SRDS_REG_TYPE_PMA, 114, 8); - al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON, + al_serdes_grp_reg_write(obj, AL_SRDS_REG_PAGE_4_COMMON, AL_SRDS_REG_TYPE_PMA, 115, 0); - al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON, + al_serdes_grp_reg_write(obj, AL_SRDS_REG_PAGE_4_COMMON, AL_SRDS_REG_TYPE_PMA, 116, 255); - al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON, + al_serdes_grp_reg_write(obj, AL_SRDS_REG_PAGE_4_COMMON, AL_SRDS_REG_TYPE_PMA, 117, 179); - al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON, + al_serdes_grp_reg_write(obj, AL_SRDS_REG_PAGE_4_COMMON, AL_SRDS_REG_TYPE_PMA, 118, 246); - al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON, + al_serdes_grp_reg_write(obj, AL_SRDS_REG_PAGE_4_COMMON, AL_SRDS_REG_TYPE_PMA, 119, 208); - al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON, + al_serdes_grp_reg_write(obj, AL_SRDS_REG_PAGE_4_COMMON, AL_SRDS_REG_TYPE_PMA, 120, 239); - al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON, + al_serdes_grp_reg_write(obj, AL_SRDS_REG_PAGE_4_COMMON, AL_SRDS_REG_TYPE_PMA, 121, 251); - al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON, + al_serdes_grp_reg_write(obj, AL_SRDS_REG_PAGE_4_COMMON, AL_SRDS_REG_TYPE_PMA, 122, 255); - al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON, + al_serdes_grp_reg_write(obj, AL_SRDS_REG_PAGE_4_COMMON, AL_SRDS_REG_TYPE_PMA, 123, 255); - al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON, + al_serdes_grp_reg_write(obj, AL_SRDS_REG_PAGE_4_COMMON, AL_SRDS_REG_TYPE_PMA, 124, 255); - al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON, + al_serdes_grp_reg_write(obj, AL_SRDS_REG_PAGE_4_COMMON, AL_SRDS_REG_TYPE_PMA, 125, 255); - al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON, + al_serdes_grp_reg_write(obj, AL_SRDS_REG_PAGE_4_COMMON, AL_SRDS_REG_TYPE_PMA, 126, 255); - al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON, + al_serdes_grp_reg_write(obj, AL_SRDS_REG_PAGE_4_COMMON, AL_SRDS_REG_TYPE_PMA, 127, 211); - al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON, + al_serdes_grp_reg_write(obj, AL_SRDS_REG_PAGE_4_COMMON, AL_SRDS_REG_TYPE_PMA, 128, 211); - al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON, + al_serdes_grp_reg_write(obj, AL_SRDS_REG_PAGE_4_COMMON, AL_SRDS_REG_TYPE_PMA, 129, 226); - al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON, + al_serdes_grp_reg_write(obj, AL_SRDS_REG_PAGE_4_COMMON, AL_SRDS_REG_TYPE_PMA, 130, 239); - al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON, + al_serdes_grp_reg_write(obj, AL_SRDS_REG_PAGE_4_COMMON, AL_SRDS_REG_TYPE_PMA, 131, 251); - al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON, + al_serdes_grp_reg_write(obj, AL_SRDS_REG_PAGE_4_COMMON, AL_SRDS_REG_TYPE_PMA, 132, 251); - al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON, + al_serdes_grp_reg_write(obj, AL_SRDS_REG_PAGE_4_COMMON, AL_SRDS_REG_TYPE_PMA, 133, 255); - al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON, + al_serdes_grp_reg_write(obj, AL_SRDS_REG_PAGE_4_COMMON, AL_SRDS_REG_TYPE_PMA, 134, 239); - al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON, + al_serdes_grp_reg_write(obj, AL_SRDS_REG_PAGE_4_COMMON, AL_SRDS_REG_TYPE_PMA, 135, 255); - al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON, + al_serdes_grp_reg_write(obj, AL_SRDS_REG_PAGE_4_COMMON, AL_SRDS_REG_TYPE_PMA, 136, 255); - al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON, + al_serdes_grp_reg_write(obj, AL_SRDS_REG_PAGE_4_COMMON, AL_SRDS_REG_TYPE_PMA, 137, 211); - al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON, + al_serdes_grp_reg_write(obj, AL_SRDS_REG_PAGE_4_COMMON, AL_SRDS_REG_TYPE_PMA, 138, 211); - al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON, + al_serdes_grp_reg_write(obj, AL_SRDS_REG_PAGE_4_COMMON, AL_SRDS_REG_TYPE_PMA, 139, 226); - al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON, + al_serdes_grp_reg_write(obj, AL_SRDS_REG_PAGE_4_COMMON, AL_SRDS_REG_TYPE_PMA, 140, 239); - al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON, + al_serdes_grp_reg_write(obj, AL_SRDS_REG_PAGE_4_COMMON, AL_SRDS_REG_TYPE_PMA, 141, 251); - al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON, + al_serdes_grp_reg_write(obj, AL_SRDS_REG_PAGE_4_COMMON, AL_SRDS_REG_TYPE_PMA, 142, 251); - al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON, + al_serdes_grp_reg_write(obj, AL_SRDS_REG_PAGE_4_COMMON, AL_SRDS_REG_TYPE_PMA, 143, 255); - al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON, + al_serdes_grp_reg_write(obj, AL_SRDS_REG_PAGE_4_COMMON, AL_SRDS_REG_TYPE_PMA, 144, 239); - al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON, + al_serdes_grp_reg_write(obj, AL_SRDS_REG_PAGE_4_COMMON, AL_SRDS_REG_TYPE_PMA, 145, 255); - al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON, + al_serdes_grp_reg_write(obj, AL_SRDS_REG_PAGE_4_COMMON, AL_SRDS_REG_TYPE_PMA, 146, 255); - al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON, + al_serdes_grp_reg_write(obj, AL_SRDS_REG_PAGE_4_COMMON, AL_SRDS_REG_TYPE_PMA, 147, 251); - al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON, + al_serdes_grp_reg_write(obj, AL_SRDS_REG_PAGE_4_COMMON, AL_SRDS_REG_TYPE_PMA, 148, 255); - al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON, + al_serdes_grp_reg_write(obj, AL_SRDS_REG_PAGE_4_COMMON, AL_SRDS_REG_TYPE_PMA, 149, 63); - al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON, + al_serdes_grp_reg_write(obj, AL_SRDS_REG_PAGE_4_COMMON, AL_SRDS_REG_TYPE_PMA, 150, 0); - al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON, + al_serdes_grp_reg_write(obj, AL_SRDS_REG_PAGE_4_COMMON, AL_SRDS_REG_TYPE_PMA, 151, 100); - al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON, + al_serdes_grp_reg_write(obj, AL_SRDS_REG_PAGE_4_COMMON, AL_SRDS_REG_TYPE_PMA, 152, 0); - al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON, + al_serdes_grp_reg_write(obj, AL_SRDS_REG_PAGE_4_COMMON, AL_SRDS_REG_TYPE_PMA, 153, 4); - al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON, + al_serdes_grp_reg_write(obj, AL_SRDS_REG_PAGE_4_COMMON, AL_SRDS_REG_TYPE_PMA, 154, 2); - al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON, + al_serdes_grp_reg_write(obj, AL_SRDS_REG_PAGE_4_COMMON, AL_SRDS_REG_TYPE_PMA, 155, 5); - al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON, + al_serdes_grp_reg_write(obj, AL_SRDS_REG_PAGE_4_COMMON, AL_SRDS_REG_TYPE_PMA, 156, 5); - al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON, + al_serdes_grp_reg_write(obj, AL_SRDS_REG_PAGE_4_COMMON, AL_SRDS_REG_TYPE_PMA, 157, 4); - al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON, + al_serdes_grp_reg_write(obj, AL_SRDS_REG_PAGE_4_COMMON, AL_SRDS_REG_TYPE_PMA, 158, 0); - al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON, + al_serdes_grp_reg_write(obj, AL_SRDS_REG_PAGE_4_COMMON, AL_SRDS_REG_TYPE_PMA, 159, 0); - al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON, + al_serdes_grp_reg_write(obj, AL_SRDS_REG_PAGE_4_COMMON, AL_SRDS_REG_TYPE_PMA, 160, 8); - al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON, + al_serdes_grp_reg_write(obj, AL_SRDS_REG_PAGE_4_COMMON, AL_SRDS_REG_TYPE_PMA, 161, 4); - al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON, + al_serdes_grp_reg_write(obj, AL_SRDS_REG_PAGE_4_COMMON, AL_SRDS_REG_TYPE_PMA, 162, 0); - al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON, + al_serdes_grp_reg_write(obj, AL_SRDS_REG_PAGE_4_COMMON, AL_SRDS_REG_TYPE_PMA, 163, 0); - al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON, + al_serdes_grp_reg_write(obj, AL_SRDS_REG_PAGE_4_COMMON, AL_SRDS_REG_TYPE_PMA, 164, 4); - al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_0_LANE_0, + al_serdes_grp_reg_write(obj, AL_SRDS_REG_PAGE_0_LANE_0, AL_SRDS_REG_TYPE_PMA, 7, 0); - al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_1_LANE_1, + al_serdes_grp_reg_write(obj, AL_SRDS_REG_PAGE_1_LANE_1, AL_SRDS_REG_TYPE_PMA, 7, 0); - al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_2_LANE_2, + al_serdes_grp_reg_write(obj, AL_SRDS_REG_PAGE_2_LANE_2, AL_SRDS_REG_TYPE_PMA, 7, 0); - al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_3_LANE_3, + al_serdes_grp_reg_write(obj, AL_SRDS_REG_PAGE_3_LANE_3, AL_SRDS_REG_TYPE_PMA, 7, 0); - al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON, + al_serdes_grp_reg_write(obj, AL_SRDS_REG_PAGE_4_COMMON, AL_SRDS_REG_TYPE_PMA, 13, 16); - al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON, + al_serdes_grp_reg_write(obj, AL_SRDS_REG_PAGE_4_COMMON, AL_SRDS_REG_TYPE_PMA, 48, 0); - al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON, + al_serdes_grp_reg_write(obj, AL_SRDS_REG_PAGE_4_COMMON, AL_SRDS_REG_TYPE_PMA, 49, 0); - al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON, + al_serdes_grp_reg_write(obj, AL_SRDS_REG_PAGE_4_COMMON, AL_SRDS_REG_TYPE_PMA, 54, 0); - al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON, + al_serdes_grp_reg_write(obj, AL_SRDS_REG_PAGE_4_COMMON, AL_SRDS_REG_TYPE_PMA, 55, 180); - al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON, + al_serdes_grp_reg_write(obj, AL_SRDS_REG_PAGE_4_COMMON, AL_SRDS_REG_TYPE_PMA, 93, 2); - al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON, + al_serdes_grp_reg_write(obj, AL_SRDS_REG_PAGE_4_COMMON, AL_SRDS_REG_TYPE_PMA, 165, 3); - al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_0123_LANES_0123, + al_serdes_grp_reg_write(obj, AL_SRDS_REG_PAGE_0123_LANES_0123, AL_SRDS_REG_TYPE_PMA, 41, 6); - al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON, + al_serdes_grp_reg_write(obj, AL_SRDS_REG_PAGE_4_COMMON, AL_SRDS_REG_TYPE_PMA, 354, 3); - al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON, + al_serdes_grp_reg_write(obj, AL_SRDS_REG_PAGE_4_COMMON, AL_SRDS_REG_TYPE_PMA, 355, 58); - al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON, + al_serdes_grp_reg_write(obj, AL_SRDS_REG_PAGE_4_COMMON, AL_SRDS_REG_TYPE_PMA, 356, 9); - al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON, + al_serdes_grp_reg_write(obj, AL_SRDS_REG_PAGE_4_COMMON, AL_SRDS_REG_TYPE_PMA, 357, 3); - al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON, + al_serdes_grp_reg_write(obj, AL_SRDS_REG_PAGE_4_COMMON, AL_SRDS_REG_TYPE_PMA, 358, 62); - al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON, + al_serdes_grp_reg_write(obj, AL_SRDS_REG_PAGE_4_COMMON, AL_SRDS_REG_TYPE_PMA, 359, 12); - al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_0123_LANES_0123, + al_serdes_grp_reg_write(obj, AL_SRDS_REG_PAGE_0123_LANES_0123, AL_SRDS_REG_TYPE_PMA, 701, 0); - al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_0123_LANES_0123, + al_serdes_grp_reg_write(obj, AL_SRDS_REG_PAGE_0123_LANES_0123, AL_SRDS_REG_TYPE_PMA, 87, 0x1f); - al_serdes_common_cfg_eth(grp_info); + al_serdes_common_cfg_eth(obj); - al_serdes_mode_rx_tx_inv_state_restore(grp_info, &rx_tx_inv_state); + al_serdes_mode_rx_tx_inv_state_restore(grp_obj, &rx_tx_inv_state); + al_reg_write32(®s_base->gen.irst, 0x0011F0); - al_reg_write32(&grp_info->regs_base->gen.irst, 0x0011F0); al_serdes_ns_delay(500); } -void al_serdes_mode_set_kr( - struct al_serdes_obj *obj, - enum al_serdes_group grp) +static void al_serdes_mode_set_kr( + struct al_serdes_grp_obj *obj) { - struct al_serdes_group_info *grp_info; + struct al_serdes_grp_obj *grp_obj = obj; + struct al_serdes_regs __iomem *regs_base = grp_obj->regs_base; struct al_serdes_mode_rx_tx_inv_state rx_tx_inv_state; al_assert(obj); - al_assert(((int)grp) >= AL_SRDS_GRP_A); - al_assert(((int)grp) <= AL_SRDS_GRP_D); + al_serdes_mode_rx_tx_inv_state_save(grp_obj, &rx_tx_inv_state); - grp_info = &obj->grp_info[grp]; - - al_serdes_mode_rx_tx_inv_state_save(grp_info, &rx_tx_inv_state); - - al_reg_write32(&grp_info->regs_base->gen.irst, 0x000000); - al_reg_write32(&grp_info->regs_base->lane[0].ictl_multi, 0x30330030); - al_reg_write32(&grp_info->regs_base->lane[1].ictl_multi, 0x30330030); - al_reg_write32(&grp_info->regs_base->lane[2].ictl_multi, 0x30330030); - al_reg_write32(&grp_info->regs_base->lane[3].ictl_multi, 0x30330030); - al_reg_write32(&grp_info->regs_base->gen.ipd_multi_synth , 0x0001); - al_reg_write32(&grp_info->regs_base->lane[0].ipd_multi, 0x0003); - al_reg_write32(&grp_info->regs_base->lane[1].ipd_multi, 0x0003); - al_reg_write32(&grp_info->regs_base->lane[2].ipd_multi, 0x0003); - al_reg_write32(&grp_info->regs_base->lane[3].ipd_multi, 0x0003); - al_reg_write32(&grp_info->regs_base->gen.ictl_pcs , 0); - al_reg_write32(&grp_info->regs_base->gen.irst, 0x001000); + al_reg_write32(®s_base->gen.irst, 0x000000); + al_reg_write32(®s_base->lane[0].ictl_multi, 0x30330030); + al_reg_write32(®s_base->lane[1].ictl_multi, 0x30330030); + al_reg_write32(®s_base->lane[2].ictl_multi, 0x30330030); + al_reg_write32(®s_base->lane[3].ictl_multi, 0x30330030); + al_reg_write32(®s_base->gen.ipd_multi_synth , 0x0001); + al_reg_write32(®s_base->lane[0].ipd_multi, 0x0003); + al_reg_write32(®s_base->lane[1].ipd_multi, 0x0003); + al_reg_write32(®s_base->lane[2].ipd_multi, 0x0003); + al_reg_write32(®s_base->lane[3].ipd_multi, 0x0003); + al_reg_write32(®s_base->gen.ictl_pcs , 0); + al_reg_write32(®s_base->gen.irst, 0x001000); al_serdes_ns_delay(800); - al_reg_write32(&grp_info->regs_base->gen.irst, 0x000000); + al_reg_write32(®s_base->gen.irst, 0x000000); al_serdes_ns_delay(500); - al_reg_write32(&grp_info->regs_base->gen.irst, 0x001000); + al_reg_write32(®s_base->gen.irst, 0x001000); al_serdes_ns_delay(500); - al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_0123_LANES_0123, + al_serdes_grp_reg_write(obj, AL_SRDS_REG_PAGE_0123_LANES_0123, AL_SRDS_REG_TYPE_PMA, 101, 189); - al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_0123_LANES_0123, + al_serdes_grp_reg_write(obj, AL_SRDS_REG_PAGE_0123_LANES_0123, AL_SRDS_REG_TYPE_PMA, 102, 189); - al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_0123_LANES_0123, + al_serdes_grp_reg_write(obj, AL_SRDS_REG_PAGE_0123_LANES_0123, AL_SRDS_REG_TYPE_PMA, 103, 6); - al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_0123_LANES_0123, + al_serdes_grp_reg_write(obj, AL_SRDS_REG_PAGE_0123_LANES_0123, AL_SRDS_REG_TYPE_PMA, 104, 6); - al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_0123_LANES_0123, + al_serdes_grp_reg_write(obj, AL_SRDS_REG_PAGE_0123_LANES_0123, AL_SRDS_REG_TYPE_PMA, 105, 27); - al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_0123_LANES_0123, + al_serdes_grp_reg_write(obj, AL_SRDS_REG_PAGE_0123_LANES_0123, AL_SRDS_REG_TYPE_PMA, 106, 27); - al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_0123_LANES_0123, + al_serdes_grp_reg_write(obj, AL_SRDS_REG_PAGE_0123_LANES_0123, AL_SRDS_REG_TYPE_PMA, 107, 1); - al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_0123_LANES_0123, + al_serdes_grp_reg_write(obj, AL_SRDS_REG_PAGE_0123_LANES_0123, AL_SRDS_REG_TYPE_PMA, 108, 1); - al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_0123_LANES_0123, + al_serdes_grp_reg_write(obj, AL_SRDS_REG_PAGE_0123_LANES_0123, AL_SRDS_REG_TYPE_PMA, 109, 119); - al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_0123_LANES_0123, + al_serdes_grp_reg_write(obj, AL_SRDS_REG_PAGE_0123_LANES_0123, AL_SRDS_REG_TYPE_PMA, 110, 5); - al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON, + al_serdes_grp_reg_write(obj, AL_SRDS_REG_PAGE_4_COMMON, AL_SRDS_REG_TYPE_PMA, 101, 170); - al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON, + al_serdes_grp_reg_write(obj, AL_SRDS_REG_PAGE_4_COMMON, AL_SRDS_REG_TYPE_PMA, 102, 0); - al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON, + al_serdes_grp_reg_write(obj, AL_SRDS_REG_PAGE_4_COMMON, AL_SRDS_REG_TYPE_PMA, 103, 108); - al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON, + al_serdes_grp_reg_write(obj, AL_SRDS_REG_PAGE_4_COMMON, AL_SRDS_REG_TYPE_PMA, 104, 189); - al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON, + al_serdes_grp_reg_write(obj, AL_SRDS_REG_PAGE_4_COMMON, AL_SRDS_REG_TYPE_PMA, 105, 189); - al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON, + al_serdes_grp_reg_write(obj, AL_SRDS_REG_PAGE_4_COMMON, AL_SRDS_REG_TYPE_PMA, 106, 6); - al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON, + al_serdes_grp_reg_write(obj, AL_SRDS_REG_PAGE_4_COMMON, AL_SRDS_REG_TYPE_PMA, 107, 6); - al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON, + al_serdes_grp_reg_write(obj, AL_SRDS_REG_PAGE_4_COMMON, AL_SRDS_REG_TYPE_PMA, 108, 27); - al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON, + al_serdes_grp_reg_write(obj, AL_SRDS_REG_PAGE_4_COMMON, AL_SRDS_REG_TYPE_PMA, 109, 27); - al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON, + al_serdes_grp_reg_write(obj, AL_SRDS_REG_PAGE_4_COMMON, AL_SRDS_REG_TYPE_PMA, 110, 7); - al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON, + al_serdes_grp_reg_write(obj, AL_SRDS_REG_PAGE_4_COMMON, AL_SRDS_REG_TYPE_PMA, 111, 12); - al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON, + al_serdes_grp_reg_write(obj, AL_SRDS_REG_PAGE_4_COMMON, AL_SRDS_REG_TYPE_PMA, 112, 16); - al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON, + al_serdes_grp_reg_write(obj, AL_SRDS_REG_PAGE_4_COMMON, AL_SRDS_REG_TYPE_PMA, 113, 0); - al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON, + al_serdes_grp_reg_write(obj, AL_SRDS_REG_PAGE_4_COMMON, AL_SRDS_REG_TYPE_PMA, 114, 16); - al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON, + al_serdes_grp_reg_write(obj, AL_SRDS_REG_PAGE_4_COMMON, AL_SRDS_REG_TYPE_PMA, 115, 0); - al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON, + al_serdes_grp_reg_write(obj, AL_SRDS_REG_PAGE_4_COMMON, AL_SRDS_REG_TYPE_PMA, 116, 255); - al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON, + al_serdes_grp_reg_write(obj, AL_SRDS_REG_PAGE_4_COMMON, AL_SRDS_REG_TYPE_PMA, 117, 179); - al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON, + al_serdes_grp_reg_write(obj, AL_SRDS_REG_PAGE_4_COMMON, AL_SRDS_REG_TYPE_PMA, 118, 246); - al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON, + al_serdes_grp_reg_write(obj, AL_SRDS_REG_PAGE_4_COMMON, AL_SRDS_REG_TYPE_PMA, 119, 208); - al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON, + al_serdes_grp_reg_write(obj, AL_SRDS_REG_PAGE_4_COMMON, AL_SRDS_REG_TYPE_PMA, 120, 239); - al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON, + al_serdes_grp_reg_write(obj, AL_SRDS_REG_PAGE_4_COMMON, AL_SRDS_REG_TYPE_PMA, 121, 251); - al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON, + al_serdes_grp_reg_write(obj, AL_SRDS_REG_PAGE_4_COMMON, AL_SRDS_REG_TYPE_PMA, 122, 255); - al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON, + al_serdes_grp_reg_write(obj, AL_SRDS_REG_PAGE_4_COMMON, AL_SRDS_REG_TYPE_PMA, 123, 255); - al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON, + al_serdes_grp_reg_write(obj, AL_SRDS_REG_PAGE_4_COMMON, AL_SRDS_REG_TYPE_PMA, 124, 255); - al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON, + al_serdes_grp_reg_write(obj, AL_SRDS_REG_PAGE_4_COMMON, AL_SRDS_REG_TYPE_PMA, 125, 255); - al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON, + al_serdes_grp_reg_write(obj, AL_SRDS_REG_PAGE_4_COMMON, AL_SRDS_REG_TYPE_PMA, 126, 255); - al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON, + al_serdes_grp_reg_write(obj, AL_SRDS_REG_PAGE_4_COMMON, AL_SRDS_REG_TYPE_PMA, 127, 211); - al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON, + al_serdes_grp_reg_write(obj, AL_SRDS_REG_PAGE_4_COMMON, AL_SRDS_REG_TYPE_PMA, 128, 211); - al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON, + al_serdes_grp_reg_write(obj, AL_SRDS_REG_PAGE_4_COMMON, AL_SRDS_REG_TYPE_PMA, 129, 226); - al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON, + al_serdes_grp_reg_write(obj, AL_SRDS_REG_PAGE_4_COMMON, AL_SRDS_REG_TYPE_PMA, 130, 239); - al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON, + al_serdes_grp_reg_write(obj, AL_SRDS_REG_PAGE_4_COMMON, AL_SRDS_REG_TYPE_PMA, 131, 251); - al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON, + al_serdes_grp_reg_write(obj, AL_SRDS_REG_PAGE_4_COMMON, AL_SRDS_REG_TYPE_PMA, 132, 251); - al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON, + al_serdes_grp_reg_write(obj, AL_SRDS_REG_PAGE_4_COMMON, AL_SRDS_REG_TYPE_PMA, 133, 255); - al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON, + al_serdes_grp_reg_write(obj, AL_SRDS_REG_PAGE_4_COMMON, AL_SRDS_REG_TYPE_PMA, 134, 239); - al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON, + al_serdes_grp_reg_write(obj, AL_SRDS_REG_PAGE_4_COMMON, AL_SRDS_REG_TYPE_PMA, 135, 255); - al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON, + al_serdes_grp_reg_write(obj, AL_SRDS_REG_PAGE_4_COMMON, AL_SRDS_REG_TYPE_PMA, 136, 255); - al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON, + al_serdes_grp_reg_write(obj, AL_SRDS_REG_PAGE_4_COMMON, AL_SRDS_REG_TYPE_PMA, 137, 211); - al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON, + al_serdes_grp_reg_write(obj, AL_SRDS_REG_PAGE_4_COMMON, AL_SRDS_REG_TYPE_PMA, 138, 211); - al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON, + al_serdes_grp_reg_write(obj, AL_SRDS_REG_PAGE_4_COMMON, AL_SRDS_REG_TYPE_PMA, 139, 226); - al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON, + al_serdes_grp_reg_write(obj, AL_SRDS_REG_PAGE_4_COMMON, AL_SRDS_REG_TYPE_PMA, 140, 239); - al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON, + al_serdes_grp_reg_write(obj, AL_SRDS_REG_PAGE_4_COMMON, AL_SRDS_REG_TYPE_PMA, 141, 251); - al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON, + al_serdes_grp_reg_write(obj, AL_SRDS_REG_PAGE_4_COMMON, AL_SRDS_REG_TYPE_PMA, 142, 251); - al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON, + al_serdes_grp_reg_write(obj, AL_SRDS_REG_PAGE_4_COMMON, AL_SRDS_REG_TYPE_PMA, 143, 255); - al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON, + al_serdes_grp_reg_write(obj, AL_SRDS_REG_PAGE_4_COMMON, AL_SRDS_REG_TYPE_PMA, 144, 239); - al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON, + al_serdes_grp_reg_write(obj, AL_SRDS_REG_PAGE_4_COMMON, AL_SRDS_REG_TYPE_PMA, 145, 255); - al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON, + al_serdes_grp_reg_write(obj, AL_SRDS_REG_PAGE_4_COMMON, AL_SRDS_REG_TYPE_PMA, 146, 255); - al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON, + al_serdes_grp_reg_write(obj, AL_SRDS_REG_PAGE_4_COMMON, AL_SRDS_REG_TYPE_PMA, 147, 251); - al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON, + al_serdes_grp_reg_write(obj, AL_SRDS_REG_PAGE_4_COMMON, AL_SRDS_REG_TYPE_PMA, 148, 255); - al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON, + al_serdes_grp_reg_write(obj, AL_SRDS_REG_PAGE_4_COMMON, AL_SRDS_REG_TYPE_PMA, 149, 63); - al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON, + al_serdes_grp_reg_write(obj, AL_SRDS_REG_PAGE_4_COMMON, AL_SRDS_REG_TYPE_PMA, 150, 0); - al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON, + al_serdes_grp_reg_write(obj, AL_SRDS_REG_PAGE_4_COMMON, AL_SRDS_REG_TYPE_PMA, 151, 50); - al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON, + al_serdes_grp_reg_write(obj, AL_SRDS_REG_PAGE_4_COMMON, AL_SRDS_REG_TYPE_PMA, 152, 17); - al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON, + al_serdes_grp_reg_write(obj, AL_SRDS_REG_PAGE_4_COMMON, AL_SRDS_REG_TYPE_PMA, 153, 2); - al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON, + al_serdes_grp_reg_write(obj, AL_SRDS_REG_PAGE_4_COMMON, AL_SRDS_REG_TYPE_PMA, 154, 1); - al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON, + al_serdes_grp_reg_write(obj, AL_SRDS_REG_PAGE_4_COMMON, AL_SRDS_REG_TYPE_PMA, 155, 0); - al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON, + al_serdes_grp_reg_write(obj, AL_SRDS_REG_PAGE_4_COMMON, AL_SRDS_REG_TYPE_PMA, 156, 0); - al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON, + al_serdes_grp_reg_write(obj, AL_SRDS_REG_PAGE_4_COMMON, AL_SRDS_REG_TYPE_PMA, 157, 4); - al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON, + al_serdes_grp_reg_write(obj, AL_SRDS_REG_PAGE_4_COMMON, AL_SRDS_REG_TYPE_PMA, 158, 0); - al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON, + al_serdes_grp_reg_write(obj, AL_SRDS_REG_PAGE_4_COMMON, AL_SRDS_REG_TYPE_PMA, 159, 0); - al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON, + al_serdes_grp_reg_write(obj, AL_SRDS_REG_PAGE_4_COMMON, AL_SRDS_REG_TYPE_PMA, 160, 8); - al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON, + al_serdes_grp_reg_write(obj, AL_SRDS_REG_PAGE_4_COMMON, AL_SRDS_REG_TYPE_PMA, 161, 4); - al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON, + al_serdes_grp_reg_write(obj, AL_SRDS_REG_PAGE_4_COMMON, AL_SRDS_REG_TYPE_PMA, 162, 0); - al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON, + al_serdes_grp_reg_write(obj, AL_SRDS_REG_PAGE_4_COMMON, AL_SRDS_REG_TYPE_PMA, 163, 0); - al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON, + al_serdes_grp_reg_write(obj, AL_SRDS_REG_PAGE_4_COMMON, AL_SRDS_REG_TYPE_PMA, 164, 4); - al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_0_LANE_0, + al_serdes_grp_reg_write(obj, AL_SRDS_REG_PAGE_0_LANE_0, AL_SRDS_REG_TYPE_PMA, 7, 0); - al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_1_LANE_1, + al_serdes_grp_reg_write(obj, AL_SRDS_REG_PAGE_1_LANE_1, AL_SRDS_REG_TYPE_PMA, 7, 0); - al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_2_LANE_2, + al_serdes_grp_reg_write(obj, AL_SRDS_REG_PAGE_2_LANE_2, AL_SRDS_REG_TYPE_PMA, 7, 0); - al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_3_LANE_3, + al_serdes_grp_reg_write(obj, AL_SRDS_REG_PAGE_3_LANE_3, AL_SRDS_REG_TYPE_PMA, 7, 0); - al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON, + al_serdes_grp_reg_write(obj, AL_SRDS_REG_PAGE_4_COMMON, AL_SRDS_REG_TYPE_PMA, 13, 16); - al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON, + al_serdes_grp_reg_write(obj, AL_SRDS_REG_PAGE_4_COMMON, AL_SRDS_REG_TYPE_PMA, 48, 0); - al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON, + al_serdes_grp_reg_write(obj, AL_SRDS_REG_PAGE_4_COMMON, AL_SRDS_REG_TYPE_PMA, 49, 0); - al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON, + al_serdes_grp_reg_write(obj, AL_SRDS_REG_PAGE_4_COMMON, AL_SRDS_REG_TYPE_PMA, 54, 0); - al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON, + al_serdes_grp_reg_write(obj, AL_SRDS_REG_PAGE_4_COMMON, AL_SRDS_REG_TYPE_PMA, 55, 149); /*Was 182*/ - al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON, + al_serdes_grp_reg_write(obj, AL_SRDS_REG_PAGE_4_COMMON, AL_SRDS_REG_TYPE_PMA, 93, 2); - al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON, + al_serdes_grp_reg_write(obj, AL_SRDS_REG_PAGE_4_COMMON, AL_SRDS_REG_TYPE_PMA, 165, 3); - al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_0123_LANES_0123, + al_serdes_grp_reg_write(obj, AL_SRDS_REG_PAGE_0123_LANES_0123, AL_SRDS_REG_TYPE_PMA, 41, 6); - al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON, + al_serdes_grp_reg_write(obj, AL_SRDS_REG_PAGE_4_COMMON, AL_SRDS_REG_TYPE_PMA, 354, 3); - al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON, + al_serdes_grp_reg_write(obj, AL_SRDS_REG_PAGE_4_COMMON, AL_SRDS_REG_TYPE_PMA, 355, 58); - al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON, + al_serdes_grp_reg_write(obj, AL_SRDS_REG_PAGE_4_COMMON, AL_SRDS_REG_TYPE_PMA, 356, 9); - al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON, + al_serdes_grp_reg_write(obj, AL_SRDS_REG_PAGE_4_COMMON, AL_SRDS_REG_TYPE_PMA, 357, 3); - al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON, + al_serdes_grp_reg_write(obj, AL_SRDS_REG_PAGE_4_COMMON, AL_SRDS_REG_TYPE_PMA, 358, 62); - al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON, + al_serdes_grp_reg_write(obj, AL_SRDS_REG_PAGE_4_COMMON, AL_SRDS_REG_TYPE_PMA, 359, 12); - al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_0123_LANES_0123, + al_serdes_grp_reg_write(obj, AL_SRDS_REG_PAGE_0123_LANES_0123, AL_SRDS_REG_TYPE_PMA, 701, 0); - al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_0123_LANES_0123, + al_serdes_grp_reg_write(obj, AL_SRDS_REG_PAGE_0123_LANES_0123, AL_SRDS_REG_TYPE_PMA, 87, 0x1f); - al_serdes_common_cfg_eth(grp_info); + al_serdes_common_cfg_eth(obj); - al_serdes_mode_rx_tx_inv_state_restore(grp_info, &rx_tx_inv_state); + al_serdes_mode_rx_tx_inv_state_restore(grp_obj, &rx_tx_inv_state); - al_reg_write32(&grp_info->regs_base->gen.irst, 0x0011F0); + al_reg_write32(®s_base->gen.irst, 0x0011F0); al_serdes_ns_delay(500); } -void al_serdes_rx_advanced_params_get(struct al_serdes_obj *obj, - enum al_serdes_group grp, - enum al_serdes_lane lane, - struct al_serdes_adv_rx_params* rx_params) +static void al_serdes_rx_advanced_params_get(struct al_serdes_grp_obj *obj, + enum al_serdes_lane lane, + void *rx_params) { + struct al_serdes_adv_rx_params *params = rx_params; uint8_t temp_val; - al_serdes_lane_read( - obj, grp, lane, AL_SRDS_REG_TYPE_PMA, + al_serdes_reg_read( + obj, (enum al_serdes_reg_page)lane, + AL_SRDS_REG_TYPE_PMA, SERDES_IREG_RX_CALEQ_1_REG_NUM, &temp_val); - rx_params->dcgain = (temp_val & SERDES_IREG_RX_CALEQ_1_DCGAIN_MASK) >> + params->dcgain = (temp_val & SERDES_IREG_RX_CALEQ_1_DCGAIN_MASK) >> SERDES_IREG_RX_CALEQ_1_DCGAIN_SHIFT; - rx_params->dfe_3db_freq = (temp_val & + params->dfe_3db_freq = (temp_val & SERDES_IREG_RX_CALEQ_1_DFEPSTAP3DB_MASK) >> SERDES_IREG_RX_CALEQ_1_DFEPSTAP3DB_SHIFT; - al_serdes_lane_read( - obj, grp, lane, AL_SRDS_REG_TYPE_PMA, + al_serdes_reg_read( + obj, (enum al_serdes_reg_page)lane, + AL_SRDS_REG_TYPE_PMA, SERDES_IREG_RX_CALEQ_2_REG_NUM, &temp_val); - rx_params->dfe_gain = (temp_val & + params->dfe_gain = (temp_val & SERDES_IREG_RX_CALEQ_2_DFEPSTAPGAIN_MASK) >> SERDES_IREG_RX_CALEQ_2_DFEPSTAPGAIN_SHIFT; - rx_params->dfe_first_tap_ctrl = (temp_val & + params->dfe_first_tap_ctrl = (temp_val & SERDES_IREG_RX_CALEQ_2_DFETAP1GAIN_MASK) >> SERDES_IREG_RX_CALEQ_2_DFETAP1GAIN_SHIFT; - al_serdes_lane_read( - obj, grp, lane, AL_SRDS_REG_TYPE_PMA, + al_serdes_reg_read( + obj, (enum al_serdes_reg_page)lane, + AL_SRDS_REG_TYPE_PMA, SERDES_IREG_RX_CALEQ_3_REG_NUM, &temp_val); - rx_params->dfe_secound_tap_ctrl = (temp_val & + params->dfe_secound_tap_ctrl = (temp_val & SERDES_IREG_RX_CALEQ_3_DFETAP2GAIN_MASK) >> SERDES_IREG_RX_CALEQ_3_DFETAP2GAIN_SHIFT; - rx_params->dfe_third_tap_ctrl = (temp_val & + params->dfe_third_tap_ctrl = (temp_val & SERDES_IREG_RX_CALEQ_3_DFETAP3GAIN_MASK) >> SERDES_IREG_RX_CALEQ_3_DFETAP3GAIN_SHIFT; - al_serdes_lane_read( - obj, grp, lane, AL_SRDS_REG_TYPE_PMA, + al_serdes_reg_read( + obj, (enum al_serdes_reg_page)lane, + AL_SRDS_REG_TYPE_PMA, SERDES_IREG_RX_CALEQ_4_REG_NUM, &temp_val); - rx_params->dfe_fourth_tap_ctrl = (temp_val & + params->dfe_fourth_tap_ctrl = (temp_val & SERDES_IREG_RX_CALEQ_4_DFETAP4GAIN_MASK) >> SERDES_IREG_RX_CALEQ_4_DFETAP4GAIN_SHIFT; - rx_params->low_freq_agc_gain = (temp_val & + params->low_freq_agc_gain = (temp_val & SERDES_IREG_RX_CALEQ_4_LOFREQAGCGAIN_MASK) >> SERDES_IREG_RX_CALEQ_4_LOFREQAGCGAIN_SHIFT; - al_serdes_lane_read( - obj, grp, lane, AL_SRDS_REG_TYPE_PMA, + al_serdes_reg_read( + obj, (enum al_serdes_reg_page)lane, + AL_SRDS_REG_TYPE_PMA, SERDES_IREG_RX_CALEQ_5_REG_NUM, &temp_val); - rx_params->precal_code_sel = (temp_val & + params->precal_code_sel = (temp_val & SERDES_IREG_RX_CALEQ_5_PRECAL_CODE_SEL_MASK) >> SERDES_IREG_RX_CALEQ_5_PRECAL_CODE_SEL_SHIFT; - rx_params->high_freq_agc_boost = (temp_val & + params->high_freq_agc_boost = (temp_val & SERDES_IREG_RX_CALEQ_5_HIFREQAGCCAP_MASK) >> SERDES_IREG_RX_CALEQ_5_HIFREQAGCCAP_SHIFT; - al_serdes_lane_read(obj, grp, lane, AL_SRDS_REG_TYPE_PMA, + al_serdes_reg_read(obj, (enum al_serdes_reg_page)lane, + AL_SRDS_REG_TYPE_PMA, SERDES_IREG_FLD_RX_DRV_OVERRIDE_EN_REG_NUM, &temp_val); - rx_params->override = ((temp_val & SERDES_IREG_FLD_RX_DRV_OVERRIDE_EN) == 0); + params->override = ((temp_val & SERDES_IREG_FLD_RX_DRV_OVERRIDE_EN) == 0); } -#if ( SERDES_IREG_FLD_RXCALEYEDIAGFSMIN_LOCWREN_REG_NUM != \ +#if (SERDES_IREG_FLD_RXCALEYEDIAGFSMIN_LOCWREN_REG_NUM != \ SERDES_IREG_FLD_RXCALROAMEYEMEASIN_LOCWREN_REG_NUM || \ SERDES_IREG_FLD_RXCALEYEDIAGFSMIN_LOCWREN_REG_NUM != \ SERDES_IREG_FLD_RXCALROAMXADJUST_LOCWREN_REG_NUM) #error Wrong assumption #endif -int al_serdes_rx_equalization( - struct al_serdes_obj *obj, - enum al_serdes_group grp, - enum al_serdes_lane lane) +static int al_serdes_rx_equalization( + struct al_serdes_grp_obj *obj, + enum al_serdes_lane lane) { uint8_t serdes_ireg_fld_rxcalroamyadjust_locwren_val; uint8_t serdes_ireg_fld_rxroam_xorbitsel_val; @@ -2667,39 +2501,43 @@ int al_serdes_rx_equalization( /* * Make sure Roam Eye mechanism is not overridden * Lane SERDES_IREG_FLD_RXCALEYEDIAGFSMIN_LOCWREN = 1, - * so Rx 4-Point Eye process is not overridden + * so Rx 4-Point Eye process is not overridden * Lane SERDES_IREG_FLD_RXCALROAMEYEMEASIN_LOCWREN = 1, - * so Eye Roam latch is not overridden + * so Eye Roam latch is not overridden * Lane SERDES_IREG_FLD_RXCALROAMXADJUST_LOCWREN = 1, - * so Eye Roam latch 'X adjust' is not overridden + * so Eye Roam latch 'X adjust' is not overridden * Lane SERDES_IREG_FLD_RXCALROAMYADJUST_LOCWREN = 1, - * so Eye Roam latch 'Y adjust' is not overridden + * so Eye Roam latch 'Y adjust' is not overridden * Lane SERDES_IREG_FLD_RXROAM_XORBITSEL = 0/1, - * so Eye Roamlatch works on the right Eye position (XORBITSEL) - * For most cases 0 is needed, but sometimes 1 is needed. - * I couldn't sort out why is this so the code uses a global + * so Eye Roamlatch works on the right Eye position (XORBITSEL) + * For most cases 0 is needed, but sometimes 1 is needed. + * I couldn't sort out why is this so the code uses a global * XORBITSELmode variable, set by the user (GUI). Default is 0. * control must be internal. At the end we restore original setting */ /* save current values for restoring them later in the end */ - al_serdes_lane_read( - obj, grp, lane, AL_SRDS_REG_TYPE_PMA, + al_serdes_reg_read( + obj, (enum al_serdes_reg_page)lane, + AL_SRDS_REG_TYPE_PMA, SERDES_IREG_FLD_RXCAL_LOCWREN_REG_NUM, &serdes_ireg_fld_rxcal_locwren_val); - al_serdes_lane_read( - obj, grp, lane, AL_SRDS_REG_TYPE_PMA, + al_serdes_reg_read( + obj, (enum al_serdes_reg_page)lane, + AL_SRDS_REG_TYPE_PMA, SERDES_IREG_FLD_RXCALROAMYADJUST_LOCWREN_REG_NUM, - &serdes_ireg_fld_rxcalroamyadjust_locwren_val ); - al_serdes_lane_read( - obj, grp, lane, AL_SRDS_REG_TYPE_PMA, + &serdes_ireg_fld_rxcalroamyadjust_locwren_val); + al_serdes_reg_read( + obj, (enum al_serdes_reg_page)lane, + AL_SRDS_REG_TYPE_PMA, SERDES_IREG_FLD_RXROAM_XORBITSEL_REG_NUM, - &serdes_ireg_fld_rxroam_xorbitsel_val ); - al_serdes_lane_read( - obj, grp, lane, AL_SRDS_REG_TYPE_PMA, + &serdes_ireg_fld_rxroam_xorbitsel_val); + al_serdes_reg_read( + obj, (enum al_serdes_reg_page)lane, + AL_SRDS_REG_TYPE_PMA, SERDES_IREG_FLD_PCSRXEQ_LOCWREN_REG_NUM, - &serdes_ireg_fld_pcsrxeq_locwren_val ); + &serdes_ireg_fld_pcsrxeq_locwren_val); /* * Set Bits: @@ -2717,10 +2555,11 @@ int al_serdes_rx_equalization( temp_val |= SERDES_IREG_FLD_RXCALROAMXADJUST_LOCWREN; temp_val |= SERDES_IREG_FLD_RX_DRV_OVERRIDE_EN; - al_serdes_lane_write( - obj, grp, lane, AL_SRDS_REG_TYPE_PMA, + al_serdes_reg_write( + obj, (enum al_serdes_reg_page)lane, + AL_SRDS_REG_TYPE_PMA, SERDES_IREG_FLD_RXCAL_LOCWREN_REG_NUM, - temp_val ); + temp_val); /* * Set bit SERDES_IREG_FLD_RXCALROAMYADJUST_LOCWREN @@ -2728,10 +2567,11 @@ int al_serdes_rx_equalization( */ temp_val = serdes_ireg_fld_rxcalroamyadjust_locwren_val | SERDES_IREG_FLD_RXCALROAMYADJUST_LOCWREN; - al_serdes_lane_write( - obj, grp, lane, AL_SRDS_REG_TYPE_PMA, + al_serdes_reg_write( + obj, (enum al_serdes_reg_page)lane, + AL_SRDS_REG_TYPE_PMA, SERDES_IREG_FLD_RXCALROAMYADJUST_LOCWREN_REG_NUM, - temp_val ); + temp_val); /* * Clear Bit: SERDES_IREG_FLD_RXROAM_XORBITSEL @@ -2739,10 +2579,11 @@ int al_serdes_rx_equalization( */ temp_val = serdes_ireg_fld_rxroam_xorbitsel_val & ~SERDES_IREG_FLD_RXROAM_XORBITSEL; - al_serdes_lane_write( - obj, grp, lane, AL_SRDS_REG_TYPE_PMA, + al_serdes_reg_write( + obj, (enum al_serdes_reg_page)lane, + AL_SRDS_REG_TYPE_PMA, SERDES_IREG_FLD_RXROAM_XORBITSEL_REG_NUM, - temp_val ); + temp_val); /* * Take Control from int.pin over RxEQ process. @@ -2751,10 +2592,11 @@ int al_serdes_rx_equalization( */ temp_val = serdes_ireg_fld_pcsrxeq_locwren_val & ~SERDES_IREG_FLD_PCSRXEQ_LOCWREN; - al_serdes_lane_write( - obj, grp, lane, AL_SRDS_REG_TYPE_PMA, + al_serdes_reg_write( + obj, (enum al_serdes_reg_page)lane, + AL_SRDS_REG_TYPE_PMA, SERDES_IREG_FLD_PCSRXEQ_LOCWREN_REG_NUM, - temp_val ); + temp_val); /* @@ -2762,30 +2604,34 @@ int al_serdes_rx_equalization( * Clear Bit SERDES_IREG_FLD_PCSRXEQ_START * to start fresh from Stop */ - al_serdes_lane_read( - obj, grp, lane, AL_SRDS_REG_TYPE_PMA, + al_serdes_reg_read( + obj, (enum al_serdes_reg_page)lane, + AL_SRDS_REG_TYPE_PMA, SERDES_IREG_FLD_PCSRXEQ_START_REG_NUM, - &temp_val ); + &temp_val); temp_val &= ~SERDES_IREG_FLD_PCSRXEQ_START; - al_serdes_lane_write( - obj, grp, lane, AL_SRDS_REG_TYPE_PMA, + al_serdes_reg_write( + obj, (enum al_serdes_reg_page)lane, + AL_SRDS_REG_TYPE_PMA, SERDES_IREG_FLD_PCSRXEQ_START_REG_NUM, - temp_val ); + temp_val); /* Set Bit SERDES_IREG_FLD_PCSRXEQ_START * to begin Rx Eq Cal */ temp_val |= SERDES_IREG_FLD_PCSRXEQ_START; - al_serdes_lane_write( - obj, grp, lane, AL_SRDS_REG_TYPE_PMA, + al_serdes_reg_write( + obj, (enum al_serdes_reg_page)lane, + AL_SRDS_REG_TYPE_PMA, SERDES_IREG_FLD_PCSRXEQ_START_REG_NUM, - temp_val ); + temp_val); /* Poll on RxEq Cal completion. SERDES_IREG_FLD_RXEQ_DONE. 1=Done. */ - for( i = 0; i < AL_SERDES_RX_EQUAL_TRIES; ++i ) { - al_serdes_lane_read( - obj, grp, lane, AL_SRDS_REG_TYPE_PMA, + for (i = 0; i < AL_SERDES_RX_EQUAL_TRIES; ++i) { + al_serdes_reg_read( + obj, (enum al_serdes_reg_page)lane, + AL_SRDS_REG_TYPE_PMA, SERDES_IREG_FLD_RXCALROAMEYEMEASDONE_REG_NUM, - &done ); + &done); done &= SERDES_IREG_FLD_RXEQ_DONE; /* Check if RxEQ Cal is done */ @@ -2801,44 +2647,51 @@ int al_serdes_rx_equalization( /* Stop the RxEQ process. */ temp_val &= ~SERDES_IREG_FLD_PCSRXEQ_START; - al_serdes_lane_write( - obj, grp, lane, AL_SRDS_REG_TYPE_PMA, + al_serdes_reg_write( + obj, (enum al_serdes_reg_page)lane, + AL_SRDS_REG_TYPE_PMA, SERDES_IREG_FLD_PCSRXEQ_START_REG_NUM, - temp_val ); + temp_val); /* Get score */ - al_serdes_lane_read( - obj, grp, lane, AL_SRDS_REG_TYPE_PMA, + al_serdes_reg_read( + obj, (enum al_serdes_reg_page)lane, + AL_SRDS_REG_TYPE_PMA, SERDES_IREG_RXEQ_BEST_EYE_MSB_VAL_REG_NUM, - &temp_val ); - test_score = (int)( (temp_val & 0xFF) << 6 ); - al_serdes_lane_read( - obj, grp, lane, AL_SRDS_REG_TYPE_PMA, + &temp_val); + test_score = (int)((temp_val & 0xFF) << 6); + al_serdes_reg_read( + obj, (enum al_serdes_reg_page)lane, + AL_SRDS_REG_TYPE_PMA, SERDES_IREG_RXEQ_BEST_EYE_LSB_VAL_REG_NUM, - &temp_val ); + &temp_val); test_score += (int)(temp_val & SERDES_IREG_RXEQ_BEST_EYE_LSB_VAL_MASK); /* Restore start values */ - al_serdes_lane_write( - obj, grp, lane, AL_SRDS_REG_TYPE_PMA, + al_serdes_reg_write( + obj, (enum al_serdes_reg_page)lane, + AL_SRDS_REG_TYPE_PMA, SERDES_IREG_FLD_RXCAL_LOCWREN_REG_NUM, serdes_ireg_fld_rxcal_locwren_val); - al_serdes_lane_write( - obj, grp, lane, AL_SRDS_REG_TYPE_PMA, + al_serdes_reg_write( + obj, (enum al_serdes_reg_page)lane, + AL_SRDS_REG_TYPE_PMA, SERDES_IREG_FLD_RXCALROAMYADJUST_LOCWREN_REG_NUM, - serdes_ireg_fld_rxcalroamyadjust_locwren_val ); - al_serdes_lane_write( - obj, grp, lane, AL_SRDS_REG_TYPE_PMA, + serdes_ireg_fld_rxcalroamyadjust_locwren_val); + al_serdes_reg_write( + obj, (enum al_serdes_reg_page)lane, + AL_SRDS_REG_TYPE_PMA, SERDES_IREG_FLD_RXROAM_XORBITSEL_REG_NUM, - serdes_ireg_fld_rxroam_xorbitsel_val ); - al_serdes_lane_write( - obj, grp, lane, AL_SRDS_REG_TYPE_PMA, + serdes_ireg_fld_rxroam_xorbitsel_val); + al_serdes_reg_write( + obj, (enum al_serdes_reg_page)lane, + AL_SRDS_REG_TYPE_PMA, SERDES_IREG_FLD_PCSRXEQ_LOCWREN_REG_NUM, - serdes_ireg_fld_pcsrxeq_locwren_val ); + serdes_ireg_fld_pcsrxeq_locwren_val); return test_score; } -#if ( SERDES_IREG_FLD_RXCAL_LOCWREN_REG_NUM != \ +#if (SERDES_IREG_FLD_RXCAL_LOCWREN_REG_NUM != \ SERDES_IREG_FLD_RXCALROAMEYEMEASIN_LOCWREN_REG_NUM || \ SERDES_IREG_FLD_RXCAL_LOCWREN_REG_NUM != \ SERDES_IREG_FLD_RXCALROAMXADJUST_LOCWREN_REG_NUM || \ @@ -2846,12 +2699,11 @@ int al_serdes_rx_equalization( SERDES_IREG_FLD_RXCALEYEDIAGFSMIN_LOCWREN_REG_NUM) #error Wrong assumption #endif -int al_serdes_calc_eye_size( - struct al_serdes_obj *obj, - enum al_serdes_group grp, - enum al_serdes_lane lane, - int* width, - int* height) +static int al_serdes_calc_eye_size( + struct al_serdes_grp_obj *obj, + enum al_serdes_lane lane, + int *width, + int *height) { uint8_t rxcaleyediagfsm_x_y_valweight_val; uint8_t rxcaleyediagfsm_xvalcoarse_val; @@ -2868,51 +2720,55 @@ int al_serdes_calc_eye_size( uint8_t reg_value; /* Save Registers */ - al_serdes_lane_read(obj, grp, lane, AL_SRDS_REG_TYPE_PMA, + al_serdes_reg_read(obj, (enum al_serdes_reg_page)lane, + AL_SRDS_REG_TYPE_PMA, SERDES_IREG_FLD_RXLOCK2REF_LOCWREN_REG_NUM, &rxlock2ref_locwren_val); - al_serdes_lane_read(obj, grp, lane, AL_SRDS_REG_TYPE_PMA, + al_serdes_reg_read(obj, (enum al_serdes_reg_page)lane, + AL_SRDS_REG_TYPE_PMA, SERDES_IREG_FLD_RXCAL_LOCWREN_REG_NUM, &rxcal_locwren_val); - al_serdes_lane_read(obj, grp, lane, AL_SRDS_REG_TYPE_PMA, + al_serdes_reg_read(obj, (enum al_serdes_reg_page)lane, + AL_SRDS_REG_TYPE_PMA, SERDES_IREG_FLD_RXCALROAMYADJUST_LOCWREN_REG_NUM, &rxcalroamyadjust_locwren_val); - al_serdes_lane_read(obj, grp, lane, AL_SRDS_REG_TYPE_PMA, + al_serdes_reg_read(obj, (enum al_serdes_reg_page)lane, + AL_SRDS_REG_TYPE_PMA, SERDES_IREG_FLD_RXLOCK2REF_OVREN_REG_NUM, &rxlock2ref_ovren_val); - al_serdes_reg_read(obj, grp, AL_SRDS_REG_PAGE_4_COMMON, + al_serdes_reg_read(obj, AL_SRDS_REG_PAGE_4_COMMON, AL_SRDS_REG_TYPE_PMA, SERDES_IREG_FLD_RXCALEYEDIAGFSM_X_Y_VALWEIGHT_REG_NUM, &rxcaleyediagfsm_x_y_valweight_val); - al_serdes_reg_read(obj, grp, AL_SRDS_REG_PAGE_4_COMMON, + al_serdes_reg_read(obj, AL_SRDS_REG_PAGE_4_COMMON, AL_SRDS_REG_TYPE_PMA, SERDES_IREG_FLD_RXCALEYEDIAGFSM_XVALCOARSE_REG_NUM, &rxcaleyediagfsm_xvalcoarse_val); - al_serdes_reg_read(obj, grp, AL_SRDS_REG_PAGE_4_COMMON, + al_serdes_reg_read(obj, AL_SRDS_REG_PAGE_4_COMMON, AL_SRDS_REG_TYPE_PMA, SERDES_IREG_FLD_RXCALEYEDIAGFSM_XVALFINE_REG_NUM, &rxcaleyediagfsm_xvalfine_val); - al_serdes_reg_read(obj, grp, AL_SRDS_REG_PAGE_4_COMMON, + al_serdes_reg_read(obj, AL_SRDS_REG_PAGE_4_COMMON, AL_SRDS_REG_TYPE_PMA, SERDES_IREG_FLD_RXCALEYEDIAGFSM_YVALCOARSE_REG_NUM, &rxcaleyediagfsm_yvalcoarse_val); - al_serdes_reg_read(obj, grp, AL_SRDS_REG_PAGE_4_COMMON, + al_serdes_reg_read(obj, AL_SRDS_REG_PAGE_4_COMMON, AL_SRDS_REG_TYPE_PMA, SERDES_IREG_FLD_RXCALEYEDIAGFSM_YVALFINE_REG_NUM, &rxcaleyediagfsm_yvalfine_val); /* * Clear Bit: - * SERDES_IREG_FLD_RXCALEYEDIAGFSMIN_LOCWREN - * to override RxEQ via PMA + * SERDES_IREG_FLD_RXCALEYEDIAGFSMIN_LOCWREN + * to override RxEQ via PMA * Set Bits: - * SERDES_IREG_FLD_RXCALROAMEYEMEASIN_LOCWREN, - * SERDES_IREG_FLD_RXCALROAMXADJUST_LOCWREN - * to keep Eye Diag Roam controlled internally + * SERDES_IREG_FLD_RXCALROAMEYEMEASIN_LOCWREN, + * SERDES_IREG_FLD_RXCALROAMXADJUST_LOCWREN + * to keep Eye Diag Roam controlled internally */ - al_serdes_grp_lane_masked_write(&obj->grp_info[grp], - lane, + al_serdes_grp_reg_masked_write(obj, + (enum al_serdes_reg_page)lane, AL_SRDS_REG_TYPE_PMA, SERDES_IREG_FLD_RXCAL_LOCWREN_REG_NUM, SERDES_IREG_FLD_RXCALEYEDIAGFSMIN_LOCWREN | @@ -2922,11 +2778,11 @@ int al_serdes_calc_eye_size( SERDES_IREG_FLD_RXCALROAMXADJUST_LOCWREN); /* * Set Bit: - * SERDES_IREG_FLD_RXCALROAMYADJUST_LOCWREN - * to keep Eye Diag Roam controlled internally + * SERDES_IREG_FLD_RXCALROAMYADJUST_LOCWREN + * to keep Eye Diag Roam controlled internally */ - al_serdes_grp_lane_masked_write(&obj->grp_info[grp], - lane, + al_serdes_grp_reg_masked_write(obj, + (enum al_serdes_reg_page)lane, AL_SRDS_REG_TYPE_PMA, SERDES_IREG_FLD_RXCALROAMYADJUST_LOCWREN_REG_NUM, SERDES_IREG_FLD_RXCALROAMYADJUST_LOCWREN, @@ -2934,14 +2790,14 @@ int al_serdes_calc_eye_size( /* * Clear Bit: - * SERDES_IREG_FLD_RXROAM_XORBITSEL, - * so XORBITSEL=0, needed for the Eye mapping + * SERDES_IREG_FLD_RXROAM_XORBITSEL, + * so XORBITSEL=0, needed for the Eye mapping * Set Bit: * SERDES_IREG_FLD_RXLOCK2REF_OVREN, * so RXLOCK2REF_OVREN=1, keeping lock to data, preventing data hit */ - al_serdes_grp_lane_masked_write(&obj->grp_info[grp], - lane, + al_serdes_grp_reg_masked_write(obj, + (enum al_serdes_reg_page)lane, AL_SRDS_REG_TYPE_PMA, SERDES_IREG_FLD_RXROAM_XORBITSEL_REG_NUM, SERDES_IREG_FLD_RXLOCK2REF_OVREN | @@ -2951,11 +2807,11 @@ int al_serdes_calc_eye_size( /* * Clear Bit: - * SERDES_IREG_FLD_RXLOCK2REF_LOCWREN, - * so RXLOCK2REF_LOCWREN=0, to override control + * SERDES_IREG_FLD_RXLOCK2REF_LOCWREN, + * so RXLOCK2REF_LOCWREN=0, to override control */ - al_serdes_grp_lane_masked_write(&obj->grp_info[grp], - lane, + al_serdes_grp_reg_masked_write(obj, + (enum al_serdes_reg_page)lane, AL_SRDS_REG_TYPE_PMA, SERDES_IREG_FLD_RXLOCK2REF_LOCWREN_REG_NUM, SERDES_IREG_FLD_RXLOCK2REF_LOCWREN, @@ -2964,49 +2820,50 @@ int al_serdes_calc_eye_size( /* Width Calculation */ /* Return Value = 0*Y + 1*X */ - al_serdes_reg_write(obj, grp, AL_SRDS_REG_PAGE_4_COMMON, + al_serdes_reg_write(obj, AL_SRDS_REG_PAGE_4_COMMON, AL_SRDS_REG_TYPE_PMA, SERDES_IREG_FLD_RXCALEYEDIAGFSM_X_Y_VALWEIGHT_REG_NUM, 0x01); /* X coarse scan step = 3 */ - al_serdes_reg_write(obj, grp, AL_SRDS_REG_PAGE_4_COMMON, + al_serdes_reg_write(obj, AL_SRDS_REG_PAGE_4_COMMON, AL_SRDS_REG_TYPE_PMA, SERDES_IREG_FLD_RXCALEYEDIAGFSM_XVALCOARSE_REG_NUM, 0x03); /* X fine scan step = 1 */ - al_serdes_reg_write(obj, grp, AL_SRDS_REG_PAGE_4_COMMON, + al_serdes_reg_write(obj, AL_SRDS_REG_PAGE_4_COMMON, AL_SRDS_REG_TYPE_PMA, SERDES_IREG_FLD_RXCALEYEDIAGFSM_XVALFINE_REG_NUM, 0x01); /* Y coarse scan step = 0 */ - al_serdes_reg_write(obj, grp, AL_SRDS_REG_PAGE_4_COMMON, + al_serdes_reg_write(obj, AL_SRDS_REG_PAGE_4_COMMON, AL_SRDS_REG_TYPE_PMA, SERDES_IREG_FLD_RXCALEYEDIAGFSM_YVALCOARSE_REG_NUM, 0x00); /* Y fine scan step = 0 */ - al_serdes_reg_write(obj, grp, AL_SRDS_REG_PAGE_4_COMMON, + al_serdes_reg_write(obj, AL_SRDS_REG_PAGE_4_COMMON, AL_SRDS_REG_TYPE_PMA, SERDES_IREG_FLD_RXCALEYEDIAGFSM_YVALFINE_REG_NUM, 0x00); /* * Set Bit: - * SERDES_IREG_FLD_RXCALEYEDIAGFSMIN_START, - * to start Eye measurement + * SERDES_IREG_FLD_RXCALEYEDIAGFSMIN_START, + * to start Eye measurement */ - al_serdes_grp_lane_masked_write(&obj->grp_info[grp], - lane, + al_serdes_grp_reg_masked_write(obj, + (enum al_serdes_reg_page)lane, AL_SRDS_REG_TYPE_PMA, SERDES_IREG_FLD_RXCALEYEDIAGFSMIN_START_REG_NUM, SERDES_IREG_FLD_RXCALEYEDIAGFSMIN_START, SERDES_IREG_FLD_RXCALEYEDIAGFSMIN_START); - for( i = 0; i < AL_SERDES_RX_EYE_CAL_TRIES; ++i ) { + for(i = 0; i < AL_SERDES_RX_EYE_CAL_TRIES; ++i) { /* Check if RxEQ Cal is done */ - al_serdes_lane_read( - obj, grp, lane, AL_SRDS_REG_TYPE_PMA, + al_serdes_reg_read( + obj, (enum al_serdes_reg_page)lane, + AL_SRDS_REG_TYPE_PMA, SERDES_IREG_FLD_RXCALEYEDIAGFSM_DONE_REG_NUM, - &status ); + &status); if (status & SERDES_IREG_FLD_RXCALEYEDIAGFSM_DONE) break; al_msleep(AL_SERDES_RX_EYE_CAL_MDELAY); @@ -3023,27 +2880,29 @@ int al_serdes_calc_eye_size( } /* Read Eye Opening Metrics, Bits: - * SERDES_IREG_FLD_RXCALEYEDIAGFSM_EYESUM_LSB, - * SERDES_IREG_FLD_RXCALEYEDIAGFSM_EYESUM_LSB + * SERDES_IREG_FLD_RXCALEYEDIAGFSM_EYESUM_LSB, + * SERDES_IREG_FLD_RXCALEYEDIAGFSM_EYESUM_LSB */ - al_serdes_lane_read( - obj, grp, lane, AL_SRDS_REG_TYPE_PMA, + al_serdes_reg_read( + obj, (enum al_serdes_reg_page)lane, + AL_SRDS_REG_TYPE_PMA, SERDES_IREG_FLD_RXCALEYEDIAGFSM_EYESUM_MSB_REG_NUM, - ®_value ); + ®_value); *width = reg_value << 6; - al_serdes_lane_read( - obj, grp, lane, AL_SRDS_REG_TYPE_PMA, + al_serdes_reg_read( + obj, (enum al_serdes_reg_page)lane, + AL_SRDS_REG_TYPE_PMA, SERDES_IREG_FLD_RXCALEYEDIAGFSM_EYESUM_LSB_REG_NUM, - ®_value ); + ®_value); *width =+ reg_value & SERDES_IREG_FLD_RXCALEYEDIAGFSM_EYESUM_LSB_MAKE; /* * Clear Bit: - * SERDES_IREG_FLD_RXCALEYEDIAGFSMIN_START, - * to stop Eye measurement + * SERDES_IREG_FLD_RXCALEYEDIAGFSMIN_START, + * to stop Eye measurement */ - al_serdes_grp_lane_masked_write(&obj->grp_info[grp], - lane, + al_serdes_grp_reg_masked_write(obj, + (enum al_serdes_reg_page)lane, AL_SRDS_REG_TYPE_PMA, SERDES_IREG_FLD_RXCALEYEDIAGFSMIN_START_REG_NUM, SERDES_IREG_FLD_RXCALEYEDIAGFSMIN_START, @@ -3052,38 +2911,38 @@ int al_serdes_calc_eye_size( /* Height Calculation */ /* Return Value = 1*Y + 0*X */ - al_serdes_reg_write(obj, grp, AL_SRDS_REG_PAGE_4_COMMON, + al_serdes_reg_write(obj, AL_SRDS_REG_PAGE_4_COMMON, AL_SRDS_REG_TYPE_PMA, SERDES_IREG_FLD_RXCALEYEDIAGFSM_X_Y_VALWEIGHT_REG_NUM, 0x10); /* X coarse scan step = 0 */ - al_serdes_reg_write(obj, grp, AL_SRDS_REG_PAGE_4_COMMON, + al_serdes_reg_write(obj, AL_SRDS_REG_PAGE_4_COMMON, AL_SRDS_REG_TYPE_PMA, SERDES_IREG_FLD_RXCALEYEDIAGFSM_XVALCOARSE_REG_NUM, 0x00); /* X fine scan step = 0 */ - al_serdes_reg_write(obj, grp, AL_SRDS_REG_PAGE_4_COMMON, + al_serdes_reg_write(obj, AL_SRDS_REG_PAGE_4_COMMON, AL_SRDS_REG_TYPE_PMA, SERDES_IREG_FLD_RXCALEYEDIAGFSM_XVALFINE_REG_NUM, 0x00); /* Y coarse scan step = 3 */ - al_serdes_reg_write(obj, grp, AL_SRDS_REG_PAGE_4_COMMON, + al_serdes_reg_write(obj, AL_SRDS_REG_PAGE_4_COMMON, AL_SRDS_REG_TYPE_PMA, SERDES_IREG_FLD_RXCALEYEDIAGFSM_YVALCOARSE_REG_NUM, 0x03); /* Y fine scan step = 1 */ - al_serdes_reg_write(obj, grp, AL_SRDS_REG_PAGE_4_COMMON, + al_serdes_reg_write(obj, AL_SRDS_REG_PAGE_4_COMMON, AL_SRDS_REG_TYPE_PMA, SERDES_IREG_FLD_RXCALEYEDIAGFSM_YVALFINE_REG_NUM, 0x01); /* * Set Bit: - * SERDES_IREG_FLD_RXCALEYEDIAGFSMIN_START, - * to start Eye measurement + * SERDES_IREG_FLD_RXCALEYEDIAGFSMIN_START, + * to start Eye measurement */ - al_serdes_grp_lane_masked_write(&obj->grp_info[grp], - lane, + al_serdes_grp_reg_masked_write(obj, + (enum al_serdes_reg_page)lane, AL_SRDS_REG_TYPE_PMA, SERDES_IREG_FLD_RXCALEYEDIAGFSMIN_START_REG_NUM, SERDES_IREG_FLD_RXCALEYEDIAGFSMIN_START, @@ -3091,8 +2950,9 @@ int al_serdes_calc_eye_size( for( i = 0; i < AL_SERDES_RX_EYE_CAL_TRIES; ++i ) { /* Check if RxEQ Cal is done */ - al_serdes_lane_read( - obj, grp, lane, AL_SRDS_REG_TYPE_PMA, + al_serdes_reg_read( + obj, (enum al_serdes_reg_page)lane, + AL_SRDS_REG_TYPE_PMA, SERDES_IREG_FLD_RXCALEYEDIAGFSM_DONE_REG_NUM, &status ); if (status & SERDES_IREG_FLD_RXCALEYEDIAGFSM_DONE) @@ -3111,118 +2971,194 @@ int al_serdes_calc_eye_size( } /* Read Eye Opening Metrics, Bits: - * SERDES_IREG_FLD_RXCALEYEDIAGFSM_EYESUM_LSB, - * SERDES_IREG_FLD_RXCALEYEDIAGFSM_EYESUM_LSB + * SERDES_IREG_FLD_RXCALEYEDIAGFSM_EYESUM_LSB, + * SERDES_IREG_FLD_RXCALEYEDIAGFSM_EYESUM_LSB */ - al_serdes_lane_read( - obj, grp, lane, AL_SRDS_REG_TYPE_PMA, + al_serdes_reg_read( + obj, (enum al_serdes_reg_page)lane, + AL_SRDS_REG_TYPE_PMA, SERDES_IREG_FLD_RXCALEYEDIAGFSM_EYESUM_MSB_REG_NUM, ®_value ); *height = reg_value << 6; - al_serdes_lane_read( - obj, grp, lane, AL_SRDS_REG_TYPE_PMA, + al_serdes_reg_read( + obj, (enum al_serdes_reg_page)lane, + AL_SRDS_REG_TYPE_PMA, SERDES_IREG_FLD_RXCALEYEDIAGFSM_EYESUM_LSB_REG_NUM, ®_value ); *height =+ reg_value & SERDES_IREG_FLD_RXCALEYEDIAGFSM_EYESUM_LSB_MAKE; /* * Clear Bit: - * SERDES_IREG_FLD_RXCALEYEDIAGFSMIN_START, - * to stop Eye measurement + * SERDES_IREG_FLD_RXCALEYEDIAGFSMIN_START, + * to stop Eye measurement */ - al_serdes_grp_lane_masked_write(&obj->grp_info[grp], - lane, + al_serdes_grp_reg_masked_write(obj, + (enum al_serdes_reg_page)lane, AL_SRDS_REG_TYPE_PMA, SERDES_IREG_FLD_RXCALEYEDIAGFSMIN_START_REG_NUM, SERDES_IREG_FLD_RXCALEYEDIAGFSMIN_START, 0); /* Restore Registers */ - al_serdes_reg_write(obj, grp, AL_SRDS_REG_PAGE_4_COMMON, + al_serdes_reg_write(obj, AL_SRDS_REG_PAGE_4_COMMON, AL_SRDS_REG_TYPE_PMA, SERDES_IREG_FLD_RXCALEYEDIAGFSM_X_Y_VALWEIGHT_REG_NUM, rxcaleyediagfsm_x_y_valweight_val); - al_serdes_reg_write(obj, grp, AL_SRDS_REG_PAGE_4_COMMON, + al_serdes_reg_write(obj, AL_SRDS_REG_PAGE_4_COMMON, AL_SRDS_REG_TYPE_PMA, SERDES_IREG_FLD_RXCALEYEDIAGFSM_XVALCOARSE_REG_NUM, rxcaleyediagfsm_xvalcoarse_val); - al_serdes_reg_write(obj, grp, AL_SRDS_REG_PAGE_4_COMMON, + al_serdes_reg_write(obj, AL_SRDS_REG_PAGE_4_COMMON, AL_SRDS_REG_TYPE_PMA, SERDES_IREG_FLD_RXCALEYEDIAGFSM_XVALFINE_REG_NUM, rxcaleyediagfsm_xvalfine_val); - al_serdes_reg_write(obj, grp, AL_SRDS_REG_PAGE_4_COMMON, + al_serdes_reg_write(obj, AL_SRDS_REG_PAGE_4_COMMON, AL_SRDS_REG_TYPE_PMA, SERDES_IREG_FLD_RXCALEYEDIAGFSM_YVALCOARSE_REG_NUM, rxcaleyediagfsm_yvalcoarse_val); - al_serdes_reg_write(obj, grp, AL_SRDS_REG_PAGE_4_COMMON, + al_serdes_reg_write(obj, AL_SRDS_REG_PAGE_4_COMMON, AL_SRDS_REG_TYPE_PMA, SERDES_IREG_FLD_RXCALEYEDIAGFSM_YVALFINE_REG_NUM, rxcaleyediagfsm_yvalfine_val); - al_serdes_lane_write(obj, grp, lane, AL_SRDS_REG_TYPE_PMA, + al_serdes_reg_write(obj, (enum al_serdes_reg_page)lane, AL_SRDS_REG_TYPE_PMA, SERDES_IREG_FLD_RXLOCK2REF_LOCWREN_REG_NUM, rxlock2ref_locwren_val); - al_serdes_lane_write(obj, grp, lane, AL_SRDS_REG_TYPE_PMA, + al_serdes_reg_write(obj, (enum al_serdes_reg_page)lane, AL_SRDS_REG_TYPE_PMA, SERDES_IREG_FLD_RXCAL_LOCWREN_REG_NUM, rxcal_locwren_val); - al_serdes_lane_write(obj, grp, lane, AL_SRDS_REG_TYPE_PMA, + al_serdes_reg_write(obj, (enum al_serdes_reg_page)lane, AL_SRDS_REG_TYPE_PMA, SERDES_IREG_FLD_RXCALROAMYADJUST_LOCWREN_REG_NUM, rxcalroamyadjust_locwren_val); - al_serdes_lane_write(obj, grp, lane, AL_SRDS_REG_TYPE_PMA, + al_serdes_reg_write(obj, (enum al_serdes_reg_page)lane, AL_SRDS_REG_TYPE_PMA, SERDES_IREG_FLD_RXLOCK2REF_OVREN_REG_NUM, rxlock2ref_ovren_val); return 0; } -void al_serdes_sris_config( - struct al_serdes_obj *obj, - enum al_serdes_group grp, - struct al_serdes_sris_params *params) +static void al_serdes_sris_config( + struct al_serdes_grp_obj *obj, + void *sris_params) { - struct al_serdes_group_info *grp_info = &obj->grp_info[grp]; + struct al_serdes_sris_params *params = sris_params; - al_serdes_reg_write(obj, grp, AL_SRDS_REG_PAGE_4_COMMON, AL_SRDS_REG_TYPE_PMA, + al_serdes_reg_write(obj, AL_SRDS_REG_PAGE_4_COMMON, AL_SRDS_REG_TYPE_PMA, SERDES_IREG_FLD_PPMDRIFTCOUNT1_REG_NUM, (params->ppm_drift_count & AL_FIELD_MASK(7, 0)) >> 0); - al_serdes_reg_write(obj, grp, AL_SRDS_REG_PAGE_4_COMMON, AL_SRDS_REG_TYPE_PMA, + al_serdes_reg_write(obj, AL_SRDS_REG_PAGE_4_COMMON, AL_SRDS_REG_TYPE_PMA, SERDES_IREG_FLD_PPMDRIFTCOUNT2_REG_NUM, (params->ppm_drift_count & AL_FIELD_MASK(15, 8)) >> 8); - al_serdes_reg_write(obj, grp, AL_SRDS_REG_PAGE_4_COMMON, AL_SRDS_REG_TYPE_PMA, + al_serdes_reg_write(obj, AL_SRDS_REG_PAGE_4_COMMON, AL_SRDS_REG_TYPE_PMA, SERDES_IREG_FLD_PPMDRIFTMAX1_REG_NUM, (params->ppm_drift_max & AL_FIELD_MASK(7, 0)) >> 0); - al_serdes_reg_write(obj, grp, AL_SRDS_REG_PAGE_4_COMMON, AL_SRDS_REG_TYPE_PMA, + al_serdes_reg_write(obj, AL_SRDS_REG_PAGE_4_COMMON, AL_SRDS_REG_TYPE_PMA, SERDES_IREG_FLD_PPMDRIFTMAX2_REG_NUM, (params->ppm_drift_max & AL_FIELD_MASK(15, 8)) >> 8); - al_serdes_reg_write(obj, grp, AL_SRDS_REG_PAGE_4_COMMON, AL_SRDS_REG_TYPE_PMA, + al_serdes_reg_write(obj, AL_SRDS_REG_PAGE_4_COMMON, AL_SRDS_REG_TYPE_PMA, SERDES_IREG_FLD_SYNTHPPMDRIFTMAX1_REG_NUM, (params->synth_ppm_drift_max & AL_FIELD_MASK(7, 0)) >> 0); - al_serdes_reg_write(obj, grp, AL_SRDS_REG_PAGE_4_COMMON, AL_SRDS_REG_TYPE_PMA, + al_serdes_reg_write(obj, AL_SRDS_REG_PAGE_4_COMMON, AL_SRDS_REG_TYPE_PMA, SERDES_IREG_FLD_SYNTHPPMDRIFTMAX2_REG_NUM, (params->synth_ppm_drift_max & AL_FIELD_MASK(15, 8)) >> 8); - al_serdes_grp_reg_masked_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON, AL_SRDS_REG_TYPE_PCS, + al_serdes_grp_reg_masked_write(obj, AL_SRDS_REG_PAGE_4_COMMON, AL_SRDS_REG_TYPE_PCS, SERDES_IREG_FLD_PCS_EBUF_FULL_D2R1_REG_NUM, SERDES_IREG_FLD_PCS_EBUF_FULL_D2R1_REG_MASK, (params->full_d2r1) << SERDES_IREG_FLD_PCS_EBUF_FULL_D2R1_REG_SHIFT); - al_serdes_grp_reg_masked_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON, AL_SRDS_REG_TYPE_PCS, + al_serdes_grp_reg_masked_write(obj, AL_SRDS_REG_PAGE_4_COMMON, AL_SRDS_REG_TYPE_PCS, SERDES_IREG_FLD_PCS_EBUF_FULL_PCIE_G3_REG_NUM, SERDES_IREG_FLD_PCS_EBUF_FULL_PCIE_G3_REG_MASK, (params->full_pcie_g3) << SERDES_IREG_FLD_PCS_EBUF_FULL_PCIE_G3_REG_SHIFT); - al_serdes_grp_reg_masked_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON, AL_SRDS_REG_TYPE_PCS, + al_serdes_grp_reg_masked_write(obj, AL_SRDS_REG_PAGE_4_COMMON, AL_SRDS_REG_TYPE_PCS, SERDES_IREG_FLD_PCS_EBUF_RD_THRESHOLD_D2R1_REG_NUM, SERDES_IREG_FLD_PCS_EBUF_RD_THRESHOLD_D2R1_REG_MASK, (params->rd_threshold_d2r1) << SERDES_IREG_FLD_PCS_EBUF_RD_THRESHOLD_D2R1_REG_SHIFT); - al_serdes_grp_reg_masked_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON, AL_SRDS_REG_TYPE_PCS, + al_serdes_grp_reg_masked_write(obj, AL_SRDS_REG_PAGE_4_COMMON, AL_SRDS_REG_TYPE_PCS, SERDES_IREG_FLD_PCS_EBUF_RD_THRESHOLD_PCIE_G3_REG_NUM, SERDES_IREG_FLD_PCS_EBUF_RD_THRESHOLD_PCIE_G3_REG_MASK, (params->rd_threshold_pcie_g3) << SERDES_IREG_FLD_PCS_EBUF_RD_THRESHOLD_PCIE_G3_REG_SHIFT); } + +/******************************************************************************/ +/******************************************************************************/ +static void al_serdes_dcgain_set( + struct al_serdes_grp_obj *obj, + uint8_t dcgain) +{ + al_serdes_grp_reg_masked_write(obj, + AL_SRDS_REG_PAGE_4_COMMON, + AL_SRDS_REG_TYPE_PMA, + SERDES_IREG_FLD_RXEQ_DCGAIN_LUP0_REG_NUM, + SERDES_IREG_FLD_RXEQ_DCGAIN_LUP0_MASK, + (dcgain << SERDES_IREG_FLD_RXEQ_DCGAIN_LUP0_SHIFT)); +} + + +/******************************************************************************/ +/******************************************************************************/ +int al_serdes_hssp_handle_init( + void __iomem *serdes_regs_base, + struct al_serdes_grp_obj *obj) +{ + al_dbg( + "%s(%p, %p)\n", + __func__, + serdes_regs_base, + obj); + + al_memset(obj, 0, sizeof(struct al_serdes_grp_obj)); + + obj->regs_base = (struct al_serdes_regs *)serdes_regs_base; + obj->type_get = al_serdes_hssp_type_get; + obj->reg_read = al_serdes_reg_read; + obj->reg_write = al_serdes_reg_write; + obj->bist_overrides_enable = AL_SRDS_ADV_SRVC(al_serdes_bist_overrides_enable); + obj->bist_overrides_disable = AL_SRDS_ADV_SRVC(al_serdes_bist_overrides_disable); + obj->rx_rate_change = AL_SRDS_ADV_SRVC(al_serdes_rx_rate_change); + obj->rx_rate_change_sw_flow_en = AL_SRDS_ADV_SRVC(al_serdes_lane_rx_rate_change_sw_flow_en); + obj->rx_rate_change_sw_flow_dis = + AL_SRDS_ADV_SRVC(al_serdes_lane_rx_rate_change_sw_flow_dis); + obj->pcie_rate_override_is_enabled = + AL_SRDS_ADV_SRVC(al_serdes_lane_pcie_rate_override_is_enabled); + obj->pcie_rate_override_enable_set = + AL_SRDS_ADV_SRVC(al_serdes_lane_pcie_rate_override_enable_set); + obj->pcie_rate_get = AL_SRDS_ADV_SRVC(al_serdes_lane_pcie_rate_get); + obj->pcie_rate_set = AL_SRDS_ADV_SRVC(al_serdes_lane_pcie_rate_set); + obj->group_pm_set = AL_SRDS_ADV_SRVC(al_serdes_group_pm_set); + obj->lane_pm_set = AL_SRDS_ADV_SRVC(al_serdes_lane_pm_set); + obj->pma_hard_reset_group = AL_SRDS_ADV_SRVC(al_serdes_pma_hard_reset_group); + obj->pma_hard_reset_lane = AL_SRDS_ADV_SRVC(al_serdes_pma_hard_reset_lane); + obj->loopback_control = AL_SRDS_ADV_SRVC(al_serdes_loopback_control); + obj->bist_pattern_select = AL_SRDS_ADV_SRVC(al_serdes_bist_pattern_select); + obj->bist_tx_enable = AL_SRDS_ADV_SRVC(al_serdes_bist_tx_enable); + obj->bist_tx_err_inject = AL_SRDS_ADV_SRVC(al_serdes_bist_tx_err_inject); + obj->bist_rx_enable = AL_SRDS_ADV_SRVC(al_serdes_bist_rx_enable); + obj->bist_rx_status = AL_SRDS_ADV_SRVC(al_serdes_bist_rx_status); + obj->tx_deemph_preset = AL_SRDS_ADV_SRVC(al_serdes_tx_deemph_preset); + obj->tx_deemph_inc = AL_SRDS_ADV_SRVC(al_serdes_tx_deemph_inc); + obj->tx_deemph_dec = AL_SRDS_ADV_SRVC(al_serdes_tx_deemph_dec); + obj->eye_measure_run = AL_SRDS_ADV_SRVC(al_serdes_eye_measure_run); + obj->eye_diag_sample = AL_SRDS_ADV_SRVC(al_serdes_eye_diag_sample); + obj->signal_is_detected = AL_SRDS_ADV_SRVC(al_serdes_signal_is_detected); + obj->tx_advanced_params_set = AL_SRDS_ADV_SRVC(al_serdes_tx_advanced_params_set); + obj->tx_advanced_params_get = AL_SRDS_ADV_SRVC(al_serdes_tx_advanced_params_get); + obj->rx_advanced_params_set = AL_SRDS_ADV_SRVC(al_serdes_rx_advanced_params_set); + obj->rx_advanced_params_get = AL_SRDS_ADV_SRVC(al_serdes_rx_advanced_params_get); + obj->mode_set_sgmii = AL_SRDS_ADV_SRVC(al_serdes_mode_set_sgmii); + obj->mode_set_kr = AL_SRDS_ADV_SRVC(al_serdes_mode_set_kr); + obj->rx_equalization = AL_SRDS_ADV_SRVC(al_serdes_rx_equalization); + obj->calc_eye_size = AL_SRDS_ADV_SRVC(al_serdes_calc_eye_size); + obj->sris_config = AL_SRDS_ADV_SRVC(al_serdes_sris_config); + obj->dcgain_set = AL_SRDS_ADV_SRVC(al_serdes_dcgain_set); + + return 0; +} diff --git a/al_hal_serdes.h b/al_hal_serdes.h index 37aec839b2f..e69de29bb2d 100644 --- a/al_hal_serdes.h +++ b/al_hal_serdes.h @@ -1,1125 +0,0 @@ -/*- -******************************************************************************* -Copyright (C) 2015 Annapurna Labs Ltd. - -This file may be licensed under the terms of the Annapurna Labs Commercial -License Agreement. - -Alternatively, this file can be distributed under the terms of the GNU General -Public License V2 as published by the Free Software Foundation and can be -found at http://www.gnu.org/licenses/gpl-2.0.html - -Alternatively, redistribution and use in source and binary forms, with or -without modification, are permitted provided that the following conditions are -met: - - * Redistributions of source code must retain the above copyright notice, -this list of conditions and the following disclaimer. - - * Redistributions in binary form must reproduce the above copyright -notice, this list of conditions and the following disclaimer in -the documentation and/or other materials provided with the -distribution. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR -ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON -ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -*******************************************************************************/ - -/** - * @defgroup group_serdes_api API - * SerDes HAL driver API - * @ingroup group_serdes SerDes - * @{ - * - * @file al_hal_serdes.h - * - * @brief Header file for the SerDes HAL driver - * - */ - -#ifndef __AL_HAL_SERDES_H__ -#define __AL_HAL_SERDES_H__ - -#include "al_hal_common.h" - -/* *INDENT-OFF* */ -#ifdef __cplusplus -extern "C" { -#endif -/* *INDENT-ON* */ - -struct al_serdes_obj; - -enum al_serdes_group { - AL_SRDS_GRP_A = 0, - AL_SRDS_GRP_B, - AL_SRDS_GRP_C, - AL_SRDS_GRP_D, - - AL_SRDS_NUM_GROUPS, -}; - -struct al_serdes_group_info { - /* - * Group parent object - filled automatically by al_serdes_handle_init - */ - struct al_serdes_obj *pobj; - - /* - * Group specific register base - filled automatically by - * al_sedres_handle_init - */ - struct al_serdes_regs __iomem *regs_base; -}; - -struct al_serdes_obj { - struct al_serdes_group_info grp_info[AL_SRDS_NUM_GROUPS]; -}; - -enum al_serdes_reg_page { - AL_SRDS_REG_PAGE_0_LANE_0 = 0, - AL_SRDS_REG_PAGE_1_LANE_1, - AL_SRDS_REG_PAGE_2_LANE_2, - AL_SRDS_REG_PAGE_3_LANE_3, - AL_SRDS_REG_PAGE_4_COMMON, - AL_SRDS_REG_PAGE_0123_LANES_0123 = 7, -}; - -enum al_serdes_reg_type { - AL_SRDS_REG_TYPE_PMA = 0, - AL_SRDS_REG_TYPE_PCS, -}; - -enum al_serdes_lane { - AL_SRDS_LANE_0 = AL_SRDS_REG_PAGE_0_LANE_0, - AL_SRDS_LANE_1 = AL_SRDS_REG_PAGE_1_LANE_1, - AL_SRDS_LANE_2 = AL_SRDS_REG_PAGE_2_LANE_2, - AL_SRDS_LANE_3 = AL_SRDS_REG_PAGE_3_LANE_3, - - AL_SRDS_NUM_LANES, - AL_SRDS_LANES_0123 = AL_SRDS_REG_PAGE_0123_LANES_0123, -}; - -/** Serdes loopback mode */ -enum al_serdes_lb_mode { - /** No loopback */ - AL_SRDS_LB_MODE_OFF, - - /** - * Transmits the untimed, partial equalized RX signal out the transmit - * IO pins. - * No clock used (untimed) - */ - AL_SRDS_LB_MODE_PMA_IO_UN_TIMED_RX_TO_TX, - - /** - * Loops back the TX serializer output into the CDR. - * CDR recovered bit clock used (without attenuation) - */ - AL_SRDS_LB_MODE_PMA_INTERNALLY_BUFFERED_SERIAL_TX_TO_RX, - - /** - * Loops back the TX driver IO signal to the RX IO pins - * CDR recovered bit clock used (only through IO) - */ - AL_SRDS_LB_MODE_PMA_SERIAL_TX_IO_TO_RX_IO, - - /** - * Parallel loopback from the PMA receive lane data ports, to the - * transmit lane data ports - * CDR recovered bit clock used - */ - AL_SRDS_LB_MODE_PMA_PARALLEL_RX_TO_TX, - - /** Loops received data after elastic buffer to transmit path */ - AL_SRDS_LB_MODE_PCS_PIPE, - - /** Loops TX data (to PMA) to RX path (instead of PMA data) */ - AL_SRDS_LB_MODE_PCS_NEAR_END, - - /** Loops receive data prior to interface block to transmit path */ - AL_SRDS_LB_MODE_PCS_FAR_END, -}; - -/** Serdes BIST pattern */ -enum al_serdes_bist_pattern { - AL_SRDS_BIST_PATTERN_USER, - AL_SRDS_BIST_PATTERN_PRBS7, - AL_SRDS_BIST_PATTERN_PRBS23, - AL_SRDS_BIST_PATTERN_PRBS31, - AL_SRDS_BIST_PATTERN_CLK1010, -}; - -/** SerDes group rate */ -enum al_serdes_rate { - AL_SRDS_RATE_1_8, - AL_SRDS_RATE_1_4, - AL_SRDS_RATE_1_2, - AL_SRDS_RATE_FULL, -}; - -/** SerDes power mode */ -enum al_serdes_pm { - AL_SRDS_PM_PD, - AL_SRDS_PM_P2, - AL_SRDS_PM_P1, - AL_SRDS_PM_P0S, - AL_SRDS_PM_P0, -}; - -/** SerDes PCIe Rate - values are important for proper behavior */ -enum al_serdes_pcie_rate { - AL_SRDS_PCIE_RATE_GEN1 = 0, - AL_SRDS_PCIE_RATE_GEN2, - AL_SRDS_PCIE_RATE_GEN3, -}; - -/** - * Initializes a SERDES object - * - * @param serdes_regs_base - * The SERDES register file base pointer - * - * @param obj - * An allocated, non initialized object context - * - * - * @return 0 if no error found. - * - */ -int al_serdes_handle_init( - void __iomem *serdes_regs_base, - struct al_serdes_obj *obj); - -/** - * SERDES register read - * - * Reads a SERDES register - * - * @param obj - * The object context - * - * @param grp - * The SERDES group - * - * @param page - * The SERDES register page within the group - * - * @param type - * The SERDES register type (PMA /PCS) - * - * @param offset - * The SERDES register offset (0 - 4095) - * - * @param data - * The read data - * - * - * @return 0 if no error found. - * - */ -int al_serdes_reg_read( - struct al_serdes_obj *obj, - enum al_serdes_group grp, - enum al_serdes_reg_page page, - enum al_serdes_reg_type type, - uint16_t offset, - uint8_t *data); - -/** - * SERDES register write - * - * Writes a SERDES register - * - * @param obj - * The object context - * - * @param grp - * The SERDES group - * - * @param page - * The SERDES register page within the group - * - * @param type - * The SERDES register type (PMA /PCS) - * - * @param offset - * The SERDES register offset (0 - 4095) - * - * @param data - * The data to write - * - * - * @return 0 if no error found. - * - */ -int al_serdes_reg_write( - struct al_serdes_obj *obj, - enum al_serdes_group grp, - enum al_serdes_reg_page page, - enum al_serdes_reg_type type, - uint16_t offset, - uint8_t data); - -/** - * Enable BIST required overrides - * - * @param obj - * The object context - * @param grp - * The SERDES group - * @param rate - * The required speed rate - */ -void al_serdes_bist_overrides_enable( - struct al_serdes_obj *obj, - enum al_serdes_group grp, - enum al_serdes_rate rate); - -/** - * Disable BIST required overrides - * - * @param obj - * The object context - * @param grp - * The SERDES group - * @param rate - * The required speed rate - */ -void al_serdes_bist_overrides_disable( - struct al_serdes_obj *obj, - enum al_serdes_group grp); - -/** - * Rx rate change - * - * @param obj - * The object context - * @param grp - * The SERDES group - * @param rate - * The Rx required rate - */ -void al_serdes_rx_rate_change( - struct al_serdes_obj *obj, - enum al_serdes_group grp, - enum al_serdes_rate rate); - -/** - * SERDES lane Rx rate change software flow enable - * - * @param obj - * The object context - * @param grp - * The SERDES group - * @param lane - * The SERDES lane within the group - */ -void al_serdes_lane_rx_rate_change_sw_flow_en( - struct al_serdes_obj *obj, - enum al_serdes_group grp, - enum al_serdes_lane lane); - -/** - * SERDES lane Rx rate change software flow disable - * - * @param obj - * The object context - * @param grp - * The SERDES group - * @param lane - * The SERDES lane within the group - */ -void al_serdes_lane_rx_rate_change_sw_flow_dis( - struct al_serdes_obj *obj, - enum al_serdes_group grp, - enum al_serdes_lane lane); - -/** - * PCIe lane rate override check - * - * @param obj - * The object context - * @param grp - * The SERDES group - * @param lane - * The SERDES lane within the group - * @returns AL_TRUE if the override is enabled - */ -al_bool al_serdes_lane_pcie_rate_override_is_enabled( - struct al_serdes_obj *obj, - enum al_serdes_group grp, - enum al_serdes_lane lane); - -/** - * PCIe lane rate override control - * - * @param obj - * The object context - * @param grp - * The SERDES group - * @param lane - * The SERDES lane within the group - * @param en - * Enable/disable - */ -void al_serdes_lane_pcie_rate_override_enable_set( - struct al_serdes_obj *obj, - enum al_serdes_group grp, - enum al_serdes_lane lane, - al_bool en); - -/** - * PCIe lane rate get - * - * @param obj - * The object context - * @param grp - * The SERDES group - * @param lane - * The SERDES lane within the group - */ -enum al_serdes_pcie_rate al_serdes_lane_pcie_rate_get( - struct al_serdes_obj *obj, - enum al_serdes_group grp, - enum al_serdes_lane lane); - -/** - * PCIe lane rate set - * - * @param obj - * The object context - * @param grp - * The SERDES group - * @param lane - * The SERDES lane within the group - * @param rate - * The required rate - */ -void al_serdes_lane_pcie_rate_set( - struct al_serdes_obj *obj, - enum al_serdes_group grp, - enum al_serdes_lane lane, - enum al_serdes_pcie_rate rate); - -/** - * SERDES group power mode control - * - * @param obj - * The object context - * @param grp - * The SERDES group - * @param pm - * The required power mode - */ -void al_serdes_group_pm_set( - struct al_serdes_obj *obj, - enum al_serdes_group grp, - enum al_serdes_pm pm); - -/** - * SERDES lane power mode control - * - * @param obj - * The object context - * @param grp - * The SERDES group - * @param lane - * The SERDES lane within the group - * @param rx_pm - * The required RX power mode - * @param tx_pm - * The required TX power mode - */ -void al_serdes_lane_pm_set( - struct al_serdes_obj *obj, - enum al_serdes_group grp, - enum al_serdes_lane lane, - enum al_serdes_pm rx_pm, - enum al_serdes_pm tx_pm); - -/** - * SERDES group PMA hard reset - * - * Controls Serdes group PMA hard reset - * - * @param obj - * The object context - * - * @param grp - * The SERDES group - * - * @param enable - * Enable/disable hard reset - */ -void al_serdes_pma_hard_reset_group( - struct al_serdes_obj *obj, - enum al_serdes_group grp, - al_bool enable); - -/** - * SERDES lane PMA hard reset - * - * Controls Serdes lane PMA hard reset - * - * @param obj - * The object context - * - * @param grp - * The SERDES group - * - * @param lane - * The SERDES lane within the group - * - * @param enable - * Enable/disable hard reset - */ -void al_serdes_pma_hard_reset_lane( - struct al_serdes_obj *obj, - enum al_serdes_group grp, - enum al_serdes_lane lane, - al_bool enable); - -/** - * SERDES loopback control - * - * Controls the loopback - * - * @param obj - * The object context - * - * @param grp - * The SERDES group - * - * @param lane - * The SERDES lane within the group - * - * @param mode - * The requested loopback mode - * - */ -void al_serdes_loopback_control( - struct al_serdes_obj *obj, - enum al_serdes_group grp, - enum al_serdes_lane lane, - enum al_serdes_lb_mode mode); - -/** - * SERDES BIST pattern selection - * - * Selects the BIST pattern to be used - * - * @param obj - * The object context - * - * @param grp - * The SERDES group - * - * @param pattern - * The pattern to set - * - * @param user_data - * The pattern user data (when pattern == AL_SRDS_BIST_PATTERN_USER) - * 80 bits (8 bytes array) - * - */ -void al_serdes_bist_pattern_select( - struct al_serdes_obj *obj, - enum al_serdes_group grp, - enum al_serdes_bist_pattern pattern, - uint8_t *user_data); - -/** - * SERDES BIST TX Enable - * - * Enables/disables TX BIST per lane - * - * @param obj - * The object context - * - * @param grp - * The SERDES group - * - * @param lane - * The SERDES lane within the group - * - * @param enable - * Enable or disable TX BIST - */ -void al_serdes_bist_tx_enable( - struct al_serdes_obj *obj, - enum al_serdes_group grp, - enum al_serdes_lane lane, - al_bool enable); - -/** - * SERDES BIST TX single bit error injection - * - * Injects single bit error during a TX BIST - * - * @param obj - * The object context - * - * @param grp - * The SERDES group - */ -void al_serdes_bist_tx_err_inject( - struct al_serdes_obj *obj, - enum al_serdes_group grp); - -/** - * SERDES BIST RX Enable - * - * Enables/disables RX BIST per lane - * - * @param obj - * The object context - * - * @param grp - * The SERDES group - * - * @param lane - * The SERDES lane within the group - * - * @param enable - * Enable or disable TX BIST - */ -void al_serdes_bist_rx_enable( - struct al_serdes_obj *obj, - enum al_serdes_group grp, - enum al_serdes_lane lane, - al_bool enable); - -/** - * SERDES BIST RX status - * - * Checks the RX BIST status for a specific SERDES lane - * - * @param obj - * The object context - * - * @param grp - * The SERDES group - * - * @param lane - * The SERDES lane within the group - * - * @param is_locked - * An indication whether RX BIST is locked - * - * @param err_cnt_overflow - * An indication whether error count overflow occured - * - * @param err_cnt - * Current bit error count - */ -void al_serdes_bist_rx_status( - struct al_serdes_obj *obj, - enum al_serdes_group grp, - enum al_serdes_lane lane, - al_bool *is_locked, - al_bool *err_cnt_overflow, - uint16_t *err_cnt); - -/** - * SERDES Digital Test Bus - * - * Samples the digital test bus of a specific SERDES lane - * - * @param obj - * The object context - * - * @param grp - * The SERDES group - * - * @param lane - * The SERDES lane within the group - * - * @param sel - * The selected sampling group (0 - 31) - * - * @param sampled_data - * The sampled data (5 bytes array) - * - * - * @return 0 if no error found. - * - */ -int al_serdes_digital_test_bus( - struct al_serdes_obj *obj, - enum al_serdes_group grp, - enum al_serdes_lane lane, - uint8_t sel, - uint8_t *sampled_data); - - -/* KR link training */ -/** - * Set the tx de-emphasis to preset values - * - * @param obj The object context - * - * @param grp The SERDES group - * - * @param lane The SERDES lane within the group - * - */ -void al_serdes_tx_deemph_preset( - struct al_serdes_obj *obj, - enum al_serdes_group grp, - enum al_serdes_lane lane); - -/** - * Tx de-emphasis parameters - */ -enum al_serdes_tx_deemph_param { - AL_SERDES_TX_DEEMP_C_ZERO, /*< c(0) */ - AL_SERDES_TX_DEEMP_C_PLUS, /*< c(1) */ - AL_SERDES_TX_DEEMP_C_MINUS, /*< c(-1) */ -}; - -/** - * Increase tx de-emphasis param. - * - * @param obj The object context - * - * @param grp The SERDES group - * - * @param lane The SERDES lane within the group - * - * @param param which tx de-emphasis to change - * - * @return false in case max is reached. true otherwise. - */ -al_bool al_serdes_tx_deemph_inc( - struct al_serdes_obj *obj, - enum al_serdes_group grp, - enum al_serdes_lane lane, - enum al_serdes_tx_deemph_param param); - -/** - * Decrease tx de-emphasis param. - * - * @param obj The object context - * - * @param grp The SERDES group - * - * @param lane The SERDES lane within the group - * - * @param param which tx de-emphasis to change - * - * @return false in case min is reached. true otherwise. - */ -al_bool al_serdes_tx_deemph_dec( - struct al_serdes_obj *obj, - enum al_serdes_group grp, - enum al_serdes_lane lane, - enum al_serdes_tx_deemph_param param); - -/** - * run Rx eye measurement. - * - * @param obj The object context - * - * @param grp The SERDES group - * - * @param lane The SERDES lane within the group - * - * @param timeout timeout in uSec - * - * @param value Rx eye measurement value - * (0 - completely closed eye, 0xffff - completely open eye). - * - * @return 0 if no error found. - */ -int al_serdes_eye_measure_run( - struct al_serdes_obj *obj, - enum al_serdes_group grp, - enum al_serdes_lane lane, - uint32_t timeout, - unsigned int *value); - -/** - * Eye diagram single sampling - * - * @param obj The object context - * - * @param grp The SERDES group - * - * @param lane The SERDES lane within the group - * - * @param x Sampling X position (0 - 63 --> -1.00 UI ... 1.00 UI) - * - * @param y Sampling Y position (0 - 62 --> 500mV ... -500mV) - * - * @param timeout timeout in uSec - * - * @param value Eye diagram sample value (BER - 0x0000 - 0xffff) - * - * @return 0 if no error found. - */ -int al_serdes_eye_diag_sample( - struct al_serdes_obj *obj, - enum al_serdes_group grp, - enum al_serdes_lane lane, - unsigned int x, - int y, - unsigned int timeout, - unsigned int *value); - -/** - * Check if signal is detected - * - * @param obj The object context - * - * @param grp The SERDES group - * - * @param lane The SERDES lane within the group - * - * @return true if signal is detected. false otherwise. - */ -al_bool al_serdes_signal_is_detected( - struct al_serdes_obj *obj, - enum al_serdes_group grp, - enum al_serdes_lane lane); - - -struct al_serdes_adv_tx_params { - /* - * select the input values location. - * When set to true the values will be taken from the internal registers - * that will be override with the next following parameters. - * When set to false the values will be taken from external pins (the - * other parameters in this case is not needed) - */ - al_bool override; - /* - * Transmit Amplitude control signal. Used to define the full-scale - * maximum swing of the driver. - * 000 - Not Supported - * 001 - 952mVdiff-pkpk - * 010 - 1024mVdiff-pkpk - * 011 - 1094mVdiff-pkpk - * 100 - 1163mVdiff-pkpk - * 101 - 1227mVdiff-pkpk - * 110 - 1283mVdiff-pkpk - * 111 - 1331mVdiff-pkpk - */ - uint8_t amp; - /* Defines the total number of driver units allocated in the driver */ - uint8_t total_driver_units; - /* Defines the total number of driver units allocated to the - * first post-cursor (C+1) tap. */ - uint8_t c_plus_1; - /* Defines the total number of driver units allocated to the - * second post-cursor (C+2) tap. */ - uint8_t c_plus_2; - /* Defines the total number of driver units allocated to the - * first pre-cursor (C-1) tap. */ - uint8_t c_minus_1; - /* TX driver Slew Rate control: - * 00 - 31ps - * 01 - 33ps - * 10 - 68ps - * 11 - 170ps - */ - uint8_t slew_rate; -}; - -struct al_serdes_adv_rx_params { - /* - * select the input values location. - * When set to true the values will be taken from the internal registers - * that will be override with the next following parameters. - * When set to false the values will be taken based in the equalization - * results (the other parameters in this case is not needed) - */ - al_bool override; - /* RX agc high frequency dc gain: - * -3'b000: -3dB - * -3'b001: -2.5dB - * -3'b010: -2dB - * -3'b011: -1.5dB - * -3'b100: -1dB - * -3'b101: -0.5dB - * -3'b110: -0dB - * -3'b111: 0.5dB - */ - uint8_t dcgain; - /* DFE post-shaping tap 3dB frequency - * -3'b000: 684MHz - * -3'b001: 576MHz - * -3'b010: 514MHz - * -3'b011: 435MHz - * -3'b100: 354MHz - * -3'b101: 281MHz - * -3'b110: 199MHz - * -3'b111: 125MHz - */ - uint8_t dfe_3db_freq; - /* DFE post-shaping tap gain - * 0: no pulse shaping tap - * 1: -24mVpeak - * 2: -45mVpeak - * 3: -64mVpeak - * 4: -80mVpeak - * 5: -93mVpeak - * 6: -101mVpeak - * 7: -105mVpeak - */ - uint8_t dfe_gain; - /* DFE first tap gain control - * -4'b0000: +1mVpeak - * -4'b0001: +10mVpeak - * .... - * -4'b0110: +55mVpeak - * -4'b0111: +64mVpeak - * -4'b1000: -1mVpeak - * -4'b1001: -10mVpeak - * .... - * -4'b1110: -55mVpeak - * -4'b1111: -64mVpeak - */ - uint8_t dfe_first_tap_ctrl; - /* DFE second tap gain control - * -4'b0000: +0mVpeak - * -4'b0001: +9mVpeak - * .... - * -4'b0110: +46mVpeak - * -4'b0111: +53mVpeak - * -4'b1000: -0mVpeak - * -4'b1001: -9mVpeak - * .... - * -4'b1110: -46mVpeak - * -4'b1111: -53mVpeak - */ - uint8_t dfe_secound_tap_ctrl; - /* DFE third tap gain control - * -4'b0000: +0mVpeak - * -4'b0001: +7mVpeak - * .... - * -4'b0110: +38mVpeak - * -4'b0111: +44mVpeak - * -4'b1000: -0mVpeak - * -4'b1001: -7mVpeak - * .... - * -4'b1110: -38mVpeak - * -4'b1111: -44mVpeak - */ - uint8_t dfe_third_tap_ctrl; - /* DFE fourth tap gain control - * -4'b0000: +0mVpeak - * -4'b0001: +6mVpeak - * .... - * -4'b0110: +29mVpeak - * -4'b0111: +33mVpeak - * -4'b1000: -0mVpeak - * -4'b1001: -6mVpeak - * .... - * -4'b1110: -29mVpeak - * -4'b1111: -33mVpeak - */ - uint8_t dfe_fourth_tap_ctrl; - /* Low frequency agc gain (att) select - * -3'b000: Disconnected - * -3'b001: -18.5dB - * -3'b010: -12.5dB - * -3'b011: -9dB - * -3'b100: -6.5dB - * -3'b101: -4.5dB - * -3'b110: -2.9dB - * -3'b111: -1.6dB - */ - uint8_t low_freq_agc_gain; - /* Provides a RX Equalizer pre-hint, prior to beginning - * adaptive equalization */ - uint8_t precal_code_sel; - /* High frequency agc boost control - * Min d0: Boost ~4dB - * Max d31: Boost ~20dB - */ - uint8_t high_freq_agc_boost; -}; - -/** - * configure tx advanced parameters - * - * @param obj The object context - * - * @param grp The SERDES group - * - * @param lane The SERDES lane within the group - * - * @param params pointer to the tx parameters - */ -void al_serdes_tx_advanced_params_set(struct al_serdes_obj *obj, - enum al_serdes_group grp, - enum al_serdes_lane lane, - struct al_serdes_adv_tx_params *params); - -/** - * read tx advanced parameters - * - * @param obj The object context - * - * @param grp The SERDES group - * - * @param lane The SERDES lane within the group - * - * @param params pointer to the tx parameters - */ -void al_serdes_tx_advanced_params_get(struct al_serdes_obj *obj, - enum al_serdes_group grp, - enum al_serdes_lane lane, - struct al_serdes_adv_tx_params *params); - -/** - * configure rx advanced parameters - * - * @param obj The object context - * - * @param grp The SERDES group - * - * @param lane The SERDES lane within the group - * - * @param params pointer to the rx parameters - */ -void al_serdes_rx_advanced_params_set(struct al_serdes_obj *obj, - enum al_serdes_group grp, - enum al_serdes_lane lane, - struct al_serdes_adv_rx_params *params); - -/** - * read rx advanced parameters - * - * @param obj The object context - * - * @param grp The SERDES group - * - * @param lane The SERDES lane within the group - * - * @param params pointer to the rx parameters - */ -void al_serdes_rx_advanced_params_get(struct al_serdes_obj *obj, - enum al_serdes_group grp, - enum al_serdes_lane lane, - struct al_serdes_adv_rx_params* params); - -/** - * Switch entire SerDes group to SGMII mode based on 156.25 Mhz reference clock - * - * @param obj The object context - * - * @param grp The SERDES group - */ -void al_serdes_mode_set_sgmii( - struct al_serdes_obj *obj, - enum al_serdes_group grp); - -/** - * Switch entire SerDes group to KR mode based on 156.25 Mhz reference clock - * - * @param obj The object context - * - * @param grp The SERDES group - */ -void al_serdes_mode_set_kr( - struct al_serdes_obj *obj, - enum al_serdes_group grp); - -/** - * performs SerDes HW equalization test and update equalization parameters - * - * @param obj the object context - * - * @param grp the SERDES group - * - * @param lane The SERDES lane within the group - */ -int al_serdes_rx_equalization( - struct al_serdes_obj *obj, - enum al_serdes_group grp, - enum al_serdes_lane lane); - -/** - * performs Rx equalization and compute the width and height of the eye - * - * @param obj the object context - * - * @param grp the SERDES group - * - * @param lane The SERDES lane within the group - * - * @param width the output width of the eye - * - * @param height the output height of the eye - */ -int al_serdes_calc_eye_size( - struct al_serdes_obj *obj, - enum al_serdes_group grp, - enum al_serdes_lane lane, - int* width, - int* height); - -/** - * SRIS parameters - */ -struct al_serdes_sris_params { - /* Controls the frequency accuracy threshold (ppm) for lock detection CDR */ - uint16_t ppm_drift_count; - /* Controls the frequency accuracy threshold (ppm) for lock detection in the CDR */ - uint16_t ppm_drift_max; - /* Controls the frequency accuracy threshold (ppm) for lock detection in PLL */ - uint16_t synth_ppm_drift_max; - /* Elastic buffer full threshold for PCIE modes: GEN1/GEN2 */ - uint8_t full_d2r1; - /* Elastic buffer full threshold for PCIE modes: GEN3 */ - uint8_t full_pcie_g3; - /* Elastic buffer midpoint threshold. - * Sets the depth of the buffer while in PCIE mode, GEN1/GEN2 - */ - uint8_t rd_threshold_d2r1; - /* Elastic buffer midpoint threshold. - * Sets the depth of the buffer while in PCIE mode, GEN3 - */ - uint8_t rd_threshold_pcie_g3; -}; - -/** - * SRIS: Separate Refclk Independent SSC (Spread Spectrum Clocking) - * Currently available only for PCIe interfaces. - * When working with local Refclk, same SRIS configuration in both serdes sides - * (EP and RC in PCIe interface) is required. - * - * performs SRIS configuration according to params - * - * @param obj the object context - * - * @param grp the SERDES group - * - * @param params the SRIS parameters - */ -void al_serdes_sris_config( - struct al_serdes_obj *obj, - enum al_serdes_group grp, - struct al_serdes_sris_params *params); - -/* *INDENT-OFF* */ -#ifdef __cplusplus -} -#endif - -/* *INDENT-ON* */ -#endif /* __AL_SRDS__ */ - -/** @} end of SERDES group */ - diff --git a/al_hal_serdes_25g.c b/al_hal_serdes_25g.c new file mode 100644 index 00000000000..68767e557fd --- /dev/null +++ b/al_hal_serdes_25g.c @@ -0,0 +1,1951 @@ +/******************************************************************************* +Copyright (C) 2015 Annapurna Labs Ltd. + +This file may be licensed under the terms of the Annapurna Labs Commercial +License Agreement. + +Alternatively, this file can be distributed under the terms of the GNU General +Public License V2 as published by the Free Software Foundation and can be +found at http://www.gnu.org/licenses/gpl-2.0.html + +Alternatively, redistribution and use in source and binary forms, with or +without modification, are permitted provided that the following conditions are +met: + + * Redistributions of source code must retain the above copyright notice, +this list of conditions and the following disclaimer. + + * Redistributions in binary form must reproduce the above copyright +notice, this list of conditions and the following disclaimer in +the documentation and/or other materials provided with the +distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +*******************************************************************************/ + +#include "al_hal_serdes_25g.h" +#include "al_hal_serdes_25g_regs.h" +#include "al_hal_serdes_25g_internal_regs.h" + +#define AL_SERDES_MB_MAX_DATA_LEN 8 + +#define AL_SERDES_25G_WAIT_FOR_READY_TO 200 +#define AL_SERDES_25G_RESET_TO 100 +#define AL_SERDES_25G_RESET_NUM_RETRIES 5 + +#if (!defined(AL_SERDES_BASIC_SERVICES_ONLY)) || (AL_SERDES_BASIC_SERVICES_ONLY == 0) +#define AL_SRDS_ADV_SRVC(func) func +#else +static void al_serdes_hssp_stub_func(void) +{ + al_err("%s: not implemented service called!\n", __func__); +} + +#define AL_SRDS_ADV_SRVC(func) ((typeof(func) *)al_serdes_hssp_stub_func) +#endif + +/******************************************************************************/ +/******************************************************************************/ +static enum al_serdes_type al_serdes_25g_type_get(void) +{ + return AL_SRDS_TYPE_25G; +} + +/******************************************************************************/ +/******************************************************************************/ +static int al_serdes_25g_reg_read( + struct al_serdes_grp_obj *obj, + enum al_serdes_reg_page page, + enum al_serdes_reg_type type, + uint16_t offset, + uint8_t *data) +{ + struct al_serdes_c_regs __iomem *regs_base = obj->regs_base; + uint32_t addr = 0; + + al_dbg("%s(%p, %d, %d, %u)\n", __func__, obj, page, type, offset); + + al_assert(obj); + al_assert(data); + + switch (page) { + case AL_SRDS_REG_PAGE_TOP: + addr = (SERDES_25G_TOP_BASE + offset); + break; + case AL_SRDS_REG_PAGE_4_COMMON: + addr = (SERDES_25G_CM_BASE + offset); + break; + case AL_SRDS_REG_PAGE_0_LANE_0: + case AL_SRDS_REG_PAGE_1_LANE_1: + addr = (SERDES_25G_LANE_BASE + (page * SERDES_25G_LANE_SIZE) + offset); + break; + default: + al_err("%s: wrong serdes type %d\n", __func__, type); + return -1; + } + + al_reg_write32(®s_base->gen.reg_addr, addr); + *data = al_reg_read32(®s_base->gen.reg_data); + + al_dbg("%s: return(%u)\n", __func__, *data); + + return 0; +} + +static int al_serdes_25g_reg_write( + struct al_serdes_grp_obj *obj, + enum al_serdes_reg_page page, + enum al_serdes_reg_type type, + uint16_t offset, + uint8_t data) +{ + struct al_serdes_c_regs __iomem *regs_base = obj->regs_base; + uint32_t addr = 0; + + al_dbg("%s(%p, %d, %d, %u)\n", __func__, obj, page, type, offset); + + al_assert(obj); + + switch (page) { + case AL_SRDS_REG_PAGE_TOP: + addr = (SERDES_25G_TOP_BASE + offset); + break; + case AL_SRDS_REG_PAGE_4_COMMON: + addr = (SERDES_25G_CM_BASE + offset); + break; + case AL_SRDS_REG_PAGE_0_LANE_0: + case AL_SRDS_REG_PAGE_1_LANE_1: + addr = (SERDES_25G_LANE_BASE + (page * SERDES_25G_LANE_SIZE) + offset); + break; + default: + al_err("%s: wrong serdes type %d\n", __func__, type); + return -1; + } + + al_reg_write32(®s_base->gen.reg_addr, addr); + al_reg_write32(®s_base->gen.reg_data, (data | SERDES_C_GEN_REG_DATA_STRB_MASK)); + + al_dbg("%s: write(%u)\n", __func__, data); + + return 0; +} + +/******************************************************************************/ +/******************************************************************************/ +static int al_serdes_25g_reg_masked_read( + struct al_serdes_grp_obj *obj, + enum al_serdes_reg_page page, + uint16_t offset, + uint8_t mask, + uint8_t shift, + uint8_t *data) +{ + uint8_t val; + int status = 0; + + status = al_serdes_25g_reg_read(obj, page, 0, offset, &val); + if (status) + return status; + + *data = AL_REG_FIELD_GET(val, mask, shift); + + return 0; +} + +static int al_serdes_25g_reg_masked_write( + struct al_serdes_grp_obj *obj, + enum al_serdes_reg_page page, + uint16_t offset, + uint8_t mask, + uint8_t shift, + uint8_t data) +{ + uint8_t val; + int status = 0; + + status = al_serdes_25g_reg_read(obj, page, 0, offset, &val); + if (status) + return status; + + val &= (~mask); + val |= (data << shift); + return al_serdes_25g_reg_write(obj, page, 0, offset, val); +} + +/******************************************************************************/ +/******************************************************************************/ +#define SERDES_25G_MB_RESP_BYTES 16 +#define SERDES_25G_MB_TIMEOUT 5000000 /* uSec */ + +static int al_serdes_25g_mailbox_send_cmd( + struct al_serdes_grp_obj *obj, + uint8_t cmd, + uint8_t *data, + uint8_t data_len) +{ + uint8_t val; + int i; + uint32_t timeout = SERDES_25G_MB_TIMEOUT; + + if (data_len > AL_SERDES_MB_MAX_DATA_LEN) { + al_err("Cannot send command, data too long\n"); + return -1; + } + + /* Wait for CMD_FLAG to clear */ + while(1) { + al_serdes_25g_reg_read(obj, AL_SRDS_REG_PAGE_TOP, 0, + SERDES_25G_TOP_CMD_FLAG_ADDR, &val); + if (val == 0) + break; + + if (timeout == 0) { + al_err("%s: timeout occurred waiting to CMD_FLAG\n", __func__); + return -1; + } + + timeout--; + al_udelay(1); + } + + for (i = 0; i < data_len; i++) { + al_serdes_25g_reg_write(obj, AL_SRDS_REG_PAGE_TOP, 0, + (SERDES_25G_TOP_CMD_DATA0_ADDR + i), data[i]); + } + + /* this write will set CMD_FLAG automatically */ + al_serdes_25g_reg_write(obj, AL_SRDS_REG_PAGE_TOP, 0, SERDES_25G_TOP_CMD_ADDR, cmd); + + return 0; +} + +static int al_serdes_25g_mailbox_recv_rsp( + struct al_serdes_grp_obj *obj, + uint8_t *rsp_code, + uint8_t *data, + uint8_t *data_len) +{ + uint8_t val; + int i; + uint32_t timeout = SERDES_25G_MB_TIMEOUT; + + /* wait for RSP_FLAG to set */ + while(1) { + al_serdes_25g_reg_read(obj, AL_SRDS_REG_PAGE_TOP, 0, + SERDES_25G_TOP_RSP_FLAG_ADDR, &val); + if (val == 0x1) + break; + + if (timeout == 0) { + al_err("%s: timeout occurred waiting to RSP_FLAG\n", __func__); + *data_len = 0; + return -1; + } + + timeout--; + al_udelay(1); + } + + /* Grab the response code and data */ + al_serdes_25g_reg_read(obj, AL_SRDS_REG_PAGE_TOP, 0, + SERDES_25G_TOP_RSP_ADDR, rsp_code); + + for (i = 0; i < SERDES_25G_MB_RESP_BYTES; i++) { + al_serdes_25g_reg_read(obj, AL_SRDS_REG_PAGE_TOP, 0, + (SERDES_25G_TOP_RSP_DATA0_ADDR + i), &data[i]); + } + + /* clear the RSP_FLAG (write 1 to clear) */ + al_serdes_25g_reg_write(obj, AL_SRDS_REG_PAGE_TOP, 0, + SERDES_25G_TOP_RSP_FLAG_ADDR, 0x1); + + *data_len = SERDES_25G_MB_RESP_BYTES; + + return 0; +} + +/******************************************************************************/ +/******************************************************************************/ +static void al_serdes_25g_bist_rx_enable( + struct al_serdes_grp_obj *obj, + enum al_serdes_lane lane, + al_bool enable) +{ + if (enable) { + switch (lane) { + case 0: + al_serdes_25g_reg_masked_write( + obj, + AL_SRDS_REG_PAGE_TOP, + SERDES_25G_TOP_CLOCK_LN0_CLK_RX_ADDR, + SERDES_25G_TOP_CLOCK_LN0_CLK_RX_CTRL_CG_EN_MASK, + SERDES_25G_TOP_CLOCK_LN0_CLK_RX_CTRL_CG_EN_SHIFT, + 0x1); + al_serdes_25g_reg_masked_write( + obj, + AL_SRDS_REG_PAGE_TOP, + SERDES_25G_TOP_CLOCK_LN0_CLK_RX_ADDR, + SERDES_25G_TOP_CLOCK_LN0_CLK_RX_CTRL_BIST_CG_EN_MASK, + SERDES_25G_TOP_CLOCK_LN0_CLK_RX_CTRL_BIST_CG_EN_SHIFT, + 0x1); + break; + case 1: + al_serdes_25g_reg_masked_write( + obj, + AL_SRDS_REG_PAGE_TOP, + SERDES_25G_TOP_CLOCK_LN1_CLK_RX_ADDR, + SERDES_25G_TOP_CLOCK_LN1_CLK_RX_CTRL_CG_EN_MASK, + SERDES_25G_TOP_CLOCK_LN1_CLK_RX_CTRL_CG_EN_SHIFT, + 0x1); + + al_serdes_25g_reg_masked_write( + obj, + AL_SRDS_REG_PAGE_TOP, + SERDES_25G_TOP_CLOCK_LN1_CLK_RX_ADDR, + SERDES_25G_TOP_CLOCK_LN1_CLK_RX_CTRL_BIST_CG_EN_MASK, + SERDES_25G_TOP_CLOCK_LN1_CLK_RX_CTRL_BIST_CG_EN_SHIFT, + 0x1); + break; + default: + al_err("%s: Wrong serdes lane %d\n", __func__, lane); + return; + } + + al_serdes_25g_reg_masked_write( + obj, + (enum al_serdes_reg_page)lane, + SERDES_25G_LANE_RX_BIST_LOSS_LOCK_CTRL4_ADDR, + SERDES_25G_LANE_RX_BIST_LOSS_LOCK_CTRL4_STOP_ON_LOSS_LOCK_MASK, + SERDES_25G_LANE_RX_BIST_LOSS_LOCK_CTRL4_STOP_ON_LOSS_LOCK_SHIFT, + 0); + al_serdes_25g_reg_masked_write( + obj, + (enum al_serdes_reg_page)lane, + SERDES_25G_LANE_RX_BIST_CTRL_ADDR, + SERDES_25G_LANE_RX_BIST_CTRL_EN_MASK, + SERDES_25G_LANE_RX_BIST_CTRL_EN_SHIFT, + 1); + al_serdes_25g_reg_masked_write( + obj, + (enum al_serdes_reg_page)lane, + SERDES_25G_LANE_RX_BIST_CTRL_ADDR, + SERDES_25G_LANE_RX_BIST_CTRL_PATTERN_SEL_MASK, + SERDES_25G_LANE_RX_BIST_CTRL_PATTERN_SEL_SHIFT, + 6); + } else { + /* clear counters */ + al_serdes_25g_reg_masked_write( + obj, + (enum al_serdes_reg_page)lane, + SERDES_25G_LANE_RX_BIST_CTRL_ADDR, + SERDES_25G_LANE_RX_BIST_CTRL_CLEAR_BER_MASK, + SERDES_25G_LANE_RX_BIST_CTRL_CLEAR_BER_SHIFT, + 1); + + al_serdes_25g_reg_masked_write( + obj, + (enum al_serdes_reg_page)lane, + SERDES_25G_LANE_RX_BIST_CTRL_ADDR, + SERDES_25G_LANE_RX_BIST_CTRL_CLEAR_BER_MASK, + SERDES_25G_LANE_RX_BIST_CTRL_CLEAR_BER_SHIFT, + 0); + + al_msleep(AL_SERDES_25G_WAIT_FOR_READY_TO); + + /* disable */ + al_serdes_25g_reg_masked_write( + obj, + (enum al_serdes_reg_page)lane, + SERDES_25G_LANE_RX_BIST_CTRL_ADDR, + SERDES_25G_LANE_RX_BIST_CTRL_EN_MASK, + SERDES_25G_LANE_RX_BIST_CTRL_EN_SHIFT, + 0); + } +} + +// TODO: [Guy] change API to be per lane. +static void al_serdes_25g_bist_pattern_select( + struct al_serdes_grp_obj *obj, + enum al_serdes_bist_pattern pattern, + uint8_t *user_data) +{ + enum al_serdes_lane lane; + uint8_t val = 0; + + switch (pattern) { + case AL_SRDS_BIST_PATTERN_USER: + al_assert(user_data); + val = SERDES_25G_LANE_TX_BIST_CTRL_PATTERN_PRBS_USER; + break; + case AL_SRDS_BIST_PATTERN_PRBS7: + val = SERDES_25G_LANE_TX_BIST_CTRL_PATTERN_PRBS7; + break; + case AL_SRDS_BIST_PATTERN_PRBS23: + val = SERDES_25G_LANE_TX_BIST_CTRL_PATTERN_PRBS23; + break; + case AL_SRDS_BIST_PATTERN_PRBS31: + val = SERDES_25G_LANE_TX_BIST_CTRL_PATTERN_PRBS31; + break; + case AL_SRDS_BIST_PATTERN_CLK1010: + default: + al_err("%s: invalid pattern (%d)\n", __func__, pattern); + al_assert(0); + } + + for (lane = AL_SRDS_LANE_0; lane <= AL_SRDS_LANE_1; lane++) { + if (pattern == AL_SRDS_BIST_PATTERN_USER) { + int i; + + for (i = 0; i < SERDES_25G_LANE_TX_BIST_UDP_NUM_BYTES; i++) + al_serdes_25g_reg_write( + obj, + (enum al_serdes_reg_page)lane, + 0, + SERDES_25G_LANE_TX_BIST_UDP_ADDR(i), + user_data[i]); + } + + al_serdes_25g_reg_masked_write( + obj, + (enum al_serdes_reg_page)lane, + SERDES_25G_LANE_TX_BIST_CTRL_ADDR, + SERDES_25G_LANE_TX_BIST_CTRL_PATTERN_SEL_MASK, + SERDES_25G_LANE_TX_BIST_CTRL_PATTERN_SEL_SHIFT, + val); + } +} + +static void al_serdes_25g_bist_tx_enable( + struct al_serdes_grp_obj *obj, + enum al_serdes_lane lane, + al_bool enable) +{ + if (enable) { + al_serdes_25g_reg_masked_write( + obj, + (enum al_serdes_reg_page)lane, + SERDES_25G_LANE_TX_BIST_CTRL_ADDR, + SERDES_25G_LANE_TX_BIST_CTRL_EN_MASK, + SERDES_25G_LANE_TX_BIST_CTRL_EN_SHIFT, + 0x1); + al_serdes_25g_reg_masked_write( + obj, + (enum al_serdes_reg_page)lane, + SERDES_25G_LANE_TOP_DPL_TXDP_CTRL1_ADDR, + SERDES_25G_LANE_TOP_DPL_TXDP_CTRL1_DMUX_TXA_SEL_MASK, + SERDES_25G_LANE_TOP_DPL_TXDP_CTRL1_DMUX_TXA_SEL_SHIFT, + 0x2); + + switch (lane) { + case AL_SRDS_LANE_0: + al_serdes_25g_reg_masked_write( + obj, + AL_SRDS_REG_PAGE_TOP, + SERDES_25G_TOP_CLOCK_LN0_CLK_TX_ADDR, + SERDES_25G_TOP_CLOCK_LN0_CLK_TX_CTRL_BIST_CG_EN_MASK, + SERDES_25G_TOP_CLOCK_LN0_CLK_TX_CTRL_BIST_CG_EN_SHIFT, + 0x1); + break; + case AL_SRDS_LANE_1: + al_serdes_25g_reg_masked_write( + obj, + AL_SRDS_REG_PAGE_TOP, + SERDES_25G_TOP_CLOCK_LN1_CLK_TX_ADDR, + SERDES_25G_TOP_CLOCK_LN1_CLK_TX_CTRL_BIST_CG_EN_MASK, + SERDES_25G_TOP_CLOCK_LN1_CLK_TX_CTRL_BIST_CG_EN_SHIFT, + 0x1); + break; + default: + al_err("%s: Wrong serdes lane %d\n", __func__, lane); + return; + } + } else { + al_serdes_25g_reg_masked_write( + obj, + (enum al_serdes_reg_page)lane, + SERDES_25G_LANE_TX_BIST_CTRL_ADDR, + SERDES_25G_LANE_TX_BIST_CTRL_EN_MASK, + SERDES_25G_LANE_TX_BIST_CTRL_EN_SHIFT, + 0); + } + +} + +static void al_serdes_25g_bist_rx_status( + struct al_serdes_grp_obj *obj, + enum al_serdes_lane lane, + al_bool *is_locked, + al_bool *err_cnt_overflow, + uint32_t *err_cnt) +{ + uint8_t status; + uint8_t err1; + uint8_t err2; + uint8_t err3; + + al_serdes_25g_reg_masked_read( + obj, + (enum al_serdes_reg_page)lane, + SERDES_25G_LANE_RX_BIST_STATUS_ADDR, + SERDES_25G_LANE_RX_BIST_STATUS_STATE_MASK, + SERDES_25G_LANE_RX_BIST_STATUS_STATE_SHIFT, + &status); + + if (status != 3) { + *is_locked = AL_FALSE; + return; + } + + *is_locked = AL_TRUE; + *err_cnt_overflow = AL_FALSE; + + al_serdes_25g_reg_masked_read( + obj, + (enum al_serdes_reg_page)lane, + SERDES_25G_LANE_RX_BIST_BER_STATUS0_ADDR, + SERDES_25G_LANE_RX_BIST_BER_STATUS0_BIT_ERROR_COUNT_7_0_MASK, + SERDES_25G_LANE_RX_BIST_BER_STATUS0_BIT_ERROR_COUNT_7_0_SHIFT, + &err1); + + al_serdes_25g_reg_masked_read( + obj, + (enum al_serdes_reg_page)lane, + SERDES_25G_LANE_RX_BIST_BER_STATUS1_ADDR, + SERDES_25G_LANE_RX_BIST_BER_STATUS1_BIT_ERROR_COUNT_15_8_MASK, + SERDES_25G_LANE_RX_BIST_BER_STATUS1_BIT_ERROR_COUNT_15_8_SHIFT, + &err2); + + al_serdes_25g_reg_masked_read( + obj, + (enum al_serdes_reg_page)lane, + SERDES_25G_LANE_RX_BIST_BER_STATUS2_ADDR, + SERDES_25G_LANE_RX_BIST_BER_STATUS2_BIT_ERROR_COUNT_23_16_MASK, + SERDES_25G_LANE_RX_BIST_BER_STATUS2_BIT_ERROR_COUNT_23_16_SHIFT, + &err3); + + *err_cnt = (err1 + (err2 << 8) + (err3 << 16)); +} + +#define SERDES_MB_CMD_SWING_CFG 0x83 +#define SERDES_MB_CMD_SAMPLES_COUNT 0x84 +#define SERDES_MB_CMD_START_MEASURE 0x82 + +#define SERDES_MB_RSP_CODE_0 0 +#define SERDES_MB_RSP_CODE_1 1 +#define SERDES_MB_RSP_CODE_2 2 + +static int al_serdes_25g_eye_diag_run( + struct al_serdes_grp_obj *obj, + enum al_serdes_lane lane, + int x_start, + int x_stop, + unsigned int x_step, + int y_start, + int y_stop, + unsigned int y_step, + uint64_t ber_target, + uint64_t *buf, + uint32_t buf_size) +{ + int rc; + uint8_t rsp_code; + uint8_t data[16]; + uint8_t data_len; + uint32_t total_bits; + uint8_t bits_left_curr_sample; + uint8_t bits_left_curr_byte; + uint32_t byte = 0; + uint32_t x = 0; + uint32_t x_samples = (((x_stop - x_start) / x_step) + 1); + uint32_t y = 0; + uint32_t y_samples = (((y_stop - y_start) / y_step) + 1); + uint8_t sample_width = (64 - __builtin_clzl(ber_target)); + uint8_t msb; + uint8_t lsb; + uint32_t samples_left = ((x_samples * y_samples)); + uint8_t sign = 0; + + al_assert(buf_size == (samples_left * sizeof(uint64_t))); + + al_memset(buf, 0, buf_size); + + if (y_start < 0) { + y_start *= -1; + sign |= 0x1; + } + + if (y_stop < 0) { + y_stop *= -1; + sign |= 0x2; + } + + data[0] = lane; + data[1] = x_start; + data[2] = x_stop; + data[3] = x_step; + data[4] = y_start; + data[5] = y_stop; + data[6] = sign; + data[7] = y_step; + + rc = al_serdes_25g_mailbox_send_cmd( + obj, + SERDES_MB_CMD_SWING_CFG, + data, + 8); + + if (rc) { + al_err("%s: Failed to send command %d to mailbox.\n", + __func__, SERDES_MB_CMD_SWING_CFG); + return rc; + } + + rc = al_serdes_25g_mailbox_recv_rsp( + obj, + &rsp_code, + data, + &data_len); + + if ((rc) || (rsp_code != SERDES_MB_RSP_CODE_0)) { + al_err("%s: Failed to send command %d to mailbox. rsp_code %d\n", + __func__, SERDES_MB_CMD_SWING_CFG, rsp_code); + + return (ETIMEDOUT); + } + + al_assert(sample_width <= 40); + + data[0] = lane; + data[1] = ((ber_target >> 32) & 0xFF); + data[2] = ((ber_target >> 24) & 0xFF); + data[3] = ((ber_target >> 16) & 0xFF); + data[4] = ((ber_target >> 8) & 0xFF); + data[5] = (ber_target & 0xFF); + + rc = al_serdes_25g_mailbox_send_cmd( + obj, + SERDES_MB_CMD_SAMPLES_COUNT, + data, + 6); + + if (rc) { + al_err("%s: Failed to send command %d to mailbox.\n", + __func__, SERDES_MB_CMD_SAMPLES_COUNT); + return rc; + } + + rc = al_serdes_25g_mailbox_recv_rsp( + obj, + &rsp_code, + data, + &data_len); + + if ((rc) || (rsp_code != SERDES_MB_RSP_CODE_0)) { + al_err("%s: Failed to send command %d to mailbox. rsp_code %d\n", + __func__, SERDES_MB_CMD_SAMPLES_COUNT, rsp_code); + + return (ETIMEDOUT); + } + + rc = al_serdes_25g_mailbox_send_cmd( + obj, + SERDES_MB_CMD_START_MEASURE, + data, + 0); + + bits_left_curr_sample = sample_width; + + while (rsp_code != SERDES_MB_RSP_CODE_1) { + uint8_t num_bits = 0; + + rc = al_serdes_25g_mailbox_recv_rsp( + obj, + &rsp_code, + data, + &data_len); + + if ((rc != 0) || (rsp_code > SERDES_MB_RSP_CODE_2)) { + al_err("%s: command %d return failure. rsp_code %d\n", + __func__, SERDES_MB_CMD_START_MEASURE, rsp_code); + + return (ETIMEDOUT); + } + byte = 0; + total_bits = data_len * 8; + bits_left_curr_byte = 8; + while (total_bits > 0) { + num_bits = al_min_t(uint8_t, bits_left_curr_sample, bits_left_curr_byte); + + buf[(y * x_samples) + x] <<= num_bits; + msb = bits_left_curr_byte - 1; + lsb = msb - num_bits + 1; + buf[(y * x_samples) + x] |= (data[byte] & AL_FIELD_MASK(msb, lsb) >> lsb); + + total_bits -= num_bits; + + bits_left_curr_byte -= num_bits; + if (!bits_left_curr_byte) { + bits_left_curr_byte = 8; + byte++; + } + + bits_left_curr_sample -= num_bits; + if (!bits_left_curr_sample) { + y++; + if (y == y_samples) { + y = 0; + x++; + } + + samples_left--; + bits_left_curr_sample = sample_width; + } + + if (samples_left == 0) + break; + } + + if ((samples_left == 0) && (rsp_code != SERDES_MB_RSP_CODE_1)) { + rc = al_serdes_25g_mailbox_recv_rsp( + obj, + &rsp_code, + data, + &data_len); + if ((rc) || (rsp_code == SERDES_MB_RSP_CODE_0)) { + al_err("%s: Parsed enough samples but f/w is still sending more\n", + __func__); + + return -EIO; + } + break; + } + } + + if (samples_left > 0) { + al_err("%s: Still need more samples but f/w has stopped sending them!?!?!?\n", + __func__); + + return -EIO; + } + + return 0; +} + +#define SERDES_25G_EYE_X_MIN 1 +#define SERDES_25G_EYE_X_MAX 127 +#define SERDES_25G_EYE_Y_MIN -200 +#define SERDES_25G_EYE_Y_MAX 200 +#define SERDES_25G_EYE_SIZE_MAX_SAMPLES 401 +#define SERDES_25G_EYE_SIZE_BER_TARGET 0xffff +#define SERDES_25G_EYE_SIZE_ERR_TH 10 + +static int al_serdes_25g_calc_eye_size( + struct al_serdes_grp_obj *obj, + enum al_serdes_lane lane, + int *width, + int *height) +{ + uint64_t samples[SERDES_25G_EYE_SIZE_MAX_SAMPLES]; + int i; + int _width = 0; + int _height = 0; + int rc; + int mid_x = ((SERDES_25G_EYE_X_MIN + SERDES_25G_EYE_X_MAX) / 2); + int mid_y = ((SERDES_25G_EYE_Y_MIN + SERDES_25G_EYE_Y_MAX) / 2); + + *height = 0; + *width = 0; + + rc = al_serdes_25g_eye_diag_run(obj, + lane, + mid_x, + mid_x, + 1, + SERDES_25G_EYE_Y_MIN, + SERDES_25G_EYE_Y_MAX, + 1, + SERDES_25G_EYE_SIZE_BER_TARGET, + samples, + ((SERDES_25G_EYE_Y_MAX - SERDES_25G_EYE_Y_MIN + 1) * + sizeof(uint64_t))); + + if (rc) { + al_err("%s: failed to run eye_diag\n", __func__); + return rc; + } + + for (i = (mid_y - SERDES_25G_EYE_Y_MIN); + ((samples[i] < SERDES_25G_EYE_SIZE_ERR_TH) && + (i < (SERDES_25G_EYE_Y_MAX - SERDES_25G_EYE_Y_MIN + 1))); + i++, (_height)++) + ; + for (i = (mid_y - SERDES_25G_EYE_Y_MIN); + ((samples[i] < SERDES_25G_EYE_SIZE_ERR_TH) && (i >= 0)); + i--, (_height)++) + ; + + rc = al_serdes_25g_eye_diag_run(obj, + lane, + SERDES_25G_EYE_X_MIN, + SERDES_25G_EYE_X_MAX, + 1, + mid_y, + mid_y, + 1, + SERDES_25G_EYE_SIZE_BER_TARGET, + samples, + ((SERDES_25G_EYE_X_MAX - SERDES_25G_EYE_X_MIN + 1) * + sizeof(uint64_t))); + + if (rc) { + al_err("%s: failed to run eye_diag\n", __func__); + return rc; + } + + for (i = (mid_x - SERDES_25G_EYE_X_MIN); + ((samples[i] < SERDES_25G_EYE_SIZE_ERR_TH) && + (i < (SERDES_25G_EYE_X_MAX - SERDES_25G_EYE_X_MIN + 1))); + i++, (_width)++) + ; + for (i = (mid_x - SERDES_25G_EYE_X_MIN); + ((samples[i] < SERDES_25G_EYE_SIZE_ERR_TH) && (i >= 0)); + i--, (_width)++) + ; + + *height = _height; + *width = _width; + + return 0; +} + + +static void al_serdes_25g_tx_advanced_params_set(struct al_serdes_grp_obj *obj, + enum al_serdes_lane lane, + void *tx_params) +{ + struct al_serdes_adv_tx_params *params = tx_params; + uint32_t timeout = 5000; + uint8_t val = 0; + + al_serdes_25g_reg_masked_write(obj, + (enum al_serdes_reg_page)lane, + SERDES_25G_LANE_DRV_TXEQ_CTRL3_ADDR, + SERDES_25G_LANE_DRV_TXEQ_CTRL3_TXEQ_CM1_MASK, + SERDES_25G_LANE_DRV_TXEQ_CTRL3_TXEQ_CM1_SHIFT, + params->c_minus_1); + + al_serdes_25g_reg_masked_write(obj, + (enum al_serdes_reg_page)lane, + SERDES_25G_LANE_DRV_TXEQ_CTRL1_ADDR, + SERDES_25G_LANE_DRV_TXEQ_CTRL1_TXEQ_C1_MASK, + SERDES_25G_LANE_DRV_TXEQ_CTRL1_TXEQ_C1_SHIFT, + params->c_plus_1); + + al_serdes_25g_reg_masked_write(obj, + (enum al_serdes_reg_page)lane, + SERDES_25G_LANE_DRV_TXEQ_CTRL5_ADDR, + SERDES_25G_LANE_DRV_TXEQ_CTRL5_DRV_SWING_MASK, + SERDES_25G_LANE_DRV_TXEQ_CTRL5_DRV_SWING_SHIFT, + params->total_driver_units); + + al_serdes_25g_reg_masked_write(obj, + (enum al_serdes_reg_page)lane, + SERDES_25G_LANE_DRV_TXEQ_CTRL0_ADDR, + SERDES_25G_LANE_DRV_TXEQ_CTRL0_REQ_MASK, + SERDES_25G_LANE_DRV_TXEQ_CTRL0_REQ_SHIFT, + 1); + + + /* wait for acknowledge */ + while (1) { + al_serdes_25g_reg_masked_read(obj, + (enum al_serdes_reg_page)lane, + SERDES_25G_LANE_DRV_TXEQ_STATUS0_ADDR, + SERDES_25G_LANE_DRV_TXEQ_STATUS0_ACK_MASK, + SERDES_25G_LANE_DRV_TXEQ_STATUS0_ACK_SHIFT, + &val); + if (val == 1) + break; + + if (timeout == 0) { + al_err("%s: timeout occurred waiting to FW ack\n", __func__); + break; + } + + timeout--; + al_udelay(1); + } + + al_serdes_25g_reg_masked_write(obj, + (enum al_serdes_reg_page)lane, + SERDES_25G_LANE_DRV_TXEQ_CTRL0_ADDR, + SERDES_25G_LANE_DRV_TXEQ_CTRL0_REQ_MASK, + SERDES_25G_LANE_DRV_TXEQ_CTRL0_REQ_SHIFT, + 0); +} + +static void al_serdes_25g_tx_advanced_params_get(struct al_serdes_grp_obj *obj, + enum al_serdes_lane lane, + void *tx_params) +{ + struct al_serdes_adv_tx_params *params = tx_params; + + al_serdes_25g_reg_masked_read(obj, + (enum al_serdes_reg_page)lane, + SERDES_25G_LANE_DRV_TXEQ_CTRL3_ADDR, + SERDES_25G_LANE_DRV_TXEQ_CTRL3_TXEQ_CM1_MASK, + SERDES_25G_LANE_DRV_TXEQ_CTRL3_TXEQ_CM1_SHIFT, + ¶ms->c_minus_1); + + al_serdes_25g_reg_masked_read(obj, + (enum al_serdes_reg_page)lane, + SERDES_25G_LANE_DRV_TXEQ_CTRL1_ADDR, + SERDES_25G_LANE_DRV_TXEQ_CTRL1_TXEQ_C1_MASK, + SERDES_25G_LANE_DRV_TXEQ_CTRL1_TXEQ_C1_SHIFT, + ¶ms->c_plus_1); + + al_serdes_25g_reg_masked_read(obj, + (enum al_serdes_reg_page)lane, + SERDES_25G_LANE_DRV_TXEQ_CTRL5_ADDR, + SERDES_25G_LANE_DRV_TXEQ_CTRL5_DRV_SWING_MASK, + SERDES_25G_LANE_DRV_TXEQ_CTRL5_DRV_SWING_SHIFT, + ¶ms->total_driver_units); +} + +static al_bool al_serdes_25g_cdr_is_locked( + struct al_serdes_grp_obj *obj, + enum al_serdes_lane lane) +{ + uint8_t reg; + + al_serdes_25g_reg_masked_read(obj, + (enum al_serdes_reg_page)lane, + SERDES_25G_LANE_CDR_RXCLK_DLPF_STATUS5_ADDR, + SERDES_25G_LANE_CDR_RXCLK_DLPF_STATUS5_LOCKED_MASK, + SERDES_25G_LANE_CDR_RXCLK_DLPF_STATUS5_LOCKED_SHIFT, + ®); + + return !!reg; + +} + +static al_bool al_serdes_25g_rx_valid( + struct al_serdes_grp_obj *obj, + enum al_serdes_lane lane) +{ + uint8_t reg; + + al_serdes_25g_reg_masked_read(obj, + (enum al_serdes_reg_page)lane, + SERDES_25G_LANE_TOP_LN_STAT_CTRL0_ADDR, + SERDES_25G_LANE_TOP_LN_STAT_CTRL0_RXVALID_MASK, + SERDES_25G_LANE_TOP_LN_STAT_CTRL0_RXVALID_SHIFT, + ®); + + return !!reg; + +} + +static al_bool al_serdes_25g_signal_is_detected( + struct al_serdes_grp_obj *obj, + enum al_serdes_lane lane) +{ + struct al_serdes_c_regs __iomem *regs_base = obj->regs_base; + uint32_t reg; + al_bool signal_detect = AL_FALSE; + + reg = al_reg_read32(®s_base->lane[lane].stat); + + signal_detect = ((reg & (SERDES_C_LANE_STAT_LN_STAT_LOS | + SERDES_C_LANE_STAT_LN_STAT_LOS_DEGLITCH)) ? + AL_FALSE : AL_TRUE); + + return signal_detect; + +} + +static int al_serdes_25g_rx_equalization( + struct al_serdes_grp_obj *obj, + enum al_serdes_lane lane) +{ + struct al_serdes_c_regs __iomem *regs_base = obj->regs_base; + uint32_t ready_mask = (SERDES_C_GEN_STATUS_CM0_RST_PD_READY | SERDES_C_GEN_STATUS_CM0_OK_O); + uint32_t reset_mask; + uint32_t timeout; + uint32_t reg_val; + uint32_t retries = AL_SERDES_25G_RESET_NUM_RETRIES; + int status = 0; + + if (lane == 0) { + ready_mask |= SERDES_C_GEN_STATUS_LN0_RST_PD_READY; + reset_mask = SERDES_C_GEN_RST_LN0_RST_N; + } else { + ready_mask |= SERDES_C_GEN_STATUS_LN1_RST_PD_READY; + reset_mask = SERDES_C_GEN_RST_LN1_RST_N; + } + + while (retries > 0) { + timeout = AL_SERDES_25G_WAIT_FOR_READY_TO; + status = 0; + + al_reg_write32_masked(®s_base->gen.rst, reset_mask, 0); + + al_msleep(AL_SERDES_25G_RESET_TO); + + al_serdes_25g_reg_masked_write(obj, + (enum al_serdes_reg_page)lane, + SERDES_25G_LANE_FEATURE_CTLE_ADAPT_MBS_CFG_ADDR, + SERDES_25G_LANE_FEATURE_CTLE_ADAPT_MBS_CFG_INIT0_EN_MASK, + SERDES_25G_LANE_FEATURE_CTLE_ADAPT_MBS_CFG_INIT0_EN_SHIFT, + 0); + + al_serdes_25g_reg_masked_write(obj, + (enum al_serdes_reg_page)lane, + SERDES_25G_LANE_LEQ_REFCLK_EQ_MB_CTRL1_ADDR, + SERDES_25G_LANE_LEQ_REFCLK_EQ_MB_CTRL1_EQ_MBF_START_MASK, + SERDES_25G_LANE_LEQ_REFCLK_EQ_MB_CTRL1_EQ_MBF_START_SHIFT, + 7); + + al_serdes_25g_reg_masked_write(obj, + (enum al_serdes_reg_page)lane, + SERDES_25G_LANE_LEQ_REFCLK_EQ_MB_CTRL1_ADDR, + SERDES_25G_LANE_LEQ_REFCLK_EQ_MB_CTRL1_EQ_MBG_START_MASK, + SERDES_25G_LANE_LEQ_REFCLK_EQ_MB_CTRL1_EQ_MBG_START_SHIFT, + 15); + + al_msleep(AL_SERDES_25G_RESET_TO); + + al_reg_write32_masked(®s_base->gen.rst, reset_mask, reset_mask); + + while (1) { + reg_val = al_reg_read32(®s_base->gen.status); + if ((reg_val & ready_mask) == ready_mask) + break; + + al_udelay(1); + timeout--; + + if (timeout == 0) { + al_err("%s: Timeout waiting for serdes ready\n", __func__); + status = ETIMEDOUT; + retries--; + break; + } + } + + if (status) + continue; + + while (1) { + reg_val = al_reg_read32(®s_base->lane[lane].stat); + reg_val &= (SERDES_C_LANE_STAT_LNX_STAT_OK | + SERDES_C_LANE_STAT_LN_STAT_RXVALID); + if (reg_val == (SERDES_C_LANE_STAT_LNX_STAT_OK | + SERDES_C_LANE_STAT_LN_STAT_RXVALID)) + break; + + al_udelay(1); + timeout--; + + if (timeout == 0) { + al_err("%s: TO waiting for lane ready (%x)\n", __func__, reg_val); + status = ETIMEDOUT; + retries--; + break; + } + } + + if (status) + continue; + + break; + } + + if (retries == 0) { + al_err("%s: Failed to run equalization\n", __func__); + status = ETIMEDOUT; + } + + return status; + +} + +#define AL_SERDES_25G_GCFSM2_READ_TIMEOUT 2000000 /* uSec */ + +static int al_serdes_25g_gcfsm2_read( + struct al_serdes_grp_obj *obj, + enum al_serdes_lane lane, + uint8_t offset, + uint16_t *data) +{ + int status = 0; + uint32_t timeout = AL_SERDES_25G_GCFSM2_READ_TIMEOUT; + uint8_t ack = 0; + uint8_t data_low, data_high; + + al_assert(data); + + /* Make sure GCFSM2 REQuest is off */ + al_serdes_25g_reg_masked_write( + obj, + (enum al_serdes_reg_page)lane, + SERDES_25G_LANE_GCFSM2_CMD_CTRL0_ADDR, + SERDES_25G_LANE_GCFSM2_CMD_CTRL0_REQ_MASK, + SERDES_25G_LANE_GCFSM2_CMD_CTRL0_REQ_SHIFT, + 0); + /* Write GCFSM2 CMD; CMD=0 for Read Request */ + al_serdes_25g_reg_masked_write( + obj, + (enum al_serdes_reg_page)lane, + SERDES_25G_LANE_GCFSM2_CMD_CTRL1_ADDR, + SERDES_25G_LANE_GCFSM2_CMD_CTRL1_CMD_MASK, + SERDES_25G_LANE_GCFSM2_CMD_CTRL1_CMD_SHIFT, + 0); + /* Write GCFSM2 the Address we wish to read */ + al_serdes_25g_reg_write( + obj, + (enum al_serdes_reg_page)lane, + 0, + SERDES_25G_LANE_GCFSM2_CMD_CTRL2_ADDR, + offset); + /* Issue a command REQuest */ + al_serdes_25g_reg_masked_write( + obj, + (enum al_serdes_reg_page)lane, + SERDES_25G_LANE_GCFSM2_CMD_CTRL0_ADDR, + SERDES_25G_LANE_GCFSM2_CMD_CTRL0_REQ_MASK, + SERDES_25G_LANE_GCFSM2_CMD_CTRL0_REQ_SHIFT, + 1); + /* Poll on GCFSM2 ACK */ + while (1) { + al_serdes_25g_reg_masked_read( + obj, + (enum al_serdes_reg_page)lane, + SERDES_25G_LANE_GCFSM2_CMD_STATUS_ADDR, + SERDES_25G_LANE_GCFSM2_CMD_STATUS_ACK_MASK, + SERDES_25G_LANE_GCFSM2_CMD_STATUS_ACK_SHIFT, + &ack); + + if (ack || (timeout == 0)) + break; + + timeout--; + al_udelay(1); + } + + if (ack) { + /* Read 12bit of register value */ + al_serdes_25g_reg_read( + obj, + (enum al_serdes_reg_page)lane, + 0, + SERDES_25G_LANE_GCFSM2_READ_SHADOW_DATA_STATUS0_ADDR, + &data_low); + al_serdes_25g_reg_masked_read( + obj, + (enum al_serdes_reg_page)lane, + SERDES_25G_LANE_GCFSM2_READ_SHADOW_DATA_STATUS1_ADDR, + SERDES_25G_LANE_GCFSM2_READ_SHADOW_DATA_STATUS1_11_8_MASK, + SERDES_25G_LANE_GCFSM2_READ_SHADOW_DATA_STATUS1_11_8_SHIFT, + &data_high); + *data = (data_high << 8) | data_low; + } else { + al_err("%s: TO waiting for GCFSM2 req to complete (%x)\n", __func__, offset); + status = ETIMEDOUT; + } + + /* Deassert the GCFSM2 REQuest */ + al_serdes_25g_reg_masked_write( + obj, + (enum al_serdes_reg_page)lane, + SERDES_25G_LANE_GCFSM2_CMD_CTRL0_ADDR, + SERDES_25G_LANE_GCFSM2_CMD_CTRL0_REQ_MASK, + SERDES_25G_LANE_GCFSM2_CMD_CTRL0_REQ_SHIFT, + 0); + + return status; +} + +enum al_serdes_25g_rx_leq_fsm_opcode { + AL_SERDES_25G_RX_LEQ_FSM_OPCODE_READ = 0x1, + AL_SERDES_25G_RX_LEQ_FSM_OPCODE_WRITE = 0x2, +}; + +enum al_serdes_25g_rx_leq_fsm_target { + AL_SERDES_25G_RX_LEQ_FSM_TARGET_AGC_SOURCE = 0x1, + AL_SERDES_25G_RX_LEQ_FSM_TARGET_PLE_ATT = 0x2, + AL_SERDES_25G_RX_LEQ_FSM_TARGET_EQ_LFG = 0x3, + AL_SERDES_25G_RX_LEQ_FSM_TARGET_GN_APG = 0x4, + AL_SERDES_25G_RX_LEQ_FSM_TARGET_GNEQ_CCL_LFG = 0x5, + AL_SERDES_25G_RX_LEQ_FSM_TARGET_HFG_SQL = 0x6, + AL_SERDES_25G_RX_LEQ_FSM_TARGET_EQ_MBF = 0x8, + AL_SERDES_25G_RX_LEQ_FSM_TARGET_EQ_MBG = 0x9, + AL_SERDES_25G_RX_LEQ_FSM_TARGET_VSCAN = 0xA, + AL_SERDES_25G_RX_LEQ_FSM_TARGET_HSCAN = 0xB, + AL_SERDES_25G_RX_LEQ_FSM_TARGET_EYE_INTF = 0xC, +}; + +#define AL_SERDES_25G_RX_LEQ_FSM_TIMEOUT 2000000 /* uSec */ + +static int al_serdes_25g_rx_leq_fsm_op( + struct al_serdes_grp_obj *obj, + enum al_serdes_lane lane, + enum al_serdes_25g_rx_leq_fsm_opcode opcode, + enum al_serdes_25g_rx_leq_fsm_target target, + uint8_t val, + uint8_t *data, + uint8_t *err) +{ + uint32_t reg; + uint32_t timeout = AL_SERDES_25G_RX_LEQ_FSM_TIMEOUT; + uint8_t ack = 0; + int status = 0; + + al_assert(data); + al_assert(err); + + /* Write the OpCode & Target to LEQ FSM */ + reg = (target << 4) | opcode; + al_serdes_25g_reg_write( + obj, + (enum al_serdes_reg_page)lane, + 0, + SERDES_25G_LANE_LEQ_REFCLK_LEQ_FSM_CMD0_ADDR, + reg); + + /* Write 0 as MiscOption value to LEQ FSM */ + al_serdes_25g_reg_write( + obj, + (enum al_serdes_reg_page)lane, + 0, + SERDES_25G_LANE_LEQ_REFCLK_LEQ_FSM_CMD2_ADDR, + 0); + + /* Write the ArgumentValue to LEQ FSM if needed*/ + if (opcode == AL_SERDES_25G_RX_LEQ_FSM_OPCODE_WRITE) { + al_serdes_25g_reg_write( + obj, + (enum al_serdes_reg_page)lane, + 0, + SERDES_25G_LANE_LEQ_REFCLK_LEQ_FSM_CMD1_ADDR, + val); + } + + /* Issue an LEQ FSM Command Request */ + al_serdes_25g_reg_masked_write( + obj, + (enum al_serdes_reg_page)lane, + SERDES_25G_LANE_LEQ_REFCLK_LEQ_FSM_CTRL0_ADDR, + SERDES_25G_LANE_LEQ_REFCLK_LEQ_FSM_CTRL0_LEQ_FSM_CMD_REQ_MASK, + SERDES_25G_LANE_LEQ_REFCLK_LEQ_FSM_CTRL0_LEQ_FSM_CMD_REQ_SHIFT, + 1); + + /* Poll on LEQ FSM Command acknowledge */ + while (1) { + al_serdes_25g_reg_masked_read( + obj, + (enum al_serdes_reg_page)lane, + SERDES_25G_LANE_LEQ_REFCLK_LEQ_FSM_STATUS5_ADDR, + SERDES_25G_LANE_LEQ_REFCLK_LEQ_FSM_STATUS5_LEQ_FSM_CMD_ACK_MASK, + SERDES_25G_LANE_LEQ_REFCLK_LEQ_FSM_STATUS5_LEQ_FSM_CMD_ACK_SHIFT, + &ack); + + if (ack || (timeout == 0)) + break; + + timeout--; + al_udelay(1); + } + + if (ack) { + uint8_t err1, err2; + al_serdes_25g_reg_read( + obj, + (enum al_serdes_reg_page)lane, + 0, + SERDES_25G_LANE_LEQ_REFCLK_LEQ_FSM_STATUS0_ADDR, + err); + + err1 = (*err & + SERDES_25G_LANE_LEQ_REFCLK_LEQ_FSM_STATUS0_LEQ_FSM_STATUS_ERROR1_MASK) >> + SERDES_25G_LANE_LEQ_REFCLK_LEQ_FSM_STATUS0_LEQ_FSM_STATUS_ERROR1_SHIFT; + err2 = (*err & + SERDES_25G_LANE_LEQ_REFCLK_LEQ_FSM_STATUS0_LEQ_FSM_STATUS_ERROR2_MASK) >> + SERDES_25G_LANE_LEQ_REFCLK_LEQ_FSM_STATUS0_LEQ_FSM_STATUS_ERROR2_SHIFT; + + if (err1 || err2) { + al_err("%s: error in RX LEQ FSM req, err status 1=0x%x, err status 2=0x%x", + __func__, err1, err2); + status = -EIO; + } + + /* Read LEQ FSM Command return Value */ + al_serdes_25g_reg_read( + obj, + (enum al_serdes_reg_page)lane, + 0, + SERDES_25G_LANE_LEQ_REFCLK_LEQ_FSM_STATUS3_ADDR, + data); + + /* Clear an LEQ FSM Command Request */ + al_serdes_25g_reg_masked_write( + obj, + (enum al_serdes_reg_page)lane, + SERDES_25G_LANE_LEQ_REFCLK_LEQ_FSM_CTRL0_ADDR, + SERDES_25G_LANE_LEQ_REFCLK_LEQ_FSM_CTRL0_LEQ_FSM_CMD_REQ_MASK, + SERDES_25G_LANE_LEQ_REFCLK_LEQ_FSM_CTRL0_LEQ_FSM_CMD_REQ_SHIFT, + 0); + } else { + al_err("%s: TO waiting for RX LEQ FSM req to complete (opcode %x, target %x, val %x)\n", + __func__, opcode, target, val); + status = ETIMEDOUT; + } + + return status; +} + +/* enum values correspond to HW values, don't change! */ +enum al_serdes_25g_tbus_obj { + AL_SERDES_25G_TBUS_OBJ_TOP = 0, + AL_SERDES_25G_TBUS_OBJ_CMU = 1, + AL_SERDES_25G_TBUS_OBJ_LANE = 2, +}; + +#define AL_SERDES_25G_TBUS_DELAY 1000 /* uSec */ +#define AL_SERDES_25G_TBUS_ADDR_HIGH_SHIFT 5 + +static int al_serdes_25g_tbus_read( + struct al_serdes_grp_obj *obj, + enum al_serdes_lane lane, + enum al_serdes_25g_tbus_obj tbus_obj, + uint8_t offset, + uint16_t *data) +{ + uint8_t addr_high, val_high, val_low; + + al_assert(lane < AL_SRDS_NUM_LANES); + + if (tbus_obj == AL_SERDES_25G_TBUS_OBJ_TOP) + addr_high = AL_SERDES_25G_TBUS_OBJ_TOP; + else if (tbus_obj == AL_SERDES_25G_TBUS_OBJ_CMU) + addr_high = AL_SERDES_25G_TBUS_OBJ_CMU; + else + addr_high = AL_SERDES_25G_TBUS_OBJ_LANE + lane; + + addr_high <<= AL_SERDES_25G_TBUS_ADDR_HIGH_SHIFT; + + al_serdes_25g_reg_write( + obj, + AL_SRDS_REG_PAGE_TOP, + 0, + SERDES_25G_TOP_TBUS_ADDR_7_0_ADDR, + offset); + + al_serdes_25g_reg_write( + obj, + AL_SRDS_REG_PAGE_TOP, + 0, + SERDES_25G_TOP_TBUS_ADDR_15_8_ADDR, + addr_high); + + al_udelay(AL_SERDES_25G_TBUS_DELAY); + + al_serdes_25g_reg_read( + obj, + AL_SRDS_REG_PAGE_TOP, + 0, + SERDES_25G_TOP_TBUS_DATA_7_0_ADDR, + &val_low); + + al_serdes_25g_reg_masked_read( + obj, + AL_SRDS_REG_PAGE_TOP, + SERDES_25G_TOP_TBUS_DATA_11_8_ADDR, + SERDES_25G_TOP_TBUS_DATA_11_8_MASK, + SERDES_25G_TOP_TBUS_DATA_11_8_SHIFT, + &val_high); + + *data = (val_high << 8) | val_low; + + return 0; +} + +#define AL_SERDES_25G_RX_ADV_PARAMS_ATT_MASK 0x07 +#define AL_SERDES_25G_RX_ADV_PARAMS_APG_MASK 0x03 +#define AL_SERDES_25G_RX_ADV_PARAMS_LFG_MASK 0x1F +#define AL_SERDES_25G_RX_ADV_PARAMS_HFG_MASK 0x1F +#define AL_SERDES_25G_RX_ADV_PARAMS_MBG_MASK 0x0F +#define AL_SERDES_25G_RX_ADV_PARAMS_MBF_MASK 0x0F +#define AL_SERDES_25G_RX_ADV_PARAMS_DFE_TAP_CNT 8 +#define AL_SERDES_25G_RX_ADV_PARAMS_DFE_TAP_MASK 0x1F +#define AL_SERDES_25G_RX_ADV_PARAMS_DFE_TAP_SIGN_SHIFT 7 + +static void al_serdes_25g_rx_advanced_params_get( + struct al_serdes_grp_obj *obj, + enum al_serdes_lane lane, + void *rx_params) +{ + struct al_serdes_25g_adv_rx_params *params = rx_params; + uint8_t value, err; + int8_t tap_weight; + uint8_t tap_sign; + int8_t *tap_ptr_arr[AL_SERDES_25G_RX_ADV_PARAMS_DFE_TAP_CNT]; + int rc; + int i; + + rc = al_serdes_25g_rx_leq_fsm_op(obj, lane, AL_SERDES_25G_RX_LEQ_FSM_OPCODE_READ, + AL_SERDES_25G_RX_LEQ_FSM_TARGET_PLE_ATT, 0, &value, &err); + if (rc || err) { + al_err("%s: al_serdes_25g_rx_leq_fsm_op failed to read att, rc %d, err %d\n", + __func__, rc, err); + return; + } + params->att = value & AL_SERDES_25G_RX_ADV_PARAMS_ATT_MASK; + + rc = al_serdes_25g_rx_leq_fsm_op(obj, lane, AL_SERDES_25G_RX_LEQ_FSM_OPCODE_READ, + AL_SERDES_25G_RX_LEQ_FSM_TARGET_GN_APG, 0, &value, &err); + if (rc || err) { + al_err("%s: al_serdes_25g_rx_leq_fsm_op failed to read apg, rc %d, err %d\n", + __func__, rc, err); + return; + } + params->apg = value & AL_SERDES_25G_RX_ADV_PARAMS_APG_MASK; + + rc = al_serdes_25g_rx_leq_fsm_op(obj, lane, AL_SERDES_25G_RX_LEQ_FSM_OPCODE_READ, + AL_SERDES_25G_RX_LEQ_FSM_TARGET_EQ_LFG, 0, &value, &err); + if (rc || err) { + al_err("%s: al_serdes_25g_rx_leq_fsm_op failed to read lfg, rc %d, err %d\n", + __func__, rc, err); + return; + } + params->lfg = value & AL_SERDES_25G_RX_ADV_PARAMS_LFG_MASK; + + rc = al_serdes_25g_rx_leq_fsm_op(obj, lane, AL_SERDES_25G_RX_LEQ_FSM_OPCODE_READ, + AL_SERDES_25G_RX_LEQ_FSM_TARGET_HFG_SQL, 0, &value, &err); + if (rc || err) { + al_err("%s: al_serdes_25g_rx_leq_fsm_op failed to read hfg, rc %d, err %d\n", + __func__, rc, err); + return; + } + params->hfg = value & AL_SERDES_25G_RX_ADV_PARAMS_HFG_MASK; + + rc = al_serdes_25g_rx_leq_fsm_op(obj, lane, AL_SERDES_25G_RX_LEQ_FSM_OPCODE_READ, + AL_SERDES_25G_RX_LEQ_FSM_TARGET_EQ_MBG, 0, &value, &err); + if (rc || err) { + al_err("%s: al_serdes_25g_rx_leq_fsm_op failed to read mbg, rc %d, err %d\n", + __func__, rc, err); + return; + } + params->mbg = value & AL_SERDES_25G_RX_ADV_PARAMS_MBG_MASK; + + rc = al_serdes_25g_rx_leq_fsm_op(obj, lane, AL_SERDES_25G_RX_LEQ_FSM_OPCODE_READ, + AL_SERDES_25G_RX_LEQ_FSM_TARGET_EQ_MBF, 0, &value, &err); + if (rc || err) { + al_err("%s: al_serdes_25g_rx_leq_fsm_op failed to read mbf, rc %d, err %d\n", + __func__, rc, err); + return; + } + params->mbf = value & AL_SERDES_25G_RX_ADV_PARAMS_MBF_MASK; + + tap_ptr_arr[0] = ¶ms->dfe_first_tap_even0_ctrl; + tap_ptr_arr[1] = ¶ms->dfe_first_tap_even1_ctrl; + tap_ptr_arr[2] = ¶ms->dfe_first_tap_odd0_ctrl; + tap_ptr_arr[3] = ¶ms->dfe_first_tap_odd1_ctrl; + tap_ptr_arr[4] = ¶ms->dfe_second_tap_ctrl; + tap_ptr_arr[5] = ¶ms->dfe_third_tap_ctrl; + tap_ptr_arr[6] = ¶ms->dfe_fourth_tap_ctrl; + tap_ptr_arr[7] = ¶ms->dfe_fifth_tap_ctrl; + + for (i = 0; i < AL_SERDES_25G_RX_ADV_PARAMS_DFE_TAP_CNT; i++) { + al_serdes_25g_reg_read( + obj, + (enum al_serdes_reg_page)lane, + 0, + SERDES_25G_LANE_DFE_REFCLK_TAP_VAL_STATUS0_ADDR + i, + &value); + + tap_weight = value & AL_SERDES_25G_RX_ADV_PARAMS_DFE_TAP_MASK; + tap_sign = (value & AL_BIT(AL_SERDES_25G_RX_ADV_PARAMS_DFE_TAP_SIGN_SHIFT)) >> + AL_SERDES_25G_RX_ADV_PARAMS_DFE_TAP_SIGN_SHIFT; + if (tap_sign == 0) + tap_weight = 0 - tap_weight; + + *tap_ptr_arr[i] = tap_weight; + } +} + +#define AL_SERDES_25G_TX_DIAG_GCFSM2_DCD_TRIM_ADDR 0x0B +#define AL_SERDES_25G_TX_DIAG_GCFSM2_DCD_TRIM_MASK 0x3F +#define AL_SERDES_25G_TX_DIAG_GCFSM2_DCD_TRIM_SIGN_SHIFT 7 +#define AL_SERDES_25G_TX_DIAG_GCFSM2_CLK_DELAY_ADDR 0x0C +#define AL_SERDES_25G_TX_DIAG_GCFSM2_CLK_DELAY_MASK 0xFFF + +static void al_serdes_25g_tx_diag_info_get( + struct al_serdes_grp_obj *obj, + enum al_serdes_lane lane, + void *tx_info) +{ + struct al_serdes_25g_tx_diag_info *info = tx_info; + uint8_t cal_x1, cal_x1_fixed, cal_x2, cal_xp5_fixed; + uint16_t val16, sign; + uint8_t val8, abs; + int rc; + + al_serdes_25g_reg_read( + obj, + (enum al_serdes_reg_page)lane, + 0, + SERDES_25G_LANE_TOP_AFE_TXCP_CTRL0_ADDR, + &val8); + info->regulated_supply = val8 & SERDES_25G_LANE_TOP_AFE_TXCP_CTRL0_REG_TXCP_TRIM_MASK; + + rc = al_serdes_25g_gcfsm2_read( + obj, + lane, + AL_SERDES_25G_TX_DIAG_GCFSM2_DCD_TRIM_ADDR, + &val16); + if (rc) { + al_err("%s: al_serdes_25g_gcfsm2_read failed to read dcd_trim, rc %d\n", + __func__, rc); + return; + } + + abs = val16 & AL_SERDES_25G_TX_DIAG_GCFSM2_DCD_TRIM_MASK; + sign = (val16 & AL_BIT(AL_SERDES_25G_TX_DIAG_GCFSM2_DCD_TRIM_SIGN_SHIFT)) >> + AL_SERDES_25G_TX_DIAG_GCFSM2_DCD_TRIM_SIGN_SHIFT; + if (sign) + info->dcd_trim = abs; + else + info->dcd_trim = 0 - abs; + + rc = al_serdes_25g_gcfsm2_read( + obj, + lane, + AL_SERDES_25G_TX_DIAG_GCFSM2_CLK_DELAY_ADDR, + &val16); + if (rc) { + al_err("%s: al_serdes_25g_gcfsm2_read failed to read clk_delay, rc %d\n", + __func__, rc); + return; + } + info->clk_delay = val16 & AL_SERDES_25G_TX_DIAG_GCFSM2_CLK_DELAY_MASK; + + al_serdes_25g_reg_read( + obj, + (enum al_serdes_reg_page)lane, + 0, + SERDES_25G_CM_TOP_AFE_TXTC_CTRL2_ADDR, + &val8); + cal_x1 = (val8 & SERDES_25G_CMU_TOP_AFE_TXTC_CTRL2_TXTC_CALP_X1_MASK) >> + SERDES_25G_CMU_TOP_AFE_TXTC_CTRL2_TXTC_CALP_X1_SHIFT; + cal_x1_fixed = (val8 & SERDES_25G_CMU_TOP_AFE_TXTC_CTRL2_TXTC_CALP_X1_FIXED_MASK) >> + SERDES_25G_CMU_TOP_AFE_TXTC_CTRL2_TXTC_CALP_X1_FIXED_SHIFT; + al_serdes_25g_reg_read( + obj, + (enum al_serdes_reg_page)lane, + 0, + SERDES_25G_CM_TOP_AFE_TXTC_CTRL3_ADDR, + &val8); + cal_x2 = (val8 & SERDES_25G_CMU_TOP_AFE_TXTC_CTRL3_TXTC_CALP_X2_MASK) >> + SERDES_25G_CMU_TOP_AFE_TXTC_CTRL3_TXTC_CALP_X2_SHIFT; + cal_xp5_fixed = (val8 & + SERDES_25G_CMU_TOP_AFE_TXTC_CTRL3_TXTC_CALP_XP5_FIXED_MASK) >> + SERDES_25G_CMU_TOP_AFE_TXTC_CTRL3_TXTC_CALP_XP5_FIXED_SHIFT; + info->calp_multiplied_by_2 = 4 * cal_x2 + 2 * cal_x1 + 2 * cal_x1_fixed + cal_xp5_fixed; + + al_serdes_25g_reg_read( + obj, + (enum al_serdes_reg_page)lane, + 0, + SERDES_25G_CM_TOP_AFE_TXTC_CTRL0_ADDR, + &val8); + cal_x1 = (val8 & SERDES_25G_CMU_TOP_AFE_TXTC_CTRL0_TXTC_CALN_X1_MASK) >> + SERDES_25G_CMU_TOP_AFE_TXTC_CTRL0_TXTC_CALN_X1_SHIFT; + cal_x1_fixed = (val8 & SERDES_25G_CMU_TOP_AFE_TXTC_CTRL0_TXTC_CALN_X1_FIXED_MASK) >> + SERDES_25G_CMU_TOP_AFE_TXTC_CTRL0_TXTC_CALN_X1_FIXED_SHIFT; + al_serdes_25g_reg_read( + obj, + (enum al_serdes_reg_page)lane, + 0, + SERDES_25G_CM_TOP_AFE_TXTC_CTRL1_ADDR, + &val8); + cal_x2 = (val8 & SERDES_25G_CMU_TOP_AFE_TXTC_CTRL1_TXTC_CALN_X2_MASK) >> + SERDES_25G_CMU_TOP_AFE_TXTC_CTRL1_TXTC_CALN_X2_SHIFT; + cal_xp5_fixed = (val8 & + SERDES_25G_CMU_TOP_AFE_TXTC_CTRL1_TXTC_CALN_XP5_FIXED_MASK) >> + SERDES_25G_CMU_TOP_AFE_TXTC_CTRL1_TXTC_CALN_XP5_FIXED_SHIFT; + info->caln_multiplied_by_2 = 4 * cal_x2 + 2 * cal_x1 + 2 * cal_x1_fixed + cal_xp5_fixed; +} + +#define AL_SERDES_25G_RX_DIAG_SIGNED_5BIT_ABS_MASK 0x1F +#define AL_SERDES_25G_RX_DIAG_SIGNED_5BIT_MASK 0x3F +#define AL_SERDES_25G_RX_DIAG_SIGNED_5BIT_SIGN_SHIFT 5 +#define AL_SERDES_25G_RX_DIAG_SIGNED_5BIT_HIGH_MASK 0xFC0 +#define AL_SERDES_25G_RX_DIAG_SIGNED_5BIT_HIGH_SHIFT 6 +#define AL_SERDES_25G_RX_DIAG_LEQ_EQ_COUNT 5 +#define AL_SERDES_25G_RX_DIAG_GCFSM2_LEQ_EQ_ADDR 0 +#define AL_SERDES_25G_RX_DIAG_GCFSM2_LEQ_GAINSTAGE_ADDR 0x5 +#define AL_SERDES_25G_RX_DIAG_GCFSM2_SUMMER_EVEN_ADDR 0x6 +#define AL_SERDES_25G_RX_DIAG_GCFSM2_SUMMER_ODD_ADDR 0x7 +#define AL_SERDES_25G_RX_DIAG_GCFSM2_VSCAN_EVEN_ADDR 0x8 +#define AL_SERDES_25G_RX_DIAG_GCFSM2_VSCAN_ODD_ADDR 0x9 +#define AL_SERDES_25G_RX_DIAG_GCFSM2_CDR_VCO_FR_ADDR 0xF +#define AL_SERDES_25G_RX_DIAG_GCFSM2_CDR_VCO_FR_MASK 0xFFF +#define AL_SERDES_25G_RX_DIAG_TBUS_DATA_SLICER_EVEN_ADDR 0x11 +#define AL_SERDES_25G_RX_DIAG_TBUS_DATA_SLICER_ODD_ADDR 0x12 +#define AL_SERDES_25G_RX_DIAG_TBUS_EDGE_SLICER_ADDR 0x13 +#define AL_SERDES_25G_RX_DIAG_TBUS_EYE_SLICER_ADDR 0x23 +#define AL_SERDES_25G_RX_DIAG_TBUS_CDR_CLK_Q_ADDR 0x2 +#define AL_SERDES_25G_RX_DIAG_TBUS_CDR_CLK_I_ADDR 0x1 +#define AL_SERDES_25G_RX_DIAG_CDR_RXCLK_DLPF_L_ADDR 0x26 +#define AL_SERDES_25G_RX_DIAG_CDR_RXCLK_DLPF_H_ADDR 0x27 + +static inline void al_serdes_25g_rx_diag_5bit_signed_set(uint8_t packed_val, int8_t *ptr) +{ + uint8_t abs, sign; + + abs = packed_val & AL_SERDES_25G_RX_DIAG_SIGNED_5BIT_ABS_MASK; + sign = (packed_val & AL_BIT(AL_SERDES_25G_RX_DIAG_SIGNED_5BIT_SIGN_SHIFT)) >> + AL_SERDES_25G_RX_DIAG_SIGNED_5BIT_SIGN_SHIFT; + if (sign) + *ptr = abs; + else + *ptr = 0 - abs; +} + +static void al_serdes_25g_rx_diag_info_get( + struct al_serdes_grp_obj *obj, + enum al_serdes_lane lane, + void *rx_info) +{ + struct al_serdes_25g_rx_diag_info *info = rx_info; + uint16_t val16; + uint8_t val8, val8_2; + int rc; + int i; + + al_serdes_25g_reg_read( + obj, + (enum al_serdes_reg_page)lane, + 0, + SERDES_25G_LANE_LOS_REFCLK_CALIBRATION_STATUS0_ADDR, + &val8); + al_serdes_25g_rx_diag_5bit_signed_set(val8, &info->los_offset); + + al_serdes_25g_reg_read( + obj, + (enum al_serdes_reg_page)lane, + 0, + SERDES_25G_LANE_LOS_REFCLK_CALIBRATION_STATUS1_ADDR, + &val8); + al_serdes_25g_rx_diag_5bit_signed_set(val8, &info->agc_offset); + + rc = al_serdes_25g_gcfsm2_read( + obj, + lane, + AL_SERDES_25G_RX_DIAG_GCFSM2_LEQ_GAINSTAGE_ADDR, + &val16); + if (rc) { + al_err("%s: al_serdes_25g_gcfsm2_read failed to read leq_gainstage, rc %d\n", + __func__, rc); + return; + } + val8 = (uint8_t)val16; + al_serdes_25g_rx_diag_5bit_signed_set(val8, &info->leq_gainstage_offset); + + for (i = 0; i < AL_SERDES_25G_RX_DIAG_LEQ_EQ_COUNT; i++) { + rc = al_serdes_25g_gcfsm2_read( + obj, + lane, + AL_SERDES_25G_RX_DIAG_GCFSM2_LEQ_EQ_ADDR + i, + &val16); + if (rc) { + al_err("%s: al_serdes_25g_gcfsm2_read failed to read leq_eq %d, rc %d\n", + __func__, i, rc); + return; + } + val8 = (uint8_t)val16; + + switch (i) { + case 0: + al_serdes_25g_rx_diag_5bit_signed_set(val8, &info->leq_eq1_offset); + break; + case 1: + al_serdes_25g_rx_diag_5bit_signed_set(val8, &info->leq_eq2_offset); + break; + case 2: + al_serdes_25g_rx_diag_5bit_signed_set(val8, &info->leq_eq3_offset); + break; + case 3: + al_serdes_25g_rx_diag_5bit_signed_set(val8, &info->leq_eq4_offset); + break; + case 4: + al_serdes_25g_rx_diag_5bit_signed_set(val8, &info->leq_eq5_offset); + break; + default: + break; + } + } + + rc = al_serdes_25g_gcfsm2_read( + obj, + lane, + AL_SERDES_25G_RX_DIAG_GCFSM2_SUMMER_EVEN_ADDR, + &val16); + if (rc) { + al_err("%s: al_serdes_25g_gcfsm2_read failed to read summer_even_offset, rc %d\n", + __func__, rc); + return; + } + val8 = (uint8_t)val16; + al_serdes_25g_rx_diag_5bit_signed_set(val8, &info->summer_even_offset); + + rc = al_serdes_25g_gcfsm2_read( + obj, + lane, + AL_SERDES_25G_RX_DIAG_GCFSM2_SUMMER_ODD_ADDR, + &val16); + if (rc) { + al_err("%s: al_serdes_25g_gcfsm2_read failed to read summer_odd_offset, rc %d\n", + __func__, rc); + return; + } + val8 = (uint8_t)val16; + al_serdes_25g_rx_diag_5bit_signed_set(val8, &info->summer_odd_offset); + + rc = al_serdes_25g_gcfsm2_read( + obj, + lane, + AL_SERDES_25G_RX_DIAG_GCFSM2_VSCAN_EVEN_ADDR, + &val16); + if (rc) { + al_err("%s: al_serdes_25g_gcfsm2_read failed to read vscan_even_offset, rc %d\n", + __func__, rc); + return; + } + val8 = (uint8_t)val16; + al_serdes_25g_rx_diag_5bit_signed_set(val8, &info->vscan_even_offset); + + rc = al_serdes_25g_gcfsm2_read( + obj, + lane, + AL_SERDES_25G_RX_DIAG_GCFSM2_VSCAN_ODD_ADDR, + &val16); + if (rc) { + al_err("%s: al_serdes_25g_gcfsm2_read failed to read vscan_odd_offset, rc %d\n", + __func__, rc); + return; + } + val8 = (uint8_t)val16; + al_serdes_25g_rx_diag_5bit_signed_set(val8, &info->vscan_odd_offset); + + al_serdes_25g_tbus_read( + obj, + lane, + AL_SERDES_25G_TBUS_OBJ_LANE, + AL_SERDES_25G_RX_DIAG_TBUS_DATA_SLICER_EVEN_ADDR, + &val16); + val8 = (uint8_t)(val16 & AL_SERDES_25G_RX_DIAG_SIGNED_5BIT_MASK); + al_serdes_25g_rx_diag_5bit_signed_set(val8, &info->data_slicer_even0_offset); + val8 = (uint8_t)((val16 & AL_SERDES_25G_RX_DIAG_SIGNED_5BIT_HIGH_MASK) >> + AL_SERDES_25G_RX_DIAG_SIGNED_5BIT_HIGH_SHIFT); + al_serdes_25g_rx_diag_5bit_signed_set(val8, &info->data_slicer_even1_offset); + + al_serdes_25g_tbus_read( + obj, + lane, + AL_SERDES_25G_TBUS_OBJ_LANE, + AL_SERDES_25G_RX_DIAG_TBUS_DATA_SLICER_ODD_ADDR, + &val16); + val8 = (uint8_t)(val16 & AL_SERDES_25G_RX_DIAG_SIGNED_5BIT_MASK); + al_serdes_25g_rx_diag_5bit_signed_set(val8, &info->data_slicer_odd0_offset); + val8 = (uint8_t)((val16 & AL_SERDES_25G_RX_DIAG_SIGNED_5BIT_HIGH_MASK) >> + AL_SERDES_25G_RX_DIAG_SIGNED_5BIT_HIGH_SHIFT); + al_serdes_25g_rx_diag_5bit_signed_set(val8, &info->data_slicer_odd1_offset); + + al_serdes_25g_tbus_read( + obj, + lane, + AL_SERDES_25G_TBUS_OBJ_LANE, + AL_SERDES_25G_RX_DIAG_TBUS_EDGE_SLICER_ADDR, + &val16); + val8 = (uint8_t)(val16 & AL_SERDES_25G_RX_DIAG_SIGNED_5BIT_MASK); + al_serdes_25g_rx_diag_5bit_signed_set(val8, &info->edge_slicer_even_offset); + val8 = (uint8_t)((val16 & AL_SERDES_25G_RX_DIAG_SIGNED_5BIT_HIGH_MASK) >> + AL_SERDES_25G_RX_DIAG_SIGNED_5BIT_HIGH_SHIFT); + al_serdes_25g_rx_diag_5bit_signed_set(val8, &info->edge_slicer_odd_offset); + + al_serdes_25g_tbus_read( + obj, + lane, + AL_SERDES_25G_TBUS_OBJ_LANE, + AL_SERDES_25G_RX_DIAG_TBUS_EYE_SLICER_ADDR, + &val16); + val8 = (uint8_t)(val16 & AL_SERDES_25G_RX_DIAG_SIGNED_5BIT_MASK); + al_serdes_25g_rx_diag_5bit_signed_set(val8, &info->eye_slicer_even_offset); + val8 = (uint8_t)((val16 & AL_SERDES_25G_RX_DIAG_SIGNED_5BIT_HIGH_MASK) >> + AL_SERDES_25G_RX_DIAG_SIGNED_5BIT_HIGH_SHIFT); + al_serdes_25g_rx_diag_5bit_signed_set(val8, &info->eye_slicer_odd_offset); + + al_serdes_25g_reg_masked_read( + obj, + (enum al_serdes_reg_page)lane, + SERDES_25G_LANE_CDR_REFCLK_AFE_PI_CTRL0_ADDR, + SERDES_25G_LANE_CDR_REFCLK_AFE_PI_CTRL0_RXCDR_HSCAN_CLKQ_MASK, + SERDES_25G_LANE_CDR_REFCLK_AFE_PI_CTRL0_RXCDR_HSCAN_CLKQ_SHIFT, + &info->cdr_clk_q); + + al_serdes_25g_reg_masked_read( + obj, + (enum al_serdes_reg_page)lane, + SERDES_25G_LANE_CDR_REFCLK_AFE_PI_CTRL1_ADDR, + SERDES_25G_LANE_CDR_REFCLK_AFE_PI_CTRL1_RXCDR_HSCAN_CLKI_MASK, + SERDES_25G_LANE_CDR_REFCLK_AFE_PI_CTRL1_RXCDR_HSCAN_CLKI_SHIFT, + &info->cdr_clk_i); + + al_serdes_25g_reg_masked_read( + obj, + (enum al_serdes_reg_page)lane, + SERDES_25G_LANE_CDR_REFCLK_AFE_PI_CTRL2_ADDR, + SERDES_25G_LANE_CDR_REFCLK_AFE_PI_CTRL2_RXCDR_HSCAN_EYE_MASK, + SERDES_25G_LANE_CDR_REFCLK_AFE_PI_CTRL2_RXCDR_HSCAN_EYE_SHIFT, + &info->cdr_dll); + + al_serdes_25g_reg_masked_read( + obj, + (enum al_serdes_reg_page)lane, + SERDES_25G_LANE_CDR_REFCLK_AFE_VCO_CTRL2_ADDR, + SERDES_25G_LANE_CDR_REFCLK_AFE_VCO_CTRL2_RXCDR_DOSC_MASK, + SERDES_25G_LANE_CDR_REFCLK_AFE_VCO_CTRL2_RXCDR_DOSC_SHIFT, + &info->cdr_vco_dosc); + + al_serdes_25g_reg_read( + obj, + (enum al_serdes_reg_page)lane, + 0, + SERDES_25G_LANE_CDR_RXCLK_LOAD_MODE_CTRL1_ADDR, + &val8_2); + al_serdes_25g_reg_read( + obj, + (enum al_serdes_reg_page)lane, + 0, + SERDES_25G_LANE_CDR_RXCLK_LOAD_MODE_CTRL0_ADDR, + &val8); + val8_2 &= SERDES_25G_LANE_CDR_RXCLK_LOAD_MODE_CTRL1_DLPF_VAL_8_MASK; + info->cdr_dlpf = (uint16_t)val8_2 << 8 | val8; + + rc = al_serdes_25g_gcfsm2_read( + obj, + lane, + AL_SERDES_25G_RX_DIAG_GCFSM2_CDR_VCO_FR_ADDR, + &val16); + if (rc) { + al_err("%s: al_serdes_25g_gcfsm2_read failed to read cdr_vco_fr, rc %d\n", + __func__, rc); + return; + } + info->cdr_vco_fr = val16 & AL_SERDES_25G_RX_DIAG_GCFSM2_CDR_VCO_FR_MASK; + + al_serdes_25g_reg_masked_read( + obj, + (enum al_serdes_reg_page)lane, + SERDES_25G_LANE_LEQ_REFCLK_AFE_PLE_CTRL0_ADDR, + SERDES_25G_LANE_LEQ_REFCLK_AFE_PLE_CTRL0_RXLEQ_PLE_BLW_ZERO_MASK, + SERDES_25G_LANE_LEQ_REFCLK_AFE_PLE_CTRL0_RXLEQ_PLE_BLW_ZERO_SHIFT, + &info->ple_resistance); + + al_serdes_25g_reg_read( + obj, + (enum al_serdes_reg_page)lane, + 0, + SERDES_25G_LANE_TOP_AFE_RXTERM_CTRL0_ADDR, + &val8); + + info->rx_term_mode = (val8 & SERDES_25G_LANE_TOP_AFE_RXTERM_CTRL0_RXTERM_HIZ_MASK) >> + SERDES_25G_LANE_TOP_AFE_RXTERM_CTRL0_RXTERM_HIZ_SHIFT; + + info->rx_coupling = (val8 & SERDES_25G_LANE_TOP_AFE_RXTERM_CTRL0_RXTERM_VCM_GND_MASK) >> + SERDES_25G_LANE_TOP_AFE_RXTERM_CTRL0_RXTERM_VCM_GND_SHIFT; + + al_serdes_25g_reg_masked_read( + obj, + (enum al_serdes_reg_page)lane, + SERDES_25G_LANE_TOP_AFE_RXTERM_CTRL1_ADDR, + SERDES_25G_LANE_TOP_AFE_RXTERM_CTRL1_RXTERM_VAL_MASK, + SERDES_25G_LANE_TOP_AFE_RXTERM_CTRL1_RXTERM_VAL_SHIFT, + &info->rx_term_cal_code); + + al_serdes_25g_reg_masked_read( + obj, + (enum al_serdes_reg_page)lane, + SERDES_25G_LANE_LEQ_REFCLK_AFE_BIAS_CTRL1_ADDR, + SERDES_25G_LANE_LEQ_REFCLK_AFE_BIAS_CTRL1_RXLEQ_BIASI_TRIM_MASK, + SERDES_25G_LANE_LEQ_REFCLK_AFE_BIAS_CTRL1_RXLEQ_BIASI_TRIM_SHIFT, + &info->rx_sheet_res_cal_code); +} + +/******************************************************************************/ +/******************************************************************************/ +int al_serdes_25g_handle_init( + void __iomem *serdes_regs_base, + struct al_serdes_grp_obj *obj) +{ + al_dbg( + "%s(%p, %p)\n", + __func__, + serdes_regs_base, + obj); + + al_memset(obj, 0, sizeof(struct al_serdes_grp_obj)); + + obj->regs_base = (struct al_serdes_regs *)serdes_regs_base; + obj->type_get = al_serdes_25g_type_get; + obj->reg_read = al_serdes_25g_reg_read; + obj->reg_write = al_serdes_25g_reg_write; + obj->bist_overrides_enable = NULL; + obj->bist_overrides_disable = NULL; + obj->rx_rate_change = NULL; + obj->group_pm_set = NULL; + obj->lane_pm_set = NULL; + obj->pma_hard_reset_group = NULL; + obj->pma_hard_reset_lane = NULL; + obj->loopback_control = NULL; + obj->bist_pattern_select = AL_SRDS_ADV_SRVC(al_serdes_25g_bist_pattern_select); + obj->bist_tx_enable = AL_SRDS_ADV_SRVC(al_serdes_25g_bist_tx_enable); + obj->bist_tx_err_inject = NULL; + obj->bist_rx_enable = AL_SRDS_ADV_SRVC(al_serdes_25g_bist_rx_enable); + obj->bist_rx_status = AL_SRDS_ADV_SRVC(al_serdes_25g_bist_rx_status); + obj->tx_deemph_preset = NULL; + obj->tx_deemph_inc = NULL; + obj->tx_deemph_dec = NULL; + obj->eye_measure_run = NULL; + obj->eye_diag_sample = NULL; + obj->eye_diag_run = AL_SRDS_ADV_SRVC(al_serdes_25g_eye_diag_run); + obj->cdr_is_locked = AL_SRDS_ADV_SRVC(al_serdes_25g_cdr_is_locked); + obj->rx_valid = AL_SRDS_ADV_SRVC(al_serdes_25g_rx_valid); + obj->signal_is_detected = AL_SRDS_ADV_SRVC(al_serdes_25g_signal_is_detected); + obj->tx_advanced_params_set = AL_SRDS_ADV_SRVC(al_serdes_25g_tx_advanced_params_set); + obj->tx_advanced_params_get = AL_SRDS_ADV_SRVC(al_serdes_25g_tx_advanced_params_get); + obj->rx_advanced_params_set = NULL; + obj->rx_advanced_params_get = AL_SRDS_ADV_SRVC(al_serdes_25g_rx_advanced_params_get); + obj->tx_diag_info_get = AL_SRDS_ADV_SRVC(al_serdes_25g_tx_diag_info_get); + obj->rx_diag_info_get = AL_SRDS_ADV_SRVC(al_serdes_25g_rx_diag_info_get); + obj->mode_set_sgmii = NULL; + obj->mode_set_kr = NULL; + obj->rx_equalization = AL_SRDS_ADV_SRVC(al_serdes_25g_rx_equalization); + obj->calc_eye_size = AL_SRDS_ADV_SRVC(al_serdes_25g_calc_eye_size); + obj->sris_config = NULL; + + return 0; +} + diff --git a/al_hal_serdes_25g.h b/al_hal_serdes_25g.h new file mode 100644 index 00000000000..8865b7da94f --- /dev/null +++ b/al_hal_serdes_25g.h @@ -0,0 +1,74 @@ +/******************************************************************************* +Copyright (C) 2015 Annapurna Labs Ltd. + +This file may be licensed under the terms of the Annapurna Labs Commercial +License Agreement. + +Alternatively, this file can be distributed under the terms of the GNU General +Public License V2 as published by the Free Software Foundation and can be +found at http://www.gnu.org/licenses/gpl-2.0.html + +Alternatively, redistribution and use in source and binary forms, with or +without modification, are permitted provided that the following conditions are +met: + + * Redistributions of source code must retain the above copyright notice, +this list of conditions and the following disclaimer. + + * Redistributions in binary form must reproduce the above copyright +notice, this list of conditions and the following disclaimer in +the documentation and/or other materials provided with the +distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +*******************************************************************************/ + +/** + * @defgroup group_serdes_api API + * SerDes HAL driver API + * @ingroup group_serdes SerDes + * @{ + * + * @file al_hal_serdes_25g.h + * + * @brief Header file for the SerDes HAL driver + * + */ + +#ifndef __AL_HAL_SERDES_25G_H__ +#define __AL_HAL_SERDES_25G_H__ + +#include "al_hal_common.h" +#include "al_hal_serdes_interface.h" + +/* *INDENT-OFF* */ +#ifdef __cplusplus +extern "C" { +#endif +/* *INDENT-ON* */ + +int al_serdes_25g_handle_init( + void __iomem *serdes_regs_base, + struct al_serdes_grp_obj *obj); + + +/* *INDENT-OFF* */ +#ifdef __cplusplus +} +#endif + +/* *INDENT-ON* */ +#endif /* __AL_SRDS__ */ + +/** @} end of SERDES group */ + diff --git a/al_hal_serdes_25g_internal_regs.h b/al_hal_serdes_25g_internal_regs.h new file mode 100644 index 00000000000..ff48f98a940 --- /dev/null +++ b/al_hal_serdes_25g_internal_regs.h @@ -0,0 +1,4205 @@ +/******************************************************************************* +Copyright (C) 2015 Annapurna Labs Ltd. + +This file may be licensed under the terms of the Annapurna Labs Commercial +License Agreement. + +Alternatively, this file can be distributed under the terms of the GNU General +Public License V2 as published by the Free Software Foundation and can be +found at http://www.gnu.org/licenses/gpl-2.0.html + +Alternatively, redistribution and use in source and binary forms, with or +without modification, are permitted provided that the following conditions are +met: + + * Redistributions of source code must retain the above copyright notice, +this list of conditions and the following disclaimer. + + * Redistributions in binary form must reproduce the above copyright +notice, this list of conditions and the following disclaimer in +the documentation and/or other materials provided with the +distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +*******************************************************************************/ +#ifndef _AL_SERDES_25G_INTERNAL_REGS_H_ +#define _AL_SERDES_25G_INTERNAL_REGS_H_ + +#ifdef _cplusplus +extern "C" { +#endif + +/******************************************************************************* + * TOP Registers + ******************************************************************************/ +#define SERDES_25G_TOP_BASE 0x00 +#define SERDES_25G_TOP_SIZE 0x200 + +#define SERDES_25G_TOP_PHY_STAT0_ADDR 0x00 +#define SERDES_25G_TOP_PHY_CTRL0_ADDR 0x08 +#define SERDES_25G_TOP_PHY_CFG0_ADDR 0x09 +#define SERDES_25G_TOP_AFE_CALCOMP_CTRL0_ADDR 0x30 +#define SERDES_25G_TOP_AFE_CALCOMP_CTRL1_ADDR 0x31 +#define SERDES_25G_TOP_AFE_CALCOMP_CTRL2_ADDR 0x32 +#define SERDES_25G_TOP_AFE_CALCOMP_STATUS0_ADDR 0x33 +#define SERDES_25G_TOP_AFE_ATEST_CTRL0_ADDR 0x38 +#define SERDES_25G_TOP_AFE_ATEST_CTRL1_ADDR 0x39 +#define SERDES_25G_TOP_RESET_CTRL_CM0_ADDR 0x50 +#define SERDES_25G_TOP_RESET_CTRL_LN0_ADDR 0x54 +#define SERDES_25G_TOP_RESET_CTRL_LN1_ADDR 0x55 +#define SERDES_25G_TOP_RESET_CTRL_LN2_ADDR 0x56 +#define SERDES_25G_TOP_RESET_CTRL_LN3_ADDR 0x57 +#define SERDES_25G_TOP_CLOCK_AFE_CM0_CLK_REF_ADDR 0x100 +#define SERDES_25G_TOP_CLOCK_CM0_CLK_REF_ADDR 0x101 +#define SERDES_25G_TOP_CLOCK_CM0_REFCLK_ADDR 0x102 +#define SERDES_25G_TOP_CLOCK_CM0_CLK_SSC_GEN_ADDR 0x103 +#define SERDES_25G_TOP_CLOCK_CM0_CLK_GCFSM_ADDR 0x104 +#define SERDES_25G_TOP_CLOCK_CM0_CLK_CMPLL_VCO_ADDR 0x105 +#define SERDES_25G_TOP_CLOCK_CM0_CLK_CMU_ADDR 0x106 +#define SERDES_25G_TOP_CLOCK_CM0_CLK_CMU_CTRL1_ADDR 0x107 +#define SERDES_25G_TOP_CLOCK_CM0_CLK_CMUDIV_ADDR 0x108 +#define SERDES_25G_TOP_CLOCK_CM0_CLK_CMUDIV_CTRL1_ADDR 0x109 +#define SERDES_25G_TOP_CLOCK_CM0_CLK_FRACN_FBK_ADDR 0x10A +#define SERDES_25G_TOP_CLOCK_LN0_CLK_TX_ADDR 0x110 +#define SERDES_25G_TOP_CLOCK_AFE_LN0_CLK_RX_ADDR 0x111 +#define SERDES_25G_TOP_CLOCK_LN0_CLK_RX_ADDR 0x112 +#define SERDES_25G_TOP_CLOCK_AFE_LN0_CLK_RXDIV_CORE_ADDR 0x113 +#define SERDES_25G_TOP_CLOCK_LN1_CLK_TX_ADDR 0x118 +#define SERDES_25G_TOP_CLOCK_AFE_LN1_CLK_RX_ADDR 0x119 +#define SERDES_25G_TOP_CLOCK_LN1_CLK_RX_ADDR 0x11A +#define SERDES_25G_TOP_CLOCK_AFE_LN1_CLK_RXDIV_CORE_ADDR 0x11B +#define SERDES_25G_TOP_CLOCK_LN2_CLK_TX_ADDR 0x120 +#define SERDES_25G_TOP_CLOCK_AFE_LN2_CLK_RX_ADDR 0x121 +#define SERDES_25G_TOP_CLOCK_LN2_CLK_RX_ADDR 0x122 +#define SERDES_25G_TOP_CLOCK_AFE_LN2_CLK_RXDIV_CORE_ADDR 0x123 +#define SERDES_25G_TOP_CLOCK_LN3_CLK_TX_ADDR 0x128 +#define SERDES_25G_TOP_CLOCK_AFE_LN3_CLK_RX_ADDR 0x129 +#define SERDES_25G_TOP_CLOCK_LN3_CLK_RX_ADDR 0x12A +#define SERDES_25G_TOP_CLOCK_AFE_LN3_CLK_RXDIV_CORE_ADDR 0x12B +#define SERDES_25G_TOP_LOS_INT_EN_CTRL_ADDR 0x130 +#define SERDES_25G_TOP_INT0_STATUS_ADDR 0x131 +#define SERDES_25G_TOP_REGBUS_TIMER_ADDR 0x170 +#define SERDES_25G_TOP_ERR_CTRL0_ADDR 0x180 +#define SERDES_25G_TOP_ERR_CTRL1_ADDR 0x181 +#define SERDES_25G_TOP_ERR_CTRL2_ADDR 0x182 +#define SERDES_25G_TOP_ERR_STATUS0_ADDR 0x185 +#define SERDES_25G_TOP_REGBUS_ERR_INFO_CTRL_ADDR 0x187 +#define SERDES_25G_TOP_REGBUS_ERR_INFO_STATUS0_ADDR 0x188 +#define SERDES_25G_TOP_REGBUS_ERR_INFO_STATUS1_ADDR 0x189 +#define SERDES_25G_TOP_REGBUS_ERR_INFO_STATUS2_ADDR 0x18A +#define SERDES_25G_TOP_REGBUS_ERR_INFO_STATUS3_ADDR 0x18B +#define SERDES_25G_TOP_REGBUS_ERR_INFO_STATUS4_ADDR 0x18C +#define SERDES_25G_TOP_TBUS_ADDR_7_0_ADDR 0x1A0 +#define SERDES_25G_TOP_TBUS_ADDR_15_8_ADDR 0x1A1 +#define SERDES_25G_TOP_TBUS_CTRL0_ADDR 0x1A2 +#define SERDES_25G_TOP_TBUS_CTRL1_ADDR 0x1A3 +#define SERDES_25G_TOP_TBUS_DATA_7_0_ADDR 0x1B0 +#define SERDES_25G_TOP_TBUS_DATA_11_8_ADDR 0x1B1 +#define SERDES_25G_TOP_SIM_CTRL_ADDR 0x1C0 + +/******************************************************************************* + * masks and shifts + ******************************************************************************/ +#define SERDES_25G_TOP_PHY_STAT0_PHY_CTRL_CFG_MASK 0x0F +#define SERDES_25G_TOP_PHY_STAT0_PHY_CTRL_CFG_SHIFT 0 + +#define SERDES_25G_TOP_PHY_CTRL0_PHY_CTRL_CFG_OVR_VAL_MASK 0x0F +#define SERDES_25G_TOP_PHY_CTRL0_PHY_CTRL_CFG_OVR_VAL_SHIFT 0 + +#define SERDES_25G_TOP_PHY_CTRL0_OVR_EN_MASK 0x80 +#define SERDES_25G_TOP_PHY_CTRL0_OVR_EN_SHIFT 7 + +#define SERDES_25G_TOP_PHY_CFG0_CPU_CLK_FREQ_MASK 0xFF +#define SERDES_25G_TOP_PHY_CFG0_CPU_CLK_FREQ_SHIFT 0 + +#define SERDES_25G_TOP_AFE_CALCOMP_CTRL0_ACAL_EN_MASK 0x0F +#define SERDES_25G_TOP_AFE_CALCOMP_CTRL0_ACAL_EN_SHIFT 0 + +#define SERDES_25G_TOP_AFE_CALCOMP_CTRL1_ACAL_SEL_MASK 0x1F +#define SERDES_25G_TOP_AFE_CALCOMP_CTRL1_ACAL_SEL_SHIFT 0 + +#define SERDES_25G_TOP_AFE_CALCOMP_CTRL2_CALCOMP_EN_MASK 0x01 +#define SERDES_25G_TOP_AFE_CALCOMP_CTRL2_CALCOMP_EN_SHIFT 0 + +#define SERDES_25G_TOP_AFE_CALCOMP_CTRL2_CALCOMP_MUTE_MASK 0x02 +#define SERDES_25G_TOP_AFE_CALCOMP_CTRL2_CALCOMP_MUTE_SHIFT 1 + +#define SERDES_25G_TOP_AFE_CALCOMP_CTRL2_CALCOMP_SEL_MASK 0x04 +#define SERDES_25G_TOP_AFE_CALCOMP_CTRL2_CALCOMP_SEL_SHIFT 2 + +#define SERDES_25G_TOP_AFE_CALCOMP_CTRL2_CALCOMP_SPARE_MASK 0xF0 +#define SERDES_25G_TOP_AFE_CALCOMP_CTRL2_CALCOMP_SPARE_SHIFT 4 + +#define SERDES_25G_TOP_AFE_CALCOMP_STATUS0_CALCOMP_OUT_MASK 0x01 +#define SERDES_25G_TOP_AFE_CALCOMP_STATUS0_CALCOMP_OUT_SHIFT 0 + +#define SERDES_25G_TOP_AFE_ATEST_CTRL0_ATEST_EN_MASK 0x0F +#define SERDES_25G_TOP_AFE_ATEST_CTRL0_ATEST_EN_SHIFT 0 + +#define SERDES_25G_TOP_AFE_ATEST_CTRL1_ATEST_SEL_MASK 0x3F +#define SERDES_25G_TOP_AFE_ATEST_CTRL1_ATEST_SEL_SHIFT 0 + +#define SERDES_25G_TOP_RESET_CTRL_CM0_CORE_SW_RESET_MASK 0x01 +#define SERDES_25G_TOP_RESET_CTRL_CM0_CORE_SW_RESET_SHIFT 0 + +#define SERDES_25G_TOP_RESET_CTRL_CM0_REG_SW_RESET_MASK 0x02 +#define SERDES_25G_TOP_RESET_CTRL_CM0_REG_SW_RESET_SHIFT 1 + +#define SERDES_25G_TOP_RESET_CTRL_CM0_SUBCORE_SW_RESET_MASK 0x04 +#define SERDES_25G_TOP_RESET_CTRL_CM0_SUBCORE_SW_RESET_SHIFT 2 + +#define SERDES_25G_TOP_RESET_CTRL_CM0_CAL_SW_RESET_MASK 0x40 +#define SERDES_25G_TOP_RESET_CTRL_CM0_CAL_SW_RESET_SHIFT 6 + +#define SERDES_25G_TOP_RESET_CTRL_LN0_CORE_SW_RESET_MASK 0x01 +#define SERDES_25G_TOP_RESET_CTRL_LN0_CORE_SW_RESET_SHIFT 0 + +#define SERDES_25G_TOP_RESET_CTRL_LN0_REG_SW_RESET_MASK 0x02 +#define SERDES_25G_TOP_RESET_CTRL_LN0_REG_SW_RESET_SHIFT 1 + +#define SERDES_25G_TOP_RESET_CTRL_LN0_SUBCORE_SW_RESET_MASK 0x04 +#define SERDES_25G_TOP_RESET_CTRL_LN0_SUBCORE_SW_RESET_SHIFT 2 + +#define SERDES_25G_TOP_RESET_CTRL_LN0_TXDP_SW_RESET_MASK 0x08 +#define SERDES_25G_TOP_RESET_CTRL_LN0_TXDP_SW_RESET_SHIFT 3 + +#define SERDES_25G_TOP_RESET_CTRL_LN0_RXDP_SW_RESET_MASK 0x10 +#define SERDES_25G_TOP_RESET_CTRL_LN0_RXDP_SW_RESET_SHIFT 4 + +#define SERDES_25G_TOP_RESET_CTRL_LN0_LOS_SW_RESET_MASK 0x20 +#define SERDES_25G_TOP_RESET_CTRL_LN0_LOS_SW_RESET_SHIFT 5 + +#define SERDES_25G_TOP_RESET_CTRL_LN0_CAL_SW_RESET_MASK 0x40 +#define SERDES_25G_TOP_RESET_CTRL_LN0_CAL_SW_RESET_SHIFT 6 + +#define SERDES_25G_TOP_RESET_CTRL_LN1_CORE_SW_RESET_MASK 0x01 +#define SERDES_25G_TOP_RESET_CTRL_LN1_CORE_SW_RESET_SHIFT 0 + +#define SERDES_25G_TOP_RESET_CTRL_LN1_REG_SW_RESET_MASK 0x02 +#define SERDES_25G_TOP_RESET_CTRL_LN1_REG_SW_RESET_SHIFT 1 + +#define SERDES_25G_TOP_RESET_CTRL_LN1_SUBCORE_SW_RESET_MASK 0x04 +#define SERDES_25G_TOP_RESET_CTRL_LN1_SUBCORE_SW_RESET_SHIFT 2 + +#define SERDES_25G_TOP_RESET_CTRL_LN1_TXDP_SW_RESET_MASK 0x08 +#define SERDES_25G_TOP_RESET_CTRL_LN1_TXDP_SW_RESET_SHIFT 3 + +#define SERDES_25G_TOP_RESET_CTRL_LN1_RXDP_SW_RESET_MASK 0x10 +#define SERDES_25G_TOP_RESET_CTRL_LN1_RXDP_SW_RESET_SHIFT 4 + +#define SERDES_25G_TOP_RESET_CTRL_LN1_LOS_SW_RESET_MASK 0x20 +#define SERDES_25G_TOP_RESET_CTRL_LN1_LOS_SW_RESET_SHIFT 5 + +#define SERDES_25G_TOP_RESET_CTRL_LN1_CAL_SW_RESET_MASK 0x40 +#define SERDES_25G_TOP_RESET_CTRL_LN1_CAL_SW_RESET_SHIFT 6 + +#define SERDES_25G_TOP_RESET_CTRL_LN2_CORE_SW_RESET_MASK 0x01 +#define SERDES_25G_TOP_RESET_CTRL_LN2_CORE_SW_RESET_SHIFT 0 + +#define SERDES_25G_TOP_RESET_CTRL_LN2_REG_SW_RESET_MASK 0x02 +#define SERDES_25G_TOP_RESET_CTRL_LN2_REG_SW_RESET_SHIFT 1 + +#define SERDES_25G_TOP_RESET_CTRL_LN2_SUBCORE_SW_RESET_MASK 0x04 +#define SERDES_25G_TOP_RESET_CTRL_LN2_SUBCORE_SW_RESET_SHIFT 2 + +#define SERDES_25G_TOP_RESET_CTRL_LN2_TXDP_SW_RESET_MASK 0x08 +#define SERDES_25G_TOP_RESET_CTRL_LN2_TXDP_SW_RESET_SHIFT 3 + +#define SERDES_25G_TOP_RESET_CTRL_LN2_RXDP_SW_RESET_MASK 0x10 +#define SERDES_25G_TOP_RESET_CTRL_LN2_RXDP_SW_RESET_SHIFT 4 + +#define SERDES_25G_TOP_RESET_CTRL_LN2_LOS_SW_RESET_MASK 0x20 +#define SERDES_25G_TOP_RESET_CTRL_LN2_LOS_SW_RESET_SHIFT 5 + +#define SERDES_25G_TOP_RESET_CTRL_LN2_CAL_SW_RESET_MASK 0x40 +#define SERDES_25G_TOP_RESET_CTRL_LN2_CAL_SW_RESET_SHIFT 6 + +#define SERDES_25G_TOP_RESET_CTRL_LN3_CORE_SW_RESET_MASK 0x01 +#define SERDES_25G_TOP_RESET_CTRL_LN3_CORE_SW_RESET_SHIFT 0 + +#define SERDES_25G_TOP_RESET_CTRL_LN3_REG_SW_RESET_MASK 0x02 +#define SERDES_25G_TOP_RESET_CTRL_LN3_REG_SW_RESET_SHIFT 1 + +#define SERDES_25G_TOP_RESET_CTRL_LN3_SUBCORE_SW_RESET_MASK 0x04 +#define SERDES_25G_TOP_RESET_CTRL_LN3_SUBCORE_SW_RESET_SHIFT 2 + +#define SERDES_25G_TOP_RESET_CTRL_LN3_TXDP_SW_RESET_MASK 0x08 +#define SERDES_25G_TOP_RESET_CTRL_LN3_TXDP_SW_RESET_SHIFT 3 + +#define SERDES_25G_TOP_RESET_CTRL_LN3_RXDP_SW_RESET_MASK 0x10 +#define SERDES_25G_TOP_RESET_CTRL_LN3_RXDP_SW_RESET_SHIFT 4 + +#define SERDES_25G_TOP_RESET_CTRL_LN3_LOS_SW_RESET_MASK 0x20 +#define SERDES_25G_TOP_RESET_CTRL_LN3_LOS_SW_RESET_SHIFT 5 + +#define SERDES_25G_TOP_RESET_CTRL_LN3_CAL_SW_RESET_MASK 0x40 +#define SERDES_25G_TOP_RESET_CTRL_LN3_CAL_SW_RESET_SHIFT 6 + +#define SERDES_25G_TOP_CLOCK_AFE_CM0_CLK_REF_CTRL_SRC_SEL_MASK 0x01 +#define SERDES_25G_TOP_CLOCK_AFE_CM0_CLK_REF_CTRL_SRC_SEL_SHIFT 0 + +#define SERDES_25G_TOP_CLOCK_AFE_CM0_CLK_REF_STAT_DEFAULT_CLK_EN_MASK 0x02 +#define SERDES_25G_TOP_CLOCK_AFE_CM0_CLK_REF_STAT_DEFAULT_CLK_EN_SHIFT 1 + +#define SERDES_25G_TOP_CLOCK_AFE_CM0_CLK_REF_STAT_REF_CLK_EN_MASK 0x04 +#define SERDES_25G_TOP_CLOCK_AFE_CM0_CLK_REF_STAT_REF_CLK_EN_SHIFT 2 + +#define SERDES_25G_TOP_CLOCK_AFE_CM0_CLK_REF_CTRL_TBUS_OUT_CG_EN_MASK 0x80 +#define SERDES_25G_TOP_CLOCK_AFE_CM0_CLK_REF_CTRL_TBUS_OUT_CG_EN_SHIFT 7 + +#define SERDES_25G_TOP_CLOCK_CM0_CLK_REF_CTRL_DIV_SEL_MASK 0x01 +#define SERDES_25G_TOP_CLOCK_CM0_CLK_REF_CTRL_DIV_SEL_SHIFT 0 + +#define SERDES_25G_TOP_CLOCK_CM0_CLK_REF_CTRL_TBUS_OUT_CG_EN_MASK 0x80 +#define SERDES_25G_TOP_CLOCK_CM0_CLK_REF_CTRL_TBUS_OUT_CG_EN_SHIFT 7 + +#define SERDES_25G_TOP_CLOCK_CM0_REFCLK_CTRL_CG_EN_MASK 0x01 +#define SERDES_25G_TOP_CLOCK_CM0_REFCLK_CTRL_CG_EN_SHIFT 0 + +#define SERDES_25G_TOP_CLOCK_CM0_REFCLK_CTRL_TBUS_OUT_CG_EN_MASK 0x80 +#define SERDES_25G_TOP_CLOCK_CM0_REFCLK_CTRL_TBUS_OUT_CG_EN_SHIFT 7 + +#define SERDES_25G_TOP_CLOCK_CM0_CLK_SSC_GEN_CTRL_DIV_SEL_MASK 0x07 +#define SERDES_25G_TOP_CLOCK_CM0_CLK_SSC_GEN_CTRL_DIV_SEL_SHIFT 0 + +#define SERDES_25G_TOP_CLOCK_CM0_CLK_SSC_GEN_CTRL_TBUS_OUT_CG_EN_MASK 0x80 +#define SERDES_25G_TOP_CLOCK_CM0_CLK_SSC_GEN_CTRL_TBUS_OUT_CG_EN_SHIFT 7 + +#define SERDES_25G_TOP_CLOCK_CM0_CLK_GCFSM_CTRL_DIV_SEL_MASK 0x07 +#define SERDES_25G_TOP_CLOCK_CM0_CLK_GCFSM_CTRL_DIV_SEL_SHIFT 0 + +#define SERDES_25G_TOP_CLOCK_CM0_CLK_GCFSM_CTRL_TBUS_OUT_CG_EN_MASK 0x80 +#define SERDES_25G_TOP_CLOCK_CM0_CLK_GCFSM_CTRL_TBUS_OUT_CG_EN_SHIFT 7 + +#define SERDES_25G_TOP_CLOCK_CM0_CLK_CMPLL_VCO_CTRL_DIV_SEL_MASK 0x01 +#define SERDES_25G_TOP_CLOCK_CM0_CLK_CMPLL_VCO_CTRL_DIV_SEL_SHIFT 0 + +#define SERDES_25G_TOP_CLOCK_CM0_CLK_CMPLL_VCO_CTRL_CG_EN_MASK 0x02 +#define SERDES_25G_TOP_CLOCK_CM0_CLK_CMPLL_VCO_CTRL_CG_EN_SHIFT 1 + +#define SERDES_25G_TOP_CLOCK_CM0_CLK_CMPLL_VCO_CTRL_TBUS_OUT_CG_EN_MASK 0x80 +#define SERDES_25G_TOP_CLOCK_CM0_CLK_CMPLL_VCO_CTRL_TBUS_OUT_CG_EN_SHIFT 7 + +#define SERDES_25G_TOP_CLOCK_CM0_CLK_CMU_CTRL_SRC_SEL_MASK 0x01 +#define SERDES_25G_TOP_CLOCK_CM0_CLK_CMU_CTRL_SRC_SEL_SHIFT 0 + +#define SERDES_25G_TOP_CLOCK_CM0_CLK_CMU_STAT_DEFAULT_CLK_EN_MASK 0x02 +#define SERDES_25G_TOP_CLOCK_CM0_CLK_CMU_STAT_DEFAULT_CLK_EN_SHIFT 1 + +#define SERDES_25G_TOP_CLOCK_CM0_CLK_CMU_STAT_CMU_CLK_EN_MASK 0x04 +#define SERDES_25G_TOP_CLOCK_CM0_CLK_CMU_STAT_CMU_CLK_EN_SHIFT 2 + +#define SERDES_25G_TOP_CLOCK_CM0_CLK_CMU_CTRL_DIV_SEL_MASK 0xF8 +#define SERDES_25G_TOP_CLOCK_CM0_CLK_CMU_CTRL_DIV_SEL_SHIFT 3 + +#define SERDES_25G_TOP_CLOCK_CM0_CLK_CMU_CTRL1_TBUS_OUT_CG_EN_MASK 0x80 +#define SERDES_25G_TOP_CLOCK_CM0_CLK_CMU_CTRL1_TBUS_OUT_CG_EN_SHIFT 7 + +#define SERDES_25G_TOP_CLOCK_CM0_CLK_CMUDIV_CTRL_SRC_SEL_MASK 0x01 +#define SERDES_25G_TOP_CLOCK_CM0_CLK_CMUDIV_CTRL_SRC_SEL_SHIFT 0 + +#define SERDES_25G_TOP_CLOCK_CM0_CLK_CMUDIV_STAT_DEFAULT_CLK_EN_MASK 0x02 +#define SERDES_25G_TOP_CLOCK_CM0_CLK_CMUDIV_STAT_DEFAULT_CLK_EN_SHIFT 1 + +#define SERDES_25G_TOP_CLOCK_CM0_CLK_CMUDIV_STAT_CMUDIV_CLK_EN_MASK 0x04 +#define SERDES_25G_TOP_CLOCK_CM0_CLK_CMUDIV_STAT_CMUDIV_CLK_EN_SHIFT 2 + +#define SERDES_25G_TOP_CLOCK_CM0_CLK_CMUDIV_CTRL_DIV_SEL_MASK 0xF8 +#define SERDES_25G_TOP_CLOCK_CM0_CLK_CMUDIV_CTRL_DIV_SEL_SHIFT 3 + +#define SERDES_25G_TOP_CLOCK_CM0_CLK_CMUDIV_CTRL1_TBUS_OUT_CG_EN_MASK 0x80 +#define SERDES_25G_TOP_CLOCK_CM0_CLK_CMUDIV_CTRL1_TBUS_OUT_CG_EN_SHIFT 7 + +#define SERDES_25G_TOP_CLOCK_CM0_CLK_FRACN_FBK_CTRL_FRCDIV_MODE_EN_MASK 0x01 +#define SERDES_25G_TOP_CLOCK_CM0_CLK_FRACN_FBK_CTRL_FRCDIV_MODE_EN_SHIFT 0 + +#define SERDES_25G_TOP_CLOCK_CM0_CLK_FRACN_FBK_CTRL_SRC_SEL_MASK 0x06 +#define SERDES_25G_TOP_CLOCK_CM0_CLK_FRACN_FBK_CTRL_SRC_SEL_SHIFT 1 + +#define SERDES_25G_TOP_CLOCK_CM0_CLK_FRACN_FBK_CTRL_DIV_SEL_MASK 0x08 +#define SERDES_25G_TOP_CLOCK_CM0_CLK_FRACN_FBK_CTRL_DIV_SEL_SHIFT 3 + +#define SERDES_25G_TOP_CLOCK_CM0_CLK_FRACN_FBK_CTRL_TBUS_OUT_CG_EN_MASK 0x80 +#define SERDES_25G_TOP_CLOCK_CM0_CLK_FRACN_FBK_CTRL_TBUS_OUT_CG_EN_SHIFT 7 + +#define SERDES_25G_TOP_CLOCK_LN0_CLK_TX_CTRL_SRC_SEL_MASK 0x03 +#define SERDES_25G_TOP_CLOCK_LN0_CLK_TX_CTRL_SRC_SEL_SHIFT 0 + +#define SERDES_25G_TOP_CLOCK_LN0_CLK_TX_CTRL_DIV_SEL_MASK 0x04 +#define SERDES_25G_TOP_CLOCK_LN0_CLK_TX_CTRL_DIV_SEL_SHIFT 2 + +#define SERDES_25G_TOP_CLOCK_LN0_CLK_TX_CTRL_BIST_CG_EN_MASK 0x10 +#define SERDES_25G_TOP_CLOCK_LN0_CLK_TX_CTRL_BIST_CG_EN_SHIFT 4 + +#define SERDES_25G_TOP_CLOCK_LN0_CLK_TX_CTRL_TBUS_OUT_CG_EN_MASK 0x80 +#define SERDES_25G_TOP_CLOCK_LN0_CLK_TX_CTRL_TBUS_OUT_CG_EN_SHIFT 7 + +#define SERDES_25G_TOP_CLOCK_AFE_LN0_CLK_RX_CTRL_SRC_SEL_MASK 0x01 +#define SERDES_25G_TOP_CLOCK_AFE_LN0_CLK_RX_CTRL_SRC_SEL_SHIFT 0 + +#define SERDES_25G_TOP_CLOCK_AFE_LN0_CLK_RX_STAT_DEFAULT_CLK_EN_MASK 0x02 +#define SERDES_25G_TOP_CLOCK_AFE_LN0_CLK_RX_STAT_DEFAULT_CLK_EN_SHIFT 1 + +#define SERDES_25G_TOP_CLOCK_AFE_LN0_CLK_RX_STAT_RX_CLK_EN_MASK 0x04 +#define SERDES_25G_TOP_CLOCK_AFE_LN0_CLK_RX_STAT_RX_CLK_EN_SHIFT 2 + +#define SERDES_25G_TOP_CLOCK_AFE_LN0_CLK_RX_CTRL_TBUS_OUT_CG_EN_MASK 0x80 +#define SERDES_25G_TOP_CLOCK_AFE_LN0_CLK_RX_CTRL_TBUS_OUT_CG_EN_SHIFT 7 + +#define SERDES_25G_TOP_CLOCK_LN0_CLK_RX_CTRL_SRC_SEL_MASK 0x03 +#define SERDES_25G_TOP_CLOCK_LN0_CLK_RX_CTRL_SRC_SEL_SHIFT 0 + +#define SERDES_25G_TOP_CLOCK_LN0_CLK_RX_CTRL_CG_EN_MASK 0x10 +#define SERDES_25G_TOP_CLOCK_LN0_CLK_RX_CTRL_CG_EN_SHIFT 4 + +#define SERDES_25G_TOP_CLOCK_LN0_CLK_RX_CTRL_BIST_CG_EN_MASK 0x20 +#define SERDES_25G_TOP_CLOCK_LN0_CLK_RX_CTRL_BIST_CG_EN_SHIFT 5 + +#define SERDES_25G_TOP_CLOCK_LN0_CLK_RX_CTRL_TBUS_OUT_CG_EN_MASK 0x80 +#define SERDES_25G_TOP_CLOCK_LN0_CLK_RX_CTRL_TBUS_OUT_CG_EN_SHIFT 7 + +#define SERDES_25G_TOP_CLOCK_AFE_LN0_CLK_RXDIV_CORE_CTRL_SRC_SEL_MASK 0x01 +#define SERDES_25G_TOP_CLOCK_AFE_LN0_CLK_RXDIV_CORE_CTRL_SRC_SEL_SHIFT 0 + +#define SERDES_25G_TOP_CLOCK_AFE_LN0_CLK_RXDIV_CORE_STAT_DEFAULT_CLK_EN_MASK 0x02 +#define SERDES_25G_TOP_CLOCK_AFE_LN0_CLK_RXDIV_CORE_STAT_DEFAULT_CLK_EN_SHIFT 1 + +#define SERDES_25G_TOP_CLOCK_AFE_LN0_CLK_RXDIV_CORE_STAT_RX_CLKDIV_EN_MASK 0x04 +#define SERDES_25G_TOP_CLOCK_AFE_LN0_CLK_RXDIV_CORE_STAT_RX_CLKDIV_EN_SHIFT 2 + +#define SERDES_25G_TOP_CLOCK_AFE_LN0_CLK_RXDIV_CORE_CTRL_TBUS_OUT_CG_EN_MASK 0x80 +#define SERDES_25G_TOP_CLOCK_AFE_LN0_CLK_RXDIV_CORE_CTRL_TBUS_OUT_CG_EN_SHIFT 7 + +#define SERDES_25G_TOP_CLOCK_LN1_CLK_TX_CTRL_SRC_SEL_MASK 0x03 +#define SERDES_25G_TOP_CLOCK_LN1_CLK_TX_CTRL_SRC_SEL_SHIFT 0 + +#define SERDES_25G_TOP_CLOCK_LN1_CLK_TX_CTRL_DIV_SEL_MASK 0x04 +#define SERDES_25G_TOP_CLOCK_LN1_CLK_TX_CTRL_DIV_SEL_SHIFT 2 + +#define SERDES_25G_TOP_CLOCK_LN1_CLK_TX_CTRL_BIST_CG_EN_MASK 0x10 +#define SERDES_25G_TOP_CLOCK_LN1_CLK_TX_CTRL_BIST_CG_EN_SHIFT 4 + +#define SERDES_25G_TOP_CLOCK_LN1_CLK_TX_CTRL_TBUS_OUT_CG_EN_MASK 0x80 +#define SERDES_25G_TOP_CLOCK_LN1_CLK_TX_CTRL_TBUS_OUT_CG_EN_SHIFT 7 + +#define SERDES_25G_TOP_CLOCK_AFE_LN1_CLK_RX_CTRL_SRC_SEL_MASK 0x01 +#define SERDES_25G_TOP_CLOCK_AFE_LN1_CLK_RX_CTRL_SRC_SEL_SHIFT 0 + +#define SERDES_25G_TOP_CLOCK_AFE_LN1_CLK_RX_STAT_DEFAULT_CLK_EN_MASK 0x02 +#define SERDES_25G_TOP_CLOCK_AFE_LN1_CLK_RX_STAT_DEFAULT_CLK_EN_SHIFT 1 + +#define SERDES_25G_TOP_CLOCK_AFE_LN1_CLK_RX_STAT_RX_CLK_EN_MASK 0x04 +#define SERDES_25G_TOP_CLOCK_AFE_LN1_CLK_RX_STAT_RX_CLK_EN_SHIFT 2 + +#define SERDES_25G_TOP_CLOCK_AFE_LN1_CLK_RX_CTRL_TBUS_OUT_CG_EN_MASK 0x80 +#define SERDES_25G_TOP_CLOCK_AFE_LN1_CLK_RX_CTRL_TBUS_OUT_CG_EN_SHIFT 7 + +#define SERDES_25G_TOP_CLOCK_LN1_CLK_RX_CTRL_SRC_SEL_MASK 0x03 +#define SERDES_25G_TOP_CLOCK_LN1_CLK_RX_CTRL_SRC_SEL_SHIFT 0 + +#define SERDES_25G_TOP_CLOCK_LN1_CLK_RX_CTRL_CG_EN_MASK 0x10 +#define SERDES_25G_TOP_CLOCK_LN1_CLK_RX_CTRL_CG_EN_SHIFT 4 + +#define SERDES_25G_TOP_CLOCK_LN1_CLK_RX_CTRL_BIST_CG_EN_MASK 0x20 +#define SERDES_25G_TOP_CLOCK_LN1_CLK_RX_CTRL_BIST_CG_EN_SHIFT 5 + +#define SERDES_25G_TOP_CLOCK_LN1_CLK_RX_CTRL_TBUS_OUT_CG_EN_MASK 0x80 +#define SERDES_25G_TOP_CLOCK_LN1_CLK_RX_CTRL_TBUS_OUT_CG_EN_SHIFT 7 + +#define SERDES_25G_TOP_CLOCK_LN2_CLK_TX_CTRL_SRC_SEL_MASK 0x03 +#define SERDES_25G_TOP_CLOCK_LN2_CLK_TX_CTRL_SRC_SEL_SHIFT 0 + +#define SERDES_25G_TOP_CLOCK_LN2_CLK_TX_CTRL_DIV_SEL_MASK 0x04 +#define SERDES_25G_TOP_CLOCK_LN2_CLK_TX_CTRL_DIV_SEL_SHIFT 2 + +#define SERDES_25G_TOP_CLOCK_LN2_CLK_TX_CTRL_BIST_CG_EN_MASK 0x10 +#define SERDES_25G_TOP_CLOCK_LN2_CLK_TX_CTRL_BIST_CG_EN_SHIFT 4 + +#define SERDES_25G_TOP_CLOCK_LN2_CLK_TX_CTRL_TBUS_OUT_CG_EN_MASK 0x80 +#define SERDES_25G_TOP_CLOCK_LN2_CLK_TX_CTRL_TBUS_OUT_CG_EN_SHIFT 7 + +#define SERDES_25G_TOP_CLOCK_AFE_LN2_CLK_RX_CTRL_SRC_SEL_MASK 0x01 +#define SERDES_25G_TOP_CLOCK_AFE_LN2_CLK_RX_CTRL_SRC_SEL_SHIFT 0 + +#define SERDES_25G_TOP_CLOCK_AFE_LN2_CLK_RX_STAT_DEFAULT_CLK_EN_MASK 0x02 +#define SERDES_25G_TOP_CLOCK_AFE_LN2_CLK_RX_STAT_DEFAULT_CLK_EN_SHIFT 1 + +#define SERDES_25G_TOP_CLOCK_AFE_LN2_CLK_RX_STAT_RX_CLK_EN_MASK 0x04 +#define SERDES_25G_TOP_CLOCK_AFE_LN2_CLK_RX_STAT_RX_CLK_EN_SHIFT 2 + +#define SERDES_25G_TOP_CLOCK_AFE_LN2_CLK_RX_CTRL_TBUS_OUT_CG_EN_MASK 0x80 +#define SERDES_25G_TOP_CLOCK_AFE_LN2_CLK_RX_CTRL_TBUS_OUT_CG_EN_SHIFT 7 + +#define SERDES_25G_TOP_CLOCK_LN2_CLK_RX_CTRL_SRC_SEL_MASK 0x03 +#define SERDES_25G_TOP_CLOCK_LN2_CLK_RX_CTRL_SRC_SEL_SHIFT 0 + +#define SERDES_25G_TOP_CLOCK_LN2_CLK_RX_CTRL_CG_EN_MASK 0x10 +#define SERDES_25G_TOP_CLOCK_LN2_CLK_RX_CTRL_CG_EN_SHIFT 4 + +#define SERDES_25G_TOP_CLOCK_LN2_CLK_RX_CTRL_BIST_CG_EN_MASK 0x20 +#define SERDES_25G_TOP_CLOCK_LN2_CLK_RX_CTRL_BIST_CG_EN_SHIFT 5 + +#define SERDES_25G_TOP_CLOCK_LN2_CLK_RX_CTRL_TBUS_OUT_CG_EN_MASK 0x80 +#define SERDES_25G_TOP_CLOCK_LN2_CLK_RX_CTRL_TBUS_OUT_CG_EN_SHIFT 7 + +#define SERDES_25G_TOP_CLOCK_LN3_CLK_TX_CTRL_SRC_SEL_MASK 0x03 +#define SERDES_25G_TOP_CLOCK_LN3_CLK_TX_CTRL_SRC_SEL_SHIFT 0 + +#define SERDES_25G_TOP_CLOCK_LN3_CLK_TX_CTRL_DIV_SEL_MASK 0x04 +#define SERDES_25G_TOP_CLOCK_LN3_CLK_TX_CTRL_DIV_SEL_SHIFT 2 + +#define SERDES_25G_TOP_CLOCK_LN3_CLK_TX_CTRL_BIST_CG_EN_MASK 0x10 +#define SERDES_25G_TOP_CLOCK_LN3_CLK_TX_CTRL_BIST_CG_EN_SHIFT 4 + +#define SERDES_25G_TOP_CLOCK_LN3_CLK_TX_CTRL_TBUS_OUT_CG_EN_MASK 0x80 +#define SERDES_25G_TOP_CLOCK_LN3_CLK_TX_CTRL_TBUS_OUT_CG_EN_SHIFT 7 + +#define SERDES_25G_TOP_CLOCK_AFE_LN3_CLK_RX_CTRL_SRC_SEL_MASK 0x01 +#define SERDES_25G_TOP_CLOCK_AFE_LN3_CLK_RX_CTRL_SRC_SEL_SHIFT 0 + +#define SERDES_25G_TOP_CLOCK_AFE_LN3_CLK_RX_STAT_DEFAULT_CLK_EN_MASK 0x02 +#define SERDES_25G_TOP_CLOCK_AFE_LN3_CLK_RX_STAT_DEFAULT_CLK_EN_SHIFT 1 + +#define SERDES_25G_TOP_CLOCK_AFE_LN3_CLK_RX_STAT_RX_CLK_EN_MASK 0x04 +#define SERDES_25G_TOP_CLOCK_AFE_LN3_CLK_RX_STAT_RX_CLK_EN_SHIFT 2 + +#define SERDES_25G_TOP_CLOCK_AFE_LN3_CLK_RX_CTRL_TBUS_OUT_CG_EN_MASK 0x80 +#define SERDES_25G_TOP_CLOCK_AFE_LN3_CLK_RX_CTRL_TBUS_OUT_CG_EN_SHIFT 7 + +#define SERDES_25G_TOP_CLOCK_LN3_CLK_RX_CTRL_SRC_SEL_MASK 0x03 +#define SERDES_25G_TOP_CLOCK_LN3_CLK_RX_CTRL_SRC_SEL_SHIFT 0 + +#define SERDES_25G_TOP_CLOCK_LN3_CLK_RX_CTRL_CG_EN_MASK 0x10 +#define SERDES_25G_TOP_CLOCK_LN3_CLK_RX_CTRL_CG_EN_SHIFT 4 + +#define SERDES_25G_TOP_CLOCK_LN3_CLK_RX_CTRL_BIST_CG_EN_MASK 0x20 +#define SERDES_25G_TOP_CLOCK_LN3_CLK_RX_CTRL_BIST_CG_EN_SHIFT 5 + +#define SERDES_25G_TOP_CLOCK_LN3_CLK_RX_CTRL_TBUS_OUT_CG_EN_MASK 0x80 +#define SERDES_25G_TOP_CLOCK_LN3_CLK_RX_CTRL_TBUS_OUT_CG_EN_SHIFT 7 + +#define SERDES_25G_TOP_LOS_INT_EN_CTRL_LN0_MASK 0x01 +#define SERDES_25G_TOP_LOS_INT_EN_CTRL_LN0_SHIFT 0 + +#define SERDES_25G_TOP_LOS_INT_EN_CTRL_LN1_MASK 0x02 +#define SERDES_25G_TOP_LOS_INT_EN_CTRL_LN1_SHIFT 1 + +#define SERDES_25G_TOP_LOS_INT_EN_CTRL_LN2_MASK 0x04 +#define SERDES_25G_TOP_LOS_INT_EN_CTRL_LN2_SHIFT 2 + +#define SERDES_25G_TOP_LOS_INT_EN_CTRL_LN3_MASK 0x08 +#define SERDES_25G_TOP_LOS_INT_EN_CTRL_LN3_SHIFT 3 + +#define SERDES_25G_TOP_REGBUS_TIMER_LOAD_VAL_MASK 0xFF +#define SERDES_25G_TOP_REGBUS_TIMER_LOAD_VAL_SHIFT 0 + +#define SERDES_25G_TOP_ERR_CTRL0_ERR_MASK 0x01 +#define SERDES_25G_TOP_ERR_CTRL0_ERR_SHIFT 0 + +#define SERDES_25G_TOP_ERR_CTRL1_ERR_CODE_7_0_MASK 0xFF +#define SERDES_25G_TOP_ERR_CTRL1_ERR_CODE_7_0_SHIFT 0 + +#define SERDES_25G_TOP_ERR_CTRL2_ERR_CODE_15_8_MASK 0xFF +#define SERDES_25G_TOP_ERR_CTRL2_ERR_CODE_15_8_SHIFT 0 + +#define SERDES_25G_TOP_ERR_STATUS0_REGBUS_ERR_MASK 0x01 +#define SERDES_25G_TOP_ERR_STATUS0_REGBUS_ERR_SHIFT 0 + +#define SERDES_25G_TOP_REGBUS_ERR_INFO_CTRL_CLR_MASK 0x01 +#define SERDES_25G_TOP_REGBUS_ERR_INFO_CTRL_CLR_SHIFT 0 + +#define SERDES_25G_TOP_REGBUS_ERR_INFO_STATUS0_ERR_TYPE_MASK 0x03 +#define SERDES_25G_TOP_REGBUS_ERR_INFO_STATUS0_ERR_TYPE_SHIFT 0 + +#define SERDES_25G_TOP_REGBUS_ERR_INFO_STATUS0_TRANSFER_RW_MASK 0x04 +#define SERDES_25G_TOP_REGBUS_ERR_INFO_STATUS0_TRANSFER_RW_SHIFT 2 + +#define SERDES_25G_TOP_REGBUS_ERR_INFO_STATUS1_TRANSFER_ADDR_LSB_MASK 0xFF +#define SERDES_25G_TOP_REGBUS_ERR_INFO_STATUS1_TRANSFER_ADDR_LSB_SHIFT 0 + +#define SERDES_25G_TOP_REGBUS_ERR_INFO_STATUS2_TRANSFER_ADDR_MSB_MASK 0x7F +#define SERDES_25G_TOP_REGBUS_ERR_INFO_STATUS2_TRANSFER_ADDR_MSB_SHIFT 0 + +#define SERDES_25G_TOP_REGBUS_ERR_INFO_STATUS3_TRANSFER_WD_MASK 0xFF +#define SERDES_25G_TOP_REGBUS_ERR_INFO_STATUS3_TRANSFER_WD_SHIFT 0 + +#define SERDES_25G_TOP_REGBUS_ERR_INFO_STATUS4_TRANSFER_WR_BIT_EN_MASK 0xFF +#define SERDES_25G_TOP_REGBUS_ERR_INFO_STATUS4_TRANSFER_WR_BIT_EN_SHIFT 0 + +#define SERDES_25G_TOP_TBUS_ADDR_7_0_MASK 0xFF +#define SERDES_25G_TOP_TBUS_ADDR_7_0_SHIFT 0 + +#define SERDES_25G_TOP_TBUS_ADDR_15_8_MASK 0xFF +#define SERDES_25G_TOP_TBUS_ADDR_15_8_SHIFT 0 + +#define SERDES_25G_TOP_TBUS_CTRL0_CLOCK_GATE0_MASK 0xFF +#define SERDES_25G_TOP_TBUS_CTRL0_CLOCK_GATE0_SHIFT 0 + +#define SERDES_25G_TOP_TBUS_CTRL1_CLOCK_GATE1_MASK 0xFF +#define SERDES_25G_TOP_TBUS_CTRL1_CLOCK_GATE1_SHIFT 0 + +#define SERDES_25G_TOP_TBUS_DATA_7_0_MASK 0xFF +#define SERDES_25G_TOP_TBUS_DATA_7_0_SHIFT 0 + +#define SERDES_25G_TOP_TBUS_DATA_11_8_MASK 0x0F +#define SERDES_25G_TOP_TBUS_DATA_11_8_SHIFT 0 + +/*********************************** Mailbox **********************************/ +#define SERDES_25G_TOP_MB_BASE 0x200 + +#define SERDES_25G_TOP_CMD_ADDR (SERDES_25G_TOP_MB_BASE + 0x00) +#define SERDES_25G_TOP_CMD_FLAG_ADDR (SERDES_25G_TOP_MB_BASE + 0x02) +#define SERDES_25G_TOP_CMD_DATA0_ADDR (SERDES_25G_TOP_MB_BASE + 0x03) +#define SERDES_25G_TOP_CMD_DATA1_ADDR (SERDES_25G_TOP_MB_BASE + 0x04) +#define SERDES_25G_TOP_CMD_DATA2_ADDR (SERDES_25G_TOP_MB_BASE + 0x05) +#define SERDES_25G_TOP_CMD_DATA3_ADDR (SERDES_25G_TOP_MB_BASE + 0x06) +#define SERDES_25G_TOP_CMD_DATA4_ADDR (SERDES_25G_TOP_MB_BASE + 0x07) +#define SERDES_25G_TOP_CMD_DATA5_ADDR (SERDES_25G_TOP_MB_BASE + 0x08) +#define SERDES_25G_TOP_CMD_DATA6_ADDR (SERDES_25G_TOP_MB_BASE + 0x09) +#define SERDES_25G_TOP_CMD_DATA7_ADDR (SERDES_25G_TOP_MB_BASE + 0x0A) +#define SERDES_25G_TOP_RSP_ADDR (SERDES_25G_TOP_MB_BASE + 0x10) +#define SERDES_25G_TOP_RSP_FLAG_ADDR (SERDES_25G_TOP_MB_BASE + 0x12) +#define SERDES_25G_TOP_RSP_DATA0_ADDR (SERDES_25G_TOP_MB_BASE + 0x13) +#define SERDES_25G_TOP_RSP_DATA1_ADDR (SERDES_25G_TOP_MB_BASE + 0x14) +#define SERDES_25G_TOP_RSP_DATA2_ADDR (SERDES_25G_TOP_MB_BASE + 0x15) +#define SERDES_25G_TOP_RSP_DATA3_ADDR (SERDES_25G_TOP_MB_BASE + 0x16) +#define SERDES_25G_TOP_RSP_DATA4_ADDR (SERDES_25G_TOP_MB_BASE + 0x17) +#define SERDES_25G_TOP_RSP_DATA5_ADDR (SERDES_25G_TOP_MB_BASE + 0x18) +#define SERDES_25G_TOP_RSP_DATA6_ADDR (SERDES_25G_TOP_MB_BASE + 0x19) +#define SERDES_25G_TOP_RSP_DATA7_ADDR (SERDES_25G_TOP_MB_BASE + 0x1A) +#define SERDES_25G_TOP_RSP_DATA8_ADDR (SERDES_25G_TOP_MB_BASE + 0x1B) +#define SERDES_25G_TOP_RSP_DATA9_ADDR (SERDES_25G_TOP_MB_BASE + 0x1C) +#define SERDES_25G_TOP_RSP_DATA10_ADDR (SERDES_25G_TOP_MB_BASE + 0x1D) +#define SERDES_25G_TOP_RSP_DATA11_ADDR (SERDES_25G_TOP_MB_BASE + 0x1E) +#define SERDES_25G_TOP_RSP_DATA12_ADDR (SERDES_25G_TOP_MB_BASE + 0x1F) +#define SERDES_25G_TOP_RSP_DATA13_ADDR (SERDES_25G_TOP_MB_BASE + 0x20) +#define SERDES_25G_TOP_RSP_DATA14_ADDR (SERDES_25G_TOP_MB_BASE + 0x21) +#define SERDES_25G_TOP_RSP_DATA15_ADDR (SERDES_25G_TOP_MB_BASE + 0x22) +/******************************************************************************* + * masks and shifts + ******************************************************************************/ +#define SERDES_25G_TOP_CMD_MASK 0xFF +#define SERDES_25G_TOP_CMD_SHIFT 0 + +#define SERDES_25G_TOP_CMD_FLAG_MASK 0x01 +#define SERDES_25G_TOP_CMD_FLAG_SHIFT 0 + +#define SERDES_25G_TOP_CMD_DATA0_MASK 0xFF +#define SERDES_25G_TOP_CMD_DATA0_SHIFT 0 + +#define SERDES_25G_TOP_CMD_DATA1_MASK 0xFF +#define SERDES_25G_TOP_CMD_DATA1_SHIFT 0 + +#define SERDES_25G_TOP_CMD_DATA2_MASK 0xFF +#define SERDES_25G_TOP_CMD_DATA2_SHIFT 0 + +#define SERDES_25G_TOP_CMD_DATA3_MASK 0xFF +#define SERDES_25G_TOP_CMD_DATA3_SHIFT 0 + +#define SERDES_25G_TOP_CMD_DATA4_MASK 0xFF +#define SERDES_25G_TOP_CMD_DATA4_SHIFT 0 + +#define SERDES_25G_TOP_CMD_DATA5_MASK 0xFF +#define SERDES_25G_TOP_CMD_DATA5_SHIFT 0 + +#define SERDES_25G_TOP_CMD_DATA6_MASK 0xFF +#define SERDES_25G_TOP_CMD_DATA6_SHIFT 0 + +#define SERDES_25G_TOP_CMD_DATA7_MASK 0xFF +#define SERDES_25G_TOP_CMD_DATA7_SHIFT 0 + +#define SERDES_25G_TOP_RSP_MASK 0xFF +#define SERDES_25G_TOP_RSP_SHIFT 0 + +#define SERDES_25G_TOP_RSP_FLAG_MASK 0x01 +#define SERDES_25G_TOP_RSP_FLAG_SHIFT 0 + +#define SERDES_25G_TOP_RSP_DATA0_MASK 0xFF +#define SERDES_25G_TOP_RSP_DATA0_SHIFT 0 + +#define SERDES_25G_TOP_RSP_DATA1_MASK 0xFF +#define SERDES_25G_TOP_RSP_DATA1_SHIFT 0 + +#define SERDES_25G_TOP_RSP_DATA2_MASK 0xFF +#define SERDES_25G_TOP_RSP_DATA2_SHIFT 0 + +#define SERDES_25G_TOP_RSP_DATA3_MASK 0xFF +#define SERDES_25G_TOP_RSP_DATA3_SHIFT 0 + +#define SERDES_25G_TOP_RSP_DATA4_MASK 0xFF +#define SERDES_25G_TOP_RSP_DATA4_SHIFT 0 + +#define SERDES_25G_TOP_RSP_DATA5_MASK 0xFF +#define SERDES_25G_TOP_RSP_DATA5_SHIFT 0 + +#define SERDES_25G_TOP_RSP_DATA6_MASK 0xFF +#define SERDES_25G_TOP_RSP_DATA6_SHIFT 0 + +#define SERDES_25G_TOP_RSP_DATA7_MASK 0xFF +#define SERDES_25G_TOP_RSP_DATA7_SHIFT 0 + +#define SERDES_25G_TOP_RSP_DATA8_MASK 0xFF +#define SERDES_25G_TOP_RSP_DATA8_SHIFT 0 + +#define SERDES_25G_TOP_RSP_DATA9_MASK 0xFF +#define SERDES_25G_TOP_RSP_DATA9_SHIFT 0 + +#define SERDES_25G_TOP_RSP_DATA10_MASK 0xFF +#define SERDES_25G_TOP_RSP_DATA10_SHIFT 0 + +#define SERDES_25G_TOP_RSP_DATA11_MASK 0xFF +#define SERDES_25G_TOP_RSP_DATA11_SHIFT 0 + +#define SERDES_25G_TOP_RSP_DATA12_MASK 0xFF +#define SERDES_25G_TOP_RSP_DATA12_SHIFT 0 + +#define SERDES_25G_TOP_RSP_DATA13_MASK 0xFF +#define SERDES_25G_TOP_RSP_DATA13_SHIFT 0 + +#define SERDES_25G_TOP_RSP_DATA14_MASK 0xFF +#define SERDES_25G_TOP_RSP_DATA14_SHIFT 0 + +#define SERDES_25G_TOP_RSP_DATA15_MASK 0xFF +#define SERDES_25G_TOP_RSP_DATA15_SHIFT 0 + +/******************************************************************************* + * Common Registers + ******************************************************************************/ +#define SERDES_25G_CM_BASE 0xC00 +#define SERDES_25G_CM_SIZE 0x400 + +#define SERDES_25G_CM_TOP_AFE_PD_CTRL0_ADDR 0x00 +#define SERDES_25G_CM_TOP_AFE_PD_CTRL1_ADDR 0x01 +#define SERDES_25G_CM_TOP_AFE_RST_CTRL0_ADDR 0x03 +#define SERDES_25G_CM_TOP_AFE_BIAS_CTRL0_ADDR 0x05 +#define SERDES_25G_CM_TOP_AFE_BIAS_CTRL1_ADDR 0x06 +#define SERDES_25G_CM_TOP_AFE_BIAS_CTRL2_ADDR 0x07 +#define SERDES_25G_CM_TOP_AFE_BIAS_CTRL3_ADDR 0x08 +#define SERDES_25G_CM_TOP_AFE_BIAS_CTRL4_ADDR 0x09 +#define SERDES_25G_CM_TOP_AFE_BIAS_CTRL5_ADDR 0x0A +#define SERDES_25G_CM_TOP_AFE_REG_CTRL0_ADDR 0x0C +#define SERDES_25G_CM_TOP_AFE_REFCLK_CTRL0_ADDR 0x1A +#define SERDES_25G_CM_TOP_AFE_REFCLK_CTRL1_ADDR 0x1B +#define SERDES_25G_CM_TOP_AFE_REFCLK_CTRL2_ADDR 0x1F +#define SERDES_25G_CM_TOP_AFE_CMCP_CTRL0_ADDR 0x20 +#define SERDES_25G_CM_TOP_AFE_CMCP_CTRL1_ADDR 0x21 +#define SERDES_25G_CM_TOP_AFE_CMCP_CTRL2_ADDR 0x22 +#define SERDES_25G_CM_TOP_AFE_MISC_CTRL0_ADDR 0x23 +#define SERDES_25G_CM_TOP_AFE_CMCP_STATUS_ADDR 0x24 +#define SERDES_25G_CM_TOP_AFE_TOGGLE_CTRL0_ADDR 0x25 +#define SERDES_25G_CM_TOP_AFE_TSTCLK_CTRL0_ADDR 0x28 +#define SERDES_25G_CM_TOP_AFE_TXTC_CTRL0_ADDR 0x30 +#define SERDES_25G_CM_TOP_AFE_TXTC_CTRL1_ADDR 0x31 +#define SERDES_25G_CM_TOP_AFE_TXTC_CTRL2_ADDR 0x32 +#define SERDES_25G_CM_TOP_AFE_TXTC_CTRL3_ADDR 0x33 +#define SERDES_25G_CM_TOP_AFE_TXTC_CTRL4_ADDR 0x34 +#define SERDES_25G_CM_TOP_PWR_STATE_REQ_STATUS_ADDR 0x50 +#define SERDES_25G_CM_TOP_PWR_STATE_ACK_CTRL_ADDR 0x51 +#define SERDES_25G_CM_TOP_PHY_IF_STATUS_ADDR 0x52 +#define SERDES_25G_CM_TOP_CMU_TOP_SPARE0_ADDR 0x58 +#define SERDES_25G_CM_TOP_CMU_TOP_SPARE1_ADDR 0x59 +#define SERDES_25G_CM_TOP_ERR_CTRL1_ADDR 0x80 +#define SERDES_25G_CM_TOP_ERR_CTRL2_ADDR 0x81 +#define SERDES_25G_CM_TOP_ERR_CTRL3_ADDR 0x82 +#define SERDES_25G_CM_TOP_CMU_IF_OVR_CTRL0_ADDR 0x8A +#define SERDES_25G_CM_TOP_CMU_IF_OVR_CTRL1_ADDR 0x8B +/******************************************************************************* + * masks and shifts + ******************************************************************************/ +#define SERDES_25G_CMU_TOP_AFE_PD_CTRL0_PD_BIAS_MASK 0x01 +#define SERDES_25G_CMU_TOP_AFE_PD_CTRL0_PD_BIAS_SHIFT 0 + +#define SERDES_25G_CMU_TOP_AFE_PD_CTRL0_PD_BIAS_ICV_MASK 0x02 +#define SERDES_25G_CMU_TOP_AFE_PD_CTRL0_PD_BIAS_ICV_SHIFT 1 + +#define SERDES_25G_CMU_TOP_AFE_PD_CTRL0_PD_BIAS_ICC_MASK 0x04 +#define SERDES_25G_CMU_TOP_AFE_PD_CTRL0_PD_BIAS_ICC_SHIFT 2 + +#define SERDES_25G_CMU_TOP_AFE_PD_CTRL0_PD_BIAS_IPTAT_MASK 0x08 +#define SERDES_25G_CMU_TOP_AFE_PD_CTRL0_PD_BIAS_IPTAT_SHIFT 3 + +#define SERDES_25G_CMU_TOP_AFE_PD_CTRL0_PD_BIAS_SLAVE_MASK 0x10 +#define SERDES_25G_CMU_TOP_AFE_PD_CTRL0_PD_BIAS_SLAVE_SHIFT 4 + +#define SERDES_25G_CMU_TOP_AFE_PD_CTRL0_PD_REG_REF_MASK 0x20 +#define SERDES_25G_CMU_TOP_AFE_PD_CTRL0_PD_REG_REF_SHIFT 5 + +#define SERDES_25G_CMU_TOP_AFE_PD_CTRL0_PD_REFCLK_MASK 0x40 +#define SERDES_25G_CMU_TOP_AFE_PD_CTRL0_PD_REFCLK_SHIFT 6 + +#define SERDES_25G_CMU_TOP_AFE_PD_CTRL1_PD_CMCP_MASK 0x01 +#define SERDES_25G_CMU_TOP_AFE_PD_CTRL1_PD_CMCP_SHIFT 0 + +#define SERDES_25G_CMU_TOP_AFE_PD_CTRL1_PD_CMCP_TXCLK_LEFT_MASK 0x02 +#define SERDES_25G_CMU_TOP_AFE_PD_CTRL1_PD_CMCP_TXCLK_LEFT_SHIFT 1 + +#define SERDES_25G_CMU_TOP_AFE_PD_CTRL1_PD_CMCP_TXCLK_RIGHT_MASK 0x04 +#define SERDES_25G_CMU_TOP_AFE_PD_CTRL1_PD_CMCP_TXCLK_RIGHT_SHIFT 2 + +#define SERDES_25G_CMU_TOP_AFE_RST_CTRL0_RST_CMCP_CLK_CMU_N_MASK 0x01 +#define SERDES_25G_CMU_TOP_AFE_RST_CTRL0_RST_CMCP_CLK_CMU_N_SHIFT 0 + +#define SERDES_25G_CMU_TOP_AFE_RST_CTRL0_RST_CMCP_CLK_CMUDIV_N_MASK 0x02 +#define SERDES_25G_CMU_TOP_AFE_RST_CTRL0_RST_CMCP_CLK_CMUDIV_N_SHIFT 1 + +#define SERDES_25G_CMU_TOP_AFE_BIAS_CTRL0_BIAS_ICV_TRIM_MASK 0x0F +#define SERDES_25G_CMU_TOP_AFE_BIAS_CTRL0_BIAS_ICV_TRIM_SHIFT 0 + +#define SERDES_25G_CMU_TOP_AFE_BIAS_CTRL0_BIAS_ICC_TRIM_MASK 0xF0 +#define SERDES_25G_CMU_TOP_AFE_BIAS_CTRL0_BIAS_ICC_TRIM_SHIFT 4 + +#define SERDES_25G_CMU_TOP_AFE_BIAS_CTRL1_BIAS_IPTAT_TRIM_MASK 0x0F +#define SERDES_25G_CMU_TOP_AFE_BIAS_CTRL1_BIAS_IPTAT_TRIM_SHIFT 0 + +#define SERDES_25G_CMU_TOP_AFE_BIAS_CTRL2_BIAS_BGSTART_BYP_MASK 0x01 +#define SERDES_25G_CMU_TOP_AFE_BIAS_CTRL2_BIAS_BGSTART_BYP_SHIFT 0 + +#define SERDES_25G_CMU_TOP_AFE_BIAS_CTRL2_BIAS_IPTATSTART_BYP_MASK 0x02 +#define SERDES_25G_CMU_TOP_AFE_BIAS_CTRL2_BIAS_IPTATSTART_BYP_SHIFT 1 + +#define SERDES_25G_CMU_TOP_AFE_BIAS_CTRL2_TERMCAL_EN_MASK 0x04 +#define SERDES_25G_CMU_TOP_AFE_BIAS_CTRL2_TERMCAL_EN_SHIFT 2 + +#define SERDES_25G_CMU_TOP_AFE_BIAS_CTRL3_TERMCAL_PTRIM_MASK 0x0F +#define SERDES_25G_CMU_TOP_AFE_BIAS_CTRL3_TERMCAL_PTRIM_SHIFT 0 + +#define SERDES_25G_CMU_TOP_AFE_BIAS_CTRL3_TERMCAL_NTRIM_MASK 0xF0 +#define SERDES_25G_CMU_TOP_AFE_BIAS_CTRL3_TERMCAL_NTRIM_SHIFT 4 + +#define SERDES_25G_CMU_TOP_AFE_BIAS_CTRL4_BIAS_SPARE_MASK 0x0F +#define SERDES_25G_CMU_TOP_AFE_BIAS_CTRL4_BIAS_SPARE_SHIFT 0 + +#define SERDES_25G_CMU_TOP_AFE_BIAS_CTRL5_BIAS_CALREF_TRIM_MASK 0x0F +#define SERDES_25G_CMU_TOP_AFE_BIAS_CTRL5_BIAS_CALREF_TRIM_SHIFT 0 + +#define SERDES_25G_CMU_TOP_AFE_REG_CTRL0_REG_REF_PASS_EN_MASK 0x01 +#define SERDES_25G_CMU_TOP_AFE_REG_CTRL0_REG_REF_PASS_EN_SHIFT 0 + +#define SERDES_25G_CMU_TOP_AFE_REG_CTRL0_REG_REF_TRIM_MASK 0x0E +#define SERDES_25G_CMU_TOP_AFE_REG_CTRL0_REG_REF_TRIM_SHIFT 1 + +#define SERDES_25G_CMU_TOP_AFE_REG_CTRL0_REG_REF_TRICKLE_MASK 0x30 +#define SERDES_25G_CMU_TOP_AFE_REG_CTRL0_REG_REF_TRICKLE_SHIFT 4 + +#define SERDES_25G_CMU_TOP_AFE_REFCLK_CTRL0_REFCLK_DIV_MASK 0x03 +#define SERDES_25G_CMU_TOP_AFE_REFCLK_CTRL0_REFCLK_DIV_SHIFT 0 + +#define SERDES_25G_CMU_TOP_AFE_REFCLK_CTRL0_REFCLK_DPL_DIV_MASK 0x0C +#define SERDES_25G_CMU_TOP_AFE_REFCLK_CTRL0_REFCLK_DPL_DIV_SHIFT 2 + +#define SERDES_25G_CMU_TOP_AFE_REFCLK_CTRL0_REFCLK_DEGLITCH_OVR_MASK 0x10 +#define SERDES_25G_CMU_TOP_AFE_REFCLK_CTRL0_REFCLK_DEGLITCH_OVR_SHIFT 4 + +#define SERDES_25G_CMU_TOP_AFE_REFCLK_CTRL1_REFCLK_TERM_MASK 0x1F +#define SERDES_25G_CMU_TOP_AFE_REFCLK_CTRL1_REFCLK_TERM_SHIFT 0 + +#define SERDES_25G_CMU_TOP_AFE_REFCLK_CTRL2_REFCLK_SPARE_MASK 0x0F +#define SERDES_25G_CMU_TOP_AFE_REFCLK_CTRL2_REFCLK_SPARE_SHIFT 0 + +#define SERDES_25G_CMU_TOP_AFE_CMCP_CTRL0_CMCP_QSAMPLE_EN_MASK 0x01 +#define SERDES_25G_CMU_TOP_AFE_CMCP_CTRL0_CMCP_QSAMPLE_EN_SHIFT 0 + +#define SERDES_25G_CMU_TOP_AFE_CMCP_CTRL0_CMCP_DCD_RANGE_MASK 0x02 +#define SERDES_25G_CMU_TOP_AFE_CMCP_CTRL0_CMCP_DCD_RANGE_SHIFT 1 + +#define SERDES_25G_CMU_TOP_AFE_CMCP_CTRL0_CMCP_CMUCLK_DIV_MASK 0x1C +#define SERDES_25G_CMU_TOP_AFE_CMCP_CTRL0_CMCP_CMUCLK_DIV_SHIFT 2 + +#define SERDES_25G_CMU_TOP_AFE_CMCP_CTRL0_CMCP_CMUDIVCLK_DIV_MASK 0xE0 +#define SERDES_25G_CMU_TOP_AFE_CMCP_CTRL0_CMCP_CMUDIVCLK_DIV_SHIFT 5 + +#define SERDES_25G_CMU_TOP_AFE_CMCP_CTRL1_CMCP_CLKDIV_SWING_MASK 0x03 +#define SERDES_25G_CMU_TOP_AFE_CMCP_CTRL1_CMCP_CLKDIV_SWING_SHIFT 0 + +#define SERDES_25G_CMU_TOP_AFE_CMCP_CTRL1_CMCP_TXCLK_SWING_MASK 0x0C +#define SERDES_25G_CMU_TOP_AFE_CMCP_CTRL1_CMCP_TXCLK_SWING_SHIFT 2 + +#define SERDES_25G_CMU_TOP_AFE_CMCP_CTRL1_CMCP_CMUCLK_DIV2_BYPASS_MASK 0x10 +#define SERDES_25G_CMU_TOP_AFE_CMCP_CTRL1_CMCP_CMUCLK_DIV2_BYPASS_SHIFT 4 + +#define SERDES_25G_CMU_TOP_AFE_CMCP_CTRL2_CMCP_CLKDIV_OVR_MASK 0x03 +#define SERDES_25G_CMU_TOP_AFE_CMCP_CTRL2_CMCP_CLKDIV_OVR_SHIFT 0 + +#define SERDES_25G_CMU_TOP_AFE_CMCP_CTRL2_CMCP_TXCLK_BIASI_MASK 0x0C +#define SERDES_25G_CMU_TOP_AFE_CMCP_CTRL2_CMCP_TXCLK_BIASI_SHIFT 2 + +#define SERDES_25G_CMU_TOP_AFE_CMCP_CTRL2_CMCP_TXCLK_DIV_MASK 0x70 +#define SERDES_25G_CMU_TOP_AFE_CMCP_CTRL2_CMCP_TXCLK_DIV_SHIFT 4 + +#define SERDES_25G_CMU_TOP_AFE_CMCP_CTRL2_CMCP_DIV1P5_DUMMY_EN_MASK 0x80 +#define SERDES_25G_CMU_TOP_AFE_CMCP_CTRL2_CMCP_DIV1P5_DUMMY_EN_SHIFT 7 + +#define SERDES_25G_CMU_TOP_AFE_MISC_CTRL0_CMCP_SPARE_MASK 0xFF +#define SERDES_25G_CMU_TOP_AFE_MISC_CTRL0_CMCP_SPARE_SHIFT 0 + +#define SERDES_25G_CMU_TOP_AFE_CMCP_STATUS_CMCP_DIV1P5_QSAMPLE_MASK 0x0F +#define SERDES_25G_CMU_TOP_AFE_CMCP_STATUS_CMCP_DIV1P5_QSAMPLE_SHIFT 0 + +#define SERDES_25G_CMU_TOP_AFE_TOGGLE_CTRL0_CLK_TOGGLE_EN_MASK 0x01 +#define SERDES_25G_CMU_TOP_AFE_TOGGLE_CTRL0_CLK_TOGGLE_EN_SHIFT 0 + +#define SERDES_25G_CMU_TOP_AFE_TOGGLE_CTRL0_CMCP_TOGGLE_EN_MASK 0x02 +#define SERDES_25G_CMU_TOP_AFE_TOGGLE_CTRL0_CMCP_TOGGLE_EN_SHIFT 1 + +#define SERDES_25G_CMU_TOP_AFE_TSTCLK_CTRL0_CMCP_TSTCLK_MUX_MASK 0x03 +#define SERDES_25G_CMU_TOP_AFE_TSTCLK_CTRL0_CMCP_TSTCLK_MUX_SHIFT 0 + +#define SERDES_25G_CMU_TOP_AFE_TSTCLK_CTRL0_CMCP_TSTCLK_DIV_MASK 0x1C +#define SERDES_25G_CMU_TOP_AFE_TSTCLK_CTRL0_CMCP_TSTCLK_DIV_SHIFT 2 + +#define SERDES_25G_CMU_TOP_AFE_TSTCLK_CTRL0_CMCP_TSTCLK_SWING_MASK 0x60 +#define SERDES_25G_CMU_TOP_AFE_TSTCLK_CTRL0_CMCP_TSTCLK_SWING_SHIFT 5 + +#define SERDES_25G_CMU_TOP_AFE_TXTC_CTRL0_TXTC_CALN_X1_MASK 0x07 +#define SERDES_25G_CMU_TOP_AFE_TXTC_CTRL0_TXTC_CALN_X1_SHIFT 0 + +#define SERDES_25G_CMU_TOP_AFE_TXTC_CTRL0_TXTC_CALN_X1_FIXED_MASK 0x18 +#define SERDES_25G_CMU_TOP_AFE_TXTC_CTRL0_TXTC_CALN_X1_FIXED_SHIFT 3 + +#define SERDES_25G_CMU_TOP_AFE_TXTC_CTRL1_TXTC_CALN_X2_MASK 0x1F +#define SERDES_25G_CMU_TOP_AFE_TXTC_CTRL1_TXTC_CALN_X2_SHIFT 0 + +#define SERDES_25G_CMU_TOP_AFE_TXTC_CTRL1_TXTC_CALN_XP5_FIXED_MASK 0x60 +#define SERDES_25G_CMU_TOP_AFE_TXTC_CTRL1_TXTC_CALN_XP5_FIXED_SHIFT 5 + +#define SERDES_25G_CMU_TOP_AFE_TXTC_CTRL2_TXTC_CALP_X1_MASK 0x07 +#define SERDES_25G_CMU_TOP_AFE_TXTC_CTRL2_TXTC_CALP_X1_SHIFT 0 + +#define SERDES_25G_CMU_TOP_AFE_TXTC_CTRL2_TXTC_CALP_X1_FIXED_MASK 0x18 +#define SERDES_25G_CMU_TOP_AFE_TXTC_CTRL2_TXTC_CALP_X1_FIXED_SHIFT 3 + +#define SERDES_25G_CMU_TOP_AFE_TXTC_CTRL3_TXTC_CALP_X2_MASK 0x1F +#define SERDES_25G_CMU_TOP_AFE_TXTC_CTRL3_TXTC_CALP_X2_SHIFT 0 + +#define SERDES_25G_CMU_TOP_AFE_TXTC_CTRL3_TXTC_CALP_XP5_FIXED_MASK 0x60 +#define SERDES_25G_CMU_TOP_AFE_TXTC_CTRL3_TXTC_CALP_XP5_FIXED_SHIFT 5 + +#define SERDES_25G_CMU_TOP_AFE_TXTC_CTRL4_TXTC_TERM_NEG_MASK 0x07 +#define SERDES_25G_CMU_TOP_AFE_TXTC_CTRL4_TXTC_TERM_NEG_SHIFT 0 + +#define SERDES_25G_CMU_TOP_AFE_TXTC_CTRL4_TXTC_TERM_POS_MASK 0x70 +#define SERDES_25G_CMU_TOP_AFE_TXTC_CTRL4_TXTC_TERM_POS_SHIFT 4 + +#define SERDES_25G_CMU_TOP_PWR_STATE_REQ_STATUS_STATE_MASK 0x07 +#define SERDES_25G_CMU_TOP_PWR_STATE_REQ_STATUS_STATE_SHIFT 0 + +#define SERDES_25G_CMU_TOP_PWR_STATE_REQ_STATUS_REQ_MASK 0x08 +#define SERDES_25G_CMU_TOP_PWR_STATE_REQ_STATUS_REQ_SHIFT 3 + +#define SERDES_25G_CMU_TOP_PWR_STATE_ACK_CTRL_STATE_MASK 0x07 +#define SERDES_25G_CMU_TOP_PWR_STATE_ACK_CTRL_STATE_SHIFT 0 + +#define SERDES_25G_CMU_TOP_PWR_STATE_ACK_CTRL_ACK_MASK 0x08 +#define SERDES_25G_CMU_TOP_PWR_STATE_ACK_CTRL_ACK_SHIFT 3 + +#define SERDES_25G_CMU_TOP_PWR_STATE_ACK_CTRL_DELAY_LEN_MASK 0x70 +#define SERDES_25G_CMU_TOP_PWR_STATE_ACK_CTRL_DELAY_LEN_SHIFT 4 + +#define SERDES_25G_CMU_TOP_PHY_IF_STATUS_CMU_OK_MASK 0x01 +#define SERDES_25G_CMU_TOP_PHY_IF_STATUS_CMU_OK_SHIFT 0 + +#define SERDES_25G_CMU_TOP_CMU_TOP_SPARE0_MASK 0xFF +#define SERDES_25G_CMU_TOP_CMU_TOP_SPARE0_SHIFT 0 + +#define SERDES_25G_CMU_TOP_CMU_TOP_SPARE1_MASK 0xFF +#define SERDES_25G_CMU_TOP_CMU_TOP_SPARE1_SHIFT 0 + +#define SERDES_25G_CMU_TOP_ERR_CTRL1_ERR_CODE_7_0_MASK 0xFF +#define SERDES_25G_CMU_TOP_ERR_CTRL1_ERR_CODE_7_0_SHIFT 0 + +#define SERDES_25G_CMU_TOP_ERR_CTRL2_ERR_CODE_15_8_MASK 0xFF +#define SERDES_25G_CMU_TOP_ERR_CTRL2_ERR_CODE_15_8_SHIFT 0 + +#define SERDES_25G_CMU_TOP_ERR_CTRL3_CMU_ERR__MASK 0x01 +#define SERDES_25G_CMU_TOP_ERR_CTRL3_CMU_ERR__SHIFT 0 + +#define SERDES_25G_CMU_TOP_CMU_IF_OVR_CTRL0_CMU_PD_OVR_EN_MASK 0x01 +#define SERDES_25G_CMU_TOP_CMU_IF_OVR_CTRL0_CMU_PD_OVR_EN_SHIFT 0 + +#define SERDES_25G_CMU_TOP_CMU_IF_OVR_CTRL0_CMU_PD_OVR_VAL_MASK 0x06 +#define SERDES_25G_CMU_TOP_CMU_IF_OVR_CTRL0_CMU_PD_OVR_VAL_SHIFT 1 + +#define SERDES_25G_CMU_TOP_CMU_IF_OVR_CTRL1_CMU_RST_N_OVR_EN_MASK 0x01 +#define SERDES_25G_CMU_TOP_CMU_IF_OVR_CTRL1_CMU_RST_N_OVR_EN_SHIFT 0 + +#define SERDES_25G_CMU_TOP_CMU_IF_OVR_CTRL1_CMU_RST_N_OVR_VAL_MASK 0x02 +#define SERDES_25G_CMU_TOP_CMU_IF_OVR_CTRL1_CMU_RST_N_OVR_VAL_SHIFT 1 + + +/******************************************************************************* + * Lane Registers + ******************************************************************************/ +#define SERDES_25G_LANE_BASE 0x1800 +#define SERDES_25G_LANE_SIZE 0x800 + +/********************************** LANE_TOP **********************************/ +#define SERDES_25G_LANE_TOP_AFE_LOOPBACK_CTRL_ADDR 0x00 +#define SERDES_25G_LANE_TOP_AFE_RX_PD_CTRL_ADDR 0x01 +#define SERDES_25G_LANE_TOP_AFE_TX_PD_CTRL_ADDR 0x02 +#define SERDES_25G_LANE_TOP_AFE_BIAS_PD_CTRL_ADDR 0x03 +#define SERDES_25G_LANE_TOP_AFE_RX_RST_CTRL_ADDR 0x04 +#define SERDES_25G_LANE_TOP_AFE_TX_RST_CTRL_ADDR 0x05 +#define SERDES_25G_LANE_TOP_AFE_BIAS_CTRL_ADDR 0x06 +#define SERDES_25G_LANE_TOP_AFE_TXCP_CTRL0_ADDR 0x10 +#define SERDES_25G_LANE_TOP_AFE_TXCP_CTRL2_ADDR 0x12 +#define SERDES_25G_LANE_TOP_AFE_TXCP_CTRL3_ADDR 0x13 +#define SERDES_25G_LANE_TOP_AFE_TXCP_CTRL4_ADDR 0x14 +#define SERDES_25G_LANE_TOP_AFE_TXDP_CTRL0_ADDR 0x16 +#define SERDES_25G_LANE_TOP_AFE_RXDP_CTRL0_ADDR 0x19 +#define SERDES_25G_LANE_TOP_AFE_RXTERM_CTRL0_ADDR 0x1B +#define SERDES_25G_LANE_TOP_AFE_RXTERM_CTRL1_ADDR 0x1C +#define SERDES_25G_LANE_TOP_DPL_TXDP_CTRL1_ADDR 0x22 +#define SERDES_25G_LANE_TOP_DPL_RXDP_CTRL1_ADDR 0x24 +#define SERDES_25G_LANE_TOP_PWR_STATE_REQ_STATUS_ADDR 0x25 +#define SERDES_25G_LANE_TOP_PWR_STATE_ACK_CTRL_ADDR 0x26 +#define SERDES_25G_LANE_TOP_PHY_IF_STATUS_ADDR 0x27 +#define SERDES_25G_LANE_TOP_DELAY_CTRL0_ADDR 0x30 +#define SERDES_25G_LANE_TOP_DELAY_CTRL1_ADDR 0x31 +#define SERDES_25G_LANE_TOP_LN_STAT_CTRL0_ADDR 0x38 +#define SERDES_25G_LANE_TOP_LN_STAT_CTRL_OVR_ADDR 0x39 +#define SERDES_25G_LANE_TOP_LN_STAT_STATUS0_ADDR 0x3A +#define SERDES_25G_LANE_TOP_LN_CTRL_OVR0_ADDR 0x3B +#define SERDES_25G_LANE_TOP_LN_CTRL_OVR1_ADDR 0x3C +#define SERDES_25G_LANE_TOP_LN_CTRL_STATUS0_ADDR 0x3D +#define SERDES_25G_LANE_TOP_ERR_CTRL1_ADDR 0x40 +#define SERDES_25G_LANE_TOP_ERR_CTRL2_ADDR 0x41 +/******************************************************************************* + * masks and shifts + ******************************************************************************/ +#define SERDES_25G_LANE_TOP_AFE_LOOPBACK_CTRL_LOOPBACK_RXCLK_EN_MASK 0x01 +#define SERDES_25G_LANE_TOP_AFE_LOOPBACK_CTRL_LOOPBACK_RXCLK_EN_SHIFT 0 + +#define SERDES_25G_LANE_TOP_AFE_LOOPBACK_CTRL_LOOPBACK_TXCLK_EN_MASK 0x02 +#define SERDES_25G_LANE_TOP_AFE_LOOPBACK_CTRL_LOOPBACK_TXCLK_EN_SHIFT 1 + +#define SERDES_25G_LANE_TOP_AFE_LOOPBACK_CTRL_LOOPBACK_FEA_EN_MASK 0x04 +#define SERDES_25G_LANE_TOP_AFE_LOOPBACK_CTRL_LOOPBACK_FEA_EN_SHIFT 2 + +#define SERDES_25G_LANE_TOP_AFE_LOOPBACK_CTRL_LOOPBACK_NEA_EN_MASK 0x08 +#define SERDES_25G_LANE_TOP_AFE_LOOPBACK_CTRL_LOOPBACK_NEA_EN_SHIFT 3 + +#define SERDES_25G_LANE_TOP_AFE_RX_PD_CTRL_PD_RXTERM_MASK 0x01 +#define SERDES_25G_LANE_TOP_AFE_RX_PD_CTRL_PD_RXTERM_SHIFT 0 + +#define SERDES_25G_LANE_TOP_AFE_RX_PD_CTRL_PD_RXDP_MASK 0x02 +#define SERDES_25G_LANE_TOP_AFE_RX_PD_CTRL_PD_RXDP_SHIFT 1 + +#define SERDES_25G_LANE_TOP_AFE_TX_PD_CTRL_PD_REG_TXCP_MASK 0x01 +#define SERDES_25G_LANE_TOP_AFE_TX_PD_CTRL_PD_REG_TXCP_SHIFT 0 + +#define SERDES_25G_LANE_TOP_AFE_TX_PD_CTRL_PD_TXCP_MASK 0x02 +#define SERDES_25G_LANE_TOP_AFE_TX_PD_CTRL_PD_TXCP_SHIFT 1 + +#define SERDES_25G_LANE_TOP_AFE_BIAS_PD_CTRL_PD_BIAS_LANE_MASK 0x01 +#define SERDES_25G_LANE_TOP_AFE_BIAS_PD_CTRL_PD_BIAS_LANE_SHIFT 0 + +#define SERDES_25G_LANE_TOP_AFE_RX_RST_CTRL_RST_RXDP_N_MASK 0x01 +#define SERDES_25G_LANE_TOP_AFE_RX_RST_CTRL_RST_RXDP_N_SHIFT 0 + +#define SERDES_25G_LANE_TOP_AFE_TX_RST_CTRL_RST_TXDP_N_MASK 0x04 +#define SERDES_25G_LANE_TOP_AFE_TX_RST_CTRL_RST_TXDP_N_SHIFT 2 + +#define SERDES_25G_LANE_TOP_AFE_BIAS_CTRL_BIAS_SPARE_MASK 0x0F +#define SERDES_25G_LANE_TOP_AFE_BIAS_CTRL_BIAS_SPARE_SHIFT 0 + +#define SERDES_25G_LANE_TOP_AFE_TXCP_CTRL0_REG_TXCP_TRIM_MASK 0x0F +#define SERDES_25G_LANE_TOP_AFE_TXCP_CTRL0_REG_TXCP_TRIM_SHIFT 0 + +#define SERDES_25G_LANE_TOP_AFE_TXCP_CTRL0_REG_TXCP_TRICKLE_MASK 0x30 +#define SERDES_25G_LANE_TOP_AFE_TXCP_CTRL0_REG_TXCP_TRICKLE_SHIFT 4 + +#define SERDES_25G_LANE_TOP_AFE_TXCP_CTRL0_REG_TXCP_PASS_EN_MASK 0x40 +#define SERDES_25G_LANE_TOP_AFE_TXCP_CTRL0_REG_TXCP_PASS_EN_SHIFT 6 + +#define SERDES_25G_LANE_TOP_AFE_TXCP_CTRL2_TXCP_TSTCLK_EN_MASK 0x01 +#define SERDES_25G_LANE_TOP_AFE_TXCP_CTRL2_TXCP_TSTCLK_EN_SHIFT 0 + +#define SERDES_25G_LANE_TOP_AFE_TXCP_CTRL2_TXCP_CLKDIV_MASK 0x06 +#define SERDES_25G_LANE_TOP_AFE_TXCP_CTRL2_TXCP_CLKDIV_SHIFT 1 + +#define SERDES_25G_LANE_TOP_AFE_TXCP_CTRL3_TXCP_SPARE_MASK 0x0F +#define SERDES_25G_LANE_TOP_AFE_TXCP_CTRL3_TXCP_SPARE_SHIFT 0 + +#define SERDES_25G_LANE_TOP_AFE_TXCP_CTRL4_TXCP_CLKDIV_SWING_MASK 0x03 +#define SERDES_25G_LANE_TOP_AFE_TXCP_CTRL4_TXCP_CLKDIV_SWING_SHIFT 0 + +#define SERDES_25G_LANE_TOP_AFE_TXCP_CTRL4_TXCP_TOGGLE_EN_MASK 0x04 +#define SERDES_25G_LANE_TOP_AFE_TXCP_CTRL4_TXCP_TOGGLE_EN_SHIFT 2 + +#define SERDES_25G_LANE_TOP_AFE_TXDP_CTRL0_TXDP_SPARE_MASK 0xF0 +#define SERDES_25G_LANE_TOP_AFE_TXDP_CTRL0_TXDP_SPARE_SHIFT 4 + +#define SERDES_25G_LANE_TOP_AFE_RXDP_CTRL0_RXDP_CLKDLY_MASK 0x07 +#define SERDES_25G_LANE_TOP_AFE_RXDP_CTRL0_RXDP_CLKDLY_SHIFT 0 + +#define SERDES_25G_LANE_TOP_AFE_RXDP_CTRL0_RXDP_SPARE_MASK 0xF0 +#define SERDES_25G_LANE_TOP_AFE_RXDP_CTRL0_RXDP_SPARE_SHIFT 4 + +#define SERDES_25G_LANE_TOP_AFE_RXTERM_CTRL0_RXTERM_CMFILT_MASK 0x07 +#define SERDES_25G_LANE_TOP_AFE_RXTERM_CTRL0_RXTERM_CMFILT_SHIFT 0 + +#define SERDES_25G_LANE_TOP_AFE_RXTERM_CTRL0_RXTERM_HIZ_MASK 0x08 +#define SERDES_25G_LANE_TOP_AFE_RXTERM_CTRL0_RXTERM_HIZ_SHIFT 3 + +#define SERDES_25G_LANE_TOP_AFE_RXTERM_CTRL0_RXTERM_VCM_GND_MASK 0x10 +#define SERDES_25G_LANE_TOP_AFE_RXTERM_CTRL0_RXTERM_VCM_GND_SHIFT 4 + +#define SERDES_25G_LANE_TOP_AFE_RXTERM_CTRL1_RXTERM_VAL_MASK 0x1F +#define SERDES_25G_LANE_TOP_AFE_RXTERM_CTRL1_RXTERM_VAL_SHIFT 0 + +#define SERDES_25G_LANE_TOP_DPL_TXDP_CTRL1_DMUX_TXA_SEL_MASK 0x03 +#define SERDES_25G_LANE_TOP_DPL_TXDP_CTRL1_DMUX_TXA_SEL_SHIFT 0 + +#define SERDES_25G_LANE_TOP_DPL_TXDP_CTRL1_TXPOLARITY_MASK 0x04 +#define SERDES_25G_LANE_TOP_DPL_TXDP_CTRL1_TXPOLARITY_SHIFT 2 + +#define SERDES_25G_LANE_TOP_DPL_TXDP_CTRL1_DMUX_TXA_LB_FED_TX_EN_MASK 0x10 +#define SERDES_25G_LANE_TOP_DPL_TXDP_CTRL1_DMUX_TXA_LB_FED_TX_EN_SHIFT 4 + +#define SERDES_25G_LANE_TOP_DPL_RXDP_CTRL1_DMUX_RX_SEL_MASK 0x01 +#define SERDES_25G_LANE_TOP_DPL_RXDP_CTRL1_DMUX_RX_SEL_SHIFT 0 + +#define SERDES_25G_LANE_TOP_PWR_STATE_REQ_STATUS_STATE_MASK 0x07 +#define SERDES_25G_LANE_TOP_PWR_STATE_REQ_STATUS_STATE_SHIFT 0 + +#define SERDES_25G_LANE_TOP_PWR_STATE_REQ_STATUS_REQ_MASK 0x08 +#define SERDES_25G_LANE_TOP_PWR_STATE_REQ_STATUS_REQ_SHIFT 3 + +#define SERDES_25G_LANE_TOP_PWR_STATE_ACK_CTRL_STATE_MASK 0x07 +#define SERDES_25G_LANE_TOP_PWR_STATE_ACK_CTRL_STATE_SHIFT 0 + +#define SERDES_25G_LANE_TOP_PWR_STATE_ACK_CTRL_ACK_MASK 0x08 +#define SERDES_25G_LANE_TOP_PWR_STATE_ACK_CTRL_ACK_SHIFT 3 + +#define SERDES_25G_LANE_TOP_PWR_STATE_ACK_CTRL_DELAY_LEN_MASK 0x70 +#define SERDES_25G_LANE_TOP_PWR_STATE_ACK_CTRL_DELAY_LEN_SHIFT 4 + +#define SERDES_25G_LANE_TOP_PHY_IF_STATUS_LN_OK_MASK 0x01 +#define SERDES_25G_LANE_TOP_PHY_IF_STATUS_LN_OK_SHIFT 0 + +#define SERDES_25G_LANE_TOP_DELAY_CTRL0_RX_DATA_EDELAY_MASK 0x07 +#define SERDES_25G_LANE_TOP_DELAY_CTRL0_RX_DATA_EDELAY_SHIFT 0 + +#define SERDES_25G_LANE_TOP_DELAY_CTRL0_RX_EDGE_DELAY_MASK 0x38 +#define SERDES_25G_LANE_TOP_DELAY_CTRL0_RX_EDGE_DELAY_SHIFT 3 + +#define SERDES_25G_LANE_TOP_DELAY_CTRL1_RX_DATA_IDELAY_MASK 0x07 +#define SERDES_25G_LANE_TOP_DELAY_CTRL1_RX_DATA_IDELAY_SHIFT 0 + +#define SERDES_25G_LANE_TOP_DELAY_CTRL1_RX_EYE_DELAY_MASK 0x38 +#define SERDES_25G_LANE_TOP_DELAY_CTRL1_RX_EYE_DELAY_SHIFT 3 + +#define SERDES_25G_LANE_TOP_LN_STAT_CTRL0_RXVALID_MASK 0x01 +#define SERDES_25G_LANE_TOP_LN_STAT_CTRL0_RXVALID_SHIFT 0 + +#define SERDES_25G_LANE_TOP_LN_STAT_CTRL_OVR_OVR_EN_MASK 0x01 +#define SERDES_25G_LANE_TOP_LN_STAT_CTRL_OVR_OVR_EN_SHIFT 0 + +#define SERDES_25G_LANE_TOP_LN_STAT_CTRL_OVR_RST_PD_READY_MASK 0x02 +#define SERDES_25G_LANE_TOP_LN_STAT_CTRL_OVR_RST_PD_READY_SHIFT 1 + +#define SERDES_25G_LANE_TOP_LN_STAT_STATUS0_RST_PD_READY_MASK 0x01 +#define SERDES_25G_LANE_TOP_LN_STAT_STATUS0_RST_PD_READY_SHIFT 0 + +#define SERDES_25G_LANE_TOP_LN_CTRL_OVR0_OVR_EN_MASK 0x01 +#define SERDES_25G_LANE_TOP_LN_CTRL_OVR0_OVR_EN_SHIFT 0 + +#define SERDES_25G_LANE_TOP_LN_CTRL_OVR0_TX_DATA_WIDTH_MASK 0x02 +#define SERDES_25G_LANE_TOP_LN_CTRL_OVR0_TX_DATA_WIDTH_SHIFT 1 + +#define SERDES_25G_LANE_TOP_LN_CTRL_OVR0_RX_DATA_WIDTH_MASK 0x04 +#define SERDES_25G_LANE_TOP_LN_CTRL_OVR0_RX_DATA_WIDTH_SHIFT 2 + +#define SERDES_25G_LANE_TOP_LN_CTRL_OVR0_RXPOLARITY_MASK 0x08 +#define SERDES_25G_LANE_TOP_LN_CTRL_OVR0_RXPOLARITY_SHIFT 3 + +#define SERDES_25G_LANE_TOP_LN_CTRL_OVR0_TX_EN_MASK 0x10 +#define SERDES_25G_LANE_TOP_LN_CTRL_OVR0_TX_EN_SHIFT 4 + +#define SERDES_25G_LANE_TOP_LN_CTRL_OVR0_LOS_EII_EN_MASK 0x20 +#define SERDES_25G_LANE_TOP_LN_CTRL_OVR0_LOS_EII_EN_SHIFT 5 + +#define SERDES_25G_LANE_TOP_LN_CTRL_OVR0_LOS_EII_VALUE_MASK 0x40 +#define SERDES_25G_LANE_TOP_LN_CTRL_OVR0_LOS_EII_VALUE_SHIFT 6 + +#define SERDES_25G_LANE_TOP_LN_CTRL_OVR1_OVR_EN_MASK 0x01 +#define SERDES_25G_LANE_TOP_LN_CTRL_OVR1_OVR_EN_SHIFT 0 + +#define SERDES_25G_LANE_TOP_LN_CTRL_OVR1_PD_MASK 0x06 +#define SERDES_25G_LANE_TOP_LN_CTRL_OVR1_PD_SHIFT 1 + +#define SERDES_25G_LANE_TOP_LN_CTRL_OVR1_RST_N_MASK 0x08 +#define SERDES_25G_LANE_TOP_LN_CTRL_OVR1_RST_N_SHIFT 3 + +#define SERDES_25G_LANE_TOP_LN_CTRL_STATUS0_TX_DATA_WIDTH_MASK 0x01 +#define SERDES_25G_LANE_TOP_LN_CTRL_STATUS0_TX_DATA_WIDTH_SHIFT 0 + +#define SERDES_25G_LANE_TOP_LN_CTRL_STATUS0_RX_DATA_WIDTH_MASK 0x02 +#define SERDES_25G_LANE_TOP_LN_CTRL_STATUS0_RX_DATA_WIDTH_SHIFT 1 + +#define SERDES_25G_LANE_TOP_ERR_CTRL1_ERR_CODE_7_0_MASK 0xFF +#define SERDES_25G_LANE_TOP_ERR_CTRL1_ERR_CODE_7_0_SHIFT 0 + +#define SERDES_25G_LANE_TOP_ERR_CTRL2_ERR_CODE_15_8_MASK 0xFF +#define SERDES_25G_LANE_TOP_ERR_CTRL2_ERR_CODE_15_8_SHIFT 0 + +/********************************* Lane CDR RXCLK ***************************/ +#define SERDES_25G_LANE_CDR_RXCLK_BASE 0x80 + +#define SERDES_25G_LANE_CDR_RXCLK_CAL_CTRL0_ADDR (SERDES_25G_LANE_CDR_RXCLK_BASE + 0x10) +#define SERDES_25G_LANE_CDR_RXCLK_CAL_CTRL1_ADDR (SERDES_25G_LANE_CDR_RXCLK_BASE + 0x11) +#define SERDES_25G_LANE_CDR_RXCLK_INTEGRAL_CTRL0_ADDR (SERDES_25G_LANE_CDR_RXCLK_BASE + 0x21) +#define SERDES_25G_LANE_CDR_RXCLK_INTEGRAL_CTRL1_ADDR (SERDES_25G_LANE_CDR_RXCLK_BASE + 0x22) +#define SERDES_25G_LANE_CDR_RXCLK_LOAD_MODE_CTRL0_ADDR (SERDES_25G_LANE_CDR_RXCLK_BASE + 0x26) +#define SERDES_25G_LANE_CDR_RXCLK_LOAD_MODE_CTRL1_ADDR (SERDES_25G_LANE_CDR_RXCLK_BASE + 0x27) +#define SERDES_25G_LANE_CDR_RXCLK_LOAD_MODE_CTRL2_ADDR (SERDES_25G_LANE_CDR_RXCLK_BASE + 0x28) +#define SERDES_25G_LANE_CDR_RXCLK_LOAD_MODE_CTRL3_ADDR (SERDES_25G_LANE_CDR_RXCLK_BASE + 0x29) +#define SERDES_25G_LANE_CDR_RXCLK_FORCE_MODE_CTRL0_ADDR (SERDES_25G_LANE_CDR_RXCLK_BASE + 0x2A) +#define SERDES_25G_LANE_CDR_RXCLK_FORCE_MODE_CTRL1_ADDR (SERDES_25G_LANE_CDR_RXCLK_BASE + 0x2B) +#define SERDES_25G_LANE_CDR_RXCLK_FORCE_MODE_CTRL2_ADDR (SERDES_25G_LANE_CDR_RXCLK_BASE + 0x2D) +#define SERDES_25G_LANE_CDR_RXCLK_DLPF_CTRL0_ADDR (SERDES_25G_LANE_CDR_RXCLK_BASE + 0x30) +#define SERDES_25G_LANE_CDR_RXCLK_DLPF_CTRL1_ADDR (SERDES_25G_LANE_CDR_RXCLK_BASE + 0x31) +#define SERDES_25G_LANE_CDR_RXCLK_DLPF_CTRL2_ADDR (SERDES_25G_LANE_CDR_RXCLK_BASE + 0x32) +#define SERDES_25G_LANE_CDR_RXCLK_DLPF_CTRL3_ADDR (SERDES_25G_LANE_CDR_RXCLK_BASE + 0x34) +#define SERDES_25G_LANE_CDR_RXCLK_DLPF_CTRL4_ADDR (SERDES_25G_LANE_CDR_RXCLK_BASE + 0x36) +#define SERDES_25G_LANE_CDR_RXCLK_DLPF_CTRL5_ADDR (SERDES_25G_LANE_CDR_RXCLK_BASE + 0x37) +#define SERDES_25G_LANE_CDR_RXCLK_DLPF_CTRL6_ADDR (SERDES_25G_LANE_CDR_RXCLK_BASE + 0x39) +#define SERDES_25G_LANE_CDR_RXCLK_DLPF_CTRL7_ADDR (SERDES_25G_LANE_CDR_RXCLK_BASE + 0x3A) +#define SERDES_25G_LANE_CDR_RXCLK_DLPF_CTRL8_ADDR (SERDES_25G_LANE_CDR_RXCLK_BASE + 0x3B) +#define SERDES_25G_LANE_CDR_RXCLK_DLPF_STATUS0_ADDR (SERDES_25G_LANE_CDR_RXCLK_BASE + 0x3C) +#define SERDES_25G_LANE_CDR_RXCLK_DLPF_STATUS1_ADDR (SERDES_25G_LANE_CDR_RXCLK_BASE + 0x3D) +#define SERDES_25G_LANE_CDR_RXCLK_DLPF_STATUS2_ADDR (SERDES_25G_LANE_CDR_RXCLK_BASE + 0x3E) +#define SERDES_25G_LANE_CDR_RXCLK_DLPF_STATUS3_ADDR (SERDES_25G_LANE_CDR_RXCLK_BASE + 0x3F) +#define SERDES_25G_LANE_CDR_RXCLK_DLPF_STATUS4_ADDR (SERDES_25G_LANE_CDR_RXCLK_BASE + 0x40) +#define SERDES_25G_LANE_CDR_RXCLK_DLPF_STATUS5_ADDR (SERDES_25G_LANE_CDR_RXCLK_BASE + 0x41) +#define SERDES_25G_LANE_CDR_RXCLK_INTEGRAL_STATUS0_ADDR (SERDES_25G_LANE_CDR_RXCLK_BASE + 0x44) +#define SERDES_25G_LANE_CDR_RXCLK_INTEGRAL_STATUS1_ADDR (SERDES_25G_LANE_CDR_RXCLK_BASE + 0x45) +#define SERDES_25G_LANE_CDR_RXCLK_INTEGRAL_STATUS2_ADDR (SERDES_25G_LANE_CDR_RXCLK_BASE + 0x46) +#define SERDES_25G_LANE_CDR_RXCLK_LOCKD_CTRL0_ADDR (SERDES_25G_LANE_CDR_RXCLK_BASE + 0x48) +#define SERDES_25G_LANE_CDR_RXCLK_LOCKD_CTRL1_ADDR (SERDES_25G_LANE_CDR_RXCLK_BASE + 0x49) +#define SERDES_25G_LANE_CDR_RXCLK_LOCKD_CTRL2_ADDR (SERDES_25G_LANE_CDR_RXCLK_BASE + 0x4A) +#define SERDES_25G_LANE_CDR_RXCLK_LOCKD_CTRL3_ADDR (SERDES_25G_LANE_CDR_RXCLK_BASE + 0x4B) +#define SERDES_25G_LANE_CDR_RXCLK_LOCKL_CTRL0_ADDR (SERDES_25G_LANE_CDR_RXCLK_BASE + 0x4C) +#define SERDES_25G_LANE_CDR_RXCLK_LOCKL_CTRL1_ADDR (SERDES_25G_LANE_CDR_RXCLK_BASE + 0x4D) +#define SERDES_25G_LANE_CDR_RXCLK_LOCKL_CTRL2_ADDR (SERDES_25G_LANE_CDR_RXCLK_BASE + 0x4E) +#define SERDES_25G_LANE_CDR_RXCLK_LOCKL_CTRL3_ADDR (SERDES_25G_LANE_CDR_RXCLK_BASE + 0x4F) +#define SERDES_25G_LANE_CDR_RXCLK_ACCUM_PEAK_DETECT_CTRL0_ADDR (SERDES_25G_LANE_CDR_RXCLK_BASE + 0x60) +#define SERDES_25G_LANE_CDR_RXCLK_ACCUM_PEAK_DETECT_CTRL1_ADDR (SERDES_25G_LANE_CDR_RXCLK_BASE + 0x61) +#define SERDES_25G_LANE_CDR_RXCLK_ACCUM_PEAK_DETECT_CTRL2_ADDR (SERDES_25G_LANE_CDR_RXCLK_BASE + 0x62) +#define SERDES_25G_LANE_CDR_RXCLK_ACCUM_PEAK_DETECT_CTRL3_ADDR (SERDES_25G_LANE_CDR_RXCLK_BASE + 0x63) +#define SERDES_25G_LANE_CDR_RXCLK_ACCUM_PEAK_DETECT_STATUS0_ADDR (SERDES_25G_LANE_CDR_RXCLK_BASE + 0x68) +#define SERDES_25G_LANE_CDR_RXCLK_ACCUM_FIRST_PEAK_STATUS0_ADDR (SERDES_25G_LANE_CDR_RXCLK_BASE + 0x69) +#define SERDES_25G_LANE_CDR_RXCLK_ACCUM_FIRST_PEAK_STATUS1_ADDR (SERDES_25G_LANE_CDR_RXCLK_BASE + 0x6A) +#define SERDES_25G_LANE_CDR_RXCLK_ACCUM_FIRST_PEAK_STATUS2_ADDR (SERDES_25G_LANE_CDR_RXCLK_BASE + 0x6B) +#define SERDES_25G_LANE_CDR_RXCLK_ACCUM_LAST_PEAK_STATUS0_ADDR (SERDES_25G_LANE_CDR_RXCLK_BASE + 0x6C) +#define SERDES_25G_LANE_CDR_RXCLK_ACCUM_LAST_PEAK_STATUS1_ADDR (SERDES_25G_LANE_CDR_RXCLK_BASE + 0x6D) +#define SERDES_25G_LANE_CDR_RXCLK_ACCUM_LAST_PEAK_STATUS2_ADDR (SERDES_25G_LANE_CDR_RXCLK_BASE + 0x6E) +/******************************************************************************* + * masks and shifts + ******************************************************************************/ +#define SERDES_25G_LANE_CDR_RXCLK_CAL_CTRL0_DLPF_SRC_SEL_MASK 0x01 +#define SERDES_25G_LANE_CDR_RXCLK_CAL_CTRL0_DLPF_SRC_SEL_SHIFT 0 + +#define SERDES_25G_LANE_CDR_RXCLK_CAL_CTRL1_CFG_DOSC_MIN_MASK 0x07 +#define SERDES_25G_LANE_CDR_RXCLK_CAL_CTRL1_CFG_DOSC_MIN_SHIFT 0 + +#define SERDES_25G_LANE_CDR_RXCLK_INTEGRAL_CTRL0_DECIMATION_MODE_MASK 0x0F +#define SERDES_25G_LANE_CDR_RXCLK_INTEGRAL_CTRL0_DECIMATION_MODE_SHIFT 0 + +#define SERDES_25G_LANE_CDR_RXCLK_INTEGRAL_CTRL0_DLPF_MODE_MASK 0x30 +#define SERDES_25G_LANE_CDR_RXCLK_INTEGRAL_CTRL0_DLPF_MODE_SHIFT 4 + +#define SERDES_25G_LANE_CDR_RXCLK_INTEGRAL_CTRL1_PD_OUT_MASK_MASK 0x03 +#define SERDES_25G_LANE_CDR_RXCLK_INTEGRAL_CTRL1_PD_OUT_MASK_SHIFT 0 + +#define SERDES_25G_LANE_CDR_RXCLK_LOAD_MODE_CTRL0_DLPF_VAL_7_0_MASK 0xFF +#define SERDES_25G_LANE_CDR_RXCLK_LOAD_MODE_CTRL0_DLPF_VAL_7_0_SHIFT 0 + +#define SERDES_25G_LANE_CDR_RXCLK_LOAD_MODE_CTRL1_DLPF_VAL_8_MASK 0x01 +#define SERDES_25G_LANE_CDR_RXCLK_LOAD_MODE_CTRL1_DLPF_VAL_8_SHIFT 0 + +#define SERDES_25G_LANE_CDR_RXCLK_LOAD_MODE_CTRL2_DLPF_DITHER_VAL_7_0_MASK 0xFF +#define SERDES_25G_LANE_CDR_RXCLK_LOAD_MODE_CTRL2_DLPF_DITHER_VAL_7_0_SHIFT 0 + +#define SERDES_25G_LANE_CDR_RXCLK_LOAD_MODE_CTRL3_DLPF_DITHER_VAL_10_8_MASK 0x07 +#define SERDES_25G_LANE_CDR_RXCLK_LOAD_MODE_CTRL3_DLPF_DITHER_VAL_10_8_SHIFT 0 + +#define SERDES_25G_LANE_CDR_RXCLK_FORCE_MODE_CTRL0_DLPF_VAL_7_0_MASK 0xFF +#define SERDES_25G_LANE_CDR_RXCLK_FORCE_MODE_CTRL0_DLPF_VAL_7_0_SHIFT 0 + +#define SERDES_25G_LANE_CDR_RXCLK_FORCE_MODE_CTRL1_DLPF_VAL_8_MASK 0x01 +#define SERDES_25G_LANE_CDR_RXCLK_FORCE_MODE_CTRL1_DLPF_VAL_8_SHIFT 0 + +#define SERDES_25G_LANE_CDR_RXCLK_FORCE_MODE_CTRL2_EN_MASK 0x01 +#define SERDES_25G_LANE_CDR_RXCLK_FORCE_MODE_CTRL2_EN_SHIFT 0 + +#define SERDES_25G_LANE_CDR_RXCLK_DLPF_CTRL0_NUM_DITHER_BITS_MASK 0x0F +#define SERDES_25G_LANE_CDR_RXCLK_DLPF_CTRL0_NUM_DITHER_BITS_SHIFT 0 + +#define SERDES_25G_LANE_CDR_RXCLK_DLPF_CTRL1_HIGH_THRESHOLD_7_0_MASK 0xFF +#define SERDES_25G_LANE_CDR_RXCLK_DLPF_CTRL1_HIGH_THRESHOLD_7_0_SHIFT 0 + +#define SERDES_25G_LANE_CDR_RXCLK_DLPF_CTRL2_HIGH_THRESHOLD_8_MASK 0x01 +#define SERDES_25G_LANE_CDR_RXCLK_DLPF_CTRL2_HIGH_THRESHOLD_8_SHIFT 0 + +#define SERDES_25G_LANE_CDR_RXCLK_DLPF_CTRL3_HIGH_COUNT_MASK 0x0F +#define SERDES_25G_LANE_CDR_RXCLK_DLPF_CTRL3_HIGH_COUNT_SHIFT 0 + +#define SERDES_25G_LANE_CDR_RXCLK_DLPF_CTRL4_LOW_THRESHOLD_7_0_MASK 0xFF +#define SERDES_25G_LANE_CDR_RXCLK_DLPF_CTRL4_LOW_THRESHOLD_7_0_SHIFT 0 + +#define SERDES_25G_LANE_CDR_RXCLK_DLPF_CTRL5_LOW_THRESHOLD_8_MASK 0x01 +#define SERDES_25G_LANE_CDR_RXCLK_DLPF_CTRL5_LOW_THRESHOLD_8_SHIFT 0 + +#define SERDES_25G_LANE_CDR_RXCLK_DLPF_CTRL6_LOW_COUNT_MASK 0x0F +#define SERDES_25G_LANE_CDR_RXCLK_DLPF_CTRL6_LOW_COUNT_SHIFT 0 + +#define SERDES_25G_LANE_CDR_RXCLK_DLPF_CTRL7_LOCK_EN_MASK 0x01 +#define SERDES_25G_LANE_CDR_RXCLK_DLPF_CTRL7_LOCK_EN_SHIFT 0 + +#define SERDES_25G_LANE_CDR_RXCLK_DLPF_CTRL7_LOCKL_EN_MASK 0x02 +#define SERDES_25G_LANE_CDR_RXCLK_DLPF_CTRL7_LOCKL_EN_SHIFT 1 + +#define SERDES_25G_LANE_CDR_RXCLK_DLPF_CTRL7_HIGH_EN_MASK 0x04 +#define SERDES_25G_LANE_CDR_RXCLK_DLPF_CTRL7_HIGH_EN_SHIFT 2 + +#define SERDES_25G_LANE_CDR_RXCLK_DLPF_CTRL7_LOW_EN_MASK 0x08 +#define SERDES_25G_LANE_CDR_RXCLK_DLPF_CTRL7_LOW_EN_SHIFT 3 + +#define SERDES_25G_LANE_CDR_RXCLK_DLPF_CTRL8_OUTPUT_SAMPLE_PERIOD_MASK 0x3F +#define SERDES_25G_LANE_CDR_RXCLK_DLPF_CTRL8_OUTPUT_SAMPLE_PERIOD_SHIFT 0 + +#define SERDES_25G_LANE_CDR_RXCLK_DLPF_STATUS0_GREY_VAL_7_0_MASK 0xFF +#define SERDES_25G_LANE_CDR_RXCLK_DLPF_STATUS0_GREY_VAL_7_0_SHIFT 0 + +#define SERDES_25G_LANE_CDR_RXCLK_DLPF_STATUS1_GREY_VAL_8_MASK 0x01 +#define SERDES_25G_LANE_CDR_RXCLK_DLPF_STATUS1_GREY_VAL_8_SHIFT 0 + +#define SERDES_25G_LANE_CDR_RXCLK_DLPF_STATUS2_BINARY_VAL_7_0_MASK 0xFF +#define SERDES_25G_LANE_CDR_RXCLK_DLPF_STATUS2_BINARY_VAL_7_0_SHIFT 0 + +#define SERDES_25G_LANE_CDR_RXCLK_DLPF_STATUS3_BINARY_VAL_8_MASK 0x01 +#define SERDES_25G_LANE_CDR_RXCLK_DLPF_STATUS3_BINARY_VAL_8_SHIFT 0 + +#define SERDES_25G_LANE_CDR_RXCLK_DLPF_STATUS4_DLPF_TOO_HIGH_MASK 0x01 +#define SERDES_25G_LANE_CDR_RXCLK_DLPF_STATUS4_DLPF_TOO_HIGH_SHIFT 0 + +#define SERDES_25G_LANE_CDR_RXCLK_DLPF_STATUS4_DLPF_TOO_LOW_MASK 0x02 +#define SERDES_25G_LANE_CDR_RXCLK_DLPF_STATUS4_DLPF_TOO_LOW_SHIFT 1 + +#define SERDES_25G_LANE_CDR_RXCLK_DLPF_STATUS4_LOCK_LOST_MASK 0x04 +#define SERDES_25G_LANE_CDR_RXCLK_DLPF_STATUS4_LOCK_LOST_SHIFT 2 + +#define SERDES_25G_LANE_CDR_RXCLK_DLPF_STATUS5_LOCKED_MASK 0x01 +#define SERDES_25G_LANE_CDR_RXCLK_DLPF_STATUS5_LOCKED_SHIFT 0 + +#define SERDES_25G_LANE_CDR_RXCLK_INTEGRAL_STATUS0_ACCUMULATOR_7_0_MASK 0xFF +#define SERDES_25G_LANE_CDR_RXCLK_INTEGRAL_STATUS0_ACCUMULATOR_7_0_SHIFT 0 + +#define SERDES_25G_LANE_CDR_RXCLK_INTEGRAL_STATUS1_ACCUMULATOR_15_8_MASK 0xFF +#define SERDES_25G_LANE_CDR_RXCLK_INTEGRAL_STATUS1_ACCUMULATOR_15_8_SHIFT 0 + +#define SERDES_25G_LANE_CDR_RXCLK_INTEGRAL_STATUS2_ACCUMULATOR_19_16_MASK 0x0F +#define SERDES_25G_LANE_CDR_RXCLK_INTEGRAL_STATUS2_ACCUMULATOR_19_16_SHIFT 0 + +#define SERDES_25G_LANE_CDR_RXCLK_LOCKD_CTRL0_DITHER_BITS_MASK 0x0F +#define SERDES_25G_LANE_CDR_RXCLK_LOCKD_CTRL0_DITHER_BITS_SHIFT 0 + +#define SERDES_25G_LANE_CDR_RXCLK_LOCKD_CTRL0_SAMPLE_PERIOD_MASK 0xF0 +#define SERDES_25G_LANE_CDR_RXCLK_LOCKD_CTRL0_SAMPLE_PERIOD_SHIFT 4 + +#define SERDES_25G_LANE_CDR_RXCLK_LOCKD_CTRL1_NUM_SAMPLES_MASK 0xFF +#define SERDES_25G_LANE_CDR_RXCLK_LOCKD_CTRL1_NUM_SAMPLES_SHIFT 0 + +#define SERDES_25G_LANE_CDR_RXCLK_LOCKD_CTRL2_SLOPE_THRESHOLD_MASK 0xFF +#define SERDES_25G_LANE_CDR_RXCLK_LOCKD_CTRL2_SLOPE_THRESHOLD_SHIFT 0 + +#define SERDES_25G_LANE_CDR_RXCLK_LOCKD_CTRL3_RANGE_THRESHOLD_MASK 0xFF +#define SERDES_25G_LANE_CDR_RXCLK_LOCKD_CTRL3_RANGE_THRESHOLD_SHIFT 0 + +#define SERDES_25G_LANE_CDR_RXCLK_LOCKL_CTRL0_DITHER_BITS_MASK 0x0F +#define SERDES_25G_LANE_CDR_RXCLK_LOCKL_CTRL0_DITHER_BITS_SHIFT 0 + +#define SERDES_25G_LANE_CDR_RXCLK_LOCKL_CTRL0_SAMPLE_PERIOD_MASK 0xF0 +#define SERDES_25G_LANE_CDR_RXCLK_LOCKL_CTRL0_SAMPLE_PERIOD_SHIFT 4 + +#define SERDES_25G_LANE_CDR_RXCLK_LOCKL_CTRL1_NUM_SAMPLES_MASK 0xFF +#define SERDES_25G_LANE_CDR_RXCLK_LOCKL_CTRL1_NUM_SAMPLES_SHIFT 0 + +#define SERDES_25G_LANE_CDR_RXCLK_LOCKL_CTRL2_SLOPE_THRESHOLD_MASK 0xFF +#define SERDES_25G_LANE_CDR_RXCLK_LOCKL_CTRL2_SLOPE_THRESHOLD_SHIFT 0 + +#define SERDES_25G_LANE_CDR_RXCLK_LOCKL_CTRL3_RANGE_THRESHOLD_MASK 0xFF +#define SERDES_25G_LANE_CDR_RXCLK_LOCKL_CTRL3_RANGE_THRESHOLD_SHIFT 0 + +#define SERDES_25G_LANE_CDR_RXCLK_ACCUM_PEAK_DETECT_CTRL0_EN_MASK 0x01 +#define SERDES_25G_LANE_CDR_RXCLK_ACCUM_PEAK_DETECT_CTRL0_EN_SHIFT 0 + +#define SERDES_25G_LANE_CDR_RXCLK_ACCUM_PEAK_DETECT_CTRL1_SAMPLE_DROP_BITS_MASK 0x07 +#define SERDES_25G_LANE_CDR_RXCLK_ACCUM_PEAK_DETECT_CTRL1_SAMPLE_DROP_BITS_SHIFT 0 + +#define SERDES_25G_LANE_CDR_RXCLK_ACCUM_PEAK_DETECT_CTRL1_NUM_PEAKS_MASK 0xF0 +#define SERDES_25G_LANE_CDR_RXCLK_ACCUM_PEAK_DETECT_CTRL1_NUM_PEAKS_SHIFT 4 + +#define SERDES_25G_LANE_CDR_RXCLK_ACCUM_PEAK_DETECT_CTRL2_PEAK2PEAK_PERIOD_MIN_MASK 0xFF +#define SERDES_25G_LANE_CDR_RXCLK_ACCUM_PEAK_DETECT_CTRL2_PEAK2PEAK_PERIOD_MIN_SHIFT 0 + +#define SERDES_25G_LANE_CDR_RXCLK_ACCUM_PEAK_DETECT_CTRL3_PEAK2PEAK_PERIOD_MAX_MASK 0xFF +#define SERDES_25G_LANE_CDR_RXCLK_ACCUM_PEAK_DETECT_CTRL3_PEAK2PEAK_PERIOD_MAX_SHIFT 0 + +#define SERDES_25G_LANE_CDR_RXCLK_ACCUM_PEAK_DETECT_STATUS0_DONE_MASK 0x01 +#define SERDES_25G_LANE_CDR_RXCLK_ACCUM_PEAK_DETECT_STATUS0_DONE_SHIFT 0 + +#define SERDES_25G_LANE_CDR_RXCLK_ACCUM_PEAK_DETECT_STATUS0_NOISY_MASK 0x02 +#define SERDES_25G_LANE_CDR_RXCLK_ACCUM_PEAK_DETECT_STATUS0_NOISY_SHIFT 1 + +#define SERDES_25G_LANE_CDR_RXCLK_ACCUM_PEAK_DETECT_STATUS0_SLOW_MASK 0x04 +#define SERDES_25G_LANE_CDR_RXCLK_ACCUM_PEAK_DETECT_STATUS0_SLOW_SHIFT 2 + +#define SERDES_25G_LANE_CDR_RXCLK_ACCUM_FIRST_PEAK_STATUS0_VAL_7_0_MASK 0xFF +#define SERDES_25G_LANE_CDR_RXCLK_ACCUM_FIRST_PEAK_STATUS0_VAL_7_0_SHIFT 0 + +#define SERDES_25G_LANE_CDR_RXCLK_ACCUM_FIRST_PEAK_STATUS1_VAL_15_8_MASK 0xFF +#define SERDES_25G_LANE_CDR_RXCLK_ACCUM_FIRST_PEAK_STATUS1_VAL_15_8_SHIFT 0 + +#define SERDES_25G_LANE_CDR_RXCLK_ACCUM_FIRST_PEAK_STATUS2_VAL_19_16_MASK 0x0F +#define SERDES_25G_LANE_CDR_RXCLK_ACCUM_FIRST_PEAK_STATUS2_VAL_19_16_SHIFT 0 + +#define SERDES_25G_LANE_CDR_RXCLK_ACCUM_LAST_PEAK_STATUS0_VAL_7_0_MASK 0xFF +#define SERDES_25G_LANE_CDR_RXCLK_ACCUM_LAST_PEAK_STATUS0_VAL_7_0_SHIFT 0 + +#define SERDES_25G_LANE_CDR_RXCLK_ACCUM_LAST_PEAK_STATUS1_VAL_15_8_MASK 0xFF +#define SERDES_25G_LANE_CDR_RXCLK_ACCUM_LAST_PEAK_STATUS1_VAL_15_8_SHIFT 0 + +#define SERDES_25G_LANE_CDR_RXCLK_ACCUM_LAST_PEAK_STATUS2_VAL_19_16_MASK 0x0F +#define SERDES_25G_LANE_CDR_RXCLK_ACCUM_LAST_PEAK_STATUS2_VAL_19_16_SHIFT 0 + +/********************************* Lane CDR_REFCLK ***************************/ +#define SERDES_25G_LANE_CDR_REFCLK_BASE 0x180 + +#define SERDES_25G_LANE_CDR_REFCLK_AFE_PD_CTRL0_ADDR (SERDES_25G_LANE_CDR_REFCLK_BASE + 0x00) +#define SERDES_25G_LANE_CDR_REFCLK_AFE_PD_CTRL1_ADDR (SERDES_25G_LANE_CDR_REFCLK_BASE + 0x01) +#define SERDES_25G_LANE_CDR_REFCLK_AFE_RST_CTRL0_ADDR (SERDES_25G_LANE_CDR_REFCLK_BASE + 0x06) +#define SERDES_25G_LANE_CDR_REFCLK_AFE_VCO_CTRL0_ADDR (SERDES_25G_LANE_CDR_REFCLK_BASE + 0x0A) +#define SERDES_25G_LANE_CDR_REFCLK_AFE_VCO_CTRL1_ADDR (SERDES_25G_LANE_CDR_REFCLK_BASE + 0x0B) +#define SERDES_25G_LANE_CDR_REFCLK_AFE_VCO_CTRL2_ADDR (SERDES_25G_LANE_CDR_REFCLK_BASE + 0x0C) +#define SERDES_25G_LANE_CDR_REFCLK_AFE_CTRL0_ADDR (SERDES_25G_LANE_CDR_REFCLK_BASE + 0x10) +#define SERDES_25G_LANE_CDR_REFCLK_AFE_CTRL1_ADDR (SERDES_25G_LANE_CDR_REFCLK_BASE + 0x11) +#define SERDES_25G_LANE_CDR_REFCLK_AFE_PI_CTRL0_ADDR (SERDES_25G_LANE_CDR_REFCLK_BASE + 0x18) +#define SERDES_25G_LANE_CDR_REFCLK_AFE_PI_CTRL1_ADDR (SERDES_25G_LANE_CDR_REFCLK_BASE + 0x19) +#define SERDES_25G_LANE_CDR_REFCLK_AFE_PI_CTRL2_ADDR (SERDES_25G_LANE_CDR_REFCLK_BASE + 0x1A) +#define SERDES_25G_LANE_CDR_REFCLK_AFE_PI_CTRL3_ADDR (SERDES_25G_LANE_CDR_REFCLK_BASE + 0x1B) +#define SERDES_25G_LANE_CDR_REFCLK_AFE_CAL_CTRL0_ADDR (SERDES_25G_LANE_CDR_REFCLK_BASE + 0x20) +#define SERDES_25G_LANE_CDR_REFCLK_AFE_CAL_CTRL1_ADDR (SERDES_25G_LANE_CDR_REFCLK_BASE + 0x21) +#define SERDES_25G_LANE_CDR_REFCLK_AFE_CAL_CTRL2_ADDR (SERDES_25G_LANE_CDR_REFCLK_BASE + 0x22) +#define SERDES_25G_LANE_CDR_REFCLK_AFE_VCOCAL_STATUS0_ADDR (SERDES_25G_LANE_CDR_REFCLK_BASE + 0x24) +#define SERDES_25G_LANE_CDR_REFCLK_RXCDR_HSCAN_EYE_CFG_ADDR (SERDES_25G_LANE_CDR_REFCLK_BASE + 0x30) +/******************************************************************************* + * masks and shifts + ******************************************************************************/ +#define SERDES_25G_LANE_CDR_REFCLK_AFE_PD_CTRL0_PD_RXCDR_MASK 0x01 +#define SERDES_25G_LANE_CDR_REFCLK_AFE_PD_CTRL0_PD_RXCDR_SHIFT 0 + +#define SERDES_25G_LANE_CDR_REFCLK_AFE_PD_CTRL0_PD_RXCDR_EYE_MASK 0x02 +#define SERDES_25G_LANE_CDR_REFCLK_AFE_PD_CTRL0_PD_RXCDR_EYE_SHIFT 1 + +#define SERDES_25G_LANE_CDR_REFCLK_AFE_PD_CTRL0_RXCDR_TOGGLE_EN_MASK 0x04 +#define SERDES_25G_LANE_CDR_REFCLK_AFE_PD_CTRL0_RXCDR_TOGGLE_EN_SHIFT 2 + +#define SERDES_25G_LANE_CDR_REFCLK_AFE_PD_CTRL1_RXCDR_PHD_EN_MASK 0xFF +#define SERDES_25G_LANE_CDR_REFCLK_AFE_PD_CTRL1_RXCDR_PHD_EN_SHIFT 0 + +#define SERDES_25G_LANE_CDR_REFCLK_AFE_RST_CTRL0_RST_RXCDR_PHD_N_MASK 0x01 +#define SERDES_25G_LANE_CDR_REFCLK_AFE_RST_CTRL0_RST_RXCDR_PHD_N_SHIFT 0 + +#define SERDES_25G_LANE_CDR_REFCLK_AFE_RST_CTRL0_RST_RXCDR_CLKDIV_N_MASK 0x02 +#define SERDES_25G_LANE_CDR_REFCLK_AFE_RST_CTRL0_RST_RXCDR_CLKDIV_N_SHIFT 1 + +#define SERDES_25G_LANE_CDR_REFCLK_AFE_VCO_CTRL0_RXCDR_VCO_KICK_MASK 0x01 +#define SERDES_25G_LANE_CDR_REFCLK_AFE_VCO_CTRL0_RXCDR_VCO_KICK_SHIFT 0 + +#define SERDES_25G_LANE_CDR_REFCLK_AFE_VCO_CTRL1_RXCDR_REGDAC_BANDWIDTH_MASK 0x01 +#define SERDES_25G_LANE_CDR_REFCLK_AFE_VCO_CTRL1_RXCDR_REGDAC_BANDWIDTH_SHIFT 0 + +#define SERDES_25G_LANE_CDR_REFCLK_AFE_VCO_CTRL1_RXCDR_SHORT_VOSC_PRP_MASK 0x02 +#define SERDES_25G_LANE_CDR_REFCLK_AFE_VCO_CTRL1_RXCDR_SHORT_VOSC_PRP_SHIFT 1 + +#define SERDES_25G_LANE_CDR_REFCLK_AFE_VCO_CTRL1_RXCDR_REFDAC_GAIN_MASK 0x0C +#define SERDES_25G_LANE_CDR_REFCLK_AFE_VCO_CTRL1_RXCDR_REFDAC_GAIN_SHIFT 2 + +#define SERDES_25G_LANE_CDR_REFCLK_AFE_VCO_CTRL2_RXCDR_DOSC_MASK 0x07 +#define SERDES_25G_LANE_CDR_REFCLK_AFE_VCO_CTRL2_RXCDR_DOSC_SHIFT 0 + +#define SERDES_25G_LANE_CDR_REFCLK_AFE_CTRL0_RXCDR_BBSTEP_MASK 0x1F +#define SERDES_25G_LANE_CDR_REFCLK_AFE_CTRL0_RXCDR_BBSTEP_SHIFT 0 + +#define SERDES_25G_LANE_CDR_REFCLK_AFE_CTRL0_RXCDR_CLKDIV_MASK 0x60 +#define SERDES_25G_LANE_CDR_REFCLK_AFE_CTRL0_RXCDR_CLKDIV_SHIFT 5 + +#define SERDES_25G_LANE_CDR_REFCLK_AFE_CTRL1_RXCDR_CLKDIV_SWING_MASK 0x03 +#define SERDES_25G_LANE_CDR_REFCLK_AFE_CTRL1_RXCDR_CLKDIV_SWING_SHIFT 0 + +#define SERDES_25G_LANE_CDR_REFCLK_AFE_CTRL1_RXCDR_SPARE_MASK 0x3C +#define SERDES_25G_LANE_CDR_REFCLK_AFE_CTRL1_RXCDR_SPARE_SHIFT 2 + +#define SERDES_25G_LANE_CDR_REFCLK_AFE_PI_CTRL0_RXCDR_HSCAN_CLKQ_MASK 0x7F +#define SERDES_25G_LANE_CDR_REFCLK_AFE_PI_CTRL0_RXCDR_HSCAN_CLKQ_SHIFT 0 + +#define SERDES_25G_LANE_CDR_REFCLK_AFE_PI_CTRL0_SRC_SEL_MASK 0x80 +#define SERDES_25G_LANE_CDR_REFCLK_AFE_PI_CTRL0_SRC_SEL_SHIFT 7 + +#define SERDES_25G_LANE_CDR_REFCLK_AFE_PI_CTRL1_RXCDR_HSCAN_CLKI_MASK 0x7F +#define SERDES_25G_LANE_CDR_REFCLK_AFE_PI_CTRL1_RXCDR_HSCAN_CLKI_SHIFT 0 + +#define SERDES_25G_LANE_CDR_REFCLK_AFE_PI_CTRL1_SRC_SEL_MASK 0x80 +#define SERDES_25G_LANE_CDR_REFCLK_AFE_PI_CTRL1_SRC_SEL_SHIFT 7 + +#define SERDES_25G_LANE_CDR_REFCLK_AFE_PI_CTRL2_RXCDR_HSCAN_EYE_MASK 0x7F +#define SERDES_25G_LANE_CDR_REFCLK_AFE_PI_CTRL2_RXCDR_HSCAN_EYE_SHIFT 0 + +#define SERDES_25G_LANE_CDR_REFCLK_AFE_PI_CTRL3_RXCDR_PI_CAP_MASK 0x07 +#define SERDES_25G_LANE_CDR_REFCLK_AFE_PI_CTRL3_RXCDR_PI_CAP_SHIFT 0 + +#define SERDES_25G_LANE_CDR_REFCLK_AFE_PI_CTRL3_RXCDR_PI_SWING_MASK 0x18 +#define SERDES_25G_LANE_CDR_REFCLK_AFE_PI_CTRL3_RXCDR_PI_SWING_SHIFT 3 + +#define SERDES_25G_LANE_CDR_REFCLK_AFE_CAL_CTRL0_RXCDR_CAL_EN_MASK 0x01 +#define SERDES_25G_LANE_CDR_REFCLK_AFE_CAL_CTRL0_RXCDR_CAL_EN_SHIFT 0 + +#define SERDES_25G_LANE_CDR_REFCLK_AFE_CAL_CTRL0_RXCDR_VCOCAL_DIV4_MASK 0x02 +#define SERDES_25G_LANE_CDR_REFCLK_AFE_CAL_CTRL0_RXCDR_VCOCAL_DIV4_SHIFT 1 + +#define SERDES_25G_LANE_CDR_REFCLK_AFE_CAL_CTRL1_RXCDR_VCOCAL_LOAD_VAL_11_8_MASK 0x0F +#define SERDES_25G_LANE_CDR_REFCLK_AFE_CAL_CTRL1_RXCDR_VCOCAL_LOAD_VAL_11_8_SHIFT 0 + +#define SERDES_25G_LANE_CDR_REFCLK_AFE_CAL_CTRL2_RXCDR_VCOCAL_LOAD_VAL_7_0_MASK 0xFF +#define SERDES_25G_LANE_CDR_REFCLK_AFE_CAL_CTRL2_RXCDR_VCOCAL_LOAD_VAL_7_0_SHIFT 0 + +#define SERDES_25G_LANE_CDR_REFCLK_AFE_VCOCAL_STATUS0_RXCDR_VCOCAL_UP_MASK 0x01 +#define SERDES_25G_LANE_CDR_REFCLK_AFE_VCOCAL_STATUS0_RXCDR_VCOCAL_UP_SHIFT 0 + +#define SERDES_25G_LANE_CDR_REFCLK_RXCDR_HSCAN_EYE_CFG_ZERO_PHASE_MASK 0x7F +#define SERDES_25G_LANE_CDR_REFCLK_RXCDR_HSCAN_EYE_CFG_ZERO_PHASE_SHIFT 0 + +/********************************* Lane BIST *********************************/ +#define SERDES_25G_LANE_TOP_AFE_LOOPBACK_CTRL_ADDR 0x00 +#define SERDES_25G_LANE_TOP_AFE_RX_PD_CTRL_ADDR 0x01 +#define SERDES_25G_LANE_TOP_AFE_TX_PD_CTRL_ADDR 0x02 +#define SERDES_25G_LANE_TOP_AFE_BIAS_PD_CTRL_ADDR 0x03 +#define SERDES_25G_LANE_TOP_AFE_RX_RST_CTRL_ADDR 0x04 +#define SERDES_25G_LANE_TOP_AFE_TX_RST_CTRL_ADDR 0x05 +#define SERDES_25G_LANE_TOP_AFE_BIAS_CTRL_ADDR 0x06 +#define SERDES_25G_LANE_TOP_AFE_TXCP_CTRL0_ADDR 0x10 +#define SERDES_25G_LANE_TOP_AFE_TXCP_CTRL2_ADDR 0x12 +#define SERDES_25G_LANE_TOP_AFE_TXCP_CTRL3_ADDR 0x13 +#define SERDES_25G_LANE_TOP_AFE_TXCP_CTRL4_ADDR 0x14 +#define SERDES_25G_LANE_TOP_AFE_TXDP_CTRL0_ADDR 0x16 +#define SERDES_25G_LANE_TOP_AFE_RXDP_CTRL0_ADDR 0x19 +#define SERDES_25G_LANE_TOP_AFE_RXTERM_CTRL0_ADDR 0x1B +#define SERDES_25G_LANE_TOP_AFE_RXTERM_CTRL1_ADDR 0x1C +#define SERDES_25G_LANE_TOP_DPL_TXDP_CTRL1_ADDR 0x22 +#define SERDES_25G_LANE_TOP_DPL_RXDP_CTRL1_ADDR 0x24 +#define SERDES_25G_LANE_TOP_PWR_STATE_REQ_STATUS_ADDR 0x25 +#define SERDES_25G_LANE_TOP_PWR_STATE_ACK_CTRL_ADDR 0x26 +#define SERDES_25G_LANE_TOP_PHY_IF_STATUS_ADDR 0x27 +#define SERDES_25G_LANE_TOP_DELAY_CTRL0_ADDR 0x30 +#define SERDES_25G_LANE_TOP_DELAY_CTRL1_ADDR 0x31 +#define SERDES_25G_LANE_TOP_LN_STAT_CTRL0_ADDR 0x38 +#define SERDES_25G_LANE_TOP_LN_STAT_CTRL_OVR_ADDR 0x39 +#define SERDES_25G_LANE_TOP_LN_STAT_STATUS0_ADDR 0x3A +#define SERDES_25G_LANE_TOP_LN_CTRL_OVR0_ADDR 0x3B +#define SERDES_25G_LANE_TOP_LN_CTRL_OVR1_ADDR 0x3C +#define SERDES_25G_LANE_TOP_LN_CTRL_STATUS0_ADDR 0x3D +#define SERDES_25G_LANE_TOP_ERR_CTRL1_ADDR 0x40 +#define SERDES_25G_LANE_TOP_ERR_CTRL2_ADDR 0x41 +/******************************************************************************* + * masks and shifts + ******************************************************************************/ +#define SERDES_25G_LANE_TOP_AFE_LOOPBACK_CTRL_LOOPBACK_RXCLK_EN_MASK 0x01 +#define SERDES_25G_LANE_TOP_AFE_LOOPBACK_CTRL_LOOPBACK_RXCLK_EN_SHIFT 0 + +#define SERDES_25G_LANE_TOP_AFE_LOOPBACK_CTRL_LOOPBACK_TXCLK_EN_MASK 0x02 +#define SERDES_25G_LANE_TOP_AFE_LOOPBACK_CTRL_LOOPBACK_TXCLK_EN_SHIFT 1 + +#define SERDES_25G_LANE_TOP_AFE_LOOPBACK_CTRL_LOOPBACK_FEA_EN_MASK 0x04 +#define SERDES_25G_LANE_TOP_AFE_LOOPBACK_CTRL_LOOPBACK_FEA_EN_SHIFT 2 + +#define SERDES_25G_LANE_TOP_AFE_LOOPBACK_CTRL_LOOPBACK_NEA_EN_MASK 0x08 +#define SERDES_25G_LANE_TOP_AFE_LOOPBACK_CTRL_LOOPBACK_NEA_EN_SHIFT 3 + +#define SERDES_25G_LANE_TOP_AFE_RX_PD_CTRL_PD_RXTERM_MASK 0x01 +#define SERDES_25G_LANE_TOP_AFE_RX_PD_CTRL_PD_RXTERM_SHIFT 0 + +#define SERDES_25G_LANE_TOP_AFE_RX_PD_CTRL_PD_RXDP_MASK 0x02 +#define SERDES_25G_LANE_TOP_AFE_RX_PD_CTRL_PD_RXDP_SHIFT 1 + +#define SERDES_25G_LANE_TOP_AFE_TX_PD_CTRL_PD_REG_TXCP_MASK 0x01 +#define SERDES_25G_LANE_TOP_AFE_TX_PD_CTRL_PD_REG_TXCP_SHIFT 0 + +#define SERDES_25G_LANE_TOP_AFE_TX_PD_CTRL_PD_TXCP_MASK 0x02 +#define SERDES_25G_LANE_TOP_AFE_TX_PD_CTRL_PD_TXCP_SHIFT 1 + +#define SERDES_25G_LANE_TOP_AFE_BIAS_PD_CTRL_PD_BIAS_LANE_MASK 0x01 +#define SERDES_25G_LANE_TOP_AFE_BIAS_PD_CTRL_PD_BIAS_LANE_SHIFT 0 + +#define SERDES_25G_LANE_TOP_AFE_RX_RST_CTRL_RST_RXDP_N_MASK 0x01 +#define SERDES_25G_LANE_TOP_AFE_RX_RST_CTRL_RST_RXDP_N_SHIFT 0 + +#define SERDES_25G_LANE_TOP_AFE_TX_RST_CTRL_RST_TXDP_N_MASK 0x04 +#define SERDES_25G_LANE_TOP_AFE_TX_RST_CTRL_RST_TXDP_N_SHIFT 2 + +#define SERDES_25G_LANE_TOP_AFE_BIAS_CTRL_BIAS_SPARE_MASK 0x0F +#define SERDES_25G_LANE_TOP_AFE_BIAS_CTRL_BIAS_SPARE_SHIFT 0 + +#define SERDES_25G_LANE_TOP_AFE_TXCP_CTRL0_REG_TXCP_TRIM_MASK 0x0F +#define SERDES_25G_LANE_TOP_AFE_TXCP_CTRL0_REG_TXCP_TRIM_SHIFT 0 + +#define SERDES_25G_LANE_TOP_AFE_TXCP_CTRL0_REG_TXCP_TRICKLE_MASK 0x30 +#define SERDES_25G_LANE_TOP_AFE_TXCP_CTRL0_REG_TXCP_TRICKLE_SHIFT 4 + +#define SERDES_25G_LANE_TOP_AFE_TXCP_CTRL0_REG_TXCP_PASS_EN_MASK 0x40 +#define SERDES_25G_LANE_TOP_AFE_TXCP_CTRL0_REG_TXCP_PASS_EN_SHIFT 6 + +#define SERDES_25G_LANE_TOP_AFE_TXCP_CTRL2_TXCP_TSTCLK_EN_MASK 0x01 +#define SERDES_25G_LANE_TOP_AFE_TXCP_CTRL2_TXCP_TSTCLK_EN_SHIFT 0 + +#define SERDES_25G_LANE_TOP_AFE_TXCP_CTRL2_TXCP_CLKDIV_MASK 0x06 +#define SERDES_25G_LANE_TOP_AFE_TXCP_CTRL2_TXCP_CLKDIV_SHIFT 1 + +#define SERDES_25G_LANE_TOP_AFE_TXCP_CTRL3_TXCP_SPARE_MASK 0x0F +#define SERDES_25G_LANE_TOP_AFE_TXCP_CTRL3_TXCP_SPARE_SHIFT 0 + +#define SERDES_25G_LANE_TOP_AFE_TXCP_CTRL4_TXCP_CLKDIV_SWING_MASK 0x03 +#define SERDES_25G_LANE_TOP_AFE_TXCP_CTRL4_TXCP_CLKDIV_SWING_SHIFT 0 + +#define SERDES_25G_LANE_TOP_AFE_TXCP_CTRL4_TXCP_TOGGLE_EN_MASK 0x04 +#define SERDES_25G_LANE_TOP_AFE_TXCP_CTRL4_TXCP_TOGGLE_EN_SHIFT 2 + +#define SERDES_25G_LANE_TOP_AFE_TXDP_CTRL0_TXDP_SPARE_MASK 0xF0 +#define SERDES_25G_LANE_TOP_AFE_TXDP_CTRL0_TXDP_SPARE_SHIFT 4 + +#define SERDES_25G_LANE_TOP_AFE_RXDP_CTRL0_RXDP_CLKDLY_MASK 0x07 +#define SERDES_25G_LANE_TOP_AFE_RXDP_CTRL0_RXDP_CLKDLY_SHIFT 0 + +#define SERDES_25G_LANE_TOP_AFE_RXDP_CTRL0_RXDP_SPARE_MASK 0xF0 +#define SERDES_25G_LANE_TOP_AFE_RXDP_CTRL0_RXDP_SPARE_SHIFT 4 + +#define SERDES_25G_LANE_TOP_AFE_RXTERM_CTRL0_RXTERM_CMFILT_MASK 0x07 +#define SERDES_25G_LANE_TOP_AFE_RXTERM_CTRL0_RXTERM_CMFILT_SHIFT 0 + +#define SERDES_25G_LANE_TOP_AFE_RXTERM_CTRL0_RXTERM_HIZ_MASK 0x08 +#define SERDES_25G_LANE_TOP_AFE_RXTERM_CTRL0_RXTERM_HIZ_SHIFT 3 + +#define SERDES_25G_LANE_TOP_AFE_RXTERM_CTRL0_RXTERM_VCM_GND_MASK 0x10 +#define SERDES_25G_LANE_TOP_AFE_RXTERM_CTRL0_RXTERM_VCM_GND_SHIFT 4 + +#define SERDES_25G_LANE_TOP_AFE_RXTERM_CTRL1_RXTERM_VAL_MASK 0x1F +#define SERDES_25G_LANE_TOP_AFE_RXTERM_CTRL1_RXTERM_VAL_SHIFT 0 + +#define SERDES_25G_LANE_TOP_DPL_TXDP_CTRL1_DMUX_TXA_SEL_MASK 0x03 +#define SERDES_25G_LANE_TOP_DPL_TXDP_CTRL1_DMUX_TXA_SEL_SHIFT 0 + +#define SERDES_25G_LANE_TOP_DPL_TXDP_CTRL1_TXPOLARITY_MASK 0x04 +#define SERDES_25G_LANE_TOP_DPL_TXDP_CTRL1_TXPOLARITY_SHIFT 2 + +#define SERDES_25G_LANE_TOP_DPL_TXDP_CTRL1_DMUX_TXA_LB_FED_TX_EN_MASK 0x10 +#define SERDES_25G_LANE_TOP_DPL_TXDP_CTRL1_DMUX_TXA_LB_FED_TX_EN_SHIFT 4 + +#define SERDES_25G_LANE_TOP_DPL_RXDP_CTRL1_DMUX_RX_SEL_MASK 0x01 +#define SERDES_25G_LANE_TOP_DPL_RXDP_CTRL1_DMUX_RX_SEL_SHIFT 0 + +#define SERDES_25G_LANE_TOP_PWR_STATE_REQ_STATUS_STATE_MASK 0x07 +#define SERDES_25G_LANE_TOP_PWR_STATE_REQ_STATUS_STATE_SHIFT 0 + +#define SERDES_25G_LANE_TOP_PWR_STATE_REQ_STATUS_REQ_MASK 0x08 +#define SERDES_25G_LANE_TOP_PWR_STATE_REQ_STATUS_REQ_SHIFT 3 + +#define SERDES_25G_LANE_TOP_PWR_STATE_ACK_CTRL_STATE_MASK 0x07 +#define SERDES_25G_LANE_TOP_PWR_STATE_ACK_CTRL_STATE_SHIFT 0 + +#define SERDES_25G_LANE_TOP_PWR_STATE_ACK_CTRL_ACK_MASK 0x08 +#define SERDES_25G_LANE_TOP_PWR_STATE_ACK_CTRL_ACK_SHIFT 3 + +#define SERDES_25G_LANE_TOP_PWR_STATE_ACK_CTRL_DELAY_LEN_MASK 0x70 +#define SERDES_25G_LANE_TOP_PWR_STATE_ACK_CTRL_DELAY_LEN_SHIFT 4 + +#define SERDES_25G_LANE_TOP_PHY_IF_STATUS_LN_OK_MASK 0x01 +#define SERDES_25G_LANE_TOP_PHY_IF_STATUS_LN_OK_SHIFT 0 + +#define SERDES_25G_LANE_TOP_DELAY_CTRL0_RX_DATA_EDELAY_MASK 0x07 +#define SERDES_25G_LANE_TOP_DELAY_CTRL0_RX_DATA_EDELAY_SHIFT 0 + +#define SERDES_25G_LANE_TOP_DELAY_CTRL0_RX_EDGE_DELAY_MASK 0x38 +#define SERDES_25G_LANE_TOP_DELAY_CTRL0_RX_EDGE_DELAY_SHIFT 3 + +#define SERDES_25G_LANE_TOP_DELAY_CTRL1_RX_DATA_IDELAY_MASK 0x07 +#define SERDES_25G_LANE_TOP_DELAY_CTRL1_RX_DATA_IDELAY_SHIFT 0 + +#define SERDES_25G_LANE_TOP_DELAY_CTRL1_RX_EYE_DELAY_MASK 0x38 +#define SERDES_25G_LANE_TOP_DELAY_CTRL1_RX_EYE_DELAY_SHIFT 3 + +#define SERDES_25G_LANE_TOP_LN_STAT_CTRL0_RXVALID_MASK 0x01 +#define SERDES_25G_LANE_TOP_LN_STAT_CTRL0_RXVALID_SHIFT 0 + +#define SERDES_25G_LANE_TOP_LN_STAT_CTRL_OVR_OVR_EN_MASK 0x01 +#define SERDES_25G_LANE_TOP_LN_STAT_CTRL_OVR_OVR_EN_SHIFT 0 + +#define SERDES_25G_LANE_TOP_LN_STAT_CTRL_OVR_RST_PD_READY_MASK 0x02 +#define SERDES_25G_LANE_TOP_LN_STAT_CTRL_OVR_RST_PD_READY_SHIFT 1 + +#define SERDES_25G_LANE_TOP_LN_STAT_STATUS0_RST_PD_READY_MASK 0x01 +#define SERDES_25G_LANE_TOP_LN_STAT_STATUS0_RST_PD_READY_SHIFT 0 + +#define SERDES_25G_LANE_TOP_LN_CTRL_OVR0_OVR_EN_MASK 0x01 +#define SERDES_25G_LANE_TOP_LN_CTRL_OVR0_OVR_EN_SHIFT 0 + +#define SERDES_25G_LANE_TOP_LN_CTRL_OVR0_TX_DATA_WIDTH_MASK 0x02 +#define SERDES_25G_LANE_TOP_LN_CTRL_OVR0_TX_DATA_WIDTH_SHIFT 1 + +#define SERDES_25G_LANE_TOP_LN_CTRL_OVR0_RX_DATA_WIDTH_MASK 0x04 +#define SERDES_25G_LANE_TOP_LN_CTRL_OVR0_RX_DATA_WIDTH_SHIFT 2 + +#define SERDES_25G_LANE_TOP_LN_CTRL_OVR0_RXPOLARITY_MASK 0x08 +#define SERDES_25G_LANE_TOP_LN_CTRL_OVR0_RXPOLARITY_SHIFT 3 + +#define SERDES_25G_LANE_TOP_LN_CTRL_OVR0_TX_EN_MASK 0x10 +#define SERDES_25G_LANE_TOP_LN_CTRL_OVR0_TX_EN_SHIFT 4 + +#define SERDES_25G_LANE_TOP_LN_CTRL_OVR0_LOS_EII_EN_MASK 0x20 +#define SERDES_25G_LANE_TOP_LN_CTRL_OVR0_LOS_EII_EN_SHIFT 5 + +#define SERDES_25G_LANE_TOP_LN_CTRL_OVR0_LOS_EII_VALUE_MASK 0x40 +#define SERDES_25G_LANE_TOP_LN_CTRL_OVR0_LOS_EII_VALUE_SHIFT 6 + +#define SERDES_25G_LANE_TOP_LN_CTRL_OVR1_OVR_EN_MASK 0x01 +#define SERDES_25G_LANE_TOP_LN_CTRL_OVR1_OVR_EN_SHIFT 0 + +#define SERDES_25G_LANE_TOP_LN_CTRL_OVR1_PD_MASK 0x06 +#define SERDES_25G_LANE_TOP_LN_CTRL_OVR1_PD_SHIFT 1 + +#define SERDES_25G_LANE_TOP_LN_CTRL_OVR1_RST_N_MASK 0x08 +#define SERDES_25G_LANE_TOP_LN_CTRL_OVR1_RST_N_SHIFT 3 + +#define SERDES_25G_LANE_TOP_LN_CTRL_STATUS0_TX_DATA_WIDTH_MASK 0x01 +#define SERDES_25G_LANE_TOP_LN_CTRL_STATUS0_TX_DATA_WIDTH_SHIFT 0 + +#define SERDES_25G_LANE_TOP_LN_CTRL_STATUS0_RX_DATA_WIDTH_MASK 0x02 +#define SERDES_25G_LANE_TOP_LN_CTRL_STATUS0_RX_DATA_WIDTH_SHIFT 1 + +#define SERDES_25G_LANE_TOP_ERR_CTRL1_ERR_CODE_7_0_MASK 0xFF +#define SERDES_25G_LANE_TOP_ERR_CTRL1_ERR_CODE_7_0_SHIFT 0 + +#define SERDES_25G_LANE_TOP_ERR_CTRL2_ERR_CODE_15_8_MASK 0xFF +#define SERDES_25G_LANE_TOP_ERR_CTRL2_ERR_CODE_15_8_SHIFT 0 + +/********************************* LEQ_REFCLK *********************************/ +#define SERDES_25G_LANE_LEQ_REFCLK_BASE 0x200 + +#define SERDES_25G_LANE_LEQ_REFCLK_AFE_PD_CTRL0_ADDR (SERDES_25G_LANE_LEQ_REFCLK_BASE + 0x00) +#define SERDES_25G_LANE_LEQ_REFCLK_AFE_BIAS_CTRL0_ADDR (SERDES_25G_LANE_LEQ_REFCLK_BASE + 0x02) +#define SERDES_25G_LANE_LEQ_REFCLK_AFE_BIAS_CTRL1_ADDR (SERDES_25G_LANE_LEQ_REFCLK_BASE + 0x03) +#define SERDES_25G_LANE_LEQ_REFCLK_AFE_PLE_CTRL0_ADDR (SERDES_25G_LANE_LEQ_REFCLK_BASE + 0x05) +#define SERDES_25G_LANE_LEQ_REFCLK_AFE_EQ_CTRL0_ADDR (SERDES_25G_LANE_LEQ_REFCLK_BASE + 0x07) +#define SERDES_25G_LANE_LEQ_REFCLK_AFE_MISC_CTRL0_ADDR (SERDES_25G_LANE_LEQ_REFCLK_BASE + 0x09) +#define SERDES_25G_LANE_LEQ_REFCLK_GN_CTRL0_ADDR (SERDES_25G_LANE_LEQ_REFCLK_BASE + 0x0A) +#define SERDES_25G_LANE_LEQ_REFCLK_GN_CTRL1_ADDR (SERDES_25G_LANE_LEQ_REFCLK_BASE + 0x0B) +#define SERDES_25G_LANE_LEQ_REFCLK_GN_CTRL2_ADDR (SERDES_25G_LANE_LEQ_REFCLK_BASE + 0x0C) +#define SERDES_25G_LANE_LEQ_REFCLK_EQ_CTRL0_ADDR (SERDES_25G_LANE_LEQ_REFCLK_BASE + 0x0E) +#define SERDES_25G_LANE_LEQ_REFCLK_EQ_CTRL1_ADDR (SERDES_25G_LANE_LEQ_REFCLK_BASE + 0x0F) +#define SERDES_25G_LANE_LEQ_REFCLK_EQ_CTRL2_ADDR (SERDES_25G_LANE_LEQ_REFCLK_BASE + 0x10) +#define SERDES_25G_LANE_LEQ_REFCLK_EQ_CTRL3_ADDR (SERDES_25G_LANE_LEQ_REFCLK_BASE + 0x11) +#define SERDES_25G_LANE_LEQ_REFCLK_LEQ_FSM_CTRL0_ADDR (SERDES_25G_LANE_LEQ_REFCLK_BASE + 0x20) +#define SERDES_25G_LANE_LEQ_REFCLK_LEQ_FSM_CMD0_ADDR (SERDES_25G_LANE_LEQ_REFCLK_BASE + 0x21) +#define SERDES_25G_LANE_LEQ_REFCLK_LEQ_FSM_CMD1_ADDR (SERDES_25G_LANE_LEQ_REFCLK_BASE + 0x22) +#define SERDES_25G_LANE_LEQ_REFCLK_LEQ_FSM_CMD2_ADDR (SERDES_25G_LANE_LEQ_REFCLK_BASE + 0x23) +#define SERDES_25G_LANE_LEQ_REFCLK_LEQ_FSM_STATUS0_ADDR (SERDES_25G_LANE_LEQ_REFCLK_BASE + 0x24) +#define SERDES_25G_LANE_LEQ_REFCLK_LEQ_FSM_STATUS1_ADDR (SERDES_25G_LANE_LEQ_REFCLK_BASE + 0x25) +#define SERDES_25G_LANE_LEQ_REFCLK_LEQ_FSM_STATUS2_ADDR (SERDES_25G_LANE_LEQ_REFCLK_BASE + 0x26) +#define SERDES_25G_LANE_LEQ_REFCLK_LEQ_FSM_STATUS3_ADDR (SERDES_25G_LANE_LEQ_REFCLK_BASE + 0x27) +#define SERDES_25G_LANE_LEQ_REFCLK_LEQ_FSM_STATUS4_ADDR (SERDES_25G_LANE_LEQ_REFCLK_BASE + 0x28) +#define SERDES_25G_LANE_LEQ_REFCLK_LEQ_FSM_CTRL1_ADDR (SERDES_25G_LANE_LEQ_REFCLK_BASE + 0x29) +#define SERDES_25G_LANE_LEQ_REFCLK_LEQ_FSM_CTRL2_ADDR (SERDES_25G_LANE_LEQ_REFCLK_BASE + 0x2A) +#define SERDES_25G_LANE_LEQ_REFCLK_LEQ_FSM_STATUS5_ADDR (SERDES_25G_LANE_LEQ_REFCLK_BASE + 0x2B) +#define SERDES_25G_LANE_LEQ_REFCLK_LEQ_FSM_STATUS6_ADDR (SERDES_25G_LANE_LEQ_REFCLK_BASE + 0x2C) +#define SERDES_25G_LANE_LEQ_REFCLK_LEQ_OUTINTF_CTRL0_ADDR (SERDES_25G_LANE_LEQ_REFCLK_BASE + 0x2E) +#define SERDES_25G_LANE_LEQ_REFCLK_AGCLOS_CTRL0_ADDR (SERDES_25G_LANE_LEQ_REFCLK_BASE + 0x30) +#define SERDES_25G_LANE_LEQ_REFCLK_AGCLOS_CTRL1_ADDR (SERDES_25G_LANE_LEQ_REFCLK_BASE + 0x31) +#define SERDES_25G_LANE_LEQ_REFCLK_AGCLOS_CTRL2_ADDR (SERDES_25G_LANE_LEQ_REFCLK_BASE + 0x32) +#define SERDES_25G_LANE_LEQ_REFCLK_AGCLOS_CTRL3_ADDR (SERDES_25G_LANE_LEQ_REFCLK_BASE + 0x33) +#define SERDES_25G_LANE_LEQ_REFCLK_AGCLOS_CTRL4_ADDR (SERDES_25G_LANE_LEQ_REFCLK_BASE + 0x34) +#define SERDES_25G_LANE_LEQ_REFCLK_AGCLOS_CTRL5_ADDR (SERDES_25G_LANE_LEQ_REFCLK_BASE + 0x35) +#define SERDES_25G_LANE_LEQ_REFCLK_AGCLOS_CTRL6_ADDR (SERDES_25G_LANE_LEQ_REFCLK_BASE + 0x36) +#define SERDES_25G_LANE_LEQ_REFCLK_AGCLOS_CTRL7_ADDR (SERDES_25G_LANE_LEQ_REFCLK_BASE + 0x37) +#define SERDES_25G_LANE_LEQ_REFCLK_AGCLOS_CTRL8_ADDR (SERDES_25G_LANE_LEQ_REFCLK_BASE + 0x38) +#define SERDES_25G_LANE_LEQ_REFCLK_AGCLOS_CTRL9_ADDR (SERDES_25G_LANE_LEQ_REFCLK_BASE + 0x39) +#define SERDES_25G_LANE_LEQ_REFCLK_AGCLOS_CTRL10_ADDR (SERDES_25G_LANE_LEQ_REFCLK_BASE + 0x3A) +#define SERDES_25G_LANE_LEQ_REFCLK_PLE_LFG_CTRL0_ADDR (SERDES_25G_LANE_LEQ_REFCLK_BASE + 0x3D) +#define SERDES_25G_LANE_LEQ_REFCLK_PLE_LFG_CTRL1_ADDR (SERDES_25G_LANE_LEQ_REFCLK_BASE + 0x3E) +#define SERDES_25G_LANE_LEQ_REFCLK_EQ_HFG_SQL_CTRL0_ADDR (SERDES_25G_LANE_LEQ_REFCLK_BASE + 0x40) +#define SERDES_25G_LANE_LEQ_REFCLK_EQ_HFG_SQL_CTRL1_ADDR (SERDES_25G_LANE_LEQ_REFCLK_BASE + 0x41) +#define SERDES_25G_LANE_LEQ_REFCLK_EQ_HFG_SQL_CTRL2_ADDR (SERDES_25G_LANE_LEQ_REFCLK_BASE + 0x42) +#define SERDES_25G_LANE_LEQ_REFCLK_EQ_HFG_SQL_CTRL3_ADDR (SERDES_25G_LANE_LEQ_REFCLK_BASE + 0x43) +#define SERDES_25G_LANE_LEQ_REFCLK_EQ_HFG_SQL_CTRL4_ADDR (SERDES_25G_LANE_LEQ_REFCLK_BASE + 0x44) +#define SERDES_25G_LANE_LEQ_REFCLK_EQ_HFG_SQL_CTRL5_ADDR (SERDES_25G_LANE_LEQ_REFCLK_BASE + 0x45) +#define SERDES_25G_LANE_LEQ_REFCLK_EQ_HFG_SQL_CTRL6_ADDR (SERDES_25G_LANE_LEQ_REFCLK_BASE + 0x46) +#define SERDES_25G_LANE_LEQ_REFCLK_EQ_SQL_CTRL0_ADDR (SERDES_25G_LANE_LEQ_REFCLK_BASE + 0x50) +#define SERDES_25G_LANE_LEQ_REFCLK_EQ_SQL_CTRL1_ADDR (SERDES_25G_LANE_LEQ_REFCLK_BASE + 0x51) +#define SERDES_25G_LANE_LEQ_REFCLK_EQ_SQL_CTRL2_ADDR (SERDES_25G_LANE_LEQ_REFCLK_BASE + 0x52) +#define SERDES_25G_LANE_LEQ_REFCLK_EQ_SQL_CTRL3_ADDR (SERDES_25G_LANE_LEQ_REFCLK_BASE + 0x53) +#define SERDES_25G_LANE_LEQ_REFCLK_EQ_SQL_CTRL4_ADDR (SERDES_25G_LANE_LEQ_REFCLK_BASE + 0x54) +#define SERDES_25G_LANE_LEQ_REFCLK_EQ_SQL_CTRL5_ADDR (SERDES_25G_LANE_LEQ_REFCLK_BASE + 0x55) +#define SERDES_25G_LANE_LEQ_REFCLK_EQ_SQL_CTRL6_ADDR (SERDES_25G_LANE_LEQ_REFCLK_BASE + 0x56) +#define SERDES_25G_LANE_LEQ_REFCLK_EQ_SQL_CTRL7_ADDR (SERDES_25G_LANE_LEQ_REFCLK_BASE + 0x57) +#define SERDES_25G_LANE_LEQ_REFCLK_EQ_SQL_CTRL8_ADDR (SERDES_25G_LANE_LEQ_REFCLK_BASE + 0x58) +#define SERDES_25G_LANE_LEQ_REFCLK_EQ_SQL_CTRL9_ADDR (SERDES_25G_LANE_LEQ_REFCLK_BASE + 0x59) +#define SERDES_25G_LANE_LEQ_REFCLK_EQ_SQL_CTRL10_ADDR (SERDES_25G_LANE_LEQ_REFCLK_BASE + 0x5A) +#define SERDES_25G_LANE_LEQ_REFCLK_EQ_SQL_CTRL11_ADDR (SERDES_25G_LANE_LEQ_REFCLK_BASE + 0x5B) +#define SERDES_25G_LANE_LEQ_REFCLK_EQ_SQL_CTRL12_ADDR (SERDES_25G_LANE_LEQ_REFCLK_BASE + 0x5C) +#define SERDES_25G_LANE_LEQ_REFCLK_EQ_SQL_CTRL13_ADDR (SERDES_25G_LANE_LEQ_REFCLK_BASE + 0x5D) +#define SERDES_25G_LANE_LEQ_REFCLK_EQ_SQL_CTRL14_ADDR (SERDES_25G_LANE_LEQ_REFCLK_BASE + 0x5E) +#define SERDES_25G_LANE_LEQ_REFCLK_EQ_SQL_CTRL15_ADDR (SERDES_25G_LANE_LEQ_REFCLK_BASE + 0x5F) +#define SERDES_25G_LANE_LEQ_REFCLK_EQ_SQL_CTRL16_ADDR (SERDES_25G_LANE_LEQ_REFCLK_BASE + 0x60) +#define SERDES_25G_LANE_LEQ_REFCLK_EQ_SQL_CTRL17_ADDR (SERDES_25G_LANE_LEQ_REFCLK_BASE + 0x61) +#define SERDES_25G_LANE_LEQ_REFCLK_EQ_SQL_CTRL18_ADDR (SERDES_25G_LANE_LEQ_REFCLK_BASE + 0x62) +#define SERDES_25G_LANE_LEQ_REFCLK_EQ_SQL_CTRL19_ADDR (SERDES_25G_LANE_LEQ_REFCLK_BASE + 0x63) +#define SERDES_25G_LANE_LEQ_REFCLK_EQ_SQL_CTRL20_ADDR (SERDES_25G_LANE_LEQ_REFCLK_BASE + 0x64) +#define SERDES_25G_LANE_LEQ_REFCLK_EQ_SQL_CTRL21_ADDR (SERDES_25G_LANE_LEQ_REFCLK_BASE + 0x65) +#define SERDES_25G_LANE_LEQ_REFCLK_EQ_SQL_CTRL22_ADDR (SERDES_25G_LANE_LEQ_REFCLK_BASE + 0x66) +#define SERDES_25G_LANE_LEQ_REFCLK_EQ_SQL_CTRL23_ADDR (SERDES_25G_LANE_LEQ_REFCLK_BASE + 0x67) +#define SERDES_25G_LANE_LEQ_REFCLK_EQ_SQL_CTRL24_ADDR (SERDES_25G_LANE_LEQ_REFCLK_BASE + 0x68) +#define SERDES_25G_LANE_LEQ_REFCLK_GN_APG_CTRL0_ADDR (SERDES_25G_LANE_LEQ_REFCLK_BASE + 0x70) +#define SERDES_25G_LANE_LEQ_REFCLK_GN_APG_CTRL1_ADDR (SERDES_25G_LANE_LEQ_REFCLK_BASE + 0x71) +#define SERDES_25G_LANE_LEQ_REFCLK_GN_APG_CTRL2_ADDR (SERDES_25G_LANE_LEQ_REFCLK_BASE + 0x72) +#define SERDES_25G_LANE_LEQ_REFCLK_GN_APG_CTRL3_ADDR (SERDES_25G_LANE_LEQ_REFCLK_BASE + 0x73) +#define SERDES_25G_LANE_LEQ_REFCLK_GN_APG_CTRL4_ADDR (SERDES_25G_LANE_LEQ_REFCLK_BASE + 0x74) +#define SERDES_25G_LANE_LEQ_REFCLK_GN_APG_CTRL5_ADDR (SERDES_25G_LANE_LEQ_REFCLK_BASE + 0x75) +#define SERDES_25G_LANE_LEQ_REFCLK_GN_APG_CTRL6_ADDR (SERDES_25G_LANE_LEQ_REFCLK_BASE + 0x76) +#define SERDES_25G_LANE_LEQ_REFCLK_EQ_LFG_CTRL0_ADDR (SERDES_25G_LANE_LEQ_REFCLK_BASE + 0x80) +#define SERDES_25G_LANE_LEQ_REFCLK_EQ_LFG_CTRL1_ADDR (SERDES_25G_LANE_LEQ_REFCLK_BASE + 0x81) +#define SERDES_25G_LANE_LEQ_REFCLK_EQ_LFG_CTRL2_ADDR (SERDES_25G_LANE_LEQ_REFCLK_BASE + 0x82) +#define SERDES_25G_LANE_LEQ_REFCLK_EQ_LFG_CTRL3_ADDR (SERDES_25G_LANE_LEQ_REFCLK_BASE + 0x83) +#define SERDES_25G_LANE_LEQ_REFCLK_EQ_LFG_CTRL4_ADDR (SERDES_25G_LANE_LEQ_REFCLK_BASE + 0x84) +#define SERDES_25G_LANE_LEQ_REFCLK_EQ_LFG_CTRL5_ADDR (SERDES_25G_LANE_LEQ_REFCLK_BASE + 0x85) +#define SERDES_25G_LANE_LEQ_REFCLK_EQ_LFG_CTRL6_ADDR (SERDES_25G_LANE_LEQ_REFCLK_BASE + 0x86) +#define SERDES_25G_LANE_LEQ_REFCLK_EQ_LFG_CTRL7_ADDR (SERDES_25G_LANE_LEQ_REFCLK_BASE + 0x87) +#define SERDES_25G_LANE_LEQ_REFCLK_EQ_LFG_CTRL8_ADDR (SERDES_25G_LANE_LEQ_REFCLK_BASE + 0x88) +#define SERDES_25G_LANE_LEQ_REFCLK_GNEQ_CCL_LFG_CTRL0_ADDR (SERDES_25G_LANE_LEQ_REFCLK_BASE + 0x90) +#define SERDES_25G_LANE_LEQ_REFCLK_GNEQ_CCL_LFG_CTRL1_ADDR (SERDES_25G_LANE_LEQ_REFCLK_BASE + 0x91) +#define SERDES_25G_LANE_LEQ_REFCLK_GNEQ_CCL_LFG_CTRL2_ADDR (SERDES_25G_LANE_LEQ_REFCLK_BASE + 0x92) +#define SERDES_25G_LANE_LEQ_REFCLK_GNEQ_CCL_LFG_CTRL3_ADDR (SERDES_25G_LANE_LEQ_REFCLK_BASE + 0x93) +#define SERDES_25G_LANE_LEQ_REFCLK_GNEQ_CCL_LFG_CTRL4_ADDR (SERDES_25G_LANE_LEQ_REFCLK_BASE + 0x94) +#define SERDES_25G_LANE_LEQ_REFCLK_GNEQ_CCL_LFG_CTRL5_ADDR (SERDES_25G_LANE_LEQ_REFCLK_BASE + 0x95) +#define SERDES_25G_LANE_LEQ_REFCLK_GNEQ_CCL_LFG_CTRL6_ADDR (SERDES_25G_LANE_LEQ_REFCLK_BASE + 0x96) +#define SERDES_25G_LANE_LEQ_REFCLK_EQ_MB_CTRL0_ADDR (SERDES_25G_LANE_LEQ_REFCLK_BASE + 0x98) +#define SERDES_25G_LANE_LEQ_REFCLK_EQ_MB_CTRL1_ADDR (SERDES_25G_LANE_LEQ_REFCLK_BASE + 0x99) +#define SERDES_25G_LANE_LEQ_REFCLK_VSCAN_CTRL0_ADDR (SERDES_25G_LANE_LEQ_REFCLK_BASE + 0x9A) +#define SERDES_25G_LANE_LEQ_REFCLK_VSCAN_CTRL1_ADDR (SERDES_25G_LANE_LEQ_REFCLK_BASE + 0x9B) +#define SERDES_25G_LANE_LEQ_REFCLK_VSCAN_CTRL2_ADDR (SERDES_25G_LANE_LEQ_REFCLK_BASE + 0x9C) +#define SERDES_25G_LANE_LEQ_REFCLK_VSCAN_CTRL3_ADDR (SERDES_25G_LANE_LEQ_REFCLK_BASE + 0x9D) +#define SERDES_25G_LANE_LEQ_REFCLK_HSCAN_CTRL0_ADDR (SERDES_25G_LANE_LEQ_REFCLK_BASE + 0xA0) +#define SERDES_25G_LANE_LEQ_REFCLK_HSCAN_CTRL1_ADDR (SERDES_25G_LANE_LEQ_REFCLK_BASE + 0xA1) +#define SERDES_25G_LANE_LEQ_REFCLK_HSCAN_CTRL2_ADDR (SERDES_25G_LANE_LEQ_REFCLK_BASE + 0xA2) +#define SERDES_25G_LANE_LEQ_REFCLK_HSCAN_CTRL3_ADDR (SERDES_25G_LANE_LEQ_REFCLK_BASE + 0xA3) +#define SERDES_25G_LANE_LEQ_REFCLK_REF_THRESHOLD0_ADDR (SERDES_25G_LANE_LEQ_REFCLK_BASE + 0xA6) +#define SERDES_25G_LANE_LEQ_REFCLK_REF_THRESHOLD1_ADDR (SERDES_25G_LANE_LEQ_REFCLK_BASE + 0xA7) +#define SERDES_25G_LANE_LEQ_REFCLK_REF_THRESHOLD2_ADDR (SERDES_25G_LANE_LEQ_REFCLK_BASE + 0xA8) +#define SERDES_25G_LANE_LEQ_REFCLK_REF_THRESHOLD3_ADDR (SERDES_25G_LANE_LEQ_REFCLK_BASE + 0xA9) +#define SERDES_25G_LANE_LEQ_REFCLK_EYE_PHASE0_ADDR (SERDES_25G_LANE_LEQ_REFCLK_BASE + 0xAB) +#define SERDES_25G_LANE_LEQ_REFCLK_EYE_PHASE1_ADDR (SERDES_25G_LANE_LEQ_REFCLK_BASE + 0xAC) +#define SERDES_25G_LANE_LEQ_REFCLK_EYEMON_CTRL0_ADDR (SERDES_25G_LANE_LEQ_REFCLK_BASE + 0xAE) +#define SERDES_25G_LANE_LEQ_REFCLK_EYEINTF_CTRL0_ADDR (SERDES_25G_LANE_LEQ_REFCLK_BASE + 0xAF) +#define SERDES_25G_LANE_LEQ_REFCLK_LEQ_REFCLK_SPARE0_ADDR (SERDES_25G_LANE_LEQ_REFCLK_BASE + 0xB8) +#define SERDES_25G_LANE_LEQ_REFCLK_LEQ_REFCLK_SPARE1_ADDR (SERDES_25G_LANE_LEQ_REFCLK_BASE + 0xB9) + +/******************************************************************************* + * masks and shifts + ******************************************************************************/ +#define SERDES_25G_LANE_LEQ_REFCLK_AFE_PD_CTRL0_PD_RXLEQ_MASK 0x3F +#define SERDES_25G_LANE_LEQ_REFCLK_AFE_PD_CTRL0_PD_RXLEQ_SHIFT 0 + +#define SERDES_25G_LANE_LEQ_REFCLK_AFE_PD_CTRL0_PD_RXLEQ_BIASGEN_MASK 0x40 +#define SERDES_25G_LANE_LEQ_REFCLK_AFE_PD_CTRL0_PD_RXLEQ_BIASGEN_SHIFT 6 + +#define SERDES_25G_LANE_LEQ_REFCLK_AFE_BIAS_CTRL0_RXLEQ_BIAS_MASK 0xFF +#define SERDES_25G_LANE_LEQ_REFCLK_AFE_BIAS_CTRL0_RXLEQ_BIAS_SHIFT 0 + +#define SERDES_25G_LANE_LEQ_REFCLK_AFE_BIAS_CTRL1_RXLEQ_VGSW_SEL_MASK 0x07 +#define SERDES_25G_LANE_LEQ_REFCLK_AFE_BIAS_CTRL1_RXLEQ_VGSW_SEL_SHIFT 0 + +#define SERDES_25G_LANE_LEQ_REFCLK_AFE_BIAS_CTRL1_RXLEQ_BIASI_TRIM_MASK 0x18 +#define SERDES_25G_LANE_LEQ_REFCLK_AFE_BIAS_CTRL1_RXLEQ_BIASI_TRIM_SHIFT 3 + +#define SERDES_25G_LANE_LEQ_REFCLK_AFE_PLE_CTRL0_RXLEQ_PLE_MUTE_MASK 0x01 +#define SERDES_25G_LANE_LEQ_REFCLK_AFE_PLE_CTRL0_RXLEQ_PLE_MUTE_SHIFT 0 + +#define SERDES_25G_LANE_LEQ_REFCLK_AFE_PLE_CTRL0_RXLEQ_PLE_BLW_ZERO_MASK 0x06 +#define SERDES_25G_LANE_LEQ_REFCLK_AFE_PLE_CTRL0_RXLEQ_PLE_BLW_ZERO_SHIFT 1 + +#define SERDES_25G_LANE_LEQ_REFCLK_AFE_PLE_CTRL0_RXLEQ_PLE_PRECH_MASK 0x08 +#define SERDES_25G_LANE_LEQ_REFCLK_AFE_PLE_CTRL0_RXLEQ_PLE_PRECH_SHIFT 3 + +#define SERDES_25G_LANE_LEQ_REFCLK_AFE_EQ_CTRL0_RXLEQ_EQ_SQL_DIR_MASK 0x01 +#define SERDES_25G_LANE_LEQ_REFCLK_AFE_EQ_CTRL0_RXLEQ_EQ_SQL_DIR_SHIFT 0 + +#define SERDES_25G_LANE_LEQ_REFCLK_AFE_MISC_CTRL0_RXLEQ_SPARE_MASK 0x0F +#define SERDES_25G_LANE_LEQ_REFCLK_AFE_MISC_CTRL0_RXLEQ_SPARE_SHIFT 0 + +#define SERDES_25G_LANE_LEQ_REFCLK_GN_CTRL0_GN_LOADRES_START0_MASK 0x07 +#define SERDES_25G_LANE_LEQ_REFCLK_GN_CTRL0_GN_LOADRES_START0_SHIFT 0 + +#define SERDES_25G_LANE_LEQ_REFCLK_GN_CTRL0_GN_LOADRES_START1_MASK 0x38 +#define SERDES_25G_LANE_LEQ_REFCLK_GN_CTRL0_GN_LOADRES_START1_SHIFT 3 + +#define SERDES_25G_LANE_LEQ_REFCLK_GN_CTRL1_GN_LOADRES_START2_MASK 0x07 +#define SERDES_25G_LANE_LEQ_REFCLK_GN_CTRL1_GN_LOADRES_START2_SHIFT 0 + +#define SERDES_25G_LANE_LEQ_REFCLK_GN_CTRL1_GN_LOADRES_START3_MASK 0x38 +#define SERDES_25G_LANE_LEQ_REFCLK_GN_CTRL1_GN_LOADRES_START3_SHIFT 3 + +#define SERDES_25G_LANE_LEQ_REFCLK_GN_CTRL2_GN_BIASI_RATE0_MASK 0x03 +#define SERDES_25G_LANE_LEQ_REFCLK_GN_CTRL2_GN_BIASI_RATE0_SHIFT 0 + +#define SERDES_25G_LANE_LEQ_REFCLK_GN_CTRL2_GN_BIASI_RATE1_MASK 0x0C +#define SERDES_25G_LANE_LEQ_REFCLK_GN_CTRL2_GN_BIASI_RATE1_SHIFT 2 + +#define SERDES_25G_LANE_LEQ_REFCLK_GN_CTRL2_GN_BIASI_RATE2_MASK 0x30 +#define SERDES_25G_LANE_LEQ_REFCLK_GN_CTRL2_GN_BIASI_RATE2_SHIFT 4 + +#define SERDES_25G_LANE_LEQ_REFCLK_GN_CTRL2_GN_BIASI_RATE3_MASK 0xC0 +#define SERDES_25G_LANE_LEQ_REFCLK_GN_CTRL2_GN_BIASI_RATE3_SHIFT 6 + +#define SERDES_25G_LANE_LEQ_REFCLK_EQ_CTRL0_EQ_LOADRES_START0_MASK 0x07 +#define SERDES_25G_LANE_LEQ_REFCLK_EQ_CTRL0_EQ_LOADRES_START0_SHIFT 0 + +#define SERDES_25G_LANE_LEQ_REFCLK_EQ_CTRL0_EQ_LOADRES_START1_MASK 0x38 +#define SERDES_25G_LANE_LEQ_REFCLK_EQ_CTRL0_EQ_LOADRES_START1_SHIFT 3 + +#define SERDES_25G_LANE_LEQ_REFCLK_EQ_CTRL1_EQ_LOADRES_START2_MASK 0x07 +#define SERDES_25G_LANE_LEQ_REFCLK_EQ_CTRL1_EQ_LOADRES_START2_SHIFT 0 + +#define SERDES_25G_LANE_LEQ_REFCLK_EQ_CTRL1_EQ_LOADRES_START3_MASK 0x38 +#define SERDES_25G_LANE_LEQ_REFCLK_EQ_CTRL1_EQ_LOADRES_START3_SHIFT 3 + +#define SERDES_25G_LANE_LEQ_REFCLK_EQ_CTRL2_EQ_BIASRES_START0_MASK 0x07 +#define SERDES_25G_LANE_LEQ_REFCLK_EQ_CTRL2_EQ_BIASRES_START0_SHIFT 0 + +#define SERDES_25G_LANE_LEQ_REFCLK_EQ_CTRL2_EQ_BIASRES_START1_MASK 0x38 +#define SERDES_25G_LANE_LEQ_REFCLK_EQ_CTRL2_EQ_BIASRES_START1_SHIFT 3 + +#define SERDES_25G_LANE_LEQ_REFCLK_EQ_CTRL3_EQ_BIASRES_START2_MASK 0x07 +#define SERDES_25G_LANE_LEQ_REFCLK_EQ_CTRL3_EQ_BIASRES_START2_SHIFT 0 + +#define SERDES_25G_LANE_LEQ_REFCLK_EQ_CTRL3_EQ_BIASRES_START3_MASK 0x38 +#define SERDES_25G_LANE_LEQ_REFCLK_EQ_CTRL3_EQ_BIASRES_START3_SHIFT 3 + +#define SERDES_25G_LANE_LEQ_REFCLK_LEQ_FSM_CTRL0_LEQ_FSM_CMD_REQ_MASK 0x01 +#define SERDES_25G_LANE_LEQ_REFCLK_LEQ_FSM_CTRL0_LEQ_FSM_CMD_REQ_SHIFT 0 + +#define SERDES_25G_LANE_LEQ_REFCLK_LEQ_FSM_CTRL0_LEQ_FSM_STATE_RESET_MASK 0x04 +#define SERDES_25G_LANE_LEQ_REFCLK_LEQ_FSM_CTRL0_LEQ_FSM_STATE_RESET_SHIFT 2 + +#define SERDES_25G_LANE_LEQ_REFCLK_LEQ_FSM_CMD0_LEQ_FSM_CMD_OPCODE_MASK 0x0F +#define SERDES_25G_LANE_LEQ_REFCLK_LEQ_FSM_CMD0_LEQ_FSM_CMD_OPCODE_SHIFT 0 + +#define SERDES_25G_LANE_LEQ_REFCLK_LEQ_FSM_CMD0_LEQ_FSM_CMD_TARGET_MASK 0xF0 +#define SERDES_25G_LANE_LEQ_REFCLK_LEQ_FSM_CMD0_LEQ_FSM_CMD_TARGET_SHIFT 4 + +#define SERDES_25G_LANE_LEQ_REFCLK_LEQ_FSM_CMD1_LEQ_FSM_CMD_SCRATCHPAD_MASK 0xFF +#define SERDES_25G_LANE_LEQ_REFCLK_LEQ_FSM_CMD1_LEQ_FSM_CMD_SCRATCHPAD_SHIFT 0 + +#define SERDES_25G_LANE_LEQ_REFCLK_LEQ_FSM_CMD2_LEQ_FSM_CMD_MISC_OPTION_MASK 0xFF +#define SERDES_25G_LANE_LEQ_REFCLK_LEQ_FSM_CMD2_LEQ_FSM_CMD_MISC_OPTION_SHIFT 0 + +#define SERDES_25G_LANE_LEQ_REFCLK_LEQ_FSM_STATUS0_LEQ_FSM_STATUS_ERROR1_MASK 0x07 +#define SERDES_25G_LANE_LEQ_REFCLK_LEQ_FSM_STATUS0_LEQ_FSM_STATUS_ERROR1_SHIFT 0 + +#define SERDES_25G_LANE_LEQ_REFCLK_LEQ_FSM_STATUS0_LEQ_FSM_STATUS_ERROR2_MASK 0x38 +#define SERDES_25G_LANE_LEQ_REFCLK_LEQ_FSM_STATUS0_LEQ_FSM_STATUS_ERROR2_SHIFT 3 + +#define SERDES_25G_LANE_LEQ_REFCLK_LEQ_FSM_STATUS0_LEQ_FSM_MAX_CLAMP_MASK 0x40 +#define SERDES_25G_LANE_LEQ_REFCLK_LEQ_FSM_STATUS0_LEQ_FSM_MAX_CLAMP_SHIFT 6 + +#define SERDES_25G_LANE_LEQ_REFCLK_LEQ_FSM_STATUS0_LEQ_FSM_MIN_CLAMP_MASK 0x80 +#define SERDES_25G_LANE_LEQ_REFCLK_LEQ_FSM_STATUS0_LEQ_FSM_MIN_CLAMP_SHIFT 7 + +#define SERDES_25G_LANE_LEQ_REFCLK_LEQ_FSM_STATUS1_LEQ_FSM_STATE_MASK 0x0F +#define SERDES_25G_LANE_LEQ_REFCLK_LEQ_FSM_STATUS1_LEQ_FSM_STATE_SHIFT 0 + +#define SERDES_25G_LANE_LEQ_REFCLK_LEQ_FSM_STATUS1_LEQ_FSM_LAST_RESULT_MASK 0xF0 +#define SERDES_25G_LANE_LEQ_REFCLK_LEQ_FSM_STATUS1_LEQ_FSM_LAST_RESULT_SHIFT 4 + +#define SERDES_25G_LANE_LEQ_REFCLK_LEQ_FSM_STATUS2_LEQ_FSM_LAST_STEP_MASK 0xFF +#define SERDES_25G_LANE_LEQ_REFCLK_LEQ_FSM_STATUS2_LEQ_FSM_LAST_STEP_SHIFT 0 + +#define SERDES_25G_LANE_LEQ_REFCLK_LEQ_FSM_STATUS3_LEQ_FSM_LAST_VALUE_MASK 0xFF +#define SERDES_25G_LANE_LEQ_REFCLK_LEQ_FSM_STATUS3_LEQ_FSM_LAST_VALUE_SHIFT 0 + +#define SERDES_25G_LANE_LEQ_REFCLK_LEQ_FSM_STATUS4_LEQ_FSM_LAST_OPCODE_MASK 0x0F +#define SERDES_25G_LANE_LEQ_REFCLK_LEQ_FSM_STATUS4_LEQ_FSM_LAST_OPCODE_SHIFT 0 + +#define SERDES_25G_LANE_LEQ_REFCLK_LEQ_FSM_STATUS4_LEQ_FSM_LAST_TARGET_MASK 0xF0 +#define SERDES_25G_LANE_LEQ_REFCLK_LEQ_FSM_STATUS4_LEQ_FSM_LAST_TARGET_SHIFT 4 + +#define SERDES_25G_LANE_LEQ_REFCLK_LEQ_FSM_CTRL1_LEQ_FSM_TIMEOUT_LIMIT_7_0_MASK 0xFF +#define SERDES_25G_LANE_LEQ_REFCLK_LEQ_FSM_CTRL1_LEQ_FSM_TIMEOUT_LIMIT_7_0_SHIFT 0 + +#define SERDES_25G_LANE_LEQ_REFCLK_LEQ_FSM_CTRL2_LEQ_FSM_TIMEOUT_LIMIT_15_8_MASK 0xFF +#define SERDES_25G_LANE_LEQ_REFCLK_LEQ_FSM_CTRL2_LEQ_FSM_TIMEOUT_LIMIT_15_8_SHIFT 0 + +#define SERDES_25G_LANE_LEQ_REFCLK_LEQ_FSM_STATUS5_LEQ_FSM_CMD_ACK_MASK 0x02 +#define SERDES_25G_LANE_LEQ_REFCLK_LEQ_FSM_STATUS5_LEQ_FSM_CMD_ACK_SHIFT 1 + +#define SERDES_25G_LANE_LEQ_REFCLK_LEQ_FSM_STATUS6_LEQ_FSM_2LST_VALUE_MASK 0xFF +#define SERDES_25G_LANE_LEQ_REFCLK_LEQ_FSM_STATUS6_LEQ_FSM_2LST_VALUE_SHIFT 0 + +#define SERDES_25G_LANE_LEQ_REFCLK_LEQ_OUTINTF_CTRL0_LEQ_OUTINTF_RDY_WAIT_MASK 0xFF +#define SERDES_25G_LANE_LEQ_REFCLK_LEQ_OUTINTF_CTRL0_LEQ_OUTINTF_RDY_WAIT_SHIFT 0 + +#define SERDES_25G_LANE_LEQ_REFCLK_AGCLOS_CTRL0_AGCLOS_START_MASK 0x0F +#define SERDES_25G_LANE_LEQ_REFCLK_AGCLOS_CTRL0_AGCLOS_START_SHIFT 0 + +#define SERDES_25G_LANE_LEQ_REFCLK_AGCLOS_CTRL1_AGCLOS_VALUE_MAX_MASK 0x0F +#define SERDES_25G_LANE_LEQ_REFCLK_AGCLOS_CTRL1_AGCLOS_VALUE_MAX_SHIFT 0 + +#define SERDES_25G_LANE_LEQ_REFCLK_AGCLOS_CTRL2_AGCLOS_VALUE_MIN_MASK 0x0F +#define SERDES_25G_LANE_LEQ_REFCLK_AGCLOS_CTRL2_AGCLOS_VALUE_MIN_SHIFT 0 + +#define SERDES_25G_LANE_LEQ_REFCLK_AGCLOS_CTRL3_AGCLOS_WRWAIT_TIME_MASK 0x0F +#define SERDES_25G_LANE_LEQ_REFCLK_AGCLOS_CTRL3_AGCLOS_WRWAIT_TIME_SHIFT 0 + +#define SERDES_25G_LANE_LEQ_REFCLK_AGCLOS_CTRL3_AGCLOS_INIT_TIMEOUT_DISABLE_MASK 0x40 +#define SERDES_25G_LANE_LEQ_REFCLK_AGCLOS_CTRL3_AGCLOS_INIT_TIMEOUT_DISABLE_SHIFT 6 + +#define SERDES_25G_LANE_LEQ_REFCLK_AGCLOS_CTRL3_AGCLOS_MEASURE_TIMEOUT_DISABLE_MASK 0x80 +#define SERDES_25G_LANE_LEQ_REFCLK_AGCLOS_CTRL3_AGCLOS_MEASURE_TIMEOUT_DISABLE_SHIFT 7 + +#define SERDES_25G_LANE_LEQ_REFCLK_AGCLOS_CTRL4_AGCLOS_STEP_BY1_MASK 0x01 +#define SERDES_25G_LANE_LEQ_REFCLK_AGCLOS_CTRL4_AGCLOS_STEP_BY1_SHIFT 0 + +#define SERDES_25G_LANE_LEQ_REFCLK_AGCLOS_CTRL4_AGCLOS_ERROR_SIGN_MASK 0x02 +#define SERDES_25G_LANE_LEQ_REFCLK_AGCLOS_CTRL4_AGCLOS_ERROR_SIGN_SHIFT 1 + +#define SERDES_25G_LANE_LEQ_REFCLK_AGCLOS_CTRL4_AGCLOS_STEP_SIZE_MASK 0x1C +#define SERDES_25G_LANE_LEQ_REFCLK_AGCLOS_CTRL4_AGCLOS_STEP_SIZE_SHIFT 2 + +#define SERDES_25G_LANE_LEQ_REFCLK_AGCLOS_CTRL5_AGCLOS_BOUNCE_LIMIT_MASK 0x0F +#define SERDES_25G_LANE_LEQ_REFCLK_AGCLOS_CTRL5_AGCLOS_BOUNCE_LIMIT_SHIFT 0 + +#define SERDES_25G_LANE_LEQ_REFCLK_AGCLOS_CTRL5_AGCLOS_LASTWR_AVG_MASK 0x30 +#define SERDES_25G_LANE_LEQ_REFCLK_AGCLOS_CTRL5_AGCLOS_LASTWR_AVG_SHIFT 4 + +#define SERDES_25G_LANE_LEQ_REFCLK_AGCLOS_CTRL5_AGCLOS_LASTWR_FLOOR_MASK 0x40 +#define SERDES_25G_LANE_LEQ_REFCLK_AGCLOS_CTRL5_AGCLOS_LASTWR_FLOOR_SHIFT 6 + +#define SERDES_25G_LANE_LEQ_REFCLK_AGCLOS_CTRL6_AGCLOS_LASTWR_ADJUST_MASK 0x0F +#define SERDES_25G_LANE_LEQ_REFCLK_AGCLOS_CTRL6_AGCLOS_LASTWR_ADJUST_SHIFT 0 + +#define SERDES_25G_LANE_LEQ_REFCLK_AGCLOS_CTRL7_AGCLOS_PEAK_ACQ_TIME_7_0_MASK 0xFF +#define SERDES_25G_LANE_LEQ_REFCLK_AGCLOS_CTRL7_AGCLOS_PEAK_ACQ_TIME_7_0_SHIFT 0 + +#define SERDES_25G_LANE_LEQ_REFCLK_AGCLOS_CTRL8_AGCLOS_PEAK_ACQ_TIME_15_8_MASK 0xFF +#define SERDES_25G_LANE_LEQ_REFCLK_AGCLOS_CTRL8_AGCLOS_PEAK_ACQ_TIME_15_8_SHIFT 0 + +#define SERDES_25G_LANE_LEQ_REFCLK_AGCLOS_CTRL9_AGCLOS_PEAK_ACQ_TIME_23_16_MASK 0xFF +#define SERDES_25G_LANE_LEQ_REFCLK_AGCLOS_CTRL9_AGCLOS_PEAK_ACQ_TIME_23_16_SHIFT 0 + +#define SERDES_25G_LANE_LEQ_REFCLK_AGCLOS_CTRL10_AGCLOS_PEAK_ACQ_TIME_25_24_MASK 0x03 +#define SERDES_25G_LANE_LEQ_REFCLK_AGCLOS_CTRL10_AGCLOS_PEAK_ACQ_TIME_25_24_SHIFT 0 + +#define SERDES_25G_LANE_LEQ_REFCLK_PLE_LFG_CTRL0_PLE_LFG_WRWAIT_TIME_MASK 0x0F +#define SERDES_25G_LANE_LEQ_REFCLK_PLE_LFG_CTRL0_PLE_LFG_WRWAIT_TIME_SHIFT 0 + +#define SERDES_25G_LANE_LEQ_REFCLK_PLE_LFG_CTRL0_PLE_LFG_STEP_BY1_MASK 0x10 +#define SERDES_25G_LANE_LEQ_REFCLK_PLE_LFG_CTRL0_PLE_LFG_STEP_BY1_SHIFT 4 + +#define SERDES_25G_LANE_LEQ_REFCLK_PLE_LFG_CTRL1_PLE_LFG_START_MASK 0x07 +#define SERDES_25G_LANE_LEQ_REFCLK_PLE_LFG_CTRL1_PLE_LFG_START_SHIFT 0 + +#define SERDES_25G_LANE_LEQ_REFCLK_EQ_HFG_SQL_CTRL0_EQ_HFG_SQL_START_MASK 0x1F +#define SERDES_25G_LANE_LEQ_REFCLK_EQ_HFG_SQL_CTRL0_EQ_HFG_SQL_START_SHIFT 0 + +#define SERDES_25G_LANE_LEQ_REFCLK_EQ_HFG_SQL_CTRL1_EQ_HFG_SQL_VALUE_MAX_MASK 0x1F +#define SERDES_25G_LANE_LEQ_REFCLK_EQ_HFG_SQL_CTRL1_EQ_HFG_SQL_VALUE_MAX_SHIFT 0 + +#define SERDES_25G_LANE_LEQ_REFCLK_EQ_HFG_SQL_CTRL2_EQ_HFG_SQL_VALUE_MIN_MASK 0x1F +#define SERDES_25G_LANE_LEQ_REFCLK_EQ_HFG_SQL_CTRL2_EQ_HFG_SQL_VALUE_MIN_SHIFT 0 + +#define SERDES_25G_LANE_LEQ_REFCLK_EQ_HFG_SQL_CTRL3_EQ_HFG_SQL_WRWAIT_TIME_MASK 0x0F +#define SERDES_25G_LANE_LEQ_REFCLK_EQ_HFG_SQL_CTRL3_EQ_HFG_SQL_WRWAIT_TIME_SHIFT 0 + +#define SERDES_25G_LANE_LEQ_REFCLK_EQ_HFG_SQL_CTRL3_EQ_HFG_SQL_MEASURE_TIMEOUT_DISABLE_MASK 0x80 +#define SERDES_25G_LANE_LEQ_REFCLK_EQ_HFG_SQL_CTRL3_EQ_HFG_SQL_MEASURE_TIMEOUT_DISABLE_SHIFT 7 + +#define SERDES_25G_LANE_LEQ_REFCLK_EQ_HFG_SQL_CTRL4_EQ_HFG_SQL_STEP_BY1_MASK 0x01 +#define SERDES_25G_LANE_LEQ_REFCLK_EQ_HFG_SQL_CTRL4_EQ_HFG_SQL_STEP_BY1_SHIFT 0 + +#define SERDES_25G_LANE_LEQ_REFCLK_EQ_HFG_SQL_CTRL4_EQ_HFG_SQL_ERROR_SIGN_MASK 0x02 +#define SERDES_25G_LANE_LEQ_REFCLK_EQ_HFG_SQL_CTRL4_EQ_HFG_SQL_ERROR_SIGN_SHIFT 1 + +#define SERDES_25G_LANE_LEQ_REFCLK_EQ_HFG_SQL_CTRL4_EQ_HFG_SQL_STEP_SIZE_MASK 0x1C +#define SERDES_25G_LANE_LEQ_REFCLK_EQ_HFG_SQL_CTRL4_EQ_HFG_SQL_STEP_SIZE_SHIFT 2 + +#define SERDES_25G_LANE_LEQ_REFCLK_EQ_HFG_SQL_CTRL5_EQ_HFG_SQL_BOUNCE_LIMIT_MASK 0x0F +#define SERDES_25G_LANE_LEQ_REFCLK_EQ_HFG_SQL_CTRL5_EQ_HFG_SQL_BOUNCE_LIMIT_SHIFT 0 + +#define SERDES_25G_LANE_LEQ_REFCLK_EQ_HFG_SQL_CTRL5_EQ_HFG_SQL_LASTWR_AVG_MASK 0x30 +#define SERDES_25G_LANE_LEQ_REFCLK_EQ_HFG_SQL_CTRL5_EQ_HFG_SQL_LASTWR_AVG_SHIFT 4 + +#define SERDES_25G_LANE_LEQ_REFCLK_EQ_HFG_SQL_CTRL5_EQ_HFG_SQL_LASTWR_FLOOR_MASK 0x40 +#define SERDES_25G_LANE_LEQ_REFCLK_EQ_HFG_SQL_CTRL5_EQ_HFG_SQL_LASTWR_FLOOR_SHIFT 6 + +#define SERDES_25G_LANE_LEQ_REFCLK_EQ_HFG_SQL_CTRL6_EQ_HFG_SQL_LASTWR_ADJUST_MASK 0x1F +#define SERDES_25G_LANE_LEQ_REFCLK_EQ_HFG_SQL_CTRL6_EQ_HFG_SQL_LASTWR_ADJUST_SHIFT 0 + +#define SERDES_25G_LANE_LEQ_REFCLK_EQ_SQL_CTRL0_EQ_SQL_MAP_OPTION_RATE0_MASK 0x01 +#define SERDES_25G_LANE_LEQ_REFCLK_EQ_SQL_CTRL0_EQ_SQL_MAP_OPTION_RATE0_SHIFT 0 + +#define SERDES_25G_LANE_LEQ_REFCLK_EQ_SQL_CTRL0_EQ_SQL_MAP_OPTION_RATE1_MASK 0x02 +#define SERDES_25G_LANE_LEQ_REFCLK_EQ_SQL_CTRL0_EQ_SQL_MAP_OPTION_RATE1_SHIFT 1 + +#define SERDES_25G_LANE_LEQ_REFCLK_EQ_SQL_CTRL0_EQ_SQL_MAP_OPTION_RATE2_MASK 0x04 +#define SERDES_25G_LANE_LEQ_REFCLK_EQ_SQL_CTRL0_EQ_SQL_MAP_OPTION_RATE2_SHIFT 2 + +#define SERDES_25G_LANE_LEQ_REFCLK_EQ_SQL_CTRL0_EQ_SQL_MAP_OPTION_RATE3_MASK 0x08 +#define SERDES_25G_LANE_LEQ_REFCLK_EQ_SQL_CTRL0_EQ_SQL_MAP_OPTION_RATE3_SHIFT 3 + +#define SERDES_25G_LANE_LEQ_REFCLK_EQ_SQL_CTRL1_EQ_SQL_MAP0_RATE0_MASK 0x07 +#define SERDES_25G_LANE_LEQ_REFCLK_EQ_SQL_CTRL1_EQ_SQL_MAP0_RATE0_SHIFT 0 + +#define SERDES_25G_LANE_LEQ_REFCLK_EQ_SQL_CTRL1_EQ_SQL_MAP1_RATE0_MASK 0x70 +#define SERDES_25G_LANE_LEQ_REFCLK_EQ_SQL_CTRL1_EQ_SQL_MAP1_RATE0_SHIFT 4 + +#define SERDES_25G_LANE_LEQ_REFCLK_EQ_SQL_CTRL2_EQ_SQL_MAP2_RATE0_MASK 0x07 +#define SERDES_25G_LANE_LEQ_REFCLK_EQ_SQL_CTRL2_EQ_SQL_MAP2_RATE0_SHIFT 0 + +#define SERDES_25G_LANE_LEQ_REFCLK_EQ_SQL_CTRL2_EQ_SQL_MAP3_RATE0_MASK 0x70 +#define SERDES_25G_LANE_LEQ_REFCLK_EQ_SQL_CTRL2_EQ_SQL_MAP3_RATE0_SHIFT 4 + +#define SERDES_25G_LANE_LEQ_REFCLK_EQ_SQL_CTRL3_EQ_SQL_MAP4_RATE0_MASK 0x07 +#define SERDES_25G_LANE_LEQ_REFCLK_EQ_SQL_CTRL3_EQ_SQL_MAP4_RATE0_SHIFT 0 + +#define SERDES_25G_LANE_LEQ_REFCLK_EQ_SQL_CTRL3_EQ_SQL_MAP5_RATE0_MASK 0x70 +#define SERDES_25G_LANE_LEQ_REFCLK_EQ_SQL_CTRL3_EQ_SQL_MAP5_RATE0_SHIFT 4 + +#define SERDES_25G_LANE_LEQ_REFCLK_EQ_SQL_CTRL4_EQ_SQL_MAP6_RATE0_MASK 0x07 +#define SERDES_25G_LANE_LEQ_REFCLK_EQ_SQL_CTRL4_EQ_SQL_MAP6_RATE0_SHIFT 0 + +#define SERDES_25G_LANE_LEQ_REFCLK_EQ_SQL_CTRL4_EQ_SQL_MAP7_RATE0_MASK 0x70 +#define SERDES_25G_LANE_LEQ_REFCLK_EQ_SQL_CTRL4_EQ_SQL_MAP7_RATE0_SHIFT 4 + +#define SERDES_25G_LANE_LEQ_REFCLK_EQ_SQL_CTRL5_EQ_SQL_MAP8_RATE0_MASK 0x07 +#define SERDES_25G_LANE_LEQ_REFCLK_EQ_SQL_CTRL5_EQ_SQL_MAP8_RATE0_SHIFT 0 + +#define SERDES_25G_LANE_LEQ_REFCLK_EQ_SQL_CTRL5_EQ_SQL_MAP9_RATE0_MASK 0x70 +#define SERDES_25G_LANE_LEQ_REFCLK_EQ_SQL_CTRL5_EQ_SQL_MAP9_RATE0_SHIFT 4 + +#define SERDES_25G_LANE_LEQ_REFCLK_EQ_SQL_CTRL6_EQ_SQL_MAP10_RATE0_MASK 0x07 +#define SERDES_25G_LANE_LEQ_REFCLK_EQ_SQL_CTRL6_EQ_SQL_MAP10_RATE0_SHIFT 0 + +#define SERDES_25G_LANE_LEQ_REFCLK_EQ_SQL_CTRL6_EQ_SQL_MAP11_RATE0_MASK 0x70 +#define SERDES_25G_LANE_LEQ_REFCLK_EQ_SQL_CTRL6_EQ_SQL_MAP11_RATE0_SHIFT 4 + +#define SERDES_25G_LANE_LEQ_REFCLK_EQ_SQL_CTRL7_EQ_SQL_MAP0_RATE1_MASK 0x07 +#define SERDES_25G_LANE_LEQ_REFCLK_EQ_SQL_CTRL7_EQ_SQL_MAP0_RATE1_SHIFT 0 + +#define SERDES_25G_LANE_LEQ_REFCLK_EQ_SQL_CTRL7_EQ_SQL_MAP1_RATE1_MASK 0x70 +#define SERDES_25G_LANE_LEQ_REFCLK_EQ_SQL_CTRL7_EQ_SQL_MAP1_RATE1_SHIFT 4 + +#define SERDES_25G_LANE_LEQ_REFCLK_EQ_SQL_CTRL8_EQ_SQL_MAP2_RATE1_MASK 0x07 +#define SERDES_25G_LANE_LEQ_REFCLK_EQ_SQL_CTRL8_EQ_SQL_MAP2_RATE1_SHIFT 0 + +#define SERDES_25G_LANE_LEQ_REFCLK_EQ_SQL_CTRL8_EQ_SQL_MAP3_RATE1_MASK 0x70 +#define SERDES_25G_LANE_LEQ_REFCLK_EQ_SQL_CTRL8_EQ_SQL_MAP3_RATE1_SHIFT 4 + +#define SERDES_25G_LANE_LEQ_REFCLK_EQ_SQL_CTRL9_EQ_SQL_MAP4_RATE1_MASK 0x07 +#define SERDES_25G_LANE_LEQ_REFCLK_EQ_SQL_CTRL9_EQ_SQL_MAP4_RATE1_SHIFT 0 + +#define SERDES_25G_LANE_LEQ_REFCLK_EQ_SQL_CTRL9_EQ_SQL_MAP5_RATE1_MASK 0x70 +#define SERDES_25G_LANE_LEQ_REFCLK_EQ_SQL_CTRL9_EQ_SQL_MAP5_RATE1_SHIFT 4 + +#define SERDES_25G_LANE_LEQ_REFCLK_EQ_SQL_CTRL10_EQ_SQL_MAP6_RATE1_MASK 0x07 +#define SERDES_25G_LANE_LEQ_REFCLK_EQ_SQL_CTRL10_EQ_SQL_MAP6_RATE1_SHIFT 0 + +#define SERDES_25G_LANE_LEQ_REFCLK_EQ_SQL_CTRL10_EQ_SQL_MAP7_RATE1_MASK 0x70 +#define SERDES_25G_LANE_LEQ_REFCLK_EQ_SQL_CTRL10_EQ_SQL_MAP7_RATE1_SHIFT 4 + +#define SERDES_25G_LANE_LEQ_REFCLK_EQ_SQL_CTRL11_EQ_SQL_MAP8_RATE1_MASK 0x07 +#define SERDES_25G_LANE_LEQ_REFCLK_EQ_SQL_CTRL11_EQ_SQL_MAP8_RATE1_SHIFT 0 + +#define SERDES_25G_LANE_LEQ_REFCLK_EQ_SQL_CTRL11_EQ_SQL_MAP9_RATE1_MASK 0x70 +#define SERDES_25G_LANE_LEQ_REFCLK_EQ_SQL_CTRL11_EQ_SQL_MAP9_RATE1_SHIFT 4 + +#define SERDES_25G_LANE_LEQ_REFCLK_EQ_SQL_CTRL12_EQ_SQL_MAP10_RATE1_MASK 0x07 +#define SERDES_25G_LANE_LEQ_REFCLK_EQ_SQL_CTRL12_EQ_SQL_MAP10_RATE1_SHIFT 0 + +#define SERDES_25G_LANE_LEQ_REFCLK_EQ_SQL_CTRL12_EQ_SQL_MAP11_RATE1_MASK 0x70 +#define SERDES_25G_LANE_LEQ_REFCLK_EQ_SQL_CTRL12_EQ_SQL_MAP11_RATE1_SHIFT 4 + +#define SERDES_25G_LANE_LEQ_REFCLK_EQ_SQL_CTRL13_EQ_SQL_MAP0_RATE2_MASK 0x07 +#define SERDES_25G_LANE_LEQ_REFCLK_EQ_SQL_CTRL13_EQ_SQL_MAP0_RATE2_SHIFT 0 + +#define SERDES_25G_LANE_LEQ_REFCLK_EQ_SQL_CTRL13_EQ_SQL_MAP1_RATE2_MASK 0x70 +#define SERDES_25G_LANE_LEQ_REFCLK_EQ_SQL_CTRL13_EQ_SQL_MAP1_RATE2_SHIFT 4 + +#define SERDES_25G_LANE_LEQ_REFCLK_EQ_SQL_CTRL14_EQ_SQL_MAP2_RATE2_MASK 0x07 +#define SERDES_25G_LANE_LEQ_REFCLK_EQ_SQL_CTRL14_EQ_SQL_MAP2_RATE2_SHIFT 0 + +#define SERDES_25G_LANE_LEQ_REFCLK_EQ_SQL_CTRL14_EQ_SQL_MAP3_RATE2_MASK 0x70 +#define SERDES_25G_LANE_LEQ_REFCLK_EQ_SQL_CTRL14_EQ_SQL_MAP3_RATE2_SHIFT 4 + +#define SERDES_25G_LANE_LEQ_REFCLK_EQ_SQL_CTRL15_EQ_SQL_MAP4_RATE2_MASK 0x07 +#define SERDES_25G_LANE_LEQ_REFCLK_EQ_SQL_CTRL15_EQ_SQL_MAP4_RATE2_SHIFT 0 + +#define SERDES_25G_LANE_LEQ_REFCLK_EQ_SQL_CTRL15_EQ_SQL_MAP5_RATE2_MASK 0x70 +#define SERDES_25G_LANE_LEQ_REFCLK_EQ_SQL_CTRL15_EQ_SQL_MAP5_RATE2_SHIFT 4 + +#define SERDES_25G_LANE_LEQ_REFCLK_EQ_SQL_CTRL16_EQ_SQL_MAP6_RATE2_MASK 0x07 +#define SERDES_25G_LANE_LEQ_REFCLK_EQ_SQL_CTRL16_EQ_SQL_MAP6_RATE2_SHIFT 0 + +#define SERDES_25G_LANE_LEQ_REFCLK_EQ_SQL_CTRL16_EQ_SQL_MAP7_RATE2_MASK 0x70 +#define SERDES_25G_LANE_LEQ_REFCLK_EQ_SQL_CTRL16_EQ_SQL_MAP7_RATE2_SHIFT 4 + +#define SERDES_25G_LANE_LEQ_REFCLK_EQ_SQL_CTRL17_EQ_SQL_MAP8_RATE2_MASK 0x07 +#define SERDES_25G_LANE_LEQ_REFCLK_EQ_SQL_CTRL17_EQ_SQL_MAP8_RATE2_SHIFT 0 + +#define SERDES_25G_LANE_LEQ_REFCLK_EQ_SQL_CTRL17_EQ_SQL_MAP9_RATE2_MASK 0x70 +#define SERDES_25G_LANE_LEQ_REFCLK_EQ_SQL_CTRL17_EQ_SQL_MAP9_RATE2_SHIFT 4 + +#define SERDES_25G_LANE_LEQ_REFCLK_EQ_SQL_CTRL18_EQ_SQL_MAP10_RATE2_MASK 0x07 +#define SERDES_25G_LANE_LEQ_REFCLK_EQ_SQL_CTRL18_EQ_SQL_MAP10_RATE2_SHIFT 0 + +#define SERDES_25G_LANE_LEQ_REFCLK_EQ_SQL_CTRL18_EQ_SQL_MAP11_RATE2_MASK 0x70 +#define SERDES_25G_LANE_LEQ_REFCLK_EQ_SQL_CTRL18_EQ_SQL_MAP11_RATE2_SHIFT 4 + +#define SERDES_25G_LANE_LEQ_REFCLK_EQ_SQL_CTRL19_EQ_SQL_MAP0_RATE3_MASK 0x07 +#define SERDES_25G_LANE_LEQ_REFCLK_EQ_SQL_CTRL19_EQ_SQL_MAP0_RATE3_SHIFT 0 + +#define SERDES_25G_LANE_LEQ_REFCLK_EQ_SQL_CTRL19_EQ_SQL_MAP1_RATE3_MASK 0x70 +#define SERDES_25G_LANE_LEQ_REFCLK_EQ_SQL_CTRL19_EQ_SQL_MAP1_RATE3_SHIFT 4 + +#define SERDES_25G_LANE_LEQ_REFCLK_EQ_SQL_CTRL20_EQ_SQL_MAP2_RATE3_MASK 0x07 +#define SERDES_25G_LANE_LEQ_REFCLK_EQ_SQL_CTRL20_EQ_SQL_MAP2_RATE3_SHIFT 0 + +#define SERDES_25G_LANE_LEQ_REFCLK_EQ_SQL_CTRL20_EQ_SQL_MAP3_RATE3_MASK 0x70 +#define SERDES_25G_LANE_LEQ_REFCLK_EQ_SQL_CTRL20_EQ_SQL_MAP3_RATE3_SHIFT 4 + +#define SERDES_25G_LANE_LEQ_REFCLK_EQ_SQL_CTRL21_EQ_SQL_MAP4_RATE3_MASK 0x07 +#define SERDES_25G_LANE_LEQ_REFCLK_EQ_SQL_CTRL21_EQ_SQL_MAP4_RATE3_SHIFT 0 + +#define SERDES_25G_LANE_LEQ_REFCLK_EQ_SQL_CTRL21_EQ_SQL_MAP5_RATE3_MASK 0x70 +#define SERDES_25G_LANE_LEQ_REFCLK_EQ_SQL_CTRL21_EQ_SQL_MAP5_RATE3_SHIFT 4 + +#define SERDES_25G_LANE_LEQ_REFCLK_EQ_SQL_CTRL22_EQ_SQL_MAP6_RATE3_MASK 0x07 +#define SERDES_25G_LANE_LEQ_REFCLK_EQ_SQL_CTRL22_EQ_SQL_MAP6_RATE3_SHIFT 0 + +#define SERDES_25G_LANE_LEQ_REFCLK_EQ_SQL_CTRL22_EQ_SQL_MAP7_RATE3_MASK 0x70 +#define SERDES_25G_LANE_LEQ_REFCLK_EQ_SQL_CTRL22_EQ_SQL_MAP7_RATE3_SHIFT 4 + +#define SERDES_25G_LANE_LEQ_REFCLK_EQ_SQL_CTRL23_EQ_SQL_MAP8_RATE3_MASK 0x07 +#define SERDES_25G_LANE_LEQ_REFCLK_EQ_SQL_CTRL23_EQ_SQL_MAP8_RATE3_SHIFT 0 + +#define SERDES_25G_LANE_LEQ_REFCLK_EQ_SQL_CTRL23_EQ_SQL_MAP9_RATE3_MASK 0x70 +#define SERDES_25G_LANE_LEQ_REFCLK_EQ_SQL_CTRL23_EQ_SQL_MAP9_RATE3_SHIFT 4 + +#define SERDES_25G_LANE_LEQ_REFCLK_EQ_SQL_CTRL24_EQ_SQL_MAP10_RATE3_MASK 0x07 +#define SERDES_25G_LANE_LEQ_REFCLK_EQ_SQL_CTRL24_EQ_SQL_MAP10_RATE3_SHIFT 0 + +#define SERDES_25G_LANE_LEQ_REFCLK_EQ_SQL_CTRL24_EQ_SQL_MAP11_RATE3_MASK 0x70 +#define SERDES_25G_LANE_LEQ_REFCLK_EQ_SQL_CTRL24_EQ_SQL_MAP11_RATE3_SHIFT 4 + +#define SERDES_25G_LANE_LEQ_REFCLK_GN_APG_CTRL0_GN_APG_START_MASK 0x03 +#define SERDES_25G_LANE_LEQ_REFCLK_GN_APG_CTRL0_GN_APG_START_SHIFT 0 + +#define SERDES_25G_LANE_LEQ_REFCLK_GN_APG_CTRL1_GN_APG_VALUE_MAX_MASK 0x03 +#define SERDES_25G_LANE_LEQ_REFCLK_GN_APG_CTRL1_GN_APG_VALUE_MAX_SHIFT 0 + +#define SERDES_25G_LANE_LEQ_REFCLK_GN_APG_CTRL1_GN_APG_VALUE_MIN_MASK 0x0C +#define SERDES_25G_LANE_LEQ_REFCLK_GN_APG_CTRL1_GN_APG_VALUE_MIN_SHIFT 2 + +#define SERDES_25G_LANE_LEQ_REFCLK_GN_APG_CTRL2_GN_APG_WRWAIT_TIME_MASK 0x0F +#define SERDES_25G_LANE_LEQ_REFCLK_GN_APG_CTRL2_GN_APG_WRWAIT_TIME_SHIFT 0 + +#define SERDES_25G_LANE_LEQ_REFCLK_GN_APG_CTRL2_GN_APG_MEASURE_TIMEOUT_DISABLE_MASK 0x80 +#define SERDES_25G_LANE_LEQ_REFCLK_GN_APG_CTRL2_GN_APG_MEASURE_TIMEOUT_DISABLE_SHIFT 7 + +#define SERDES_25G_LANE_LEQ_REFCLK_GN_APG_CTRL3_GN_APG_STEP_BY1_MASK 0x01 +#define SERDES_25G_LANE_LEQ_REFCLK_GN_APG_CTRL3_GN_APG_STEP_BY1_SHIFT 0 + +#define SERDES_25G_LANE_LEQ_REFCLK_GN_APG_CTRL3_GN_APG_ERROR_SIGN_MASK 0x02 +#define SERDES_25G_LANE_LEQ_REFCLK_GN_APG_CTRL3_GN_APG_ERROR_SIGN_SHIFT 1 + +#define SERDES_25G_LANE_LEQ_REFCLK_GN_APG_CTRL3_GN_APG_STEP_SIZE_MASK 0x0C +#define SERDES_25G_LANE_LEQ_REFCLK_GN_APG_CTRL3_GN_APG_STEP_SIZE_SHIFT 2 + +#define SERDES_25G_LANE_LEQ_REFCLK_GN_APG_CTRL4_GN_APG_BOUNCE_LIMIT_MASK 0x0F +#define SERDES_25G_LANE_LEQ_REFCLK_GN_APG_CTRL4_GN_APG_BOUNCE_LIMIT_SHIFT 0 + +#define SERDES_25G_LANE_LEQ_REFCLK_GN_APG_CTRL4_GN_APG_LASTWR_AVG_MASK 0x30 +#define SERDES_25G_LANE_LEQ_REFCLK_GN_APG_CTRL4_GN_APG_LASTWR_AVG_SHIFT 4 + +#define SERDES_25G_LANE_LEQ_REFCLK_GN_APG_CTRL4_GN_APG_LASTWR_FLOOR_MASK 0x40 +#define SERDES_25G_LANE_LEQ_REFCLK_GN_APG_CTRL4_GN_APG_LASTWR_FLOOR_SHIFT 6 + +#define SERDES_25G_LANE_LEQ_REFCLK_GN_APG_CTRL5_GN_APG_LASTWR_ADJUST_MASK 0x03 +#define SERDES_25G_LANE_LEQ_REFCLK_GN_APG_CTRL5_GN_APG_LASTWR_ADJUST_SHIFT 0 + +#define SERDES_25G_LANE_LEQ_REFCLK_GN_APG_CTRL6_GN_APG_CCL_DELTA_MASK 0x03 +#define SERDES_25G_LANE_LEQ_REFCLK_GN_APG_CTRL6_GN_APG_CCL_DELTA_SHIFT 0 + +#define SERDES_25G_LANE_LEQ_REFCLK_GN_APG_CTRL6_GN_APG_CCL_MAX_MASK 0x0C +#define SERDES_25G_LANE_LEQ_REFCLK_GN_APG_CTRL6_GN_APG_CCL_MAX_SHIFT 2 + +#define SERDES_25G_LANE_LEQ_REFCLK_EQ_LFG_CTRL0_EQ_LFG_START_MASK 0x1F +#define SERDES_25G_LANE_LEQ_REFCLK_EQ_LFG_CTRL0_EQ_LFG_START_SHIFT 0 + +#define SERDES_25G_LANE_LEQ_REFCLK_EQ_LFG_CTRL1_EQ_LFG_VALUE_MAX_MASK 0x1F +#define SERDES_25G_LANE_LEQ_REFCLK_EQ_LFG_CTRL1_EQ_LFG_VALUE_MAX_SHIFT 0 + +#define SERDES_25G_LANE_LEQ_REFCLK_EQ_LFG_CTRL2_EQ_LFG_VALUE_MIN_MASK 0x1F +#define SERDES_25G_LANE_LEQ_REFCLK_EQ_LFG_CTRL2_EQ_LFG_VALUE_MIN_SHIFT 0 + +#define SERDES_25G_LANE_LEQ_REFCLK_EQ_LFG_CTRL3_EQ_LFG_WRWAIT_TIME_MASK 0x0F +#define SERDES_25G_LANE_LEQ_REFCLK_EQ_LFG_CTRL3_EQ_LFG_WRWAIT_TIME_SHIFT 0 + +#define SERDES_25G_LANE_LEQ_REFCLK_EQ_LFG_CTRL3_EQ_LFG_MEASURE_TIMEOUT_DISABLE_MASK 0x80 +#define SERDES_25G_LANE_LEQ_REFCLK_EQ_LFG_CTRL3_EQ_LFG_MEASURE_TIMEOUT_DISABLE_SHIFT 7 + +#define SERDES_25G_LANE_LEQ_REFCLK_EQ_LFG_CTRL4_EQ_LFG_STEP_BY1_MASK 0x01 +#define SERDES_25G_LANE_LEQ_REFCLK_EQ_LFG_CTRL4_EQ_LFG_STEP_BY1_SHIFT 0 + +#define SERDES_25G_LANE_LEQ_REFCLK_EQ_LFG_CTRL4_EQ_LFG_ERROR_SIGN_MASK 0x02 +#define SERDES_25G_LANE_LEQ_REFCLK_EQ_LFG_CTRL4_EQ_LFG_ERROR_SIGN_SHIFT 1 + +#define SERDES_25G_LANE_LEQ_REFCLK_EQ_LFG_CTRL4_EQ_LFG_STEP_SIZE_MASK 0x1C +#define SERDES_25G_LANE_LEQ_REFCLK_EQ_LFG_CTRL4_EQ_LFG_STEP_SIZE_SHIFT 2 + +#define SERDES_25G_LANE_LEQ_REFCLK_EQ_LFG_CTRL5_EQ_LFG_BOUNCE_LIMIT_MASK 0x0F +#define SERDES_25G_LANE_LEQ_REFCLK_EQ_LFG_CTRL5_EQ_LFG_BOUNCE_LIMIT_SHIFT 0 + +#define SERDES_25G_LANE_LEQ_REFCLK_EQ_LFG_CTRL5_EQ_LFG_LASTWR_AVG_MASK 0x30 +#define SERDES_25G_LANE_LEQ_REFCLK_EQ_LFG_CTRL5_EQ_LFG_LASTWR_AVG_SHIFT 4 + +#define SERDES_25G_LANE_LEQ_REFCLK_EQ_LFG_CTRL5_EQ_LFG_LASTWR_FLOOR_MASK 0x40 +#define SERDES_25G_LANE_LEQ_REFCLK_EQ_LFG_CTRL5_EQ_LFG_LASTWR_FLOOR_SHIFT 6 + +#define SERDES_25G_LANE_LEQ_REFCLK_EQ_LFG_CTRL6_EQ_LFG_LASTWR_ADJUST_MASK 0x1F +#define SERDES_25G_LANE_LEQ_REFCLK_EQ_LFG_CTRL6_EQ_LFG_LASTWR_ADJUST_SHIFT 0 + +#define SERDES_25G_LANE_LEQ_REFCLK_EQ_LFG_CTRL7_EQ_LFG_CCL_DELTA_MASK 0x1F +#define SERDES_25G_LANE_LEQ_REFCLK_EQ_LFG_CTRL7_EQ_LFG_CCL_DELTA_SHIFT 0 + +#define SERDES_25G_LANE_LEQ_REFCLK_EQ_LFG_CTRL8_EQ_LFG_CCL_MAX_MASK 0x1F +#define SERDES_25G_LANE_LEQ_REFCLK_EQ_LFG_CTRL8_EQ_LFG_CCL_MAX_SHIFT 0 + +#define SERDES_25G_LANE_LEQ_REFCLK_GNEQ_CCL_LFG_CTRL0_GNEQ_CCL_LFG_START_MASK 0x1F +#define SERDES_25G_LANE_LEQ_REFCLK_GNEQ_CCL_LFG_CTRL0_GNEQ_CCL_LFG_START_SHIFT 0 + +#define SERDES_25G_LANE_LEQ_REFCLK_GNEQ_CCL_LFG_CTRL1_GNEQ_CCL_LFG_VALUE_MAX_MASK 0x1F +#define SERDES_25G_LANE_LEQ_REFCLK_GNEQ_CCL_LFG_CTRL1_GNEQ_CCL_LFG_VALUE_MAX_SHIFT 0 + +#define SERDES_25G_LANE_LEQ_REFCLK_GNEQ_CCL_LFG_CTRL2_GNEQ_CCL_LFG_VALUE_MIN_MASK 0x1F +#define SERDES_25G_LANE_LEQ_REFCLK_GNEQ_CCL_LFG_CTRL2_GNEQ_CCL_LFG_VALUE_MIN_SHIFT 0 + +#define SERDES_25G_LANE_LEQ_REFCLK_GNEQ_CCL_LFG_CTRL3_GNEQ_CCL_LFG_WRWAIT_TIME_MASK 0x0F +#define SERDES_25G_LANE_LEQ_REFCLK_GNEQ_CCL_LFG_CTRL3_GNEQ_CCL_LFG_WRWAIT_TIME_SHIFT 0 + +#define SERDES_25G_LANE_LEQ_REFCLK_GNEQ_CCL_LFG_CTRL3_GNEQ_CCL_LFG_MEASURE_TIMEOUT_DISABLE_MASK 0x80 +#define SERDES_25G_LANE_LEQ_REFCLK_GNEQ_CCL_LFG_CTRL3_GNEQ_CCL_LFG_MEASURE_TIMEOUT_DISABLE_SHIFT 7 + +#define SERDES_25G_LANE_LEQ_REFCLK_GNEQ_CCL_LFG_CTRL4_GNEQ_CCL_LFG_STEP_BY1_MASK 0x01 +#define SERDES_25G_LANE_LEQ_REFCLK_GNEQ_CCL_LFG_CTRL4_GNEQ_CCL_LFG_STEP_BY1_SHIFT 0 + +#define SERDES_25G_LANE_LEQ_REFCLK_GNEQ_CCL_LFG_CTRL4_GNEQ_CCL_LFG_ERROR_SIGN_MASK 0x02 +#define SERDES_25G_LANE_LEQ_REFCLK_GNEQ_CCL_LFG_CTRL4_GNEQ_CCL_LFG_ERROR_SIGN_SHIFT 1 + +#define SERDES_25G_LANE_LEQ_REFCLK_GNEQ_CCL_LFG_CTRL4_GNEQ_CCL_LFG_STEP_SIZE_MASK 0x1C +#define SERDES_25G_LANE_LEQ_REFCLK_GNEQ_CCL_LFG_CTRL4_GNEQ_CCL_LFG_STEP_SIZE_SHIFT 2 + +#define SERDES_25G_LANE_LEQ_REFCLK_GNEQ_CCL_LFG_CTRL5_GNEQ_CCL_LFG_BOUNCE_LIMIT_MASK 0x0F +#define SERDES_25G_LANE_LEQ_REFCLK_GNEQ_CCL_LFG_CTRL5_GNEQ_CCL_LFG_BOUNCE_LIMIT_SHIFT 0 + +#define SERDES_25G_LANE_LEQ_REFCLK_GNEQ_CCL_LFG_CTRL5_GNEQ_CCL_LFG_LASTWR_AVG_MASK 0x30 +#define SERDES_25G_LANE_LEQ_REFCLK_GNEQ_CCL_LFG_CTRL5_GNEQ_CCL_LFG_LASTWR_AVG_SHIFT 4 + +#define SERDES_25G_LANE_LEQ_REFCLK_GNEQ_CCL_LFG_CTRL5_GNEQ_CCL_LFG_LASTWR_FLOOR_MASK 0x40 +#define SERDES_25G_LANE_LEQ_REFCLK_GNEQ_CCL_LFG_CTRL5_GNEQ_CCL_LFG_LASTWR_FLOOR_SHIFT 6 + +#define SERDES_25G_LANE_LEQ_REFCLK_GNEQ_CCL_LFG_CTRL6_GNEQ_CCL_LFG_LASTWR_ADJUST_MASK 0x1F +#define SERDES_25G_LANE_LEQ_REFCLK_GNEQ_CCL_LFG_CTRL6_GNEQ_CCL_LFG_LASTWR_ADJUST_SHIFT 0 + +#define SERDES_25G_LANE_LEQ_REFCLK_EQ_MB_CTRL0_EQ_MB_WRWAIT_TIME_MASK 0x0F +#define SERDES_25G_LANE_LEQ_REFCLK_EQ_MB_CTRL0_EQ_MB_WRWAIT_TIME_SHIFT 0 + +#define SERDES_25G_LANE_LEQ_REFCLK_EQ_MB_CTRL0_EQ_MB_STEP_BY1_MASK 0x10 +#define SERDES_25G_LANE_LEQ_REFCLK_EQ_MB_CTRL0_EQ_MB_STEP_BY1_SHIFT 4 + +#define SERDES_25G_LANE_LEQ_REFCLK_EQ_MB_CTRL1_EQ_MBF_START_MASK 0x0F +#define SERDES_25G_LANE_LEQ_REFCLK_EQ_MB_CTRL1_EQ_MBF_START_SHIFT 0 + +#define SERDES_25G_LANE_LEQ_REFCLK_EQ_MB_CTRL1_EQ_MBG_START_MASK 0xF0 +#define SERDES_25G_LANE_LEQ_REFCLK_EQ_MB_CTRL1_EQ_MBG_START_SHIFT 4 + +#define SERDES_25G_LANE_LEQ_REFCLK_VSCAN_CTRL0_VSCAN_VALUE_MAX_MASK 0xFF +#define SERDES_25G_LANE_LEQ_REFCLK_VSCAN_CTRL0_VSCAN_VALUE_MAX_SHIFT 0 + +#define SERDES_25G_LANE_LEQ_REFCLK_VSCAN_CTRL1_VSCAN_VALUE_MIN_MASK 0xFF +#define SERDES_25G_LANE_LEQ_REFCLK_VSCAN_CTRL1_VSCAN_VALUE_MIN_SHIFT 0 + +#define SERDES_25G_LANE_LEQ_REFCLK_VSCAN_CTRL2_VSCAN_STEP_BY1_MASK 0x01 +#define SERDES_25G_LANE_LEQ_REFCLK_VSCAN_CTRL2_VSCAN_STEP_BY1_SHIFT 0 + +#define SERDES_25G_LANE_LEQ_REFCLK_VSCAN_CTRL2_VSCAN_ERROR_SIGN_MASK 0x02 +#define SERDES_25G_LANE_LEQ_REFCLK_VSCAN_CTRL2_VSCAN_ERROR_SIGN_SHIFT 1 + +#define SERDES_25G_LANE_LEQ_REFCLK_VSCAN_CTRL2_VSCAN_STEP_SIZE_MASK 0x3C +#define SERDES_25G_LANE_LEQ_REFCLK_VSCAN_CTRL2_VSCAN_STEP_SIZE_SHIFT 2 + +#define SERDES_25G_LANE_LEQ_REFCLK_VSCAN_CTRL3_VSCAN_BOUNCE_LIMIT_MASK 0x0F +#define SERDES_25G_LANE_LEQ_REFCLK_VSCAN_CTRL3_VSCAN_BOUNCE_LIMIT_SHIFT 0 + +#define SERDES_25G_LANE_LEQ_REFCLK_VSCAN_CTRL3_VSCAN_LASTWR_AVG_MASK 0x30 +#define SERDES_25G_LANE_LEQ_REFCLK_VSCAN_CTRL3_VSCAN_LASTWR_AVG_SHIFT 4 + +#define SERDES_25G_LANE_LEQ_REFCLK_VSCAN_CTRL3_VSCAN_LASTWR_FLOOR_MASK 0x40 +#define SERDES_25G_LANE_LEQ_REFCLK_VSCAN_CTRL3_VSCAN_LASTWR_FLOOR_SHIFT 6 + +#define SERDES_25G_LANE_LEQ_REFCLK_HSCAN_CTRL0_HSCAN_VALUE_MAX_MASK 0xFF +#define SERDES_25G_LANE_LEQ_REFCLK_HSCAN_CTRL0_HSCAN_VALUE_MAX_SHIFT 0 + +#define SERDES_25G_LANE_LEQ_REFCLK_HSCAN_CTRL1_HSCAN_VALUE_MIN_MASK 0xFF +#define SERDES_25G_LANE_LEQ_REFCLK_HSCAN_CTRL1_HSCAN_VALUE_MIN_SHIFT 0 + +#define SERDES_25G_LANE_LEQ_REFCLK_HSCAN_CTRL2_HSCAN_STEP_BY1_MASK 0x01 +#define SERDES_25G_LANE_LEQ_REFCLK_HSCAN_CTRL2_HSCAN_STEP_BY1_SHIFT 0 + +#define SERDES_25G_LANE_LEQ_REFCLK_HSCAN_CTRL2_HSCAN_ERROR_SIGN_MASK 0x02 +#define SERDES_25G_LANE_LEQ_REFCLK_HSCAN_CTRL2_HSCAN_ERROR_SIGN_SHIFT 1 + +#define SERDES_25G_LANE_LEQ_REFCLK_HSCAN_CTRL2_HSCAN_STEP_SIZE_MASK 0x3C +#define SERDES_25G_LANE_LEQ_REFCLK_HSCAN_CTRL2_HSCAN_STEP_SIZE_SHIFT 2 + +#define SERDES_25G_LANE_LEQ_REFCLK_HSCAN_CTRL3_HSCAN_BOUNCE_LIMIT_MASK 0x0F +#define SERDES_25G_LANE_LEQ_REFCLK_HSCAN_CTRL3_HSCAN_BOUNCE_LIMIT_SHIFT 0 + +#define SERDES_25G_LANE_LEQ_REFCLK_HSCAN_CTRL3_HSCAN_LASTWR_AVG_MASK 0x30 +#define SERDES_25G_LANE_LEQ_REFCLK_HSCAN_CTRL3_HSCAN_LASTWR_AVG_SHIFT 4 + +#define SERDES_25G_LANE_LEQ_REFCLK_HSCAN_CTRL3_HSCAN_LASTWR_FLOOR_MASK 0x40 +#define SERDES_25G_LANE_LEQ_REFCLK_HSCAN_CTRL3_HSCAN_LASTWR_FLOOR_SHIFT 6 + +#define SERDES_25G_LANE_LEQ_REFCLK_REF_THRESHOLD0_GN_APG_REF_N_MASK 0xFF +#define SERDES_25G_LANE_LEQ_REFCLK_REF_THRESHOLD0_GN_APG_REF_N_SHIFT 0 + +#define SERDES_25G_LANE_LEQ_REFCLK_REF_THRESHOLD1_GN_APG_REF_P_MASK 0xFF +#define SERDES_25G_LANE_LEQ_REFCLK_REF_THRESHOLD1_GN_APG_REF_P_SHIFT 0 + +#define SERDES_25G_LANE_LEQ_REFCLK_REF_THRESHOLD2_EQ_LFG_REF_N_MASK 0xFF +#define SERDES_25G_LANE_LEQ_REFCLK_REF_THRESHOLD2_EQ_LFG_REF_N_SHIFT 0 + +#define SERDES_25G_LANE_LEQ_REFCLK_REF_THRESHOLD3_EQ_LFG_REF_P_MASK 0xFF +#define SERDES_25G_LANE_LEQ_REFCLK_REF_THRESHOLD3_EQ_LFG_REF_P_SHIFT 0 + +#define SERDES_25G_LANE_LEQ_REFCLK_EYE_PHASE0_EYE_PHASE_7_0_MASK 0xFF +#define SERDES_25G_LANE_LEQ_REFCLK_EYE_PHASE0_EYE_PHASE_7_0_SHIFT 0 + +#define SERDES_25G_LANE_LEQ_REFCLK_EYE_PHASE1_EYE_PHASE_8_MASK 0x01 +#define SERDES_25G_LANE_LEQ_REFCLK_EYE_PHASE1_EYE_PHASE_8_SHIFT 0 + +#define SERDES_25G_LANE_LEQ_REFCLK_EYE_PHASE1_EYE_PHASE_VALID_MASK 0x02 +#define SERDES_25G_LANE_LEQ_REFCLK_EYE_PHASE1_EYE_PHASE_VALID_SHIFT 1 + +#define SERDES_25G_LANE_LEQ_REFCLK_EYEMON_CTRL0_EYE_MONITOR_ODDEYE_MASK 0x01 +#define SERDES_25G_LANE_LEQ_REFCLK_EYEMON_CTRL0_EYE_MONITOR_ODDEYE_SHIFT 0 + +#define SERDES_25G_LANE_LEQ_REFCLK_EYEMON_CTRL0_EYE_MONITOR_PATH1_MASK 0x02 +#define SERDES_25G_LANE_LEQ_REFCLK_EYEMON_CTRL0_EYE_MONITOR_PATH1_SHIFT 1 + +#define SERDES_25G_LANE_LEQ_REFCLK_EYEINTF_CTRL0_EYEINTF_INIT_TIMEOUT_DISABLE_MASK 0x40 +#define SERDES_25G_LANE_LEQ_REFCLK_EYEINTF_CTRL0_EYEINTF_INIT_TIMEOUT_DISABLE_SHIFT 6 + +#define SERDES_25G_LANE_LEQ_REFCLK_LEQ_REFCLK_SPARE0_MASK 0xFF +#define SERDES_25G_LANE_LEQ_REFCLK_LEQ_REFCLK_SPARE0_SHIFT 0 + +#define SERDES_25G_LANE_LEQ_REFCLK_LEQ_REFCLK_SPARE1_MASK 0xFF +#define SERDES_25G_LANE_LEQ_REFCLK_LEQ_REFCLK_SPARE1_SHIFT 0 + +/********************************* DRV_REFCLK *********************************/ +#define SERDES_25G_LANE_DRV_REFCLK_BASE 0x380 + +#define SERDES_25G_LANE_DRV_AFE_PD_CTRL0_ADDR (SERDES_25G_LANE_DRV_REFCLK_BASE + 0x00) +#define SERDES_25G_LANE_DRV_AFE_RST_CTRL0_ADDR (SERDES_25G_LANE_DRV_REFCLK_BASE + 0x01) +#define SERDES_25G_LANE_DRV_AFE_CTRL1_ADDR (SERDES_25G_LANE_DRV_REFCLK_BASE + 0x03) +#define SERDES_25G_LANE_DRV_AFE_CTRL2_ADDR (SERDES_25G_LANE_DRV_REFCLK_BASE + 0x04) +#define SERDES_25G_LANE_DRV_AFE_CTRL3_ADDR (SERDES_25G_LANE_DRV_REFCLK_BASE + 0x05) +#define SERDES_25G_LANE_DRV_AFE_C1_CTRL0_ADDR (SERDES_25G_LANE_DRV_REFCLK_BASE + 0x06) +#define SERDES_25G_LANE_DRV_AFE_CM1_CTRL0_ADDR (SERDES_25G_LANE_DRV_REFCLK_BASE + 0x08) +#define SERDES_25G_LANE_DRV_AFE_ATT_CTRL0_ADDR (SERDES_25G_LANE_DRV_REFCLK_BASE + 0x09) +#define SERDES_25G_LANE_DRV_AFE_CALN_CTRL0_ADDR (SERDES_25G_LANE_DRV_REFCLK_BASE + 0x0A) +#define SERDES_25G_LANE_DRV_AFE_CALN_CTRL1_ADDR (SERDES_25G_LANE_DRV_REFCLK_BASE + 0x0B) +#define SERDES_25G_LANE_DRV_AFE_CALP_CTRL0_ADDR (SERDES_25G_LANE_DRV_REFCLK_BASE + 0x0C) +#define SERDES_25G_LANE_DRV_AFE_CALP_CTRL1_ADDR (SERDES_25G_LANE_DRV_REFCLK_BASE + 0x0D) +#define SERDES_25G_LANE_DRV_TXEQ_CTRL0_ADDR (SERDES_25G_LANE_DRV_REFCLK_BASE + 0x10) +#define SERDES_25G_LANE_DRV_TXEQ_STATUS0_ADDR (SERDES_25G_LANE_DRV_REFCLK_BASE + 0x11) +#define SERDES_25G_LANE_DRV_TXEQ_CTRL1_ADDR (SERDES_25G_LANE_DRV_REFCLK_BASE + 0x12) +#define SERDES_25G_LANE_DRV_TXEQ_CTRL2_ADDR (SERDES_25G_LANE_DRV_REFCLK_BASE + 0x13) +#define SERDES_25G_LANE_DRV_TXEQ_CTRL3_ADDR (SERDES_25G_LANE_DRV_REFCLK_BASE + 0x14) +#define SERDES_25G_LANE_DRV_TXEQ_CTRL4_ADDR (SERDES_25G_LANE_DRV_REFCLK_BASE + 0x15) +#define SERDES_25G_LANE_DRV_TXEQ_CTRL5_ADDR (SERDES_25G_LANE_DRV_REFCLK_BASE + 0x16) +/******************************************************************************* + * masks and shifts + ******************************************************************************/ +#define SERDES_25G_LANE_DRV_AFE_PD_CTRL0_PD_TXDRV_MASK 0x01 +#define SERDES_25G_LANE_DRV_AFE_PD_CTRL0_PD_TXDRV_SHIFT 0 + +#define SERDES_25G_LANE_DRV_AFE_PD_CTRL0_TXDRV_LP_IDLE_MASK 0x02 +#define SERDES_25G_LANE_DRV_AFE_PD_CTRL0_TXDRV_LP_IDLE_SHIFT 1 + +#define SERDES_25G_LANE_DRV_AFE_RST_CTRL0_RST_TXDRV_DIV2_N_MASK 0x01 +#define SERDES_25G_LANE_DRV_AFE_RST_CTRL0_RST_TXDRV_DIV2_N_SHIFT 0 + +#define SERDES_25G_LANE_DRV_AFE_CTRL1_TXDRV_SPARE_MASK 0xFF +#define SERDES_25G_LANE_DRV_AFE_CTRL1_TXDRV_SPARE_SHIFT 0 + +#define SERDES_25G_LANE_DRV_AFE_CTRL2_TXDRV_TOGGLE_EN_MASK 0x01 +#define SERDES_25G_LANE_DRV_AFE_CTRL2_TXDRV_TOGGLE_EN_SHIFT 0 + +#define SERDES_25G_LANE_DRV_AFE_CTRL2_TXDRV_CLK_DELAY_MASK 0x3E +#define SERDES_25G_LANE_DRV_AFE_CTRL2_TXDRV_CLK_DELAY_SHIFT 1 + +#define SERDES_25G_LANE_DRV_AFE_CTRL3_TXDRV_CO_POL_MASK 0x07 +#define SERDES_25G_LANE_DRV_AFE_CTRL3_TXDRV_CO_POL_SHIFT 0 + +#define SERDES_25G_LANE_DRV_AFE_C1_CTRL0_TXDRV_SEL_C1_P5_MASK 0x01 +#define SERDES_25G_LANE_DRV_AFE_C1_CTRL0_TXDRV_SEL_C1_P5_SHIFT 0 + +#define SERDES_25G_LANE_DRV_AFE_C1_CTRL0_TXDRV_SEL_C1_X1_MASK 0x02 +#define SERDES_25G_LANE_DRV_AFE_C1_CTRL0_TXDRV_SEL_C1_X1_SHIFT 1 + +#define SERDES_25G_LANE_DRV_AFE_C1_CTRL0_TXDRV_SEL_C1_X2_MASK 0x1C +#define SERDES_25G_LANE_DRV_AFE_C1_CTRL0_TXDRV_SEL_C1_X2_SHIFT 2 + +#define SERDES_25G_LANE_DRV_AFE_C1_CTRL0_TXDRV_SEL_CXC1_X1_MASK 0x20 +#define SERDES_25G_LANE_DRV_AFE_C1_CTRL0_TXDRV_SEL_CXC1_X1_SHIFT 5 + +#define SERDES_25G_LANE_DRV_AFE_C1_CTRL0_TXDRV_SEL_CXC1_X2_MASK 0xC0 +#define SERDES_25G_LANE_DRV_AFE_C1_CTRL0_TXDRV_SEL_CXC1_X2_SHIFT 6 + +#define SERDES_25G_LANE_DRV_AFE_CM1_CTRL0_TXDRV_SEL_CM1_P5_MASK 0x01 +#define SERDES_25G_LANE_DRV_AFE_CM1_CTRL0_TXDRV_SEL_CM1_P5_SHIFT 0 + +#define SERDES_25G_LANE_DRV_AFE_CM1_CTRL0_TXDRV_SEL_CM1_X1_MASK 0x02 +#define SERDES_25G_LANE_DRV_AFE_CM1_CTRL0_TXDRV_SEL_CM1_X1_SHIFT 1 + +#define SERDES_25G_LANE_DRV_AFE_CM1_CTRL0_TXDRV_SEL_CM1_X2_MASK 0x0C +#define SERDES_25G_LANE_DRV_AFE_CM1_CTRL0_TXDRV_SEL_CM1_X2_SHIFT 2 + +#define SERDES_25G_LANE_DRV_AFE_CM1_CTRL0_TXDRV_SEL_CXCM1_X2_MASK 0x10 +#define SERDES_25G_LANE_DRV_AFE_CM1_CTRL0_TXDRV_SEL_CXCM1_X2_SHIFT 4 + +#define SERDES_25G_LANE_DRV_AFE_ATT_CTRL0_TXDRV_SEL_ATT_X1_MASK 0x07 +#define SERDES_25G_LANE_DRV_AFE_ATT_CTRL0_TXDRV_SEL_ATT_X1_SHIFT 0 + +#define SERDES_25G_LANE_DRV_AFE_ATT_CTRL0_TXDRV_SEL_ATT_X2_MASK 0xF8 +#define SERDES_25G_LANE_DRV_AFE_ATT_CTRL0_TXDRV_SEL_ATT_X2_SHIFT 3 + +#define SERDES_25G_LANE_DRV_AFE_CALN_CTRL0_TXDRV_SEL_CXN_X1_MASK 0x07 +#define SERDES_25G_LANE_DRV_AFE_CALN_CTRL0_TXDRV_SEL_CXN_X1_SHIFT 0 + +#define SERDES_25G_LANE_DRV_AFE_CALN_CTRL0_TXDRV_SEL_FIXEDCXN_X1_MASK 0x18 +#define SERDES_25G_LANE_DRV_AFE_CALN_CTRL0_TXDRV_SEL_FIXEDCXN_X1_SHIFT 3 + +#define SERDES_25G_LANE_DRV_AFE_CALN_CTRL1_TXDRV_SEL_CXN_X2_MASK 0x1F +#define SERDES_25G_LANE_DRV_AFE_CALN_CTRL1_TXDRV_SEL_CXN_X2_SHIFT 0 + +#define SERDES_25G_LANE_DRV_AFE_CALN_CTRL1_TXDRV_SEL_FIXEDCXN_XP5_MASK 0x60 +#define SERDES_25G_LANE_DRV_AFE_CALN_CTRL1_TXDRV_SEL_FIXEDCXN_XP5_SHIFT 5 + +#define SERDES_25G_LANE_DRV_AFE_CALP_CTRL0_TXDRV_SEL_CXP_X1_MASK 0x07 +#define SERDES_25G_LANE_DRV_AFE_CALP_CTRL0_TXDRV_SEL_CXP_X1_SHIFT 0 + +#define SERDES_25G_LANE_DRV_AFE_CALP_CTRL0_TXDRV_SEL_FIXEDCXP_X1_MASK 0x18 +#define SERDES_25G_LANE_DRV_AFE_CALP_CTRL0_TXDRV_SEL_FIXEDCXP_X1_SHIFT 3 + +#define SERDES_25G_LANE_DRV_AFE_CALP_CTRL1_TXDRV_SEL_CXP_X2_MASK 0x1F +#define SERDES_25G_LANE_DRV_AFE_CALP_CTRL1_TXDRV_SEL_CXP_X2_SHIFT 0 + +#define SERDES_25G_LANE_DRV_AFE_CALP_CTRL1_TXDRV_SEL_FIXEDCXP_XP5_MASK 0x60 +#define SERDES_25G_LANE_DRV_AFE_CALP_CTRL1_TXDRV_SEL_FIXEDCXP_XP5_SHIFT 5 + +#define SERDES_25G_LANE_DRV_TXEQ_CTRL0_REQ_MASK 0x01 +#define SERDES_25G_LANE_DRV_TXEQ_CTRL0_REQ_SHIFT 0 + +#define SERDES_25G_LANE_DRV_TXEQ_STATUS0_ACK_MASK 0x01 +#define SERDES_25G_LANE_DRV_TXEQ_STATUS0_ACK_SHIFT 0 + +#define SERDES_25G_LANE_DRV_TXEQ_CTRL1_TXEQ_C1_MASK 0x1F +#define SERDES_25G_LANE_DRV_TXEQ_CTRL1_TXEQ_C1_SHIFT 0 + +#define SERDES_25G_LANE_DRV_TXEQ_CTRL2_TXEQ_C2_MASK 0x03 +#define SERDES_25G_LANE_DRV_TXEQ_CTRL2_TXEQ_C2_SHIFT 0 + +#define SERDES_25G_LANE_DRV_TXEQ_CTRL3_TXEQ_CM1_MASK 0x0F +#define SERDES_25G_LANE_DRV_TXEQ_CTRL3_TXEQ_CM1_SHIFT 0 + +#define SERDES_25G_LANE_DRV_TXEQ_CTRL4_TXEQ_1LSB_MODE_MASK 0x01 +#define SERDES_25G_LANE_DRV_TXEQ_CTRL4_TXEQ_1LSB_MODE_SHIFT 0 + +#define SERDES_25G_LANE_DRV_TXEQ_CTRL4_SWING_1LSB_MODE_MASK 0x02 +#define SERDES_25G_LANE_DRV_TXEQ_CTRL4_SWING_1LSB_MODE_SHIFT 1 + +#define SERDES_25G_LANE_DRV_TXEQ_CTRL5_DRV_SWING_MASK 0x0F +#define SERDES_25G_LANE_DRV_TXEQ_CTRL5_DRV_SWING_SHIFT 0 + +/********************************* DFE REFCLK *********************************/ +#define SERDES_25G_LANE_DFE_REFCLK_BASE 0x400 + +#define SERDES_25G_LANE_DFE_REFCLK_AFE_PD_CTRL0_ADDR (SERDES_25G_LANE_DFE_REFCLK_BASE + 0x00) +#define SERDES_25G_LANE_DFE_REFCLK_AFE_PD_CTRL1_ADDR (SERDES_25G_LANE_DFE_REFCLK_BASE + 0x01) +#define SERDES_25G_LANE_DFE_REFCLK_AFE_PD_CTRL2_ADDR (SERDES_25G_LANE_DFE_REFCLK_BASE + 0x02) +#define SERDES_25G_LANE_DFE_REFCLK_AFE_RST_CTRL0_ADDR (SERDES_25G_LANE_DFE_REFCLK_BASE + 0x04) +#define SERDES_25G_LANE_DFE_REFCLK_AFE_TOGGLE_CTRL0_ADDR (SERDES_25G_LANE_DFE_REFCLK_BASE + 0x06) +#define SERDES_25G_LANE_DFE_REFCLK_AFE_MUTE_CTRL0_ADDR (SERDES_25G_LANE_DFE_REFCLK_BASE + 0x0A) +#define SERDES_25G_LANE_DFE_REFCLK_AFE_CLK_CTRL0_ADDR (SERDES_25G_LANE_DFE_REFCLK_BASE + 0x0C) +#define SERDES_25G_LANE_DFE_REFCLK_AFE_EYECLK_CTRL0_ADDR (SERDES_25G_LANE_DFE_REFCLK_BASE + 0x0E) +#define SERDES_25G_LANE_DFE_REFCLK_AFE_CML_CTRL0_ADDR (SERDES_25G_LANE_DFE_REFCLK_BASE + 0x10) +#define SERDES_25G_LANE_DFE_REFCLK_AFE_MISC_CTRL0_ADDR (SERDES_25G_LANE_DFE_REFCLK_BASE + 0x12) +#define SERDES_25G_LANE_DFE_REFCLK_AFE_SPARE_ADDR (SERDES_25G_LANE_DFE_REFCLK_BASE + 0x14) +#define SERDES_25G_LANE_DFE_REFCLK_AFE_QSAMPLE_STATUS0_ADDR (SERDES_25G_LANE_DFE_REFCLK_BASE + 0x16) +#define SERDES_25G_LANE_DFE_REFCLK_EYE_VSCAN_CTRL0_ADDR (SERDES_25G_LANE_DFE_REFCLK_BASE + 0x18) +#define SERDES_25G_LANE_DFE_REFCLK_EYE_VSCAN_CTRL1_ADDR (SERDES_25G_LANE_DFE_REFCLK_BASE + 0x19) +#define SERDES_25G_LANE_DFE_REFCLK_EYE_TAP1_CTRL0_ADDR (SERDES_25G_LANE_DFE_REFCLK_BASE + 0x1B) +#define SERDES_25G_LANE_DFE_REFCLK_FSM_CTRL0_ADDR (SERDES_25G_LANE_DFE_REFCLK_BASE + 0x20) +#define SERDES_25G_LANE_DFE_REFCLK_FSM_CTRL1_ADDR (SERDES_25G_LANE_DFE_REFCLK_BASE + 0x21) +#define SERDES_25G_LANE_DFE_REFCLK_FSM_CTRL2_ADDR (SERDES_25G_LANE_DFE_REFCLK_BASE + 0x22) +#define SERDES_25G_LANE_DFE_REFCLK_FSM_CTRL3_ADDR (SERDES_25G_LANE_DFE_REFCLK_BASE + 0x23) +#define SERDES_25G_LANE_DFE_REFCLK_FSM_CTRL4_ADDR (SERDES_25G_LANE_DFE_REFCLK_BASE + 0x24) +#define SERDES_25G_LANE_DFE_REFCLK_FSM_CTRL5_ADDR (SERDES_25G_LANE_DFE_REFCLK_BASE + 0x25) +#define SERDES_25G_LANE_DFE_REFCLK_FSM_CTRL6_ADDR (SERDES_25G_LANE_DFE_REFCLK_BASE + 0x26) +#define SERDES_25G_LANE_DFE_REFCLK_FSM_CTRL7_ADDR (SERDES_25G_LANE_DFE_REFCLK_BASE + 0x27) +#define SERDES_25G_LANE_DFE_REFCLK_FSM_STATUS0_ADDR (SERDES_25G_LANE_DFE_REFCLK_BASE + 0x28) +#define SERDES_25G_LANE_DFE_REFCLK_TAP_CTRL0_ADDR (SERDES_25G_LANE_DFE_REFCLK_BASE + 0x2A) +#define SERDES_25G_LANE_DFE_REFCLK_TAP_START_VAL_CTRL0_ADDR (SERDES_25G_LANE_DFE_REFCLK_BASE + 0x2B) +#define SERDES_25G_LANE_DFE_REFCLK_TAP_START_VAL_CTRL1_ADDR (SERDES_25G_LANE_DFE_REFCLK_BASE + 0x2C) +#define SERDES_25G_LANE_DFE_REFCLK_TAP_START_VAL_CTRL2_ADDR (SERDES_25G_LANE_DFE_REFCLK_BASE + 0x2D) +#define SERDES_25G_LANE_DFE_REFCLK_TAP_START_VAL_CTRL3_ADDR (SERDES_25G_LANE_DFE_REFCLK_BASE + 0x2E) +#define SERDES_25G_LANE_DFE_REFCLK_TAP_START_VAL_CTRL4_ADDR (SERDES_25G_LANE_DFE_REFCLK_BASE + 0x2F) +#define SERDES_25G_LANE_DFE_REFCLK_TAP_START_VAL_CTRL5_ADDR (SERDES_25G_LANE_DFE_REFCLK_BASE + 0x30) +#define SERDES_25G_LANE_DFE_REFCLK_TAP_START_VAL_CTRL6_ADDR (SERDES_25G_LANE_DFE_REFCLK_BASE + 0x31) +#define SERDES_25G_LANE_DFE_REFCLK_TAP_START_VAL_CTRL7_ADDR (SERDES_25G_LANE_DFE_REFCLK_BASE + 0x32) +#define SERDES_25G_LANE_DFE_REFCLK_TAP_LOAD_VAL_CTRL0_ADDR (SERDES_25G_LANE_DFE_REFCLK_BASE + 0x33) +#define SERDES_25G_LANE_DFE_REFCLK_TAP_LOAD_VAL_CTRL1_ADDR (SERDES_25G_LANE_DFE_REFCLK_BASE + 0x34) +#define SERDES_25G_LANE_DFE_REFCLK_TAP_LOAD_VAL_CTRL2_ADDR (SERDES_25G_LANE_DFE_REFCLK_BASE + 0x35) +#define SERDES_25G_LANE_DFE_REFCLK_TAP_LOAD_VAL_CTRL3_ADDR (SERDES_25G_LANE_DFE_REFCLK_BASE + 0x36) +#define SERDES_25G_LANE_DFE_REFCLK_TAP_LOAD_VAL_CTRL4_ADDR (SERDES_25G_LANE_DFE_REFCLK_BASE + 0x37) +#define SERDES_25G_LANE_DFE_REFCLK_TAP_LOAD_VAL_CTRL5_ADDR (SERDES_25G_LANE_DFE_REFCLK_BASE + 0x38) +#define SERDES_25G_LANE_DFE_REFCLK_TAP_LOAD_VAL_CTRL6_ADDR (SERDES_25G_LANE_DFE_REFCLK_BASE + 0x39) +#define SERDES_25G_LANE_DFE_REFCLK_TAP_LOAD_VAL_CTRL7_ADDR (SERDES_25G_LANE_DFE_REFCLK_BASE + 0x3A) +#define SERDES_25G_LANE_DFE_REFCLK_TAP_VAL_STATUS0_ADDR (SERDES_25G_LANE_DFE_REFCLK_BASE + 0x3B) +#define SERDES_25G_LANE_DFE_REFCLK_TAP_VAL_STATUS1_ADDR (SERDES_25G_LANE_DFE_REFCLK_BASE + 0x3C) +#define SERDES_25G_LANE_DFE_REFCLK_TAP_VAL_STATUS2_ADDR (SERDES_25G_LANE_DFE_REFCLK_BASE + 0x3D) +#define SERDES_25G_LANE_DFE_REFCLK_TAP_VAL_STATUS3_ADDR (SERDES_25G_LANE_DFE_REFCLK_BASE + 0x3E) +#define SERDES_25G_LANE_DFE_REFCLK_TAP_VAL_STATUS4_ADDR (SERDES_25G_LANE_DFE_REFCLK_BASE + 0x3F) +#define SERDES_25G_LANE_DFE_REFCLK_TAP_VAL_STATUS5_ADDR (SERDES_25G_LANE_DFE_REFCLK_BASE + 0x40) +#define SERDES_25G_LANE_DFE_REFCLK_TAP_VAL_STATUS6_ADDR (SERDES_25G_LANE_DFE_REFCLK_BASE + 0x41) +#define SERDES_25G_LANE_DFE_REFCLK_TAP_VAL_STATUS7_ADDR (SERDES_25G_LANE_DFE_REFCLK_BASE + 0x42) +#define SERDES_25G_LANE_DFE_REFCLK_SLICER_OFST_CTRL0_ADDR (SERDES_25G_LANE_DFE_REFCLK_BASE + 0x50) +#define SERDES_25G_LANE_DFE_REFCLK_SLICER_OFST_CTRL1_ADDR (SERDES_25G_LANE_DFE_REFCLK_BASE + 0x51) +#define SERDES_25G_LANE_DFE_REFCLK_SLICER_OFST_CTRL2_ADDR (SERDES_25G_LANE_DFE_REFCLK_BASE + 0x52) +#define SERDES_25G_LANE_DFE_REFCLK_SLICER_OFST_LOAD_VAL_CTRL0_ADDR (SERDES_25G_LANE_DFE_REFCLK_BASE + 0x53) +#define SERDES_25G_LANE_DFE_REFCLK_SLICER_OFST_LOAD_VAL_CTRL1_ADDR (SERDES_25G_LANE_DFE_REFCLK_BASE + 0x54) +#define SERDES_25G_LANE_DFE_REFCLK_SLICER_OFST_LOAD_VAL_CTRL2_ADDR (SERDES_25G_LANE_DFE_REFCLK_BASE + 0x55) +#define SERDES_25G_LANE_DFE_REFCLK_SLICER_OFST_LOAD_VAL_CTRL3_ADDR (SERDES_25G_LANE_DFE_REFCLK_BASE + 0x56) +#define SERDES_25G_LANE_DFE_REFCLK_SLICER_OFST_LOAD_VAL_CTRL4_ADDR (SERDES_25G_LANE_DFE_REFCLK_BASE + 0x57) +#define SERDES_25G_LANE_DFE_REFCLK_SLICER_OFST_LOAD_VAL_CTRL5_ADDR (SERDES_25G_LANE_DFE_REFCLK_BASE + 0x58) +#define SERDES_25G_LANE_DFE_REFCLK_SLICER_OFST_LOAD_VAL_CTRL6_ADDR (SERDES_25G_LANE_DFE_REFCLK_BASE + 0x59) +#define SERDES_25G_LANE_DFE_REFCLK_SLICER_OFST_LOAD_VAL_CTRL7_ADDR (SERDES_25G_LANE_DFE_REFCLK_BASE + 0x5A) +#define SERDES_25G_LANE_DFE_REFCLK_SLICER_OFST_VAL_STATUS0_ADDR (SERDES_25G_LANE_DFE_REFCLK_BASE + 0x5B) +#define SERDES_25G_LANE_DFE_REFCLK_SLICER_OFST_VAL_STATUS1_ADDR (SERDES_25G_LANE_DFE_REFCLK_BASE + 0x5C) +#define SERDES_25G_LANE_DFE_REFCLK_SLICER_OFST_VAL_STATUS2_ADDR (SERDES_25G_LANE_DFE_REFCLK_BASE + 0x5D) +#define SERDES_25G_LANE_DFE_REFCLK_SLICER_OFST_VAL_STATUS3_ADDR (SERDES_25G_LANE_DFE_REFCLK_BASE + 0x5E) +#define SERDES_25G_LANE_DFE_REFCLK_SLICER_OFST_VAL_STATUS4_ADDR (SERDES_25G_LANE_DFE_REFCLK_BASE + 0x5F) +#define SERDES_25G_LANE_DFE_REFCLK_SLICER_OFST_VAL_STATUS5_ADDR (SERDES_25G_LANE_DFE_REFCLK_BASE + 0x60) +#define SERDES_25G_LANE_DFE_REFCLK_SLICER_OFST_VAL_STATUS6_ADDR (SERDES_25G_LANE_DFE_REFCLK_BASE + 0x61) +#define SERDES_25G_LANE_DFE_REFCLK_SLICER_OFST_VAL_STATUS7_ADDR (SERDES_25G_LANE_DFE_REFCLK_BASE + 0x62) +#define SERDES_25G_LANE_DFE_REFCLK_SLICER_OFST_LOAD_SOURCE_CTRL0_ADDR (SERDES_25G_LANE_DFE_REFCLK_BASE + 0x63) +#define SERDES_25G_LANE_DFE_REFCLK_SLICER_OFST_STATUS0_ADDR (SERDES_25G_LANE_DFE_REFCLK_BASE + 0x64) +#define SERDES_25G_LANE_DFE_REFCLK_SLICER_OFST_STATUS1_ADDR (SERDES_25G_LANE_DFE_REFCLK_BASE + 0x65) +/******************************************************************************* + * masks and shifts + ******************************************************************************/ +#define SERDES_25G_LANE_DFE_REFCLK_AFE_PD_CTRL0_PD_RXDFE_MASK 0x01 +#define SERDES_25G_LANE_DFE_REFCLK_AFE_PD_CTRL0_PD_RXDFE_SHIFT 0 + +#define SERDES_25G_LANE_DFE_REFCLK_AFE_PD_CTRL0_PD_RXDFE_TAP_MASK 0x3E +#define SERDES_25G_LANE_DFE_REFCLK_AFE_PD_CTRL0_PD_RXDFE_TAP_SHIFT 1 + +#define SERDES_25G_LANE_DFE_REFCLK_AFE_PD_CTRL1_PD_RXDFE_EVEN_PATH_MASK 0x03 +#define SERDES_25G_LANE_DFE_REFCLK_AFE_PD_CTRL1_PD_RXDFE_EVEN_PATH_SHIFT 0 + +#define SERDES_25G_LANE_DFE_REFCLK_AFE_PD_CTRL1_PD_RXDFE_ODD_PATH_MASK 0x0C +#define SERDES_25G_LANE_DFE_REFCLK_AFE_PD_CTRL1_PD_RXDFE_ODD_PATH_SHIFT 2 + +#define SERDES_25G_LANE_DFE_REFCLK_AFE_PD_CTRL2_PD_RXDFE_EYE_EVEN_MASK 0x07 +#define SERDES_25G_LANE_DFE_REFCLK_AFE_PD_CTRL2_PD_RXDFE_EYE_EVEN_SHIFT 0 + +#define SERDES_25G_LANE_DFE_REFCLK_AFE_PD_CTRL2_PD_RXDFE_EYE_ODD_MASK 0x38 +#define SERDES_25G_LANE_DFE_REFCLK_AFE_PD_CTRL2_PD_RXDFE_EYE_ODD_SHIFT 3 + +#define SERDES_25G_LANE_DFE_REFCLK_AFE_RST_CTRL0_RST_RXDFE_N_MASK 0x01 +#define SERDES_25G_LANE_DFE_REFCLK_AFE_RST_CTRL0_RST_RXDFE_N_SHIFT 0 + +#define SERDES_25G_LANE_DFE_REFCLK_AFE_TOGGLE_CTRL0_RXDFE_TOGGLE_EN_MASK 0x01 +#define SERDES_25G_LANE_DFE_REFCLK_AFE_TOGGLE_CTRL0_RXDFE_TOGGLE_EN_SHIFT 0 + +#define SERDES_25G_LANE_DFE_REFCLK_AFE_MUTE_CTRL0_RXDFE_MUTE_EYE_EVEN_MASK 0x01 +#define SERDES_25G_LANE_DFE_REFCLK_AFE_MUTE_CTRL0_RXDFE_MUTE_EYE_EVEN_SHIFT 0 + +#define SERDES_25G_LANE_DFE_REFCLK_AFE_MUTE_CTRL0_RXDFE_MUTE_EYE_ODD_MASK 0x02 +#define SERDES_25G_LANE_DFE_REFCLK_AFE_MUTE_CTRL0_RXDFE_MUTE_EYE_ODD_SHIFT 1 + +#define SERDES_25G_LANE_DFE_REFCLK_AFE_MUTE_CTRL0_RXDFE_EDGE_MUTE_MASK 0x0C +#define SERDES_25G_LANE_DFE_REFCLK_AFE_MUTE_CTRL0_RXDFE_EDGE_MUTE_SHIFT 2 + +#define SERDES_25G_LANE_DFE_REFCLK_AFE_CLK_CTRL0_RXDFE_CLK_DELAY_MASK 0x0F +#define SERDES_25G_LANE_DFE_REFCLK_AFE_CLK_CTRL0_RXDFE_CLK_DELAY_SHIFT 0 + +#define SERDES_25G_LANE_DFE_REFCLK_AFE_CLK_CTRL0_RXDFE_CLKDIV_OVR_MASK 0x30 +#define SERDES_25G_LANE_DFE_REFCLK_AFE_CLK_CTRL0_RXDFE_CLKDIV_OVR_SHIFT 4 + +#define SERDES_25G_LANE_DFE_REFCLK_AFE_EYECLK_CTRL0_RXDFE_EYECLK_DELAY_MASK 0x0F +#define SERDES_25G_LANE_DFE_REFCLK_AFE_EYECLK_CTRL0_RXDFE_EYECLK_DELAY_SHIFT 0 + +#define SERDES_25G_LANE_DFE_REFCLK_AFE_EYECLK_CTRL0_RXDFE_CLKDIVEYE_OVR_MASK 0x30 +#define SERDES_25G_LANE_DFE_REFCLK_AFE_EYECLK_CTRL0_RXDFE_CLKDIVEYE_OVR_SHIFT 4 + +#define SERDES_25G_LANE_DFE_REFCLK_AFE_EYECLK_CTRL0_RXDFE_EYERESAMP_ADJ_MASK 0xC0 +#define SERDES_25G_LANE_DFE_REFCLK_AFE_EYECLK_CTRL0_RXDFE_EYERESAMP_ADJ_SHIFT 6 + +#define SERDES_25G_LANE_DFE_REFCLK_AFE_CML_CTRL0_RXDFE_CMLI_MASK 0x0F +#define SERDES_25G_LANE_DFE_REFCLK_AFE_CML_CTRL0_RXDFE_CMLI_SHIFT 0 + +#define SERDES_25G_LANE_DFE_REFCLK_AFE_CML_CTRL0_RXDFE_CMLR_MASK 0x30 +#define SERDES_25G_LANE_DFE_REFCLK_AFE_CML_CTRL0_RXDFE_CMLR_SHIFT 4 + +#define SERDES_25G_LANE_DFE_REFCLK_AFE_CML_CTRL0_RXDFE_CMLR_LTCH_MASK 0x40 +#define SERDES_25G_LANE_DFE_REFCLK_AFE_CML_CTRL0_RXDFE_CMLR_LTCH_SHIFT 6 + +#define SERDES_25G_LANE_DFE_REFCLK_AFE_MISC_CTRL0_RXDFE_SUMGAIN_MASK 0x01 +#define SERDES_25G_LANE_DFE_REFCLK_AFE_MISC_CTRL0_RXDFE_SUMGAIN_SHIFT 0 + +#define SERDES_25G_LANE_DFE_REFCLK_AFE_MISC_CTRL0_RXDFE_LDR_MASK 0x06 +#define SERDES_25G_LANE_DFE_REFCLK_AFE_MISC_CTRL0_RXDFE_LDR_SHIFT 1 + +#define SERDES_25G_LANE_DFE_REFCLK_AFE_SPARE_RXDFE_SPARE_MASK 0xFF +#define SERDES_25G_LANE_DFE_REFCLK_AFE_SPARE_RXDFE_SPARE_SHIFT 0 + +#define SERDES_25G_LANE_DFE_REFCLK_AFE_QSAMPLE_STATUS0_RXDFE_CLKDIV_QSAMPLE_MASK 0x01 +#define SERDES_25G_LANE_DFE_REFCLK_AFE_QSAMPLE_STATUS0_RXDFE_CLKDIV_QSAMPLE_SHIFT 0 + +#define SERDES_25G_LANE_DFE_REFCLK_AFE_QSAMPLE_STATUS0_RXDFE_CLKDIVEYE_QSAMPLE_MASK 0x1E +#define SERDES_25G_LANE_DFE_REFCLK_AFE_QSAMPLE_STATUS0_RXDFE_CLKDIVEYE_QSAMPLE_SHIFT 1 + +#define SERDES_25G_LANE_DFE_REFCLK_EYE_VSCAN_CTRL0_MAG_MASK 0xFF +#define SERDES_25G_LANE_DFE_REFCLK_EYE_VSCAN_CTRL0_MAG_SHIFT 0 + +#define SERDES_25G_LANE_DFE_REFCLK_EYE_VSCAN_CTRL1_POL_MASK 0x01 +#define SERDES_25G_LANE_DFE_REFCLK_EYE_VSCAN_CTRL1_POL_SHIFT 0 + +#define SERDES_25G_LANE_DFE_REFCLK_EYE_TAP1_CTRL0_MAG_MASK 0x1F +#define SERDES_25G_LANE_DFE_REFCLK_EYE_TAP1_CTRL0_MAG_SHIFT 0 + +#define SERDES_25G_LANE_DFE_REFCLK_EYE_TAP1_CTRL0_POL_MASK 0x80 +#define SERDES_25G_LANE_DFE_REFCLK_EYE_TAP1_CTRL0_POL_SHIFT 7 + +#define SERDES_25G_LANE_DFE_REFCLK_FSM_CTRL0_REQ_MASK 0x01 +#define SERDES_25G_LANE_DFE_REFCLK_FSM_CTRL0_REQ_SHIFT 0 + +#define SERDES_25G_LANE_DFE_REFCLK_FSM_CTRL0_CMD_MASK 0x3E +#define SERDES_25G_LANE_DFE_REFCLK_FSM_CTRL0_CMD_SHIFT 1 + +#define SERDES_25G_LANE_DFE_REFCLK_FSM_CTRL0_FINISH_MASK 0x40 +#define SERDES_25G_LANE_DFE_REFCLK_FSM_CTRL0_FINISH_SHIFT 6 + +#define SERDES_25G_LANE_DFE_REFCLK_FSM_CTRL0_DRIVE_BEFORE_EVAL_MASK 0x80 +#define SERDES_25G_LANE_DFE_REFCLK_FSM_CTRL0_DRIVE_BEFORE_EVAL_SHIFT 7 + +#define SERDES_25G_LANE_DFE_REFCLK_FSM_CTRL1_NEXT_STATE_MASK 0x0F +#define SERDES_25G_LANE_DFE_REFCLK_FSM_CTRL1_NEXT_STATE_SHIFT 0 + +#define SERDES_25G_LANE_DFE_REFCLK_FSM_CTRL1_CTRL_EN_MASK 0x10 +#define SERDES_25G_LANE_DFE_REFCLK_FSM_CTRL1_CTRL_EN_SHIFT 4 + +#define SERDES_25G_LANE_DFE_REFCLK_FSM_CTRL2_WAIT_1_TIMER7_0_MASK 0xFF +#define SERDES_25G_LANE_DFE_REFCLK_FSM_CTRL2_WAIT_1_TIMER7_0_SHIFT 0 + +#define SERDES_25G_LANE_DFE_REFCLK_FSM_CTRL3_WAIT_1_TIMER9_8_MASK 0x03 +#define SERDES_25G_LANE_DFE_REFCLK_FSM_CTRL3_WAIT_1_TIMER9_8_SHIFT 0 + +#define SERDES_25G_LANE_DFE_REFCLK_FSM_CTRL4_WAIT_2_TIMER7_0_MASK 0xFF +#define SERDES_25G_LANE_DFE_REFCLK_FSM_CTRL4_WAIT_2_TIMER7_0_SHIFT 0 + +#define SERDES_25G_LANE_DFE_REFCLK_FSM_CTRL5_WAIT_2_TIMER9_8_MASK 0x03 +#define SERDES_25G_LANE_DFE_REFCLK_FSM_CTRL5_WAIT_2_TIMER9_8_SHIFT 0 + +#define SERDES_25G_LANE_DFE_REFCLK_FSM_CTRL6_TAP_DELAY_7_0_MASK 0xFF +#define SERDES_25G_LANE_DFE_REFCLK_FSM_CTRL6_TAP_DELAY_7_0_SHIFT 0 + +#define SERDES_25G_LANE_DFE_REFCLK_FSM_CTRL7_TAP_DELAY_9_8_MASK 0x03 +#define SERDES_25G_LANE_DFE_REFCLK_FSM_CTRL7_TAP_DELAY_9_8_SHIFT 0 + +#define SERDES_25G_LANE_DFE_REFCLK_FSM_STATUS0_ACK_MASK 0x01 +#define SERDES_25G_LANE_DFE_REFCLK_FSM_STATUS0_ACK_SHIFT 0 + +#define SERDES_25G_LANE_DFE_REFCLK_FSM_STATUS0_SLICER_OFST_ACK_MASK 0x02 +#define SERDES_25G_LANE_DFE_REFCLK_FSM_STATUS0_SLICER_OFST_ACK_SHIFT 1 + +#define SERDES_25G_LANE_DFE_REFCLK_FSM_STATUS0_ERR_FUNC_ACK_MASK 0x04 +#define SERDES_25G_LANE_DFE_REFCLK_FSM_STATUS0_ERR_FUNC_ACK_SHIFT 2 + +#define SERDES_25G_LANE_DFE_REFCLK_FSM_STATUS0_AFE_DRV_ACK_MASK 0x08 +#define SERDES_25G_LANE_DFE_REFCLK_FSM_STATUS0_AFE_DRV_ACK_SHIFT 3 + +#define SERDES_25G_LANE_DFE_REFCLK_TAP_CTRL0_TAP1_EVEN0_EN_MASK 0x01 +#define SERDES_25G_LANE_DFE_REFCLK_TAP_CTRL0_TAP1_EVEN0_EN_SHIFT 0 + +#define SERDES_25G_LANE_DFE_REFCLK_TAP_CTRL0_TAP1_EVEN1_EN_MASK 0x02 +#define SERDES_25G_LANE_DFE_REFCLK_TAP_CTRL0_TAP1_EVEN1_EN_SHIFT 1 + +#define SERDES_25G_LANE_DFE_REFCLK_TAP_CTRL0_TAP1_ODD0_EN_MASK 0x04 +#define SERDES_25G_LANE_DFE_REFCLK_TAP_CTRL0_TAP1_ODD0_EN_SHIFT 2 + +#define SERDES_25G_LANE_DFE_REFCLK_TAP_CTRL0_TAP1_ODD1_EN_MASK 0x08 +#define SERDES_25G_LANE_DFE_REFCLK_TAP_CTRL0_TAP1_ODD1_EN_SHIFT 3 + +#define SERDES_25G_LANE_DFE_REFCLK_TAP_CTRL0_TAP2_EN_MASK 0x10 +#define SERDES_25G_LANE_DFE_REFCLK_TAP_CTRL0_TAP2_EN_SHIFT 4 + +#define SERDES_25G_LANE_DFE_REFCLK_TAP_CTRL0_TAP3_EN_MASK 0x20 +#define SERDES_25G_LANE_DFE_REFCLK_TAP_CTRL0_TAP3_EN_SHIFT 5 + +#define SERDES_25G_LANE_DFE_REFCLK_TAP_CTRL0_TAP4_EN_MASK 0x40 +#define SERDES_25G_LANE_DFE_REFCLK_TAP_CTRL0_TAP4_EN_SHIFT 6 + +#define SERDES_25G_LANE_DFE_REFCLK_TAP_CTRL0_TAP5_EN_MASK 0x80 +#define SERDES_25G_LANE_DFE_REFCLK_TAP_CTRL0_TAP5_EN_SHIFT 7 + +#define SERDES_25G_LANE_DFE_REFCLK_TAP_START_VAL_CTRL0_TAP1_EVEN0_MASK 0x1F +#define SERDES_25G_LANE_DFE_REFCLK_TAP_START_VAL_CTRL0_TAP1_EVEN0_SHIFT 0 + +#define SERDES_25G_LANE_DFE_REFCLK_TAP_START_VAL_CTRL0_TAP1_EVEN0_POLARITY_MASK 0x80 +#define SERDES_25G_LANE_DFE_REFCLK_TAP_START_VAL_CTRL0_TAP1_EVEN0_POLARITY_SHIFT 7 + +#define SERDES_25G_LANE_DFE_REFCLK_TAP_START_VAL_CTRL1_TAP1_EVEN1_MASK 0x1F +#define SERDES_25G_LANE_DFE_REFCLK_TAP_START_VAL_CTRL1_TAP1_EVEN1_SHIFT 0 + +#define SERDES_25G_LANE_DFE_REFCLK_TAP_START_VAL_CTRL1_TAP1_EVEN1_POLARITY_MASK 0x80 +#define SERDES_25G_LANE_DFE_REFCLK_TAP_START_VAL_CTRL1_TAP1_EVEN1_POLARITY_SHIFT 7 + +#define SERDES_25G_LANE_DFE_REFCLK_TAP_START_VAL_CTRL2_TAP1_ODD0_MASK 0x1F +#define SERDES_25G_LANE_DFE_REFCLK_TAP_START_VAL_CTRL2_TAP1_ODD0_SHIFT 0 + +#define SERDES_25G_LANE_DFE_REFCLK_TAP_START_VAL_CTRL2_TAP1_ODD0_POLARITY_MASK 0x80 +#define SERDES_25G_LANE_DFE_REFCLK_TAP_START_VAL_CTRL2_TAP1_ODD0_POLARITY_SHIFT 7 + +#define SERDES_25G_LANE_DFE_REFCLK_TAP_START_VAL_CTRL3_TAP1_ODD1_MASK 0x1F +#define SERDES_25G_LANE_DFE_REFCLK_TAP_START_VAL_CTRL3_TAP1_ODD1_SHIFT 0 + +#define SERDES_25G_LANE_DFE_REFCLK_TAP_START_VAL_CTRL3_TAP1_ODD1_POLARITY_MASK 0x80 +#define SERDES_25G_LANE_DFE_REFCLK_TAP_START_VAL_CTRL3_TAP1_ODD1_POLARITY_SHIFT 7 + +#define SERDES_25G_LANE_DFE_REFCLK_TAP_START_VAL_CTRL4_TAP2_MASK 0x0F +#define SERDES_25G_LANE_DFE_REFCLK_TAP_START_VAL_CTRL4_TAP2_SHIFT 0 + +#define SERDES_25G_LANE_DFE_REFCLK_TAP_START_VAL_CTRL4_TAP2_POLARITY_MASK 0x80 +#define SERDES_25G_LANE_DFE_REFCLK_TAP_START_VAL_CTRL4_TAP2_POLARITY_SHIFT 7 + +#define SERDES_25G_LANE_DFE_REFCLK_TAP_START_VAL_CTRL5_TAP3_MASK 0x07 +#define SERDES_25G_LANE_DFE_REFCLK_TAP_START_VAL_CTRL5_TAP3_SHIFT 0 + +#define SERDES_25G_LANE_DFE_REFCLK_TAP_START_VAL_CTRL5_TAP3_POLARITY_MASK 0x80 +#define SERDES_25G_LANE_DFE_REFCLK_TAP_START_VAL_CTRL5_TAP3_POLARITY_SHIFT 7 + +#define SERDES_25G_LANE_DFE_REFCLK_TAP_START_VAL_CTRL6_TAP4_MASK 0x07 +#define SERDES_25G_LANE_DFE_REFCLK_TAP_START_VAL_CTRL6_TAP4_SHIFT 0 + +#define SERDES_25G_LANE_DFE_REFCLK_TAP_START_VAL_CTRL6_TAP4_POLARITY_MASK 0x80 +#define SERDES_25G_LANE_DFE_REFCLK_TAP_START_VAL_CTRL6_TAP4_POLARITY_SHIFT 7 + +#define SERDES_25G_LANE_DFE_REFCLK_TAP_START_VAL_CTRL7_TAP5_MASK 0x07 +#define SERDES_25G_LANE_DFE_REFCLK_TAP_START_VAL_CTRL7_TAP5_SHIFT 0 + +#define SERDES_25G_LANE_DFE_REFCLK_TAP_START_VAL_CTRL7_TAP5_POLARITY_MASK 0x80 +#define SERDES_25G_LANE_DFE_REFCLK_TAP_START_VAL_CTRL7_TAP5_POLARITY_SHIFT 7 + +#define SERDES_25G_LANE_DFE_REFCLK_TAP_LOAD_VAL_CTRL0_TAP1_EVEN0_MASK 0x1F +#define SERDES_25G_LANE_DFE_REFCLK_TAP_LOAD_VAL_CTRL0_TAP1_EVEN0_SHIFT 0 + +#define SERDES_25G_LANE_DFE_REFCLK_TAP_LOAD_VAL_CTRL0_TAP1_EVEN0_POLARITY_MASK 0x80 +#define SERDES_25G_LANE_DFE_REFCLK_TAP_LOAD_VAL_CTRL0_TAP1_EVEN0_POLARITY_SHIFT 7 + +#define SERDES_25G_LANE_DFE_REFCLK_TAP_LOAD_VAL_CTRL1_TAP1_EVEN1_MASK 0x1F +#define SERDES_25G_LANE_DFE_REFCLK_TAP_LOAD_VAL_CTRL1_TAP1_EVEN1_SHIFT 0 + +#define SERDES_25G_LANE_DFE_REFCLK_TAP_LOAD_VAL_CTRL1_TAP1_EVEN1_POLARITY_MASK 0x80 +#define SERDES_25G_LANE_DFE_REFCLK_TAP_LOAD_VAL_CTRL1_TAP1_EVEN1_POLARITY_SHIFT 7 + +#define SERDES_25G_LANE_DFE_REFCLK_TAP_LOAD_VAL_CTRL2_TAP1_ODD0_MASK 0x1F +#define SERDES_25G_LANE_DFE_REFCLK_TAP_LOAD_VAL_CTRL2_TAP1_ODD0_SHIFT 0 + +#define SERDES_25G_LANE_DFE_REFCLK_TAP_LOAD_VAL_CTRL2_TAP1_ODD0_POLARITY_MASK 0x80 +#define SERDES_25G_LANE_DFE_REFCLK_TAP_LOAD_VAL_CTRL2_TAP1_ODD0_POLARITY_SHIFT 7 + +#define SERDES_25G_LANE_DFE_REFCLK_TAP_LOAD_VAL_CTRL3_TAP1_ODD1_MASK 0x1F +#define SERDES_25G_LANE_DFE_REFCLK_TAP_LOAD_VAL_CTRL3_TAP1_ODD1_SHIFT 0 + +#define SERDES_25G_LANE_DFE_REFCLK_TAP_LOAD_VAL_CTRL3_TAP1_ODD1_POLARITY_MASK 0x80 +#define SERDES_25G_LANE_DFE_REFCLK_TAP_LOAD_VAL_CTRL3_TAP1_ODD1_POLARITY_SHIFT 7 + +#define SERDES_25G_LANE_DFE_REFCLK_TAP_LOAD_VAL_CTRL4_TAP2_MASK 0x0F +#define SERDES_25G_LANE_DFE_REFCLK_TAP_LOAD_VAL_CTRL4_TAP2_SHIFT 0 + +#define SERDES_25G_LANE_DFE_REFCLK_TAP_LOAD_VAL_CTRL4_TAP2_POLARITY_MASK 0x80 +#define SERDES_25G_LANE_DFE_REFCLK_TAP_LOAD_VAL_CTRL4_TAP2_POLARITY_SHIFT 7 + +#define SERDES_25G_LANE_DFE_REFCLK_TAP_LOAD_VAL_CTRL5_TAP3_MASK 0x07 +#define SERDES_25G_LANE_DFE_REFCLK_TAP_LOAD_VAL_CTRL5_TAP3_SHIFT 0 + +#define SERDES_25G_LANE_DFE_REFCLK_TAP_LOAD_VAL_CTRL5_TAP3_POLARITY_MASK 0x80 +#define SERDES_25G_LANE_DFE_REFCLK_TAP_LOAD_VAL_CTRL5_TAP3_POLARITY_SHIFT 7 + +#define SERDES_25G_LANE_DFE_REFCLK_TAP_LOAD_VAL_CTRL6_TAP4_MASK 0x07 +#define SERDES_25G_LANE_DFE_REFCLK_TAP_LOAD_VAL_CTRL6_TAP4_SHIFT 0 + +#define SERDES_25G_LANE_DFE_REFCLK_TAP_LOAD_VAL_CTRL6_TAP4_POLARITY_MASK 0x80 +#define SERDES_25G_LANE_DFE_REFCLK_TAP_LOAD_VAL_CTRL6_TAP4_POLARITY_SHIFT 7 + +#define SERDES_25G_LANE_DFE_REFCLK_TAP_LOAD_VAL_CTRL7_TAP5_MASK 0x07 +#define SERDES_25G_LANE_DFE_REFCLK_TAP_LOAD_VAL_CTRL7_TAP5_SHIFT 0 + +#define SERDES_25G_LANE_DFE_REFCLK_TAP_LOAD_VAL_CTRL7_TAP5_POLARITY_MASK 0x80 +#define SERDES_25G_LANE_DFE_REFCLK_TAP_LOAD_VAL_CTRL7_TAP5_POLARITY_SHIFT 7 + +#define SERDES_25G_LANE_DFE_REFCLK_TAP_VAL_STATUS0_TAP1_EVEN0_MASK 0x1F +#define SERDES_25G_LANE_DFE_REFCLK_TAP_VAL_STATUS0_TAP1_EVEN0_SHIFT 0 + +#define SERDES_25G_LANE_DFE_REFCLK_TAP_VAL_STATUS0_TAP1_EVEN0_POLARITY_MASK 0x80 +#define SERDES_25G_LANE_DFE_REFCLK_TAP_VAL_STATUS0_TAP1_EVEN0_POLARITY_SHIFT 7 + +#define SERDES_25G_LANE_DFE_REFCLK_TAP_VAL_STATUS1_TAP1_EVEN1_MASK 0x1F +#define SERDES_25G_LANE_DFE_REFCLK_TAP_VAL_STATUS1_TAP1_EVEN1_SHIFT 0 + +#define SERDES_25G_LANE_DFE_REFCLK_TAP_VAL_STATUS1_TAP1_EVEN1_POLARITY_MASK 0x80 +#define SERDES_25G_LANE_DFE_REFCLK_TAP_VAL_STATUS1_TAP1_EVEN1_POLARITY_SHIFT 7 + +#define SERDES_25G_LANE_DFE_REFCLK_TAP_VAL_STATUS2_TAP1_ODD0_MASK 0x1F +#define SERDES_25G_LANE_DFE_REFCLK_TAP_VAL_STATUS2_TAP1_ODD0_SHIFT 0 + +#define SERDES_25G_LANE_DFE_REFCLK_TAP_VAL_STATUS2_TAP1_ODD0_POLARITY_MASK 0x80 +#define SERDES_25G_LANE_DFE_REFCLK_TAP_VAL_STATUS2_TAP1_ODD0_POLARITY_SHIFT 7 + +#define SERDES_25G_LANE_DFE_REFCLK_TAP_VAL_STATUS3_TAP1_ODD1_MASK 0x1F +#define SERDES_25G_LANE_DFE_REFCLK_TAP_VAL_STATUS3_TAP1_ODD1_SHIFT 0 + +#define SERDES_25G_LANE_DFE_REFCLK_TAP_VAL_STATUS3_TAP1_ODD1_POLARITY_MASK 0x80 +#define SERDES_25G_LANE_DFE_REFCLK_TAP_VAL_STATUS3_TAP1_ODD1_POLARITY_SHIFT 7 + +#define SERDES_25G_LANE_DFE_REFCLK_TAP_VAL_STATUS4_TAP2_MASK 0x0F +#define SERDES_25G_LANE_DFE_REFCLK_TAP_VAL_STATUS4_TAP2_SHIFT 0 + +#define SERDES_25G_LANE_DFE_REFCLK_TAP_VAL_STATUS4_TAP2_POLARITY_MASK 0x80 +#define SERDES_25G_LANE_DFE_REFCLK_TAP_VAL_STATUS4_TAP2_POLARITY_SHIFT 7 + +#define SERDES_25G_LANE_DFE_REFCLK_TAP_VAL_STATUS5_TAP3_MASK 0x07 +#define SERDES_25G_LANE_DFE_REFCLK_TAP_VAL_STATUS5_TAP3_SHIFT 0 + +#define SERDES_25G_LANE_DFE_REFCLK_TAP_VAL_STATUS5_TAP3_POLARITY_MASK 0x80 +#define SERDES_25G_LANE_DFE_REFCLK_TAP_VAL_STATUS5_TAP3_POLARITY_SHIFT 7 + +#define SERDES_25G_LANE_DFE_REFCLK_TAP_VAL_STATUS6_TAP4_MASK 0x07 +#define SERDES_25G_LANE_DFE_REFCLK_TAP_VAL_STATUS6_TAP4_SHIFT 0 + +#define SERDES_25G_LANE_DFE_REFCLK_TAP_VAL_STATUS6_TAP4_POLARITY_MASK 0x80 +#define SERDES_25G_LANE_DFE_REFCLK_TAP_VAL_STATUS6_TAP4_POLARITY_SHIFT 7 + +#define SERDES_25G_LANE_DFE_REFCLK_TAP_VAL_STATUS7_TAP5_MASK 0x07 +#define SERDES_25G_LANE_DFE_REFCLK_TAP_VAL_STATUS7_TAP5_SHIFT 0 + +#define SERDES_25G_LANE_DFE_REFCLK_TAP_VAL_STATUS7_TAP5_POLARITY_MASK 0x80 +#define SERDES_25G_LANE_DFE_REFCLK_TAP_VAL_STATUS7_TAP5_POLARITY_SHIFT 7 + +#define SERDES_25G_LANE_DFE_REFCLK_SLICER_OFST_CTRL0_EVEN0_DATA_EN_MASK 0x01 +#define SERDES_25G_LANE_DFE_REFCLK_SLICER_OFST_CTRL0_EVEN0_DATA_EN_SHIFT 0 + +#define SERDES_25G_LANE_DFE_REFCLK_SLICER_OFST_CTRL0_EVEN1_DATA_EN_MASK 0x02 +#define SERDES_25G_LANE_DFE_REFCLK_SLICER_OFST_CTRL0_EVEN1_DATA_EN_SHIFT 1 + +#define SERDES_25G_LANE_DFE_REFCLK_SLICER_OFST_CTRL0_ODD0_DATA_EN_MASK 0x04 +#define SERDES_25G_LANE_DFE_REFCLK_SLICER_OFST_CTRL0_ODD0_DATA_EN_SHIFT 2 + +#define SERDES_25G_LANE_DFE_REFCLK_SLICER_OFST_CTRL0_ODD1_DATA_EN_MASK 0x08 +#define SERDES_25G_LANE_DFE_REFCLK_SLICER_OFST_CTRL0_ODD1_DATA_EN_SHIFT 3 + +#define SERDES_25G_LANE_DFE_REFCLK_SLICER_OFST_CTRL0_EVEN_EDGE_EN_MASK 0x10 +#define SERDES_25G_LANE_DFE_REFCLK_SLICER_OFST_CTRL0_EVEN_EDGE_EN_SHIFT 4 + +#define SERDES_25G_LANE_DFE_REFCLK_SLICER_OFST_CTRL0_ODD_EDGE_EN_MASK 0x20 +#define SERDES_25G_LANE_DFE_REFCLK_SLICER_OFST_CTRL0_ODD_EDGE_EN_SHIFT 5 + +#define SERDES_25G_LANE_DFE_REFCLK_SLICER_OFST_CTRL0_EVEN_EYE_EN_MASK 0x40 +#define SERDES_25G_LANE_DFE_REFCLK_SLICER_OFST_CTRL0_EVEN_EYE_EN_SHIFT 6 + +#define SERDES_25G_LANE_DFE_REFCLK_SLICER_OFST_CTRL0_ODD_EYE_EN_MASK 0x80 +#define SERDES_25G_LANE_DFE_REFCLK_SLICER_OFST_CTRL0_ODD_EYE_EN_SHIFT 7 + +#define SERDES_25G_LANE_DFE_REFCLK_SLICER_OFST_CTRL1_LIMIT_MASK 0x1F +#define SERDES_25G_LANE_DFE_REFCLK_SLICER_OFST_CTRL1_LIMIT_SHIFT 0 + +#define SERDES_25G_LANE_DFE_REFCLK_SLICER_OFST_CTRL2_MAX_BOUNCES_MASK 0x0F +#define SERDES_25G_LANE_DFE_REFCLK_SLICER_OFST_CTRL2_MAX_BOUNCES_SHIFT 0 + +#define SERDES_25G_LANE_DFE_REFCLK_SLICER_OFST_LOAD_VAL_CTRL0_EVEN0_DATA_MASK 0x3F +#define SERDES_25G_LANE_DFE_REFCLK_SLICER_OFST_LOAD_VAL_CTRL0_EVEN0_DATA_SHIFT 0 + +#define SERDES_25G_LANE_DFE_REFCLK_SLICER_OFST_LOAD_VAL_CTRL1_EVEN1_DATA_MASK 0x3F +#define SERDES_25G_LANE_DFE_REFCLK_SLICER_OFST_LOAD_VAL_CTRL1_EVEN1_DATA_SHIFT 0 + +#define SERDES_25G_LANE_DFE_REFCLK_SLICER_OFST_LOAD_VAL_CTRL2_ODD0_DATA_MASK 0x3F +#define SERDES_25G_LANE_DFE_REFCLK_SLICER_OFST_LOAD_VAL_CTRL2_ODD0_DATA_SHIFT 0 + +#define SERDES_25G_LANE_DFE_REFCLK_SLICER_OFST_LOAD_VAL_CTRL3_ODD1_DATA_MASK 0x3F +#define SERDES_25G_LANE_DFE_REFCLK_SLICER_OFST_LOAD_VAL_CTRL3_ODD1_DATA_SHIFT 0 + +#define SERDES_25G_LANE_DFE_REFCLK_SLICER_OFST_LOAD_VAL_CTRL4_EVEN_EDGE_MASK 0x3F +#define SERDES_25G_LANE_DFE_REFCLK_SLICER_OFST_LOAD_VAL_CTRL4_EVEN_EDGE_SHIFT 0 + +#define SERDES_25G_LANE_DFE_REFCLK_SLICER_OFST_LOAD_VAL_CTRL5_ODD_EDGE_MASK 0x3F +#define SERDES_25G_LANE_DFE_REFCLK_SLICER_OFST_LOAD_VAL_CTRL5_ODD_EDGE_SHIFT 0 + +#define SERDES_25G_LANE_DFE_REFCLK_SLICER_OFST_LOAD_VAL_CTRL6_EVEN_EYE_MASK 0x3F +#define SERDES_25G_LANE_DFE_REFCLK_SLICER_OFST_LOAD_VAL_CTRL6_EVEN_EYE_SHIFT 0 + +#define SERDES_25G_LANE_DFE_REFCLK_SLICER_OFST_LOAD_VAL_CTRL7_ODD_EYE_MASK 0x3F +#define SERDES_25G_LANE_DFE_REFCLK_SLICER_OFST_LOAD_VAL_CTRL7_ODD_EYE_SHIFT 0 + +#define SERDES_25G_LANE_DFE_REFCLK_SLICER_OFST_VAL_STATUS0_EVEN0_DATA_MASK 0x3F +#define SERDES_25G_LANE_DFE_REFCLK_SLICER_OFST_VAL_STATUS0_EVEN0_DATA_SHIFT 0 + +#define SERDES_25G_LANE_DFE_REFCLK_SLICER_OFST_VAL_STATUS1_EVEN1_DATA_MASK 0x3F +#define SERDES_25G_LANE_DFE_REFCLK_SLICER_OFST_VAL_STATUS1_EVEN1_DATA_SHIFT 0 + +#define SERDES_25G_LANE_DFE_REFCLK_SLICER_OFST_VAL_STATUS2_ODD0_DATA_MASK 0x3F +#define SERDES_25G_LANE_DFE_REFCLK_SLICER_OFST_VAL_STATUS2_ODD0_DATA_SHIFT 0 + +#define SERDES_25G_LANE_DFE_REFCLK_SLICER_OFST_VAL_STATUS3_ODD1_DATA_MASK 0x3F +#define SERDES_25G_LANE_DFE_REFCLK_SLICER_OFST_VAL_STATUS3_ODD1_DATA_SHIFT 0 + +#define SERDES_25G_LANE_DFE_REFCLK_SLICER_OFST_VAL_STATUS4_EVEN_EDGE_MASK 0x3F +#define SERDES_25G_LANE_DFE_REFCLK_SLICER_OFST_VAL_STATUS4_EVEN_EDGE_SHIFT 0 + +#define SERDES_25G_LANE_DFE_REFCLK_SLICER_OFST_VAL_STATUS5_ODD_EDGE_MASK 0x3F +#define SERDES_25G_LANE_DFE_REFCLK_SLICER_OFST_VAL_STATUS5_ODD_EDGE_SHIFT 0 + +#define SERDES_25G_LANE_DFE_REFCLK_SLICER_OFST_VAL_STATUS6_EVEN_EYE_MASK 0x3F +#define SERDES_25G_LANE_DFE_REFCLK_SLICER_OFST_VAL_STATUS6_EVEN_EYE_SHIFT 0 + +#define SERDES_25G_LANE_DFE_REFCLK_SLICER_OFST_VAL_STATUS7_ODD_EYE_MASK 0x3F +#define SERDES_25G_LANE_DFE_REFCLK_SLICER_OFST_VAL_STATUS7_ODD_EYE_SHIFT 0 + +#define SERDES_25G_LANE_DFE_REFCLK_SLICER_OFST_LOAD_SOURCE_CTRL0_EVEN0_DATA_MASK 0x01 +#define SERDES_25G_LANE_DFE_REFCLK_SLICER_OFST_LOAD_SOURCE_CTRL0_EVEN0_DATA_SHIFT 0 + +#define SERDES_25G_LANE_DFE_REFCLK_SLICER_OFST_LOAD_SOURCE_CTRL0_EVEN1_DATA_MASK 0x02 +#define SERDES_25G_LANE_DFE_REFCLK_SLICER_OFST_LOAD_SOURCE_CTRL0_EVEN1_DATA_SHIFT 1 + +#define SERDES_25G_LANE_DFE_REFCLK_SLICER_OFST_LOAD_SOURCE_CTRL0_ODD0_DATA_MASK 0x04 +#define SERDES_25G_LANE_DFE_REFCLK_SLICER_OFST_LOAD_SOURCE_CTRL0_ODD0_DATA_SHIFT 2 + +#define SERDES_25G_LANE_DFE_REFCLK_SLICER_OFST_LOAD_SOURCE_CTRL0_ODD1_DATA_MASK 0x08 +#define SERDES_25G_LANE_DFE_REFCLK_SLICER_OFST_LOAD_SOURCE_CTRL0_ODD1_DATA_SHIFT 3 + +#define SERDES_25G_LANE_DFE_REFCLK_SLICER_OFST_LOAD_SOURCE_CTRL0_EVEN_EDGE_MASK 0x10 +#define SERDES_25G_LANE_DFE_REFCLK_SLICER_OFST_LOAD_SOURCE_CTRL0_EVEN_EDGE_SHIFT 4 + +#define SERDES_25G_LANE_DFE_REFCLK_SLICER_OFST_LOAD_SOURCE_CTRL0_ODD_EDGE_MASK 0x20 +#define SERDES_25G_LANE_DFE_REFCLK_SLICER_OFST_LOAD_SOURCE_CTRL0_ODD_EDGE_SHIFT 5 + +#define SERDES_25G_LANE_DFE_REFCLK_SLICER_OFST_LOAD_SOURCE_CTRL0_EVEN_EYE_MASK 0x40 +#define SERDES_25G_LANE_DFE_REFCLK_SLICER_OFST_LOAD_SOURCE_CTRL0_EVEN_EYE_SHIFT 6 + +#define SERDES_25G_LANE_DFE_REFCLK_SLICER_OFST_LOAD_SOURCE_CTRL0_ODD_EYE_MASK 0x80 +#define SERDES_25G_LANE_DFE_REFCLK_SLICER_OFST_LOAD_SOURCE_CTRL0_ODD_EYE_SHIFT 7 + +#define SERDES_25G_LANE_DFE_REFCLK_SLICER_OFST_STATUS0_ERR_MASK 0x01 +#define SERDES_25G_LANE_DFE_REFCLK_SLICER_OFST_STATUS0_ERR_SHIFT 0 + +#define SERDES_25G_LANE_DFE_REFCLK_SLICER_OFST_STATUS0_INC_MASK 0x02 +#define SERDES_25G_LANE_DFE_REFCLK_SLICER_OFST_STATUS0_INC_SHIFT 1 + +#define SERDES_25G_LANE_DFE_REFCLK_SLICER_OFST_STATUS0_DEC_MASK 0x04 +#define SERDES_25G_LANE_DFE_REFCLK_SLICER_OFST_STATUS0_DEC_SHIFT 2 + +#define SERDES_25G_LANE_DFE_REFCLK_SLICER_OFST_STATUS1_EVEN0_DATA_MASK 0x01 +#define SERDES_25G_LANE_DFE_REFCLK_SLICER_OFST_STATUS1_EVEN0_DATA_SHIFT 0 + +#define SERDES_25G_LANE_DFE_REFCLK_SLICER_OFST_STATUS1_EVEN1_DATA_MASK 0x02 +#define SERDES_25G_LANE_DFE_REFCLK_SLICER_OFST_STATUS1_EVEN1_DATA_SHIFT 1 + +#define SERDES_25G_LANE_DFE_REFCLK_SLICER_OFST_STATUS1_ODD0_DATA_MASK 0x04 +#define SERDES_25G_LANE_DFE_REFCLK_SLICER_OFST_STATUS1_ODD0_DATA_SHIFT 2 + +#define SERDES_25G_LANE_DFE_REFCLK_SLICER_OFST_STATUS1_ODD1_DATA_MASK 0x08 +#define SERDES_25G_LANE_DFE_REFCLK_SLICER_OFST_STATUS1_ODD1_DATA_SHIFT 3 + +#define SERDES_25G_LANE_DFE_REFCLK_SLICER_OFST_STATUS1_EVEN_EDGE_MASK 0x10 +#define SERDES_25G_LANE_DFE_REFCLK_SLICER_OFST_STATUS1_EVEN_EDGE_SHIFT 4 + +#define SERDES_25G_LANE_DFE_REFCLK_SLICER_OFST_STATUS1_ODD_EDGE_MASK 0x20 +#define SERDES_25G_LANE_DFE_REFCLK_SLICER_OFST_STATUS1_ODD_EDGE_SHIFT 5 + +#define SERDES_25G_LANE_DFE_REFCLK_SLICER_OFST_STATUS1_EVEN_EYE_MASK 0x40 +#define SERDES_25G_LANE_DFE_REFCLK_SLICER_OFST_STATUS1_EVEN_EYE_SHIFT 6 + +#define SERDES_25G_LANE_DFE_REFCLK_SLICER_OFST_STATUS1_ODD_EYE_MASK 0x80 +#define SERDES_25G_LANE_DFE_REFCLK_SLICER_OFST_STATUS1_ODD_EYE_SHIFT 7 + +/********************************** LOS REFCLK **********************************/ +#define SERDES_25G_LANE_LOS_REFCLK_BASE 0x500 + +#define SERDES_25G_LANE_LOS_REFCLK_RUN_LENGTH_CTRL0_ADDR (SERDES_25G_LANE_LOS_REFCLK_BASE + 0x00) +#define SERDES_25G_LANE_LOS_REFCLK_RUN_LENGTH_CTRL1_ADDR (SERDES_25G_LANE_LOS_REFCLK_BASE + 0x01) +#define SERDES_25G_LANE_LOS_REFCLK_RUN_LENGTH_STATUS0_ADDR (SERDES_25G_LANE_LOS_REFCLK_BASE + 0x02) +#define SERDES_25G_LANE_LOS_REFCLK_FILTER_CTRL0_ADDR (SERDES_25G_LANE_LOS_REFCLK_BASE + 0x10) +#define SERDES_25G_LANE_LOS_REFCLK_FILTER_CTRL1_ADDR (SERDES_25G_LANE_LOS_REFCLK_BASE + 0x11) +#define SERDES_25G_LANE_LOS_REFCLK_FILTER_CTRL2_ADDR (SERDES_25G_LANE_LOS_REFCLK_BASE + 0x12) +#define SERDES_25G_LANE_LOS_REFCLK_FILTER_CTRL3_ADDR (SERDES_25G_LANE_LOS_REFCLK_BASE + 0x13) +#define SERDES_25G_LANE_LOS_REFCLK_FILTER_CTRL4_ADDR (SERDES_25G_LANE_LOS_REFCLK_BASE + 0x14) +#define SERDES_25G_LANE_LOS_REFCLK_FILTER_CTRL5_ADDR (SERDES_25G_LANE_LOS_REFCLK_BASE + 0x15) +#define SERDES_25G_LANE_LOS_REFCLK_FILTER_CTRL6_ADDR (SERDES_25G_LANE_LOS_REFCLK_BASE + 0x16) +#define SERDES_25G_LANE_LOS_REFCLK_TIMED_MODE_CTRL0_ADDR (SERDES_25G_LANE_LOS_REFCLK_BASE + 0x20) +#define SERDES_25G_LANE_LOS_REFCLK_TIMED_MODE_CTRL1_ADDR (SERDES_25G_LANE_LOS_REFCLK_BASE + 0x21) +#define SERDES_25G_LANE_LOS_REFCLK_TIMED_MODE_CTRL2_ADDR (SERDES_25G_LANE_LOS_REFCLK_BASE + 0x22) +#define SERDES_25G_LANE_LOS_REFCLK_TIMED_MODE_CTRL3_ADDR (SERDES_25G_LANE_LOS_REFCLK_BASE + 0x23) +#define SERDES_25G_LANE_LOS_REFCLK_TIMED_MODE_CTRL4_ADDR (SERDES_25G_LANE_LOS_REFCLK_BASE + 0x24) +#define SERDES_25G_LANE_LOS_REFCLK_OVERRIDE_CTRL0_ADDR (SERDES_25G_LANE_LOS_REFCLK_BASE + 0x30) +#define SERDES_25G_LANE_LOS_REFCLK_OVERRIDE_CTRL1_ADDR (SERDES_25G_LANE_LOS_REFCLK_BASE + 0x31) +#define SERDES_25G_LANE_LOS_REFCLK_OVERRIDE_CTRL2_ADDR (SERDES_25G_LANE_LOS_REFCLK_BASE + 0x32) +#define SERDES_25G_LANE_LOS_REFCLK_OVERRIDE_CTRL3_ADDR (SERDES_25G_LANE_LOS_REFCLK_BASE + 0x33) +#define SERDES_25G_LANE_LOS_REFCLK_COMPARATOR_CTRL0_ADDR (SERDES_25G_LANE_LOS_REFCLK_BASE + 0x40) +#define SERDES_25G_LANE_LOS_REFCLK_COMPARATOR_CTRL1_ADDR (SERDES_25G_LANE_LOS_REFCLK_BASE + 0x41) +#define SERDES_25G_LANE_LOS_REFCLK_COMPARATOR_CTRL2_ADDR (SERDES_25G_LANE_LOS_REFCLK_BASE + 0x42) +#define SERDES_25G_LANE_LOS_REFCLK_COMPARATOR_CTRL3_ADDR (SERDES_25G_LANE_LOS_REFCLK_BASE + 0x43) +#define SERDES_25G_LANE_LOS_REFCLK_EYE_CTRL_ADDR (SERDES_25G_LANE_LOS_REFCLK_BASE + 0x46) +#define SERDES_25G_LANE_LOS_REFCLK_CALIBRATION_CTRL0_ADDR (SERDES_25G_LANE_LOS_REFCLK_BASE + 0x51) +#define SERDES_25G_LANE_LOS_REFCLK_CALIBRATION_STATUS0_ADDR (SERDES_25G_LANE_LOS_REFCLK_BASE + 0x59) +#define SERDES_25G_LANE_LOS_REFCLK_CALIBRATION_STATUS1_ADDR (SERDES_25G_LANE_LOS_REFCLK_BASE + 0x60) +#define SERDES_25G_LANE_LOS_REFCLK_CTRL0_ADDR (SERDES_25G_LANE_LOS_REFCLK_BASE + 0x70) +#define SERDES_25G_LANE_LOS_REFCLK_STATUS0_ADDR (SERDES_25G_LANE_LOS_REFCLK_BASE + 0x71) +#define SERDES_25G_LANE_LOS_REFCLK_AFE_SPARE_CTRL0_ADDR (SERDES_25G_LANE_LOS_REFCLK_BASE + 0x72) +#define SERDES_25G_LANE_LOS_REFCLK_AFE_PD_CTRL0_ADDR (SERDES_25G_LANE_LOS_REFCLK_BASE + 0x73) +/******************************************************************************* + * masks and shifts + ******************************************************************************/ + +#define SERDES_25G_LANE_LOS_REFCLK_RUN_LENGTH_CTRL0_EN_MASK 0x01 +#define SERDES_25G_LANE_LOS_REFCLK_RUN_LENGTH_CTRL0_EN_SHIFT 0 + +#define SERDES_25G_LANE_LOS_REFCLK_RUN_LENGTH_CTRL1_ASSERT_THRESHOLD_MASK 0xFF +#define SERDES_25G_LANE_LOS_REFCLK_RUN_LENGTH_CTRL1_ASSERT_THRESHOLD_SHIFT 0 + +#define SERDES_25G_LANE_LOS_REFCLK_RUN_LENGTH_STATUS0_EXCEED_MASK 0x01 +#define SERDES_25G_LANE_LOS_REFCLK_RUN_LENGTH_STATUS0_EXCEED_SHIFT 0 + +#define SERDES_25G_LANE_LOS_REFCLK_RUN_LENGTH_STATUS0_EXCEED_STICKY_MASK 0x02 +#define SERDES_25G_LANE_LOS_REFCLK_RUN_LENGTH_STATUS0_EXCEED_STICKY_SHIFT 1 + +#define SERDES_25G_LANE_LOS_REFCLK_FILTER_CTRL0_ASSERT_THRESHOLD_7_0_MASK 0xFF +#define SERDES_25G_LANE_LOS_REFCLK_FILTER_CTRL0_ASSERT_THRESHOLD_7_0_SHIFT 0 + +#define SERDES_25G_LANE_LOS_REFCLK_FILTER_CTRL1_ASSERT_THRESHOLD_15_8_MASK 0xFF +#define SERDES_25G_LANE_LOS_REFCLK_FILTER_CTRL1_ASSERT_THRESHOLD_15_8_SHIFT 0 + +#define SERDES_25G_LANE_LOS_REFCLK_FILTER_CTRL2_DEASSERT_THRESHOLD_7_0_MASK 0xFF +#define SERDES_25G_LANE_LOS_REFCLK_FILTER_CTRL2_DEASSERT_THRESHOLD_7_0_SHIFT 0 + +#define SERDES_25G_LANE_LOS_REFCLK_FILTER_CTRL3_DEASSERT_THRESHOLD_15_8_MASK 0xFF +#define SERDES_25G_LANE_LOS_REFCLK_FILTER_CTRL3_DEASSERT_THRESHOLD_15_8_SHIFT 0 + +#define SERDES_25G_LANE_LOS_REFCLK_FILTER_CTRL4_DEASSERT_THRESHOLD_23_16_MASK 0xFF +#define SERDES_25G_LANE_LOS_REFCLK_FILTER_CTRL4_DEASSERT_THRESHOLD_23_16_SHIFT 0 + +#define SERDES_25G_LANE_LOS_REFCLK_FILTER_CTRL5_DEASSERT_THRESHOLD_25_24_MASK 0x03 +#define SERDES_25G_LANE_LOS_REFCLK_FILTER_CTRL5_DEASSERT_THRESHOLD_25_24_SHIFT 0 + +#define SERDES_25G_LANE_LOS_REFCLK_FILTER_CTRL6_EN_MASK 0x01 +#define SERDES_25G_LANE_LOS_REFCLK_FILTER_CTRL6_EN_SHIFT 0 + +#define SERDES_25G_LANE_LOS_REFCLK_TIMED_MODE_CTRL0_EN_MASK 0x01 +#define SERDES_25G_LANE_LOS_REFCLK_TIMED_MODE_CTRL0_EN_SHIFT 0 + +#define SERDES_25G_LANE_LOS_REFCLK_TIMED_MODE_CTRL1_PERIOD_7_0_MASK 0xFF +#define SERDES_25G_LANE_LOS_REFCLK_TIMED_MODE_CTRL1_PERIOD_7_0_SHIFT 0 + +#define SERDES_25G_LANE_LOS_REFCLK_TIMED_MODE_CTRL2_PERIOD_15_8_MASK 0xFF +#define SERDES_25G_LANE_LOS_REFCLK_TIMED_MODE_CTRL2_PERIOD_15_8_SHIFT 0 + +#define SERDES_25G_LANE_LOS_REFCLK_TIMED_MODE_CTRL3_PERIOD_23_16_MASK 0xFF +#define SERDES_25G_LANE_LOS_REFCLK_TIMED_MODE_CTRL3_PERIOD_23_16_SHIFT 0 + +#define SERDES_25G_LANE_LOS_REFCLK_TIMED_MODE_CTRL4_PERIOD_25_24_MASK 0x03 +#define SERDES_25G_LANE_LOS_REFCLK_TIMED_MODE_CTRL4_PERIOD_25_24_SHIFT 0 + +#define SERDES_25G_LANE_LOS_REFCLK_OVERRIDE_CTRL0_LOS_O_EN_MASK 0x01 +#define SERDES_25G_LANE_LOS_REFCLK_OVERRIDE_CTRL0_LOS_O_EN_SHIFT 0 + +#define SERDES_25G_LANE_LOS_REFCLK_OVERRIDE_CTRL0_LOS_O_VALUE_MASK 0x10 +#define SERDES_25G_LANE_LOS_REFCLK_OVERRIDE_CTRL0_LOS_O_VALUE_SHIFT 4 + +#define SERDES_25G_LANE_LOS_REFCLK_OVERRIDE_CTRL1_LOS_I_EN_MASK 0x01 +#define SERDES_25G_LANE_LOS_REFCLK_OVERRIDE_CTRL1_LOS_I_EN_SHIFT 0 + +#define SERDES_25G_LANE_LOS_REFCLK_OVERRIDE_CTRL1_LOS_I_VALUE_MASK 0x10 +#define SERDES_25G_LANE_LOS_REFCLK_OVERRIDE_CTRL1_LOS_I_VALUE_SHIFT 4 + +#define SERDES_25G_LANE_LOS_REFCLK_OVERRIDE_CTRL2_LOS_OFFSET_VALUE_MASK 0x3F +#define SERDES_25G_LANE_LOS_REFCLK_OVERRIDE_CTRL2_LOS_OFFSET_VALUE_SHIFT 0 + +#define SERDES_25G_LANE_LOS_REFCLK_OVERRIDE_CTRL2_LOS_OFFSET_EN_MASK 0x40 +#define SERDES_25G_LANE_LOS_REFCLK_OVERRIDE_CTRL2_LOS_OFFSET_EN_SHIFT 6 + +#define SERDES_25G_LANE_LOS_REFCLK_OVERRIDE_CTRL3_AGC_OFFSET_VALUE_MASK 0x3F +#define SERDES_25G_LANE_LOS_REFCLK_OVERRIDE_CTRL3_AGC_OFFSET_VALUE_SHIFT 0 + +#define SERDES_25G_LANE_LOS_REFCLK_OVERRIDE_CTRL3_AGC_OFFSET_EN_MASK 0x40 +#define SERDES_25G_LANE_LOS_REFCLK_OVERRIDE_CTRL3_AGC_OFFSET_EN_SHIFT 6 + +#define SERDES_25G_LANE_LOS_REFCLK_COMPARATOR_CTRL0_BANDWIDTH_MASK 0x01 +#define SERDES_25G_LANE_LOS_REFCLK_COMPARATOR_CTRL0_BANDWIDTH_SHIFT 0 + +#define SERDES_25G_LANE_LOS_REFCLK_COMPARATOR_CTRL0_HYSTERESIS_MASK 0x0E +#define SERDES_25G_LANE_LOS_REFCLK_COMPARATOR_CTRL0_HYSTERESIS_SHIFT 1 + +#define SERDES_25G_LANE_LOS_REFCLK_COMPARATOR_CTRL0_ENVDET_BYP_MASK 0x10 +#define SERDES_25G_LANE_LOS_REFCLK_COMPARATOR_CTRL0_ENVDET_BYP_SHIFT 4 + +#define SERDES_25G_LANE_LOS_REFCLK_COMPARATOR_CTRL1_GAIN_MASK 0x01 +#define SERDES_25G_LANE_LOS_REFCLK_COMPARATOR_CTRL1_GAIN_SHIFT 0 + +#define SERDES_25G_LANE_LOS_REFCLK_COMPARATOR_CTRL1_LOS_INVERT_MASK 0x02 +#define SERDES_25G_LANE_LOS_REFCLK_COMPARATOR_CTRL1_LOS_INVERT_SHIFT 1 + +#define SERDES_25G_LANE_LOS_REFCLK_COMPARATOR_CTRL1_AGC_INVERT_MASK 0x04 +#define SERDES_25G_LANE_LOS_REFCLK_COMPARATOR_CTRL1_AGC_INVERT_SHIFT 2 + +#define SERDES_25G_LANE_LOS_REFCLK_COMPARATOR_CTRL1_THRESHOLD_MASK 0x78 +#define SERDES_25G_LANE_LOS_REFCLK_COMPARATOR_CTRL1_THRESHOLD_SHIFT 3 + +#define SERDES_25G_LANE_LOS_REFCLK_COMPARATOR_CTRL2_MODE_SWITCH_WAIT_7_0_MASK 0xFF +#define SERDES_25G_LANE_LOS_REFCLK_COMPARATOR_CTRL2_MODE_SWITCH_WAIT_7_0_SHIFT 0 + +#define SERDES_25G_LANE_LOS_REFCLK_COMPARATOR_CTRL3_MODE_SWITCH_WAIT_15_8_MASK 0xFF +#define SERDES_25G_LANE_LOS_REFCLK_COMPARATOR_CTRL3_MODE_SWITCH_WAIT_15_8_SHIFT 0 + +#define SERDES_25G_LANE_LOS_REFCLK_EYE_CTRL_EYE_DATA_PARITY_MASK 0x01 +#define SERDES_25G_LANE_LOS_REFCLK_EYE_CTRL_EYE_DATA_PARITY_SHIFT 0 + +#define SERDES_25G_LANE_LOS_REFCLK_CALIBRATION_CTRL0_EN_MASK 0x01 +#define SERDES_25G_LANE_LOS_REFCLK_CALIBRATION_CTRL0_EN_SHIFT 0 + +#define SERDES_25G_LANE_LOS_REFCLK_CALIBRATION_CTRL0_MODE_MASK 0x02 +#define SERDES_25G_LANE_LOS_REFCLK_CALIBRATION_CTRL0_MODE_SHIFT 1 + +#define SERDES_25G_LANE_LOS_REFCLK_CALIBRATION_STATUS0_LOS_OFFSET_MASK 0x3F +#define SERDES_25G_LANE_LOS_REFCLK_CALIBRATION_STATUS0_LOS_OFFSET_SHIFT 0 + +#define SERDES_25G_LANE_LOS_REFCLK_CALIBRATION_STATUS1_AGC_CALIB_DONE_MASK 0x40 +#define SERDES_25G_LANE_LOS_REFCLK_CALIBRATION_STATUS1_AGC_CALIB_DONE_SHIFT 6 + +#define SERDES_25G_LANE_LOS_REFCLK_CTRL0_EN_MASK 0x01 +#define SERDES_25G_LANE_LOS_REFCLK_CTRL0_EN_SHIFT 0 + +#define SERDES_25G_LANE_FEATURE_CTRL0_SRC_SELECT_MASK 0x02 +#define SERDES_25G_LANE_FEATURE_CTRL0_SRC_SELECT_SHIFT 1 + +#define SERDES_25G_LANE_LOS_REFCLK_STATUS0_LOS_READY_MASK 0x01 +#define SERDES_25G_LANE_LOS_REFCLK_STATUS0_LOS_READY_SHIFT 0 + +#define SERDES_25G_LANE_LOS_REFCLK_STATUS0_AGC_READY_MASK 0x02 +#define SERDES_25G_LANE_LOS_REFCLK_STATUS0_AGC_READY_SHIFT 1 + +#define SERDES_25G_LANE_LOS_REFCLK_STATUS0_LOS_MASK 0x04 +#define SERDES_25G_LANE_LOS_REFCLK_STATUS0_LOS_SHIFT 2 + +#define SERDES_25G_LANE_LOS_REFCLK_STATUS0_LOS_RAW_MASK 0x08 +#define SERDES_25G_LANE_LOS_REFCLK_STATUS0_LOS_RAW_SHIFT 3 + +#define SERDES_25G_LANE_LOS_REFCLK_STATUS0_AGC_MASK 0x10 +#define SERDES_25G_LANE_LOS_REFCLK_STATUS0_AGC_SHIFT 4 + +#define SERDES_25G_LANE_LOS_REFCLK_AFE_SPARE_CTRL0_RXLOS_SPARE_MASK 0x0F +#define SERDES_25G_LANE_LOS_REFCLK_AFE_SPARE_CTRL0_RXLOS_SPARE_SHIFT 0 + +#define SERDES_25G_LANE_LOS_REFCLK_AFE_PD_CTRL0_PD_RXLOS_MASK 0x01 +#define SERDES_25G_LANE_LOS_REFCLK_AFE_PD_CTRL0_PD_RXLOS_SHIFT 0 + +#define SERDES_25G_LANE_LOS_REFCLK_CALIBRATION_CTRL6_REQ_MASK 0x01 +#define SERDES_25G_LANE_LOS_REFCLK_CALIBRATION_CTRL6_REQ_SHIFT 0 + +#define SERDES_25G_LANE_LOS_REFCLK_CALIBRATION_STATUS2_ACK_MASK 0x01 +#define SERDES_25G_LANE_LOS_REFCLK_CALIBRATION_STATUS2_ACK_SHIFT 0 + +/********************************** GCFSM2 **********************************/ +#define SERDES_25G_LANE_GCFSM2_BASE 0x580 + +#define SERDES_25G_LANE_GCFSM2_CMD_CTRL0_ADDR (SERDES_25G_LANE_GCFSM2_BASE + 0x00) +#define SERDES_25G_LANE_GCFSM2_CMD_CTRL1_ADDR (SERDES_25G_LANE_GCFSM2_BASE + 0x01) +#define SERDES_25G_LANE_GCFSM2_CMD_CTRL2_ADDR (SERDES_25G_LANE_GCFSM2_BASE + 0x02) +#define SERDES_25G_LANE_GCFSM2_CMD_STATUS_ADDR (SERDES_25G_LANE_GCFSM2_BASE + 0x03) +#define SERDES_25G_LANE_GCFSM2_READ_SHADOW_DATA_STATUS0_ADDR (SERDES_25G_LANE_GCFSM2_BASE + 0x10) +#define SERDES_25G_LANE_GCFSM2_READ_SHADOW_DATA_STATUS1_ADDR (SERDES_25G_LANE_GCFSM2_BASE + 0x11) +#define SERDES_25G_LANE_GCFSM2_AVG_UP_CNT_STATUS0_ADDR (SERDES_25G_LANE_GCFSM2_BASE + 0x12) +#define SERDES_25G_LANE_GCFSM2_AVG_UP_CNT_STATUS1_ADDR (SERDES_25G_LANE_GCFSM2_BASE + 0x13) +#define SERDES_25G_LANE_GCFSM2_DATA_CTRL0_ADDR (SERDES_25G_LANE_GCFSM2_BASE + 0x20) +#define SERDES_25G_LANE_GCFSM2_DATA_CTRL1_ADDR (SERDES_25G_LANE_GCFSM2_BASE + 0x21) +#define SERDES_25G_LANE_GCFSM2_DATA_CTRL2_ADDR (SERDES_25G_LANE_GCFSM2_BASE + 0x22) +#define SERDES_25G_LANE_GCFSM2_DATA_CTRL3_ADDR (SERDES_25G_LANE_GCFSM2_BASE + 0x23) +#define SERDES_25G_LANE_GCFSM2_DATA_CTRL4_ADDR (SERDES_25G_LANE_GCFSM2_BASE + 0x24) +#define SERDES_25G_LANE_GCFSM2_DATA_CTRL5_ADDR (SERDES_25G_LANE_GCFSM2_BASE + 0x25) +#define SERDES_25G_LANE_GCFSM2_DATA_CTRL6_ADDR (SERDES_25G_LANE_GCFSM2_BASE + 0x26) +#define SERDES_25G_LANE_GCFSM2_PARAMETER_CTRL0_ADDR (SERDES_25G_LANE_GCFSM2_BASE + 0x30) +#define SERDES_25G_LANE_GCFSM2_PARAMETER_CTRL1_ADDR (SERDES_25G_LANE_GCFSM2_BASE + 0x31) +#define SERDES_25G_LANE_GCFSM2_PARAMETER_CTRL2_ADDR (SERDES_25G_LANE_GCFSM2_BASE + 0x32) +#define SERDES_25G_LANE_GCFSM2_WAIT_CTRL0_ADDR (SERDES_25G_LANE_GCFSM2_BASE + 0x40) +#define SERDES_25G_LANE_GCFSM2_WAIT_CTRL1_ADDR (SERDES_25G_LANE_GCFSM2_BASE + 0x41) +#define SERDES_25G_LANE_GCFSM2_WAIT_CTRL2_ADDR (SERDES_25G_LANE_GCFSM2_BASE + 0x42) +#define SERDES_25G_LANE_GCFSM2_WAIT_CTRL3_ADDR (SERDES_25G_LANE_GCFSM2_BASE + 0x43) +#define SERDES_25G_LANE_GCFSM2_WAIT_CTRL4_ADDR (SERDES_25G_LANE_GCFSM2_BASE + 0x44) +#define SERDES_25G_LANE_GCFSM2_WAIT_CTRL5_ADDR (SERDES_25G_LANE_GCFSM2_BASE + 0x45) +#define SERDES_25G_LANE_GCFSM2_WAIT_CTRL6_ADDR (SERDES_25G_LANE_GCFSM2_BASE + 0x46) +#define SERDES_25G_LANE_GCFSM2_WAIT_CTRL7_ADDR (SERDES_25G_LANE_GCFSM2_BASE + 0x47) +#define SERDES_25G_LANE_GCFSM2_WAIT_CTRL8_ADDR (SERDES_25G_LANE_GCFSM2_BASE + 0x48) +#define SERDES_25G_LANE_GCFSM2_FEEDBACK_CTRL0_ADDR (SERDES_25G_LANE_GCFSM2_BASE + 0x50) +#define SERDES_25G_LANE_GCFSM2_FEEDBACK_CTRL1_ADDR (SERDES_25G_LANE_GCFSM2_BASE + 0x51) +/******************************************************************************* + * masks and shifts + ******************************************************************************/ +#define SERDES_25G_LANE_GCFSM2_CMD_CTRL0_REQ_MASK 0x01 +#define SERDES_25G_LANE_GCFSM2_CMD_CTRL0_REQ_SHIFT 0 + +#define SERDES_25G_LANE_GCFSM2_CMD_CTRL1_CMD_MASK 0x07 +#define SERDES_25G_LANE_GCFSM2_CMD_CTRL1_CMD_SHIFT 0 + +#define SERDES_25G_LANE_GCFSM2_CMD_CTRL2_ADDR_MASK 0xFF +#define SERDES_25G_LANE_GCFSM2_CMD_CTRL2_ADDR_SHIFT 0 + +#define SERDES_25G_LANE_GCFSM2_CMD_STATUS_ACK_MASK 0x01 +#define SERDES_25G_LANE_GCFSM2_CMD_STATUS_ACK_SHIFT 0 + +#define SERDES_25G_LANE_GCFSM2_CMD_STATUS_CODE_MASK 0x1E +#define SERDES_25G_LANE_GCFSM2_CMD_STATUS_CODE_SHIFT 1 + +#define SERDES_25G_LANE_GCFSM2_READ_SHADOW_DATA_STATUS0_7_0_MASK 0xFF +#define SERDES_25G_LANE_GCFSM2_READ_SHADOW_DATA_STATUS0_7_0_SHIFT 0 + +#define SERDES_25G_LANE_GCFSM2_READ_SHADOW_DATA_STATUS1_11_8_MASK 0x0F +#define SERDES_25G_LANE_GCFSM2_READ_SHADOW_DATA_STATUS1_11_8_SHIFT 0 + +#define SERDES_25G_LANE_GCFSM2_AVG_UP_CNT_STATUS0_7_0_MASK 0xFF +#define SERDES_25G_LANE_GCFSM2_AVG_UP_CNT_STATUS0_7_0_SHIFT 0 + +#define SERDES_25G_LANE_GCFSM2_AVG_UP_CNT_STATUS1_8_8_MASK 0x01 +#define SERDES_25G_LANE_GCFSM2_AVG_UP_CNT_STATUS1_8_8_SHIFT 0 + +#define SERDES_25G_LANE_GCFSM2_DATA_CTRL0_TYPE_MASK 0x03 +#define SERDES_25G_LANE_GCFSM2_DATA_CTRL0_TYPE_SHIFT 0 + +#define SERDES_25G_LANE_GCFSM2_DATA_CTRL0_WIDTH_MASK 0x3C +#define SERDES_25G_LANE_GCFSM2_DATA_CTRL0_WIDTH_SHIFT 2 + +#define SERDES_25G_LANE_GCFSM2_DATA_CTRL1_START_7_0_MASK 0xFF +#define SERDES_25G_LANE_GCFSM2_DATA_CTRL1_START_7_0_SHIFT 0 + +#define SERDES_25G_LANE_GCFSM2_DATA_CTRL2_START_11_8_MASK 0x0F +#define SERDES_25G_LANE_GCFSM2_DATA_CTRL2_START_11_8_SHIFT 0 + +#define SERDES_25G_LANE_GCFSM2_DATA_CTRL3_MIN_7_0_MASK 0xFF +#define SERDES_25G_LANE_GCFSM2_DATA_CTRL3_MIN_7_0_SHIFT 0 + +#define SERDES_25G_LANE_GCFSM2_DATA_CTRL4_MIN_11_8_MASK 0x0F +#define SERDES_25G_LANE_GCFSM2_DATA_CTRL4_MIN_11_8_SHIFT 0 + +#define SERDES_25G_LANE_GCFSM2_DATA_CTRL5_MAX_7_0_MASK 0xFF +#define SERDES_25G_LANE_GCFSM2_DATA_CTRL5_MAX_7_0_SHIFT 0 + +#define SERDES_25G_LANE_GCFSM2_DATA_CTRL6_MAX_11_8_MASK 0x0F +#define SERDES_25G_LANE_GCFSM2_DATA_CTRL6_MAX_11_8_SHIFT 0 + +#define SERDES_25G_LANE_GCFSM2_PARAMETER_CTRL0_STEP_SIZE_MASK 0x1F +#define SERDES_25G_LANE_GCFSM2_PARAMETER_CTRL0_STEP_SIZE_SHIFT 0 + +#define SERDES_25G_LANE_GCFSM2_PARAMETER_CTRL1_BOUNCE_NUM_MASK 0x0F +#define SERDES_25G_LANE_GCFSM2_PARAMETER_CTRL1_BOUNCE_NUM_SHIFT 0 + +#define SERDES_25G_LANE_GCFSM2_PARAMETER_CTRL1_COARSE_BOUNCE_NUM_MASK 0xF0 +#define SERDES_25G_LANE_GCFSM2_PARAMETER_CTRL1_COARSE_BOUNCE_NUM_SHIFT 4 + +#define SERDES_25G_LANE_GCFSM2_PARAMETER_CTRL2_SETTLE_ON_LOWEST_AVG_EN_MASK 0x01 +#define SERDES_25G_LANE_GCFSM2_PARAMETER_CTRL2_SETTLE_ON_LOWEST_AVG_EN_SHIFT 0 + +#define SERDES_25G_LANE_GCFSM2_WAIT_CTRL0_LEN_DELAY_AFE_EN_MASK 0x03 +#define SERDES_25G_LANE_GCFSM2_WAIT_CTRL0_LEN_DELAY_AFE_EN_SHIFT 0 + +#define SERDES_25G_LANE_GCFSM2_WAIT_CTRL1_LEN_AFE_1ST_LATCH_SETTLE_7_0_MASK 0xFF +#define SERDES_25G_LANE_GCFSM2_WAIT_CTRL1_LEN_AFE_1ST_LATCH_SETTLE_7_0_SHIFT 0 + +#define SERDES_25G_LANE_GCFSM2_WAIT_CTRL2_LEN_AFE_1ST_LATCH_SETTLE_15_8_MASK 0xFF +#define SERDES_25G_LANE_GCFSM2_WAIT_CTRL2_LEN_AFE_1ST_LATCH_SETTLE_15_8_SHIFT 0 + +#define SERDES_25G_LANE_GCFSM2_WAIT_CTRL3_LEN_AFE_LATCH_SETTLE_MASK 0xFF +#define SERDES_25G_LANE_GCFSM2_WAIT_CTRL3_LEN_AFE_LATCH_SETTLE_SHIFT 0 + +#define SERDES_25G_LANE_GCFSM2_WAIT_CTRL4_LEN_AFE_CMP_7_0_MASK 0xFF +#define SERDES_25G_LANE_GCFSM2_WAIT_CTRL4_LEN_AFE_CMP_7_0_SHIFT 0 + +#define SERDES_25G_LANE_GCFSM2_WAIT_CTRL5_LEN_AFE_CMP_15_8_MASK 0xFF +#define SERDES_25G_LANE_GCFSM2_WAIT_CTRL5_LEN_AFE_CMP_15_8_SHIFT 0 + +#define SERDES_25G_LANE_GCFSM2_WAIT_CTRL6_LEN_COARSE_BOUNCE_AFE_CMP_7_0_MASK 0xFF +#define SERDES_25G_LANE_GCFSM2_WAIT_CTRL6_LEN_COARSE_BOUNCE_AFE_CMP_7_0_SHIFT 0 + +#define SERDES_25G_LANE_GCFSM2_WAIT_CTRL7_LEN_COARSE_BOUNCE_AFE_CMP_15_8_MASK 0xFF +#define SERDES_25G_LANE_GCFSM2_WAIT_CTRL7_LEN_COARSE_BOUNCE_AFE_CMP_15_8_SHIFT 0 + +#define SERDES_25G_LANE_GCFSM2_WAIT_CTRL8_WAIT_MODE_MASK 0x01 +#define SERDES_25G_LANE_GCFSM2_WAIT_CTRL8_WAIT_MODE_SHIFT 0 + +#define SERDES_25G_LANE_GCFSM2_FEEDBACK_CTRL0_INVERT_AFE_UP_MASK 0x01 +#define SERDES_25G_LANE_GCFSM2_FEEDBACK_CTRL0_INVERT_AFE_UP_SHIFT 0 + +#define SERDES_25G_LANE_GCFSM2_FEEDBACK_CTRL0_LEN_WAIT_AFE_UP_MASK 0x1E +#define SERDES_25G_LANE_GCFSM2_FEEDBACK_CTRL0_LEN_WAIT_AFE_UP_SHIFT 1 + +#define SERDES_25G_LANE_GCFSM2_FEEDBACK_CTRL1_LEN_AVG_AFE_UP_MASK 0xFF +#define SERDES_25G_LANE_GCFSM2_FEEDBACK_CTRL1_LEN_AVG_AFE_UP_SHIFT 0 + +/********************************** TX BIST **********************************/ +#define SERDES_25G_LANE_TX_BIST_BASE 0x600 + +#define SERDES_25G_LANE_TX_BIST_CTRL_ADDR (SERDES_25G_LANE_TX_BIST_BASE + 0x00) +#define SERDES_25G_LANE_TX_BIST_BER_CTRL0_ADDR (SERDES_25G_LANE_TX_BIST_BASE + 0x04) +#define SERDES_25G_LANE_TX_BIST_BER_CTRL1_ADDR (SERDES_25G_LANE_TX_BIST_BASE + 0x05) +#define SERDES_25G_LANE_TX_BIST_BER_CTRL2_ADDR (SERDES_25G_LANE_TX_BIST_BASE + 0x06) +#define SERDES_25G_LANE_TX_BIST_BER_CTRL3_ADDR (SERDES_25G_LANE_TX_BIST_BASE + 0x07) +#define SERDES_25G_LANE_TX_BIST_BER_CTRL4_ADDR (SERDES_25G_LANE_TX_BIST_BASE + 0x08) +#define SERDES_25G_LANE_TX_BIST_BER_CTRL5_ADDR (SERDES_25G_LANE_TX_BIST_BASE + 0x09) +#define SERDES_25G_LANE_TX_BIST_BER_CTRL6_ADDR (SERDES_25G_LANE_TX_BIST_BASE + 0x0A) +#define SERDES_25G_LANE_TX_BIST_BER_CTRL7_ADDR (SERDES_25G_LANE_TX_BIST_BASE + 0x0B) +#define SERDES_25G_LANE_TX_BIST_UDP_SHIFT_AMOUNT_ADDR (SERDES_25G_LANE_TX_BIST_BASE + 0x20) +#define SERDES_25G_LANE_TX_BIST_UDP_ADDR(byte_num) \ + ((SERDES_25G_LANE_TX_BIST_BASE + 0x24) + byte_num) +#define SERDES_25G_LANE_TX_BIST_UDP_NUM_BYTES 20 +#define SERDES_25G_LANE_TX_BIST_UDP_7_0_ADDR (SERDES_25G_LANE_TX_BIST_BASE + 0x24) +#define SERDES_25G_LANE_TX_BIST_UDP_15_8_ADDR (SERDES_25G_LANE_TX_BIST_BASE + 0x25) +#define SERDES_25G_LANE_TX_BIST_UDP_23_16_ADDR (SERDES_25G_LANE_TX_BIST_BASE + 0x26) +#define SERDES_25G_LANE_TX_BIST_UDP_31_24_ADDR (SERDES_25G_LANE_TX_BIST_BASE + 0x27) +#define SERDES_25G_LANE_TX_BIST_UDP_39_32_ADDR (SERDES_25G_LANE_TX_BIST_BASE + 0x28) +#define SERDES_25G_LANE_TX_BIST_UDP_47_40_ADDR (SERDES_25G_LANE_TX_BIST_BASE + 0x29) +#define SERDES_25G_LANE_TX_BIST_UDP_55_48_ADDR (SERDES_25G_LANE_TX_BIST_BASE + 0x2A) +#define SERDES_25G_LANE_TX_BIST_UDP_63_56_ADDR (SERDES_25G_LANE_TX_BIST_BASE + 0x2B) +#define SERDES_25G_LANE_TX_BIST_UDP_71_64_ADDR (SERDES_25G_LANE_TX_BIST_BASE + 0x2C) +#define SERDES_25G_LANE_TX_BIST_UDP_79_72_ADDR (SERDES_25G_LANE_TX_BIST_BASE + 0x2D) +#define SERDES_25G_LANE_TX_BIST_UDP_87_80_ADDR (SERDES_25G_LANE_TX_BIST_BASE + 0x2E) +#define SERDES_25G_LANE_TX_BIST_UDP_95_88_ADDR (SERDES_25G_LANE_TX_BIST_BASE + 0x2F) +#define SERDES_25G_LANE_TX_BIST_UDP_103_96_ADDR (SERDES_25G_LANE_TX_BIST_BASE + 0x30) +#define SERDES_25G_LANE_TX_BIST_UDP_111_104_ADDR (SERDES_25G_LANE_TX_BIST_BASE + 0x31) +#define SERDES_25G_LANE_TX_BIST_UDP_119_112_ADDR (SERDES_25G_LANE_TX_BIST_BASE + 0x32) +#define SERDES_25G_LANE_TX_BIST_UDP_127_120_ADDR (SERDES_25G_LANE_TX_BIST_BASE + 0x33) +#define SERDES_25G_LANE_TX_BIST_UDP_135_128_ADDR (SERDES_25G_LANE_TX_BIST_BASE + 0x34) +#define SERDES_25G_LANE_TX_BIST_UDP_143_136_ADDR (SERDES_25G_LANE_TX_BIST_BASE + 0x35) +#define SERDES_25G_LANE_TX_BIST_UDP_151_144_ADDR (SERDES_25G_LANE_TX_BIST_BASE + 0x36) +#define SERDES_25G_LANE_TX_BIST_UDP_159_152_ADDR (SERDES_25G_LANE_TX_BIST_BASE + 0x37) +#define SERDES_25G_LANE_TX_BIST_UDP_167_160_ADDR (SERDES_25G_LANE_TX_BIST_BASE + 0x38) +#define SERDES_25G_LANE_TX_BIST_UDP_175_168_ADDR (SERDES_25G_LANE_TX_BIST_BASE + 0x39) +#define SERDES_25G_LANE_TX_BIST_UDP_183_176_ADDR (SERDES_25G_LANE_TX_BIST_BASE + 0x3A) +#define SERDES_25G_LANE_TX_BIST_UDP_191_184_ADDR (SERDES_25G_LANE_TX_BIST_BASE + 0x3B) +#define SERDES_25G_LANE_TX_BIST_UDP_199_192_ADDR (SERDES_25G_LANE_TX_BIST_BASE + 0x3C) + +#define SERDES_25G_LANE_TX_BIST_CTRL_EN_MASK 0x01 +#define SERDES_25G_LANE_TX_BIST_CTRL_EN_SHIFT 0 + +#define SERDES_25G_LANE_TX_BIST_CTRL_PATTERN_SEL_MASK 0x1E +#define SERDES_25G_LANE_TX_BIST_CTRL_PATTERN_SEL_SHIFT 1 + +#define SERDES_25G_LANE_TX_BIST_CTRL_PATTERN_PRBS7 1 +#define SERDES_25G_LANE_TX_BIST_CTRL_PATTERN_PRBS9 2 +#define SERDES_25G_LANE_TX_BIST_CTRL_PATTERN_PRBS11 3 +#define SERDES_25G_LANE_TX_BIST_CTRL_PATTERN_PRBS15 4 +#define SERDES_25G_LANE_TX_BIST_CTRL_PATTERN_PRBS23 5 +#define SERDES_25G_LANE_TX_BIST_CTRL_PATTERN_PRBS31 6 +#define SERDES_25G_LANE_TX_BIST_CTRL_PATTERN_PRBS_USER 7 + +#define SERDES_25G_LANE_TX_BIST_BER_CTRL0_MODE_MASK 0x03 +#define SERDES_25G_LANE_TX_BIST_BER_CTRL0_MODE_SHIFT 0 + +#define SERDES_25G_LANE_TX_BIST_BER_CTRL1_TIMER_7_0_MASK 0xFF +#define SERDES_25G_LANE_TX_BIST_BER_CTRL1_TIMER_7_0_SHIFT 0 + +#define SERDES_25G_LANE_TX_BIST_BER_CTRL2_TIMER_15_8_MASK 0xFF +#define SERDES_25G_LANE_TX_BIST_BER_CTRL2_TIMER_15_8_SHIFT 0 + +#define SERDES_25G_LANE_TX_BIST_BER_CTRL3_BIT_ERROR_FIELD_7_0_MASK 0xFF +#define SERDES_25G_LANE_TX_BIST_BER_CTRL3_BIT_ERROR_FIELD_7_0_SHIFT 0 + +#define SERDES_25G_LANE_TX_BIST_BER_CTRL4_BIT_ERROR_FIELD_15_8_MASK 0xFF +#define SERDES_25G_LANE_TX_BIST_BER_CTRL4_BIT_ERROR_FIELD_15_8_SHIFT 0 + +#define SERDES_25G_LANE_TX_BIST_BER_CTRL5_BIT_ERROR_FIELD_23_16_MASK 0xFF +#define SERDES_25G_LANE_TX_BIST_BER_CTRL5_BIT_ERROR_FIELD_23_16_SHIFT 0 + +#define SERDES_25G_LANE_TX_BIST_BER_CTRL6_BIT_ERROR_FIELD_31_24_MASK 0xFF +#define SERDES_25G_LANE_TX_BIST_BER_CTRL6_BIT_ERROR_FIELD_31_24_SHIFT 0 + +#define SERDES_25G_LANE_TX_BIST_BER_CTRL7_BIT_ERROR_FIELD_39_32_MASK 0xFF +#define SERDES_25G_LANE_TX_BIST_BER_CTRL7_BIT_ERROR_FIELD_39_32_SHIFT 0 + +#define SERDES_25G_LANE_TX_BIST_SHIFT_AMOUNT_MASK 0xFF +#define SERDES_25G_LANE_TX_BIST_SHIFT_AMOUNT_SHIFT 0 + +#define SERDES_25G_LANE_TX_BIST_UDP_7_0_MASK 0xFF +#define SERDES_25G_LANE_TX_BIST_UDP_7_0_SHIFT 0 + +#define SERDES_25G_LANE_TX_BIST_UDP_15_8_MASK 0xFF +#define SERDES_25G_LANE_TX_BIST_UDP_15_8_SHIFT 0 + +#define SERDES_25G_LANE_TX_BIST_UDP_23_16_MASK 0xFF +#define SERDES_25G_LANE_TX_BIST_UDP_23_16_SHIFT 0 + +#define SERDES_25G_LANE_TX_BIST_UDP_31_24_MASK 0xFF +#define SERDES_25G_LANE_TX_BIST_UDP_31_24_SHIFT 0 + +#define SERDES_25G_LANE_TX_BIST_UDP_39_32_MASK 0xFF +#define SERDES_25G_LANE_TX_BIST_UDP_39_32_SHIFT 0 + +#define SERDES_25G_LANE_TX_BIST_UDP_47_40_MASK 0xFF +#define SERDES_25G_LANE_TX_BIST_UDP_47_40_SHIFT 0 + +#define SERDES_25G_LANE_TX_BIST_UDP_55_48_MASK 0xFF +#define SERDES_25G_LANE_TX_BIST_UDP_55_48_SHIFT 0 + +#define SERDES_25G_LANE_TX_BIST_UDP_63_56_MASK 0xFF +#define SERDES_25G_LANE_TX_BIST_UDP_63_56_SHIFT 0 + +#define SERDES_25G_LANE_TX_BIST_UDP_71_64_MASK 0xFF +#define SERDES_25G_LANE_TX_BIST_UDP_71_64_SHIFT 0 + +#define SERDES_25G_LANE_TX_BIST_UDP_79_72_MASK 0xFF +#define SERDES_25G_LANE_TX_BIST_UDP_79_72_SHIFT 0 + +#define SERDES_25G_LANE_TX_BIST_UDP_87_80_MASK 0xFF +#define SERDES_25G_LANE_TX_BIST_UDP_87_80_SHIFT 0 + +#define SERDES_25G_LANE_TX_BIST_UDP_95_88_MASK 0xFF +#define SERDES_25G_LANE_TX_BIST_UDP_95_88_SHIFT 0 + +#define SERDES_25G_LANE_TX_BIST_UDP_103_96_MASK 0xFF +#define SERDES_25G_LANE_TX_BIST_UDP_103_96_SHIFT 0 + +#define SERDES_25G_LANE_TX_BIST_UDP_111_104_MASK 0xFF +#define SERDES_25G_LANE_TX_BIST_UDP_111_104_SHIFT 0 + +#define SERDES_25G_LANE_TX_BIST_UDP_119_112_MASK 0xFF +#define SERDES_25G_LANE_TX_BIST_UDP_119_112_SHIFT 0 + +#define SERDES_25G_LANE_TX_BIST_UDP_127_120_MASK 0xFF +#define SERDES_25G_LANE_TX_BIST_UDP_127_120_SHIFT 0 + +#define SERDES_25G_LANE_TX_BIST_UDP_135_128_MASK 0xFF +#define SERDES_25G_LANE_TX_BIST_UDP_135_128_SHIFT 0 + +#define SERDES_25G_LANE_TX_BIST_UDP_143_136_MASK 0xFF +#define SERDES_25G_LANE_TX_BIST_UDP_143_136_SHIFT 0 + +#define SERDES_25G_LANE_TX_BIST_UDP_151_144_MASK 0xFF +#define SERDES_25G_LANE_TX_BIST_UDP_151_144_SHIFT 0 + +#define SERDES_25G_LANE_TX_BIST_UDP_159_152_MASK 0xFF +#define SERDES_25G_LANE_TX_BIST_UDP_159_152_SHIFT 0 + +#define SERDES_25G_LANE_TX_BIST_UDP_167_160_MASK 0xFF +#define SERDES_25G_LANE_TX_BIST_UDP_167_160_SHIFT 0 + +#define SERDES_25G_LANE_TX_BIST_UDP_175_168_MASK 0xFF +#define SERDES_25G_LANE_TX_BIST_UDP_175_168_SHIFT 0 + +#define SERDES_25G_LANE_TX_BIST_UDP_183_176_MASK 0xFF +#define SERDES_25G_LANE_TX_BIST_UDP_183_176_SHIFT 0 + +#define SERDES_25G_LANE_TX_BIST_UDP_191_184_MASK 0xFF +#define SERDES_25G_LANE_TX_BIST_UDP_191_184_SHIFT 0 + +#define SERDES_25G_LANE_TX_BIST_UDP_199_192_MASK 0xFF +#define SERDES_25G_LANE_TX_BIST_UDP_199_192_SHIFT 0 + +/********************************** RX BIST **********************************/ +#define SERDES_25G_LANE_RX_BIST_BASE 0x680 + +#define SERDES_25G_LANE_RX_BIST_CTRL_ADDR (SERDES_25G_LANE_RX_BIST_BASE + 0x00) +#define SERDES_25G_LANE_RX_BIST_STATUS_ADDR (SERDES_25G_LANE_RX_BIST_BASE + 0x04) +#define SERDES_25G_LANE_RX_BIST_BER_STATUS0_ADDR (SERDES_25G_LANE_RX_BIST_BASE + 0x08) +#define SERDES_25G_LANE_RX_BIST_BER_STATUS1_ADDR (SERDES_25G_LANE_RX_BIST_BASE + 0x09) +#define SERDES_25G_LANE_RX_BIST_BER_STATUS2_ADDR (SERDES_25G_LANE_RX_BIST_BASE + 0x0A) +#define SERDES_25G_LANE_RX_BIST_BER_STATUS4_ADDR (SERDES_25G_LANE_RX_BIST_BASE + 0x0C) +#define SERDES_25G_LANE_RX_BIST_BER_STATUS5_ADDR (SERDES_25G_LANE_RX_BIST_BASE + 0x0D) +#define SERDES_25G_LANE_RX_BIST_BER_STATUS6_ADDR (SERDES_25G_LANE_RX_BIST_BASE + 0x0E) +#define SERDES_25G_LANE_RX_BIST_LOCK_CTRL0_ADDR (SERDES_25G_LANE_RX_BIST_BASE + 0x14) +#define SERDES_25G_LANE_RX_BIST_LOCK_CTRL1_ADDR (SERDES_25G_LANE_RX_BIST_BASE + 0x15) +#define SERDES_25G_LANE_RX_BIST_LOCK_CTRL2_ADDR (SERDES_25G_LANE_RX_BIST_BASE + 0x16) +#define SERDES_25G_LANE_RX_BIST_LOCK_CTRL3_ADDR (SERDES_25G_LANE_RX_BIST_BASE + 0x17) +#define SERDES_25G_LANE_RX_BIST_LOSS_LOCK_CTRL0_ADDR (SERDES_25G_LANE_RX_BIST_BASE + 0x20) +#define SERDES_25G_LANE_RX_BIST_LOSS_LOCK_CTRL1_ADDR (SERDES_25G_LANE_RX_BIST_BASE + 0x21) +#define SERDES_25G_LANE_RX_BIST_LOSS_LOCK_CTRL2_ADDR (SERDES_25G_LANE_RX_BIST_BASE + 0x22) +#define SERDES_25G_LANE_RX_BIST_LOSS_LOCK_CTRL3_ADDR (SERDES_25G_LANE_RX_BIST_BASE + 0x23) +#define SERDES_25G_LANE_RX_BIST_LOSS_LOCK_CTRL4_ADDR (SERDES_25G_LANE_RX_BIST_BASE + 0x24) +#define SERDES_25G_LANE_RX_BIST_SHIFT_AMOUNT_ADDR (SERDES_25G_LANE_RX_BIST_BASE + 0x30) +#define SERDES_25G_LANE_RX_BIST_UDP_7_0_ADDR (SERDES_25G_LANE_RX_BIST_BASE + 0x34) +#define SERDES_25G_LANE_RX_BIST_UDP_15_8_ADDR (SERDES_25G_LANE_RX_BIST_BASE + 0x35) +#define SERDES_25G_LANE_RX_BIST_UDP_23_16_ADDR (SERDES_25G_LANE_RX_BIST_BASE + 0x36) +#define SERDES_25G_LANE_RX_BIST_UDP_31_24_ADDR (SERDES_25G_LANE_RX_BIST_BASE + 0x37) +#define SERDES_25G_LANE_RX_BIST_UDP_39_32_ADDR (SERDES_25G_LANE_RX_BIST_BASE + 0x38) +#define SERDES_25G_LANE_RX_BIST_UDP_47_40_ADDR (SERDES_25G_LANE_RX_BIST_BASE + 0x39) +#define SERDES_25G_LANE_RX_BIST_UDP_55_48_ADDR (SERDES_25G_LANE_RX_BIST_BASE + 0x3A) +#define SERDES_25G_LANE_RX_BIST_UDP_63_56_ADDR (SERDES_25G_LANE_RX_BIST_BASE + 0x3B) +#define SERDES_25G_LANE_RX_BIST_UDP_71_64_ADDR (SERDES_25G_LANE_RX_BIST_BASE + 0x3C) +#define SERDES_25G_LANE_RX_BIST_UDP_79_72_ADDR (SERDES_25G_LANE_RX_BIST_BASE + 0x3D) +#define SERDES_25G_LANE_RX_BIST_UDP_87_80_ADDR (SERDES_25G_LANE_RX_BIST_BASE + 0x3E) +#define SERDES_25G_LANE_RX_BIST_UDP_95_88_ADDR (SERDES_25G_LANE_RX_BIST_BASE + 0x3F) +#define SERDES_25G_LANE_RX_BIST_UDP_103_96_ADDR (SERDES_25G_LANE_RX_BIST_BASE + 0x40) +#define SERDES_25G_LANE_RX_BIST_UDP_111_104_ADDR (SERDES_25G_LANE_RX_BIST_BASE + 0x41) +#define SERDES_25G_LANE_RX_BIST_UDP_119_112_ADDR (SERDES_25G_LANE_RX_BIST_BASE + 0x42) +#define SERDES_25G_LANE_RX_BIST_UDP_127_120_ADDR (SERDES_25G_LANE_RX_BIST_BASE + 0x43) +#define SERDES_25G_LANE_RX_BIST_UDP_135_128_ADDR (SERDES_25G_LANE_RX_BIST_BASE + 0x44) +#define SERDES_25G_LANE_RX_BIST_UDP_143_136_ADDR (SERDES_25G_LANE_RX_BIST_BASE + 0x45) +#define SERDES_25G_LANE_RX_BIST_UDP_151_144_ADDR (SERDES_25G_LANE_RX_BIST_BASE + 0x46) +#define SERDES_25G_LANE_RX_BIST_UDP_159_152_ADDR (SERDES_25G_LANE_RX_BIST_BASE + 0x47) +#define SERDES_25G_LANE_RX_BIST_UDP_167_160_ADDR (SERDES_25G_LANE_RX_BIST_BASE + 0x48) +#define SERDES_25G_LANE_RX_BIST_UDP_175_168_ADDR (SERDES_25G_LANE_RX_BIST_BASE + 0x49) +#define SERDES_25G_LANE_RX_BIST_UDP_183_176_ADDR (SERDES_25G_LANE_RX_BIST_BASE + 0x4A) +#define SERDES_25G_LANE_RX_BIST_UDP_191_184_ADDR (SERDES_25G_LANE_RX_BIST_BASE + 0x4B) +#define SERDES_25G_LANE_RX_BIST_UDP_199_192_ADDR (SERDES_25G_LANE_RX_BIST_BASE + 0x4C) + +/******************************************************************************* + * masks and shifts + ******************************************************************************/ +#define SERDES_25G_LANE_RX_BIST_CTRL_EN_MASK 0x01 +#define SERDES_25G_LANE_RX_BIST_CTRL_EN_SHIFT 0 + +#define SERDES_25G_LANE_RX_BIST_CTRL_PATTERN_SEL_MASK 0x1E +#define SERDES_25G_LANE_RX_BIST_CTRL_PATTERN_SEL_SHIFT 1 + +#define SERDES_25G_LANE_RX_BIST_CTRL_CLEAR_BER_MASK 0x20 +#define SERDES_25G_LANE_RX_BIST_CTRL_CLEAR_BER_SHIFT 5 + +#define SERDES_25G_LANE_RX_BIST_CTRL_STOP_ERROR_COUNT_MASK 0x40 +#define SERDES_25G_LANE_RX_BIST_CTRL_STOP_ERROR_COUNT_SHIFT 6 + +#define SERDES_25G_LANE_RX_BIST_CTRL_FORCE_LFSR_WITH_RXDATA_MASK 0x80 +#define SERDES_25G_LANE_RX_BIST_CTRL_FORCE_LFSR_WITH_RXDATA_SHIFT 7 + +#define SERDES_25G_LANE_RX_BIST_STATUS_STATE_MASK 0x07 +#define SERDES_25G_LANE_RX_BIST_STATUS_STATE_SHIFT 0 + +#define SERDES_25G_LANE_RX_BIST_STATUS_PATTERN_DET_MASK 0x78 +#define SERDES_25G_LANE_RX_BIST_STATUS_PATTERN_DET_SHIFT 3 + +#define SERDES_25G_LANE_RX_BIST_BER_STATUS0_BIT_ERROR_COUNT_7_0_MASK 0xFF +#define SERDES_25G_LANE_RX_BIST_BER_STATUS0_BIT_ERROR_COUNT_7_0_SHIFT 0 + +#define SERDES_25G_LANE_RX_BIST_BER_STATUS1_BIT_ERROR_COUNT_15_8_MASK 0xFF +#define SERDES_25G_LANE_RX_BIST_BER_STATUS1_BIT_ERROR_COUNT_15_8_SHIFT 0 + +#define SERDES_25G_LANE_RX_BIST_BER_STATUS2_BIT_ERROR_COUNT_23_16_MASK 0xFF +#define SERDES_25G_LANE_RX_BIST_BER_STATUS2_BIT_ERROR_COUNT_23_16_SHIFT 0 + +#define SERDES_25G_LANE_RX_BIST_BER_STATUS4_CYCLE_COUNT_7_0_MASK 0xFF +#define SERDES_25G_LANE_RX_BIST_BER_STATUS4_CYCLE_COUNT_7_0_SHIFT 0 + +#define SERDES_25G_LANE_RX_BIST_BER_STATUS5_CYCLE_COUNT_15_8_MASK 0xFF +#define SERDES_25G_LANE_RX_BIST_BER_STATUS5_CYCLE_COUNT_15_8_SHIFT 0 + +#define SERDES_25G_LANE_RX_BIST_BER_STATUS6_CYCLE_COUNT_23_16_MASK 0xFF +#define SERDES_25G_LANE_RX_BIST_BER_STATUS6_CYCLE_COUNT_23_16_SHIFT 0 + +#define SERDES_25G_LANE_RX_BIST_LOCK_CTRL0_NUM_CYCLES_7_0_MASK 0xFF +#define SERDES_25G_LANE_RX_BIST_LOCK_CTRL0_NUM_CYCLES_7_0_SHIFT 0 + +#define SERDES_25G_LANE_RX_BIST_LOCK_CTRL1_NUM_CYCLES_15_8_MASK 0xFF +#define SERDES_25G_LANE_RX_BIST_LOCK_CTRL1_NUM_CYCLES_15_8_SHIFT 0 + +#define SERDES_25G_LANE_RX_BIST_LOCK_CTRL2_MAX_ERRORS_7_0_MASK 0xFF +#define SERDES_25G_LANE_RX_BIST_LOCK_CTRL2_MAX_ERRORS_7_0_SHIFT 0 + +#define SERDES_25G_LANE_RX_BIST_LOCK_CTRL3_MAX_ERRORS_15_8_MASK 0xFF +#define SERDES_25G_LANE_RX_BIST_LOCK_CTRL3_MAX_ERRORS_15_8_SHIFT 0 + +#define SERDES_25G_LANE_RX_BIST_LOSS_LOCK_CTRL0_NUM_CYCLES_7_0_MASK 0xFF +#define SERDES_25G_LANE_RX_BIST_LOSS_LOCK_CTRL0_NUM_CYCLES_7_0_SHIFT 0 + +#define SERDES_25G_LANE_RX_BIST_LOSS_LOCK_CTRL1_NUM_CYCLES_15_8_MASK 0xFF +#define SERDES_25G_LANE_RX_BIST_LOSS_LOCK_CTRL1_NUM_CYCLES_15_8_SHIFT 0 + +#define SERDES_25G_LANE_RX_BIST_LOSS_LOCK_CTRL2_MIN_ERRORS_7_0_MASK 0xFF +#define SERDES_25G_LANE_RX_BIST_LOSS_LOCK_CTRL2_MIN_ERRORS_7_0_SHIFT 0 + +#define SERDES_25G_LANE_RX_BIST_LOSS_LOCK_CTRL3_MIN_ERRORS_15_8_MASK 0xFF +#define SERDES_25G_LANE_RX_BIST_LOSS_LOCK_CTRL3_MIN_ERRORS_15_8_SHIFT 0 + +#define SERDES_25G_LANE_RX_BIST_LOSS_LOCK_CTRL4_STOP_ON_LOSS_LOCK_MASK 0x01 +#define SERDES_25G_LANE_RX_BIST_LOSS_LOCK_CTRL4_STOP_ON_LOSS_LOCK_SHIFT 0 + +#define SERDES_25G_LANE_RX_BIST_SHIFT_AMOUNT_MASK 0xFF +#define SERDES_25G_LANE_RX_BIST_SHIFT_AMOUNT_SHIFT 0 + +#define SERDES_25G_LANE_RX_BIST_UDP_7_0_MASK 0xFF +#define SERDES_25G_LANE_RX_BIST_UDP_7_0_SHIFT 0 + +#define SERDES_25G_LANE_RX_BIST_UDP_15_8_MASK 0xFF +#define SERDES_25G_LANE_RX_BIST_UDP_15_8_SHIFT 0 + +#define SERDES_25G_LANE_RX_BIST_UDP_23_16_MASK 0xFF +#define SERDES_25G_LANE_RX_BIST_UDP_23_16_SHIFT 0 + +#define SERDES_25G_LANE_RX_BIST_UDP_31_24_MASK 0xFF +#define SERDES_25G_LANE_RX_BIST_UDP_31_24_SHIFT 0 + +#define SERDES_25G_LANE_RX_BIST_UDP_39_32_MASK 0xFF +#define SERDES_25G_LANE_RX_BIST_UDP_39_32_SHIFT 0 + +#define SERDES_25G_LANE_RX_BIST_UDP_47_40_MASK 0xFF +#define SERDES_25G_LANE_RX_BIST_UDP_47_40_SHIFT 0 + +#define SERDES_25G_LANE_RX_BIST_UDP_55_48_MASK 0xFF +#define SERDES_25G_LANE_RX_BIST_UDP_55_48_SHIFT 0 + +#define SERDES_25G_LANE_RX_BIST_UDP_63_56_MASK 0xFF +#define SERDES_25G_LANE_RX_BIST_UDP_63_56_SHIFT 0 + +#define SERDES_25G_LANE_RX_BIST_UDP_71_64_MASK 0xFF +#define SERDES_25G_LANE_RX_BIST_UDP_71_64_SHIFT 0 + +#define SERDES_25G_LANE_RX_BIST_UDP_79_72_MASK 0xFF +#define SERDES_25G_LANE_RX_BIST_UDP_79_72_SHIFT 0 + +#define SERDES_25G_LANE_RX_BIST_UDP_87_80_MASK 0xFF +#define SERDES_25G_LANE_RX_BIST_UDP_87_80_SHIFT 0 + +#define SERDES_25G_LANE_RX_BIST_UDP_95_88_MASK 0xFF +#define SERDES_25G_LANE_RX_BIST_UDP_95_88_SHIFT 0 + +#define SERDES_25G_LANE_RX_BIST_UDP_103_96_MASK 0xFF +#define SERDES_25G_LANE_RX_BIST_UDP_103_96_SHIFT 0 + +#define SERDES_25G_LANE_RX_BIST_UDP_111_104_MASK 0xFF +#define SERDES_25G_LANE_RX_BIST_UDP_111_104_SHIFT 0 + +#define SERDES_25G_LANE_RX_BIST_UDP_119_112_MASK 0xFF +#define SERDES_25G_LANE_RX_BIST_UDP_119_112_SHIFT 0 + +#define SERDES_25G_LANE_RX_BIST_UDP_127_120_MASK 0xFF +#define SERDES_25G_LANE_RX_BIST_UDP_127_120_SHIFT 0 + +#define SERDES_25G_LANE_RX_BIST_UDP_135_128_MASK 0xFF +#define SERDES_25G_LANE_RX_BIST_UDP_135_128_SHIFT 0 + +#define SERDES_25G_LANE_RX_BIST_UDP_143_136_MASK 0xFF +#define SERDES_25G_LANE_RX_BIST_UDP_143_136_SHIFT 0 + +#define SERDES_25G_LANE_RX_BIST_UDP_151_144_MASK 0xFF +#define SERDES_25G_LANE_RX_BIST_UDP_151_144_SHIFT 0 + +#define SERDES_25G_LANE_RX_BIST_UDP_159_152_MASK 0xFF +#define SERDES_25G_LANE_RX_BIST_UDP_159_152_SHIFT 0 + +#define SERDES_25G_LANE_RX_BIST_UDP_167_160_MASK 0xFF +#define SERDES_25G_LANE_RX_BIST_UDP_167_160_SHIFT 0 + +#define SERDES_25G_LANE_RX_BIST_UDP_175_168_MASK 0xFF +#define SERDES_25G_LANE_RX_BIST_UDP_175_168_SHIFT 0 + +#define SERDES_25G_LANE_RX_BIST_UDP_183_176_MASK 0xFF +#define SERDES_25G_LANE_RX_BIST_UDP_183_176_SHIFT 0 + +#define SERDES_25G_LANE_RX_BIST_UDP_191_184_MASK 0xFF +#define SERDES_25G_LANE_RX_BIST_UDP_191_184_SHIFT 0 + +#define SERDES_25G_LANE_RX_BIST_UDP_199_192_MASK 0xFF +#define SERDES_25G_LANE_RX_BIST_UDP_199_192_SHIFT 0 + +/*********************************** FEATURE **********************************/ +#define SERDES_25G_LANE_FEATURE_BASE 0x700 + +#define SERDES_25G_LANE_FEATURE_RXTERM_CFG0_ADDR (SERDES_25G_LANE_FEATURE_BASE + 0x00) +#define SERDES_25G_LANE_FEATURE_LOS_CAL_CFG0_ADDR (SERDES_25G_LANE_FEATURE_BASE + 0x04) +#define SERDES_25G_LANE_FEATURE_LEQ_OFFSET_CAL_CFG0_ADDR (SERDES_25G_LANE_FEATURE_BASE + 0x05) +#define SERDES_25G_LANE_FEATURE_DFE_OFFSET_CAL_CFG0_ADDR (SERDES_25G_LANE_FEATURE_BASE + 0x06) +#define SERDES_25G_LANE_FEATURE_DFE_OFFSET_CAL_CFG1_ADDR (SERDES_25G_LANE_FEATURE_BASE + 0x07) +#define SERDES_25G_LANE_FEATURE_CDR_CAL_CFG0_ADDR (SERDES_25G_LANE_FEATURE_BASE + 0x08) +#define SERDES_25G_LANE_FEATURE_TX_CAL_CFG0_ADDR (SERDES_25G_LANE_FEATURE_BASE + 0x09) +#define SERDES_25G_LANE_FEATURE_ADAPT_CFG_ADDR (SERDES_25G_LANE_FEATURE_BASE + 0x0C) +#define SERDES_25G_LANE_FEATURE_CTLE_ADAPT_CFG_ADDR (SERDES_25G_LANE_FEATURE_BASE + 0x10) +#define SERDES_25G_LANE_FEATURE_CTLE_ADAPT_CONT_CFG0_ADDR (SERDES_25G_LANE_FEATURE_BASE + 0x11) +#define SERDES_25G_LANE_FEATURE_CTLE_ADAPT_CONT_CFG1_ADDR (SERDES_25G_LANE_FEATURE_BASE + 0x12) +#define SERDES_25G_LANE_FEATURE_CTLE_ADAPT_CONT_CFG2_ADDR (SERDES_25G_LANE_FEATURE_BASE + 0x13) +#define SERDES_25G_LANE_FEATURE_CTLE_ADAPT_AGC_CFG_ADDR (SERDES_25G_LANE_FEATURE_BASE + 0x14) +#define SERDES_25G_LANE_FEATURE_CTLE_ADAPT_APG_MAP_CFG_ADDR (SERDES_25G_LANE_FEATURE_BASE + 0x15) +#define SERDES_25G_LANE_FEATURE_CTLE_ADAPT_LFG_CFG_ADDR (SERDES_25G_LANE_FEATURE_BASE + 0x16) +#define SERDES_25G_LANE_FEATURE_CTLE_ADAPT_HFG_CFG0_ADDR (SERDES_25G_LANE_FEATURE_BASE + 0x17) +#define SERDES_25G_LANE_FEATURE_CTLE_ADAPT_HFG_CFG1_ADDR (SERDES_25G_LANE_FEATURE_BASE + 0x18) +#define SERDES_25G_LANE_FEATURE_CTLE_ADAPT_HFG_CFG2_ADDR (SERDES_25G_LANE_FEATURE_BASE + 0x19) +#define SERDES_25G_LANE_FEATURE_CTLE_ADAPT_MBS_CFG_ADDR (SERDES_25G_LANE_FEATURE_BASE + 0x1A) +#define SERDES_25G_LANE_FEATURE_CTLE_ADAPT_EIE0_CFG_ADDR (SERDES_25G_LANE_FEATURE_BASE + 0x1B) +#define SERDES_25G_LANE_FEATURE_DFE_CFG_ADDR (SERDES_25G_LANE_FEATURE_BASE + 0x1F) +#define SERDES_25G_LANE_FEATURE_DFE_ADAPT_CFG_ADDR (SERDES_25G_LANE_FEATURE_BASE + 0x20) +#define SERDES_25G_LANE_FEATURE_DFE_ADAPT_CONT_CFG0_ADDR (SERDES_25G_LANE_FEATURE_BASE + 0x21) +#define SERDES_25G_LANE_FEATURE_DFE_ADAPT_CONT_CFG1_ADDR (SERDES_25G_LANE_FEATURE_BASE + 0x22) +#define SERDES_25G_LANE_FEATURE_DFE_ADAPT_CONT_CFG2_ADDR (SERDES_25G_LANE_FEATURE_BASE + 0x23) +#define SERDES_25G_LANE_FEATURE_DFE_ADAPT_TAP1_CFG_ADDR (SERDES_25G_LANE_FEATURE_BASE + 0x24) +#define SERDES_25G_LANE_FEATURE_DFE_ADAPT_TAP2_CFG_ADDR (SERDES_25G_LANE_FEATURE_BASE + 0x25) +#define SERDES_25G_LANE_FEATURE_DFE_ADAPT_TAP3_CFG_ADDR (SERDES_25G_LANE_FEATURE_BASE + 0x26) +#define SERDES_25G_LANE_FEATURE_DFE_ADAPT_TAP4_CFG_ADDR (SERDES_25G_LANE_FEATURE_BASE + 0x27) +#define SERDES_25G_LANE_FEATURE_DFE_ADAPT_TAP5_CFG_ADDR (SERDES_25G_LANE_FEATURE_BASE + 0x28) +#define SERDES_25G_LANE_FEATURE_RX_CTRL_CFG0_ADDR (SERDES_25G_LANE_FEATURE_BASE + 0x30) +#define SERDES_25G_LANE_FEATURE_RX_CTRL_CFG1_ADDR (SERDES_25G_LANE_FEATURE_BASE + 0x31) +#define SERDES_25G_LANE_FEATURE_RX_CTRL_CFG2_ADDR (SERDES_25G_LANE_FEATURE_BASE + 0x32) +#define SERDES_25G_LANE_FEATURE_RX_CTRL_CFG3_ADDR (SERDES_25G_LANE_FEATURE_BASE + 0x33) +#define SERDES_25G_LANE_FEATURE_EYE_LOS_CFG0_ADDR (SERDES_25G_LANE_FEATURE_BASE + 0x40) +#define SERDES_25G_LANE_FEATURE_EYE_LOS_CFG1_ADDR (SERDES_25G_LANE_FEATURE_BASE + 0x41) +#define SERDES_25G_LANE_FEATURE_EYE_LOS_CFG2_ADDR (SERDES_25G_LANE_FEATURE_BASE + 0x42) +#define SERDES_25G_LANE_FEATURE_EYE_LOS_CFG3_ADDR (SERDES_25G_LANE_FEATURE_BASE + 0x43) +#define SERDES_25G_LANE_FEATURE_EYE_LOS_CFG4_ADDR (SERDES_25G_LANE_FEATURE_BASE + 0x44) +#define SERDES_25G_LANE_FEATURE_EYE_LOS_CFG5_ADDR (SERDES_25G_LANE_FEATURE_BASE + 0x45) +#define SERDES_25G_LANE_FEATURE_EYE_LOS_CFG6_ADDR (SERDES_25G_LANE_FEATURE_BASE + 0x46) +#define SERDES_25G_LANE_FEATURE_EYE_LOS_CFG7_ADDR (SERDES_25G_LANE_FEATURE_BASE + 0x47) +#define SERDES_25G_LANE_FEATURE_EYE_LOS_CFG8_ADDR (SERDES_25G_LANE_FEATURE_BASE + 0x48) +#define SERDES_25G_LANE_FEATURE_EYE_LOS_CFG9_ADDR (SERDES_25G_LANE_FEATURE_BASE + 0x49) +#define SERDES_25G_LANE_FEATURE_TEST_CFG0_ADDR (SERDES_25G_LANE_FEATURE_BASE + 0x50) +#define SERDES_25G_LANE_FEATURE_SPARE_CFG0_ADDR (SERDES_25G_LANE_FEATURE_BASE + 0x58) +#define SERDES_25G_LANE_FEATURE_SPARE_CFG1_ADDR (SERDES_25G_LANE_FEATURE_BASE + 0x59) +#define SERDES_25G_LANE_FEATURE_SPARE_CFG2_ADDR (SERDES_25G_LANE_FEATURE_BASE + 0x5A) +#define SERDES_25G_LANE_FEATURE_SPARE_CFG3_ADDR (SERDES_25G_LANE_FEATURE_BASE + 0x5B) +#define SERDES_25G_LANE_FEATURE_SPARE_CFG4_ADDR (SERDES_25G_LANE_FEATURE_BASE + 0x5C) +#define SERDES_25G_LANE_FEATURE_SPARE_CFG5_ADDR (SERDES_25G_LANE_FEATURE_BASE + 0x5D) +#define SERDES_25G_LANE_FEATURE_SPARE_CFG6_ADDR (SERDES_25G_LANE_FEATURE_BASE + 0x5E) +#define SERDES_25G_LANE_FEATURE_SPARE_CFG7_ADDR (SERDES_25G_LANE_FEATURE_BASE + 0x5F) +/******************************************************************************* + * masks and shifts + ******************************************************************************/ +#define SERDES_25G_LANE_FEATURE_RXTERM_CFG0_AC_COUPLED_MASK 0x01 +#define SERDES_25G_LANE_FEATURE_RXTERM_CFG0_AC_COUPLED_SHIFT 0 + +#define SERDES_25G_LANE_FEATURE_LOS_CAL_CFG0_LOS_COMP_EN_MASK 0x01 +#define SERDES_25G_LANE_FEATURE_LOS_CAL_CFG0_LOS_COMP_EN_SHIFT 0 + +#define SERDES_25G_LANE_FEATURE_LOS_CAL_CFG0_AGC_COMP_EN_MASK 0x02 +#define SERDES_25G_LANE_FEATURE_LOS_CAL_CFG0_AGC_COMP_EN_SHIFT 1 + +#define SERDES_25G_LANE_FEATURE_LEQ_OFFSET_CAL_CFG0_GN_EN_MASK 0x01 +#define SERDES_25G_LANE_FEATURE_LEQ_OFFSET_CAL_CFG0_GN_EN_SHIFT 0 + +#define SERDES_25G_LANE_FEATURE_LEQ_OFFSET_CAL_CFG0_EQ1_EN_MASK 0x02 +#define SERDES_25G_LANE_FEATURE_LEQ_OFFSET_CAL_CFG0_EQ1_EN_SHIFT 1 + +#define SERDES_25G_LANE_FEATURE_LEQ_OFFSET_CAL_CFG0_EQ2_EN_MASK 0x04 +#define SERDES_25G_LANE_FEATURE_LEQ_OFFSET_CAL_CFG0_EQ2_EN_SHIFT 2 + +#define SERDES_25G_LANE_FEATURE_LEQ_OFFSET_CAL_CFG0_EQ3_EN_MASK 0x08 +#define SERDES_25G_LANE_FEATURE_LEQ_OFFSET_CAL_CFG0_EQ3_EN_SHIFT 3 + +#define SERDES_25G_LANE_FEATURE_LEQ_OFFSET_CAL_CFG0_EQ4_EN_MASK 0x10 +#define SERDES_25G_LANE_FEATURE_LEQ_OFFSET_CAL_CFG0_EQ4_EN_SHIFT 4 + +#define SERDES_25G_LANE_FEATURE_LEQ_OFFSET_CAL_CFG0_EQ5_EN_MASK 0x20 +#define SERDES_25G_LANE_FEATURE_LEQ_OFFSET_CAL_CFG0_EQ5_EN_SHIFT 5 + +#define SERDES_25G_LANE_FEATURE_DFE_OFFSET_CAL_CFG0_SUMMODD_EN_MASK 0x01 +#define SERDES_25G_LANE_FEATURE_DFE_OFFSET_CAL_CFG0_SUMMODD_EN_SHIFT 0 + +#define SERDES_25G_LANE_FEATURE_DFE_OFFSET_CAL_CFG0_SUMMEVEN_EN_MASK 0x02 +#define SERDES_25G_LANE_FEATURE_DFE_OFFSET_CAL_CFG0_SUMMEVEN_EN_SHIFT 1 + +#define SERDES_25G_LANE_FEATURE_DFE_OFFSET_CAL_CFG0_VSCANODD_EN_MASK 0x04 +#define SERDES_25G_LANE_FEATURE_DFE_OFFSET_CAL_CFG0_VSCANODD_EN_SHIFT 2 + +#define SERDES_25G_LANE_FEATURE_DFE_OFFSET_CAL_CFG0_VSCANEVEN_EN_MASK 0x08 +#define SERDES_25G_LANE_FEATURE_DFE_OFFSET_CAL_CFG0_VSCANEVEN_EN_SHIFT 3 + +#define SERDES_25G_LANE_FEATURE_DFE_OFFSET_CAL_CFG1_DATASLICEREVEN1_EN_MASK 0x01 +#define SERDES_25G_LANE_FEATURE_DFE_OFFSET_CAL_CFG1_DATASLICEREVEN1_EN_SHIFT 0 + +#define SERDES_25G_LANE_FEATURE_DFE_OFFSET_CAL_CFG1_DATASLICEREVEN0_EN_MASK 0x02 +#define SERDES_25G_LANE_FEATURE_DFE_OFFSET_CAL_CFG1_DATASLICEREVEN0_EN_SHIFT 1 + +#define SERDES_25G_LANE_FEATURE_DFE_OFFSET_CAL_CFG1_DATASLICERODD1_EN_MASK 0x04 +#define SERDES_25G_LANE_FEATURE_DFE_OFFSET_CAL_CFG1_DATASLICERODD1_EN_SHIFT 2 + +#define SERDES_25G_LANE_FEATURE_DFE_OFFSET_CAL_CFG1_DATASLICERODD0_EN_MASK 0x08 +#define SERDES_25G_LANE_FEATURE_DFE_OFFSET_CAL_CFG1_DATASLICERODD0_EN_SHIFT 3 + +#define SERDES_25G_LANE_FEATURE_DFE_OFFSET_CAL_CFG1_EDGESLICEREVEN_EN_MASK 0x10 +#define SERDES_25G_LANE_FEATURE_DFE_OFFSET_CAL_CFG1_EDGESLICEREVEN_EN_SHIFT 4 + +#define SERDES_25G_LANE_FEATURE_DFE_OFFSET_CAL_CFG1_EDGESLICERODD_EN_MASK 0x20 +#define SERDES_25G_LANE_FEATURE_DFE_OFFSET_CAL_CFG1_EDGESLICERODD_EN_SHIFT 5 + +#define SERDES_25G_LANE_FEATURE_DFE_OFFSET_CAL_CFG1_EYESLICEREVEN_EN_MASK 0x40 +#define SERDES_25G_LANE_FEATURE_DFE_OFFSET_CAL_CFG1_EYESLICEREVEN_EN_SHIFT 6 + +#define SERDES_25G_LANE_FEATURE_DFE_OFFSET_CAL_CFG1_EYESLICERODD_EN_MASK 0x80 +#define SERDES_25G_LANE_FEATURE_DFE_OFFSET_CAL_CFG1_EYESLICERODD_EN_SHIFT 7 + +#define SERDES_25G_LANE_FEATURE_CDR_CAL_CFG0_VCO_FREQ_EN_MASK 0x01 +#define SERDES_25G_LANE_FEATURE_CDR_CAL_CFG0_VCO_FREQ_EN_SHIFT 0 + +#define SERDES_25G_LANE_FEATURE_CDR_CAL_CFG0_CDR_IQ_CAL1_EN_MASK 0x02 +#define SERDES_25G_LANE_FEATURE_CDR_CAL_CFG0_CDR_IQ_CAL1_EN_SHIFT 1 + +#define SERDES_25G_LANE_FEATURE_CDR_CAL_CFG0_CDR_IQ_CAL2_EN_MASK 0x04 +#define SERDES_25G_LANE_FEATURE_CDR_CAL_CFG0_CDR_IQ_CAL2_EN_SHIFT 2 + +#define SERDES_25G_LANE_FEATURE_CDR_CAL_CFG0_CDR_IQ_CAL3_EN_MASK 0x08 +#define SERDES_25G_LANE_FEATURE_CDR_CAL_CFG0_CDR_IQ_CAL3_EN_SHIFT 3 + +#define SERDES_25G_LANE_FEATURE_CDR_CAL_CFG0_CDR_IQ_CAL_RESULT_SEL_MASK 0x30 +#define SERDES_25G_LANE_FEATURE_CDR_CAL_CFG0_CDR_IQ_CAL_RESULT_SEL_SHIFT 4 + +#define SERDES_25G_LANE_FEATURE_TX_CAL_CFG0_TX_REG_EN_MASK 0x01 +#define SERDES_25G_LANE_FEATURE_TX_CAL_CFG0_TX_REG_EN_SHIFT 0 + +#define SERDES_25G_LANE_FEATURE_TX_CAL_CFG0_TX_DCD_EN_MASK 0x02 +#define SERDES_25G_LANE_FEATURE_TX_CAL_CFG0_TX_DCD_EN_SHIFT 1 + +#define SERDES_25G_LANE_FEATURE_TX_CAL_CFG0_TXDP_CLOCK_PHASE_EN_MASK 0x04 +#define SERDES_25G_LANE_FEATURE_TX_CAL_CFG0_TXDP_CLOCK_PHASE_EN_SHIFT 2 + +#define SERDES_25G_LANE_FEATURE_ADAPT_CFG_EYE_MON_MASK 0x01 +#define SERDES_25G_LANE_FEATURE_ADAPT_CFG_EYE_MON_SHIFT 0 + +#define SERDES_25G_LANE_FEATURE_CTLE_ADAPT_CFG_REPEAT_COUNT_INIT0_MASK 0x03 +#define SERDES_25G_LANE_FEATURE_CTLE_ADAPT_CFG_REPEAT_COUNT_INIT0_SHIFT 0 + +#define SERDES_25G_LANE_FEATURE_CTLE_ADAPT_CFG_REPEAT_COUNT_INIT1_MASK 0x0C +#define SERDES_25G_LANE_FEATURE_CTLE_ADAPT_CFG_REPEAT_COUNT_INIT1_SHIFT 2 + +#define SERDES_25G_LANE_FEATURE_CTLE_ADAPT_CFG_REPEAT_COUNT_EIE0_MASK 0x30 +#define SERDES_25G_LANE_FEATURE_CTLE_ADAPT_CFG_REPEAT_COUNT_EIE0_SHIFT 4 + +#define SERDES_25G_LANE_FEATURE_CTLE_ADAPT_CFG_REPEAT_COUNT_EIE1_MASK 0xC0 +#define SERDES_25G_LANE_FEATURE_CTLE_ADAPT_CFG_REPEAT_COUNT_EIE1_SHIFT 6 + +#define SERDES_25G_LANE_FEATURE_CTLE_ADAPT_CONT_CFG0_INTERVAL_7_0_MASK 0xFF +#define SERDES_25G_LANE_FEATURE_CTLE_ADAPT_CONT_CFG0_INTERVAL_7_0_SHIFT 0 + +#define SERDES_25G_LANE_FEATURE_CTLE_ADAPT_CONT_CFG1_INTERVAL_15_8_MASK 0xFF +#define SERDES_25G_LANE_FEATURE_CTLE_ADAPT_CONT_CFG1_INTERVAL_15_8_SHIFT 0 + +#define SERDES_25G_LANE_FEATURE_CTLE_ADAPT_CONT_CFG2_INTERVAL_23_16_MASK 0xFF +#define SERDES_25G_LANE_FEATURE_CTLE_ADAPT_CONT_CFG2_INTERVAL_23_16_SHIFT 0 + +#define SERDES_25G_LANE_FEATURE_CTLE_ADAPT_AGC_CFG_INIT0_EN_MASK 0x01 +#define SERDES_25G_LANE_FEATURE_CTLE_ADAPT_AGC_CFG_INIT0_EN_SHIFT 0 + +#define SERDES_25G_LANE_FEATURE_CTLE_ADAPT_AGC_CFG_EIE0_EN_MASK 0x04 +#define SERDES_25G_LANE_FEATURE_CTLE_ADAPT_AGC_CFG_EIE0_EN_SHIFT 2 + +#define SERDES_25G_LANE_FEATURE_CTLE_ADAPT_APG_MAP_CFG_INIT0_EN_MASK 0x01 +#define SERDES_25G_LANE_FEATURE_CTLE_ADAPT_APG_MAP_CFG_INIT0_EN_SHIFT 0 + +#define SERDES_25G_LANE_FEATURE_CTLE_ADAPT_APG_MAP_CFG_EIE0_EN_MASK 0x04 +#define SERDES_25G_LANE_FEATURE_CTLE_ADAPT_APG_MAP_CFG_EIE0_EN_SHIFT 2 + +#define SERDES_25G_LANE_FEATURE_CTLE_ADAPT_LFG_CFG_INIT0_SEL_MASK 0x03 +#define SERDES_25G_LANE_FEATURE_CTLE_ADAPT_LFG_CFG_INIT0_SEL_SHIFT 0 + +#define SERDES_25G_LANE_FEATURE_CTLE_ADAPT_LFG_CFG_INIT1_SEL_MASK 0x0C +#define SERDES_25G_LANE_FEATURE_CTLE_ADAPT_LFG_CFG_INIT1_SEL_SHIFT 2 + +#define SERDES_25G_LANE_FEATURE_CTLE_ADAPT_LFG_CFG_EIE0_SEL_MASK 0x30 +#define SERDES_25G_LANE_FEATURE_CTLE_ADAPT_LFG_CFG_EIE0_SEL_SHIFT 4 + +#define SERDES_25G_LANE_FEATURE_CTLE_ADAPT_LFG_CFG_EIE1_SEL_MASK 0xC0 +#define SERDES_25G_LANE_FEATURE_CTLE_ADAPT_LFG_CFG_EIE1_SEL_SHIFT 6 + +#define SERDES_25G_LANE_FEATURE_CTLE_ADAPT_HFG_CFG0_INIT0_EDGE_EN_MASK 0x01 +#define SERDES_25G_LANE_FEATURE_CTLE_ADAPT_HFG_CFG0_INIT0_EDGE_EN_SHIFT 0 + +#define SERDES_25G_LANE_FEATURE_CTLE_ADAPT_HFG_CFG0_INIT0_DATA_EN_MASK 0x02 +#define SERDES_25G_LANE_FEATURE_CTLE_ADAPT_HFG_CFG0_INIT0_DATA_EN_SHIFT 1 + +#define SERDES_25G_LANE_FEATURE_CTLE_ADAPT_HFG_CFG0_INIT1_EDGE_EN_MASK 0x04 +#define SERDES_25G_LANE_FEATURE_CTLE_ADAPT_HFG_CFG0_INIT1_EDGE_EN_SHIFT 2 + +#define SERDES_25G_LANE_FEATURE_CTLE_ADAPT_HFG_CFG0_INIT1_DATA_EN_MASK 0x08 +#define SERDES_25G_LANE_FEATURE_CTLE_ADAPT_HFG_CFG0_INIT1_DATA_EN_SHIFT 3 + +#define SERDES_25G_LANE_FEATURE_CTLE_ADAPT_HFG_CFG0_EIE0_EDGE_EN_MASK 0x10 +#define SERDES_25G_LANE_FEATURE_CTLE_ADAPT_HFG_CFG0_EIE0_EDGE_EN_SHIFT 4 + +#define SERDES_25G_LANE_FEATURE_CTLE_ADAPT_HFG_CFG0_EIE0_DATA_EN_MASK 0x20 +#define SERDES_25G_LANE_FEATURE_CTLE_ADAPT_HFG_CFG0_EIE0_DATA_EN_SHIFT 5 + +#define SERDES_25G_LANE_FEATURE_CTLE_ADAPT_HFG_CFG0_EIE1_EDGE_EN_MASK 0x40 +#define SERDES_25G_LANE_FEATURE_CTLE_ADAPT_HFG_CFG0_EIE1_EDGE_EN_SHIFT 6 + +#define SERDES_25G_LANE_FEATURE_CTLE_ADAPT_HFG_CFG0_EIE1_DATA_EN_MASK 0x80 +#define SERDES_25G_LANE_FEATURE_CTLE_ADAPT_HFG_CFG0_EIE1_DATA_EN_SHIFT 7 + +#define SERDES_25G_LANE_FEATURE_CTLE_ADAPT_HFG_CFG1_INIT0_RESULT_SEL_MASK 0x03 +#define SERDES_25G_LANE_FEATURE_CTLE_ADAPT_HFG_CFG1_INIT0_RESULT_SEL_SHIFT 0 + +#define SERDES_25G_LANE_FEATURE_CTLE_ADAPT_HFG_CFG1_INIT1_RESULT_SEL_MASK 0x0C +#define SERDES_25G_LANE_FEATURE_CTLE_ADAPT_HFG_CFG1_INIT1_RESULT_SEL_SHIFT 2 + +#define SERDES_25G_LANE_FEATURE_CTLE_ADAPT_HFG_CFG1_EIE0_RESULT_SEL_MASK 0x30 +#define SERDES_25G_LANE_FEATURE_CTLE_ADAPT_HFG_CFG1_EIE0_RESULT_SEL_SHIFT 4 + +#define SERDES_25G_LANE_FEATURE_CTLE_ADAPT_HFG_CFG1_EIE1_RESULT_SEL_MASK 0xC0 +#define SERDES_25G_LANE_FEATURE_CTLE_ADAPT_HFG_CFG1_EIE1_RESULT_SEL_SHIFT 6 + +#define SERDES_25G_LANE_FEATURE_CTLE_ADAPT_HFG_CFG2_CONT_EDGE_EN_MASK 0x01 +#define SERDES_25G_LANE_FEATURE_CTLE_ADAPT_HFG_CFG2_CONT_EDGE_EN_SHIFT 0 + +#define SERDES_25G_LANE_FEATURE_CTLE_ADAPT_HFG_CFG2_CONT_DATA_EN_MASK 0x02 +#define SERDES_25G_LANE_FEATURE_CTLE_ADAPT_HFG_CFG2_CONT_DATA_EN_SHIFT 1 + +#define SERDES_25G_LANE_FEATURE_CTLE_ADAPT_HFG_CFG2_CONT_RESULT_SEL_MASK 0x0C +#define SERDES_25G_LANE_FEATURE_CTLE_ADAPT_HFG_CFG2_CONT_RESULT_SEL_SHIFT 2 + +#define SERDES_25G_LANE_FEATURE_CTLE_ADAPT_MBS_CFG_INIT0_EN_MASK 0x01 +#define SERDES_25G_LANE_FEATURE_CTLE_ADAPT_MBS_CFG_INIT0_EN_SHIFT 0 + +#define SERDES_25G_LANE_FEATURE_CTLE_ADAPT_MBS_CFG_INIT1_EN_MASK 0x02 +#define SERDES_25G_LANE_FEATURE_CTLE_ADAPT_MBS_CFG_INIT1_EN_SHIFT 1 + +#define SERDES_25G_LANE_FEATURE_CTLE_ADAPT_MBS_CFG_EIE0_EN_MASK 0x04 +#define SERDES_25G_LANE_FEATURE_CTLE_ADAPT_MBS_CFG_EIE0_EN_SHIFT 2 + +#define SERDES_25G_LANE_FEATURE_CTLE_ADAPT_MBS_CFG_EIE1_EN_MASK 0x08 +#define SERDES_25G_LANE_FEATURE_CTLE_ADAPT_MBS_CFG_EIE1_EN_SHIFT 3 + +#define SERDES_25G_LANE_FEATURE_CTLE_ADAPT_MBS_CFG_CONT_EN_MASK 0x10 +#define SERDES_25G_LANE_FEATURE_CTLE_ADAPT_MBS_CFG_CONT_EN_SHIFT 4 + +#define SERDES_25G_LANE_FEATURE_CTLE_ADAPT_EIE0_CFG_AGCLOS_START_VAL_SEL_MASK 0x01 +#define SERDES_25G_LANE_FEATURE_CTLE_ADAPT_EIE0_CFG_AGCLOS_START_VAL_SEL_SHIFT 0 + +#define SERDES_25G_LANE_FEATURE_CTLE_ADAPT_EIE0_CFG_PLE_ATT_START_VAL_SEL_MASK 0x02 +#define SERDES_25G_LANE_FEATURE_CTLE_ADAPT_EIE0_CFG_PLE_ATT_START_VAL_SEL_SHIFT 1 + +#define SERDES_25G_LANE_FEATURE_CTLE_ADAPT_EIE0_CFG_GN_APG_START_VAL_SEL_MASK 0x04 +#define SERDES_25G_LANE_FEATURE_CTLE_ADAPT_EIE0_CFG_GN_APG_START_VAL_SEL_SHIFT 2 + +#define SERDES_25G_LANE_FEATURE_CTLE_ADAPT_EIE0_CFG_EQ_LFG_START_VAL_SEL_MASK 0x08 +#define SERDES_25G_LANE_FEATURE_CTLE_ADAPT_EIE0_CFG_EQ_LFG_START_VAL_SEL_SHIFT 3 + +#define SERDES_25G_LANE_FEATURE_CTLE_ADAPT_EIE0_CFG_GNEQ_CCL_LFG_START_VAL_SEL_MASK 0x10 +#define SERDES_25G_LANE_FEATURE_CTLE_ADAPT_EIE0_CFG_GNEQ_CCL_LFG_START_VAL_SEL_SHIFT 4 + +#define SERDES_25G_LANE_FEATURE_CTLE_ADAPT_EIE0_CFG_EQ_HFG_SQL_START_VAL_SEL_MASK 0x20 +#define SERDES_25G_LANE_FEATURE_CTLE_ADAPT_EIE0_CFG_EQ_HFG_SQL_START_VAL_SEL_SHIFT 5 + +#define SERDES_25G_LANE_FEATURE_CTLE_ADAPT_EIE0_CFG_EQ_MBF_START_VAL_SEL_MASK 0x40 +#define SERDES_25G_LANE_FEATURE_CTLE_ADAPT_EIE0_CFG_EQ_MBF_START_VAL_SEL_SHIFT 6 + +#define SERDES_25G_LANE_FEATURE_CTLE_ADAPT_EIE0_CFG_EQ_MBG_START_VAL_SEL_MASK 0x80 +#define SERDES_25G_LANE_FEATURE_CTLE_ADAPT_EIE0_CFG_EQ_MBG_START_VAL_SEL_SHIFT 7 + +#define SERDES_25G_LANE_FEATURE_DFE_CFG_TAP1_EN_MASK 0x01 +#define SERDES_25G_LANE_FEATURE_DFE_CFG_TAP1_EN_SHIFT 0 + +#define SERDES_25G_LANE_FEATURE_DFE_CFG_TAP2_EN_MASK 0x02 +#define SERDES_25G_LANE_FEATURE_DFE_CFG_TAP2_EN_SHIFT 1 + +#define SERDES_25G_LANE_FEATURE_DFE_CFG_TAP3_EN_MASK 0x04 +#define SERDES_25G_LANE_FEATURE_DFE_CFG_TAP3_EN_SHIFT 2 + +#define SERDES_25G_LANE_FEATURE_DFE_CFG_TAP4_EN_MASK 0x08 +#define SERDES_25G_LANE_FEATURE_DFE_CFG_TAP4_EN_SHIFT 3 + +#define SERDES_25G_LANE_FEATURE_DFE_CFG_TAP5_EN_MASK 0x10 +#define SERDES_25G_LANE_FEATURE_DFE_CFG_TAP5_EN_SHIFT 4 + +#define SERDES_25G_LANE_FEATURE_DFE_ADAPT_CFG_METHOD_SEL_MASK 0x01 +#define SERDES_25G_LANE_FEATURE_DFE_ADAPT_CFG_METHOD_SEL_SHIFT 0 + +#define SERDES_25G_LANE_FEATURE_DFE_ADAPT_CONT_CFG0_INTERVAL_7_0_MASK 0xFF +#define SERDES_25G_LANE_FEATURE_DFE_ADAPT_CONT_CFG0_INTERVAL_7_0_SHIFT 0 + +#define SERDES_25G_LANE_FEATURE_DFE_ADAPT_CONT_CFG1_INTERVAL_15_8_MASK 0xFF +#define SERDES_25G_LANE_FEATURE_DFE_ADAPT_CONT_CFG1_INTERVAL_15_8_SHIFT 0 + +#define SERDES_25G_LANE_FEATURE_DFE_ADAPT_CONT_CFG2_INTERVAL_23_16_MASK 0xFF +#define SERDES_25G_LANE_FEATURE_DFE_ADAPT_CONT_CFG2_INTERVAL_23_16_SHIFT 0 + +#define SERDES_25G_LANE_FEATURE_DFE_ADAPT_TAP1_CFG_TAP1_INIT_EN_MASK 0x01 +#define SERDES_25G_LANE_FEATURE_DFE_ADAPT_TAP1_CFG_TAP1_INIT_EN_SHIFT 0 + +#define SERDES_25G_LANE_FEATURE_DFE_ADAPT_TAP1_CFG_TAP1_EIE_EN_MASK 0x02 +#define SERDES_25G_LANE_FEATURE_DFE_ADAPT_TAP1_CFG_TAP1_EIE_EN_SHIFT 1 + +#define SERDES_25G_LANE_FEATURE_DFE_ADAPT_TAP1_CFG_TAP1_CONT_EN_MASK 0x04 +#define SERDES_25G_LANE_FEATURE_DFE_ADAPT_TAP1_CFG_TAP1_CONT_EN_SHIFT 2 + +#define SERDES_25G_LANE_FEATURE_DFE_ADAPT_TAP1_CFG_TAP1_START_VAL_SEL_MASK 0x08 +#define SERDES_25G_LANE_FEATURE_DFE_ADAPT_TAP1_CFG_TAP1_START_VAL_SEL_SHIFT 3 + +#define SERDES_25G_LANE_FEATURE_DFE_ADAPT_TAP2_CFG_TAP2_INIT_EN_MASK 0x01 +#define SERDES_25G_LANE_FEATURE_DFE_ADAPT_TAP2_CFG_TAP2_INIT_EN_SHIFT 0 + +#define SERDES_25G_LANE_FEATURE_DFE_ADAPT_TAP2_CFG_TAP2_EIE_EN_MASK 0x02 +#define SERDES_25G_LANE_FEATURE_DFE_ADAPT_TAP2_CFG_TAP2_EIE_EN_SHIFT 1 + +#define SERDES_25G_LANE_FEATURE_DFE_ADAPT_TAP2_CFG_TAP2_CONT_EN_MASK 0x04 +#define SERDES_25G_LANE_FEATURE_DFE_ADAPT_TAP2_CFG_TAP2_CONT_EN_SHIFT 2 + +#define SERDES_25G_LANE_FEATURE_DFE_ADAPT_TAP2_CFG_TAP2_START_VAL_SEL_MASK 0x08 +#define SERDES_25G_LANE_FEATURE_DFE_ADAPT_TAP2_CFG_TAP2_START_VAL_SEL_SHIFT 3 + +#define SERDES_25G_LANE_FEATURE_DFE_ADAPT_TAP3_CFG_TAP3_INIT_EN_MASK 0x01 +#define SERDES_25G_LANE_FEATURE_DFE_ADAPT_TAP3_CFG_TAP3_INIT_EN_SHIFT 0 + +#define SERDES_25G_LANE_FEATURE_DFE_ADAPT_TAP3_CFG_TAP3_EIE_EN_MASK 0x02 +#define SERDES_25G_LANE_FEATURE_DFE_ADAPT_TAP3_CFG_TAP3_EIE_EN_SHIFT 1 + +#define SERDES_25G_LANE_FEATURE_DFE_ADAPT_TAP3_CFG_TAP3_CONT_EN_MASK 0x04 +#define SERDES_25G_LANE_FEATURE_DFE_ADAPT_TAP3_CFG_TAP3_CONT_EN_SHIFT 2 + +#define SERDES_25G_LANE_FEATURE_DFE_ADAPT_TAP3_CFG_TAP3_START_VAL_SEL_MASK 0x08 +#define SERDES_25G_LANE_FEATURE_DFE_ADAPT_TAP3_CFG_TAP3_START_VAL_SEL_SHIFT 3 + +#define SERDES_25G_LANE_FEATURE_DFE_ADAPT_TAP4_CFG_TAP4_INIT_EN_MASK 0x01 +#define SERDES_25G_LANE_FEATURE_DFE_ADAPT_TAP4_CFG_TAP4_INIT_EN_SHIFT 0 + +#define SERDES_25G_LANE_FEATURE_DFE_ADAPT_TAP4_CFG_TAP4_EIE_EN_MASK 0x02 +#define SERDES_25G_LANE_FEATURE_DFE_ADAPT_TAP4_CFG_TAP4_EIE_EN_SHIFT 1 + +#define SERDES_25G_LANE_FEATURE_DFE_ADAPT_TAP4_CFG_TAP4_CONT_EN_MASK 0x04 +#define SERDES_25G_LANE_FEATURE_DFE_ADAPT_TAP4_CFG_TAP4_CONT_EN_SHIFT 2 + +#define SERDES_25G_LANE_FEATURE_DFE_ADAPT_TAP4_CFG_TAP4_START_VAL_SEL_MASK 0x08 +#define SERDES_25G_LANE_FEATURE_DFE_ADAPT_TAP4_CFG_TAP4_START_VAL_SEL_SHIFT 3 + +#define SERDES_25G_LANE_FEATURE_DFE_ADAPT_TAP5_CFG_TAP5_INIT_EN_MASK 0x01 +#define SERDES_25G_LANE_FEATURE_DFE_ADAPT_TAP5_CFG_TAP5_INIT_EN_SHIFT 0 + +#define SERDES_25G_LANE_FEATURE_DFE_ADAPT_TAP5_CFG_TAP5_EIE_EN_MASK 0x02 +#define SERDES_25G_LANE_FEATURE_DFE_ADAPT_TAP5_CFG_TAP5_EIE_EN_SHIFT 1 + +#define SERDES_25G_LANE_FEATURE_DFE_ADAPT_TAP5_CFG_TAP5_CONT_EN_MASK 0x04 +#define SERDES_25G_LANE_FEATURE_DFE_ADAPT_TAP5_CFG_TAP5_CONT_EN_SHIFT 2 + +#define SERDES_25G_LANE_FEATURE_DFE_ADAPT_TAP5_CFG_TAP5_START_VAL_SEL_MASK 0x08 +#define SERDES_25G_LANE_FEATURE_DFE_ADAPT_TAP5_CFG_TAP5_START_VAL_SEL_SHIFT 3 + +#define SERDES_25G_LANE_FEATURE_RX_CTRL_CFG0_CDR_LOCKD_EN_MASK 0x01 +#define SERDES_25G_LANE_FEATURE_RX_CTRL_CFG0_CDR_LOCKD_EN_SHIFT 0 + +#define SERDES_25G_LANE_FEATURE_RX_CTRL_CFG0_CDR_LOCKD_TIMEOUT_US_MASK 0xFE +#define SERDES_25G_LANE_FEATURE_RX_CTRL_CFG0_CDR_LOCKD_TIMEOUT_US_SHIFT 1 + +#define SERDES_25G_LANE_FEATURE_RX_CTRL_CFG1_CDR_LOCK_WAIT_TIME_US_MASK 0xFF +#define SERDES_25G_LANE_FEATURE_RX_CTRL_CFG1_CDR_LOCK_WAIT_TIME_US_SHIFT 0 + +#define SERDES_25G_LANE_FEATURE_RX_CTRL_CFG2_CDR_FREQ_MEASURE_EN_MASK 0x01 +#define SERDES_25G_LANE_FEATURE_RX_CTRL_CFG2_CDR_FREQ_MEASURE_EN_SHIFT 0 + +#define SERDES_25G_LANE_FEATURE_RX_CTRL_CFG3_RXCLKDIV_EN_MASK 0x01 +#define SERDES_25G_LANE_FEATURE_RX_CTRL_CFG3_RXCLKDIV_EN_SHIFT 0 + +#define SERDES_25G_LANE_FEATURE_RX_CTRL_CFG3_BIST_HANDSHAKE_EN_MASK 0x02 +#define SERDES_25G_LANE_FEATURE_RX_CTRL_CFG3_BIST_HANDSHAKE_EN_SHIFT 1 + +#define SERDES_25G_LANE_FEATURE_EYE_LOS_CFG0_SIG_DET_MODE_MASK 0x03 +#define SERDES_25G_LANE_FEATURE_EYE_LOS_CFG0_SIG_DET_MODE_SHIFT 0 + +#define SERDES_25G_LANE_FEATURE_EYE_LOS_CFG0_LOS_DET_MODE_MASK 0x0C +#define SERDES_25G_LANE_FEATURE_EYE_LOS_CFG0_LOS_DET_MODE_SHIFT 2 + +#define SERDES_25G_LANE_FEATURE_EYE_LOS_CFG1_SIG_DET_THRESHOLD_MASK 0xFF +#define SERDES_25G_LANE_FEATURE_EYE_LOS_CFG1_SIG_DET_THRESHOLD_SHIFT 0 + +#define SERDES_25G_LANE_FEATURE_EYE_LOS_CFG2_LOS_DET_THRESHOLD_MASK 0xFF +#define SERDES_25G_LANE_FEATURE_EYE_LOS_CFG2_LOS_DET_THRESHOLD_SHIFT 0 + +#define SERDES_25G_LANE_FEATURE_EYE_LOS_CFG3_INTERVAL_7_0_MASK 0xFF +#define SERDES_25G_LANE_FEATURE_EYE_LOS_CFG3_INTERVAL_7_0_SHIFT 0 + +#define SERDES_25G_LANE_FEATURE_EYE_LOS_CFG4_INTERVAL_15_8_MASK 0xFF +#define SERDES_25G_LANE_FEATURE_EYE_LOS_CFG4_INTERVAL_15_8_SHIFT 0 + +#define SERDES_25G_LANE_FEATURE_EYE_LOS_CFG5_SAMPLE_LEN_7_0_MASK 0xFF +#define SERDES_25G_LANE_FEATURE_EYE_LOS_CFG5_SAMPLE_LEN_7_0_SHIFT 0 + +#define SERDES_25G_LANE_FEATURE_EYE_LOS_CFG6_SAMPLE_LEN_11_8_MASK 0x0F +#define SERDES_25G_LANE_FEATURE_EYE_LOS_CFG6_SAMPLE_LEN_11_8_SHIFT 0 + +#define SERDES_25G_LANE_FEATURE_EYE_LOS_CFG7_PLE_ATT_MASK 0x07 +#define SERDES_25G_LANE_FEATURE_EYE_LOS_CFG7_PLE_ATT_SHIFT 0 + +#define SERDES_25G_LANE_FEATURE_EYE_LOS_CFG7_EQ_LFG_MASK 0xF8 +#define SERDES_25G_LANE_FEATURE_EYE_LOS_CFG7_EQ_LFG_SHIFT 3 + +#define SERDES_25G_LANE_FEATURE_EYE_LOS_CFG8_GN_APG_MASK 0x03 +#define SERDES_25G_LANE_FEATURE_EYE_LOS_CFG8_GN_APG_SHIFT 0 + +#define SERDES_25G_LANE_FEATURE_EYE_LOS_CFG8_HFG_SQL_MASK 0x7C +#define SERDES_25G_LANE_FEATURE_EYE_LOS_CFG8_HFG_SQL_SHIFT 2 + +#define SERDES_25G_LANE_FEATURE_EYE_LOS_CFG9_MBF_MASK 0x0F +#define SERDES_25G_LANE_FEATURE_EYE_LOS_CFG9_MBF_SHIFT 0 + +#define SERDES_25G_LANE_FEATURE_EYE_LOS_CFG9_MBG_MASK 0xF0 +#define SERDES_25G_LANE_FEATURE_EYE_LOS_CFG9_MBG_SHIFT 4 + +#define SERDES_25G_LANE_FEATURE_TEST_CFG0_LANE_MSM_DIS_MASK 0x01 +#define SERDES_25G_LANE_FEATURE_TEST_CFG0_LANE_MSM_DIS_SHIFT 0 + +#define SERDES_25G_LANE_FEATURE_TEST_CFG0_RX_CTRL_DIS_MASK 0x02 +#define SERDES_25G_LANE_FEATURE_TEST_CFG0_RX_CTRL_DIS_SHIFT 1 + +#define SERDES_25G_LANE_FEATURE_SPARE_CFG0_MASK 0xFF +#define SERDES_25G_LANE_FEATURE_SPARE_CFG0_SHIFT 0 + +#define SERDES_25G_LANE_FEATURE_SPARE_CFG1_MASK 0xFF +#define SERDES_25G_LANE_FEATURE_SPARE_CFG1_SHIFT 0 + +#define SERDES_25G_LANE_FEATURE_SPARE_CFG2_MASK 0xFF +#define SERDES_25G_LANE_FEATURE_SPARE_CFG2_SHIFT 0 + +#define SERDES_25G_LANE_FEATURE_SPARE_CFG3_MASK 0xFF +#define SERDES_25G_LANE_FEATURE_SPARE_CFG3_SHIFT 0 + +#define SERDES_25G_LANE_FEATURE_SPARE_CFG4_MASK 0xFF +#define SERDES_25G_LANE_FEATURE_SPARE_CFG4_SHIFT 0 + +#define SERDES_25G_LANE_FEATURE_SPARE_CFG5_MASK 0xFF +#define SERDES_25G_LANE_FEATURE_SPARE_CFG5_SHIFT 0 + +#define SERDES_25G_LANE_FEATURE_SPARE_CFG6_MASK 0xFF +#define SERDES_25G_LANE_FEATURE_SPARE_CFG6_SHIFT 0 + +#define SERDES_25G_LANE_FEATURE_SPARE_CFG7_MASK 0xFF +#define SERDES_25G_LANE_FEATURE_SPARE_CFG7_SHIFT 0 + +#ifdef _cplusplus +} +#endif + +#endif diff --git a/al_hal_serdes_25g_regs.h b/al_hal_serdes_25g_regs.h new file mode 100644 index 00000000000..64422f7e931 --- /dev/null +++ b/al_hal_serdes_25g_regs.h @@ -0,0 +1,434 @@ +/******************************************************************************* +Copyright (C) 2013 Annapurna Labs Ltd. + +This file may be licensed under the terms of the Annapurna Labs Commercial +License Agreement. + +Alternatively, this file can be distributed under the terms of the GNU General +Public License V2 or V3 as published by the Free Software Foundation and can be +found at http://www.gnu.org/licenses/gpl-2.0.html + +Alternatively, redistribution and use in source and binary forms, with or +without modification, are permitted provided that the following conditions are +met: + + * Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in + the documentation and/or other materials provided with the + distribution. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR + ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +*******************************************************************************/ + +/** + * @{ + * @file al_hal_serdes_c_regs.h + * + * @brief ... registers + * + */ + +#ifndef __AL_HAL_serdes_c_REGS_H__ +#define __AL_HAL_serdes_c_REGS_H__ + +#include "al_hal_plat_types.h" + +#ifdef __cplusplus +extern "C" { +#endif +/* +* Unit Registers +*/ + +struct al_serdes_c_gen { + /* [0x0] SERDES registers Version */ + uint32_t version; + uint32_t rsrvd_0[3]; + /* [0x10] SERDES register file address */ + uint32_t reg_addr; + /* [0x14] SERDES register file data */ + uint32_t reg_data; + /* [0x18] SERDES control */ + uint32_t ctrl; + /* [0x1c] SERDES cpu mem address */ + uint32_t cpu_prog_addr; + /* [0x20] SERDES cpu mem data */ + uint32_t cpu_prog_data; + /* [0x24] SERDES data mem address */ + uint32_t cpu_data_mem_addr; + /* [0x28] SERDES data mem data */ + uint32_t cpu_data_mem_data; + /* [0x2c] SERDES control */ + uint32_t rst; + /* [0x30] SERDES control */ + uint32_t status; + uint32_t rsrvd[51]; +}; +struct al_serdes_c_lane { + uint32_t rsrvd_0[4]; + /* [0x10] Data configuration */ + uint32_t cfg; + /* [0x14] Lane status */ + uint32_t stat; + /* [0x18] SERDES control */ + uint32_t reserved; + uint32_t rsrvd[25]; +}; + +struct al_serdes_c_regs { + uint32_t rsrvd_0[64]; + struct al_serdes_c_gen gen; /* [0x100] */ + struct al_serdes_c_lane lane[2]; /* [0x200] */ +}; + + +/* +* Registers Fields +*/ + + +/**** version register ****/ +/* Revision number (Minor) */ +#define SERDES_C_GEN_VERSION_RELEASE_NUM_MINOR_MASK 0x000000FF +#define SERDES_C_GEN_VERSION_RELEASE_NUM_MINOR_SHIFT 0 +/* Revision number (Major) */ +#define SERDES_C_GEN_VERSION_RELEASE_NUM_MAJOR_MASK 0x0000FF00 +#define SERDES_C_GEN_VERSION_RELEASE_NUM_MAJOR_SHIFT 8 +/* date of release */ +#define SERDES_C_GEN_VERSION_DATE_DAY_MASK 0x001F0000 +#define SERDES_C_GEN_VERSION_DATE_DAY_SHIFT 16 +/* month of release */ +#define SERDES_C_GEN_VERSION_DATA_MONTH_MASK 0x01E00000 +#define SERDES_C_GEN_VERSION_DATA_MONTH_SHIFT 21 +/* year of release (starting from 2000) */ +#define SERDES_C_GEN_VERSION_DATE_YEAR_MASK 0x3E000000 +#define SERDES_C_GEN_VERSION_DATE_YEAR_SHIFT 25 +/* Reserved */ +#define SERDES_C_GEN_VERSION_RESERVED_MASK 0xC0000000 +#define SERDES_C_GEN_VERSION_RESERVED_SHIFT 30 + +/**** reg_addr register ****/ +/* address value */ +#define SERDES_C_GEN_REG_ADDR_VAL_MASK 0x00007FFF +#define SERDES_C_GEN_REG_ADDR_VAL_SHIFT 0 + +/**** reg_data register ****/ +/* data value */ +#define SERDES_C_GEN_REG_DATA_VAL_MASK 0x000000FF +#define SERDES_C_GEN_REG_DATA_VAL_SHIFT 0 +/* Bit-wise write enable */ +#define SERDES_C_GEN_REG_DATA_STRB_MASK 0x0000FF00 +#define SERDES_C_GEN_REG_DATA_STRB_SHIFT 8 + +/**** ctrl register ****/ +/* + * 0x0 – Select reference clock from Bump + * 0x1 – Select inter-macro reference clock from the left side + * 0x2 – Same as 0x0 + * 0x3 – Select inter-macro reference clock from the right side + */ +#define SERDES_C_GEN_CTRL_REFCLK_INPUT_SEL_MASK 0x00000003 +#define SERDES_C_GEN_CTRL_REFCLK_INPUT_SEL_SHIFT 0 + +#define SERDES_C_GEN_CTRL_REFCLK_INPUT_SEL_REF \ + (0 << (SERDES_C_GEN_CTRL_REFCLK_INPUT_SEL_SHIFT)) +#define SERDES_C_GEN_CTRL_REFCLK_INPUT_SEL_L2R \ + (1 << (SERDES_C_GEN_CTRL_REFCLK_INPUT_SEL_SHIFT)) +#define SERDES_C_GEN_CTRL_REFCLK_INPUT_SEL_R2L \ + (3 << (SERDES_C_GEN_CTRL_REFCLK_INPUT_SEL_SHIFT)) + +/* + * 0x0 – Tied to 0 to save power + * 0x1 – Select reference clock from Bump + * 0x2 – Select inter-macro reference clock input from right side + * 0x3 – Same as 0x2 + */ +#define SERDES_C_GEN_CTRL_REFCLK_LEFT_SEL_MASK 0x00000030 +#define SERDES_C_GEN_CTRL_REFCLK_LEFT_SEL_SHIFT 4 + +#define SERDES_C_GEN_CTRL_REFCLK_LEFT_SEL_0 \ + (0 << (SERDES_C_GEN_CTRL_REFCLK_LEFT_SEL_SHIFT)) +#define SERDES_C_GEN_CTRL_REFCLK_LEFT_SEL_REF \ + (1 << (SERDES_C_GEN_CTRL_REFCLK_LEFT_SEL_SHIFT)) +#define SERDES_C_GEN_CTRL_REFCLK_LEFT_SEL_R2L \ + (2 << (SERDES_C_GEN_CTRL_REFCLK_LEFT_SEL_SHIFT)) + +/* + * 0x0 – Tied to 0 to save power + * 0x1 – Select reference clock from Bump + * 0x2 – Select inter-macro reference clock input from left side + * 0x3 – Same as 0x2 + */ +#define SERDES_C_GEN_CTRL_REFCLK_RIGHT_SEL_MASK 0x000000C0 +#define SERDES_C_GEN_CTRL_REFCLK_RIGHT_SEL_SHIFT 6 + +#define SERDES_C_GEN_CTRL_REFCLK_RIGHT_SEL_0 \ + (0 << (SERDES_C_GEN_CTRL_REFCLK_RIGHT_SEL_SHIFT)) +#define SERDES_C_GEN_CTRL_REFCLK_RIGHT_SEL_REF \ + (1 << (SERDES_C_GEN_CTRL_REFCLK_RIGHT_SEL_SHIFT)) +#define SERDES_C_GEN_CTRL_REFCLK_RIGHT_SEL_L2R \ + (2 << (SERDES_C_GEN_CTRL_REFCLK_RIGHT_SEL_SHIFT)) + +/* + * Program memory acknowledge - Only when the access + * to the program memory is not + * ready for the microcontroller, it + * is driven to 0 + */ +#define SERDES_C_GEN_CTRL_CPU_MEMPSACK (1 << 8) +/* + * Data memory acknowledge - Only when the access + * to the program memory is not + * ready for the microcontroller, it + * is driven to 0 + */ +#define SERDES_C_GEN_CTRL_CPU_MEMACK (1 << 12) +/* + * 0 - keep cpu clk as sb clk + * 1 – cpu_clk is sb_clk divided by 2 + */ +#define SERDES_C_GEN_CTRL_CPU_CLK_DIV (1 << 16) +/* + * 0x0 – OIF CEI-28G-SR + * 0x1 – OIF CIE-25G-LR + * 0x8 – XFI + * Others – Reserved + * + * Note that phy_ctrl_cfg_i[3] is used to signify high-speed/low-speed + */ +#define SERDES_C_GEN_CTRL_PHY_CTRL_CFG_MASK 0x00F00000 +#define SERDES_C_GEN_CTRL_PHY_CTRL_CFG_SHIFT 20 +/* + * 0 - Internal 8051 micro- controller is allowed to access the internal APB + * CSR. Internal APB runs at cpu_clk_i, and the accesses from the external APB + * in apb_clk_i domain to APB CSR are resynchronized to cpu_clk_i. 1 – Bypass + * CPU. Internal 8051 micro-controller is blocked from accessing the internal + * APB CSR. Internal APB runs at apb_clk_i. + */ +#define SERDES_C_GEN_CTRL_CPU_BYPASS (1 << 24) + +/**** cpu_prog_addr register ****/ +/* + * address value 32 bit, + * The firmware data will be 1 byte with 64K rows + */ +#define SERDES_C_GEN_CPU_PROG_ADDR_VAL_MASK 0x00007FFF +#define SERDES_C_GEN_CPU_PROG_ADDR_VAL_SHIFT 0 + +/**** cpu_data_mem_addr register ****/ +/* address value – 8K byte memory */ +#define SERDES_C_GEN_CPU_DATA_MEM_ADDR_VAL_MASK 0x00001FFF +#define SERDES_C_GEN_CPU_DATA_MEM_ADDR_VAL_SHIFT 0 + +/**** cpu_data_mem_data register ****/ +/* data value */ +#define SERDES_C_GEN_CPU_DATA_MEM_DATA_VAL_MASK 0x000000FF +#define SERDES_C_GEN_CPU_DATA_MEM_DATA_VAL_SHIFT 0 + +/**** rst register ****/ +/* Power on reset Signal – active low */ +#define SERDES_C_GEN_RST_POR_N (1 << 0) +/* CMU reset Active low */ +#define SERDES_C_GEN_RST_CM0_RST_N (1 << 1) +/* + * 0x0 – Normal / Active + * 0x1 – Partial power down + * 0x2 – Near complete power down (only + * refclk buffers and portions of analog bias + * active) + * 0x3 – complete power down (IDDQ mode) + * Can be asserted when CMU is in normal + * mode. These modes provide an increased + * power savings compared to reset mode. + * Signal is overridden by por_n_i so has no + * effect in power on reset state. + */ +#define SERDES_C_GEN_RST_CM0_PD_MASK 0x00000030 +#define SERDES_C_GEN_RST_CM0_PD_SHIFT 4 +/* Lane0 reset signal active low */ +#define SERDES_C_GEN_RST_LN0_RST_N (1 << 6) +/* Lane1 reset signal active low */ +#define SERDES_C_GEN_RST_LN1_RST_N (1 << 7) +/* + * 0x0 – Normal / Active + * 0x1 – Partial power down + * 0x2 – Most blocks powered down (only LOS + * active) + * 0x3 – complete power down (IDDQ mode) + * Can be asserted when Lane is in normal + * mode. These modes provide an increased + * power savings compared to reset mode. + * Signal is overridden by por_n_i so has no + * affect in power on reset state + */ +#define SERDES_C_GEN_RST_LN0_PD_MASK 0x00000300 +#define SERDES_C_GEN_RST_LN0_PD_SHIFT 8 +/* + * 0x0 – Normal / Active + * 0x1 – Partial power down + * 0x2 – Most blocks powered down (only LOS + * active) + * 0x3 – complete power down (IDDQ mode) + * Can be asserted when Lane is in normal + * mode. These modes provide an increased + * power savings compared to reset mode. + * Signal is overridden by por_n_i so has no + * affect in power on reset state + */ +#define SERDES_C_GEN_RST_LN1_PD_MASK 0x00000C00 +#define SERDES_C_GEN_RST_LN1_PD_SHIFT 10 + +#define SERDES_C_GEN_RST_CPU_MEM_RESET (1 << 12) + +#define SERDES_C_GEN_RST_CPU_MEM_SHUTDOWN (1 << 13) + +#define SERDES_C_GEN_RST_CAPRI_APB_RESET (1 << 14) + +/**** status register ****/ +/* + * 0x0 – No error + * 0x1 – PHY has an internal error + */ +#define SERDES_C_GEN_STATUS_ERR_O (1 << 0) +/* + * 0x0 – PHY is not ready to respond to + * cm0_rst_n_i and cm0_pd_i[1:0]. The + * signals should not be changed. + * 0x1 - PHY is ready to respond to + * cm0_rst_n_i and cm0_pd_i[1:0] + */ +#define SERDES_C_GEN_STATUS_CM0_RST_PD_READY (1 << 1) +/* + * Indicates CMU PLL has locked to the + * reference clock and all output clocks are at + * the correct frequency + */ +#define SERDES_C_GEN_STATUS_CM0_OK_O (1 << 2) +/* + * 0x0 – PHY is not ready to respond to + * ln0_rst_n and ln0_pd[1:0]. The signals + * should not be changed. + * 0x1 - PHY is ready to respond to lnX_rst_n_i + * and lnX_pd_i[1:0] + */ +#define SERDES_C_GEN_STATUS_LN0_RST_PD_READY (1 << 3) +/* + * 0x0 – PHY is not ready to respond to + * ln1_rst_n_i and ln1_pd[1:0]. The signals + * should not be changed. + * 0x1 - PHY is ready to respond to lnX_rst_n_i + * and lnX_pd_i[1:0] + */ +#define SERDES_C_GEN_STATUS_LN1_RST_PD_READY (1 << 4) +/* + * Active low when the CPU performs a wait cycle (internally or externally + * generated) + */ +#define SERDES_C_GEN_STATUS_CPU_WAITSTATE (1 << 5) + +#define SERDES_C_GEN_STATUS_TBUS_MASK 0x000FFF00 +#define SERDES_C_GEN_STATUS_TBUS_SHIFT 8 + +/**** cfg register ****/ +/* 1- Swap 32 bit data on RX side */ +#define SERDES_C_LANE_CFG_RX_LANE_SWAP (1 << 0) +/* 1- Swap 32 bit data on TX side */ +#define SERDES_C_LANE_CFG_TX_LANE_SWAP (1 << 1) +/* 1 – invert rx data polarity */ +#define SERDES_C_LANE_CFG_LN_CTRL_RXPOLARITY (1 << 2) +/* 1 – invert tx data polarity */ +#define SERDES_C_LANE_CFG_TX_LANE_POLARITY (1 << 3) +/* + * 0x0 –Data on lnX_txdata_o will not be + * transmitted. Transmitter will be placed into + * electrical idle. + * 0x1 – Data on the active bits of + * lnX_txdata_o will be transmitted + */ +#define SERDES_C_LANE_CFG_LN_CTRL_TX_EN (1 << 4) +/* + * Informs the PHY to bypass the output of the + * analog LOS detector and instead rely upon + * a protocol LOS mechanism in the SoC/ASIC + * 0x0 – LOS operates as normal + * 0x1 – Bypass analog LOS output and + * instead rely upon protocol-level LOS + * detection via input lnX_ctrl_los_eii_value + */ +#define SERDES_C_LANE_CFG_LN_CTRL_LOS_EII_EN (1 << 5) +/* + * If lnX_ctrl_los_eii_en_i = 1 then Informs + * the PHY that the received signal was lost + */ +#define SERDES_C_LANE_CFG_LN_CTRL_LOS_EII_VALUE (1 << 6) +/* One hot mux */ +#define SERDES_C_LANE_CFG_TX_DATA_SRC_SELECT_MASK 0x00000F00 +#define SERDES_C_LANE_CFG_TX_DATA_SRC_SELECT_SHIFT 8 +/* 0x0 - 20-bit 0x1 – 40-bit */ +#define SERDES_C_LANE_CFG_LN_CTRL_DATA_WIDTH (1 << 12) + +/**** stat register ****/ +/* + * x0 – lane is not ready to send and receive data + * 0x1 – lane is ready to send and receive data + */ +#define SERDES_C_LANE_STAT_LNX_STAT_OK (1 << 0) +/* + * 0x0 – received data run length has not + * exceed the programmable run length + * detector threshold + * 0x1 – received data run length has + * exceeded the programmable run length + * detector threshold + */ +#define SERDES_C_LANE_STAT_LN_STAT_RUNLEN_ERR (1 << 1) +/* + * 0x0 – data on lnX_rxdata_o are invalid + * 0x1 – data on the active bits of + * lnX_rxdata_o are valid + */ +#define SERDES_C_LANE_STAT_LN_STAT_RXVALID (1 << 2) +/* + * Loss of Signal (LOS) indicator that includes + * the combined functions of the digitally + * assisted analog LOS, digital LOS, and + * protocol LOS override features + * 0x0 – Signal detected on lnX_rxp_i / + * lnX_rxm_i pins + * 0x1 – No signal detected on lnX_rxp_i / + * lnX_rxm_i pins + */ +#define SERDES_C_LANE_STAT_LN_STAT_LOS (1 << 3) + +#define SERDES_C_LANE_STAT_LN_STAT_LOS_DEGLITCH (1 << 4) + +/**** reserved register ****/ + +#define SERDES_C_LANE_RESERVED_DEF_0_MASK 0x0000FFFF +#define SERDES_C_LANE_RESERVED_DEF_0_SHIFT 0 + +#define SERDES_C_LANE_RESERVED_DEF_1_MASK 0xFFFF0000 +#define SERDES_C_LANE_RESERVED_DEF_1_SHIFT 16 + +#ifdef __cplusplus +} +#endif + +#endif /* __AL_HAL_serdes_c_REGS_H__ */ + +/** @} end of ... group */ + + diff --git a/al_hal_serdes_hssp.h b/al_hal_serdes_hssp.h new file mode 100644 index 00000000000..fe530f6a31b --- /dev/null +++ b/al_hal_serdes_hssp.h @@ -0,0 +1,87 @@ +/******************************************************************************* +Copyright (C) 2015 Annapurna Labs Ltd. + +This file may be licensed under the terms of the Annapurna Labs Commercial +License Agreement. + +Alternatively, this file can be distributed under the terms of the GNU General +Public License V2 as published by the Free Software Foundation and can be +found at http://www.gnu.org/licenses/gpl-2.0.html + +Alternatively, redistribution and use in source and binary forms, with or +without modification, are permitted provided that the following conditions are +met: + + * Redistributions of source code must retain the above copyright notice, +this list of conditions and the following disclaimer. + + * Redistributions in binary form must reproduce the above copyright +notice, this list of conditions and the following disclaimer in +the documentation and/or other materials provided with the +distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +*******************************************************************************/ + +/** + * @defgroup group_serdes_api API + * SerDes HAL driver API + * @ingroup group_serdes SerDes + * @{ + * + * @file al_hal_serdes.h + * + * @brief Header file for the SerDes HAL driver + * + */ + +#ifndef __AL_HAL_SERDES_H__ +#define __AL_HAL_SERDES_H__ + +#include "al_hal_common.h" +#include "al_hal_serdes_interface.h" +#include "al_hal_serdes_hssp_regs.h" + +/* *INDENT-OFF* */ +#ifdef __cplusplus +extern "C" { +#endif +/* *INDENT-ON* */ + +/** + * Initializes a SERDES group object + * + * @param serdes_regs_base + * The SERDES register file base pointer + * + * @param obj + * An allocated, non initialized object context + * + * @return 0 if no error found. + * + */ +int al_serdes_hssp_handle_init( + void __iomem *serdes_regs_base, + struct al_serdes_grp_obj *obj); + + +/* *INDENT-OFF* */ +#ifdef __cplusplus +} +#endif + +/* *INDENT-ON* */ +#endif /* __AL_SRDS__ */ + +/** @} end of SERDES group */ + diff --git a/al_hal_serdes_hssp_internal_regs.h b/al_hal_serdes_hssp_internal_regs.h new file mode 100644 index 00000000000..d5b02151994 --- /dev/null +++ b/al_hal_serdes_hssp_internal_regs.h @@ -0,0 +1,749 @@ +/******************************************************************************* +Copyright (C) 2015 Annapurna Labs Ltd. + +This file may be licensed under the terms of the Annapurna Labs Commercial +License Agreement. + +Alternatively, this file can be distributed under the terms of the GNU General +Public License V2 as published by the Free Software Foundation and can be +found at http://www.gnu.org/licenses/gpl-2.0.html + +Alternatively, redistribution and use in source and binary forms, with or +without modification, are permitted provided that the following conditions are +met: + + * Redistributions of source code must retain the above copyright notice, +this list of conditions and the following disclaimer. + + * Redistributions in binary form must reproduce the above copyright +notice, this list of conditions and the following disclaimer in +the documentation and/or other materials provided with the +distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +*******************************************************************************/ +#ifndef __AL_SERDES_INTERNAL_REGS_H__ +#define __AL_SERDES_INTERNAL_REGS_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +/******************************************************************************* + * Per lane register fields + ******************************************************************************/ +/* + * RX and TX lane hard reset + * 0 - Hard reset is asserted + * 1 - Hard reset is de-asserted + */ +#define SERDES_IREG_FLD_CMNCTLPOR_HARDRSTBYPASS_REG_NUM 2 +#define SERDES_IREG_FLD_CMNCTLPOR_HARDRSTBYPASS_MASK 0x01 +#define SERDES_IREG_FLD_CMNCTLPOR_HARDRSTBYPASS_VAL_ASSERT 0x00 +#define SERDES_IREG_FLD_CMNCTLPOR_HARDRSTBYPASS_VAL_DEASSERT 0x01 + +/* + * RX and TX lane hard reset control + * 0 - Hard reset is taken from the interface pins + * 1 - Hard reset is taken from registers + */ +#define SERDES_IREG_FLD_CMNCTLPOR_HARDRSTBYPASSEN_REG_NUM 2 +#define SERDES_IREG_FLD_CMNCTLPOR_HARDRSTBYPASSEN_MASK 0x02 +#define SERDES_IREG_FLD_CMNCTLPOR_HARDRSTBYPASSEN_VAL_IFACE 0x00 +#define SERDES_IREG_FLD_CMNCTLPOR_HARDRSTBYPASSEN_VAL_REGS 0x02 + +/* RX lane power state control */ +#define SERDES_IREG_FLD_LANEPCSPSTATE_RX_REG_NUM 3 +#define SERDES_IREG_FLD_LANEPCSPSTATE_RX_MASK 0x1f +#define SERDES_IREG_FLD_LANEPCSPSTATE_RX_VAL_PD 0x01 +#define SERDES_IREG_FLD_LANEPCSPSTATE_RX_VAL_P2 0x02 +#define SERDES_IREG_FLD_LANEPCSPSTATE_RX_VAL_P1 0x04 +#define SERDES_IREG_FLD_LANEPCSPSTATE_RX_VAL_P0S 0x08 +#define SERDES_IREG_FLD_LANEPCSPSTATE_RX_VAL_P0 0x10 + +/* TX lane power state control */ +#define SERDES_IREG_FLD_LANEPCSPSTATE_TX_REG_NUM 4 +#define SERDES_IREG_FLD_LANEPCSPSTATE_TX_MASK 0x1f +#define SERDES_IREG_FLD_LANEPCSPSTATE_TX_VAL_PD 0x01 +#define SERDES_IREG_FLD_LANEPCSPSTATE_TX_VAL_P2 0x02 +#define SERDES_IREG_FLD_LANEPCSPSTATE_TX_VAL_P1 0x04 +#define SERDES_IREG_FLD_LANEPCSPSTATE_TX_VAL_P0S 0x08 +#define SERDES_IREG_FLD_LANEPCSPSTATE_TX_VAL_P0 0x10 + +/* RX lane word width */ +#define SERDES_IREG_FLD_PCSRX_DATAWIDTH_REG_NUM 5 +#define SERDES_IREG_FLD_PCSRX_DATAWIDTH_MASK 0x07 +#define SERDES_IREG_FLD_PCSRX_DATAWIDTH_VAL_8 0x00 +#define SERDES_IREG_FLD_PCSRX_DATAWIDTH_VAL_10 0x01 +#define SERDES_IREG_FLD_PCSRX_DATAWIDTH_VAL_16 0x02 +#define SERDES_IREG_FLD_PCSRX_DATAWIDTH_VAL_20 0x03 +#define SERDES_IREG_FLD_PCSRX_DATAWIDTH_VAL_32 0x04 +#define SERDES_IREG_FLD_PCSRX_DATAWIDTH_VAL_40 0x05 + +/* TX lane word width */ +#define SERDES_IREG_FLD_PCSTX_DATAWIDTH_REG_NUM 5 +#define SERDES_IREG_FLD_PCSTX_DATAWIDTH_MASK 0x70 +#define SERDES_IREG_FLD_PCSTX_DATAWIDTH_VAL_8 0x00 +#define SERDES_IREG_FLD_PCSTX_DATAWIDTH_VAL_10 0x10 +#define SERDES_IREG_FLD_PCSTX_DATAWIDTH_VAL_16 0x20 +#define SERDES_IREG_FLD_PCSTX_DATAWIDTH_VAL_20 0x30 +#define SERDES_IREG_FLD_PCSTX_DATAWIDTH_VAL_32 0x40 +#define SERDES_IREG_FLD_PCSTX_DATAWIDTH_VAL_40 0x50 + +/* RX lane rate select */ +#define SERDES_IREG_FLD_PCSRX_DIVRATE_REG_NUM 6 +#define SERDES_IREG_FLD_PCSRX_DIVRATE_MASK 0x07 +#define SERDES_IREG_FLD_PCSRX_DIVRATE_VAL_1_8 0x00 +#define SERDES_IREG_FLD_PCSRX_DIVRATE_VAL_1_4 0x01 +#define SERDES_IREG_FLD_PCSRX_DIVRATE_VAL_1_2 0x02 +#define SERDES_IREG_FLD_PCSRX_DIVRATE_VAL_1_1 0x03 + +/* TX lane rate select */ +#define SERDES_IREG_FLD_PCSTX_DIVRATE_REG_NUM 6 +#define SERDES_IREG_FLD_PCSTX_DIVRATE_MASK 0x70 +#define SERDES_IREG_FLD_PCSTX_DIVRATE_VAL_1_8 0x00 +#define SERDES_IREG_FLD_PCSTX_DIVRATE_VAL_1_4 0x10 +#define SERDES_IREG_FLD_PCSTX_DIVRATE_VAL_1_2 0x20 +#define SERDES_IREG_FLD_PCSTX_DIVRATE_VAL_1_1 0x30 + +/* + * PMA serial RX-to-TX loop-back enable (from AGC to IO Driver). Serial receive + * to transmit loopback: 0 - Disables loopback 1 - Transmits the untimed, + * partial equalized RX signal out the transmit IO pins + */ +#define SERDES_IREG_FLD_LB_RX2TXUNTIMEDEN_REG_NUM 7 +#define SERDES_IREG_FLD_LB_RX2TXUNTIMEDEN 0x10 + +/* + * PMA TX-to-RX buffered serial loop-back enable (bypasses IO Driver). Serial + * transmit to receive buffered loopback: 0 - Disables loopback 1 - Loops back + * the TX serializer output into the CDR + */ +#define SERDES_IREG_FLD_LB_TX2RXBUFTIMEDEN_REG_NUM 7 +#define SERDES_IREG_FLD_LB_TX2RXBUFTIMEDEN 0x20 + +/* + * PMA TX-to-RX I/O serial loop-back enable (loop back done directly from TX to + * RX pads). Serial IO loopback from the transmit lane IO pins to the receive + * lane IO pins: 0 - Disables loopback 1 - Loops back the driver IO signal to + * the RX IO pins + */ +#define SERDES_IREG_FLD_LB_TX2RXIOTIMEDEN_REG_NUM 7 +#define SERDES_IREG_FLD_LB_TX2RXIOTIMEDEN 0x40 + +/* + * PMA Parallel RX-to-TX loop-back enable. Parallel loopback from the PMA + * receive lane 20-bit data ports, to the transmit lane 20-bit data ports 0 - + * Disables loopback 1 - Loops back the 20-bit receive data port to the + * transmitter + */ +#define SERDES_IREG_FLD_LB_PARRX2TXTIMEDEN_REG_NUM 7 +#define SERDES_IREG_FLD_LB_PARRX2TXTIMEDEN 0x80 + +/* + * PMA CDR recovered-clock loopback enable; asserted when PARRX2TXTIMEDEN is 1. + * Transmit bit clock select: 0 - Selects synthesizer bit clock for transmit 1 + * - Selects CDR clock for transmit + */ +#define SERDES_IREG_FLD_LB_CDRCLK2TXEN_REG_NUM 7 +#define SERDES_IREG_FLD_LB_CDRCLK2TXEN 0x01 + +/* Receive lane BIST enable. Active High */ +#define SERDES_IREG_FLD_PCSRXBIST_EN_REG_NUM 8 +#define SERDES_IREG_FLD_PCSRXBIST_EN 0x01 + +/* TX lane BIST enable. Active High */ +#define SERDES_IREG_FLD_PCSTXBIST_EN_REG_NUM 8 +#define SERDES_IREG_FLD_PCSTXBIST_EN 0x02 + +/* + * RX BIST completion signal 0 - Indicates test is not completed 1 - Indicates + * the test has completed, and will remain high until a new test is initiated + */ +#define SERDES_IREG_FLD_RXBIST_DONE_REG_NUM 8 +#define SERDES_IREG_FLD_RXBIST_DONE 0x04 + +/* + * RX BIST error count overflow indicator. Indicates an overflow in the number + * of byte errors identified during the course of the test. This word is stable + * to sample when *_DONE_* signal has asserted + */ +#define SERDES_IREG_FLD_RXBIST_ERRCOUNT_OVERFLOW_REG_NUM 8 +#define SERDES_IREG_FLD_RXBIST_ERRCOUNT_OVERFLOW 0x08 + +/* + * RX BIST locked indicator 0 - Indicates BIST is not word locked and error + * comparisons have not begun yet 1 - Indicates BIST is word locked and error + * comparisons have begun + */ +#define SERDES_IREG_FLD_RXBIST_RXLOCKED_REG_NUM 8 +#define SERDES_IREG_FLD_RXBIST_RXLOCKED 0x10 + +/* + * RX BIST error count word. Indicates the number of byte errors identified + * during the course of the test. This word is stable to sample when *_DONE_* + * signal has asserted + */ +#define SERDES_IREG_FLD_RXBIST_ERRCOUNT_MSB_REG_NUM 9 +#define SERDES_IREG_FLD_RXBIST_ERRCOUNT_LSB_REG_NUM 10 + +/* Tx params */ +#define SERDES_IREG_TX_DRV_1_REG_NUM 21 +#define SERDES_IREG_TX_DRV_1_HLEV_MASK 0x7 +#define SERDES_IREG_TX_DRV_1_HLEV_SHIFT 0 +#define SERDES_IREG_TX_DRV_1_LEVN_MASK 0xf8 +#define SERDES_IREG_TX_DRV_1_LEVN_SHIFT 3 + +#define SERDES_IREG_TX_DRV_2_REG_NUM 22 +#define SERDES_IREG_TX_DRV_2_LEVNM1_MASK 0xf +#define SERDES_IREG_TX_DRV_2_LEVNM1_SHIFT 0 +#define SERDES_IREG_TX_DRV_2_LEVNM2_MASK 0x30 +#define SERDES_IREG_TX_DRV_2_LEVNM2_SHIFT 4 + +#define SERDES_IREG_TX_DRV_3_REG_NUM 23 +#define SERDES_IREG_TX_DRV_3_LEVNP1_MASK 0x7 +#define SERDES_IREG_TX_DRV_3_LEVNP1_SHIFT 0 +#define SERDES_IREG_TX_DRV_3_SLEW_MASK 0x18 +#define SERDES_IREG_TX_DRV_3_SLEW_SHIFT 3 + +/* Rx params */ +#define SERDES_IREG_RX_CALEQ_1_REG_NUM 24 +#define SERDES_IREG_RX_CALEQ_1_DCGAIN_MASK 0x7 +#define SERDES_IREG_RX_CALEQ_1_DCGAIN_SHIFT 0 +/* DFE post-shaping tap 3dB frequency */ +#define SERDES_IREG_RX_CALEQ_1_DFEPSTAP3DB_MASK 0x38 +#define SERDES_IREG_RX_CALEQ_1_DFEPSTAP3DB_SHIFT 3 + +#define SERDES_IREG_RX_CALEQ_2_REG_NUM 25 +/* DFE post-shaping tap gain */ +#define SERDES_IREG_RX_CALEQ_2_DFEPSTAPGAIN_MASK 0x7 +#define SERDES_IREG_RX_CALEQ_2_DFEPSTAPGAIN_SHIFT 0 +/* DFE first tap gain control */ +#define SERDES_IREG_RX_CALEQ_2_DFETAP1GAIN_MASK 0x78 +#define SERDES_IREG_RX_CALEQ_2_DFETAP1GAIN_SHIFT 3 + +#define SERDES_IREG_RX_CALEQ_3_REG_NUM 26 +#define SERDES_IREG_RX_CALEQ_3_DFETAP2GAIN_MASK 0xf +#define SERDES_IREG_RX_CALEQ_3_DFETAP2GAIN_SHIFT 0 +#define SERDES_IREG_RX_CALEQ_3_DFETAP3GAIN_MASK 0xf0 +#define SERDES_IREG_RX_CALEQ_3_DFETAP3GAIN_SHIFT 4 + +#define SERDES_IREG_RX_CALEQ_4_REG_NUM 27 +#define SERDES_IREG_RX_CALEQ_4_DFETAP4GAIN_MASK 0xf +#define SERDES_IREG_RX_CALEQ_4_DFETAP4GAIN_SHIFT 0 +#define SERDES_IREG_RX_CALEQ_4_LOFREQAGCGAIN_MASK 0x70 +#define SERDES_IREG_RX_CALEQ_4_LOFREQAGCGAIN_SHIFT 4 + +#define SERDES_IREG_RX_CALEQ_5_REG_NUM 28 +#define SERDES_IREG_RX_CALEQ_5_PRECAL_CODE_SEL_MASK 0x7 +#define SERDES_IREG_RX_CALEQ_5_PRECAL_CODE_SEL_SHIFT 0 +#define SERDES_IREG_RX_CALEQ_5_HIFREQAGCCAP_MASK 0xf8 +#define SERDES_IREG_RX_CALEQ_5_HIFREQAGCCAP_SHIFT 3 + +/* RX lane best eye point measurement result */ +#define SERDES_IREG_RXEQ_BEST_EYE_MSB_VAL_REG_NUM 29 +#define SERDES_IREG_RXEQ_BEST_EYE_LSB_VAL_REG_NUM 30 +#define SERDES_IREG_RXEQ_BEST_EYE_LSB_VAL_MASK 0x3F + +/* + * Adaptive RX Equalization enable + * 0 - Disables adaptive RX equalization. + * 1 - Enables adaptive RX equalization. + */ +#define SERDES_IREG_FLD_PCSRXEQ_START_REG_NUM 31 +#define SERDES_IREG_FLD_PCSRXEQ_START (1 << 0) + +/* + * Enables an eye diagram measurement + * within the PHY. + * 0 - Disables eye diagram measurement + * 1 - Enables eye diagram measurement + */ +#define SERDES_IREG_FLD_RXCALEYEDIAGFSMIN_START_REG_NUM 31 +#define SERDES_IREG_FLD_RXCALEYEDIAGFSMIN_START (1 << 1) + + +/* + * RX lane single roam eye point measurement start signal. + * If asserted, single measurement at fix XADJUST and YADJUST is started. + */ +#define SERDES_IREG_FLD_RXCALROAMEYEMEASIN_CYCLEEN_REG_NUM 31 +#define SERDES_IREG_FLD_RXCALROAMEYEMEASIN_CYCLEEN_START (1 << 2) + + +/* + * PHY Eye diagram measurement status + * signal + * 0 - Indicates eye diagram results are not + * valid for sampling + * 1 - Indicates eye diagram is complete and + * results are valid for sampling + */ +#define SERDES_IREG_FLD_RXCALEYEDIAGFSM_DONE_REG_NUM 32 +#define SERDES_IREG_FLD_RXCALEYEDIAGFSM_DONE (1 << 0) + +/* + * Eye diagram error signal. Indicates if the + * measurement was invalid because the eye + * diagram was interrupted by the link entering + * electrical idle. + * 0 - Indicates eye diagram is valid + * 1- Indicates an error occurred, and the eye + * diagram measurement should be re-run + */ +#define SERDES_IREG_FLD_RXCALEYEDIAGFSM_ERR_REG_NUM 32 +#define SERDES_IREG_FLD_RXCALEYEDIAGFSM_ERR (1 << 1) + +/* + * PHY Adaptive Equalization status + * 0 - Indicates Adaptive Equalization results are not valid for sampling + * 1 - Indicates Adaptive Equalization is complete and results are valid for + * sampling + */ +#define SERDES_IREG_FLD_RXCALROAMEYEMEASDONE_REG_NUM 32 +#define SERDES_IREG_FLD_RXCALROAMEYEMEASDONE (1 << 2) + +/* + * + * PHY Adaptive Equalization Status Signal + * 0 – Indicates adaptive equalization results + * are not valid for sampling + * 1 – Indicates adaptive equalization is + * complete and results are valid for sampling. + */ +#define SERDES_IREG_FLD_RXEQ_DONE_REG_NUM 32 +#define SERDES_IREG_FLD_RXEQ_DONE (1 << 3) + + +/* + * 7-bit eye diagram time adjust control + * - 6-bits per UI + * - spans 2 UI + */ +#define SERDES_IREG_FLD_RXCALROAMXADJUST_REG_NUM 33 + +/* 6-bit eye diagram voltage adjust control - spans +/-300mVdiff */ +#define SERDES_IREG_FLD_RXCALROAMYADJUST_REG_NUM 34 + +/* + * Eye diagram status signal. Safe for + * sampling when *DONE* signal has + * asserted + * 14'h0000 - Completely Closed Eye + * 14'hFFFF - Completely Open Eye + */ +#define SERDES_IREG_FLD_RXCALEYEDIAGFSM_EYESUM_MSB_REG_NUM 35 +#define SERDES_IREG_FLD_RXCALEYEDIAGFSM_EYESUM_MSB_MAKE 0xFF +#define SERDES_IREG_FLD_RXCALEYEDIAGFSM_EYESUM_MSB_SHIFT 0 + +#define SERDES_IREG_FLD_RXCALEYEDIAGFSM_EYESUM_LSB_REG_NUM 36 +#define SERDES_IREG_FLD_RXCALEYEDIAGFSM_EYESUM_LSB_MAKE 0x3F +#define SERDES_IREG_FLD_RXCALEYEDIAGFSM_EYESUM_LSB_SHIFT 0 + +/* + * RX lane single roam eye point measurement result. + * If 0, eye is open at current XADJUST and YADJUST settings. + */ +#define SERDES_IREG_FLD_RXCALROAMEYEMEAS_ACC_MSB_REG_NUM 37 +#define SERDES_IREG_FLD_RXCALROAMEYEMEAS_ACC_LSB_REG_NUM 38 + +/* + * Override enable for CDR lock to reference clock + * 0 - CDR is always locked to reference + * 1 - CDR operation mode (Lock2Reference or Lock2data are controlled internally + * depending on the incoming signal and ppm status) + */ +#define SERDES_IREG_FLD_RXLOCK2REF_OVREN_REG_NUM 39 +#define SERDES_IREG_FLD_RXLOCK2REF_OVREN (1 << 1) + +/* + * Selects Eye to capture based on edge + * 0 - Capture 1st Eye in Eye Diagram + * 1 - Capture 2nd Eye in Eye Diagram measurement + */ +#define SERDES_IREG_FLD_RXROAM_XORBITSEL_REG_NUM 39 +#define SERDES_IREG_FLD_RXROAM_XORBITSEL (1 << 2) +#define SERDES_IREG_FLD_RXROAM_XORBITSEL_1ST 0 +#define SERDES_IREG_FLD_RXROAM_XORBITSEL_2ND (1 << 2) + +/* + * RX Signal detect. 0 indicates no signal, 1 indicates signal detected. + */ +#define SERDES_IREG_FLD_RXRANDET_REG_NUM 41 +#define SERDES_IREG_FLD_RXRANDET_STAT 0x20 + +/* + * RX data polarity inversion control: + * 1'b0: no inversion + * 1'b1: invert polarity + */ +#define SERDES_IREG_FLD_POLARITY_RX_REG_NUM 46 +#define SERDES_IREG_FLD_POLARITY_RX_INV (1 << 0) + +/* + * TX data polarity inversion control: + * 1'b0: no inversion + * 1'b1: invert polarity + */ +#define SERDES_IREG_FLD_POLARITY_TX_REG_NUM 46 +#define SERDES_IREG_FLD_POLARITY_TX_INV (1 << 1) + +/* LANEPCSPSTATE* override enable (Active low) */ +#define SERDES_IREG_FLD_LANEPCSPSTATE_LOCWREN_REG_NUM 85 +#define SERDES_IREG_FLD_LANEPCSPSTATE_LOCWREN (1 << 0) + +/* LB* override enable (Active low) */ +#define SERDES_IREG_FLD_LB_LOCWREN_REG_NUM 85 +#define SERDES_IREG_FLD_LB_LOCWREN (1 << 1) + +/* PCSRX* override enable (Active low) */ +#define SERDES_IREG_FLD_PCSRX_LOCWREN_REG_NUM 85 +#define SERDES_IREG_FLD_PCSRX_LOCWREN (1 << 4) + +/* PCSRXBIST* override enable (Active low) */ +#define SERDES_IREG_FLD_PCSRXBIST_LOCWREN_REG_NUM 85 +#define SERDES_IREG_FLD_PCSRXBIST_LOCWREN (1 << 5) + +/* PCSRXEQ* override enable (Active low) */ +#define SERDES_IREG_FLD_PCSRXEQ_LOCWREN_REG_NUM 85 +#define SERDES_IREG_FLD_PCSRXEQ_LOCWREN (1 << 6) + +/* PCSTX* override enable (Active low) */ +#define SERDES_IREG_FLD_PCSTX_LOCWREN_REG_NUM 85 +#define SERDES_IREG_FLD_PCSTX_LOCWREN (1 << 7) + +/* + * group registers: + * SERDES_IREG_FLD_RXCALEYEDIAGFSMIN_LOCWREN, + * SERDES_IREG_FLD_RXCALROAMEYEMEASIN_LOCWREN + * SERDES_IREG_FLD_RXCALROAMXADJUST_LOCWREN + */ +#define SERDES_IREG_FLD_RXCAL_LOCWREN_REG_NUM 86 + +/* PCSTXBIST* override enable (Active low) */ +#define SERDES_IREG_FLD_PCSTXBIST_LOCWREN_REG_NUM 86 +#define SERDES_IREG_FLD_PCSTXBIST_LOCWREN (1 << 0) + +/* Override RX_CALCEQ through the internal registers (Active low) */ +#define SERDES_IREG_FLD_RX_DRV_OVERRIDE_EN_REG_NUM 86 +#define SERDES_IREG_FLD_RX_DRV_OVERRIDE_EN (1 << 3) + +#define SERDES_IREG_FLD_RXCALEYEDIAGFSMIN_LOCWREN_REG_NUM 86 +#define SERDES_IREG_FLD_RXCALEYEDIAGFSMIN_LOCWREN (1 << 4) + + +/* RXCALROAMEYEMEASIN* override enable - Active Low */ +#define SERDES_IREG_FLD_RXCALROAMEYEMEASIN_LOCWREN_REG_NUM 86 +#define SERDES_IREG_FLD_RXCALROAMEYEMEASIN_LOCWREN (1 << 6) + +/* RXCALROAMXADJUST* override enable - Active Low */ +#define SERDES_IREG_FLD_RXCALROAMXADJUST_LOCWREN_REG_NUM 86 +#define SERDES_IREG_FLD_RXCALROAMXADJUST_LOCWREN (1 << 7) + +/* RXCALROAMYADJUST* override enable - Active Low */ +#define SERDES_IREG_FLD_RXCALROAMYADJUST_LOCWREN_REG_NUM 87 +#define SERDES_IREG_FLD_RXCALROAMYADJUST_LOCWREN (1 << 0) + +/* RXCDRCALFOSC* override enable. Active Low */ +#define SERDES_IREG_FLD_RXCDRCALFOSC_LOCWREN_REG_NUM 87 +#define SERDES_IREG_FLD_RXCDRCALFOSC_LOCWREN (1 << 1) + +/* Over-write enable for RXEYEDIAGFSM_INITXVAL */ +#define SERDES_IREG_FLD_RXEYEDIAGFSM_LOCWREN_REG_NUM 87 +#define SERDES_IREG_FLD_RXEYEDIAGFSM_LOCWREN (1 << 2) + +/* Over-write enable for CMNCLKGENMUXSEL_TXINTERNAL */ +#define SERDES_IREG_FLD_RXTERMHIZ_LOCWREN_REG_NUM 87 +#define SERDES_IREG_FLD_RXTERMHIZ_LOCWREN (1 << 3) + +/* TXCALTCLKDUTY* override enable. Active Low */ +#define SERDES_IREG_FLD_TXCALTCLKDUTY_LOCWREN_REG_NUM 87 +#define SERDES_IREG_FLD_TXCALTCLKDUTY_LOCWREN (1 << 4) + +/* Override TX_DRV through the internal registers (Active low) */ +#define SERDES_IREG_FLD_TX_DRV_OVERRIDE_EN_REG_NUM 87 +#define SERDES_IREG_FLD_TX_DRV_OVERRIDE_EN (1 << 5) + +/******************************************************************************* + * Common lane register fields - PMA + ******************************************************************************/ +/* + * Common lane hard reset control + * 0 - Hard reset is taken from the interface pins + * 1 - Hard reset is taken from registers + */ +#define SERDES_IREG_FLD_CMNCTLPOR_HARDRSTBYPASSEN_SYNTH_REG_NUM 2 +#define SERDES_IREG_FLD_CMNCTLPOR_HARDRSTBYPASSEN_SYNTH_MASK 0x01 +#define SERDES_IREG_FLD_CMNCTLPOR_HARDRSTBYPASSEN_SYNTH_VAL_IFACE 0x00 +#define SERDES_IREG_FLD_CMNCTLPOR_HARDRSTBYPASSEN_SYNTH_VAL_REGS 0x01 + +/* + * Common lane hard reset + * 0 - Hard reset is asserted + * 1 - Hard reset is de-asserted + */ +#define SERDES_IREG_FLD_CMNCTLPOR_HARDRSTBYPASS_SYNTH_REG_NUM 2 +#define SERDES_IREG_FLD_CMNCTLPOR_HARDRSTBYPASS_SYNTH_MASK 0x02 +#define SERDES_IREG_FLD_CMNCTLPOR_HARDRSTBYPASS_SYNTH_VAL_ASSERT 0x00 +#define SERDES_IREG_FLD_CMNCTLPOR_HARDRSTBYPASS_SYNTH_VAL_DEASSERT 0x02 + +/* Synth power state control */ +#define SERDES_IREG_FLD_CMNPCSPSTATE_SYNTH_REG_NUM 3 +#define SERDES_IREG_FLD_CMNPCSPSTATE_SYNTH_MASK 0x1f +#define SERDES_IREG_FLD_CMNPCSPSTATE_SYNTH_VAL_PD 0x01 +#define SERDES_IREG_FLD_CMNPCSPSTATE_SYNTH_VAL_P2 0x02 +#define SERDES_IREG_FLD_CMNPCSPSTATE_SYNTH_VAL_P1 0x04 +#define SERDES_IREG_FLD_CMNPCSPSTATE_SYNTH_VAL_P0S 0x08 +#define SERDES_IREG_FLD_CMNPCSPSTATE_SYNTH_VAL_P0 0x10 + +/* Transmit datapath FIFO enable (Active High) */ +#define SERDES_IREG_FLD_CMNPCS_TXENABLE_REG_NUM 8 +#define SERDES_IREG_FLD_CMNPCS_TXENABLE (1 << 2) + +/* + * RX lost of signal detector enable + * - 0 - disable + * - 1 - enable + */ +#define SERDES_IREG_FLD_RXLOSDET_ENABLE_REG_NUM 13 +#define SERDES_IREG_FLD_RXLOSDET_ENABLE AL_BIT(4) + +/* Signal Detect Threshold Level */ +#define SERDES_IREG_FLD_RXELECIDLE_SIGDETTHRESH_REG_NUM 15 +#define SERDES_IREG_FLD_RXELECIDLE_SIGDETTHRESH_MASK AL_FIELD_MASK(2, 0) + +/* LOS Detect Threshold Level */ +#define SERDES_IREG_FLD_RXLOSDET_THRESH_REG_NUM 15 +#define SERDES_IREG_FLD_RXLOSDET_THRESH_MASK AL_FIELD_MASK(4, 3) +#define SERDES_IREG_FLD_RXLOSDET_THRESH_SHIFT 3 + +#define SERDES_IREG_FLD_RXEQ_COARSE_ITER_NUM_REG_NUM 30 +#define SERDES_IREG_FLD_RXEQ_COARSE_ITER_NUM_MASK 0x7f +#define SERDES_IREG_FLD_RXEQ_COARSE_ITER_NUM_SHIFT 0 + +#define SERDES_IREG_FLD_RXEQ_FINE_ITER_NUM_REG_NUM 31 +#define SERDES_IREG_FLD_RXEQ_FINE_ITER_NUM_MASK 0x7f +#define SERDES_IREG_FLD_RXEQ_FINE_ITER_NUM_SHIFT 0 + +#define SERDES_IREG_FLD_RXEQ_COARSE_RUN1_MASK_REG_NUM 32 +#define SERDES_IREG_FLD_RXEQ_COARSE_RUN1_MASK_MASK 0xff +#define SERDES_IREG_FLD_RXEQ_COARSE_RUN1_MASK_SHIFT 0 + +#define SERDES_IREG_FLD_RXEQ_COARSE_RUN2_MASK_REG_NUM 33 +#define SERDES_IREG_FLD_RXEQ_COARSE_RUN2_MASK_MASK 0x1 +#define SERDES_IREG_FLD_RXEQ_COARSE_RUN2_MASK_SHIFT 0 + +#define SERDES_IREG_FLD_RXEQ_COARSE_STEP_REG_NUM 33 +#define SERDES_IREG_FLD_RXEQ_COARSE_STEP_MASK 0x3e +#define SERDES_IREG_FLD_RXEQ_COARSE_STEP_SHIFT 1 + +#define SERDES_IREG_FLD_RXEQ_FINE_RUN1_MASK_REG_NUM 34 +#define SERDES_IREG_FLD_RXEQ_FINE_RUN1_MASK_MASK 0xff +#define SERDES_IREG_FLD_RXEQ_FINE_RUN1_MASK_SHIFT 0 + +#define SERDES_IREG_FLD_RXEQ_FINE_RUN2_MASK_REG_NUM 35 +#define SERDES_IREG_FLD_RXEQ_FINE_RUN2_MASK_MASK 0x1 +#define SERDES_IREG_FLD_RXEQ_FINE_RUN2_MASK_SHIFT 0 + +#define SERDES_IREG_FLD_RXEQ_FINE_STEP_REG_NUM 35 +#define SERDES_IREG_FLD_RXEQ_FINE_STEP_MASK 0x3e +#define SERDES_IREG_FLD_RXEQ_FINE_STEP_SHIFT 1 + +#define SERDES_IREG_FLD_RXEQ_LOOKUP_CODE_EN_REG_NUM 36 +#define SERDES_IREG_FLD_RXEQ_LOOKUP_CODE_EN_MASK 0xff +#define SERDES_IREG_FLD_RXEQ_LOOKUP_CODE_EN_SHIFT 0 + +#define SERDES_IREG_FLD_RXEQ_LOOKUP_LASTCODE_REG_NUM 37 +#define SERDES_IREG_FLD_RXEQ_LOOKUP_LASTCODE_MASK 0x7 +#define SERDES_IREG_FLD_RXEQ_LOOKUP_LASTCODE_SHIFT 0 + +#define SERDES_IREG_FLD_RXEQ_DCGAIN_LUP0_REG_NUM 43 +#define SERDES_IREG_FLD_RXEQ_DCGAIN_LUP0_MASK 0x7 +#define SERDES_IREG_FLD_RXEQ_DCGAIN_LUP0_SHIFT 0 + +#define SERDES_IREG_FLD_TX_BIST_PAT_REG_NUM(byte_num) (56 + (byte_num)) +#define SERDES_IREG_FLD_TX_BIST_PAT_NUM_BYTES 10 + +/* + * Selects the transmit BIST mode: + * 0 - Uses the 80-bit internal memory pattern (w/ OOB) + * 1 - Uses a 27 PRBS pattern + * 2 - Uses a 223 PRBS pattern + * 3 - Uses a 231 PRBS pattern + * 4 - Uses a 1010 clock pattern + * 5 and above - Reserved + */ +#define SERDES_IREG_FLD_CMNPCSBIST_MODESEL_REG_NUM 80 +#define SERDES_IREG_FLD_CMNPCSBIST_MODESEL_MASK 0x07 +#define SERDES_IREG_FLD_CMNPCSBIST_MODESEL_VAL_USER 0x00 +#define SERDES_IREG_FLD_CMNPCSBIST_MODESEL_VAL_PRBS7 0x01 +#define SERDES_IREG_FLD_CMNPCSBIST_MODESEL_VAL_PRBS23 0x02 +#define SERDES_IREG_FLD_CMNPCSBIST_MODESEL_VAL_PRBS31 0x03 +#define SERDES_IREG_FLD_CMNPCSBIST_MODESEL_VAL_CLK1010 0x04 + +/* Single-Bit error injection enable (on posedge) */ +#define SERDES_IREG_FLD_TXBIST_BITERROR_EN_REG_NUM 80 +#define SERDES_IREG_FLD_TXBIST_BITERROR_EN 0x20 + +/* CMNPCIEGEN3* override enable (Active Low) */ +#define SERDES_IREG_FLD_CMNPCIEGEN3_LOCWREN_REG_NUM 95 +#define SERDES_IREG_FLD_CMNPCIEGEN3_LOCWREN (1 << 2) + +/* CMNPCS* override enable (Active Low) */ +#define SERDES_IREG_FLD_CMNPCS_LOCWREN_REG_NUM 95 +#define SERDES_IREG_FLD_CMNPCS_LOCWREN (1 << 3) + +/* CMNPCSBIST* override enable (Active Low) */ +#define SERDES_IREG_FLD_CMNPCSBIST_LOCWREN_REG_NUM 95 +#define SERDES_IREG_FLD_CMNPCSBIST_LOCWREN (1 << 4) + +/* CMNPCSPSTATE* override enable (Active Low) */ +#define SERDES_IREG_FLD_CMNPCSPSTATE_LOCWREN_REG_NUM 95 +#define SERDES_IREG_FLD_CMNPCSPSTATE_LOCWREN (1 << 5) + +/* PCS_EN* override enable (Active Low) */ +#define SERDES_IREG_FLD_PCS_LOCWREN_REG_NUM 96 +#define SERDES_IREG_FLD_PCS_LOCWREN (1 << 3) + +/* Eye diagram sample count */ +#define SERDES_IREG_FLD_EYE_DIAG_SAMPLE_CNT_MSB_REG_NUM 150 +#define SERDES_IREG_FLD_EYE_DIAG_SAMPLE_CNT_MSB_MASK 0xff +#define SERDES_IREG_FLD_EYE_DIAG_SAMPLE_CNT_MSB_SHIFT 0 + +#define SERDES_IREG_FLD_EYE_DIAG_SAMPLE_CNT_LSB_REG_NUM 151 +#define SERDES_IREG_FLD_EYE_DIAG_SAMPLE_CNT_LSB_MASK 0xff +#define SERDES_IREG_FLD_EYE_DIAG_SAMPLE_CNT_LSB_SHIFT 0 + +/* override control */ +#define SERDES_IREG_FLD_RXLOCK2REF_LOCWREN_REG_NUM 230 +#define SERDES_IREG_FLD_RXLOCK2REF_LOCWREN 1 << 0 + +#define SERDES_IREG_FLD_RXCALEYEDIAGFSM_BERTHRESHOLD1_REG_NUM 623 +#define SERDES_IREG_FLD_RXCALEYEDIAGFSM_BERTHRESHOLD1_MASK 0xff +#define SERDES_IREG_FLD_RXCALEYEDIAGFSM_BERTHRESHOLD1_SHIFT 0 + +#define SERDES_IREG_FLD_RXCALEYEDIAGFSM_BERTHRESHOLD2_REG_NUM 624 +#define SERDES_IREG_FLD_RXCALEYEDIAGFSM_BERTHRESHOLD2_MASK 0xff +#define SERDES_IREG_FLD_RXCALEYEDIAGFSM_BERTHRESHOLD2_SHIFT 0 + +/* X and Y coefficient return value */ +#define SERDES_IREG_FLD_RXCALEYEDIAGFSM_X_Y_VALWEIGHT_REG_NUM 626 +#define SERDES_IREG_FLD_RXCALEYEDIAGFSM_XVALWEIGHT_MASK 0x0F +#define SERDES_IREG_FLD_RXCALEYEDIAGFSM_XVALWEIGHT_SHIFT 0 +#define SERDES_IREG_FLD_RXCALEYEDIAGFSM_YVALWEIGHT_MASK 0xF0 +#define SERDES_IREG_FLD_RXCALEYEDIAGFSM_YVALWEIGHT_SHIFT 4 + +/* X coarse scan step */ +#define SERDES_IREG_FLD_RXCALEYEDIAGFSM_XVALCOARSE_REG_NUM 627 +#define SERDES_IREG_FLD_RXCALEYEDIAGFSM_XVALCOARSE_MASK 0x7F +#define SERDES_IREG_FLD_RXCALEYEDIAGFSM_XVALCOARSE_SHIFT 0 + +/* X fine scan step */ +#define SERDES_IREG_FLD_RXCALEYEDIAGFSM_XVALFINE_REG_NUM 628 +#define SERDES_IREG_FLD_RXCALEYEDIAGFSM_XVALFINE_MASK 0x7F +#define SERDES_IREG_FLD_RXCALEYEDIAGFSM_XVALFINE_SHIFT 0 + +/* Y coarse scan step */ +#define SERDES_IREG_FLD_RXCALEYEDIAGFSM_YVALCOARSE_REG_NUM 629 +#define SERDES_IREG_FLD_RXCALEYEDIAGFSM_YVALCOARSE_MASK 0x0F +#define SERDES_IREG_FLD_RXCALEYEDIAGFSM_YVALCOARSE_SHIFT 0 + +/* Y fine scan step */ +#define SERDES_IREG_FLD_RXCALEYEDIAGFSM_YVALFINE_REG_NUM 630 +#define SERDES_IREG_FLD_RXCALEYEDIAGFSM_YVALFINE_MASK 0x0F +#define SERDES_IREG_FLD_RXCALEYEDIAGFSM_YVALFINE_SHIFT 0 + +#define SERDES_IREG_FLD_PPMDRIFTCOUNT1_REG_NUM 157 + +#define SERDES_IREG_FLD_PPMDRIFTCOUNT2_REG_NUM 158 + +#define SERDES_IREG_FLD_PPMDRIFTMAX1_REG_NUM 159 + +#define SERDES_IREG_FLD_PPMDRIFTMAX2_REG_NUM 160 + +#define SERDES_IREG_FLD_SYNTHPPMDRIFTMAX1_REG_NUM 163 + +#define SERDES_IREG_FLD_SYNTHPPMDRIFTMAX2_REG_NUM 164 + +/******************************************************************************* + * Common lane register fields - PCS + ******************************************************************************/ +#define SERDES_IREG_FLD_PCS_VPCSIF_OVR_RATE_REG_NUM 3 +#define SERDES_IREG_FLD_PCS_VPCSIF_OVR_RATE_MASK AL_FIELD_MASK(5, 4) +#define SERDES_IREG_FLD_PCS_VPCSIF_OVR_RATE_SHIFT 4 + +#define SERDES_IREG_FLD_PCS_VPCSIF_OVR_RATE_ENA_REG_NUM 6 +#define SERDES_IREG_FLD_PCS_VPCSIF_OVR_RATE_ENA AL_BIT(2) + +#define SERDES_IREG_FLD_PCS_EBUF_FULL_D2R1_REG_NUM 18 +#define SERDES_IREG_FLD_PCS_EBUF_FULL_D2R1_REG_MASK 0x1F +#define SERDES_IREG_FLD_PCS_EBUF_FULL_D2R1_REG_SHIFT 0 + +#define SERDES_IREG_FLD_PCS_EBUF_FULL_PCIE_G3_REG_NUM 19 +#define SERDES_IREG_FLD_PCS_EBUF_FULL_PCIE_G3_REG_MASK 0x7C +#define SERDES_IREG_FLD_PCS_EBUF_FULL_PCIE_G3_REG_SHIFT 2 + +#define SERDES_IREG_FLD_PCS_EBUF_RD_THRESHOLD_D2R1_REG_NUM 20 +#define SERDES_IREG_FLD_PCS_EBUF_RD_THRESHOLD_D2R1_REG_MASK 0x1F +#define SERDES_IREG_FLD_PCS_EBUF_RD_THRESHOLD_D2R1_REG_SHIFT 0 + +#define SERDES_IREG_FLD_PCS_EBUF_RD_THRESHOLD_PCIE_G3_REG_NUM 21 +#define SERDES_IREG_FLD_PCS_EBUF_RD_THRESHOLD_PCIE_G3_REG_MASK 0x7C +#define SERDES_IREG_FLD_PCS_EBUF_RD_THRESHOLD_PCIE_G3_REG_SHIFT 2 + +#define SERDES_IREG_FLD_PCS_RXEQ_COARSE_ITER_NUM_REG_NUM 22 +#define SERDES_IREG_FLD_PCS_RXEQ_COARSE_ITER_NUM_MASK 0x7f +#define SERDES_IREG_FLD_PCS_RXEQ_COARSE_ITER_NUM_SHIFT 0 + +#define SERDES_IREG_FLD_PCS_RXEQ_FINE_ITER_NUM_REG_NUM 34 +#define SERDES_IREG_FLD_PCS_RXEQ_FINE_ITER_NUM_MASK 0x7f +#define SERDES_IREG_FLD_PCS_RXEQ_FINE_ITER_NUM_SHIFT 0 + +#define SERDES_IREG_FLD_PCS_RXEQ_COARSE_RUN1_MASK_REG_NUM 23 +#define SERDES_IREG_FLD_PCS_RXEQ_COARSE_RUN1_MASK_MASK 0xff +#define SERDES_IREG_FLD_PCS_RXEQ_COARSE_RUN1_MASK_SHIFT 0 + +#define SERDES_IREG_FLD_PCS_RXEQ_COARSE_RUN2_MASK_REG_NUM 22 +#define SERDES_IREG_FLD_PCS_RXEQ_COARSE_RUN2_MASK_MASK 0x80 +#define SERDES_IREG_FLD_PCS_RXEQ_COARSE_RUN2_MASK_SHIFT 7 + +#define SERDES_IREG_FLD_PCS_RXEQ_COARSE_STEP_REG_NUM 24 +#define SERDES_IREG_FLD_PCS_RXEQ_COARSE_STEP_MASK 0x3e +#define SERDES_IREG_FLD_PCS_RXEQ_COARSE_STEP_SHIFT 1 + +#define SERDES_IREG_FLD_PCS_RXEQ_FINE_RUN1_MASK_REG_NUM 35 +#define SERDES_IREG_FLD_PCS_RXEQ_FINE_RUN1_MASK_MASK 0xff +#define SERDES_IREG_FLD_PCS_RXEQ_FINE_RUN1_MASK_SHIFT 0 + +#define SERDES_IREG_FLD_PCS_RXEQ_FINE_RUN2_MASK_REG_NUM 34 +#define SERDES_IREG_FLD_PCS_RXEQ_FINE_RUN2_MASK_MASK 0x80 +#define SERDES_IREG_FLD_PCS_RXEQ_FINE_RUN2_MASK_SHIFT 7 + +#define SERDES_IREG_FLD_PCS_RXEQ_FINE_STEP_REG_NUM 36 +#define SERDES_IREG_FLD_PCS_RXEQ_FINE_STEP_MASK 0x1f +#define SERDES_IREG_FLD_PCS_RXEQ_FINE_STEP_SHIFT 0 + +#define SERDES_IREG_FLD_PCS_RXEQ_LOOKUP_CODE_EN_REG_NUM 37 +#define SERDES_IREG_FLD_PCS_RXEQ_LOOKUP_CODE_EN_MASK 0xff +#define SERDES_IREG_FLD_PCS_RXEQ_LOOKUP_CODE_EN_SHIFT 0 + +#define SERDES_IREG_FLD_PCS_RXEQ_LOOKUP_LASTCODE_REG_NUM 36 +#define SERDES_IREG_FLD_PCS_RXEQ_LOOKUP_LASTCODE_MASK 0xe0 +#define SERDES_IREG_FLD_PCS_RXEQ_LOOKUP_LASTCODE_SHIFT 5 + +#ifdef __cplusplus +} +#endif + +#endif /* __AL_serdes_REG_H */ + diff --git a/al_hal_serdes_hssp_regs.h b/al_hal_serdes_hssp_regs.h new file mode 100644 index 00000000000..20f6cbfa020 --- /dev/null +++ b/al_hal_serdes_hssp_regs.h @@ -0,0 +1,494 @@ +/******************************************************************************* +Copyright (C) 2015 Annapurna Labs Ltd. + +This file may be licensed under the terms of the Annapurna Labs Commercial +License Agreement. + +Alternatively, this file can be distributed under the terms of the GNU General +Public License V2 as published by the Free Software Foundation and can be +found at http://www.gnu.org/licenses/gpl-2.0.html + +Alternatively, redistribution and use in source and binary forms, with or +without modification, are permitted provided that the following conditions are +met: + + * Redistributions of source code must retain the above copyright notice, +this list of conditions and the following disclaimer. + + * Redistributions in binary form must reproduce the above copyright +notice, this list of conditions and the following disclaimer in +the documentation and/or other materials provided with the +distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +*******************************************************************************/ + +/** + * @{ + * @file al_hal_serdes_regs.h + * + * @brief ... registers + * + */ + +#ifndef __AL_HAL_SERDES_REGS_H__ +#define __AL_HAL_SERDES_REGS_H__ + +#include "al_hal_plat_types.h" + +#ifdef __cplusplus +extern "C" { +#endif +/* +* Unit Registers +*/ + +struct serdes_gen { + /* [0x0] SerDes Registers Version */ + uint32_t version; + uint32_t rsrvd_0[3]; + /* [0x10] SerDes register file address */ + uint32_t reg_addr; + /* [0x14] SerDes register file data */ + uint32_t reg_data; + uint32_t rsrvd_1[2]; + /* [0x20] SerDes control */ + uint32_t ictl_multi_bist; + /* [0x24] SerDes control */ + uint32_t ictl_pcs; + /* [0x28] SerDes control */ + uint32_t ictl_pma; + uint32_t rsrvd_2; + /* [0x30] SerDes control */ + uint32_t ipd_multi_synth; + /* [0x34] SerDes control */ + uint32_t irst; + /* [0x38] SerDes control */ + uint32_t octl_multi_synthready; + /* [0x3c] SerDes control */ + uint32_t octl_multi_synthstatus; + /* [0x40] SerDes control */ + uint32_t clk_out; + uint32_t rsrvd[47]; +}; +struct serdes_lane { + uint32_t rsrvd1[4]; + /* [0x10] SerDes status */ + uint32_t octl_pma; + /* [0x14] SerDes control */ + uint32_t ictl_multi_andme; + /* [0x18] SerDes control */ + uint32_t ictl_multi_lb; + /* [0x1c] SerDes control */ + uint32_t ictl_multi_rxbist; + /* [0x20] SerDes control */ + uint32_t ictl_multi_txbist; + /* [0x24] SerDes control */ + uint32_t ictl_multi; + /* [0x28] SerDes control */ + uint32_t ictl_multi_rxeq; + /* [0x2c] SerDes control */ + uint32_t ictl_multi_rxeq_l_low; + /* [0x30] SerDes control */ + uint32_t ictl_multi_rxeq_l_high; + /* [0x34] SerDes control */ + uint32_t ictl_multi_rxeyediag; + /* [0x38] SerDes control */ + uint32_t ictl_multi_txdeemph; + /* [0x3c] SerDes control */ + uint32_t ictl_multi_txmargin; + /* [0x40] SerDes control */ + uint32_t ictl_multi_txswing; + /* [0x44] SerDes control */ + uint32_t idat_multi; + /* [0x48] SerDes control */ + uint32_t ipd_multi; + /* [0x4c] SerDes control */ + uint32_t octl_multi_rxbist; + /* [0x50] SerDes control */ + uint32_t octl_multi; + /* [0x54] SerDes control */ + uint32_t octl_multi_rxeyediag; + /* [0x58] SerDes control */ + uint32_t odat_multi_rxbist; + /* [0x5c] SerDes control */ + uint32_t odat_multi_rxeq; + /* [0x60] SerDes control */ + uint32_t multi_rx_dvalid; + /* [0x64] SerDes control */ + uint32_t reserved; + uint32_t rsrvd[6]; +}; + +struct al_serdes_regs { + uint32_t rsrvd_0[64]; + struct serdes_gen gen; /* [0x100] */ + struct serdes_lane lane[4]; /* [0x200] */ +}; + + +/* +* Registers Fields +*/ + + +/**** version register ****/ +/* Revision number (Minor) */ +#define SERDES_GEN_VERSION_RELEASE_NUM_MINOR_MASK 0x000000FF +#define SERDES_GEN_VERSION_RELEASE_NUM_MINOR_SHIFT 0 +/* Revision number (Major) */ +#define SERDES_GEN_VERSION_RELEASE_NUM_MAJOR_MASK 0x0000FF00 +#define SERDES_GEN_VERSION_RELEASE_NUM_MAJOR_SHIFT 8 +/* Date of release */ +#define SERDES_GEN_VERSION_DATE_DAY_MASK 0x001F0000 +#define SERDES_GEN_VERSION_DATE_DAY_SHIFT 16 +/* Month of release */ +#define SERDES_GEN_VERSION_DATA_MONTH_MASK 0x01E00000 +#define SERDES_GEN_VERSION_DATA_MONTH_SHIFT 21 +/* Year of release (starting from 2000) */ +#define SERDES_GEN_VERSION_DATE_YEAR_MASK 0x3E000000 +#define SERDES_GEN_VERSION_DATE_YEAR_SHIFT 25 +/* Reserved */ +#define SERDES_GEN_VERSION_RESERVED_MASK 0xC0000000 +#define SERDES_GEN_VERSION_RESERVED_SHIFT 30 + +/**** reg_addr register ****/ +/* Address value */ +#define SERDES_GEN_REG_ADDR_VAL_MASK 0x0000FFFF +#define SERDES_GEN_REG_ADDR_VAL_SHIFT 0 + +/**** reg_data register ****/ +/* Data value */ +#define SERDES_GEN_REG_DATA_VAL_MASK 0x000000FF +#define SERDES_GEN_REG_DATA_VAL_SHIFT 0 + +/**** ICTL_MULTI_BIST register ****/ + +#define SERDES_GEN_ICTL_MULTI_BIST_MODESEL_NT_MASK 0x00000007 +#define SERDES_GEN_ICTL_MULTI_BIST_MODESEL_NT_SHIFT 0 + +/**** ICTL_PCS register ****/ + +#define SERDES_GEN_ICTL_PCS_EN_NT (1 << 0) + +/**** ICTL_PMA register ****/ + +#define SERDES_GEN_ICTL_PMA_REF_SEL_NT_MASK 0x00000007 +#define SERDES_GEN_ICTL_PMA_REF_SEL_NT_SHIFT 0 + +#define SERDES_GEN_ICTL_PMA_REF_SEL_NT_REF \ + (0 << (SERDES_GEN_ICTL_PMA_REF_SEL_NT_SHIFT)) +#define SERDES_GEN_ICTL_PMA_REF_SEL_NT_R2L \ + (3 << (SERDES_GEN_ICTL_PMA_REF_SEL_NT_SHIFT)) +#define SERDES_GEN_ICTL_PMA_REF_SEL_NT_L2R \ + (4 << (SERDES_GEN_ICTL_PMA_REF_SEL_NT_SHIFT)) + +#define SERDES_GEN_ICTL_PMA_REFBUSRIGHT2LEFT_MODE_NT_MASK 0x00000070 +#define SERDES_GEN_ICTL_PMA_REFBUSRIGHT2LEFT_MODE_NT_SHIFT 4 + +#define SERDES_GEN_ICTL_PMA_REFBUSRIGHT2LEFT_MODE_NT_0 \ + (0 << (SERDES_GEN_ICTL_PMA_REFBUSRIGHT2LEFT_MODE_NT_SHIFT)) +#define SERDES_GEN_ICTL_PMA_REFBUSRIGHT2LEFT_MODE_NT_REF \ + (2 << (SERDES_GEN_ICTL_PMA_REFBUSRIGHT2LEFT_MODE_NT_SHIFT)) +#define SERDES_GEN_ICTL_PMA_REFBUSRIGHT2LEFT_MODE_NT_R2L \ + (3 << (SERDES_GEN_ICTL_PMA_REFBUSRIGHT2LEFT_MODE_NT_SHIFT)) + +#define SERDES_GEN_ICTL_PMA_REFBUSLEFT2RIGHT_MODE_NT_MASK 0x00000700 +#define SERDES_GEN_ICTL_PMA_REFBUSLEFT2RIGHT_MODE_NT_SHIFT 8 + +#define SERDES_GEN_ICTL_PMA_REFBUSLEFT2RIGHT_MODE_NT_0 \ + (0 << (SERDES_GEN_ICTL_PMA_REFBUSLEFT2RIGHT_MODE_NT_SHIFT)) +#define SERDES_GEN_ICTL_PMA_REFBUSLEFT2RIGHT_MODE_NT_REF \ + (2 << (SERDES_GEN_ICTL_PMA_REFBUSLEFT2RIGHT_MODE_NT_SHIFT)) +#define SERDES_GEN_ICTL_PMA_REFBUSLEFT2RIGHT_MODE_NT_L2R \ + (3 << (SERDES_GEN_ICTL_PMA_REFBUSLEFT2RIGHT_MODE_NT_SHIFT)) + +#define SERDES_GEN_ICTL_PMA_TXENABLE_A_SRC (1 << 11) +#define SERDES_GEN_ICTL_PMA_TXENABLE_A_SRC_THIS (0 << 11) +#define SERDES_GEN_ICTL_PMA_TXENABLE_A_SRC_MASTER (1 << 11) + +#define SERDES_GEN_ICTL_PMA_TXENABLE_A (1 << 12) + +#define SERDES_GEN_ICTL_PMA_SYNTHCKBYPASSEN_NT (1 << 13) + +/**** IPD_MULTI_SYNTH register ****/ + +#define SERDES_GEN_IPD_MULTI_SYNTH_B (1 << 0) + +/**** IRST register ****/ + +#define SERDES_GEN_IRST_PIPE_RST_L3_B_A (1 << 0) + +#define SERDES_GEN_IRST_PIPE_RST_L2_B_A (1 << 1) + +#define SERDES_GEN_IRST_PIPE_RST_L1_B_A (1 << 2) + +#define SERDES_GEN_IRST_PIPE_RST_L0_B_A (1 << 3) + +#define SERDES_GEN_IRST_MULTI_HARD_TXRX_L3_B_A (1 << 4) + +#define SERDES_GEN_IRST_MULTI_HARD_TXRX_L2_B_A (1 << 5) + +#define SERDES_GEN_IRST_MULTI_HARD_TXRX_L1_B_A (1 << 6) + +#define SERDES_GEN_IRST_MULTI_HARD_TXRX_L0_B_A (1 << 7) + +#define SERDES_GEN_IRST_MULTI_HARD_SYNTH_B_A (1 << 8) + +#define SERDES_GEN_IRST_POR_B_A (1 << 12) + +#define SERDES_GEN_IRST_PIPE_RST_L3_B_A_SEL (1 << 16) + +#define SERDES_GEN_IRST_PIPE_RST_L2_B_A_SEL (1 << 17) + +#define SERDES_GEN_IRST_PIPE_RST_L1_B_A_SEL (1 << 18) + +#define SERDES_GEN_IRST_PIPE_RST_L0_B_A_SEL (1 << 19) + +#define SERDES_GEN_IRST_MULTI_HARD_TXRX_L3_B_A_SEL (1 << 20) + +#define SERDES_GEN_IRST_MULTI_HARD_TXRX_L2_B_A_SEL (1 << 21) + +#define SERDES_GEN_IRST_MULTI_HARD_TXRX_L1_B_A_SEL (1 << 22) + +#define SERDES_GEN_IRST_MULTI_HARD_TXRX_L0_B_A_SEL (1 << 23) + +/**** OCTL_MULTI_SYNTHREADY register ****/ + +#define SERDES_GEN_OCTL_MULTI_SYNTHREADY_A (1 << 0) + +/**** OCTL_MULTI_SYNTHSTATUS register ****/ + +#define SERDES_GEN_OCTL_MULTI_SYNTHSTATUS_A (1 << 0) + +/**** clk_out register ****/ + +#define SERDES_GEN_CLK_OUT_SEL_MASK 0x0000003F +#define SERDES_GEN_CLK_OUT_SEL_SHIFT 0 + +/**** OCTL_PMA register ****/ + +#define SERDES_LANE_OCTL_PMA_TXSTATUS_L_A (1 << 0) + +/**** ICTL_MULTI_ANDME register ****/ + +#define SERDES_LANE_ICTL_MULTI_ANDME_EN_L_A (1 << 0) + +#define SERDES_LANE_ICTL_MULTI_ANDME_EN_L_A_SEL (1 << 1) + +/**** ICTL_MULTI_LB register ****/ + +#define SERDES_LANE_ICTL_MULTI_LB_TX2RXIOTIMEDEN_L_NT (1 << 0) + +#define SERDES_LANE_ICTL_MULTI_LB_TX2RXBUFTIMEDEN_L_NT (1 << 1) + +#define SERDES_LANE_ICTL_MULTI_LB_RX2TXUNTIMEDEN_L_NT (1 << 2) + +#define SERDES_LANE_ICTL_MULTI_LB_PARRX2TXTIMEDEN_L_NT (1 << 3) + +#define SERDES_LANE_ICTL_MULTI_LB_CDRCLK2TXEN_L_NT (1 << 4) + +#define SERDES_LANE_ICTL_MULTI_LB_TX2RXBUFTIMEDEN_L_NT_SEL (1 << 8) + +#define SERDES_LANE_ICTL_MULTI_LB_RX2TXUNTIMEDEN_L_NT_SEL (1 << 9) + +/**** ICTL_MULTI_RXBIST register ****/ + +#define SERDES_LANE_ICTL_MULTI_RXBIST_EN_L_A (1 << 0) + +/**** ICTL_MULTI_TXBIST register ****/ + +#define SERDES_LANE_ICTL_MULTI_TXBIST_EN_L_A (1 << 0) + +/**** ICTL_MULTI register ****/ + +#define SERDES_LANE_ICTL_MULTI_PSTATE_L_MASK 0x00000003 +#define SERDES_LANE_ICTL_MULTI_PSTATE_L_SHIFT 0 + +#define SERDES_LANE_ICTL_MULTI_PSTATE_L_SEL (1 << 2) + +#define SERDES_LANE_ICTL_MULTI_RXDATAWIDTH_L_MASK 0x00000070 +#define SERDES_LANE_ICTL_MULTI_RXDATAWIDTH_L_SHIFT 4 + +#define SERDES_LANE_ICTL_MULTI_RXOVRCDRLOCK2DATAEN_L_A (1 << 8) + +#define SERDES_LANE_ICTL_MULTI_RXOVRCDRLOCK2DATA_L_A (1 << 9) + +#define SERDES_LANE_ICTL_MULTI_TXBEACON_L_A (1 << 12) + +#define SERDES_LANE_ICTL_MULTI_TXDETECTRXREQ_L_A (1 << 13) + +#define SERDES_LANE_ICTL_MULTI_RXRATE_L_MASK 0x00070000 +#define SERDES_LANE_ICTL_MULTI_RXRATE_L_SHIFT 16 + +#define SERDES_LANE_ICTL_MULTI_RXRATE_L_SEL (1 << 19) + +#define SERDES_LANE_ICTL_MULTI_TXRATE_L_MASK 0x00700000 +#define SERDES_LANE_ICTL_MULTI_TXRATE_L_SHIFT 20 + +#define SERDES_LANE_ICTL_MULTI_TXRATE_L_SEL (1 << 23) + +#define SERDES_LANE_ICTL_MULTI_TXAMP_L_MASK 0x07000000 +#define SERDES_LANE_ICTL_MULTI_TXAMP_L_SHIFT 24 + +#define SERDES_LANE_ICTL_MULTI_TXAMP_EN_L (1 << 27) + +#define SERDES_LANE_ICTL_MULTI_TXDATAWIDTH_L_MASK 0x70000000 +#define SERDES_LANE_ICTL_MULTI_TXDATAWIDTH_L_SHIFT 28 + +/**** ICTL_MULTI_RXEQ register ****/ + +#define SERDES_LANE_ICTL_MULTI_RXEQ_EN_L (1 << 0) + +#define SERDES_LANE_ICTL_MULTI_RXEQ_START_L_A (1 << 1) + +#define SERDES_LANE_ICTL_MULTI_RXEQ_PRECAL_CODE_SEL_MASK 0x00000070 +#define SERDES_LANE_ICTL_MULTI_RXEQ_PRECAL_CODE_SEL_SHIFT 4 + +/**** ICTL_MULTI_RXEQ_L_high register ****/ + +#define SERDES_LANE_ICTL_MULTI_RXEQ_L_HIGH_VAL (1 << 0) + +/**** ICTL_MULTI_RXEYEDIAG register ****/ + +#define SERDES_LANE_ICTL_MULTI_RXEYEDIAG_START_L_A (1 << 0) + +/**** ICTL_MULTI_TXDEEMPH register ****/ + +#define SERDES_LANE_ICTL_MULTI_TXDEEMPH_L_MASK 0x0003FFFF +#define SERDES_LANE_ICTL_MULTI_TXDEEMPH_L_SHIFT 0 + +#define SERDES_LANE_ICTL_MULTI_TXDEEMPH_C_ZERO_MASK 0x7c0 +#define SERDES_LANE_ICTL_MULTI_TXDEEMPH_C_ZERO_SHIFT 6 +#define SERDES_LANE_ICTL_MULTI_TXDEEMPH_C_PLUS_MASK 0xf000 +#define SERDES_LANE_ICTL_MULTI_TXDEEMPH_C_PLUS_SHIFT 12 +#define SERDES_LANE_ICTL_MULTI_TXDEEMPH_C_MINUS_MASK 0x7 +#define SERDES_LANE_ICTL_MULTI_TXDEEMPH_C_MINUS_SHIFT 0 + +/**** ICTL_MULTI_TXMARGIN register ****/ + +#define SERDES_LANE_ICTL_MULTI_TXMARGIN_L_MASK 0x00000007 +#define SERDES_LANE_ICTL_MULTI_TXMARGIN_L_SHIFT 0 + +/**** ICTL_MULTI_TXSWING register ****/ + +#define SERDES_LANE_ICTL_MULTI_TXSWING_L (1 << 0) + +/**** IDAT_MULTI register ****/ + +#define SERDES_LANE_IDAT_MULTI_TXELECIDLE_L_MASK 0x0000000F +#define SERDES_LANE_IDAT_MULTI_TXELECIDLE_L_SHIFT 0 + +#define SERDES_LANE_IDAT_MULTI_TXELECIDLE_L_SEL (1 << 4) + +/**** IPD_MULTI register ****/ + +#define SERDES_LANE_IPD_MULTI_TX_L_B (1 << 0) + +#define SERDES_LANE_IPD_MULTI_RX_L_B (1 << 1) + +/**** OCTL_MULTI_RXBIST register ****/ + +#define SERDES_LANE_OCTL_MULTI_RXBIST_DONE_L_A (1 << 0) + +#define SERDES_LANE_OCTL_MULTI_RXBIST_RXLOCKED_L_A (1 << 1) + +/**** OCTL_MULTI register ****/ + +#define SERDES_LANE_OCTL_MULTI_RXCDRLOCK2DATA_L_A (1 << 0) + +#define SERDES_LANE_OCTL_MULTI_RXEQ_DONE_L_A (1 << 1) + +#define SERDES_LANE_OCTL_MULTI_RXREADY_L_A (1 << 2) + +#define SERDES_LANE_OCTL_MULTI_RXSTATUS_L_A (1 << 3) + +#define SERDES_LANE_OCTL_MULTI_TXREADY_L_A (1 << 4) + +#define SERDES_LANE_OCTL_MULTI_TXDETECTRXSTAT_L_A (1 << 5) + +#define SERDES_LANE_OCTL_MULTI_TXDETECTRXACK_L_A (1 << 6) + +#define SERDES_LANE_OCTL_MULTI_RXSIGNALDETECT_L_A (1 << 7) + +/**** OCTL_MULTI_RXEYEDIAG register ****/ + +#define SERDES_LANE_OCTL_MULTI_RXEYEDIAG_STAT_L_A_MASK 0x00003FFF +#define SERDES_LANE_OCTL_MULTI_RXEYEDIAG_STAT_L_A_SHIFT 0 + +#define SERDES_LANE_OCTL_MULTI_RXEYEDIAG_DONE_L_A (1 << 16) + +#define SERDES_LANE_OCTL_MULTI_RXEYEDIAG_ERR_L_A (1 << 17) + +/**** ODAT_MULTI_RXBIST register ****/ + +#define SERDES_LANE_ODAT_MULTI_RXBIST_ERRCOUNT_L_A_MASK 0x0000FFFF +#define SERDES_LANE_ODAT_MULTI_RXBIST_ERRCOUNT_L_A_SHIFT 0 + +#define SERDES_LANE_ODAT_MULTI_RXBIST_ERRCOUNT_OVERFLOW_L_A (1 << 16) + +/**** ODAT_MULTI_RXEQ register ****/ + +#define SERDES_LANE_ODAT_MULTI_RXEQ_BEST_EYE_VAL_L_A_MASK 0x00003FFF +#define SERDES_LANE_ODAT_MULTI_RXEQ_BEST_EYE_VAL_L_A_SHIFT 0 + +/**** MULTI_RX_DVALID register ****/ + +#define SERDES_LANE_MULTI_RX_DVALID_MASK_CDR_LOCK (1 << 0) + +#define SERDES_LANE_MULTI_RX_DVALID_MASK_SIGNALDETECT (1 << 1) + +#define SERDES_LANE_MULTI_RX_DVALID_MASK_TX_READY (1 << 2) + +#define SERDES_LANE_MULTI_RX_DVALID_MASK_RX_READY (1 << 3) + +#define SERDES_LANE_MULTI_RX_DVALID_MASK_SYNT_READY (1 << 4) + +#define SERDES_LANE_MULTI_RX_DVALID_MASK_RX_ELECIDLE (1 << 5) + +#define SERDES_LANE_MULTI_RX_DVALID_MUX_SEL_MASK 0x00FF0000 +#define SERDES_LANE_MULTI_RX_DVALID_MUX_SEL_SHIFT 16 + +#define SERDES_LANE_MULTI_RX_DVALID_PS_00_SEL (1 << 24) + +#define SERDES_LANE_MULTI_RX_DVALID_PS_00_VAL (1 << 25) + +#define SERDES_LANE_MULTI_RX_DVALID_PS_01_SEL (1 << 26) + +#define SERDES_LANE_MULTI_RX_DVALID_PS_01_VAL (1 << 27) + +#define SERDES_LANE_MULTI_RX_DVALID_PS_10_SEL (1 << 28) + +#define SERDES_LANE_MULTI_RX_DVALID_PS_10_VAL (1 << 29) + +#define SERDES_LANE_MULTI_RX_DVALID_PS_11_SEL (1 << 30) + +#define SERDES_LANE_MULTI_RX_DVALID_PS_11_VAL (1 << 31) + +/**** reserved register ****/ + +#define SERDES_LANE_RESERVED_OUT_MASK 0x000000FF +#define SERDES_LANE_RESERVED_OUT_SHIFT 0 + +#define SERDES_LANE_RESERVED_IN_MASK 0x00FF0000 +#define SERDES_LANE_RESERVED_IN_SHIFT 16 + +#ifdef __cplusplus +} +#endif + +#endif /* __AL_HAL_serdes_REGS_H__ */ + +/** @} end of ... group */ + + diff --git a/al_hal_serdes_interface.h b/al_hal_serdes_interface.h new file mode 100644 index 00000000000..c41e6c30b69 --- /dev/null +++ b/al_hal_serdes_interface.h @@ -0,0 +1,875 @@ +/******************************************************************************* +Copyright (C) 2015 Annapurna Labs Ltd. + +This file may be licensed under the terms of the Annapurna Labs Commercial +License Agreement. + +Alternatively, this file can be distributed under the terms of the GNU General +Public License V2 as published by the Free Software Foundation and can be +found at http://www.gnu.org/licenses/gpl-2.0.html + +Alternatively, redistribution and use in source and binary forms, with or +without modification, are permitted provided that the following conditions are +met: + + * Redistributions of source code must retain the above copyright notice, +this list of conditions and the following disclaimer. + + * Redistributions in binary form must reproduce the above copyright +notice, this list of conditions and the following disclaimer in +the documentation and/or other materials provided with the +distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +*******************************************************************************/ + +/** + * @defgroup group_serdes_api API + * SerDes HAL driver API + * @ingroup group_serdes SerDes + * @{ + * + * @file al_hal_serdes_interface.h + * + * @brief Header file for the SerDes HAL driver + * + */ + +#ifndef __AL_HAL_SERDES_INTERFACE_H__ +#define __AL_HAL_SERDES_INTERFACE_H__ + +#include "al_hal_common.h" + +/* *INDENT-OFF* */ +#ifdef __cplusplus +extern "C" { +#endif +/* *INDENT-ON* */ + +enum al_serdes_type { + AL_SRDS_TYPE_HSSP, + AL_SRDS_TYPE_25G, +}; + +enum al_serdes_reg_page { + /* Relevant to Serdes hssp and 25g */ + AL_SRDS_REG_PAGE_0_LANE_0 = 0, + AL_SRDS_REG_PAGE_1_LANE_1, + /* Relevant to Serdes hssp only */ + AL_SRDS_REG_PAGE_2_LANE_2, + AL_SRDS_REG_PAGE_3_LANE_3, + /* Relevant to Serdes hssp and 25g */ + AL_SRDS_REG_PAGE_4_COMMON, + /* Relevant to Serdes hssp only */ + AL_SRDS_REG_PAGE_0123_LANES_0123 = 7, + /* Relevant to Serdes 25g only */ + AL_SRDS_REG_PAGE_TOP, +}; + +/* Relevant to Serdes hssp only */ +enum al_serdes_reg_type { + AL_SRDS_REG_TYPE_PMA = 0, + AL_SRDS_REG_TYPE_PCS, +}; + +enum al_serdes_lane { + AL_SRDS_LANE_0 = AL_SRDS_REG_PAGE_0_LANE_0, + AL_SRDS_LANE_1 = AL_SRDS_REG_PAGE_1_LANE_1, + AL_SRDS_LANE_2 = AL_SRDS_REG_PAGE_2_LANE_2, + AL_SRDS_LANE_3 = AL_SRDS_REG_PAGE_3_LANE_3, + + AL_SRDS_NUM_LANES, + AL_SRDS_LANES_0123 = AL_SRDS_REG_PAGE_0123_LANES_0123, +}; + +/** Serdes loopback mode */ +enum al_serdes_lb_mode { + /** No loopback */ + AL_SRDS_LB_MODE_OFF, + + /** + * Transmits the untimed, partial equalized RX signal out the transmit + * IO pins. + * No clock used (untimed) + */ + AL_SRDS_LB_MODE_PMA_IO_UN_TIMED_RX_TO_TX, + + /** + * Loops back the TX serializer output into the CDR. + * CDR recovered bit clock used (without attenuation) + */ + AL_SRDS_LB_MODE_PMA_INTERNALLY_BUFFERED_SERIAL_TX_TO_RX, + + /** + * Loops back the TX driver IO signal to the RX IO pins + * CDR recovered bit clock used (only through IO) + */ + AL_SRDS_LB_MODE_PMA_SERIAL_TX_IO_TO_RX_IO, + + /** + * Parallel loopback from the PMA receive lane data ports, to the + * transmit lane data ports + * CDR recovered bit clock used + */ + AL_SRDS_LB_MODE_PMA_PARALLEL_RX_TO_TX, + + /** Loops received data after elastic buffer to transmit path */ + AL_SRDS_LB_MODE_PCS_PIPE, + + /** Loops TX data (to PMA) to RX path (instead of PMA data) */ + AL_SRDS_LB_MODE_PCS_NEAR_END, + + /** Loops receive data prior to interface block to transmit path */ + AL_SRDS_LB_MODE_PCS_FAR_END, +}; + +enum al_serdes_clk_freq { + AL_SRDS_CLK_FREQ_NA, + AL_SRDS_CLK_FREQ_100_MHZ, + AL_SRDS_CLK_FREQ_125_MHZ, + AL_SRDS_CLK_FREQ_156_MHZ, +}; + +enum al_serdes_clk_src { + AL_SRDS_CLK_SRC_LOGIC_0, + AL_SRDS_CLK_SRC_REF_PINS, + AL_SRDS_CLK_SRC_R2L, + AL_SRDS_CLK_SRC_R2L_PLL, + AL_SRDS_CLK_SRC_L2R, +}; + +/** Serdes BIST pattern */ +enum al_serdes_bist_pattern { + AL_SRDS_BIST_PATTERN_USER, + AL_SRDS_BIST_PATTERN_PRBS7, + AL_SRDS_BIST_PATTERN_PRBS23, + AL_SRDS_BIST_PATTERN_PRBS31, + AL_SRDS_BIST_PATTERN_CLK1010, +}; + +/** SerDes group rate */ +enum al_serdes_rate { + AL_SRDS_RATE_1_8, + AL_SRDS_RATE_1_4, + AL_SRDS_RATE_1_2, + AL_SRDS_RATE_FULL, +}; + +/** SerDes power mode */ +enum al_serdes_pm { + AL_SRDS_PM_PD, + AL_SRDS_PM_P2, + AL_SRDS_PM_P1, + AL_SRDS_PM_P0S, + AL_SRDS_PM_P0, +}; + +/** + * Tx de-emphasis parameters + */ +enum al_serdes_tx_deemph_param { + AL_SERDES_TX_DEEMP_C_ZERO, /*< c(0) */ + AL_SERDES_TX_DEEMP_C_PLUS, /*< c(1) */ + AL_SERDES_TX_DEEMP_C_MINUS, /*< c(-1) */ +}; + +struct al_serdes_adv_tx_params { + /* + * select the input values location. + * When set to true the values will be taken from the internal registers + * that will be override with the next following parameters. + * When set to false the values will be taken from external pins (the + * other parameters in this case is not needed) + */ + al_bool override; + /* + * Transmit Amplitude control signal. Used to define the full-scale + * maximum swing of the driver. + * 000 - Not Supported + * 001 - 952mVdiff-pkpk + * 010 - 1024mVdiff-pkpk + * 011 - 1094mVdiff-pkpk + * 100 - 1163mVdiff-pkpk + * 101 - 1227mVdiff-pkpk + * 110 - 1283mVdiff-pkpk + * 111 - 1331mVdiff-pkpk + */ + uint8_t amp; + /* Defines the total number of driver units allocated in the driver */ + uint8_t total_driver_units; + /* Defines the total number of driver units allocated to the + * first post-cursor (C+1) tap. */ + uint8_t c_plus_1; + /* Defines the total number of driver units allocated to the + * second post-cursor (C+2) tap. */ + uint8_t c_plus_2; + /* Defines the total number of driver units allocated to the + * first pre-cursor (C-1) tap. */ + uint8_t c_minus_1; + /* TX driver Slew Rate control: + * 00 - 31ps + * 01 - 33ps + * 10 - 68ps + * 11 - 170ps + */ + uint8_t slew_rate; +}; + +struct al_serdes_adv_rx_params { + /* + * select the input values location. + * When set to true the values will be taken from the internal registers + * that will be override with the next following parameters. + * When set to false the values will be taken based in the equalization + * results (the other parameters in this case is not needed) + */ + al_bool override; + /* RX agc high frequency dc gain: + * -3'b000: -3dB + * -3'b001: -2.5dB + * -3'b010: -2dB + * -3'b011: -1.5dB + * -3'b100: -1dB + * -3'b101: -0.5dB + * -3'b110: -0dB + * -3'b111: 0.5dB + */ + uint8_t dcgain; + /* DFE post-shaping tap 3dB frequency + * -3'b000: 684MHz + * -3'b001: 576MHz + * -3'b010: 514MHz + * -3'b011: 435MHz + * -3'b100: 354MHz + * -3'b101: 281MHz + * -3'b110: 199MHz + * -3'b111: 125MHz + */ + uint8_t dfe_3db_freq; + /* DFE post-shaping tap gain + * 0: no pulse shaping tap + * 1: -24mVpeak + * 2: -45mVpeak + * 3: -64mVpeak + * 4: -80mVpeak + * 5: -93mVpeak + * 6: -101mVpeak + * 7: -105mVpeak + */ + uint8_t dfe_gain; + /* DFE first tap gain control + * -4'b0000: +1mVpeak + * -4'b0001: +10mVpeak + * .... + * -4'b0110: +55mVpeak + * -4'b0111: +64mVpeak + * -4'b1000: -1mVpeak + * -4'b1001: -10mVpeak + * .... + * -4'b1110: -55mVpeak + * -4'b1111: -64mVpeak + */ + uint8_t dfe_first_tap_ctrl; + /* DFE second tap gain control + * -4'b0000: +0mVpeak + * -4'b0001: +9mVpeak + * .... + * -4'b0110: +46mVpeak + * -4'b0111: +53mVpeak + * -4'b1000: -0mVpeak + * -4'b1001: -9mVpeak + * .... + * -4'b1110: -46mVpeak + * -4'b1111: -53mVpeak + */ + uint8_t dfe_secound_tap_ctrl; + /* DFE third tap gain control + * -4'b0000: +0mVpeak + * -4'b0001: +7mVpeak + * .... + * -4'b0110: +38mVpeak + * -4'b0111: +44mVpeak + * -4'b1000: -0mVpeak + * -4'b1001: -7mVpeak + * .... + * -4'b1110: -38mVpeak + * -4'b1111: -44mVpeak + */ + uint8_t dfe_third_tap_ctrl; + /* DFE fourth tap gain control + * -4'b0000: +0mVpeak + * -4'b0001: +6mVpeak + * .... + * -4'b0110: +29mVpeak + * -4'b0111: +33mVpeak + * -4'b1000: -0mVpeak + * -4'b1001: -6mVpeak + * .... + * -4'b1110: -29mVpeak + * -4'b1111: -33mVpeak + */ + uint8_t dfe_fourth_tap_ctrl; + /* Low frequency agc gain (att) select + * -3'b000: Disconnected + * -3'b001: -18.5dB + * -3'b010: -12.5dB + * -3'b011: -9dB + * -3'b100: -6.5dB + * -3'b101: -4.5dB + * -3'b110: -2.9dB + * -3'b111: -1.6dB + */ + uint8_t low_freq_agc_gain; + /* Provides a RX Equalizer pre-hint, prior to beginning + * adaptive equalization */ + uint8_t precal_code_sel; + /* High frequency agc boost control + * Min d0: Boost ~4dB + * Max d31: Boost ~20dB + */ + uint8_t high_freq_agc_boost; +}; + +struct al_serdes_25g_adv_rx_params { + /* ATT (PLE Flat-Band Gain) */ + uint8_t att; + /* APG (CTLE's Flat-Band Gain) */ + uint8_t apg; + /* LFG (Low-Freq Gain) */ + uint8_t lfg; + /* HFG (High-Freq Gain) */ + uint8_t hfg; + /* MBG (MidBand-Freq-knob Gain) */ + uint8_t mbg; + /* MBF (MidBand-Freq-knob Frequency position Gain) */ + uint8_t mbf; + /* DFE Tap1 even#0 Value */ + int8_t dfe_first_tap_even0_ctrl; + /* DFE Tap1 even#1 Value */ + int8_t dfe_first_tap_even1_ctrl; + /* DFE Tap1 odd#0 Value */ + int8_t dfe_first_tap_odd0_ctrl; + /* DFE Tap1 odd#1 Value */ + int8_t dfe_first_tap_odd1_ctrl; + /* DFE Tap2 Value */ + int8_t dfe_second_tap_ctrl; + /* DFE Tap3 Value */ + int8_t dfe_third_tap_ctrl; + /* DFE Tap4 Value */ + int8_t dfe_fourth_tap_ctrl; + /* DFE Tap5 Value */ + int8_t dfe_fifth_tap_ctrl; +}; + +struct al_serdes_25g_tx_diag_info { + uint8_t regulated_supply; + int8_t dcd_trim; + uint8_t clk_delay; + uint8_t calp_multiplied_by_2; + uint8_t caln_multiplied_by_2; +}; + +struct al_serdes_25g_rx_diag_info { + int8_t los_offset; + int8_t agc_offset; + int8_t leq_gainstage_offset; + int8_t leq_eq1_offset; + int8_t leq_eq2_offset; + int8_t leq_eq3_offset; + int8_t leq_eq4_offset; + int8_t leq_eq5_offset; + int8_t summer_even_offset; + int8_t summer_odd_offset; + int8_t vscan_even_offset; + int8_t vscan_odd_offset; + int8_t data_slicer_even0_offset; + int8_t data_slicer_even1_offset; + int8_t data_slicer_odd0_offset; + int8_t data_slicer_odd1_offset; + int8_t edge_slicer_even_offset; + int8_t edge_slicer_odd_offset; + int8_t eye_slicer_even_offset; + int8_t eye_slicer_odd_offset; + uint8_t cdr_clk_i; + uint8_t cdr_clk_q; + uint8_t cdr_dll; + uint8_t cdr_vco_dosc; + uint8_t cdr_vco_fr; + uint16_t cdr_dlpf; + uint8_t ple_resistance; + uint8_t rx_term_mode; + uint8_t rx_coupling; + uint8_t rx_term_cal_code; + uint8_t rx_sheet_res_cal_code; +}; + +/** + * SRIS parameters + */ +struct al_serdes_sris_params { + /* Controls the frequency accuracy threshold (ppm) for lock detection CDR */ + uint16_t ppm_drift_count; + /* Controls the frequency accuracy threshold (ppm) for lock detection in the CDR */ + uint16_t ppm_drift_max; + /* Controls the frequency accuracy threshold (ppm) for lock detection in PLL */ + uint16_t synth_ppm_drift_max; + /* Elastic buffer full threshold for PCIE modes: GEN1/GEN2 */ + uint8_t full_d2r1; + /* Elastic buffer full threshold for PCIE modes: GEN3 */ + uint8_t full_pcie_g3; + /* Elastic buffer midpoint threshold. + * Sets the depth of the buffer while in PCIE mode, GEN1/GEN2 + */ + uint8_t rd_threshold_d2r1; + /* Elastic buffer midpoint threshold. + * Sets the depth of the buffer while in PCIE mode, GEN3 + */ + uint8_t rd_threshold_pcie_g3; +}; + +/** SerDes PCIe Rate - values are important for proper behavior */ +enum al_serdes_pcie_rate { + AL_SRDS_PCIE_RATE_GEN1 = 0, + AL_SRDS_PCIE_RATE_GEN2, + AL_SRDS_PCIE_RATE_GEN3, +}; + +struct al_serdes_grp_obj { + void __iomem *regs_base; + + /** + * get the type of the serdes. + * Must be implemented for all SerDes unit. + * + * @return the serdes type. + */ + enum al_serdes_type (*type_get)(void); + + /** + * Reads a SERDES internal register + * + * @param obj The object context + * @param page The SERDES register page within the group + * @param type The SERDES register type (PMA /PCS) + * @param offset The SERDES register offset (0 - 4095) + * @param data The read data + * + * @return 0 if no error found. + */ + int (*reg_read)(struct al_serdes_grp_obj *, enum al_serdes_reg_page, + enum al_serdes_reg_type, uint16_t, uint8_t *); + + /** + * Writes a SERDES internal register + * + * @param obj The object context + * @param page The SERDES register page within the group + * @param type The SERDES register type (PMA /PCS) + * @param offset The SERDES register offset (0 - 4095) + * @param data The data to write + * + * @return 0 if no error found. + */ + int (*reg_write)(struct al_serdes_grp_obj *, enum al_serdes_reg_page, + enum al_serdes_reg_type, uint16_t, uint8_t); + + /** + * Enable BIST required overrides + * + * @param obj The object context + * @param grp The SERDES group + * @param rate The required speed rate + */ + void (*bist_overrides_enable)(struct al_serdes_grp_obj *, enum al_serdes_rate); + /** + * Disable BIST required overrides + * + * @param obj The object context + * @param grp The SERDES group + * @param rate The required speed rate + */ + void (*bist_overrides_disable)(struct al_serdes_grp_obj *); + /** + * Rx rate change + * + * @param obj The object context + * @param grp The SERDES group + * @param rate The Rx required rate + */ + void (*rx_rate_change)(struct al_serdes_grp_obj *, enum al_serdes_rate); + /** + * SERDES lane Rx rate change software flow enable + * + * @param obj The object context + * @param lane The SERDES lane within the group + */ + void (*rx_rate_change_sw_flow_en)(struct al_serdes_grp_obj *, enum al_serdes_lane); + /** + * SERDES lane Rx rate change software flow disable + * + * @param obj The object context + * @param lane The SERDES lane within the group + */ + void (*rx_rate_change_sw_flow_dis)(struct al_serdes_grp_obj *, enum al_serdes_lane); + /** + * PCIe lane rate override check + * + * @param obj The object context + * @param grp The SERDES group + * @param lane The SERDES lane within the group + * + * @returns AL_TRUE if the override is enabled + */ + al_bool (*pcie_rate_override_is_enabled)(struct al_serdes_grp_obj *, enum al_serdes_lane); + /** + * PCIe lane rate override control + * + * @param obj The object context + * @param lane The SERDES lane within the group + * @param en Enable/disable + */ + void (*pcie_rate_override_enable_set)(struct al_serdes_grp_obj *, enum al_serdes_lane, + al_bool en); + /** + * PCIe lane rate get + * + * @param obj The object context + * @param lane The SERDES lane within the group + */ + enum al_serdes_pcie_rate (*pcie_rate_get)(struct al_serdes_grp_obj *, enum al_serdes_lane); + /** + * PCIe lane rate set + * + * @param obj The object context + * @param lane The SERDES lane within the group + * @param rate The required rate + */ + void (*pcie_rate_set)(struct al_serdes_grp_obj *, enum al_serdes_lane, + enum al_serdes_pcie_rate rate); + /** + * SERDES group power mode control + * + * @param obj The object context + * @param grp The SERDES group + * @param pm The required power mode + */ + void (*group_pm_set)(struct al_serdes_grp_obj *, enum al_serdes_pm); + /** + * SERDES lane power mode control + * + * @param obj The object context + * @param grp The SERDES group + * @param lane The SERDES lane within the group + * @param rx_pm The required RX power mode + * @param tx_pm The required TX power mode + */ + void (*lane_pm_set)(struct al_serdes_grp_obj *, enum al_serdes_lane, + enum al_serdes_pm, enum al_serdes_pm); + + /** + * SERDES group PMA hard reset + * Controls Serdes group PMA hard reset + * + * @param obj The object context + * @param grp The SERDES group + * @param enable Enable/disable hard reset + */ + void (*pma_hard_reset_group)(struct al_serdes_grp_obj *, al_bool); + /** + * SERDES lane PMA hard reset + * Controls Serdes lane PMA hard reset + * + * @param obj The object context + * @param lane The SERDES lane within the group + * @param enable Enable/disable hard reset + */ + void (*pma_hard_reset_lane)(struct al_serdes_grp_obj *, enum al_serdes_lane, al_bool); + /** + * Configure SERDES loopback + * Controls the loopback + * + * @param obj The object context + * @param lane The SERDES lane within the group + * @param mode The requested loopback mode + */ + void (*loopback_control)(struct al_serdes_grp_obj *, enum al_serdes_lane, + enum al_serdes_lb_mode); + /** + * SERDES BIST pattern selection + * Selects the BIST pattern to be used + * + * @param obj The object context + * @param pattern The pattern to set + * @param user_data The pattern user data (when pattern == AL_SRDS_BIST_PATTERN_USER) + * 80 bits (8 bytes array) + */ + void (*bist_pattern_select)(struct al_serdes_grp_obj *, + enum al_serdes_bist_pattern, uint8_t *); + /** + * SERDES BIST TX Enable + * Enables/disables TX BIST per lane + * + * @param obj The object context + * @param lane The SERDES lane within the group + * @param enable Enable or disable TX BIST + */ + void (*bist_tx_enable)(struct al_serdes_grp_obj *, enum al_serdes_lane, al_bool); + /** + * SERDES BIST TX single bit error injection + * Injects single bit error during a TX BIST + * + * @param obj The object context + */ + void (*bist_tx_err_inject)(struct al_serdes_grp_obj *); + /** + * SERDES BIST RX Enable + * Enables/disables RX BIST per lane + * + * @param obj The object context + * @param lane The SERDES lane within the group + * @param enable Enable or disable TX BIST + */ + void (*bist_rx_enable)(struct al_serdes_grp_obj *, enum al_serdes_lane, al_bool); + /** + * SERDES BIST RX status + * Checks the RX BIST status for a specific SERDES lane + * + * @param obj The object context + * @param lane The SERDES lane within the group + * @param is_locked An indication whether RX BIST is locked + * @param err_cnt_overflow An indication whether error count overflow occured + * @param err_cnt Current bit error count + */ + void (*bist_rx_status)(struct al_serdes_grp_obj *, enum al_serdes_lane, al_bool *, + al_bool *, uint32_t *); + + /** + * Set the tx de-emphasis to preset values + * + * @param obj The object context + * @param lane The SERDES lane within the group + * + */ + void (*tx_deemph_preset)(struct al_serdes_grp_obj *, enum al_serdes_lane); + /** + * Increase tx de-emphasis param. + * + * @param obj The object context + * @param lane The SERDES lane within the group + * @param param which tx de-emphasis to change + * + * @return false in case max is reached. true otherwise. + */ + al_bool (*tx_deemph_inc)(struct al_serdes_grp_obj *, enum al_serdes_lane, + enum al_serdes_tx_deemph_param); + /** + * Decrease tx de-emphasis param. + * + * @param obj The object context + * @param lane The SERDES lane within the group + * @param param which tx de-emphasis to change + * + * @return false in case min is reached. true otherwise. + */ + al_bool (*tx_deemph_dec)(struct al_serdes_grp_obj *, enum al_serdes_lane, + enum al_serdes_tx_deemph_param); + /** + * run Rx eye measurement. + * + * @param obj The object context + * @param lane The SERDES lane within the group + * @param timeout timeout in uSec + * @param value Rx eye measurement value + * (0 - completely closed eye, 0xffff - completely open eye). + * + * @return 0 if no error found. + */ + int (*eye_measure_run)(struct al_serdes_grp_obj *, enum al_serdes_lane, + uint32_t, unsigned int *); + /** + * Eye diagram single sampling + * + * @param obj The object context + * @param lane The SERDES lane within the group + * @param x Sampling X position (0 - 63 --> -1.00 UI ... 1.00 UI) + * @param y Sampling Y position (0 - 62 --> 500mV ... -500mV) + * @param timeout timeout in uSec + * @param value Eye diagram sample value (BER - 0x0000 - 0xffff) + * + * @return 0 if no error found. + */ + int (*eye_diag_sample)(struct al_serdes_grp_obj *, enum al_serdes_lane, + unsigned int, int, unsigned int, unsigned int *); + + /** + * Eye diagram full run + * + * @param obj The object context + * @param lane The SERDES lane within the group + * @param x_start Sampling from X position + * @param x_stop Sampling to X position + * @param x_step jump in x_step + * @param y_start Sampling from Y position + * @param y_stop Sampling to Y position + * @param y_step jump in y_step + * @param num_bits_per_sample How many bits to check + * @param buf array of results + * @param buf_size array size - must be equal to + * (((y_stop - y_start) / y_step) + 1) * + * (((x_stop - x_start) / x_step) + 1) + * + * @return 0 if no error found. + */ + int (*eye_diag_run)(struct al_serdes_grp_obj *, enum al_serdes_lane, + int, int, unsigned int, int, int, unsigned int, uint64_t, uint64_t *, + uint32_t); + /** + * Check if signal is detected + * + * @param obj The object context + * @param lane The SERDES lane within the group + * + * @return true if signal is detected. false otherwise. + */ + al_bool (*signal_is_detected)(struct al_serdes_grp_obj *, enum al_serdes_lane); + + /** + * Check if CDR is locked + * + * @param obj The object context + * @param lane The SERDES lane within the group + * + * @return true if cdr is locked. false otherwise. + */ + al_bool (*cdr_is_locked)(struct al_serdes_grp_obj *, enum al_serdes_lane); + + /** + * Check if rx is valid for this lane + * + * @param obj The object context + * @param lane The SERDES lane within the group + * + * @return true if rx is valid. false otherwise. + */ + al_bool (*rx_valid)(struct al_serdes_grp_obj *, enum al_serdes_lane); + + /** + * configure tx advanced parameters + * + * @param obj The object context + * @param lane The SERDES lane within the group + * @param params pointer to the tx parameters + */ + void (*tx_advanced_params_set)(struct al_serdes_grp_obj *, enum al_serdes_lane, void *); + /** + * read tx advanced parameters + * + * @param obj The object context + * @param lane The SERDES lane within the group + * @param params pointer to the tx parameters + */ + void (*tx_advanced_params_get)(struct al_serdes_grp_obj *, enum al_serdes_lane, void *); + /** + * configure rx advanced parameters + * + * @param obj The object context + * @param lane The SERDES lane within the group + * @param params pointer to the rx parameters + */ + void (*rx_advanced_params_set)(struct al_serdes_grp_obj *, enum al_serdes_lane, void *); + /** + * read rx advanced parameters + * + * @param obj The object context + * @param lane The SERDES lane within the group + * @param params pointer to the rx parameters + */ + void (*rx_advanced_params_get)(struct al_serdes_grp_obj *, enum al_serdes_lane, void *); + /** + * Switch entire SerDes group to SGMII mode based on 156.25 Mhz reference clock + * + * @param obj The object context + * + */ + void (*mode_set_sgmii)(struct al_serdes_grp_obj *); + /** + * Switch entire SerDes group to KR mode based on 156.25 Mhz reference clock + * + * @param obj The object context + * + */ + void (*mode_set_kr)(struct al_serdes_grp_obj *); + /** + * performs SerDes HW equalization test and update equalization parameters + * + * @param obj the object context + * @param lane The SERDES lane within the group + */ + int (*rx_equalization)(struct al_serdes_grp_obj *, enum al_serdes_lane); + /** + * performs Rx equalization and compute the width and height of the eye + * + * @param obj the object context + * @param lane The SERDES lane within the group + * @param width the output width of the eye + * @param height the output height of the eye + */ + int (*calc_eye_size)(struct al_serdes_grp_obj *, enum al_serdes_lane, int *, int *); + /** + * SRIS: Separate Refclk Independent SSC (Spread Spectrum Clocking) + * Currently available only for PCIe interfaces. + * When working with local Refclk, same SRIS configuration in both serdes sides + * (EP and RC in PCIe interface) is required. + * + * performs SRIS configuration according to params + * + * @param obj the object context + * @param params the SRIS parameters + */ + void (*sris_config)(struct al_serdes_grp_obj *, void *); + /** + * set SERDES dcgain parameter + * + * @param obj the object context + * @param dcgain dcgain value to set + */ + void (*dcgain_set)(struct al_serdes_grp_obj *, uint8_t); + /** + * read tx diagnostics info + * + * @param obj The object context + * @param lane The SERDES lane within the group + * @param params pointer to the tx diagnostics info structure + */ + void (*tx_diag_info_get)(struct al_serdes_grp_obj *, enum al_serdes_lane, void*); + /** + * read rx diagnostics info + * + * @param obj The object context + * @param lane The SERDES lane within the group + * @param params pointer to the rx diagnostics info structure + */ + void (*rx_diag_info_get)(struct al_serdes_grp_obj *, enum al_serdes_lane, void*); +}; + + +/* *INDENT-OFF* */ +#ifdef __cplusplus +} +#endif + +/* *INDENT-ON* */ +#endif /* __AL_HAL_SERDES_INTERFACE_H__ */ + +/** @} end of SERDES group */ + diff --git a/al_hal_udma.h b/al_hal_udma.h index a1bdb4fe8db..6d94379869b 100644 --- a/al_hal_udma.h +++ b/al_hal_udma.h @@ -70,7 +70,6 @@ extern "C" { /* Default Max number of descriptors supported per action */ #define AL_UDMA_DEFAULT_MAX_ACTN_DESCS 16 -#define AL_UDMA_REV_ID_0 0 #define AL_UDMA_REV_ID_1 1 #define AL_UDMA_REV_ID_2 2 @@ -130,8 +129,8 @@ union al_udma_desc { #define AL_S2M_DESC_LEN2_MASK (0x3fff << AL_S2M_DESC_LEN2_SHIFT) #define AL_S2M_DESC_LEN2_GRANULARITY_SHIFT 6 -/* TX/RX descriptor VMID field (in the buffer address 64 bit field) */ -#define AL_UDMA_DESC_VMID_SHIFT 48 +/* TX/RX descriptor Target-ID field (in the buffer address 64 bit field) */ +#define AL_UDMA_DESC_TGTID_SHIFT 48 /** UDMA completion descriptor */ union al_udma_cdesc { @@ -168,11 +167,11 @@ struct al_block { uint32_t num; /**< Number of buffers of the block */ /**< - * VMID to be assigned to the block descriptors - * Requires VMID in descriptor to be enabled for the specific UDMA + * Target-ID to be assigned to the block descriptors + * Requires Target-ID in descriptor to be enabled for the specific UDMA * queue. */ - uint16_t vmid; + uint16_t tgtid; }; /** UDMA type */ diff --git a/al_hal_udma_config.c b/al_hal_udma_config.c index a06f7898308..5ef01f356e0 100644 --- a/al_hal_udma_config.c +++ b/al_hal_udma_config.c @@ -565,7 +565,7 @@ int al_udma_s2m_pref_set(struct al_udma *udma, reg &= ~UDMA_S2M_RD_DESC_PREF_CFG_3_MIN_BURST_ABOVE_THR_MASK; reg |=(conf->min_burst_above_thr << UDMA_S2M_RD_DESC_PREF_CFG_3_MIN_BURST_ABOVE_THR_SHIFT) & - UDMA_S2M_RD_DESC_PREF_CFG_3_MIN_BURST_BELOW_THR_MASK; + UDMA_S2M_RD_DESC_PREF_CFG_3_MIN_BURST_ABOVE_THR_MASK; al_reg_write32(&udma->udma_regs->s2m.s2m_rd.desc_pref_cfg_3, reg); @@ -1114,260 +1114,105 @@ int al_udma_s2m_q_comp_set(struct al_udma_q *udma_q, return 0; } -/* UDMA VMID control configuration */ -void al_udma_gen_vmid_conf_set( +/* UDMA Target-ID control configuration per queue */ +void al_udma_gen_tgtid_conf_queue_set( struct unit_regs *unit_regs, - struct al_udma_gen_vmid_conf *conf) + struct al_udma_gen_tgtid_conf *conf, + uint32_t qid) { + uint32_t *tx_tgtid_reg, *rx_tgtid_reg, *tx_tgtaddr_reg, *rx_tgtaddr_reg; unsigned int rev_id; - al_reg_write32_masked( - &unit_regs->gen.vmid.cfg_vmid_0, - UDMA_GEN_VMID_CFG_VMID_0_TX_Q_VMID_DESC_EN_MASK | - UDMA_GEN_VMID_CFG_VMID_0_TX_Q_VMID_QUEUE_EN_MASK | - UDMA_GEN_VMID_CFG_VMID_0_RX_Q_VMID_DESC_EN_MASK | - UDMA_GEN_VMID_CFG_VMID_0_RX_Q_VMID_QUEUE_EN_MASK, - (((conf->tx_q_conf[0].desc_en << 0) | - (conf->tx_q_conf[1].desc_en << 1) | - (conf->tx_q_conf[2].desc_en << 2) | - (conf->tx_q_conf[3].desc_en << 3)) << - UDMA_GEN_VMID_CFG_VMID_0_TX_Q_VMID_DESC_EN_SHIFT) | - (((conf->tx_q_conf[0].queue_en << 0) | - (conf->tx_q_conf[1].queue_en << 1) | - (conf->tx_q_conf[2].queue_en << 2) | - (conf->tx_q_conf[3].queue_en << 3)) << - UDMA_GEN_VMID_CFG_VMID_0_TX_Q_VMID_QUEUE_EN_SHIFT) | - (((conf->rx_q_conf[0].desc_en << 0) | - (conf->rx_q_conf[1].desc_en << 1) | - (conf->rx_q_conf[2].desc_en << 2) | - (conf->rx_q_conf[3].desc_en << 3)) << - UDMA_GEN_VMID_CFG_VMID_0_RX_Q_VMID_DESC_EN_SHIFT) | - (((conf->rx_q_conf[0].queue_en << 0) | - (conf->rx_q_conf[1].queue_en << 1) | - (conf->rx_q_conf[2].queue_en << 2) | - (conf->rx_q_conf[3].queue_en << 3)) << - UDMA_GEN_VMID_CFG_VMID_0_RX_Q_VMID_QUEUE_EN_SHIFT)); - - /* VMID per queue */ - al_reg_write32( - &unit_regs->gen.vmid.cfg_vmid_1, - (conf->tx_q_conf[0].vmid << - UDMA_GEN_VMID_CFG_VMID_1_TX_Q_0_VMID_SHIFT) | - (conf->tx_q_conf[1].vmid << - UDMA_GEN_VMID_CFG_VMID_1_TX_Q_1_VMID_SHIFT)); - - al_reg_write32( - &unit_regs->gen.vmid.cfg_vmid_2, - (conf->tx_q_conf[2].vmid << - UDMA_GEN_VMID_CFG_VMID_2_TX_Q_2_VMID_SHIFT) | - (conf->tx_q_conf[3].vmid << - UDMA_GEN_VMID_CFG_VMID_2_TX_Q_3_VMID_SHIFT)); - - al_reg_write32( - &unit_regs->gen.vmid.cfg_vmid_3, - (conf->rx_q_conf[0].vmid << - UDMA_GEN_VMID_CFG_VMID_3_RX_Q_0_VMID_SHIFT) | - (conf->rx_q_conf[1].vmid << - UDMA_GEN_VMID_CFG_VMID_3_RX_Q_1_VMID_SHIFT)); - - al_reg_write32( - &unit_regs->gen.vmid.cfg_vmid_4, - (conf->rx_q_conf[2].vmid << - UDMA_GEN_VMID_CFG_VMID_4_RX_Q_2_VMID_SHIFT) | - (conf->rx_q_conf[3].vmid << - UDMA_GEN_VMID_CFG_VMID_4_RX_Q_3_VMID_SHIFT)); - - /* VMADDR per queue */ + al_assert(qid < DMA_MAX_Q); rev_id = al_udma_get_revision(unit_regs); + + /* Target-ID TX DESC EN */ + al_reg_write32_masked(&unit_regs->gen.tgtid.cfg_tgtid_0, + (conf->tx_q_conf[qid].desc_en << qid) << + UDMA_GEN_TGTID_CFG_TGTID_0_TX_Q_TGTID_DESC_EN_SHIFT, + (conf->tx_q_conf[qid].desc_en << qid) << + UDMA_GEN_TGTID_CFG_TGTID_0_TX_Q_TGTID_DESC_EN_SHIFT); + + /* Target-ID TX QUEUE EN */ + al_reg_write32_masked(&unit_regs->gen.tgtid.cfg_tgtid_0, + (conf->tx_q_conf[qid].queue_en << qid) << + UDMA_GEN_TGTID_CFG_TGTID_0_TX_Q_TGTID_QUEUE_EN_SHIFT, + (conf->tx_q_conf[qid].queue_en << qid) << + UDMA_GEN_TGTID_CFG_TGTID_0_TX_Q_TGTID_QUEUE_EN_SHIFT); + + /* Target-ID RX DESC EN */ + al_reg_write32_masked(&unit_regs->gen.tgtid.cfg_tgtid_0, + (conf->rx_q_conf[qid].desc_en << qid) << + UDMA_GEN_TGTID_CFG_TGTID_0_RX_Q_TGTID_DESC_EN_SHIFT, + (conf->rx_q_conf[qid].desc_en << qid) << + UDMA_GEN_TGTID_CFG_TGTID_0_RX_Q_TGTID_DESC_EN_SHIFT); + + /* Target-ID RX QUEUE EN */ + al_reg_write32_masked(&unit_regs->gen.tgtid.cfg_tgtid_0, + (conf->rx_q_conf[qid].queue_en << qid) << + UDMA_GEN_TGTID_CFG_TGTID_0_RX_Q_TGTID_QUEUE_EN_SHIFT, + (conf->rx_q_conf[qid].queue_en << qid) << + UDMA_GEN_TGTID_CFG_TGTID_0_RX_Q_TGTID_QUEUE_EN_SHIFT); + + switch (qid) { + case 0: + case 1: + tx_tgtid_reg = &unit_regs->gen.tgtid.cfg_tgtid_1; + rx_tgtid_reg = &unit_regs->gen.tgtid.cfg_tgtid_3; + tx_tgtaddr_reg = &unit_regs->gen.tgtaddr.cfg_tgtaddr_0; + rx_tgtaddr_reg = &unit_regs->gen.tgtaddr.cfg_tgtaddr_2; + break; + case 2: + case 3: + tx_tgtid_reg = &unit_regs->gen.tgtid.cfg_tgtid_2; + rx_tgtid_reg = &unit_regs->gen.tgtid.cfg_tgtid_4; + tx_tgtaddr_reg = &unit_regs->gen.tgtaddr.cfg_tgtaddr_1; + rx_tgtaddr_reg = &unit_regs->gen.tgtaddr.cfg_tgtaddr_3; + break; + default: + al_assert(AL_FALSE); + return; + } + + al_reg_write32_masked(tx_tgtid_reg, + UDMA_GEN_TGTID_CFG_TGTID_MASK(qid), + conf->tx_q_conf[qid].tgtid << UDMA_GEN_TGTID_CFG_TGTID_SHIFT(qid)); + + al_reg_write32_masked(rx_tgtid_reg, + UDMA_GEN_TGTID_CFG_TGTID_MASK(qid), + conf->rx_q_conf[qid].tgtid << UDMA_GEN_TGTID_CFG_TGTID_SHIFT(qid)); + if (rev_id >= AL_UDMA_REV_ID_REV2) { - al_reg_write32( - &unit_regs->gen.vmaddr.cfg_vmaddr_0, - (conf->tx_q_conf[0].vmaddr << - UDMA_GEN_VMADDR_CFG_VMADDR_0_TX_Q_0_VMADDR_SHIFT) | - (conf->tx_q_conf[1].vmaddr << - UDMA_GEN_VMADDR_CFG_VMADDR_0_TX_Q_1_VMADDR_SHIFT)); + al_reg_write32_masked(tx_tgtaddr_reg, + UDMA_GEN_TGTADDR_CFG_MASK(qid), + conf->tx_q_conf[qid].tgtaddr << UDMA_GEN_TGTADDR_CFG_SHIFT(qid)); - al_reg_write32( - &unit_regs->gen.vmaddr.cfg_vmaddr_1, - (conf->tx_q_conf[2].vmaddr << - UDMA_GEN_VMADDR_CFG_VMADDR_1_TX_Q_2_VMADDR_SHIFT) | - (conf->tx_q_conf[3].vmaddr << - UDMA_GEN_VMADDR_CFG_VMADDR_1_TX_Q_3_VMADDR_SHIFT)); - - al_reg_write32( - &unit_regs->gen.vmaddr.cfg_vmaddr_2, - (conf->rx_q_conf[0].vmaddr << - UDMA_GEN_VMADDR_CFG_VMADDR_2_RX_Q_0_VMADDR_SHIFT) | - (conf->rx_q_conf[1].vmaddr << - UDMA_GEN_VMADDR_CFG_VMADDR_2_RX_Q_1_VMADDR_SHIFT)); - - al_reg_write32( - &unit_regs->gen.vmaddr.cfg_vmaddr_3, - (conf->rx_q_conf[2].vmaddr << - UDMA_GEN_VMADDR_CFG_VMADDR_3_RX_Q_2_VMADDR_SHIFT) | - (conf->rx_q_conf[3].vmaddr << - UDMA_GEN_VMADDR_CFG_VMADDR_3_RX_Q_3_VMADDR_SHIFT)); + al_reg_write32_masked(rx_tgtaddr_reg, + UDMA_GEN_TGTADDR_CFG_MASK(qid), + conf->rx_q_conf[qid].tgtaddr << UDMA_GEN_TGTADDR_CFG_SHIFT(qid)); } } -/* UDMA VMID MSIX control configuration */ -void al_udma_gen_vmid_msix_conf_set( +/* UDMA Target-ID control configuration */ +void al_udma_gen_tgtid_conf_set( + struct unit_regs *unit_regs, + struct al_udma_gen_tgtid_conf *conf) +{ + int i; + + for (i = 0; i < DMA_MAX_Q; i++) + al_udma_gen_tgtid_conf_queue_set(unit_regs, conf, i); +} + +/* UDMA Target-ID MSIX control configuration */ +void al_udma_gen_tgtid_msix_conf_set( struct unit_regs *unit_regs, - struct al_udma_gen_vmid_msix_conf *conf) + struct al_udma_gen_tgtid_msix_conf *conf) { al_reg_write32_masked( - &unit_regs->gen.vmid.cfg_vmid_0, - UDMA_GEN_VMID_CFG_VMID_0_MSIX_VMID_ACCESS_EN | - UDMA_GEN_VMID_CFG_VMID_0_MSIX_VMID_SEL, - (conf->access_en ? UDMA_GEN_VMID_CFG_VMID_0_MSIX_VMID_ACCESS_EN : 0) | - (conf->sel ? UDMA_GEN_VMID_CFG_VMID_0_MSIX_VMID_SEL : 0)); + &unit_regs->gen.tgtid.cfg_tgtid_0, + UDMA_GEN_TGTID_CFG_TGTID_0_MSIX_TGTID_ACCESS_EN | + UDMA_GEN_TGTID_CFG_TGTID_0_MSIX_TGTID_SEL, + (conf->access_en ? UDMA_GEN_TGTID_CFG_TGTID_0_MSIX_TGTID_ACCESS_EN : 0) | + (conf->sel ? UDMA_GEN_TGTID_CFG_TGTID_0_MSIX_TGTID_SEL : 0)); } - -/* UDMA VMID control advanced Tx queue configuration */ -void al_udma_gen_vmid_advanced_tx_q_conf( - struct al_udma_q *q, - struct al_udma_gen_vmid_advanced_tx_q_conf *conf) -{ - struct udma_gen_regs *gen_regs = q->udma->gen_regs; - struct udma_gen_vmpr *vmpr = &gen_regs->vmpr[q->qid]; - - al_reg_write32_masked( - &vmpr->cfg_vmpr_0, - UDMA_GEN_VMPR_CFG_VMPR_0_TX_Q_HISEL_MASK | - UDMA_GEN_VMPR_CFG_VMPR_0_TX_Q_DATA_VMID_EN | - UDMA_GEN_VMPR_CFG_VMPR_0_TX_Q_PREF_VMID_EN | - UDMA_GEN_VMPR_CFG_VMPR_0_TX_Q_CMPL_VMID_EN, - conf->tx_q_addr_hi_sel | - ((conf->tx_q_data_vmid_en == AL_TRUE) ? - UDMA_GEN_VMPR_CFG_VMPR_0_TX_Q_DATA_VMID_EN : 0) | - ((conf->tx_q_prefetch_vmid_en == AL_TRUE) ? - UDMA_GEN_VMPR_CFG_VMPR_0_TX_Q_PREF_VMID_EN : 0) | - ((conf->tx_q_compl_vmid_en == AL_TRUE) ? - UDMA_GEN_VMPR_CFG_VMPR_0_TX_Q_CMPL_VMID_EN : 0)); - - al_reg_write32( - &vmpr->cfg_vmpr_1, - conf->tx_q_addr_hi); - - al_reg_write32_masked( - &vmpr->cfg_vmpr_2, - UDMA_GEN_VMPR_CFG_VMPR_2_TX_Q_PREF_VMID_MASK | - UDMA_GEN_VMPR_CFG_VMPR_2_TX_Q_CMPL_VMID_MASK, - (conf->tx_q_prefetch_vmid << - UDMA_GEN_VMPR_CFG_VMPR_2_TX_Q_PREF_VMID_SHIFT) | - (conf->tx_q_compl_vmid << - UDMA_GEN_VMPR_CFG_VMPR_2_TX_Q_CMPL_VMID_SHIFT)); - - al_reg_write32_masked( - &vmpr->cfg_vmpr_3, - UDMA_GEN_VMPR_CFG_VMPR_3_TX_Q_DATA_VMID_MASK | - UDMA_GEN_VMPR_CFG_VMPR_3_TX_Q_DATA_VMID_SEL_MASK, - (conf->tx_q_data_vmid << - UDMA_GEN_VMPR_CFG_VMPR_3_TX_Q_DATA_VMID_SHIFT) | - (conf->tx_q_data_vmid_mask << - UDMA_GEN_VMPR_CFG_VMPR_3_TX_Q_DATA_VMID_SEL_SHIFT)); -} - -/** UDMA VMID control advanced Rx queue configuration */ -void al_udma_gen_vmid_advanced_rx_q_conf( - struct al_udma_q *q, - struct al_udma_gen_vmid_advanced_rx_q_conf *conf) -{ - struct udma_gen_regs *gen_regs = q->udma->gen_regs; - struct udma_gen_vmpr *vmpr = &gen_regs->vmpr[q->qid]; - - al_reg_write32_masked( - &vmpr->cfg_vmpr_4, - UDMA_GEN_VMPR_CFG_VMPR_4_RX_Q_BUF1_HISEL_MASK | - UDMA_GEN_VMPR_CFG_VMPR_4_RX_Q_BUF1_VMID_EN | - UDMA_GEN_VMPR_CFG_VMPR_4_RX_Q_BUF2_HISEL_MASK | - UDMA_GEN_VMPR_CFG_VMPR_4_RX_Q_BUF2_VMID_EN | - UDMA_GEN_VMPR_CFG_VMPR_4_RX_Q_DDP_HISEL_MASK | - UDMA_GEN_VMPR_CFG_VMPR_4_RX_Q_DDP_VMID_EN | - UDMA_GEN_VMPR_CFG_VMPR_4_RX_Q_PREF_VMID_EN | - UDMA_GEN_VMPR_CFG_VMPR_4_RX_Q_CMPL_VMID_EN, - (conf->rx_q_addr_hi_sel << - UDMA_GEN_VMPR_CFG_VMPR_4_RX_Q_BUF1_HISEL_SHIFT) | - ((conf->rx_q_data_vmid_en == AL_TRUE) ? - UDMA_GEN_VMPR_CFG_VMPR_4_RX_Q_BUF1_VMID_EN : 0) | - (conf->rx_q_data_buff2_addr_hi_sel << - UDMA_GEN_VMPR_CFG_VMPR_4_RX_Q_BUF2_HISEL_SHIFT) | - ((conf->rx_q_data_buff2_vmid_en == AL_TRUE) ? - UDMA_GEN_VMPR_CFG_VMPR_4_RX_Q_BUF2_VMID_EN : 0) | - (conf->rx_q_ddp_addr_hi_sel << - UDMA_GEN_VMPR_CFG_VMPR_4_RX_Q_DDP_HISEL_SHIFT) | - ((conf->rx_q_ddp_vmid_en == AL_TRUE) ? - UDMA_GEN_VMPR_CFG_VMPR_4_RX_Q_DDP_VMID_EN : 0) | - ((conf->rx_q_prefetch_vmid_en == AL_TRUE) ? - UDMA_GEN_VMPR_CFG_VMPR_4_RX_Q_PREF_VMID_EN : 0) | - ((conf->rx_q_compl_vmid_en == AL_TRUE) ? - UDMA_GEN_VMPR_CFG_VMPR_4_RX_Q_CMPL_VMID_EN : 0)); - - al_reg_write32_masked( - &vmpr->cfg_vmpr_6, - UDMA_GEN_VMPR_CFG_VMPR_6_RX_Q_PREF_VMID_MASK | - UDMA_GEN_VMPR_CFG_VMPR_6_RX_Q_CMPL_VMID_MASK, - (conf->rx_q_prefetch_vmid << - UDMA_GEN_VMPR_CFG_VMPR_6_RX_Q_PREF_VMID_SHIFT) | - (conf->rx_q_compl_vmid << - UDMA_GEN_VMPR_CFG_VMPR_6_RX_Q_CMPL_VMID_SHIFT)); - - al_reg_write32_masked( - &vmpr->cfg_vmpr_7, - UDMA_GEN_VMPR_CFG_VMPR_7_RX_Q_BUF1_VMID_MASK | - UDMA_GEN_VMPR_CFG_VMPR_7_RX_Q_BUF1_VMID_SEL_MASK, - (conf->rx_q_data_vmid << - UDMA_GEN_VMPR_CFG_VMPR_7_RX_Q_BUF1_VMID_SHIFT) | - (conf->rx_q_data_vmid_mask << - UDMA_GEN_VMPR_CFG_VMPR_7_RX_Q_BUF1_VMID_SEL_SHIFT)); - - al_reg_write32_masked( - &vmpr->cfg_vmpr_8, - UDMA_GEN_VMPR_CFG_VMPR_8_RX_Q_BUF2_VMID_MASK | - UDMA_GEN_VMPR_CFG_VMPR_8_RX_Q_BUF2_VMID_SEL_MASK, - (conf->rx_q_data_buff2_vmid << - UDMA_GEN_VMPR_CFG_VMPR_8_RX_Q_BUF2_VMID_SHIFT) | - (conf->rx_q_data_buff2_mask << - UDMA_GEN_VMPR_CFG_VMPR_8_RX_Q_BUF2_VMID_SEL_SHIFT)); - - al_reg_write32_masked( - &vmpr->cfg_vmpr_9, - UDMA_GEN_VMPR_CFG_VMPR_9_RX_Q_DDP_VMID_MASK | - UDMA_GEN_VMPR_CFG_VMPR_9_RX_Q_DDP_VMID_SEL_MASK, - (conf->rx_q_ddp_vmid << - UDMA_GEN_VMPR_CFG_VMPR_9_RX_Q_DDP_VMID_SHIFT) | - (conf->rx_q_ddp_mask << - UDMA_GEN_VMPR_CFG_VMPR_9_RX_Q_DDP_VMID_SEL_SHIFT)); - - al_reg_write32( - &vmpr->cfg_vmpr_10, - conf->rx_q_addr_hi); - - al_reg_write32( - &vmpr->cfg_vmpr_11, - conf->rx_q_data_buff2_addr_hi); - - al_reg_write32( - &vmpr->cfg_vmpr_12, - conf->rx_q_ddp_addr_hi); -} - -/* UDMA header split buffer 2 Rx queue configuration */ -void al_udma_gen_hdr_split_buff2_rx_q_conf( - struct al_udma_q *q, - struct al_udma_gen_hdr_split_buff2_q_conf *conf) -{ - struct udma_gen_regs *gen_regs = q->udma->gen_regs; - struct udma_gen_vmpr *vmpr = &gen_regs->vmpr[q->qid]; - - al_reg_write32_masked( - &vmpr->cfg_vmpr_4, - UDMA_GEN_VMPR_CFG_VMPR_4_RX_Q_BUF2_MSB_ADDR_SEL_MASK, - conf->add_msb_sel << - UDMA_GEN_VMPR_CFG_VMPR_4_RX_Q_BUF2_MSB_ADDR_SEL_SHIFT); - - al_reg_write32( - &vmpr->cfg_vmpr_5, - conf->addr_msb); -} - diff --git a/al_hal_udma_config.h b/al_hal_udma_config.h index b742e1824c9..8e689a630c2 100644 --- a/al_hal_udma_config.h +++ b/al_hal_udma_config.h @@ -1,5 +1,4 @@ -/*- -******************************************************************************* +/******************************************************************************* Copyright (C) 2015 Annapurna Labs Ltd. This file may be licensed under the terms of the Annapurna Labs Commercial @@ -313,237 +312,40 @@ struct al_udma_s2m_q_comp_conf { uint8_t q_qos; /* queue QoS */ }; -/** UDMA per queue VMID control configuration */ -struct al_udma_gen_vmid_q_conf { - /* Enable usage of the VMID per queue according to 'vmid' */ +/** UDMA per queue Target-ID control configuration */ +struct al_udma_gen_tgtid_q_conf { + /* Enable usage of the Target-ID per queue according to 'tgtid' */ al_bool queue_en; - /* Enable usage of the VMID from the descriptor buffer address 63:48 */ + /* Enable usage of the Target-ID from the descriptor buffer address 63:48 */ al_bool desc_en; - /* VMID to be applied when 'queue_en' is asserted */ - uint16_t vmid; + /* Target-ID to be applied when 'queue_en' is asserted */ + uint16_t tgtid; - /* VMADDR to be applied to msbs when 'desc_en' is asserted. + /* TGTADDR to be applied to msbs when 'desc_en' is asserted. * Relevant for revisions >= AL_UDMA_REV_ID_REV2 */ - uint16_t vmaddr; + uint16_t tgtaddr; }; -/** UDMA VMID control configuration */ -struct al_udma_gen_vmid_conf { +/** UDMA Target-ID control configuration */ +struct al_udma_gen_tgtid_conf { /* TX queue configuration */ - struct al_udma_gen_vmid_q_conf tx_q_conf[DMA_MAX_Q]; + struct al_udma_gen_tgtid_q_conf tx_q_conf[DMA_MAX_Q]; /* RX queue configuration */ - struct al_udma_gen_vmid_q_conf rx_q_conf[DMA_MAX_Q]; + struct al_udma_gen_tgtid_q_conf rx_q_conf[DMA_MAX_Q]; }; -/** UDMA VMID MSIX control configuration */ -struct al_udma_gen_vmid_msix_conf { - /* Enable write to all VMID_n registers in the MSI-X Controller */ +/** UDMA Target-ID MSIX control configuration */ +struct al_udma_gen_tgtid_msix_conf { + /* Enable write to all TGTID_n registers in the MSI-X Controller */ al_bool access_en; - /* use VMID_n [7:0] from MSI-X Controller for MSI-X message */ + /* use TGTID_n [7:0] from MSI-X Controller for MSI-X message */ al_bool sel; }; -/** UDMA per Tx queue advanced VMID control configuration */ -struct al_udma_gen_vmid_advanced_tx_q_conf { - /********************************************************************** - * Tx Data VMID - **********************************************************************/ - /* Tx data VMID enable */ - al_bool tx_q_data_vmid_en; - - /* - * For Tx data reads, replacement bits for the original address. - * The number of bits replaced is determined according to - * 'tx_q_addr_hi_sel' - */ - unsigned int tx_q_addr_hi; - - /* - * For Tx data reads, 6 bits serving the number of bits taken from the - * extra register on account of bits coming from the original address - * field. - * When 'tx_q_addr_hi_sel'=32 all of 'tx_q_addr_hi' will be taken. - * When 'tx_q_addr_hi_sel'=0 none of it will be taken, and when any - * value in between, it will start from the MSB bit and sweep down as - * many bits as needed. For example if 'tx_q_addr_hi_sel'=8, the final - * address [63:56] will carry 'tx_q_addr_hi'[31:24] while [55:32] will - * carry the original buffer address[55:32]. - */ - unsigned int tx_q_addr_hi_sel; - - /* - * Tx data read VMID - * Masked per bit with 'tx_q_data_vmid_mask' - */ - unsigned int tx_q_data_vmid; - - /* - * Tx data read VMID mask - * Each '1' selects from the buffer address, each '0' selects from - * 'tx_q_data_vmid' - */ - unsigned int tx_q_data_vmid_mask; - - /********************************************************************** - * Tx prefetch VMID - **********************************************************************/ - /* Tx prefetch VMID enable */ - al_bool tx_q_prefetch_vmid_en; - - /* Tx prefetch VMID */ - unsigned int tx_q_prefetch_vmid; - - /********************************************************************** - * Tx completion VMID - **********************************************************************/ - /* Tx completion VMID enable */ - al_bool tx_q_compl_vmid_en; - - /* Tx completion VMID */ - unsigned int tx_q_compl_vmid; -}; - -/** UDMA per Rx queue advanced VMID control configuration */ -struct al_udma_gen_vmid_advanced_rx_q_conf { - /********************************************************************** - * Rx Data VMID - **********************************************************************/ - /* Rx data VMID enable */ - al_bool rx_q_data_vmid_en; - - /* - * For Rx data writes, replacement bits for the original address. - * The number of bits replaced is determined according to - * 'rx_q_addr_hi_sel' - */ - unsigned int rx_q_addr_hi; - - /* - * For Rx data writes, 6 bits serving the number of bits taken from the - * extra register on account of bits coming from the original address - * field. - */ - unsigned int rx_q_addr_hi_sel; - - /* - * Rx data write VMID - * Masked per bit with 'rx_q_data_vmid_mask' - */ - unsigned int rx_q_data_vmid; - - /* Rx data write VMID mask */ - unsigned int rx_q_data_vmid_mask; - - /********************************************************************** - * Rx Data Buffer 2 VMID - **********************************************************************/ - /* Rx data buff2 VMID enable */ - al_bool rx_q_data_buff2_vmid_en; - - /* - * For Rx data buff2 writes, replacement bits for the original address. - * The number of bits replaced is determined according to - * 'rx_q_data_buff2_addr_hi_sel' - */ - unsigned int rx_q_data_buff2_addr_hi; - - /* - * For Rx data buff2 writes, 6 bits serving the number of bits taken - * from the extra register on account of bits coming from the original - * address field. - */ - unsigned int rx_q_data_buff2_addr_hi_sel; - - /* - * Rx data buff2 write VMID - * Masked per bit with 'rx_q_data_buff2_mask' - */ - unsigned int rx_q_data_buff2_vmid; - - /* Rx data buff2 write VMID mask */ - unsigned int rx_q_data_buff2_mask; - - /********************************************************************** - * Rx DDP VMID - **********************************************************************/ - /* Rx DDP write VMID enable */ - al_bool rx_q_ddp_vmid_en; - - /* - * For Rx DDP writes, replacement bits for the original address. - * The number of bits replaced is determined according to - * 'rx_q_ddp_addr_hi_sel' - */ - unsigned int rx_q_ddp_addr_hi; - - /* - * For Rx DDP writes, 6 bits serving the number of bits taken from the - * extra register on account of bits coming from the original address - * field. - */ - unsigned int rx_q_ddp_addr_hi_sel; - - /* - * Rx DDP write VMID - * Masked per bit with 'rx_q_ddp_mask' - */ - unsigned int rx_q_ddp_vmid; - - /* Rx DDP write VMID mask */ - unsigned int rx_q_ddp_mask; - - /********************************************************************** - * Rx prefetch VMID - **********************************************************************/ - /* Rx prefetch VMID enable */ - al_bool rx_q_prefetch_vmid_en; - - /* Rx prefetch VMID */ - unsigned int rx_q_prefetch_vmid; - - /********************************************************************** - * Rx completion VMID - **********************************************************************/ - /* Rx completion VMID enable */ - al_bool rx_q_compl_vmid_en; - - /* Rx completion VMID */ - unsigned int rx_q_compl_vmid; -}; - -/** - * Header split, buffer 2 per queue configuration - * When header split is enabled, Buffer_2 is used as an address for the header - * data. Buffer_2 is defined as 32-bits in the RX descriptor and it is defined - * that the MSB ([63:32]) of Buffer_1 is used as address [63:32] for the header - * address. - */ -struct al_udma_gen_hdr_split_buff2_q_conf { - /* - * MSB of the 64-bit address (bits [63:32]) that can be used for header - * split for this queue - */ - unsigned int addr_msb; - - /* - * Determine how to select the MSB (bits [63:32]) of the address when - * header split is enabled (4 bits, one per byte) - * - Bits [3:0]: - * [0] – selector for bits [39:32] - * [1] – selector for bits [47:40] - * [2] – selector for bits [55:48] - * [3] – selector for bits [63:55] - * - Bit value: - * 0 – Use Buffer_1 (legacy operation) - * 1 – Use the queue configuration 'addr_msb' - */ - unsigned int add_msb_sel; -}; - /* Report Error - to be used for abort */ void al_udma_err_report(struct al_udma *udma); @@ -721,30 +523,21 @@ int al_udma_s2m_q_compl_hdr_split_config(struct al_udma_q *udma_q, int al_udma_s2m_q_comp_set(struct al_udma_q *udma_q, struct al_udma_s2m_q_comp_conf *conf); -/** UDMA VMID control configuration */ -void al_udma_gen_vmid_conf_set( +/** UDMA Target-ID control configuration per queue */ +void al_udma_gen_tgtid_conf_queue_set( + struct unit_regs *unit_regs, + struct al_udma_gen_tgtid_conf *conf, + uint32_t qid); + +/** UDMA Target-ID control configuration */ +void al_udma_gen_tgtid_conf_set( struct unit_regs __iomem *unit_regs, - struct al_udma_gen_vmid_conf *conf); + struct al_udma_gen_tgtid_conf *conf); -/** UDMA VMID MSIX control configuration */ -void al_udma_gen_vmid_msix_conf_set( +/** UDMA Target-ID MSIX control configuration */ +void al_udma_gen_tgtid_msix_conf_set( struct unit_regs __iomem *unit_regs, - struct al_udma_gen_vmid_msix_conf *conf); - -/** UDMA VMID control advanced Tx queue configuration */ -void al_udma_gen_vmid_advanced_tx_q_conf( - struct al_udma_q *q, - struct al_udma_gen_vmid_advanced_tx_q_conf *conf); - -/** UDMA VMID control advanced Rx queue configuration */ -void al_udma_gen_vmid_advanced_rx_q_conf( - struct al_udma_q *q, - struct al_udma_gen_vmid_advanced_rx_q_conf *conf); - -/** UDMA header split buffer 2 Rx queue configuration */ -void al_udma_gen_hdr_split_buff2_rx_q_conf( - struct al_udma_q *q, - struct al_udma_gen_hdr_split_buff2_q_conf *conf); + struct al_udma_gen_tgtid_msix_conf *conf); /* *INDENT-OFF* */ #ifdef __cplusplus diff --git a/al_hal_udma_debug.c b/al_hal_udma_debug.c index c6b9bf4b9bf..189e6767e89 100644 --- a/al_hal_udma_debug.c +++ b/al_hal_udma_debug.c @@ -425,9 +425,9 @@ void al_udma_q_struct_print(struct al_udma *udma, uint32_t qid) al_dbg(" comp_head_ptr = %p\n", queue->comp_head_ptr); al_dbg(" pkt_crnt_descs = %d\n", (uint32_t)queue->pkt_crnt_descs); al_dbg(" comp_ring_id = %d\n", (uint32_t)queue->comp_ring_id); - al_dbg(" desc_phy_base = 0x%016llx\n", (uint64_t)queue->desc_phy_base); - al_dbg(" cdesc_phy_base = 0x%016llx\n", - (uint64_t)queue->cdesc_phy_base); + al_dbg(" desc_phy_base = 0x%016jx\n", (uintmax_t)queue->desc_phy_base); + al_dbg(" cdesc_phy_base = 0x%016jx\n", + (uintmax_t)queue->cdesc_phy_base); al_dbg(" flags = 0x%08x\n", (uint32_t)queue->flags); al_dbg(" size = %d\n", (uint32_t)queue->size); al_dbg(" status = %d\n", (uint32_t)queue->status); @@ -471,7 +471,7 @@ void al_udma_ring_print(struct al_udma *udma, uint32_t qid, } for (i = 0; i < queue->size; i++) { - uint32_t *curr_addr = (void*)((uint32_t)base_ptr + i * desc_size); + uint32_t *curr_addr = (void*)((uintptr_t)base_ptr + i * desc_size); if (desc_size == 16) al_dbg("[%04d](%p): %08x %08x %08x %08x\n", i, diff --git a/al_hal_udma_iofic.h b/al_hal_udma_iofic.h index 9e795004837..65871c80f17 100644 --- a/al_hal_udma_iofic.h +++ b/al_hal_udma_iofic.h @@ -610,5 +610,23 @@ static INLINE uint32_t al_udma_iofic_read_cause( return al_iofic_read_cause(al_udma_iofic_reg_base_get(regs, level), group); } +/** + * clear bits in the interrupt cause register for a given group + * + * @param regs pointer to udma unit registers + * @param level the interrupt controller level (primary / secondary) + * @param group the interrupt group ('AL_INT_GROUP_*') + * @param mask bitwise of bits to be cleared, set bits will be cleared. + */ +static INLINE void al_udma_iofic_clear_cause( + struct unit_regs __iomem *regs, + enum al_udma_iofic_level level, + int group, + uint32_t mask) +{ + al_assert(al_udma_iofic_level_and_group_valid(level, group)); + al_iofic_clear_cause(al_udma_iofic_reg_base_get(regs, level), group, mask); +} + #endif /** @} end of UDMA group */ diff --git a/al_hal_udma_main.c b/al_hal_udma_main.c index 6e9919b3596..6dac88c1b7c 100644 --- a/al_hal_udma_main.c +++ b/al_hal_udma_main.c @@ -70,7 +70,6 @@ const char *const al_udma_states_name[] = { static void al_udma_set_defaults(struct al_udma *udma) { - uint32_t tmp; uint8_t rev_id = udma->rev_id; if (udma->type == UDMA_TX) { @@ -85,25 +84,11 @@ static void al_udma_set_defaults(struct al_udma *udma) 256 << UDMA_M2S_RD_DATA_CFG_DATA_FIFO_DEPTH_SHIFT); } - if (rev_id == AL_UDMA_REV_ID_0) - /* disable AXI timeout for M0*/ - al_reg_write32(&tmp_unit_regs->gen.axi.cfg_1, 0); - else - /* set AXI timeout to 1M (~2.6 ms) */ - al_reg_write32(&tmp_unit_regs->gen.axi.cfg_1, 1000000); + /* set AXI timeout to 1M (~2.6 ms) */ + al_reg_write32(&tmp_unit_regs->gen.axi.cfg_1, 1000000); al_reg_write32(&tmp_unit_regs->m2s.m2s_comp.cfg_application_ack , 0); /* Ack time out */ - - - if (rev_id == AL_UDMA_REV_ID_0) { - tmp = al_reg_read32(&udma->udma_regs->m2s.axi_m2s.desc_wr_cfg_1); - tmp &= ~UDMA_AXI_M2S_DESC_WR_CFG_1_MAX_AXI_BEATS_MASK; - tmp |= 4 << UDMA_AXI_M2S_DESC_WR_CFG_1_MAX_AXI_BEATS_SHIFT; - al_reg_write32(&udma->udma_regs->m2s.axi_m2s.desc_wr_cfg_1 - , tmp); - } - } if (udma->type == UDMA_RX) { al_reg_write32( @@ -365,14 +350,13 @@ int al_udma_q_init(struct al_udma *udma, uint32_t qid, al_udma_q_enable(udma_q, 1); al_dbg("udma [%s %d]: %s q init. size 0x%x\n" - " desc ring info: phys base 0x%llx virt base %p\n" - " cdesc ring info: phys base 0x%llx virt base %p " - "entry size 0x%x", + " desc ring info: phys base 0x%llx virt base %p)", udma_q->udma->name, udma_q->qid, udma->type == UDMA_TX ? "Tx" : "Rx", q_params->size, (unsigned long long)q_params->desc_phy_base, - q_params->desc_base, + q_params->desc_base); + al_dbg(" cdesc ring info: phys base 0x%llx virt base %p entry size 0x%x", (unsigned long long)q_params->cdesc_phy_base, q_params->cdesc_base, q_params->cdesc_size); diff --git a/al_hal_udma_regs_gen.h b/al_hal_udma_regs_gen.h index 89f94b85a56..5c60fc9506e 100644 --- a/al_hal_udma_regs_gen.h +++ b/al_hal_udma_regs_gen.h @@ -1,5 +1,4 @@ -/*- -******************************************************************************* +/******************************************************************************* Copyright (C) 2015 Annapurna Labs Ltd. This file may be licensed under the terms of the Annapurna Labs Commercial @@ -97,48 +96,48 @@ struct udma_gen_sram_ctrl { /* [0x0] Timing configuration */ uint32_t timing; }; -struct udma_gen_vmid { - /* [0x0] VMID control */ - uint32_t cfg_vmid_0; - /* [0x4] TX queue 0/1 VMID */ - uint32_t cfg_vmid_1; - /* [0x8] TX queue 2/3 VMID */ - uint32_t cfg_vmid_2; - /* [0xc] RX queue 0/1 VMID */ - uint32_t cfg_vmid_3; - /* [0x10] RX queue 2/3 VMID */ - uint32_t cfg_vmid_4; +struct udma_gen_tgtid { + /* [0x0] Target-ID control */ + uint32_t cfg_tgtid_0; + /* [0x4] TX queue 0/1 Target-ID */ + uint32_t cfg_tgtid_1; + /* [0x8] TX queue 2/3 Target-ID */ + uint32_t cfg_tgtid_2; + /* [0xc] RX queue 0/1 Target-ID */ + uint32_t cfg_tgtid_3; + /* [0x10] RX queue 2/3 Target-ID */ + uint32_t cfg_tgtid_4; }; -struct udma_gen_vmaddr { - /* [0x0] TX queue 0/1 VMADDR */ - uint32_t cfg_vmaddr_0; - /* [0x4] TX queue 2/3 VMADDR */ - uint32_t cfg_vmaddr_1; - /* [0x8] RX queue 0/1 VMADDR */ - uint32_t cfg_vmaddr_2; - /* [0xc] RX queue 2/3 VMADDR */ - uint32_t cfg_vmaddr_3; +struct udma_gen_tgtaddr { + /* [0x0] TX queue 0/1 Target-Address */ + uint32_t cfg_tgtaddr_0; + /* [0x4] TX queue 2/3 Target-Address */ + uint32_t cfg_tgtaddr_1; + /* [0x8] RX queue 0/1 Target-Address */ + uint32_t cfg_tgtaddr_2; + /* [0xc] RX queue 2/3 Target-Address */ + uint32_t cfg_tgtaddr_3; }; struct udma_gen_vmpr { /* [0x0] TX VMPR control */ uint32_t cfg_vmpr_0; /* [0x4] TX VMPR Address High Regsiter */ uint32_t cfg_vmpr_1; - /* [0x8] TX queue VMID values */ + /* [0x8] TX queue Target-ID values */ uint32_t cfg_vmpr_2; - /* [0xc] TX queue VMID values */ + /* [0xc] TX queue Target-ID values */ uint32_t cfg_vmpr_3; /* [0x10] RX VMPR control */ uint32_t cfg_vmpr_4; /* [0x14] RX VMPR Buffer2 MSB address */ uint32_t cfg_vmpr_5; - /* [0x18] RX queue VMID values */ + /* [0x18] RX queue Target-ID values */ uint32_t cfg_vmpr_6; - /* [0x1c] RX queue BUF1 VMID values */ + /* [0x1c] RX queue BUF1 Target-ID values */ uint32_t cfg_vmpr_7; - /* [0x20] RX queue BUF2 VMID values */ + /* [0x20] RX queue BUF2 Target-ID values */ uint32_t cfg_vmpr_8; - /* [0x24] RX queue Direct Data Placement VMID values */ + /* [0x24] RX queue Direct Data Placement Target-ID values */ uint32_t cfg_vmpr_9; /* [0x28] RX VMPR BUF1 Address High Regsiter */ uint32_t cfg_vmpr_10; @@ -156,8 +155,8 @@ struct udma_gen_regs { struct udma_gen_axi axi; /* [0x2280] */ struct udma_gen_sram_ctrl sram_ctrl[25]; /* [0x2380] */ uint32_t rsrvd_1[2]; - struct udma_gen_vmid vmid; /* [0x23ec] */ - struct udma_gen_vmaddr vmaddr; /* [0x2400] */ + struct udma_gen_tgtid tgtid; /* [0x23ec] */ + struct udma_gen_tgtaddr tgtaddr; /* [0x2400] */ uint32_t rsrvd_2[252]; struct udma_gen_vmpr vmpr[4]; /* [0x2800] */ }; @@ -236,176 +235,182 @@ struct udma_gen_regs { /* Read margin enable */ #define UDMA_GEN_SRAM_CTRL_TIMING_RMEB (1 << 24) -/**** cfg_vmid_0 register ****/ -/* For M2S queues 3:0, enable usage of the VMID from the buffer address 63:56 */ -#define UDMA_GEN_VMID_CFG_VMID_0_TX_Q_VMID_DESC_EN_MASK 0x0000000F -#define UDMA_GEN_VMID_CFG_VMID_0_TX_Q_VMID_DESC_EN_SHIFT 0 +/**** cfg_tgtid_0 register ****/ +/* For M2S queues 3:0, enable usage of the Target-ID from the buffer address 63:56 */ +#define UDMA_GEN_TGTID_CFG_TGTID_0_TX_Q_TGTID_DESC_EN_MASK 0x0000000F +#define UDMA_GEN_TGTID_CFG_TGTID_0_TX_Q_TGTID_DESC_EN_SHIFT 0 /* - * For M2S queues 3:0, enable usage of the VMID from the configuration register - * (cfg_vmid_1/2 used for M2S queue_x) + * For M2S queues 3:0, enable usage of the Target-ID from the configuration register + * (cfg_tgtid_1/2 used for M2S queue_x) */ -#define UDMA_GEN_VMID_CFG_VMID_0_TX_Q_VMID_QUEUE_EN_MASK 0x000000F0 -#define UDMA_GEN_VMID_CFG_VMID_0_TX_Q_VMID_QUEUE_EN_SHIFT 4 -/* use VMID_n [7:0] from MSI-X Controller for MSI-X message */ -#define UDMA_GEN_VMID_CFG_VMID_0_MSIX_VMID_SEL (1 << 8) -/* Enable write to all VMID_n registers in the MSI-X Controller */ -#define UDMA_GEN_VMID_CFG_VMID_0_MSIX_VMID_ACCESS_EN (1 << 9) -/* For S2M queues 3:0, enable usage of the VMID from the buffer address 63:56 */ -#define UDMA_GEN_VMID_CFG_VMID_0_RX_Q_VMID_DESC_EN_MASK 0x000F0000 -#define UDMA_GEN_VMID_CFG_VMID_0_RX_Q_VMID_DESC_EN_SHIFT 16 +#define UDMA_GEN_TGTID_CFG_TGTID_0_TX_Q_TGTID_QUEUE_EN_MASK 0x000000F0 +#define UDMA_GEN_TGTID_CFG_TGTID_0_TX_Q_TGTID_QUEUE_EN_SHIFT 4 +/* use Target-ID_n [7:0] from MSI-X Controller for MSI-X message */ +#define UDMA_GEN_TGTID_CFG_TGTID_0_MSIX_TGTID_SEL (1 << 8) +/* Enable write to all Target-ID_n registers in the MSI-X Controller */ +#define UDMA_GEN_TGTID_CFG_TGTID_0_MSIX_TGTID_ACCESS_EN (1 << 9) +/* For S2M queues 3:0, enable usage of the Target-ID from the buffer address 63:56 */ +#define UDMA_GEN_TGTID_CFG_TGTID_0_RX_Q_TGTID_DESC_EN_MASK 0x000F0000 +#define UDMA_GEN_TGTID_CFG_TGTID_0_RX_Q_TGTID_DESC_EN_SHIFT 16 /* - * For S2M queues 3:0, enable usage of the VMID from the configuration register - * (cfg_vmid_3/4 used for M2S queue_x) + * For S2M queues 3:0, enable usage of the Target-ID from the configuration register + * (cfg_tgtid_3/4 used for M2S queue_x) */ -#define UDMA_GEN_VMID_CFG_VMID_0_RX_Q_VMID_QUEUE_EN_MASK 0x00F00000 -#define UDMA_GEN_VMID_CFG_VMID_0_RX_Q_VMID_QUEUE_EN_SHIFT 20 +#define UDMA_GEN_TGTID_CFG_TGTID_0_RX_Q_TGTID_QUEUE_EN_MASK 0x00F00000 +#define UDMA_GEN_TGTID_CFG_TGTID_0_RX_Q_TGTID_QUEUE_EN_SHIFT 20 -/**** cfg_vmid_1 register ****/ -/* TX queue 0 VMID value */ -#define UDMA_GEN_VMID_CFG_VMID_1_TX_Q_0_VMID_MASK 0x0000FFFF -#define UDMA_GEN_VMID_CFG_VMID_1_TX_Q_0_VMID_SHIFT 0 -/* TX queue 1 VMID value */ -#define UDMA_GEN_VMID_CFG_VMID_1_TX_Q_1_VMID_MASK 0xFFFF0000 -#define UDMA_GEN_VMID_CFG_VMID_1_TX_Q_1_VMID_SHIFT 16 +#define UDMA_GEN_TGTID_CFG_TGTID_SHIFT(qid) (((qid) & 0x1) ? 16 : 0) +#define UDMA_GEN_TGTID_CFG_TGTID_MASK(qid) (((qid) & 0x1) ? 0xFFFF0000 : 0x0000FFFF) -/**** cfg_vmid_2 register ****/ -/* TX queue 2 VMID value */ -#define UDMA_GEN_VMID_CFG_VMID_2_TX_Q_2_VMID_MASK 0x0000FFFF -#define UDMA_GEN_VMID_CFG_VMID_2_TX_Q_2_VMID_SHIFT 0 -/* TX queue 3 VMID value */ -#define UDMA_GEN_VMID_CFG_VMID_2_TX_Q_3_VMID_MASK 0xFFFF0000 -#define UDMA_GEN_VMID_CFG_VMID_2_TX_Q_3_VMID_SHIFT 16 +/**** cfg_tgtid_1 register ****/ +/* TX queue 0 Target-ID value */ +#define UDMA_GEN_TGTID_CFG_TGTID_1_TX_Q_0_TGTID_MASK 0x0000FFFF +#define UDMA_GEN_TGTID_CFG_TGTID_1_TX_Q_0_TGTID_SHIFT 0 +/* TX queue 1 Target-ID value */ +#define UDMA_GEN_TGTID_CFG_TGTID_1_TX_Q_1_TGTID_MASK 0xFFFF0000 +#define UDMA_GEN_TGTID_CFG_TGTID_1_TX_Q_1_TGTID_SHIFT 16 -/**** cfg_vmid_3 register ****/ -/* RX queue 0 VMID value */ -#define UDMA_GEN_VMID_CFG_VMID_3_RX_Q_0_VMID_MASK 0x0000FFFF -#define UDMA_GEN_VMID_CFG_VMID_3_RX_Q_0_VMID_SHIFT 0 -/* RX queue 1 VMID value */ -#define UDMA_GEN_VMID_CFG_VMID_3_RX_Q_1_VMID_MASK 0xFFFF0000 -#define UDMA_GEN_VMID_CFG_VMID_3_RX_Q_1_VMID_SHIFT 16 +/**** cfg_tgtid_2 register ****/ +/* TX queue 2 Target-ID value */ +#define UDMA_GEN_TGTID_CFG_TGTID_2_TX_Q_2_TGTID_MASK 0x0000FFFF +#define UDMA_GEN_TGTID_CFG_TGTID_2_TX_Q_2_TGTID_SHIFT 0 +/* TX queue 3 Target-ID value */ +#define UDMA_GEN_TGTID_CFG_TGTID_2_TX_Q_3_TGTID_MASK 0xFFFF0000 +#define UDMA_GEN_TGTID_CFG_TGTID_2_TX_Q_3_TGTID_SHIFT 16 -/**** cfg_vmid_4 register ****/ -/* RX queue 2 VMID value */ -#define UDMA_GEN_VMID_CFG_VMID_4_RX_Q_2_VMID_MASK 0x0000FFFF -#define UDMA_GEN_VMID_CFG_VMID_4_RX_Q_2_VMID_SHIFT 0 -/* RX queue 3 VMID value */ -#define UDMA_GEN_VMID_CFG_VMID_4_RX_Q_3_VMID_MASK 0xFFFF0000 -#define UDMA_GEN_VMID_CFG_VMID_4_RX_Q_3_VMID_SHIFT 16 +/**** cfg_tgtid_3 register ****/ +/* RX queue 0 Target-ID value */ +#define UDMA_GEN_TGTID_CFG_TGTID_3_RX_Q_0_TGTID_MASK 0x0000FFFF +#define UDMA_GEN_TGTID_CFG_TGTID_3_RX_Q_0_TGTID_SHIFT 0 +/* RX queue 1 Target-ID value */ +#define UDMA_GEN_TGTID_CFG_TGTID_3_RX_Q_1_TGTID_MASK 0xFFFF0000 +#define UDMA_GEN_TGTID_CFG_TGTID_3_RX_Q_1_TGTID_SHIFT 16 -/**** cfg_vmaddr_0 register ****/ -/* TX queue 0 VMADDR value */ -#define UDMA_GEN_VMADDR_CFG_VMADDR_0_TX_Q_0_VMADDR_MASK 0x0000FFFF -#define UDMA_GEN_VMADDR_CFG_VMADDR_0_TX_Q_0_VMADDR_SHIFT 0 -/* TX queue 1 VMADDR value */ -#define UDMA_GEN_VMADDR_CFG_VMADDR_0_TX_Q_1_VMADDR_MASK 0xFFFF0000 -#define UDMA_GEN_VMADDR_CFG_VMADDR_0_TX_Q_1_VMADDR_SHIFT 16 +/**** cfg_tgtid_4 register ****/ +/* RX queue 2 Target-ID value */ +#define UDMA_GEN_TGTID_CFG_TGTID_4_RX_Q_2_TGTID_MASK 0x0000FFFF +#define UDMA_GEN_TGTID_CFG_TGTID_4_RX_Q_2_TGTID_SHIFT 0 +/* RX queue 3 Target-ID value */ +#define UDMA_GEN_TGTID_CFG_TGTID_4_RX_Q_3_TGTID_MASK 0xFFFF0000 +#define UDMA_GEN_TGTID_CFG_TGTID_4_RX_Q_3_TGTID_SHIFT 16 -/**** cfg_vmaddr_1 register ****/ -/* TX queue 2 VMADDR value */ -#define UDMA_GEN_VMADDR_CFG_VMADDR_1_TX_Q_2_VMADDR_MASK 0x0000FFFF -#define UDMA_GEN_VMADDR_CFG_VMADDR_1_TX_Q_2_VMADDR_SHIFT 0 -/* TX queue 3 VMADDR value */ -#define UDMA_GEN_VMADDR_CFG_VMADDR_1_TX_Q_3_VMADDR_MASK 0xFFFF0000 -#define UDMA_GEN_VMADDR_CFG_VMADDR_1_TX_Q_3_VMADDR_SHIFT 16 +#define UDMA_GEN_TGTADDR_CFG_SHIFT(qid) (((qid) & 0x1) ? 16 : 0) +#define UDMA_GEN_TGTADDR_CFG_MASK(qid) (((qid) & 0x1) ? 0xFFFF0000 : 0x0000FFFF) -/**** cfg_vmaddr_2 register ****/ -/* RX queue 0 VMADDR value */ -#define UDMA_GEN_VMADDR_CFG_VMADDR_2_RX_Q_0_VMADDR_MASK 0x0000FFFF -#define UDMA_GEN_VMADDR_CFG_VMADDR_2_RX_Q_0_VMADDR_SHIFT 0 -/* RX queue 1 VMADDR value */ -#define UDMA_GEN_VMADDR_CFG_VMADDR_2_RX_Q_1_VMADDR_MASK 0xFFFF0000 -#define UDMA_GEN_VMADDR_CFG_VMADDR_2_RX_Q_1_VMADDR_SHIFT 16 +/**** cfg_tgtaddr_0 register ****/ +/* TX queue 0 Target-Address value */ +#define UDMA_GEN_TGTADDR_CFG_TGTADDR_0_TX_Q_0_TGTADDR_MASK 0x0000FFFF +#define UDMA_GEN_TGTADDR_CFG_TGTADDR_0_TX_Q_0_TGTADDR_SHIFT 0 +/* TX queue 1 Target-Address value */ +#define UDMA_GEN_TGTADDR_CFG_TGTADDR_0_TX_Q_1_TGTADDR_MASK 0xFFFF0000 +#define UDMA_GEN_TGTADDR_CFG_TGTADDR_0_TX_Q_1_TGTADDR_SHIFT 16 -/**** cfg_vmaddr_3 register ****/ -/* RX queue 2 VMADDR value */ -#define UDMA_GEN_VMADDR_CFG_VMADDR_3_RX_Q_2_VMADDR_MASK 0x0000FFFF -#define UDMA_GEN_VMADDR_CFG_VMADDR_3_RX_Q_2_VMADDR_SHIFT 0 -/* RX queue 3 VMADDR value */ -#define UDMA_GEN_VMADDR_CFG_VMADDR_3_RX_Q_3_VMADDR_MASK 0xFFFF0000 -#define UDMA_GEN_VMADDR_CFG_VMADDR_3_RX_Q_3_VMADDR_SHIFT 16 +/**** cfg_tgtaddr_1 register ****/ +/* TX queue 2 Target-Address value */ +#define UDMA_GEN_TGTADDR_CFG_TGTADDR_1_TX_Q_2_TGTADDR_MASK 0x0000FFFF +#define UDMA_GEN_TGTADDR_CFG_TGTADDR_1_TX_Q_2_TGTADDR_SHIFT 0 +/* TX queue 3 Target-Address value */ +#define UDMA_GEN_TGTADDR_CFG_TGTADDR_1_TX_Q_3_TGTADDR_MASK 0xFFFF0000 +#define UDMA_GEN_TGTADDR_CFG_TGTADDR_1_TX_Q_3_TGTADDR_SHIFT 16 + +/**** cfg_tgtaddr_2 register ****/ +/* RX queue 0 Target-Address value */ +#define UDMA_GEN_TGTADDR_CFG_TGTADDR_2_RX_Q_0_TGTADDR_MASK 0x0000FFFF +#define UDMA_GEN_TGTADDR_CFG_TGTADDR_2_RX_Q_0_TGTADDR_SHIFT 0 +/* RX queue 1 Target-Address value */ +#define UDMA_GEN_TGTADDR_CFG_TGTADDR_2_RX_Q_1_TGTADDR_MASK 0xFFFF0000 +#define UDMA_GEN_TGTADDR_CFG_TGTADDR_2_RX_Q_1_TGTADDR_SHIFT 16 + +/**** cfg_tgtaddr_3 register ****/ +/* RX queue 2 Target-Address value */ +#define UDMA_GEN_TGTADDR_CFG_TGTADDR_3_RX_Q_2_TGTADDR_MASK 0x0000FFFF +#define UDMA_GEN_TGTADDR_CFG_TGTADDR_3_RX_Q_2_TGTADDR_SHIFT 0 +/* RX queue 3 Target-Address value */ +#define UDMA_GEN_TGTADDR_CFG_TGTADDR_3_RX_Q_3_TGTADDR_MASK 0xFFFF0000 +#define UDMA_GEN_TGTADDR_CFG_TGTADDR_3_RX_Q_3_TGTADDR_SHIFT 16 /**** cfg_vmpr_0 register ****/ /* TX High Address Select Per Q */ #define UDMA_GEN_VMPR_CFG_VMPR_0_TX_Q_HISEL_MASK 0x0000003F #define UDMA_GEN_VMPR_CFG_VMPR_0_TX_Q_HISEL_SHIFT 0 -/* TX Data VMID Enable Per Q */ -#define UDMA_GEN_VMPR_CFG_VMPR_0_TX_Q_DATA_VMID_EN (1 << 7) -/* TX Prefetch VMID Enable Per Q */ -#define UDMA_GEN_VMPR_CFG_VMPR_0_TX_Q_PREF_VMID_EN (1 << 28) -/* TX Completions VMID Enable Per Q */ -#define UDMA_GEN_VMPR_CFG_VMPR_0_TX_Q_CMPL_VMID_EN (1 << 29) +/* TX Data Target-ID Enable Per Q */ +#define UDMA_GEN_VMPR_CFG_VMPR_0_TX_Q_DATA_TGTID_EN (1 << 7) +/* TX Prefetch Target-ID Enable Per Q */ +#define UDMA_GEN_VMPR_CFG_VMPR_0_TX_Q_PREF_TGTID_EN (1 << 28) +/* TX Completions Target-ID Enable Per Q */ +#define UDMA_GEN_VMPR_CFG_VMPR_0_TX_Q_CMPL_TGTID_EN (1 << 29) /**** cfg_vmpr_2 register ****/ -/* TX queue Prefetch VMID */ -#define UDMA_GEN_VMPR_CFG_VMPR_2_TX_Q_PREF_VMID_MASK 0x0000FFFF -#define UDMA_GEN_VMPR_CFG_VMPR_2_TX_Q_PREF_VMID_SHIFT 0 -/* TX queue Completion VMID */ -#define UDMA_GEN_VMPR_CFG_VMPR_2_TX_Q_CMPL_VMID_MASK 0xFFFF0000 -#define UDMA_GEN_VMPR_CFG_VMPR_2_TX_Q_CMPL_VMID_SHIFT 16 +/* TX queue Prefetch Target-ID */ +#define UDMA_GEN_VMPR_CFG_VMPR_2_TX_Q_PREF_TGTID_MASK 0x0000FFFF +#define UDMA_GEN_VMPR_CFG_VMPR_2_TX_Q_PREF_TGTID_SHIFT 0 +/* TX queue Completion Target-ID */ +#define UDMA_GEN_VMPR_CFG_VMPR_2_TX_Q_CMPL_TGTID_MASK 0xFFFF0000 +#define UDMA_GEN_VMPR_CFG_VMPR_2_TX_Q_CMPL_TGTID_SHIFT 16 /**** cfg_vmpr_3 register ****/ -/* TX queue Data VMID */ -#define UDMA_GEN_VMPR_CFG_VMPR_3_TX_Q_DATA_VMID_MASK 0x0000FFFF -#define UDMA_GEN_VMPR_CFG_VMPR_3_TX_Q_DATA_VMID_SHIFT 0 -/* TX queue Data VMID select */ -#define UDMA_GEN_VMPR_CFG_VMPR_3_TX_Q_DATA_VMID_SEL_MASK 0xFFFF0000 -#define UDMA_GEN_VMPR_CFG_VMPR_3_TX_Q_DATA_VMID_SEL_SHIFT 16 +/* TX queue Data Target-ID */ +#define UDMA_GEN_VMPR_CFG_VMPR_3_TX_Q_DATA_TGTID_MASK 0x0000FFFF +#define UDMA_GEN_VMPR_CFG_VMPR_3_TX_Q_DATA_TGTID_SHIFT 0 +/* TX queue Data Target-ID select */ +#define UDMA_GEN_VMPR_CFG_VMPR_3_TX_Q_DATA_TGTID_SEL_MASK 0xFFFF0000 +#define UDMA_GEN_VMPR_CFG_VMPR_3_TX_Q_DATA_TGTID_SEL_SHIFT 16 /**** cfg_vmpr_4 register ****/ /* RX Data Buffer1 - High Address Select Per Q */ #define UDMA_GEN_VMPR_CFG_VMPR_4_RX_Q_BUF1_HISEL_MASK 0x0000003F #define UDMA_GEN_VMPR_CFG_VMPR_4_RX_Q_BUF1_HISEL_SHIFT 0 -/* RX Data Buffer1 VMID Enable Per Q */ -#define UDMA_GEN_VMPR_CFG_VMPR_4_RX_Q_BUF1_VMID_EN (1 << 7) +/* RX Data Buffer1 Target-ID Enable Per Q */ +#define UDMA_GEN_VMPR_CFG_VMPR_4_RX_Q_BUF1_TGTID_EN (1 << 7) /* RX Data Buffer2 - High Address Select Per Q */ #define UDMA_GEN_VMPR_CFG_VMPR_4_RX_Q_BUF2_HISEL_MASK 0x00003F00 #define UDMA_GEN_VMPR_CFG_VMPR_4_RX_Q_BUF2_HISEL_SHIFT 8 -/* RX Data Buffer2 VMID Enable Per Q */ -#define UDMA_GEN_VMPR_CFG_VMPR_4_RX_Q_BUF2_VMID_EN (1 << 15) +/* RX Data Buffer2 Target-ID Enable Per Q */ +#define UDMA_GEN_VMPR_CFG_VMPR_4_RX_Q_BUF2_TGTID_EN (1 << 15) /* RX Direct Data Placement - High Address Select Per Q */ #define UDMA_GEN_VMPR_CFG_VMPR_4_RX_Q_DDP_HISEL_MASK 0x003F0000 #define UDMA_GEN_VMPR_CFG_VMPR_4_RX_Q_DDP_HISEL_SHIFT 16 -/* RX Direct Data Placement VMID Enable Per Q */ -#define UDMA_GEN_VMPR_CFG_VMPR_4_RX_Q_DDP_VMID_EN (1 << 23) +/* RX Direct Data Placement Target-ID Enable Per Q */ +#define UDMA_GEN_VMPR_CFG_VMPR_4_RX_Q_DDP_TGTID_EN (1 << 23) /* RX Buffer 2 MSB address word selects per bytes, per queue */ #define UDMA_GEN_VMPR_CFG_VMPR_4_RX_Q_BUF2_MSB_ADDR_SEL_MASK 0x0F000000 #define UDMA_GEN_VMPR_CFG_VMPR_4_RX_Q_BUF2_MSB_ADDR_SEL_SHIFT 24 -/* RX Prefetch VMID Enable Per Q */ -#define UDMA_GEN_VMPR_CFG_VMPR_4_RX_Q_PREF_VMID_EN (1 << 28) -/* RX Completions VMID Enable Per Q */ -#define UDMA_GEN_VMPR_CFG_VMPR_4_RX_Q_CMPL_VMID_EN (1 << 29) +/* RX Prefetch Target-ID Enable Per Q */ +#define UDMA_GEN_VMPR_CFG_VMPR_4_RX_Q_PREF_TGTID_EN (1 << 28) +/* RX Completions Target-ID Enable Per Q */ +#define UDMA_GEN_VMPR_CFG_VMPR_4_RX_Q_CMPL_TGTID_EN (1 << 29) /**** cfg_vmpr_6 register ****/ -/* RX queue Prefetch VMID */ -#define UDMA_GEN_VMPR_CFG_VMPR_6_RX_Q_PREF_VMID_MASK 0x0000FFFF -#define UDMA_GEN_VMPR_CFG_VMPR_6_RX_Q_PREF_VMID_SHIFT 0 -/* RX queue Completion VMID */ -#define UDMA_GEN_VMPR_CFG_VMPR_6_RX_Q_CMPL_VMID_MASK 0xFFFF0000 -#define UDMA_GEN_VMPR_CFG_VMPR_6_RX_Q_CMPL_VMID_SHIFT 16 +/* RX queue Prefetch Target-ID */ +#define UDMA_GEN_VMPR_CFG_VMPR_6_RX_Q_PREF_TGTID_MASK 0x0000FFFF +#define UDMA_GEN_VMPR_CFG_VMPR_6_RX_Q_PREF_TGTID_SHIFT 0 +/* RX queue Completion Target-ID */ +#define UDMA_GEN_VMPR_CFG_VMPR_6_RX_Q_CMPL_TGTID_MASK 0xFFFF0000 +#define UDMA_GEN_VMPR_CFG_VMPR_6_RX_Q_CMPL_TGTID_SHIFT 16 /**** cfg_vmpr_7 register ****/ -/* RX queue Data Buffer 1 VMID */ -#define UDMA_GEN_VMPR_CFG_VMPR_7_RX_Q_BUF1_VMID_MASK 0x0000FFFF -#define UDMA_GEN_VMPR_CFG_VMPR_7_RX_Q_BUF1_VMID_SHIFT 0 -/* RX queue Data Buffer 1 VMID select */ -#define UDMA_GEN_VMPR_CFG_VMPR_7_RX_Q_BUF1_VMID_SEL_MASK 0xFFFF0000 -#define UDMA_GEN_VMPR_CFG_VMPR_7_RX_Q_BUF1_VMID_SEL_SHIFT 16 +/* RX queue Data Buffer 1 Target-ID */ +#define UDMA_GEN_VMPR_CFG_VMPR_7_RX_Q_BUF1_TGTID_MASK 0x0000FFFF +#define UDMA_GEN_VMPR_CFG_VMPR_7_RX_Q_BUF1_TGTID_SHIFT 0 +/* RX queue Data Buffer 1 Target-ID select */ +#define UDMA_GEN_VMPR_CFG_VMPR_7_RX_Q_BUF1_TGTID_SEL_MASK 0xFFFF0000 +#define UDMA_GEN_VMPR_CFG_VMPR_7_RX_Q_BUF1_TGTID_SEL_SHIFT 16 /**** cfg_vmpr_8 register ****/ -/* RX queue Data Buffer 2 VMID */ -#define UDMA_GEN_VMPR_CFG_VMPR_8_RX_Q_BUF2_VMID_MASK 0x0000FFFF -#define UDMA_GEN_VMPR_CFG_VMPR_8_RX_Q_BUF2_VMID_SHIFT 0 -/* RX queue Data Buffer 2 VMID select */ -#define UDMA_GEN_VMPR_CFG_VMPR_8_RX_Q_BUF2_VMID_SEL_MASK 0xFFFF0000 -#define UDMA_GEN_VMPR_CFG_VMPR_8_RX_Q_BUF2_VMID_SEL_SHIFT 16 +/* RX queue Data Buffer 2 Target-ID */ +#define UDMA_GEN_VMPR_CFG_VMPR_8_RX_Q_BUF2_TGTID_MASK 0x0000FFFF +#define UDMA_GEN_VMPR_CFG_VMPR_8_RX_Q_BUF2_TGTID_SHIFT 0 +/* RX queue Data Buffer 2 Target-ID select */ +#define UDMA_GEN_VMPR_CFG_VMPR_8_RX_Q_BUF2_TGTID_SEL_MASK 0xFFFF0000 +#define UDMA_GEN_VMPR_CFG_VMPR_8_RX_Q_BUF2_TGTID_SEL_SHIFT 16 /**** cfg_vmpr_9 register ****/ -/* RX queue DDP VMID */ -#define UDMA_GEN_VMPR_CFG_VMPR_9_RX_Q_DDP_VMID_MASK 0x0000FFFF -#define UDMA_GEN_VMPR_CFG_VMPR_9_RX_Q_DDP_VMID_SHIFT 0 -/* RX queue DDP VMID select */ -#define UDMA_GEN_VMPR_CFG_VMPR_9_RX_Q_DDP_VMID_SEL_MASK 0xFFFF0000 -#define UDMA_GEN_VMPR_CFG_VMPR_9_RX_Q_DDP_VMID_SEL_SHIFT 16 +/* RX queue DDP Target-ID */ +#define UDMA_GEN_VMPR_CFG_VMPR_9_RX_Q_DDP_TGTID_MASK 0x0000FFFF +#define UDMA_GEN_VMPR_CFG_VMPR_9_RX_Q_DDP_TGTID_SHIFT 0 +/* RX queue DDP Target-ID select */ +#define UDMA_GEN_VMPR_CFG_VMPR_9_RX_Q_DDP_TGTID_SEL_MASK 0xFFFF0000 +#define UDMA_GEN_VMPR_CFG_VMPR_9_RX_Q_DDP_TGTID_SEL_SHIFT 16 #ifdef __cplusplus } diff --git a/al_hal_unit_adapter_regs.h b/al_hal_unit_adapter_regs.h index 740b959ab43..7a832cde94c 100644 --- a/al_hal_unit_adapter_regs.h +++ b/al_hal_unit_adapter_regs.h @@ -274,11 +274,11 @@ extern "C" { #define AL_ADPTR_GEN_CTL_13_SATA_ARUSER_VAL_SHIFT 0 #define AL_ADPTR_GEN_CTL_13_SATA_ARUSER_SEL_MASK AL_FIELD_MASK(31, 16) #define AL_ADPTR_GEN_CTL_13_SATA_ARUSER_SEL_SHIFT 16 -/* Central VMID enabler. If set, then each entry will be used as programmed */ -#define AL_ADPTR_GEN_CTL_14_SATA_MSIX_VMID_SEL AL_BIT(0) -/* Allow access to store VMID values per entry */ -#define AL_ADPTR_GEN_CTL_14_SATA_MSIX_VMID_ACCESS_EN AL_BIT(1) -/* VMID Address select */ +/* Central Target-ID enabler. If set, then each entry will be used as programmed */ +#define AL_ADPTR_GEN_CTL_14_SATA_MSIX_TGTID_SEL AL_BIT(0) +/* Allow access to store Target-ID values per entry */ +#define AL_ADPTR_GEN_CTL_14_SATA_MSIX_TGTID_ACCESS_EN AL_BIT(1) +/* Target-ID Address select */ /* Tx */ #define AL_ADPTR_GEN_CTL_14_SATA_VM_ARADDR_SEL_MASK AL_FIELD_MASK(13, 8) #define AL_ADPTR_GEN_CTL_14_SATA_VM_ARADDR_SEL_SHIFT 8 @@ -294,13 +294,13 @@ extern "C" { /* * ROB registers */ -/* Read ROB_Enable, when disabled the read ROB is bypassed */ +/* Read ROB Enable, when disabled the read ROB is bypassed */ #define AL_ADPTR_GEN_CTL_19_READ_ROB_EN AL_BIT(0) /* Read force in-order of every read transaction */ #define AL_ADPTR_GEN_CTL_19_READ_ROB_FORCE_INORDER AL_BIT(1) /* Read software reset */ #define AL_ADPTR_GEN_CTL_19_READ_ROB_SW_RESET AL_BIT(15) -/* Write ROB_Enable, when disabled_the_Write ROB is bypassed */ +/* Write ROB Enable, when disabled the Write ROB is bypassed */ #define AL_ADPTR_GEN_CTL_19_WRITE_ROB_EN AL_BIT(16) /* Write force in-order of every write transaction */ #define AL_ADPTR_GEN_CTL_19_WRITE_ROB_FORCE_INORDER AL_BIT(17) diff --git a/al_serdes.c b/al_serdes.c new file mode 100644 index 00000000000..6f978232756 --- /dev/null +++ b/al_serdes.c @@ -0,0 +1,59 @@ +/******************************************************************************* +Copyright (C) 2015 Annapurna Labs Ltd. + +This file may be licensed under the terms of the Annapurna Labs Commercial +License Agreement. + +Alternatively, this file can be distributed under the terms of the GNU General +Public License V2 as published by the Free Software Foundation and can be +found at http://www.gnu.org/licenses/gpl-2.0.html + +Alternatively, redistribution and use in source and binary forms, with or +without modification, are permitted provided that the following conditions are +met: + + * Redistributions of source code must retain the above copyright notice, +this list of conditions and the following disclaimer. + + * Redistributions in binary form must reproduce the above copyright +notice, this list of conditions and the following disclaimer in +the documentation and/or other materials provided with the +distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +*******************************************************************************/ + +#include "al_serdes.h" +#include "al_hal_serdes_hssp.h" +#include "al_hal_serdes_25g.h" + +static int(*handle_init[AL_SRDS_NUM_GROUPS])(void __iomem *, struct al_serdes_grp_obj *) = { + al_serdes_hssp_handle_init, + al_serdes_hssp_handle_init, + al_serdes_hssp_handle_init, + al_serdes_hssp_handle_init, +#if CHECK_ALPINE_V2 + al_serdes_25g_handle_init, +#endif +}; + +int al_serdes_handle_grp_init( + void __iomem *serdes_regs_base, + enum al_serdes_group grp, + struct al_serdes_grp_obj *obj) +{ + handle_init[grp](serdes_regs_base, obj); + + return 0; +} + diff --git a/al_serdes.h b/al_serdes.h new file mode 100644 index 00000000000..44e217e7887 --- /dev/null +++ b/al_serdes.h @@ -0,0 +1,78 @@ +/******************************************************************************* +Copyright (C) 2013 Annapurna Labs Ltd. + +This file is licensed under the terms of the Annapurna Labs' Commercial License +Agreement distributed with the file or available on the software download site. +Recipient shall use the content of this file only on semiconductor devices or +systems developed by or for Annapurna Labs. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR + ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +*******************************************************************************/ + +/** + * @defgroup group_serdes_init SerDes Initialization + * @ingroup group_serdes SerDes + * @{ + * + * @file al_serdes.h + * + */ + +#ifndef __AL_SERDES_H__ +#define __AL_SERDES_H__ + +#include "al_hal_serdes_interface.h" + +/* *INDENT-OFF* */ +#ifdef __cplusplus +extern "C" { +#endif +/* *INDENT-ON* */ + +#ifdef AL_DEV_ID +#define CHECK_ALPINE_V1 (AL_DEV_ID == AL_DEV_ID_ALPINE_V1) +#define CHECK_ALPINE_V2 (AL_DEV_ID == AL_DEV_ID_ALPINE_V2) +#else +#define CHECK_ALPINE_V1 1 +#define CHECK_ALPINE_V2 1 +#endif + +enum al_serdes_group { + AL_SRDS_GRP_A = 0, + AL_SRDS_GRP_B, + AL_SRDS_GRP_C, + AL_SRDS_GRP_D, + AL_SRDS_NUM_HSSP_GROUPS, +#if CHECK_ALPINE_V2 + AL_SRDS_GRP_E = AL_SRDS_NUM_HSSP_GROUPS, + AL_SRDS_NUM_GROUPS, +#else + AL_SRDS_NUM_GROUPS = AL_SRDS_NUM_HSSP_GROUPS, +#endif +}; + +int al_serdes_handle_grp_init( + void __iomem *serdes_regs_base, + enum al_serdes_group grp, + struct al_serdes_grp_obj *obj); + +/* *INDENT-OFF* */ +#ifdef __cplusplus +} +#endif + +/* *INDENT-ON* */ +#endif + +/** @} end of SERDES group */ + diff --git a/eth/al_hal_eth.h b/eth/al_hal_eth.h index 86108b0df4c..12944d30772 100644 --- a/eth/al_hal_eth.h +++ b/eth/al_hal_eth.h @@ -68,7 +68,7 @@ extern "C" { #ifndef AL_ETH_EX #define AL_ETH_PKT_MAX_BUFS 19 #else -#define AL_ETH_PKT_MAX_BUFS 29 +#define AL_ETH_PKT_MAX_BUFS 30 #endif #endif @@ -136,7 +136,8 @@ enum al_eth_mac_mode { AL_ETH_MAC_MODE_10G_SGMII, /**< SGMII using the 10G MAC, don't use*/ AL_ETH_MAC_MODE_XLG_LL_40G, /**< applies to 40G mode using the 40G low latency (LL) MAC */ AL_ETH_MAC_MODE_KR_LL_25G, /**< applies to 25G mode using the 10/25G low latency (LL) MAC */ - AL_ETH_MAC_MODE_XLG_LL_50G /**< applies to 50G mode using the 40/50G low latency (LL) MAC */ + AL_ETH_MAC_MODE_XLG_LL_50G, /**< applies to 50G mode using the 40/50G low latency (LL) MAC */ + AL_ETH_MAC_MODE_XLG_LL_25G /**< applies to 25G mode using the 40/50G low latency (LL) MAC */ }; struct al_eth_capabilities { @@ -338,11 +339,11 @@ struct al_eth_meta_data{ /* Packet Rx flags when adding buffer to receive queue */ /**< - * VMID to be assigned to the packet descriptors - * Requires VMID in descriptor to be enabled for the specific UDMA + * Target-ID to be assigned to the packet descriptors + * Requires Target-ID in descriptor to be enabled for the specific UDMA * queue. */ -#define AL_ETH_RX_FLAGS_VMID_MASK AL_FIELD_MASK(15, 0) +#define AL_ETH_RX_FLAGS_TGTID_MASK AL_FIELD_MASK(15, 0) #define AL_ETH_RX_FLAGS_NO_SNOOP AL_M2S_DESC_NO_SNOOP_H #define AL_ETH_RX_FLAGS_INT AL_M2S_DESC_INT_EN #define AL_ETH_RX_FLAGS_DUAL_BUF AL_BIT(31) @@ -382,11 +383,11 @@ struct al_eth_pkt{ enum AL_ETH_PROTO_ID outer_l3_proto_idx; /**< for tunneling mode */ /**< - * VMID to be assigned to the packet descriptors - * Requires VMID in descriptor to be enabled for the specific UDMA + * Target-ID to be assigned to the packet descriptors + * Requires Target-ID in descriptor to be enabled for the specific UDMA * queue. */ - uint16_t vmid; + uint16_t tgtid; uint32_t rx_header_len; /**< header buffer length of rx packet, not used */ struct al_eth_meta_data *meta; /**< if null, then no meta added */ @@ -434,6 +435,7 @@ struct al_hal_eth_adapter{ enum al_eth_mdio_type mdio_type; /**< mdio protocol type */ al_bool shared_mdio_if; /**< when AL_TRUE, the mdio interface is shared with other controllers.*/ uint8_t curr_lt_unit; + uint8_t serdes_lane; #ifdef AL_ETH_EX struct al_eth_ex_state ex_state; #endif @@ -452,6 +454,8 @@ struct al_eth_adapter_params{ * can be null if the function is virtual */ char *name; /**< the upper layer must keep the string area */ + + uint8_t serdes_lane; /**< serdes lane (relevant to 25G macs only) */ }; /* adapter management */ @@ -563,6 +567,39 @@ int al_eth_mac_stop(struct al_hal_eth_adapter *adapter); */ int al_eth_mac_start(struct al_hal_eth_adapter *adapter); +/** + * Perform gearbox reset for tx lanes And/Or Rx lanes. + * applicable only when the controller is connected to srds25G. + * This reset should be performed after each operation that changes the clocks + * (such as serdes reset, mac stop, etc.) + * + * @param adapter pointer to the private structure. + * @param tx_reset assert and de-assert reset for tx lanes + * @param rx_reset assert and de-assert reset for rx lanes + */ +void al_eth_gearbox_reset(struct al_hal_eth_adapter *adapter, al_bool tx_reset, al_bool rx_reset); + +/** + * Enable / Disable forward error correction (FEC) + * + * @param adapter pointer to the private structure. + * @param enable true to enable FEC. false to disable FEC. + * + * @return 0 on success. negative error on failure. + */ +int al_eth_fec_enable(struct al_hal_eth_adapter *adapter, al_bool enable); + +/** + * Get forward error correction (FEC) statistics + * + * @param adapter pointer to the private structure. + * @param corrected number of bits been corrected by the FEC + * @param uncorrectable number of bits that FEC couldn't correct. + * + * @return 0 on success. negative error on failure. + */ +int al_eth_fec_stats_get(struct al_hal_eth_adapter *adapter, + uint32_t *corrected, uint32_t *uncorrectable); /** * get the adapter capabilities (speed, duplex,..) @@ -1333,6 +1370,7 @@ struct al_eth_eee_params{ uint32_t tx_eee_timer; /**< time in cycles the interface delays prior to entering eee state */ uint32_t min_interval; /**< minimum interval in cycles between two eee states */ uint32_t stop_cnt; /**< time in cycles to stop Tx mac i/f after getting out of eee state */ + al_bool fast_wake; /**< fast_wake is only applicable to 40/50G, otherwise the mode is deep_sleep */ }; /** @@ -1609,6 +1647,8 @@ int al_eth_pth_pulse_out_config(struct al_hal_eth_adapter *adapter, /* link */ struct al_eth_link_status { al_bool link_up; + al_bool local_fault; + al_bool remote_fault; }; /** @@ -1622,7 +1662,19 @@ struct al_eth_link_status { * * @return return 0 on success. otherwise on failure. */ -int al_eth_link_status_get(struct al_hal_eth_adapter *adapter, struct al_eth_link_status *status); +int al_eth_link_status_get(struct al_hal_eth_adapter *adapter, + struct al_eth_link_status *status); + +/** + * clear link status + * + * this function clear latched status of the link. + * + * @param adapter pointer to the private structure. + * + * @return return 0 if supported. + */ +int al_eth_link_status_clear(struct al_hal_eth_adapter *adapter); /** * Set LEDs to represent link status. @@ -1929,6 +1981,7 @@ enum al_eth_board_media_type { AL_ETH_BOARD_MEDIA_TYPE_AUTO_DETECT_AUTO_SPEED = 5, AL_ETH_BOARD_MEDIA_TYPE_SGMII_2_5G = 6, AL_ETH_BOARD_MEDIA_TYPE_NBASE_T = 7, + AL_ETH_BOARD_MEDIA_TYPE_25G = 8, }; enum al_eth_board_mdio_freq { @@ -1961,13 +2014,18 @@ enum al_eth_retimer_channel { AL_ETH_RETIMER_CHANNEL_B = 1, AL_ETH_RETIMER_CHANNEL_C = 2, AL_ETH_RETIMER_CHANNEL_D = 3, - AL_ETH_RETIMER_CHANNEL_MAX = 4 + AL_ETH_RETIMER_CHANNEL_E = 4, + AL_ETH_RETIMER_CHANNEL_F = 5, + AL_ETH_RETIMER_CHANNEL_G = 6, + AL_ETH_RETIMER_CHANNEL_H = 7, + AL_ETH_RETIMER_CHANNEL_MAX = 8 }; /* list of supported retimers */ enum al_eth_retimer_type { AL_ETH_RETIMER_BR_210 = 0, AL_ETH_RETIMER_BR_410 = 1, + AL_ETH_RETIMER_DS_25 = 2, AL_ETH_RETIMER_TYPE_MAX = 4, }; @@ -1999,10 +2057,12 @@ struct al_eth_board_params { al_bool retimer_exist; /**< retimer is exist on the board */ uint8_t retimer_bus_id; /**< in what i2c bus the retimer is on */ uint8_t retimer_i2c_addr; /**< i2c address of the retimer */ - enum al_eth_retimer_channel retimer_channel; /**< what channel connected to this port */ + enum al_eth_retimer_channel retimer_channel; /**< what channel connected to this port (Rx) */ al_bool dac; /**< assume direct attached cable is connected if auto detect is off or failed */ uint8_t dac_len; /**< assume this cable length if auto detect is off or failed */ enum al_eth_retimer_type retimer_type; /**< the type of the specific retimer */ + enum al_eth_retimer_channel retimer_tx_channel; /**< what channel connected to this port (Tx) */ + uint8_t gpio_sfp_present; /**< gpio number of sfp present for this port. 0 if not exist */ }; /** diff --git a/eth/al_hal_eth_mac_regs.h b/eth/al_hal_eth_mac_regs.h index a2dc745ffde..3218e5c4cac 100644 --- a/eth/al_hal_eth_mac_regs.h +++ b/eth/al_hal_eth_mac_regs.h @@ -54,6 +54,42 @@ extern "C" { * Unit Registers */ +struct al_eth_mac_1g_stats { + uint32_t reserved1[2]; + uint32_t aFramesTransmittedOK; /* 0x68 */ + uint32_t aFramesReceivedOK; /* 0x6c */ + uint32_t aFrameCheckSequenceErrors; /* 0x70 */ + uint32_t aAlignmentErrors; /* 0x74 */ + uint32_t aOctetsTransmittedOK; /* 0x78 */ + uint32_t aOctetsReceivedOK; /* 0x7c */ + uint32_t aPAUSEMACCtrlFramesTransmitted; /* 0x80 */ + uint32_t aPAUSEMACCtrlFramesReceived; /* 0x84 */ + uint32_t ifInErrors ; /* 0x88 */ + uint32_t ifOutErrors; /* 0x8c */ + uint32_t ifInUcastPkts; /* 0x90 */ + uint32_t ifInMulticastPkts; /* 0x94 */ + uint32_t ifInBroadcastPkts; /* 0x98 */ + uint32_t reserved2; + uint32_t ifOutUcastPkts; /* 0xa0 */ + uint32_t ifOutMulticastPkts; /* 0xa4 */ + uint32_t ifOutBroadcastPkts; /* 0xa8 */ + uint32_t etherStatsDropEvents; /* 0xac */ + uint32_t etherStatsOctets; /* 0xb0 */ + uint32_t etherStatsPkts; /* 0xb4 */ + uint32_t etherStatsUndersizePkts; /* 0xb8 */ + uint32_t etherStatsOversizePkts; /* 0xbc */ + uint32_t etherStatsPkts64Octets; /* 0xc0 */ + uint32_t etherStatsPkts65to127Octets; /* 0xc4 */ + uint32_t etherStatsPkts128to255Octets; /* 0xc8 */ + uint32_t etherStatsPkts256to511Octets; /* 0xcc */ + uint32_t etherStatsPkts512to1023Octets; /* 0xd0 */ + uint32_t etherStatsPkts1024to1518Octets; /* 0xd4 */ + uint32_t etherStatsPkts1519toX; /* 0xd8 */ + uint32_t etherStatsJabbers; /* 0xdc */ + uint32_t etherStatsFragments; /* 0xe0 */ + uint32_t reserved3[71]; +}; + struct al_eth_mac_1g { /* [0x0] */ uint32_t rev; @@ -82,12 +118,202 @@ struct al_eth_mac_1g { uint32_t reg_stat; uint32_t tx_ipg_len; /* [0x60] */ - uint32_t Reserved1[104]; + struct al_eth_mac_1g_stats stats; /* [0x200] */ uint32_t phy_regs_base; uint32_t Reserved2[127]; }; +struct al_eth_mac_10g_stats_v2 { + uint32_t aFramesTransmittedOK; /* 0x80 */ + uint32_t reserved1; + uint32_t aFramesReceivedOK; /* 0x88 */ + uint32_t reserved2; + uint32_t aFrameCheckSequenceErrors; /* 0x90 */ + uint32_t reserved3; + uint32_t aAlignmentErrors; /* 0x98 */ + uint32_t reserved4; + uint32_t aPAUSEMACCtrlFramesTransmitted; /* 0xa0 */ + uint32_t reserved5; + uint32_t aPAUSEMACCtrlFramesReceived; /* 0xa8 */ + uint32_t reserved6; + uint32_t aFrameTooLongErrors; /* 0xb0 */ + uint32_t reserved7; + uint32_t aInRangeLengthErrors; /* 0xb8 */ + uint32_t reserved8; + uint32_t VLANTransmittedOK; /* 0xc0 */ + uint32_t reserved9; + uint32_t VLANReceivedOK; /* 0xc8 */ + uint32_t reserved10; + uint32_t ifOutOctetsL; /* 0xd0 */ + uint32_t ifOutOctetsH; /* 0xd4 */ + uint32_t ifInOctetsL; /* 0xd8 */ + uint32_t ifInOctetsH; /* 0xdc */ + uint32_t ifInUcastPkts; /* 0xe0 */ + uint32_t reserved11; + uint32_t ifInMulticastPkts; /* 0xe8 */ + uint32_t reserved12; + uint32_t ifInBroadcastPkts; /* 0xf0 */ + uint32_t reserved13; + uint32_t ifOutErrors; /* 0xf8 */ + uint32_t reserved14[3]; + uint32_t ifOutUcastPkts; /* 0x108 */ + uint32_t reserved15; + uint32_t ifOutMulticastPkts; /* 0x110 */ + uint32_t reserved16; + uint32_t ifOutBroadcastPkts; /* 0x118 */ + uint32_t reserved17; + uint32_t etherStatsDropEvents; /* 0x120 */ + uint32_t reserved18; + uint32_t etherStatsOctets; /* 0x128 */ + uint32_t reserved19; + uint32_t etherStatsPkts; /* 0x130 */ + uint32_t reserved20; + uint32_t etherStatsUndersizePkts; /* 0x138 */ + uint32_t reserved21; + uint32_t etherStatsPkts64Octets; /* 0x140 */ + uint32_t reserved22; + uint32_t etherStatsPkts65to127Octets; /* 0x148 */ + uint32_t reserved23; + uint32_t etherStatsPkts128to255Octets; /* 0x150 */ + uint32_t reserved24; + uint32_t etherStatsPkts256to511Octets; /* 0x158 */ + uint32_t reserved25; + uint32_t etherStatsPkts512to1023Octets; /* 0x160 */ + uint32_t reserved26; + uint32_t etherStatsPkts1024to1518Octets; /* 0x168 */ + uint32_t reserved27; + uint32_t etherStatsPkts1519toX; /* 0x170 */ + uint32_t reserved28; + uint32_t etherStatsOversizePkts; /* 0x178 */ + uint32_t reserved29; + uint32_t etherStatsJabbers; /* 0x180 */ + uint32_t reserved30; + uint32_t etherStatsFragments; /* 0x188 */ + uint32_t reserved31; + uint32_t ifInErrors; /* 0x190 */ + uint32_t reserved32[91]; +}; + +struct al_eth_mac_10g_stats_v3_rx { + uint32_t etherStatsOctets; /* 0x00 */ + uint32_t reserved2; + uint32_t ifOctetsL; /* 0x08 */ + uint32_t ifOctetsH; /* 0x0c */ + uint32_t aAlignmentErrors; /* 0x10 */ + uint32_t reserved4; + uint32_t aPAUSEMACCtrlFrames; /* 0x18 */ + uint32_t reserved5; + uint32_t FramesOK; /* 0x20 */ + uint32_t reserved6; + uint32_t CRCErrors; /* 0x28 */ + uint32_t reserved7; + uint32_t VLANOK; /* 0x30 */ + uint32_t reserved8; + uint32_t ifInErrors; /* 0x38 */ + uint32_t reserved9; + uint32_t ifInUcastPkts; /* 0x40 */ + uint32_t reserved10; + uint32_t ifInMulticastPkts; /* 0x48 */ + uint32_t reserved11; + uint32_t ifInBroadcastPkts; /* 0x50 */ + uint32_t reserved12; + uint32_t etherStatsDropEvents; /* 0x58 */ + uint32_t reserved13; + uint32_t etherStatsPkts; /* 0x60 */ + uint32_t reserved14; + uint32_t etherStatsUndersizePkts; /* 0x68 */ + uint32_t reserved15; + uint32_t etherStatsPkts64Octets; /* 0x70 */ + uint32_t reserved16; + uint32_t etherStatsPkts65to127Octets; /* 0x78 */ + uint32_t reserved17; + uint32_t etherStatsPkts128to255Octets; /* 0x80 */ + uint32_t reserved18; + uint32_t etherStatsPkts256to511Octets; /* 0x88 */ + uint32_t reserved19; + uint32_t etherStatsPkts512to1023Octets; /* 0x90 */ + uint32_t reserved20; + uint32_t etherStatsPkts1024to1518Octets; /* 0x98 */ + uint32_t reserved21; + uint32_t etherStatsPkts1519toMax; /* 0xa0 */ + uint32_t reserved22; + uint32_t etherStatsOversizePkts; /* 0xa8 */ + uint32_t reserved23; + uint32_t etherStatsJabbers; /* 0xb0 */ + uint32_t reserved24; + uint32_t etherStatsFragments; /* 0xb8 */ + uint32_t reserved25; + uint32_t aMACControlFramesReceived; /* 0xc0 */ + uint32_t reserved26; + uint32_t aFrameTooLong; /* 0xc8 */ + uint32_t reserved27; + uint32_t aInRangeLengthErrors; /* 0xd0 */ + uint32_t reserved28; + uint32_t reserved29[10]; +}; + +struct al_eth_mac_10g_stats_v3_tx { + uint32_t etherStatsOctets; /* 0x00 */ + uint32_t reserved30; + uint32_t ifOctetsL; /* 0x08 */ + uint32_t ifOctetsH; /* 0x0c */ + uint32_t aAlignmentErrors; /* 0x10 */ + uint32_t reserved32; + uint32_t aPAUSEMACCtrlFrames; /* 0x18 */ + uint32_t reserved33; + uint32_t FramesOK; /* 0x20 */ + uint32_t reserved34; + uint32_t CRCErrors; /* 0x28 */ + uint32_t reserved35; + uint32_t VLANOK; /* 0x30 */ + uint32_t reserved36; + uint32_t ifOutErrors; /* 0x38 */ + uint32_t reserved37; + uint32_t ifUcastPkts; /* 0x40 */ + uint32_t reserved38; + uint32_t ifMulticastPkts; /* 0x48 */ + uint32_t reserved39; + uint32_t ifBroadcastPkts; /* 0x50 */ + uint32_t reserved40; + uint32_t etherStatsDropEvents; /* 0x58 */ + uint32_t reserved41; + uint32_t etherStatsPkts; /* 0x60 */ + uint32_t reserved42; + uint32_t etherStatsUndersizePkts; /* 0x68 */ + uint32_t reserved43; + uint32_t etherStatsPkts64Octets; /* 0x70 */ + uint32_t reserved44; + uint32_t etherStatsPkts65to127Octets; /* 0x78 */ + uint32_t reserved45; + uint32_t etherStatsPkts128to255Octets; /* 0x80 */ + uint32_t reserved46; + uint32_t etherStatsPkts256to511Octets; /* 0x88 */ + uint32_t reserved47; + uint32_t etherStatsPkts512to1023Octets; /* 0x90 */ + uint32_t reserved48; + uint32_t etherStatsPkts1024to1518Octets; /* 0x98 */ + uint32_t reserved49; + uint32_t etherStatsPkts1519toTX_MTU; /* 0xa0 */ + uint32_t reserved50; + uint32_t reserved51[4]; + uint32_t aMACControlFrames; /* 0xc0 */ + uint32_t reserved52[15]; +}; + +struct al_eth_mac_10g_stats_v3 { + uint32_t reserved1[32]; + /* 0x100 */ + struct al_eth_mac_10g_stats_v3_rx rx; + /* 0x200 */ + struct al_eth_mac_10g_stats_v3_tx tx; +}; + +union al_eth_mac_10g_stats { + struct al_eth_mac_10g_stats_v2 v2; + struct al_eth_mac_10g_stats_v3 v3; +}; + struct al_eth_mac_10g { /* [0x0] */ uint32_t rev; @@ -131,8 +357,7 @@ struct al_eth_mac_10g { uint32_t Reserved2; uint32_t ts_timestamp; /* [0x80] */ - - uint32_t Reserved3[160]; + union al_eth_mac_10g_stats stats; /* [0x300] */ uint32_t control; @@ -442,16 +667,45 @@ struct al_eth_mac_regs { * Registers Fields */ -/**** control register (1G mac) ****/ +/**** 1G MAC registers ****/ +/* cmd_cfg */ +#define ETH_1G_MAC_CMD_CFG_TX_ENA (1 << 0) +#define ETH_1G_MAC_CMD_CFG_RX_ENA (1 << 1) /* enable Half Duplex */ -#define AL_ETH_1G_MAC_CTRL_HD_EN (1 << 10) +#define ETH_1G_MAC_CMD_CFG_HD_EN (1 << 10) /* enable 1G speed */ -#define AL_ETH_1G_MAC_CTRL_1G_SPD (1 << 3) +#define ETH_1G_MAC_CMD_CFG_1G_SPD (1 << 3) /* enable 10M speed */ -#define AL_ETH_1G_MAC_CTRL_10M_SPD (1 << 25) +#define ETH_1G_MAC_CMD_CFG_10M_SPD (1 << 25) +/**** 10G MAC registers ****/ +/* cmd_cfg */ +#define ETH_10G_MAC_CMD_CFG_TX_ENA (1 << 0) +#define ETH_10G_MAC_CMD_CFG_RX_ENA (1 << 1) +#define ETH_10G_MAC_CMD_CFG_WAN_MODE (1 << 3) +#define ETH_10G_MAC_CMD_CFG_PROMIS_EN (1 << 4) +#define ETH_10G_MAC_CMD_CFG_PAD_EN (1 << 5) +#define ETH_10G_MAC_CMD_CFG_CRC_FWD (1 << 6) +#define ETH_10G_MAC_CMD_CFG_PAUSE_FWD (1 << 7) +#define ETH_10G_MAC_CMD_CFG_PAUSE_IGNORE (1 << 8) +#define ETH_10G_MAC_CMD_CFG_TX_ADDR_INS (1 << 9) +#define ETH_10G_MAC_CMD_CFG_LOOP_ENA (1 << 10) +#define ETH_10G_MAC_CMD_CFG_TX_PAD_EN (1 << 11) +#define ETH_10G_MAC_CMD_CFG_SW_RESET (1 << 12) +#define ETH_10G_MAC_CMD_CFG_CNTL_FRM_ENA (1 << 13) +#define ETH_10G_MAC_CMD_CFG_RX_ERR_DISC (1 << 14) +#define ETH_10G_MAC_CMD_CFG_PHY_TXENA (1 << 15) +#define ETH_10G_MAC_CMD_CFG_FORCE_SEND_IDLE (1 << 16) +#define ETH_10G_MAC_CMD_CFG_NO_LGTH_CHECK (1 << 17) +#define ETH_10G_MAC_CMD_CFG_COL_CNT_EXT (1 << 18) +#define ETH_10G_MAC_CMD_CFG_PFC_MODE (1 << 19) +#define ETH_10G_MAC_CMD_CFG_PAUSE_PFC_COMP (1 << 20) +#define ETH_10G_MAC_CMD_CFG_SFD_ANY (1 << 21) +#define ETH_10G_MAC_CMD_CFG_TX_FLUSH (1 << 22) +#define ETH_10G_MAC_CMD_CFG_TX_LOWP_ENA (1 << 23) +#define ETH_10G_MAC_CMD_CFG_REG_LOWP_RXEMPTY (1 << 24) +#define ETH_10G_MAC_CMD_CFG_SHORT_DISCARD (1 << 25) -/**** 10G MAC register ****/ /* mdio_cfg_status */ #define ETH_10G_MAC_MDIO_CFG_HOLD_TIME_MASK 0x0000001c #define ETH_10G_MAC_MDIO_CFG_HOLD_TIME_SHIFT 2 @@ -465,6 +719,27 @@ struct al_eth_mac_regs { #define ETH_10G_MAC_MDIO_CFG_HOLD_TIME_13_CLK 6 #define ETH_10G_MAC_MDIO_CFG_HOLD_TIME_15_CLK 7 +/* control */ +#define ETH_10G_MAC_CONTROL_AN_EN_MASK 0x00001000 +#define ETH_10G_MAC_CONTROL_AN_EN_SHIFT 12 + +/* if_mode */ +#define ETH_10G_MAC_IF_MODE_SGMII_EN_MASK 0x00000001 +#define ETH_10G_MAC_IF_MODE_SGMII_EN_SHIFT 0 +#define ETH_10G_MAC_IF_MODE_SGMII_AN_MASK 0x00000002 +#define ETH_10G_MAC_IF_MODE_SGMII_AN_SHIFT 1 +#define ETH_10G_MAC_IF_MODE_SGMII_SPEED_MASK 0x0000000c +#define ETH_10G_MAC_IF_MODE_SGMII_SPEED_SHIFT 2 +#define ETH_10G_MAC_IF_MODE_SGMII_DUPLEX_MASK 0x00000010 +#define ETH_10G_MAC_IF_MODE_SGMII_DUPLEX_SHIFT 4 + +#define ETH_10G_MAC_IF_MODE_SGMII_SPEED_10M 0 +#define ETH_10G_MAC_IF_MODE_SGMII_SPEED_100M 1 +#define ETH_10G_MAC_IF_MODE_SGMII_SPEED_1G 2 + +#define ETH_10G_MAC_IF_MODE_SGMII_DUPLEX_FULL 0 +#define ETH_10G_MAC_IF_MODE_SGMII_DUPLEX_HALF 1 + /**** version register ****/ /* Revision number (Minor) */ #define ETH_MAC_GEN_VERSION_RELEASE_NUM_MINOR_MASK 0x000000FF @@ -1794,9 +2069,13 @@ struct al_eth_mac_regs { /*** PCS Core registers addresses ***/ /* 40g control/status */ #define ETH_MAC_GEN_V3_PCS_40G_CONTROL_STATUS_ADDR 0x00000000 +/* 40g EEE control and capability */ +#define ETH_MAC_GEN_V3_PCS_40G_EEE_CONTROL_ADDR 0x00000028 /* 10g control_1 */ #define ETH_MAC_KR_PCS_CONTROL_1_ADDR 0x00000000 +#define ETH_MAC_KR_PCS_BASE_R_STATUS2 0x00000021 + #define ETH_MAC_KR_AN_MILLISECONDS_COUNTER_ADDR 0x00008000 #define ETH_MAC_AN_LT_MILLISECONDS_COUNTER_ADDR 0x00000020 diff --git a/eth/al_hal_eth_main.c b/eth/al_hal_eth_main.c index b3a5c70b1f0..d7913af2c93 100644 --- a/eth/al_hal_eth_main.c +++ b/eth/al_hal_eth_main.c @@ -43,18 +43,20 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "al_hal_eth.h" -#include -#include -#include +#include "al_hal_udma_iofic.h" +#include "al_hal_udma_config.h" #include "al_hal_eth_ec_regs.h" #include "al_hal_eth_mac_regs.h" -#include +#include "al_hal_unit_adapter_regs.h" #ifdef AL_ETH_EX #include "al_hal_eth_ex_internal.h" #endif /* Number of xfi_txclk cycles that accumulate into 100ns */ -#define ETH_MAC_KR_PCS_CFG_EEE_TIMER_VAL 52 +#define ETH_MAC_KR_10_PCS_CFG_EEE_TIMER_VAL 52 +#define ETH_MAC_KR_25_PCS_CFG_EEE_TIMER_VAL 80 +#define ETH_MAC_XLG_40_PCS_CFG_EEE_TIMER_VAL 63 +#define ETH_MAC_XLG_50_PCS_CFG_EEE_TIMER_VAL 85 #define AL_ETH_TX_PKT_UDMA_FLAGS (AL_ETH_TX_FLAGS_NO_SNOOP | \ AL_ETH_TX_FLAGS_INT) @@ -335,6 +337,8 @@ static const char *al_eth_mac_mode_str(enum al_eth_mac_mode mode) return "40G_LL"; case AL_ETH_MAC_MODE_XLG_LL_50G: return "50G_LL"; + case AL_ETH_MAC_MODE_XLG_LL_25G: + return "25G_LL"; default: return "N/A"; } @@ -572,8 +576,10 @@ int al_eth_adapter_init(struct al_hal_eth_adapter *adapter, struct al_eth_adapte adapter->mac_regs_base = (struct al_eth_mac_regs __iomem*)params->mac_regs_base; adapter->unit_regs = (struct unit_regs __iomem *)params->udma_regs_base; adapter->enable_rx_parser = params->enable_rx_parser; - adapter->ec_ints_base = (void __iomem *)((uint32_t)adapter->ec_regs_base + 0x1c00); - adapter->mac_ints_base = (void __iomem *)((uint32_t)adapter->mac_regs_base + 0x800); + adapter->serdes_lane = params->serdes_lane; + adapter->ec_ints_base = (uint8_t __iomem *)adapter->ec_regs_base + 0x1c00; + adapter->mac_ints_base = (struct interrupt_controller_ctrl __iomem *) + ((uint8_t __iomem *)adapter->mac_regs_base + 0x800); /* initialize Tx udma */ udma_params.udma_regs_base = adapter->unit_regs; @@ -963,7 +969,7 @@ int al_eth_mac_config(struct al_hal_eth_adapter *adapter, enum al_eth_mac_mode m if (adapter->rev_id > AL_ETH_REV_ID_2) { /* configure and enable the ASYNC FIFO between the MACs and the EC */ /* TX min packet size */ - al_reg_write32(&adapter->mac_regs_base->gen_v3.tx_afifo_cfg_1, 0x00000037); + al_reg_write32(&adapter->mac_regs_base->gen_v3.tx_afifo_cfg_1, 0x00000010); /* TX max packet size */ al_reg_write32(&adapter->mac_regs_base->gen_v3.tx_afifo_cfg_2, 0x00002800); /* TX input bus configuration */ @@ -1060,7 +1066,7 @@ int al_eth_mac_config(struct al_hal_eth_adapter *adapter, enum al_eth_mac_mode m if (adapter->rev_id > AL_ETH_REV_ID_2) { /* configure and enable the ASYNC FIFO between the MACs and the EC */ /* TX min packet size */ - al_reg_write32(&adapter->mac_regs_base->gen_v3.tx_afifo_cfg_1, 0x00000037); + al_reg_write32(&adapter->mac_regs_base->gen_v3.tx_afifo_cfg_1, 0x00000010); /* TX max packet size */ al_reg_write32(&adapter->mac_regs_base->gen_v3.tx_afifo_cfg_2, 0x00002800); /* TX input bus configuration */ @@ -1110,7 +1116,7 @@ int al_eth_mac_config(struct al_hal_eth_adapter *adapter, enum al_eth_mac_mode m if (adapter->rev_id > AL_ETH_REV_ID_2) { /* configure and enable the ASYNC FIFO between the MACs and the EC */ /* TX min packet size */ - al_reg_write32(&adapter->mac_regs_base->gen_v3.tx_afifo_cfg_1, 0x00000037); + al_reg_write32(&adapter->mac_regs_base->gen_v3.tx_afifo_cfg_1, 0x00000010); /* TX max packet size */ al_reg_write32(&adapter->mac_regs_base->gen_v3.tx_afifo_cfg_2, 0x00002800); /* TX input bus configuration */ @@ -1162,11 +1168,12 @@ int al_eth_mac_config(struct al_hal_eth_adapter *adapter, enum al_eth_mac_mode m case AL_ETH_MAC_MODE_KR_LL_25G: /* select 25G SERDES lane 0 and lane 1 */ - al_reg_write32(&adapter->mac_regs_base->gen_v3.ext_serdes_ctrl, 0x03821101); + al_reg_write32(&adapter->mac_regs_base->gen_v3.ext_serdes_ctrl, 0x0002110f); + if (adapter->rev_id > AL_ETH_REV_ID_2) { /* configure and enable the ASYNC FIFO between the MACs and the EC */ /* TX min packet size */ - al_reg_write32(&adapter->mac_regs_base->gen_v3.tx_afifo_cfg_1, 0x00000037); + al_reg_write32(&adapter->mac_regs_base->gen_v3.tx_afifo_cfg_1, 0x00000010); /* TX max packet size */ al_reg_write32(&adapter->mac_regs_base->gen_v3.tx_afifo_cfg_2, 0x00002800); /* TX input bus configuration */ @@ -1205,15 +1212,29 @@ int al_eth_mac_config(struct al_hal_eth_adapter *adapter, enum al_eth_mac_mode m /* al_reg_write32(&adapter->mac_regs_base->gen.mac_res_1_out, 0x00000401); */ al_reg_write32(&adapter->mac_regs_base->gen.xgmii_dfifo_64_32, 0x00000401); /* al_reg_write32(&adapter->mac_regs_base->gen.mac_res_1_in, 0x00000401); */ - al_reg_write32_masked(&adapter->mac_regs_base->gen.mux_sel, + + if (adapter->serdes_lane == 0) + al_reg_write32_masked(&adapter->mac_regs_base->gen.mux_sel, ~ETH_MAC_GEN_MUX_SEL_KR_IN_MASK, 0x00073910); - al_reg_write32(&adapter->mac_regs_base->gen.clk_cfg, 0x10003210); + else + al_reg_write32(&adapter->mac_regs_base->gen.mux_sel, 0x00077910); + + if (adapter->serdes_lane == 0) + al_reg_write32(&adapter->mac_regs_base->gen.clk_cfg, 0x10003210); + else + al_reg_write32(&adapter->mac_regs_base->gen.clk_cfg, 0x10000101); + al_reg_write32(&adapter->mac_regs_base->gen.sd_fifo_ctrl, 0x000004f0); al_reg_write32(&adapter->mac_regs_base->gen.sd_fifo_ctrl, 0x00000401); al_reg_write32_masked(&adapter->mac_regs_base->gen.led_cfg, ETH_MAC_GEN_LED_CFG_SEL_MASK, ETH_MAC_GEN_LED_CFG_SEL_DEFAULT_REG); + + if (adapter->serdes_lane == 1) + al_reg_write32(&adapter->mac_regs_base->gen.los_sel, 0x101); + + break; case AL_ETH_MAC_MODE_10G_SGMII: @@ -1250,7 +1271,7 @@ int al_eth_mac_config(struct al_hal_eth_adapter *adapter, enum al_eth_mac_mode m case AL_ETH_MAC_MODE_XLG_LL_40G: /* configure and enable the ASYNC FIFO between the MACs and the EC */ /* TX min packet size */ - al_reg_write32(&adapter->mac_regs_base->gen_v3.tx_afifo_cfg_1, 0x00000037); + al_reg_write32(&adapter->mac_regs_base->gen_v3.tx_afifo_cfg_1, 0x00000010); /* TX max packet size */ al_reg_write32(&adapter->mac_regs_base->gen_v3.tx_afifo_cfg_2, 0x00002800); /* TX input bus configuration */ @@ -1318,11 +1339,102 @@ int al_eth_mac_config(struct al_hal_eth_adapter *adapter, enum al_eth_mac_mode m ETH_MAC_GEN_LED_CFG_SEL_DEFAULT_REG); break; + case AL_ETH_MAC_MODE_XLG_LL_25G: + /* xgmii_mode: 0=xlgmii, 1=xgmii */ + al_reg_write32(&adapter->mac_regs_base->gen_v3.mac_40g_ll_addr, 0x0080); + al_reg_write32(&adapter->mac_regs_base->gen_v3.mac_40g_ll_data, 0x00000001); + + /* configure and enable the ASYNC FIFO between the MACs and the EC */ + /* TX min packet size */ + al_reg_write32(&adapter->mac_regs_base->gen_v3.tx_afifo_cfg_1, 0x00000010); + /* TX max packet size */ + al_reg_write32(&adapter->mac_regs_base->gen_v3.tx_afifo_cfg_2, 0x00002800); + /* TX input bus configuration */ + al_reg_write32(&adapter->mac_regs_base->gen_v3.tx_afifo_cfg_3, 0x00000080); + /* TX output bus configuration */ + al_reg_write32(&adapter->mac_regs_base->gen_v3.tx_afifo_cfg_4, 0x00010040); + /* TX Valid/ready configuration */ + al_reg_write32(&adapter->mac_regs_base->gen_v3.tx_afifo_cfg_5, 0x00000023); + /* RX min packet size */ + /* al_reg_write32(&adapter->mac_regs_base->gen_v3.rx_afifo_cfg_1, 0x00000040); */ + /* RX max packet size */ + /* al_reg_write32(&adapter->mac_regs_base->gen_v3.rx_afifo_cfg_2, 0x00002800); */ + /* RX input bus configuration */ + al_reg_write32(&adapter->mac_regs_base->gen_v3.rx_afifo_cfg_3, 0x00010040); + /* RX output bus configuration */ + al_reg_write32(&adapter->mac_regs_base->gen_v3.rx_afifo_cfg_4, 0x00000080); + /* RX Valid/ready configuration */ + al_reg_write32(&adapter->mac_regs_base->gen_v3.rx_afifo_cfg_5, 0x00000112); + /* V3 additional MAC selection */ + al_reg_write32(&adapter->mac_regs_base->gen_v3.mac_sel, 0x00000010); + al_reg_write32(&adapter->mac_regs_base->gen_v3.mac_10g_ll_cfg, 0x00000000); + al_reg_write32(&adapter->mac_regs_base->gen_v3.mac_10g_ll_ctrl, 0x00000000); + al_reg_write32(&adapter->mac_regs_base->gen_v3.pcs_10g_ll_cfg, 0x00000000); + /* ASYNC FIFO ENABLE */ + al_reg_write32(&adapter->mac_regs_base->gen_v3.afifo_ctrl, 0x00003333); + + /* cmd_cfg */ + al_reg_write32(&adapter->mac_regs_base->gen_v3.mac_40g_ll_addr, 0x00000008); + al_reg_write32(&adapter->mac_regs_base->gen_v3.mac_40g_ll_data, 0x01022810); + /* speed_ability //Read-Only */ + /* al_reg_write32(&adapter->mac_regs_base->gen_v3.pcs_40g_ll_addr, 0x00000008); */ + /* 40G capable */ + /* al_reg_write32(&adapter->mac_regs_base->gen_v3.pcs_40g_ll_data, 0x00000002); */ + + /* select the 25G serdes for lanes 0/1 */ + al_reg_write32(&adapter->mac_regs_base->gen_v3.ext_serdes_ctrl, 0x0002110f); + /* configure the PCS to work with 2 lanes */ + /* configure which two of the 4 PCS Lanes (VL) are combined to one RXLAUI lane */ + /* use VL 0-2 for RXLAUI lane 0, use VL 1-3 for RXLAUI lane 1 */ + al_eth_40g_pcs_reg_write(adapter, 0x00010008, 0x0d80); + /* configure the PCS to work 32 bit interface */ + al_reg_write32(&adapter->mac_regs_base->gen_v3.pcs_40g_ll_cfg, 0x00440000); + + /* disable MLD and move to clause 49 PCS: */ + al_reg_write32(&adapter->mac_regs_base->gen_v3.pcs_40g_ll_addr, 0xE); + al_reg_write32(&adapter->mac_regs_base->gen_v3.pcs_40g_ll_data, 0); + +#ifdef AL_HAL_ETH_FAST_AN + al_eth_40g_pcs_reg_write(adapter, 0x00010004, 1023); + al_eth_40g_pcs_reg_write(adapter, 0x00000000, 0xA04c); + al_eth_40g_pcs_reg_write(adapter, 0x00000000, 0x204c); +#endif + + /* XAUI MAC control register */ + if (adapter->serdes_lane == 0) + al_reg_write32_masked(&adapter->mac_regs_base->gen.mux_sel, + ~ETH_MAC_GEN_MUX_SEL_KR_IN_MASK, 0x06883910); + else + al_reg_write32(&adapter->mac_regs_base->gen.mux_sel, 0x06803950); + + al_reg_write32(&adapter->mac_regs_base->gen.sd_fifo_ctrl, 0x0000040f); + + /* XAUI MAC control register */ + al_reg_write32(&adapter->mac_regs_base->gen.cfg, 0x00000005); + /* RXAUI MAC control register */ + al_reg_write32(&adapter->mac_regs_base->gen.rxaui_cfg, 0x00000007); + al_reg_write32(&adapter->mac_regs_base->gen.sd_cfg, 0x000001F1); + al_reg_write32(&adapter->mac_regs_base->gen.xgmii_dfifo_32_64, 0x00000401); + al_reg_write32(&adapter->mac_regs_base->gen.xgmii_dfifo_64_32, 0x00000401); + if (adapter->serdes_lane == 0) + al_reg_write32(&adapter->mac_regs_base->gen.clk_cfg, 0x10003210); + else + al_reg_write32(&adapter->mac_regs_base->gen.clk_cfg, 0x10000101); + + al_reg_write32_masked(&adapter->mac_regs_base->gen.led_cfg, + ETH_MAC_GEN_LED_CFG_SEL_MASK, + ETH_MAC_GEN_LED_CFG_SEL_DEFAULT_REG); + + if (adapter->serdes_lane == 1) + al_reg_write32(&adapter->mac_regs_base->gen.los_sel, 0x101); + + break; + case AL_ETH_MAC_MODE_XLG_LL_50G: /* configure and enable the ASYNC FIFO between the MACs and the EC */ /* TX min packet size */ - al_reg_write32(&adapter->mac_regs_base->gen_v3.tx_afifo_cfg_1, 0x00000037); + al_reg_write32(&adapter->mac_regs_base->gen_v3.tx_afifo_cfg_1, 0x00000010); /* TX max packet size */ al_reg_write32(&adapter->mac_regs_base->gen_v3.tx_afifo_cfg_2, 0x00002800); /* TX input bus configuration */ @@ -1414,19 +1526,26 @@ int al_eth_mac_start(struct al_hal_eth_adapter *adapter) { if (AL_ETH_IS_1G_MAC(adapter->mac_mode)) { /* 1G MAC control register */ - al_reg_write32_masked(&adapter->mac_regs_base->mac_1g.cmd_cfg, 0x3, 0x3); + al_reg_write32_masked(&adapter->mac_regs_base->mac_1g.cmd_cfg, + ETH_1G_MAC_CMD_CFG_TX_ENA | ETH_1G_MAC_CMD_CFG_RX_ENA, + ETH_1G_MAC_CMD_CFG_TX_ENA | ETH_1G_MAC_CMD_CFG_RX_ENA); } else if (AL_ETH_IS_10G_MAC(adapter->mac_mode) || AL_ETH_IS_25G_MAC(adapter->mac_mode)) { /* 10G MAC control register */ - al_reg_write32_masked(&adapter->mac_regs_base->mac_10g.cmd_cfg, 0x3, 0x3); + al_reg_write32_masked(&adapter->mac_regs_base->mac_10g.cmd_cfg, + ETH_10G_MAC_CMD_CFG_TX_ENA | ETH_10G_MAC_CMD_CFG_RX_ENA, + ETH_10G_MAC_CMD_CFG_TX_ENA | ETH_10G_MAC_CMD_CFG_RX_ENA); } else { uint32_t cmd_cfg; - cmd_cfg = al_eth_40g_mac_reg_read(adapter, ETH_MAC_GEN_V3_MAC_40G_COMMAND_CONFIG_ADDR); + cmd_cfg = al_eth_40g_mac_reg_read(adapter, + ETH_MAC_GEN_V3_MAC_40G_COMMAND_CONFIG_ADDR); cmd_cfg |= (ETH_MAC_GEN_V3_MAC_40G_COMMAND_CONFIG_TX_ENA | ETH_MAC_GEN_V3_MAC_40G_COMMAND_CONFIG_RX_ENA); - al_eth_40g_mac_reg_write(adapter, ETH_MAC_GEN_V3_MAC_40G_COMMAND_CONFIG_ADDR, cmd_cfg); + al_eth_40g_mac_reg_write(adapter, + ETH_MAC_GEN_V3_MAC_40G_COMMAND_CONFIG_ADDR, + cmd_cfg); } return 0; @@ -1437,16 +1556,91 @@ int al_eth_mac_stop(struct al_hal_eth_adapter *adapter) { if (AL_ETH_IS_1G_MAC(adapter->mac_mode)) /* 1G MAC control register */ - al_reg_write32(&adapter->mac_regs_base->mac_1g.cmd_cfg, 0x0); + al_reg_write32_masked(&adapter->mac_regs_base->mac_1g.cmd_cfg, + ETH_1G_MAC_CMD_CFG_TX_ENA | ETH_1G_MAC_CMD_CFG_RX_ENA, + 0); else if (AL_ETH_IS_10G_MAC(adapter->mac_mode) || AL_ETH_IS_25G_MAC(adapter->mac_mode)) /* 10G MAC control register */ - al_reg_write32(&adapter->mac_regs_base->mac_10g.cmd_cfg, 0x0); - else - al_eth_40g_mac_reg_write(adapter, ETH_MAC_GEN_V3_MAC_40G_COMMAND_CONFIG_ADDR, 0); + al_reg_write32_masked(&adapter->mac_regs_base->mac_10g.cmd_cfg, + ETH_10G_MAC_CMD_CFG_TX_ENA | ETH_10G_MAC_CMD_CFG_RX_ENA, + 0); + else { + uint32_t cmd_cfg; + + cmd_cfg = al_eth_40g_mac_reg_read(adapter, + ETH_MAC_GEN_V3_MAC_40G_COMMAND_CONFIG_ADDR); + + cmd_cfg &= ~(ETH_MAC_GEN_V3_MAC_40G_COMMAND_CONFIG_TX_ENA | + ETH_MAC_GEN_V3_MAC_40G_COMMAND_CONFIG_RX_ENA); + + al_eth_40g_mac_reg_write(adapter, + ETH_MAC_GEN_V3_MAC_40G_COMMAND_CONFIG_ADDR, + cmd_cfg); + } return 0; } +void al_eth_gearbox_reset(struct al_hal_eth_adapter *adapter, al_bool tx_reset, al_bool rx_reset) +{ + uint32_t reg, orig_val; + + /* Gearbox is exist only from revision 3 */ + al_assert(adapter->rev_id > AL_ETH_REV_ID_2); + + orig_val = al_reg_read32(&adapter->mac_regs_base->gen_v3.ext_serdes_ctrl); + reg = orig_val; + + if (tx_reset) { + reg |= (ETH_MAC_GEN_V3_EXT_SERDES_CTRL_LANE_0_TX_25_GS_SW_RESET | + ETH_MAC_GEN_V3_EXT_SERDES_CTRL_LANE_1_TX_25_GS_SW_RESET); + } + + if (rx_reset) { + reg |= (ETH_MAC_GEN_V3_EXT_SERDES_CTRL_LANE_0_RX_25_GS_SW_RESET | + ETH_MAC_GEN_V3_EXT_SERDES_CTRL_LANE_1_RX_25_GS_SW_RESET); + } + + al_dbg("%s: perform gearbox reset (Tx %d, Rx %d) \n", __func__, tx_reset, rx_reset); + al_reg_write32(&adapter->mac_regs_base->gen_v3.ext_serdes_ctrl, reg); + + al_udelay(10); + + al_reg_write32(&adapter->mac_regs_base->gen_v3.ext_serdes_ctrl, orig_val); +} + +int al_eth_fec_enable(struct al_hal_eth_adapter *adapter, al_bool enable) +{ + if (adapter->rev_id <= AL_ETH_REV_ID_2) + return -1; + + if (enable) + al_reg_write32_masked(&adapter->mac_regs_base->gen_v3.pcs_10g_ll_cfg, + (ETH_MAC_GEN_V3_PCS_10G_LL_CFG_FEC_EN_RX | + ETH_MAC_GEN_V3_PCS_10G_LL_CFG_FEC_EN_TX), + (ETH_MAC_GEN_V3_PCS_10G_LL_CFG_FEC_EN_RX | + ETH_MAC_GEN_V3_PCS_10G_LL_CFG_FEC_EN_TX)); + else + al_reg_write32_masked(&adapter->mac_regs_base->gen_v3.pcs_10g_ll_cfg, + (ETH_MAC_GEN_V3_PCS_10G_LL_CFG_FEC_EN_RX | + ETH_MAC_GEN_V3_PCS_10G_LL_CFG_FEC_EN_TX), + 0); + return 0; +} + +int al_eth_fec_stats_get(struct al_hal_eth_adapter *adapter, + uint32_t *corrected, uint32_t *uncorrectable) +{ + if (adapter->rev_id <= AL_ETH_REV_ID_2) + return -1; + + *corrected = al_reg_read32(&adapter->mac_regs_base->stat.v3_pcs_10g_ll_cerr); + *uncorrectable = al_reg_read32(&adapter->mac_regs_base->stat.v3_pcs_10g_ll_ncerr); + + return 0; +} + + int al_eth_capabilities_get(struct al_hal_eth_adapter *adapter, struct al_eth_capabilities *caps) { al_assert(caps); @@ -1483,46 +1677,18 @@ int al_eth_capabilities_get(struct al_hal_eth_adapter *adapter, struct al_eth_ca return 0; } -/* update link speed and duplex mode */ -int al_eth_mac_link_config(struct al_hal_eth_adapter *adapter, - al_bool force_1000_base_x, - al_bool an_enable, - uint32_t speed, - al_bool full_duplex) +static void al_eth_mac_link_config_1g_mac( + struct al_hal_eth_adapter *adapter, + al_bool force_1000_base_x, + al_bool an_enable, + uint32_t speed, + al_bool full_duplex) { uint32_t mac_ctrl; uint32_t sgmii_ctrl = 0; uint32_t sgmii_if_mode = 0; uint32_t rgmii_ctrl = 0; - if (!AL_ETH_IS_1G_MAC(adapter->mac_mode)) { - al_err("eth [%s]: this function not supported in this mac mode.\n", - adapter->name); - return -EINVAL; - } - - if ((adapter->mac_mode != AL_ETH_MAC_MODE_RGMII) && (an_enable)) { - /* - * an_enable is not relevant to RGMII mode. - * in AN mode speed and duplex aren't relevant. - */ - al_info("eth [%s]: set auto negotiation to enable\n", adapter->name); - } else { - al_info("eth [%s]: set link speed to %dMbps. %s duplex.\n", adapter->name, - speed, full_duplex == AL_TRUE ? "full" : "half"); - - if ((speed != 10) && (speed != 100) && (speed != 1000)) { - al_err("eth [%s]: bad speed parameter (%d).\n", - adapter->name, speed); - return -EINVAL; - } - if ((speed == 1000) && (full_duplex == AL_FALSE)) { - al_err("eth [%s]: half duplex in 1Gbps is not supported.\n", - adapter->name); - return -EINVAL; - } - } - mac_ctrl = al_reg_read32(&adapter->mac_regs_base->mac_1g.cmd_cfg); if (adapter->mac_mode == AL_ETH_MAC_MODE_SGMII) { @@ -1558,22 +1724,22 @@ int al_eth_mac_link_config(struct al_hal_eth_adapter *adapter, } if (full_duplex == AL_TRUE) { - AL_REG_MASK_CLEAR(mac_ctrl, AL_ETH_1G_MAC_CTRL_HD_EN); + AL_REG_MASK_CLEAR(mac_ctrl, ETH_1G_MAC_CMD_CFG_HD_EN); } else { - AL_REG_MASK_SET(mac_ctrl, AL_ETH_1G_MAC_CTRL_HD_EN); + AL_REG_MASK_SET(mac_ctrl, ETH_1G_MAC_CMD_CFG_HD_EN); sgmii_if_mode |= ETH_MAC_SGMII_REG_DATA_IF_MODE_SGMII_DUPLEX; } if (speed == 1000) { - AL_REG_MASK_SET(mac_ctrl, AL_ETH_1G_MAC_CTRL_1G_SPD); + AL_REG_MASK_SET(mac_ctrl, ETH_1G_MAC_CMD_CFG_1G_SPD); sgmii_if_mode |= ETH_MAC_SGMII_REG_DATA_IF_MODE_SGMII_SPEED_1000; } else { - AL_REG_MASK_CLEAR(mac_ctrl, AL_ETH_1G_MAC_CTRL_1G_SPD); + AL_REG_MASK_CLEAR(mac_ctrl, ETH_1G_MAC_CMD_CFG_1G_SPD); if (speed == 10) { - AL_REG_MASK_SET(mac_ctrl, AL_ETH_1G_MAC_CTRL_10M_SPD); + AL_REG_MASK_SET(mac_ctrl, ETH_1G_MAC_CMD_CFG_10M_SPD); } else { sgmii_if_mode |= ETH_MAC_SGMII_REG_DATA_IF_MODE_SGMII_SPEED_100; - AL_REG_MASK_CLEAR(mac_ctrl, AL_ETH_1G_MAC_CTRL_10M_SPD); + AL_REG_MASK_CLEAR(mac_ctrl, ETH_1G_MAC_CMD_CFG_10M_SPD); } } @@ -1590,6 +1756,113 @@ int al_eth_mac_link_config(struct al_hal_eth_adapter *adapter, } al_reg_write32(&adapter->mac_regs_base->mac_1g.cmd_cfg, mac_ctrl); +} + +static void al_eth_mac_link_config_10g_mac( + struct al_hal_eth_adapter *adapter, + al_bool force_1000_base_x, + al_bool an_enable, + uint32_t speed, + al_bool full_duplex) +{ + uint32_t if_mode; + uint32_t val; + + if_mode = al_reg_read32(&adapter->mac_regs_base->mac_10g.if_mode); + + if (force_1000_base_x) { + uint32_t control; + + AL_REG_MASK_CLEAR(if_mode, ETH_10G_MAC_IF_MODE_SGMII_EN_MASK); + + control = al_reg_read32(&adapter->mac_regs_base->mac_10g.control); + + if (an_enable) + AL_REG_MASK_SET(control, ETH_10G_MAC_CONTROL_AN_EN_MASK); + else + AL_REG_MASK_CLEAR(control, ETH_10G_MAC_CONTROL_AN_EN_MASK); + + al_reg_write32(&adapter->mac_regs_base->mac_10g.control, control); + + } else { + AL_REG_MASK_SET(if_mode, ETH_10G_MAC_IF_MODE_SGMII_EN_MASK); + if (an_enable) { + AL_REG_MASK_SET(if_mode, ETH_10G_MAC_IF_MODE_SGMII_AN_MASK); + } else { + AL_REG_MASK_CLEAR(if_mode, ETH_10G_MAC_IF_MODE_SGMII_AN_MASK); + + if (speed == 1000) + val = ETH_10G_MAC_IF_MODE_SGMII_SPEED_1G; + else if (speed == 100) + val = ETH_10G_MAC_IF_MODE_SGMII_SPEED_100M; + else + val = ETH_10G_MAC_IF_MODE_SGMII_SPEED_10M; + + AL_REG_FIELD_SET(if_mode, + ETH_10G_MAC_IF_MODE_SGMII_SPEED_MASK, + ETH_10G_MAC_IF_MODE_SGMII_SPEED_SHIFT, + val); + + AL_REG_FIELD_SET(if_mode, + ETH_10G_MAC_IF_MODE_SGMII_DUPLEX_MASK, + ETH_10G_MAC_IF_MODE_SGMII_DUPLEX_SHIFT, + ((full_duplex) ? + ETH_10G_MAC_IF_MODE_SGMII_DUPLEX_FULL : + ETH_10G_MAC_IF_MODE_SGMII_DUPLEX_HALF)); + } + } + + al_reg_write32(&adapter->mac_regs_base->mac_10g.if_mode, if_mode); +} + +/* update link speed and duplex mode */ +int al_eth_mac_link_config(struct al_hal_eth_adapter *adapter, + al_bool force_1000_base_x, + al_bool an_enable, + uint32_t speed, + al_bool full_duplex) +{ + if ((!AL_ETH_IS_1G_MAC(adapter->mac_mode)) && + (adapter->mac_mode != AL_ETH_MAC_MODE_SGMII_2_5G)) { + al_err("eth [%s]: this function not supported in this mac mode.\n", + adapter->name); + return -EINVAL; + } + + if ((adapter->mac_mode != AL_ETH_MAC_MODE_RGMII) && (an_enable)) { + /* + * an_enable is not relevant to RGMII mode. + * in AN mode speed and duplex aren't relevant. + */ + al_info("eth [%s]: set auto negotiation to enable\n", adapter->name); + } else { + al_info("eth [%s]: set link speed to %dMbps. %s duplex.\n", adapter->name, + speed, full_duplex == AL_TRUE ? "full" : "half"); + + if ((speed != 10) && (speed != 100) && (speed != 1000)) { + al_err("eth [%s]: bad speed parameter (%d).\n", + adapter->name, speed); + return -EINVAL; + } + if ((speed == 1000) && (full_duplex == AL_FALSE)) { + al_err("eth [%s]: half duplex in 1Gbps is not supported.\n", + adapter->name); + return -EINVAL; + } + } + + if (AL_ETH_IS_1G_MAC(adapter->mac_mode)) + al_eth_mac_link_config_1g_mac(adapter, + force_1000_base_x, + an_enable, + speed, + full_duplex); + else + al_eth_mac_link_config_10g_mac(adapter, + force_1000_base_x, + an_enable, + speed, + full_duplex); return 0; } @@ -2014,12 +2287,12 @@ al_dump_tx_pkt(struct al_udma_q *tx_dma_q, struct al_eth_pkt *pkt) const char *l3_proto_name = "unknown"; const char *l4_proto_name = "unknown"; const char *outer_l3_proto_name = "N/A"; - const char *tunnel_mode = ((pkt->tunnel_mode & AL_ETH_TUNNEL_WITH_UDP) == - AL_ETH_TUNNEL_WITH_UDP) ? - "TUNNEL_WITH_UDP" : - ((pkt->tunnel_mode & AL_ETH_TUNNEL_NO_UDP) == - AL_ETH_TUNNEL_NO_UDP) ? - "TUNNEL_NO_UDP" : ""; + const char *tunnel_mode = (((pkt->tunnel_mode & + AL_ETH_TUNNEL_WITH_UDP) == AL_ETH_TUNNEL_WITH_UDP) ? + "TUNNEL_WITH_UDP" : + (((pkt->tunnel_mode & + AL_ETH_TUNNEL_NO_UDP) == AL_ETH_TUNNEL_NO_UDP) ? + "TUNNEL_NO_UDP" : "")); uint32_t total_len = 0; int i; @@ -2071,26 +2344,19 @@ al_dump_tx_pkt(struct al_udma_q *tx_dma_q, struct al_eth_pkt *pkt) if (pkt->meta) { const char * store = pkt->meta->store ? "Yes" : "No"; + const char *ptp_val = (pkt->flags & AL_ETH_TX_FLAGS_TS) ? "Yes" : "No"; al_dbg("[%s %d]: tx pkt with meta data. words valid %x\n", tx_dma_q->udma->name, tx_dma_q->qid, pkt->meta->words_valid); - if (tx_dma_q->adapter_rev_id == AL_ETH_REV_ID_0) - al_dbg("[%s %d]: meta: store to cache %s. l3 hdr len %d. l3 hdr offset %d. l4 hdr len %d. mss sel %d\n" - , tx_dma_q->udma->name, tx_dma_q->qid, store, - pkt->meta->l3_header_len, pkt->meta->l3_header_offset, - pkt->meta->l4_header_len, - pkt->meta->mss_idx_sel); - else { - const char *ptp_val = (pkt->flags & AL_ETH_TX_FLAGS_TS) ? "Yes" : "No"; - al_dbg("[%s %d]: meta: store to cache %s. l3 hdr len %d. l3 hdr offset %d. l4 hdr len %d. mss val %d ts_index %d ts_val:%s\n" - , tx_dma_q->udma->name, tx_dma_q->qid, store, - pkt->meta->l3_header_len, pkt->meta->l3_header_offset, - pkt->meta->l4_header_len, pkt->meta->mss_val, - pkt->meta->ts_index, ptp_val); - al_dbg("outer_l3_hdr_offset %d. outer_l3_len %d.\n", - pkt->meta->outer_l3_offset, pkt->meta->outer_l3_len); - } + al_dbg("[%s %d]: meta: store to cache %s. l3 hdr len %d. l3 hdr offset %d. " + "l4 hdr len %d. mss val %d ts_index %d ts_val:%s\n" + , tx_dma_q->udma->name, tx_dma_q->qid, store, + pkt->meta->l3_header_len, pkt->meta->l3_header_offset, + pkt->meta->l4_header_len, pkt->meta->mss_val, + pkt->meta->ts_index, ptp_val); + al_dbg("outer_l3_hdr_offset %d. outer_l3_len %d.\n", + pkt->meta->outer_l3_offset, pkt->meta->outer_l3_len); } al_dbg("[%s %d]: num of bufs: %d\n", tx_dma_q->udma->name, tx_dma_q->qid, @@ -2115,7 +2381,7 @@ int al_eth_tx_pkt_prepare(struct al_udma_q *tx_dma_q, struct al_eth_pkt *pkt) uint32_t flags = AL_M2S_DESC_FIRST | AL_M2S_DESC_CONCAT | (pkt->flags & AL_ETH_TX_FLAGS_INT); - uint64_t vmid = ((uint64_t)pkt->vmid) << AL_UDMA_DESC_VMID_SHIFT; + uint64_t tgtid = ((uint64_t)pkt->tgtid) << AL_UDMA_DESC_TGTID_SHIFT; uint32_t meta_ctrl; uint32_t ring_id; int buf_idx; @@ -2190,49 +2456,46 @@ int al_eth_tx_pkt_prepare(struct al_udma_q *tx_dma_q, struct al_eth_pkt *pkt) } if (pkt->meta->words_valid & 4) { + uint32_t l3_offset; + meta_word_2 = pkt->meta->l3_header_len & AL_ETH_TX_META_L3_LEN_MASK; meta_word_2 |= (pkt->meta->l3_header_offset & AL_ETH_TX_META_L3_OFF_MASK) << AL_ETH_TX_META_L3_OFF_SHIFT; meta_word_2 |= (pkt->meta->l4_header_len & 0x3f) << 16; - if (tx_dma_q->adapter_rev_id == AL_ETH_REV_ID_0) { - meta_word_2 |= (pkt->meta->mss_idx_sel & 7) << 24; - } else { - uint32_t l3_offset; + if (unlikely(pkt->flags & AL_ETH_TX_FLAGS_TS)) + meta_word_0 |= pkt->meta->ts_index << + AL_ETH_TX_META_MSS_MSB_TS_VAL_SHIFT; + else + meta_word_0 |= (((pkt->meta->mss_val & 0x3c00) >> 10) + << AL_ETH_TX_META_MSS_MSB_TS_VAL_SHIFT); + meta_word_2 |= ((pkt->meta->mss_val & 0x03ff) + << AL_ETH_TX_META_MSS_LSB_VAL_SHIFT); - if (unlikely(pkt->flags & AL_ETH_TX_FLAGS_TS)) - meta_word_0 |= pkt->meta->ts_index << AL_ETH_TX_META_MSS_MSB_TS_VAL_SHIFT; - else - meta_word_0 |= (((pkt->meta->mss_val & 0x3c00) >> 10) - << AL_ETH_TX_META_MSS_MSB_TS_VAL_SHIFT); - meta_word_2 |= ((pkt->meta->mss_val & 0x03ff) - << AL_ETH_TX_META_MSS_LSB_VAL_SHIFT); + /* + * move from bytes to multiplication of 2 as the HW + * expect to get it + */ + l3_offset = (pkt->meta->outer_l3_offset >> 1); - /* - * move from bytes to multiplication of 2 as the HW - * expect to get it - */ - l3_offset = (pkt->meta->outer_l3_offset >> 1); + meta_word_0 |= + (((l3_offset & + AL_ETH_TX_META_OUTER_L3_OFF_HIGH_MASK) >> 3) + << AL_ETH_TX_META_OUTER_L3_OFF_HIGH_SHIFT); - meta_word_0 |= - (((l3_offset & - AL_ETH_TX_META_OUTER_L3_OFF_HIGH_MASK) >> 3) - << AL_ETH_TX_META_OUTER_L3_OFF_HIGH_SHIFT); + meta_word_3 |= + ((l3_offset & + AL_ETH_TX_META_OUTER_L3_OFF_LOW_MASK) + << AL_ETH_TX_META_OUTER_L3_OFF_LOW_SHIFT); - meta_word_3 |= - ((l3_offset & - AL_ETH_TX_META_OUTER_L3_OFF_LOW_MASK) - << AL_ETH_TX_META_OUTER_L3_OFF_LOW_SHIFT); - - /* - * shift right 2 bits to work in multiplication of 4 - * as the HW expect to get it - */ - meta_word_3 |= - (((pkt->meta->outer_l3_len >> 2) & - AL_ETH_TX_META_OUTER_L3_LEN_MASK) - << AL_ETH_TX_META_OUTER_L3_LEN_SHIFT); - } + /* + * shift right 2 bits to work in multiplication of 4 + * as the HW expect to get it + */ + meta_word_3 |= + (((pkt->meta->outer_l3_len >> 2) & + AL_ETH_TX_META_OUTER_L3_LEN_MASK) + << AL_ETH_TX_META_OUTER_L3_LEN_SHIFT); } tx_desc->tx_meta.len_ctrl = swap32_to_le(meta_word_0); @@ -2266,11 +2529,9 @@ int al_eth_tx_pkt_prepare(struct al_udma_q *tx_dma_q, struct al_eth_pkt *pkt) meta_ctrl |= AL_ETH_TX_FLAGS_ENCRYPT; #endif - if (tx_dma_q->adapter_rev_id > AL_ETH_REV_ID_0) { - meta_ctrl |= pkt->tunnel_mode << AL_ETH_TX_TUNNEL_MODE_SHIFT; - if (pkt->outer_l3_proto_idx == AL_ETH_PROTO_ID_IPv4) - meta_ctrl |= 1 << AL_ETH_TX_OUTER_L3_PROTO_SHIFT; - } + meta_ctrl |= pkt->tunnel_mode << AL_ETH_TX_TUNNEL_MODE_SHIFT; + if (pkt->outer_l3_proto_idx == AL_ETH_PROTO_ID_IPv4) + meta_ctrl |= 1 << AL_ETH_TX_OUTER_L3_PROTO_SHIFT; flags |= pkt->flags & AL_ETH_TX_PKT_UDMA_FLAGS; for(buf_idx = 0; buf_idx < pkt->num_of_bufs; buf_idx++ ) { @@ -2295,7 +2556,7 @@ int al_eth_tx_pkt_prepare(struct al_udma_q *tx_dma_q, struct al_eth_pkt *pkt) if (buf_idx == 0) tx_desc->tx.meta_ctrl = swap32_to_le(meta_ctrl); tx_desc->tx.buf_ptr = swap64_to_le( - pkt->bufs[buf_idx].addr | vmid); + pkt->bufs[buf_idx].addr | tgtid); al_dump_tx_desc(tx_desc); } @@ -2408,10 +2669,6 @@ int al_eth_rx_header_split_config(struct al_hal_eth_adapter *adapter, al_bool en { uint32_t reg; - if (adapter->rev_id < AL_ETH_REV_ID_1) { - al_err("[%s]: header split feature not supported by this revision\n", adapter->name); - return -EINVAL; - } reg = al_reg_read32(&adapter->ec_regs_base->rfw.hdr_split); if (enable == AL_TRUE) reg |= EC_RFW_HDR_SPLIT_EN; @@ -2447,9 +2704,9 @@ int al_eth_rx_buffer_add(struct al_udma_q *rx_dma_q, struct al_buf *buf, uint32_t flags, struct al_buf *header_buf) { - uint64_t vmid = ((uint64_t)flags & AL_ETH_RX_FLAGS_VMID_MASK) << - AL_UDMA_DESC_VMID_SHIFT; - uint32_t flags_len = flags & ~AL_ETH_RX_FLAGS_VMID_MASK; + uint64_t tgtid = ((uint64_t)flags & AL_ETH_RX_FLAGS_TGTID_MASK) << + AL_UDMA_DESC_TGTID_SHIFT; + uint32_t flags_len = flags & ~AL_ETH_RX_FLAGS_TGTID_MASK; union al_udma_desc *rx_desc; al_dbg("[%s %d]: add rx buffer.\n", rx_dma_q->udma->name, rx_dma_q->qid); @@ -2476,7 +2733,7 @@ int al_eth_rx_buffer_add(struct al_udma_q *rx_dma_q, rx_desc->rx.buf2_ptr_lo = swap32_to_le(AL_ADDR_LOW(header_buf->addr)); } rx_desc->rx.len_ctrl = swap32_to_le(flags_len); - rx_desc->rx.buf1_ptr = swap64_to_le(buf->addr | vmid); + rx_desc->rx.buf1_ptr = swap64_to_le(buf->addr | tgtid); return 0; } @@ -2943,7 +3200,8 @@ int al_eth_switching_config_set(struct al_hal_eth_adapter *adapter, uint8_t udma AL_ETH_RFW_FILTER_VLAN_VID | \ AL_ETH_RFW_FILTER_CTRL_TABLE | \ AL_ETH_RFW_FILTER_PROT_INDEX | \ - ((rev_id > AL_ETH_REV_ID_0) ? ((AL_ETH_RFW_FILTER_WOL) | (AL_ETH_RFW_FILTER_PARSE)) : 0)) + AL_ETH_RFW_FILTER_WOL | \ + AL_ETH_RFW_FILTER_PARSE) /* Configure the receive filters */ int al_eth_filter_config(struct al_hal_eth_adapter *adapter, struct al_eth_filter_params *params) @@ -3236,11 +3494,27 @@ int al_eth_eee_config(struct al_hal_eth_adapter *adapter, struct al_eth_eee_para al_reg_write32(&adapter->ec_regs_base->eee.cfg_e, 0); return 0; } - if (AL_ETH_IS_10G_MAC(adapter->mac_mode)) { - reg = ETH_MAC_KR_PCS_CFG_EEE_TIMER_VAL << ETH_MAC_KR_PCS_CFG_EEE_TIMER_VAL_SHIFT; + if (AL_ETH_IS_10G_MAC(adapter->mac_mode) || AL_ETH_IS_25G_MAC(adapter->mac_mode)) { al_reg_write32_masked( &adapter->mac_regs_base->kr.pcs_cfg, - ETH_MAC_KR_PCS_CFG_EEE_TIMER_VAL_MASK, reg); + ETH_MAC_KR_PCS_CFG_EEE_TIMER_VAL_MASK, + ((AL_ETH_IS_10G_MAC(adapter->mac_mode)) ? + ETH_MAC_KR_10_PCS_CFG_EEE_TIMER_VAL : + ETH_MAC_KR_25_PCS_CFG_EEE_TIMER_VAL) << + ETH_MAC_KR_PCS_CFG_EEE_TIMER_VAL_SHIFT); + } + if ((adapter->mac_mode == AL_ETH_MAC_MODE_XLG_LL_40G) || + (adapter->mac_mode == AL_ETH_MAC_MODE_XLG_LL_50G)) { + al_reg_write32_masked( + &adapter->mac_regs_base->gen_v3.pcs_40g_ll_eee_cfg, + ETH_MAC_GEN_V3_PCS_40G_LL_EEE_CFG_TIMER_VAL_MASK, + ((adapter->mac_mode == AL_ETH_MAC_MODE_XLG_LL_40G) ? + ETH_MAC_XLG_40_PCS_CFG_EEE_TIMER_VAL : + ETH_MAC_XLG_50_PCS_CFG_EEE_TIMER_VAL) << + ETH_MAC_GEN_V3_PCS_40G_LL_EEE_CFG_TIMER_VAL_SHIFT); + /* set Deep sleep mode as the LPI function (instead of Fast wake mode) */ + al_eth_40g_pcs_reg_write(adapter, ETH_MAC_GEN_V3_PCS_40G_EEE_CONTROL_ADDR, + params->fast_wake ? 1 : 0); } al_reg_write32(&adapter->ec_regs_base->eee.pre_cnt, params->tx_eee_timer); @@ -3551,13 +3825,24 @@ int al_eth_link_status_get(struct al_hal_eth_adapter *adapter, uint32_t reg; if (AL_ETH_IS_10G_MAC(adapter->mac_mode) || AL_ETH_IS_25G_MAC(adapter->mac_mode)) { - reg = al_reg_read32(&adapter->mac_regs_base->gen.mac_10g_stat); + status->link_up = AL_FALSE; + status->local_fault = AL_TRUE; + status->remote_fault = AL_TRUE; - status->link_up = AL_TRUE; + al_reg_write32(&adapter->mac_regs_base->kr.pcs_addr, ETH_MAC_KR_PCS_BASE_R_STATUS2); + reg = al_reg_read32(&adapter->mac_regs_base->kr.pcs_data); - if (reg & (ETH_MAC_GEN_MAC_10G_STAT_LOC_FAULT | - ETH_MAC_GEN_MAC_10G_STAT_REM_FAULT)) - status->link_up = AL_FALSE; + if (reg & AL_BIT(15)) { + reg = al_reg_read32(&adapter->mac_regs_base->mac_10g.status); + + status->remote_fault = ((reg & ETH_MAC_GEN_MAC_10G_STAT_REM_FAULT) ? + AL_TRUE : AL_FALSE); + status->local_fault = ((reg & ETH_MAC_GEN_MAC_10G_STAT_LOC_FAULT) ? + AL_TRUE : AL_FALSE); + + status->link_up = ((status->remote_fault == AL_FALSE) && + (status->local_fault == AL_FALSE)); + } } else if (adapter->mac_mode == AL_ETH_MAC_MODE_SGMII) { al_reg_write32(&adapter->mac_regs_base->sgmii.reg_addr, 1); @@ -3586,6 +3871,27 @@ int al_eth_link_status_get(struct al_hal_eth_adapter *adapter, if (reg & AL_BIT(4)) status->link_up = AL_TRUE; + } else if (adapter->mac_mode == AL_ETH_MAC_MODE_XLG_LL_25G) { + status->link_up = AL_FALSE; + status->local_fault = AL_TRUE; + status->remote_fault = AL_TRUE; + + reg = al_reg_read32(&adapter->mac_regs_base->gen_v3.pcs_40g_ll_status); + + status->link_up = AL_FALSE; + + if ((reg & 0xF) == 0xF) { + reg = al_reg_read32(&adapter->mac_regs_base->gen_v3.mac_40g_ll_status); + + status->remote_fault = ((reg & ETH_MAC_GEN_V3_MAC_40G_LL_STATUS_REM_FAULT) ? + AL_TRUE : AL_FALSE); + status->local_fault = ((reg & ETH_MAC_GEN_V3_MAC_40G_LL_STATUS_LOC_FAULT) ? + AL_TRUE : AL_FALSE); + + status->link_up = ((status->remote_fault == AL_FALSE) && + (status->local_fault == AL_FALSE)); + } + } else if ((adapter->mac_mode == AL_ETH_MAC_MODE_XLG_LL_40G) || (adapter->mac_mode == AL_ETH_MAC_MODE_XLG_LL_50G)) { reg = al_reg_read32(&adapter->mac_regs_base->gen_v3.pcs_40g_ll_status); @@ -3595,7 +3901,7 @@ int al_eth_link_status_get(struct al_hal_eth_adapter *adapter, if ((reg & 0x1F) == 0x1F) { reg = al_reg_read32(&adapter->mac_regs_base->gen_v3.mac_40g_ll_status); if ((reg & (ETH_MAC_GEN_V3_MAC_40G_LL_STATUS_REM_FAULT | -ETH_MAC_GEN_V3_MAC_40G_LL_STATUS_LOC_FAULT)) == 0) + ETH_MAC_GEN_V3_MAC_40G_LL_STATUS_LOC_FAULT)) == 0) status->link_up = AL_TRUE; } @@ -3611,6 +3917,22 @@ ETH_MAC_GEN_V3_MAC_40G_LL_STATUS_LOC_FAULT)) == 0) return 0; } +int al_eth_link_status_clear(struct al_hal_eth_adapter *adapter) +{ + int status = 0; + + if (AL_ETH_IS_10G_MAC(adapter->mac_mode) || AL_ETH_IS_25G_MAC(adapter->mac_mode)) { + al_reg_write32(&adapter->mac_regs_base->kr.pcs_addr, ETH_MAC_KR_PCS_BASE_R_STATUS2); + al_reg_read32(&adapter->mac_regs_base->kr.pcs_data); + + al_reg_read32(&adapter->mac_regs_base->mac_10g.status); + } else { + status = -1; + } + + return status; +} + /** set LED mode and value */ int al_eth_led_set(struct al_hal_eth_adapter *adapter, al_bool link_is_up) { @@ -3641,179 +3963,220 @@ int al_eth_mac_stats_get(struct al_hal_eth_adapter *adapter, struct al_eth_mac_s { al_assert(stats); + al_memset(stats, 0, sizeof(struct al_eth_mac_stats)); + if (AL_ETH_IS_1G_MAC(adapter->mac_mode)) { - void __iomem *mac_1g_regs_base = &adapter->mac_regs_base->mac_1g; + struct al_eth_mac_1g_stats __iomem *reg_stats = + &adapter->mac_regs_base->mac_1g.stats; - stats->ifInUcastPkts = al_reg_read32((void *)((uint32_t)mac_1g_regs_base + 0x90)); - stats->ifInMulticastPkts = al_reg_read32((void *)((uint32_t)mac_1g_regs_base + 0x94)); - stats->ifInBroadcastPkts = al_reg_read32((void *)((uint32_t)mac_1g_regs_base + 0x98)); - stats->etherStatsPkts = al_reg_read32((void *)((uint32_t)mac_1g_regs_base + 0xb4)); - stats->ifOutUcastPkts = al_reg_read32((void *)((uint32_t)mac_1g_regs_base + 0xa0)); - stats->ifOutMulticastPkts = al_reg_read32((void *)((uint32_t)mac_1g_regs_base + 0xa4)); - stats->ifOutBroadcastPkts = al_reg_read32((void *)((uint32_t)mac_1g_regs_base + 0xa8)); - stats->ifInErrors = al_reg_read32((void *)((uint32_t)mac_1g_regs_base + 0x88)); - stats->ifOutErrors = al_reg_read32((void *)((uint32_t)mac_1g_regs_base + 0x8c)); - - stats->aFramesReceivedOK = al_reg_read32((void *)((uint32_t)mac_1g_regs_base + 0x6c)); - stats->aFramesTransmittedOK = al_reg_read32((void *)((uint32_t)mac_1g_regs_base + 0x68)); - - stats->aOctetsReceivedOK = al_reg_read32((void *)((uint32_t)mac_1g_regs_base + 0x7c)); - stats->aOctetsTransmittedOK = al_reg_read32((void *)((uint32_t)mac_1g_regs_base + 0x78)); - - stats->etherStatsUndersizePkts = al_reg_read32((void *)((uint32_t)mac_1g_regs_base + 0xB8)); - stats->etherStatsFragments = al_reg_read32((void *)((uint32_t)mac_1g_regs_base + 0xE0)); - stats->etherStatsJabbers = al_reg_read32((void *)((uint32_t)mac_1g_regs_base + 0xDC)); - stats->etherStatsOversizePkts = al_reg_read32((void *)((uint32_t)mac_1g_regs_base + 0xBC)); - - stats->aFrameCheckSequenceErrors = al_reg_read32((void *)((uint32_t)mac_1g_regs_base + 0x70)); - stats->aAlignmentErrors = al_reg_read32((void *)((uint32_t)mac_1g_regs_base + 0x74)); - stats->etherStatsDropEvents = al_reg_read32((void *)((uint32_t)mac_1g_regs_base + 0xAC)); - - stats->aPAUSEMACCtrlFramesTransmitted = al_reg_read32((void *)((uint32_t)mac_1g_regs_base + 0x80)); - stats->aPAUSEMACCtrlFramesReceived = al_reg_read32((void *)((uint32_t)mac_1g_regs_base + 0x84)); + stats->ifInUcastPkts = al_reg_read32(®_stats->ifInUcastPkts); + stats->ifInMulticastPkts = al_reg_read32(®_stats->ifInMulticastPkts); + stats->ifInBroadcastPkts = al_reg_read32(®_stats->ifInBroadcastPkts); + stats->etherStatsPkts = al_reg_read32(®_stats->etherStatsPkts); + stats->ifOutUcastPkts = al_reg_read32(®_stats->ifOutUcastPkts); + stats->ifOutMulticastPkts = al_reg_read32(®_stats->ifOutMulticastPkts); + stats->ifOutBroadcastPkts = al_reg_read32(®_stats->ifOutBroadcastPkts); + stats->ifInErrors = al_reg_read32(®_stats->ifInErrors); + stats->ifOutErrors = al_reg_read32(®_stats->ifOutErrors); + stats->aFramesReceivedOK = al_reg_read32(®_stats->aFramesReceivedOK); + stats->aFramesTransmittedOK = al_reg_read32(®_stats->aFramesTransmittedOK); + stats->aOctetsReceivedOK = al_reg_read32(®_stats->aOctetsReceivedOK); + stats->aOctetsTransmittedOK = al_reg_read32(®_stats->aOctetsTransmittedOK); + stats->etherStatsUndersizePkts = al_reg_read32(®_stats->etherStatsUndersizePkts); + stats->etherStatsFragments = al_reg_read32(®_stats->etherStatsFragments); + stats->etherStatsJabbers = al_reg_read32(®_stats->etherStatsJabbers); + stats->etherStatsOversizePkts = al_reg_read32(®_stats->etherStatsOversizePkts); + stats->aFrameCheckSequenceErrors = + al_reg_read32(®_stats->aFrameCheckSequenceErrors); + stats->aAlignmentErrors = al_reg_read32(®_stats->aAlignmentErrors); + stats->etherStatsDropEvents = al_reg_read32(®_stats->etherStatsDropEvents); + stats->aPAUSEMACCtrlFramesTransmitted = + al_reg_read32(®_stats->aPAUSEMACCtrlFramesTransmitted); + stats->aPAUSEMACCtrlFramesReceived = + al_reg_read32(®_stats->aPAUSEMACCtrlFramesReceived); stats->aFrameTooLongErrors = 0; /* N/A */ stats->aInRangeLengthErrors = 0; /* N/A */ stats->VLANTransmittedOK = 0; /* N/A */ stats->VLANReceivedOK = 0; /* N/A */ - stats->etherStatsOctets = al_reg_read32((void *)((uint32_t)mac_1g_regs_base + 0xB0)); - - stats->etherStatsPkts64Octets = al_reg_read32((void *)((uint32_t)mac_1g_regs_base + 0xC0)); - stats->etherStatsPkts65to127Octets = al_reg_read32((void *)((uint32_t)mac_1g_regs_base + 0xC4)); - stats->etherStatsPkts128to255Octets = al_reg_read32((void *)((uint32_t)mac_1g_regs_base + 0xC8)); - stats->etherStatsPkts256to511Octets = al_reg_read32((void *)((uint32_t)mac_1g_regs_base + 0xCC)); - stats->etherStatsPkts512to1023Octets = al_reg_read32((void *)((uint32_t)mac_1g_regs_base + 0xD0)); - stats->etherStatsPkts1024to1518Octets = al_reg_read32((void *)((uint32_t)mac_1g_regs_base + 0xD4)); - stats->etherStatsPkts1519toX = al_reg_read32((void *)((uint32_t)mac_1g_regs_base + 0xD8)); + stats->etherStatsOctets = al_reg_read32(®_stats->etherStatsOctets); + stats->etherStatsPkts64Octets = al_reg_read32(®_stats->etherStatsPkts64Octets); + stats->etherStatsPkts65to127Octets = + al_reg_read32(®_stats->etherStatsPkts65to127Octets); + stats->etherStatsPkts128to255Octets = + al_reg_read32(®_stats->etherStatsPkts128to255Octets); + stats->etherStatsPkts256to511Octets = + al_reg_read32(®_stats->etherStatsPkts256to511Octets); + stats->etherStatsPkts512to1023Octets = + al_reg_read32(®_stats->etherStatsPkts512to1023Octets); + stats->etherStatsPkts1024to1518Octets = + al_reg_read32(®_stats->etherStatsPkts1024to1518Octets); + stats->etherStatsPkts1519toX = al_reg_read32(®_stats->etherStatsPkts1519toX); } else if (AL_ETH_IS_10G_MAC(adapter->mac_mode) || AL_ETH_IS_25G_MAC(adapter->mac_mode)) { if (adapter->rev_id < AL_ETH_REV_ID_3) { - void __iomem *mac_10g_regs_base = &adapter->mac_regs_base->mac_10g; + struct al_eth_mac_10g_stats_v2 __iomem *reg_stats = + &adapter->mac_regs_base->mac_10g.stats.v2; uint64_t octets; - stats->ifInUcastPkts = al_reg_read32((void *)((uint32_t)mac_10g_regs_base + 0xE0)); - stats->ifInMulticastPkts = al_reg_read32((void *)((uint32_t)mac_10g_regs_base + 0xE8)); - stats->ifInBroadcastPkts = al_reg_read32((void *)((uint32_t)mac_10g_regs_base + 0xF0)); - stats->etherStatsPkts = al_reg_read32((void *)((uint32_t)mac_10g_regs_base + 0x130)); - stats->ifOutUcastPkts = al_reg_read32((void *)((uint32_t)mac_10g_regs_base + 0x108)); - stats->ifOutMulticastPkts = al_reg_read32((void *)((uint32_t)mac_10g_regs_base + 0x110)); - stats->ifOutBroadcastPkts = al_reg_read32((void *)((uint32_t)mac_10g_regs_base + 0x118)); - stats->ifInErrors = al_reg_read32((void *)((uint32_t)mac_10g_regs_base + 0x190)); - stats->ifOutErrors = al_reg_read32((void *)((uint32_t)mac_10g_regs_base + 0xf8)); + stats->ifInUcastPkts = al_reg_read32(®_stats->ifInUcastPkts); + stats->ifInMulticastPkts = al_reg_read32(®_stats->ifInMulticastPkts); + stats->ifInBroadcastPkts = al_reg_read32(®_stats->ifInBroadcastPkts); + stats->etherStatsPkts = al_reg_read32(®_stats->etherStatsPkts); + stats->ifOutUcastPkts = al_reg_read32(®_stats->ifOutUcastPkts); + stats->ifOutMulticastPkts = al_reg_read32(®_stats->ifOutMulticastPkts); + stats->ifOutBroadcastPkts = al_reg_read32(®_stats->ifOutBroadcastPkts); + stats->ifInErrors = al_reg_read32(®_stats->ifInErrors); + stats->ifOutErrors = al_reg_read32(®_stats->ifOutErrors); + stats->aFramesReceivedOK = al_reg_read32(®_stats->aFramesReceivedOK); + stats->aFramesTransmittedOK = al_reg_read32(®_stats->aFramesTransmittedOK); - stats->aFramesReceivedOK = al_reg_read32((void *)((uint32_t)mac_10g_regs_base + 0x88)); - stats->aFramesTransmittedOK = al_reg_read32((void *)((uint32_t)mac_10g_regs_base + 0x80)); /* aOctetsReceivedOK = ifInOctets - 18 * aFramesReceivedOK - 4 * VLANReceivedOK */ - octets = al_reg_read32((void *)((uint32_t)mac_10g_regs_base + 0xD8)); - octets |= (uint64_t)(al_reg_read32((void *)((uint32_t)mac_10g_regs_base + 0xDC))) << 32; + octets = al_reg_read32(®_stats->ifInOctetsL); + octets |= (uint64_t)(al_reg_read32(®_stats->ifInOctetsH)) << 32; octets -= 18 * stats->aFramesReceivedOK; - octets -= 4 * al_reg_read32((void *)((uint32_t)mac_10g_regs_base + 0xC8)); + octets -= 4 * al_reg_read32(®_stats->VLANReceivedOK); stats->aOctetsReceivedOK = octets; /* aOctetsTransmittedOK = ifOutOctets - 18 * aFramesTransmittedOK - 4 * VLANTransmittedOK */ - octets = al_reg_read32((void *)((uint32_t)mac_10g_regs_base + 0xD0)); - octets |= (uint64_t)(al_reg_read32((void *)((uint32_t)mac_10g_regs_base + 0xD4))) << 32; + octets = al_reg_read32(®_stats->ifOutOctetsL); + octets |= (uint64_t)(al_reg_read32(®_stats->ifOutOctetsH)) << 32; octets -= 18 * stats->aFramesTransmittedOK; - octets -= 4 * al_reg_read32((void *)((uint32_t)mac_10g_regs_base + 0xC0)); + octets -= 4 * al_reg_read32(®_stats->VLANTransmittedOK); stats->aOctetsTransmittedOK = octets; - stats->etherStatsUndersizePkts = al_reg_read32((void *)((uint32_t)mac_10g_regs_base + 0x138)); - stats->etherStatsFragments = al_reg_read32((void *)((uint32_t)mac_10g_regs_base + 0x188)); - stats->etherStatsJabbers = al_reg_read32((void *)((uint32_t)mac_10g_regs_base + 0x180)); - stats->etherStatsOversizePkts = al_reg_read32((void *)((uint32_t)mac_10g_regs_base + 0x178)); - - stats->aFrameCheckSequenceErrors = al_reg_read32((void *)((uint32_t)mac_10g_regs_base + 0x90)); - stats->aAlignmentErrors = al_reg_read32((void *)((uint32_t)mac_10g_regs_base + 0x98)); - stats->etherStatsDropEvents = al_reg_read32((void *)((uint32_t)mac_10g_regs_base + 0x120)); - - stats->aPAUSEMACCtrlFramesTransmitted = al_reg_read32((void *)((uint32_t)mac_10g_regs_base + 0xA0)); - stats->aPAUSEMACCtrlFramesReceived = al_reg_read32((void *)((uint32_t)mac_10g_regs_base + 0xA8)); - stats->aFrameTooLongErrors = al_reg_read32((void *)((uint32_t)mac_10g_regs_base + 0xB0)); - stats->aInRangeLengthErrors = al_reg_read32((void *)((uint32_t)mac_10g_regs_base + 0xB8)); - stats->VLANTransmittedOK = al_reg_read32((void *)((uint32_t)mac_10g_regs_base + 0xC0)); - stats->VLANReceivedOK = al_reg_read32((void *)((uint32_t)mac_10g_regs_base + 0xC8)); - stats->etherStatsOctets = al_reg_read32((void *)((uint32_t)mac_10g_regs_base + 0x128)); - - stats->etherStatsPkts64Octets = al_reg_read32((void *)((uint32_t)mac_10g_regs_base + 0x140)); - stats->etherStatsPkts65to127Octets = al_reg_read32((void *)((uint32_t)mac_10g_regs_base + 0x148)); - stats->etherStatsPkts128to255Octets = al_reg_read32((void *)((uint32_t)mac_10g_regs_base + 0x150)); - stats->etherStatsPkts256to511Octets = al_reg_read32((void *)((uint32_t)mac_10g_regs_base + 0x158)); - stats->etherStatsPkts512to1023Octets = al_reg_read32((void *)((uint32_t)mac_10g_regs_base + 0x160)); - stats->etherStatsPkts1024to1518Octets = al_reg_read32((void *)((uint32_t)mac_10g_regs_base + 0x168)); - stats->etherStatsPkts1519toX = al_reg_read32((void *)((uint32_t)mac_10g_regs_base + 0x170)); + stats->etherStatsUndersizePkts = al_reg_read32(®_stats->etherStatsUndersizePkts); + stats->etherStatsFragments = al_reg_read32(®_stats->etherStatsFragments); + stats->etherStatsJabbers = al_reg_read32(®_stats->etherStatsJabbers); + stats->etherStatsOversizePkts = al_reg_read32(®_stats->etherStatsOversizePkts); + stats->aFrameCheckSequenceErrors = al_reg_read32(®_stats->aFrameCheckSequenceErrors); + stats->aAlignmentErrors = al_reg_read32(®_stats->aAlignmentErrors); + stats->etherStatsDropEvents = al_reg_read32(®_stats->etherStatsDropEvents); + stats->aPAUSEMACCtrlFramesTransmitted = al_reg_read32(®_stats->aPAUSEMACCtrlFramesTransmitted); + stats->aPAUSEMACCtrlFramesReceived = al_reg_read32(®_stats->aPAUSEMACCtrlFramesReceived); + stats->aFrameTooLongErrors = al_reg_read32(®_stats->aFrameTooLongErrors); + stats->aInRangeLengthErrors = al_reg_read32(®_stats->aInRangeLengthErrors); + stats->VLANTransmittedOK = al_reg_read32(®_stats->VLANTransmittedOK); + stats->VLANReceivedOK = al_reg_read32(®_stats->VLANReceivedOK); + stats->etherStatsOctets = al_reg_read32(®_stats->etherStatsOctets); + stats->etherStatsPkts64Octets = al_reg_read32(®_stats->etherStatsPkts64Octets); + stats->etherStatsPkts65to127Octets = al_reg_read32(®_stats->etherStatsPkts65to127Octets); + stats->etherStatsPkts128to255Octets = al_reg_read32(®_stats->etherStatsPkts128to255Octets); + stats->etherStatsPkts256to511Octets = al_reg_read32(®_stats->etherStatsPkts256to511Octets); + stats->etherStatsPkts512to1023Octets = al_reg_read32(®_stats->etherStatsPkts512to1023Octets); + stats->etherStatsPkts1024to1518Octets = al_reg_read32(®_stats->etherStatsPkts1024to1518Octets); + stats->etherStatsPkts1519toX = al_reg_read32(®_stats->etherStatsPkts1519toX); } else { - void __iomem *mac_10g_regs_base = &adapter->mac_regs_base->mac_10g; + struct al_eth_mac_10g_stats_v3_rx __iomem *reg_rx_stats = + &adapter->mac_regs_base->mac_10g.stats.v3.rx; + struct al_eth_mac_10g_stats_v3_tx __iomem *reg_tx_stats = + &adapter->mac_regs_base->mac_10g.stats.v3.tx; uint64_t octets; - /* TODO - change to 64 bit */ - stats->ifInUcastPkts = al_reg_read32((void *)((uint32_t)mac_10g_regs_base + 0x140)); - stats->ifInMulticastPkts = al_reg_read32((void *)((uint32_t)mac_10g_regs_base + 0x148)); - stats->ifInBroadcastPkts = al_reg_read32((void *)((uint32_t)mac_10g_regs_base + 0x150)); - stats->etherStatsPkts = al_reg_read32((void *)((uint32_t)mac_10g_regs_base + 0x160)); - stats->ifOutUcastPkts = al_reg_read32((void *)((uint32_t)mac_10g_regs_base + 0x240)); - stats->ifOutMulticastPkts = al_reg_read32((void *)((uint32_t)mac_10g_regs_base + 0x248)); - stats->ifOutBroadcastPkts = al_reg_read32((void *)((uint32_t)mac_10g_regs_base + 0x250)); - stats->ifInErrors = al_reg_read32((void *)((uint32_t)mac_10g_regs_base + 0x138)); - stats->ifOutErrors = al_reg_read32((void *)((uint32_t)mac_10g_regs_base + 0x238)); - stats->aFramesReceivedOK = al_reg_read32((void *)((uint32_t)mac_10g_regs_base + 0x120)); /*frames_ok*/ - stats->aFramesTransmittedOK = al_reg_read32((void *)((uint32_t)mac_10g_regs_base + 0x220)); /*frames_ok*/ + stats->ifInUcastPkts = al_reg_read32(®_rx_stats->ifInUcastPkts); + stats->ifInMulticastPkts = al_reg_read32(®_rx_stats->ifInMulticastPkts); + stats->ifInBroadcastPkts = al_reg_read32(®_rx_stats->ifInBroadcastPkts); + stats->etherStatsPkts = al_reg_read32(®_rx_stats->etherStatsPkts); + stats->ifOutUcastPkts = al_reg_read32(®_tx_stats->ifUcastPkts); + stats->ifOutMulticastPkts = al_reg_read32(®_tx_stats->ifMulticastPkts); + stats->ifOutBroadcastPkts = al_reg_read32(®_tx_stats->ifBroadcastPkts); + stats->ifInErrors = al_reg_read32(®_rx_stats->ifInErrors); + stats->ifOutErrors = al_reg_read32(®_tx_stats->ifOutErrors); + stats->aFramesReceivedOK = al_reg_read32(®_rx_stats->FramesOK); + stats->aFramesTransmittedOK = al_reg_read32(®_tx_stats->FramesOK); + /* aOctetsReceivedOK = ifInOctets - 18 * aFramesReceivedOK - 4 * VLANReceivedOK */ - octets = al_reg_read32((void *)((uint32_t)mac_10g_regs_base + 0x108)); /*OctetsOK*/ - octets |= (uint64_t)(al_reg_read32((void *)((uint32_t)mac_10g_regs_base + 0x10C))) << 32; + octets = al_reg_read32(®_rx_stats->ifOctetsL); + octets |= (uint64_t)(al_reg_read32(®_rx_stats->ifOctetsH)) << 32; octets -= 18 * stats->aFramesReceivedOK; - octets -= 4 * al_reg_read32((void *)((uint32_t)mac_10g_regs_base + 0x130)); /*VLANOK*/ + octets -= 4 * al_reg_read32(®_rx_stats->VLANOK); stats->aOctetsReceivedOK = octets; /* aOctetsTransmittedOK = ifOutOctets - 18 * aFramesTransmittedOK - 4 * VLANTransmittedOK */ - octets = al_reg_read32((void *)((uint32_t)mac_10g_regs_base + 0x208)); /*OctetsOK*/ - octets |= (uint64_t)(al_reg_read32((void *)((uint32_t)mac_10g_regs_base + 0x20c))) << 32; + octets = al_reg_read32(®_tx_stats->ifOctetsL); + octets |= (uint64_t)(al_reg_read32(®_tx_stats->ifOctetsH)) << 32; octets -= 18 * stats->aFramesTransmittedOK; - octets -= 4 * al_reg_read32((void *)((uint32_t)mac_10g_regs_base + 0x230)); /*VLANOK*/ + octets -= 4 * al_reg_read32(®_tx_stats->VLANOK); stats->aOctetsTransmittedOK = octets; - stats->etherStatsUndersizePkts = al_reg_read32((void *)((uint32_t)mac_10g_regs_base + 0x168)); - stats->etherStatsFragments = al_reg_read32((void *)((uint32_t)mac_10g_regs_base + 0x1b8)); - stats->etherStatsJabbers = al_reg_read32((void *)((uint32_t)mac_10g_regs_base + 0x1b0)); - stats->etherStatsOversizePkts = al_reg_read32((void *)((uint32_t)mac_10g_regs_base + 0x1a8)); - - stats->aFrameCheckSequenceErrors = al_reg_read32((void *)((uint32_t)mac_10g_regs_base + 0x128)); /* CRCErrors */ - /* stats->aAlignmentErrors = al_reg_read32((void *)((uint32_t)mac_10g_regs_base + 0x98)); */ /* not implemented */ - stats->etherStatsDropEvents = al_reg_read32((void *)((uint32_t)mac_10g_regs_base + 0x158)); + stats->etherStatsUndersizePkts = al_reg_read32(®_rx_stats->etherStatsUndersizePkts); + stats->etherStatsFragments = al_reg_read32(®_rx_stats->etherStatsFragments); + stats->etherStatsJabbers = al_reg_read32(®_rx_stats->etherStatsJabbers); + stats->etherStatsOversizePkts = al_reg_read32(®_rx_stats->etherStatsOversizePkts); + stats->aFrameCheckSequenceErrors = al_reg_read32(®_rx_stats->CRCErrors); + stats->aAlignmentErrors = al_reg_read32(®_rx_stats->aAlignmentErrors); + stats->etherStatsDropEvents = al_reg_read32(®_rx_stats->etherStatsDropEvents); + stats->aPAUSEMACCtrlFramesTransmitted = al_reg_read32(®_tx_stats->aPAUSEMACCtrlFrames); + stats->aPAUSEMACCtrlFramesReceived = al_reg_read32(®_rx_stats->aPAUSEMACCtrlFrames); + stats->aFrameTooLongErrors = al_reg_read32(®_rx_stats->aFrameTooLong); + stats->aInRangeLengthErrors = al_reg_read32(®_rx_stats->aInRangeLengthErrors); + stats->VLANTransmittedOK = al_reg_read32(®_tx_stats->VLANOK); + stats->VLANReceivedOK = al_reg_read32(®_rx_stats->VLANOK); + stats->etherStatsOctets = al_reg_read32(®_rx_stats->etherStatsOctets); + stats->etherStatsPkts64Octets = al_reg_read32(®_rx_stats->etherStatsPkts64Octets); + stats->etherStatsPkts65to127Octets = al_reg_read32(®_rx_stats->etherStatsPkts65to127Octets); + stats->etherStatsPkts128to255Octets = al_reg_read32(®_rx_stats->etherStatsPkts128to255Octets); + stats->etherStatsPkts256to511Octets = al_reg_read32(®_rx_stats->etherStatsPkts256to511Octets); + stats->etherStatsPkts512to1023Octets = al_reg_read32(®_rx_stats->etherStatsPkts512to1023Octets); + stats->etherStatsPkts1024to1518Octets = al_reg_read32(®_rx_stats->etherStatsPkts1024to1518Octets); + stats->etherStatsPkts1519toX = al_reg_read32(®_rx_stats->etherStatsPkts1519toMax); } } else { + struct al_eth_mac_10g_stats_v3_rx __iomem *reg_rx_stats = + &adapter->mac_regs_base->mac_10g.stats.v3.rx; + struct al_eth_mac_10g_stats_v3_tx __iomem *reg_tx_stats = + &adapter->mac_regs_base->mac_10g.stats.v3.tx; uint64_t octets; - /* TODO - change to 64 bit */ - stats->ifInUcastPkts = al_eth_40g_mac_reg_read(adapter, 0x140); - stats->ifInMulticastPkts = al_eth_40g_mac_reg_read(adapter, 0x148); - stats->ifInBroadcastPkts = al_eth_40g_mac_reg_read(adapter, 0x150); - stats->etherStatsPkts = al_eth_40g_mac_reg_read(adapter, 0x160); - stats->ifOutUcastPkts = al_eth_40g_mac_reg_read(adapter, 0x240); - stats->ifOutMulticastPkts = al_eth_40g_mac_reg_read(adapter, 0x248); - stats->ifOutBroadcastPkts = al_eth_40g_mac_reg_read(adapter, 0x250); - stats->ifInErrors = al_eth_40g_mac_reg_read(adapter, 0x138); - stats->ifOutErrors = al_eth_40g_mac_reg_read(adapter, 0x238); - stats->aFramesReceivedOK = al_eth_40g_mac_reg_read(adapter, 0x120); - stats->aFramesTransmittedOK = al_eth_40g_mac_reg_read(adapter, 0x220); + + /* 40G MAC statistics registers are the same, only read indirectly */ + #define _40g_mac_reg_read32(field) al_eth_40g_mac_reg_read(adapter, \ + ((uint8_t *)(field)) - ((uint8_t *)&adapter->mac_regs_base->mac_10g)) + + stats->ifInUcastPkts = _40g_mac_reg_read32(®_rx_stats->ifInUcastPkts); + stats->ifInMulticastPkts = _40g_mac_reg_read32(®_rx_stats->ifInMulticastPkts); + stats->ifInBroadcastPkts = _40g_mac_reg_read32(®_rx_stats->ifInBroadcastPkts); + stats->etherStatsPkts = _40g_mac_reg_read32(®_rx_stats->etherStatsPkts); + stats->ifOutUcastPkts = _40g_mac_reg_read32(®_tx_stats->ifUcastPkts); + stats->ifOutMulticastPkts = _40g_mac_reg_read32(®_tx_stats->ifMulticastPkts); + stats->ifOutBroadcastPkts = _40g_mac_reg_read32(®_tx_stats->ifBroadcastPkts); + stats->ifInErrors = _40g_mac_reg_read32(®_rx_stats->ifInErrors); + stats->ifOutErrors = _40g_mac_reg_read32(®_tx_stats->ifOutErrors); + stats->aFramesReceivedOK = _40g_mac_reg_read32(®_rx_stats->FramesOK); + stats->aFramesTransmittedOK = _40g_mac_reg_read32(®_tx_stats->FramesOK); /* aOctetsReceivedOK = ifInOctets - 18 * aFramesReceivedOK - 4 * VLANReceivedOK */ - octets = al_eth_40g_mac_reg_read(adapter, 0x100); - octets |= (uint64_t)(al_eth_40g_mac_reg_read(adapter, 0x104)) << 32; + octets = _40g_mac_reg_read32(®_rx_stats->ifOctetsL); + octets |= (uint64_t)(_40g_mac_reg_read32(®_rx_stats->ifOctetsH)) << 32; octets -= 18 * stats->aFramesReceivedOK; - octets -= 4 * al_eth_40g_mac_reg_read(adapter, 0x130); /*VLANOK*/ - stats->aOctetsTransmittedOK = octets; - - /* aOctetsTransmittedOK = ifOutOctets - 18 * aFramesTransmittedOK - 4 * VLANTransmittedOK */ - octets = al_eth_40g_mac_reg_read(adapter, 0x200); - octets |= (uint64_t)(al_eth_40g_mac_reg_read(adapter, 0x204)) << 32; - octets -= 18 * stats->aFramesReceivedOK; - octets -= 4 * al_eth_40g_mac_reg_read(adapter, 0x230); /*VLANOK*/ + octets -= 4 * _40g_mac_reg_read32(®_rx_stats->VLANOK); stats->aOctetsReceivedOK = octets; - stats->etherStatsUndersizePkts = al_eth_40g_mac_reg_read(adapter, 0x168); - stats->etherStatsFragments = al_eth_40g_mac_reg_read(adapter, 0x1b8); - stats->etherStatsJabbers = al_eth_40g_mac_reg_read(adapter, 0x1b0); - stats->etherStatsOversizePkts = al_eth_40g_mac_reg_read(adapter, 0x1a8); - stats->aFrameCheckSequenceErrors = al_eth_40g_mac_reg_read(adapter, 0x128); - stats->aAlignmentErrors = al_eth_40g_mac_reg_read(adapter, 0x110); - stats->etherStatsDropEvents = al_eth_40g_mac_reg_read(adapter, 0x158); + /* aOctetsTransmittedOK = ifOutOctets - 18 * aFramesTransmittedOK - 4 * VLANTransmittedOK */ + octets = _40g_mac_reg_read32(®_tx_stats->ifOctetsL); + octets |= (uint64_t)(_40g_mac_reg_read32(®_tx_stats->ifOctetsH)) << 32; + octets -= 18 * stats->aFramesTransmittedOK; + octets -= 4 * _40g_mac_reg_read32(®_tx_stats->VLANOK); + stats->aOctetsTransmittedOK = octets; + + stats->etherStatsUndersizePkts = _40g_mac_reg_read32(®_rx_stats->etherStatsUndersizePkts); + stats->etherStatsFragments = _40g_mac_reg_read32(®_rx_stats->etherStatsFragments); + stats->etherStatsJabbers = _40g_mac_reg_read32(®_rx_stats->etherStatsJabbers); + stats->etherStatsOversizePkts = _40g_mac_reg_read32(®_rx_stats->etherStatsOversizePkts); + stats->aFrameCheckSequenceErrors = _40g_mac_reg_read32(®_rx_stats->CRCErrors); + stats->aAlignmentErrors = _40g_mac_reg_read32(®_rx_stats->aAlignmentErrors); + stats->etherStatsDropEvents = _40g_mac_reg_read32(®_rx_stats->etherStatsDropEvents); + stats->aPAUSEMACCtrlFramesTransmitted = _40g_mac_reg_read32(®_tx_stats->aPAUSEMACCtrlFrames); + stats->aPAUSEMACCtrlFramesReceived = _40g_mac_reg_read32(®_rx_stats->aPAUSEMACCtrlFrames); + stats->aFrameTooLongErrors = _40g_mac_reg_read32(®_rx_stats->aFrameTooLong); + stats->aInRangeLengthErrors = _40g_mac_reg_read32(®_rx_stats->aInRangeLengthErrors); + stats->VLANTransmittedOK = _40g_mac_reg_read32(®_tx_stats->VLANOK); + stats->VLANReceivedOK = _40g_mac_reg_read32(®_rx_stats->VLANOK); + stats->etherStatsOctets = _40g_mac_reg_read32(®_rx_stats->etherStatsOctets); + stats->etherStatsPkts64Octets = _40g_mac_reg_read32(®_rx_stats->etherStatsPkts64Octets); + stats->etherStatsPkts65to127Octets = _40g_mac_reg_read32(®_rx_stats->etherStatsPkts65to127Octets); + stats->etherStatsPkts128to255Octets = _40g_mac_reg_read32(®_rx_stats->etherStatsPkts128to255Octets); + stats->etherStatsPkts256to511Octets = _40g_mac_reg_read32(®_rx_stats->etherStatsPkts256to511Octets); + stats->etherStatsPkts512to1023Octets = _40g_mac_reg_read32(®_rx_stats->etherStatsPkts512to1023Octets); + stats->etherStatsPkts1024to1518Octets = _40g_mac_reg_read32(®_rx_stats->etherStatsPkts1024to1518Octets); + stats->etherStatsPkts1519toX = _40g_mac_reg_read32(®_rx_stats->etherStatsPkts1519toMax); } stats->eee_in = al_reg_read32(&adapter->mac_regs_base->stat.eee_in); @@ -3958,7 +4321,7 @@ int al_eth_flr_rmn(int (* pci_read_config_u32)(void *handle, int where, uint32_t al_reg_write32_masked(&mac_regs_base->gen.mux_sel, ETH_MAC_GEN_MUX_SEL_KR_IN_MASK, mux_sel); /* set SGMII clock to 125MHz */ - al_reg_write32(mac_base + 0xB08, 0x03320501); + al_reg_write32(&mac_regs_base->sgmii.clk_div, 0x03320501); /* reset 1G mac */ AL_REG_MASK_SET(reg, AL_ADAPTER_GENERIC_CONTROL_0_ETH_RESET_1GMAC); @@ -3971,15 +4334,15 @@ int al_eth_flr_rmn(int (* pci_read_config_u32)(void *handle, int where, uint32_t (*pci_write_config_u32)(handle, AL_ADAPTER_GENERIC_CONTROL_0, reg); /* reset SGMII mac clock to default */ - al_reg_write32(mac_base + 0xB08, 0x00320501); + al_reg_write32(&mac_regs_base->sgmii.clk_div, 0x00320501); al_udelay(1000); /* reset async fifo */ - reg = al_reg_read32((void*)((uint32_t)mac_base + 0x95c)); + reg = al_reg_read32(&mac_regs_base->gen.sd_fifo_ctrl); AL_REG_MASK_SET(reg, 0xF0); - al_reg_write32((void*)((uint32_t)mac_base + 0x95c), reg); - reg = al_reg_read32((void*)((uint32_t)mac_base + 0x95c)); + al_reg_write32(&mac_regs_base->gen.sd_fifo_ctrl, reg); + reg = al_reg_read32(&mac_regs_base->gen.sd_fifo_ctrl); AL_REG_MASK_CLEAR(reg, 0xF0); - al_reg_write32((void*)((uint32_t)mac_base + 0x95c), reg); + al_reg_write32(&mac_regs_base->gen.sd_fifo_ctrl, reg); return 0; } @@ -4028,6 +4391,7 @@ int al_eth_flr_rmn_restore_params(int (* pci_read_config_u32)(void *handle, int #define AL_HAL_ETH_EXT_PHY_IF_MASK (AL_FIELD_MASK(21, 20)) #define AL_HAL_ETH_EXT_PHY_IF_SHIFT 20 #define AL_HAL_ETH_AUTO_NEG_MODE_SHIFT 22 +#define AL_HAL_ETH_SERDES_GRP_2_SHIFT 23 #define AL_HAL_ETH_SERDES_GRP_MASK (AL_FIELD_MASK(26, 25)) #define AL_HAL_ETH_SERDES_GRP_SHIFT 25 #define AL_HAL_ETH_SERDES_LANE_MASK (AL_FIELD_MASK(28, 27)) @@ -4054,9 +4418,19 @@ int al_eth_flr_rmn_restore_params(int (* pci_read_config_u32)(void *handle, int #define AL_HAL_ETH_DAC_SHIFT 24 #define AL_HAL_ETH_RETIMER_TYPE_MASK (AL_FIELD_MASK(26, 25)) #define AL_HAL_ETH_RETIMER_TYPE_SHIFT 25 +#define AL_HAL_ETH_RETIMER_CHANNEL_2_MASK (AL_FIELD_MASK(28, 27)) #define AL_HAL_ETH_RETIMER_CHANNEL_2_SHIFT 27 +#define AL_HAL_ETH_RETIMER_TX_CHANNEL_MASK (AL_FIELD_MASK(31, 29)) +#define AL_HAL_ETH_RETIMER_TX_CHANNEL_SHIFT 29 -int al_eth_board_params_set(void * __iomem mac_base, struct al_eth_board_params *params){ +/* board params register 3 */ +#define AL_HAL_ETH_GPIO_SFP_PRESENT_MASK (AL_FIELD_MASK(5, 0)) +#define AL_HAL_ETH_GPIO_SFP_PRESENT_SHIFT 0 + +int al_eth_board_params_set(void * __iomem mac_base, struct al_eth_board_params *params) +{ + struct al_eth_mac_regs __iomem *mac_regs_base = + (struct al_eth_mac_regs __iomem *)mac_base; uint32_t reg = 0; /* ************* Setting Board params register 1 **************** */ @@ -4083,6 +4457,10 @@ int al_eth_board_params_set(void * __iomem mac_base, struct al_eth_board_params AL_REG_FIELD_SET(reg, AL_HAL_ETH_SERDES_GRP_MASK, AL_HAL_ETH_SERDES_GRP_SHIFT, params->serdes_grp); + + AL_REG_BIT_VAL_SET(reg, AL_HAL_ETH_SERDES_GRP_2_SHIFT, + (params->serdes_grp & AL_BIT(2)) ? 1 : 0); + AL_REG_FIELD_SET(reg, AL_HAL_ETH_SERDES_LANE_MASK, AL_HAL_ETH_SERDES_LANE_SHIFT, params->serdes_lane); @@ -4091,7 +4469,7 @@ int al_eth_board_params_set(void * __iomem mac_base, struct al_eth_board_params al_assert(reg != 0); - al_reg_write32(mac_base + 0x4, reg); + al_reg_write32(&mac_regs_base->mac_1g.scratch, reg); /* ************* Setting Board params register 2 **************** */ reg = 0; @@ -4120,12 +4498,11 @@ int al_eth_board_params_set(void * __iomem mac_base, struct al_eth_board_params AL_HAL_ETH_RETIMER_I2C_ADDR_SHIFT, params->retimer_i2c_addr); AL_REG_BIT_VAL_SET(reg, AL_HAL_ETH_RETIMER_CHANNEL_SHIFT, - ((params->retimer_channel == AL_ETH_RETIMER_CHANNEL_B) || - (params->retimer_channel == AL_ETH_RETIMER_CHANNEL_D))); + (params->retimer_channel & AL_BIT(0))); - AL_REG_BIT_VAL_SET(reg, AL_HAL_ETH_RETIMER_CHANNEL_2_SHIFT, - ((params->retimer_channel == AL_ETH_RETIMER_CHANNEL_C) || - (params->retimer_channel == AL_ETH_RETIMER_CHANNEL_D))); + AL_REG_FIELD_SET(reg, AL_HAL_ETH_RETIMER_CHANNEL_2_MASK, + AL_HAL_ETH_RETIMER_CHANNEL_2_SHIFT, + (AL_REG_FIELD_GET(params->retimer_channel, 0x6, 1))); AL_REG_FIELD_SET(reg, AL_HAL_ETH_DAC_LENGTH_MASK, AL_HAL_ETH_DAC_LENGTH_SHIFT, params->dac_len); @@ -4134,12 +4511,29 @@ int al_eth_board_params_set(void * __iomem mac_base, struct al_eth_board_params AL_REG_FIELD_SET(reg, AL_HAL_ETH_RETIMER_TYPE_MASK, AL_HAL_ETH_RETIMER_TYPE_SHIFT, params->retimer_type); - al_reg_write32(mac_base + 0x404, reg); + AL_REG_FIELD_SET(reg, AL_HAL_ETH_RETIMER_TX_CHANNEL_MASK, + AL_HAL_ETH_RETIMER_TX_CHANNEL_SHIFT, + params->retimer_tx_channel); + + al_reg_write32(&mac_regs_base->mac_10g.scratch, reg); + + /* ************* Setting Board params register 3 **************** */ + reg = 0; + + AL_REG_FIELD_SET(reg, AL_HAL_ETH_GPIO_SFP_PRESENT_MASK, + AL_HAL_ETH_GPIO_SFP_PRESENT_SHIFT, + params->gpio_sfp_present); + + al_reg_write32(&mac_regs_base->mac_1g.mac_0, reg); + return 0; } -int al_eth_board_params_get(void * __iomem mac_base, struct al_eth_board_params *params){ - uint32_t reg = al_reg_read32((void*)((uint32_t)mac_base + 0x4)); +int al_eth_board_params_get(void * __iomem mac_base, struct al_eth_board_params *params) +{ + struct al_eth_mac_regs __iomem *mac_regs_base = + (struct al_eth_mac_regs __iomem *)mac_base; + uint32_t reg = al_reg_read32(&mac_regs_base->mac_1g.scratch); /* check if the register was initialized, 0 is not a valid value */ if (reg == 0) @@ -4197,6 +4591,8 @@ int al_eth_board_params_get(void * __iomem mac_base, struct al_eth_board_params AL_HAL_ETH_SERDES_GRP_MASK, AL_HAL_ETH_SERDES_GRP_SHIFT); + params->serdes_grp |= (AL_REG_BIT_GET(reg, AL_HAL_ETH_SERDES_GRP_2_SHIFT) ? AL_BIT(2) : 0); + params->serdes_lane = AL_REG_FIELD_GET(reg, AL_HAL_ETH_SERDES_LANE_MASK, AL_HAL_ETH_SERDES_LANE_SHIFT); @@ -4206,7 +4602,7 @@ int al_eth_board_params_get(void * __iomem mac_base, struct al_eth_board_params AL_HAL_ETH_REF_CLK_FREQ_SHIFT); /* ************* Getting Board params register 2 **************** */ - reg = al_reg_read32((void*)((uint32_t)mac_base + 0x404)); + reg = al_reg_read32(&mac_regs_base->mac_10g.scratch); if (AL_REG_BIT_GET(reg, AL_HAL_ETH_DONT_OVERRIDE_SERDES_SHIFT)) params->dont_override_serdes = AL_TRUE; else @@ -4250,7 +4646,8 @@ int al_eth_board_params_get(void * __iomem mac_base, struct al_eth_board_params params->retimer_channel = ((AL_REG_BIT_GET(reg, AL_HAL_ETH_RETIMER_CHANNEL_SHIFT)) | - (AL_REG_BIT_GET(reg, AL_HAL_ETH_RETIMER_CHANNEL_2_SHIFT) << 1)); + (AL_REG_FIELD_GET(reg, AL_HAL_ETH_RETIMER_CHANNEL_2_MASK, + AL_HAL_ETH_RETIMER_CHANNEL_2_SHIFT) << 1)); params->dac_len = AL_REG_FIELD_GET(reg, AL_HAL_ETH_DAC_LENGTH_MASK, @@ -4265,6 +4662,17 @@ int al_eth_board_params_get(void * __iomem mac_base, struct al_eth_board_params AL_HAL_ETH_RETIMER_TYPE_MASK, AL_HAL_ETH_RETIMER_TYPE_SHIFT); + params->retimer_tx_channel = AL_REG_FIELD_GET(reg, + AL_HAL_ETH_RETIMER_TX_CHANNEL_MASK, + AL_HAL_ETH_RETIMER_TX_CHANNEL_SHIFT); + + /* ************* Getting Board params register 3 **************** */ + reg = al_reg_read32(&mac_regs_base->mac_1g.mac_0); + + params->gpio_sfp_present = AL_REG_FIELD_GET(reg, + AL_HAL_ETH_GPIO_SFP_PRESENT_MASK, + AL_HAL_ETH_GPIO_SFP_PRESENT_SHIFT); + return 0; }