Path: blob/main/sys/contrib/alpine-hal/eth/al_hal_eth_main.c
48255 views
/*-1*******************************************************************************2Copyright (C) 2015 Annapurna Labs Ltd.34This file may be licensed under the terms of the Annapurna Labs Commercial5License Agreement.67Alternatively, this file can be distributed under the terms of the GNU General8Public License V2 as published by the Free Software Foundation and can be9found at http://www.gnu.org/licenses/gpl-2.0.html1011Alternatively, redistribution and use in source and binary forms, with or12without modification, are permitted provided that the following conditions are13met:1415* Redistributions of source code must retain the above copyright notice,16this list of conditions and the following disclaimer.1718* Redistributions in binary form must reproduce the above copyright19notice, this list of conditions and the following disclaimer in20the documentation and/or other materials provided with the21distribution.2223THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND24ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED25WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE26DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR27ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES28(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;29LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON30ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT31(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS32SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.3334*******************************************************************************/3536/**37* @{38* @file al_hal_eth_main.c39*40* @brief XG Ethernet unit HAL driver for main functions (initialization, data path)41*42*/4344#include "al_hal_eth.h"45#include "al_hal_udma_iofic.h"46#include "al_hal_udma_config.h"47#include "al_hal_eth_ec_regs.h"48#include "al_hal_eth_mac_regs.h"49#include "al_hal_unit_adapter_regs.h"50#ifdef AL_ETH_EX51#include "al_hal_eth_ex_internal.h"52#endif5354/* Number of xfi_txclk cycles that accumulate into 100ns */55#define ETH_MAC_KR_10_PCS_CFG_EEE_TIMER_VAL 5256#define ETH_MAC_KR_25_PCS_CFG_EEE_TIMER_VAL 8057#define ETH_MAC_XLG_40_PCS_CFG_EEE_TIMER_VAL 6358#define ETH_MAC_XLG_50_PCS_CFG_EEE_TIMER_VAL 855960#define AL_ETH_TX_PKT_UDMA_FLAGS (AL_ETH_TX_FLAGS_NO_SNOOP | \61AL_ETH_TX_FLAGS_INT)6263#define AL_ETH_TX_PKT_META_FLAGS (AL_ETH_TX_FLAGS_IPV4_L3_CSUM | \64AL_ETH_TX_FLAGS_L4_CSUM | \65AL_ETH_TX_FLAGS_L4_PARTIAL_CSUM | \66AL_ETH_TX_FLAGS_L2_MACSEC_PKT | \67AL_ETH_TX_FLAGS_L2_DIS_FCS |\68AL_ETH_TX_FLAGS_TSO |\69AL_ETH_TX_FLAGS_TS)7071#define AL_ETH_TX_SRC_VLAN_CNT_MASK 372#define AL_ETH_TX_SRC_VLAN_CNT_SHIFT 573#define AL_ETH_TX_L4_PROTO_IDX_MASK 0x1F74#define AL_ETH_TX_L4_PROTO_IDX_SHIFT 875#define AL_ETH_TX_TUNNEL_MODE_SHIFT 1876#define AL_ETH_TX_OUTER_L3_PROTO_SHIFT 2077#define AL_ETH_TX_VLAN_MOD_ADD_SHIFT 2278#define AL_ETH_TX_VLAN_MOD_DEL_SHIFT 2479#define AL_ETH_TX_VLAN_MOD_E_SEL_SHIFT 2680#define AL_ETH_TX_VLAN_MOD_VID_SEL_SHIFT 2881#define AL_ETH_TX_VLAN_MOD_PBIT_SEL_SHIFT 308283/* tx Meta Descriptor defines */84#define AL_ETH_TX_META_STORE (1 << 21)85#define AL_ETH_TX_META_L3_LEN_MASK 0xff86#define AL_ETH_TX_META_L3_OFF_MASK 0xff87#define AL_ETH_TX_META_L3_OFF_SHIFT 888#define AL_ETH_TX_META_MSS_LSB_VAL_SHIFT 2289#define AL_ETH_TX_META_MSS_MSB_TS_VAL_SHIFT 1690#define AL_ETH_TX_META_OUTER_L3_LEN_MASK 0x1f91#define AL_ETH_TX_META_OUTER_L3_LEN_SHIFT 2492#define AL_ETH_TX_META_OUTER_L3_OFF_HIGH_MASK 0x1893#define AL_ETH_TX_META_OUTER_L3_OFF_HIGH_SHIFT 1094#define AL_ETH_TX_META_OUTER_L3_OFF_LOW_MASK 0x0795#define AL_ETH_TX_META_OUTER_L3_OFF_LOW_SHIFT 299697/* tx Meta Descriptor defines - MacSec */98#define AL_ETH_TX_MACSEC_SIGN_SHIFT 0 /* Sign TX pkt */99#define AL_ETH_TX_MACSEC_ENCRYPT_SHIFT 1 /* Encrypt TX pkt */100#define AL_ETH_TX_MACSEC_AN_LSB_SHIFT 2 /* Association Number */101#define AL_ETH_TX_MACSEC_AN_MSB_SHIFT 3102#define AL_ETH_TX_MACSEC_SC_LSB_SHIFT 4 /* Secured Channel */103#define AL_ETH_TX_MACSEC_SC_MSB_SHIFT 9104#define AL_ETH_TX_MACSEC_SECURED_PYLD_LEN_LSB_SHIFT 10 /* Secure Payload Length (0x3FFF for non-SL packets) */105#define AL_ETH_TX_MACSEC_SECURED_PYLD_LEN_MSB_SHIFT 23106107/* Rx Descriptor defines */108#define AL_ETH_RX_L3_PROTO_IDX_MASK 0x1F109#define AL_ETH_RX_SRC_VLAN_CNT_MASK 3110#define AL_ETH_RX_SRC_VLAN_CNT_SHIFT 5111#define AL_ETH_RX_L4_PROTO_IDX_MASK 0x1F112#define AL_ETH_RX_L4_PROTO_IDX_SHIFT 8113114#define AL_ETH_RX_L3_OFFSET_SHIFT 9115#define AL_ETH_RX_L3_OFFSET_MASK (0x7f << AL_ETH_RX_L3_OFFSET_SHIFT)116#define AL_ETH_RX_HASH_SHIFT 16117#define AL_ETH_RX_HASH_MASK (0xffff << AL_ETH_RX_HASH_SHIFT)118119#define ETH_MAC_GEN_LED_CFG_BLINK_TIMER_VAL 5120#define ETH_MAC_GEN_LED_CFG_ACT_TIMER_VAL 7121122/* Tx VID Table*/123#define AL_ETH_TX_VLAN_TABLE_UDMA_MASK 0xF124#define AL_ETH_TX_VLAN_TABLE_FWD_TO_MAC (1 << 4)125126/* tx gpd defines */127#define AL_ETH_TX_GPD_L3_PROTO_MASK 0x1f128#define AL_ETH_TX_GPD_L3_PROTO_SHIFT 0129#define AL_ETH_TX_GPD_L4_PROTO_MASK 0x1f130#define AL_ETH_TX_GPD_L4_PROTO_SHIFT 5131#define AL_ETH_TX_GPD_TUNNEL_CTRL_MASK 0x7132#define AL_ETH_TX_GPD_TUNNEL_CTRL_SHIFT 10133#define AL_ETH_TX_GPD_SRC_VLAN_CNT_MASK 0x3134#define AL_ETH_TX_GPD_SRC_VLAN_CNT_SHIFT 13135#define AL_ETH_TX_GPD_CAM_DATA_2_SHIFT 32136#define AL_ETH_TX_GPD_CAM_MASK_2_SHIFT 32137#define AL_ETH_TX_GPD_CAM_CTRL_VALID_SHIFT 31138139/* tx gcp defines */140#define AL_ETH_TX_GCP_POLY_SEL_MASK 0x1141#define AL_ETH_TX_GCP_POLY_SEL_SHIFT 0142#define AL_ETH_TX_GCP_CRC32_BIT_COMP_MASK 0x1143#define AL_ETH_TX_GCP_CRC32_BIT_COMP_SHIFT 1144#define AL_ETH_TX_GCP_CRC32_BIT_SWAP_MASK 0x1145#define AL_ETH_TX_GCP_CRC32_BIT_SWAP_SHIFT 2146#define AL_ETH_TX_GCP_CRC32_BYTE_SWAP_MASK 0x1147#define AL_ETH_TX_GCP_CRC32_BYTE_SWAP_SHIFT 3148#define AL_ETH_TX_GCP_DATA_BIT_SWAP_MASK 0x1149#define AL_ETH_TX_GCP_DATA_BIT_SWAP_SHIFT 4150#define AL_ETH_TX_GCP_DATA_BYTE_SWAP_MASK 0x1151#define AL_ETH_TX_GCP_DATA_BYTE_SWAP_SHIFT 5152#define AL_ETH_TX_GCP_TRAIL_SIZE_MASK 0xF153#define AL_ETH_TX_GCP_TRAIL_SIZE_SHIFT 6154#define AL_ETH_TX_GCP_HEAD_SIZE_MASK 0xFF155#define AL_ETH_TX_GCP_HEAD_SIZE_SHIFT 16156#define AL_ETH_TX_GCP_HEAD_CALC_MASK 0x1157#define AL_ETH_TX_GCP_HEAD_CALC_SHIFT 24158#define AL_ETH_TX_GCP_MASK_POLARITY_MASK 0x1159#define AL_ETH_TX_GCP_MASK_POLARITY_SHIFT 25160161#define AL_ETH_TX_GCP_OPCODE_1_MASK 0x3F162#define AL_ETH_TX_GCP_OPCODE_1_SHIFT 0163#define AL_ETH_TX_GCP_OPCODE_2_MASK 0x3F164#define AL_ETH_TX_GCP_OPCODE_2_SHIFT 6165#define AL_ETH_TX_GCP_OPCODE_3_MASK 0x3F166#define AL_ETH_TX_GCP_OPCODE_3_SHIFT 12167#define AL_ETH_TX_GCP_OPSEL_1_MASK 0xF168#define AL_ETH_TX_GCP_OPSEL_1_SHIFT 0169#define AL_ETH_TX_GCP_OPSEL_2_MASK 0xF170#define AL_ETH_TX_GCP_OPSEL_2_SHIFT 4171#define AL_ETH_TX_GCP_OPSEL_3_MASK 0xF172#define AL_ETH_TX_GCP_OPSEL_3_SHIFT 8173#define AL_ETH_TX_GCP_OPSEL_4_MASK 0xF174#define AL_ETH_TX_GCP_OPSEL_4_SHIFT 12175176/* Tx crc_chksum_replace defines */177#define L4_CHECKSUM_DIS_AND_L3_CHECKSUM_DIS 0x00178#define L4_CHECKSUM_DIS_AND_L3_CHECKSUM_EN 0x20179#define L4_CHECKSUM_EN_AND_L3_CHECKSUM_DIS 0x40180#define L4_CHECKSUM_EN_AND_L3_CHECKSUM_EN 0x60181182/* rx gpd defines */183#define AL_ETH_RX_GPD_OUTER_L3_PROTO_MASK 0x1f184#define AL_ETH_RX_GPD_OUTER_L3_PROTO_SHIFT (3 + 0)185#define AL_ETH_RX_GPD_OUTER_L4_PROTO_MASK 0x1f186#define AL_ETH_RX_GPD_OUTER_L4_PROTO_SHIFT (3 + 8)187#define AL_ETH_RX_GPD_INNER_L3_PROTO_MASK 0x1f188#define AL_ETH_RX_GPD_INNER_L3_PROTO_SHIFT (3 + 16)189#define AL_ETH_RX_GPD_INNER_L4_PROTO_MASK 0x1f190#define AL_ETH_RX_GPD_INNER_L4_PROTO_SHIFT (3 + 24)191#define AL_ETH_RX_GPD_OUTER_PARSE_CTRL_MASK 0xFF192#define AL_ETH_RX_GPD_OUTER_PARSE_CTRL_SHIFT 32193#define AL_ETH_RX_GPD_INNER_PARSE_CTRL_MASK 0xFF194#define AL_ETH_RX_GPD_INNER_PARSE_CTRL_SHIFT 40195#define AL_ETH_RX_GPD_L3_PRIORITY_MASK 0xFF196#define AL_ETH_RX_GPD_L3_PRIORITY_SHIFT 48197#define AL_ETH_RX_GPD_L4_DST_PORT_LSB_MASK 0xFF198#define AL_ETH_RX_GPD_L4_DST_PORT_LSB_SHIFT 56199#define AL_ETH_RX_GPD_CAM_DATA_2_SHIFT 32200#define AL_ETH_RX_GPD_CAM_MASK_2_SHIFT 32201#define AL_ETH_RX_GPD_CAM_CTRL_VALID_SHIFT 31202203#define AL_ETH_RX_GPD_PARSE_RESULT_OUTER_L3_PROTO_IDX_OFFSET (106 + 5)204#define AL_ETH_RX_GPD_PARSE_RESULT_OUTER_L4_PROTO_IDX_OFFSET (106 + 10)205#define AL_ETH_RX_GPD_PARSE_RESULT_INNER_L3_PROTO_IDX_OFFSET (0 + 5)206#define AL_ETH_RX_GPD_PARSE_RESULT_INNER_L4_PROTO_IDX_OFFSET (0 + 10)207#define AL_ETH_RX_GPD_PARSE_RESULT_OUTER_PARSE_CTRL (106 + 4)208#define AL_ETH_RX_GPD_PARSE_RESULT_INNER_PARSE_CTRL 4209#define AL_ETH_RX_GPD_PARSE_RESULT_L3_PRIORITY (106 + 13)210#define AL_ETH_RX_GPD_PARSE_RESULT_OUTER_L4_DST_PORT_LSB (106 + 65)211212/* rx gcp defines */213#define AL_ETH_RX_GCP_POLY_SEL_MASK 0x1214#define AL_ETH_RX_GCP_POLY_SEL_SHIFT 0215#define AL_ETH_RX_GCP_CRC32_BIT_COMP_MASK 0x1216#define AL_ETH_RX_GCP_CRC32_BIT_COMP_SHIFT 1217#define AL_ETH_RX_GCP_CRC32_BIT_SWAP_MASK 0x1218#define AL_ETH_RX_GCP_CRC32_BIT_SWAP_SHIFT 2219#define AL_ETH_RX_GCP_CRC32_BYTE_SWAP_MASK 0x1220#define AL_ETH_RX_GCP_CRC32_BYTE_SWAP_SHIFT 3221#define AL_ETH_RX_GCP_DATA_BIT_SWAP_MASK 0x1222#define AL_ETH_RX_GCP_DATA_BIT_SWAP_SHIFT 4223#define AL_ETH_RX_GCP_DATA_BYTE_SWAP_MASK 0x1224#define AL_ETH_RX_GCP_DATA_BYTE_SWAP_SHIFT 5225#define AL_ETH_RX_GCP_TRAIL_SIZE_MASK 0xF226#define AL_ETH_RX_GCP_TRAIL_SIZE_SHIFT 6227#define AL_ETH_RX_GCP_HEAD_SIZE_MASK 0xFF228#define AL_ETH_RX_GCP_HEAD_SIZE_SHIFT 16229#define AL_ETH_RX_GCP_HEAD_CALC_MASK 0x1230#define AL_ETH_RX_GCP_HEAD_CALC_SHIFT 24231#define AL_ETH_RX_GCP_MASK_POLARITY_MASK 0x1232#define AL_ETH_RX_GCP_MASK_POLARITY_SHIFT 25233234#define AL_ETH_RX_GCP_OPCODE_1_MASK 0x3F235#define AL_ETH_RX_GCP_OPCODE_1_SHIFT 0236#define AL_ETH_RX_GCP_OPCODE_2_MASK 0x3F237#define AL_ETH_RX_GCP_OPCODE_2_SHIFT 6238#define AL_ETH_RX_GCP_OPCODE_3_MASK 0x3F239#define AL_ETH_RX_GCP_OPCODE_3_SHIFT 12240#define AL_ETH_RX_GCP_OPSEL_1_MASK 0xF241#define AL_ETH_RX_GCP_OPSEL_1_SHIFT 0242#define AL_ETH_RX_GCP_OPSEL_2_MASK 0xF243#define AL_ETH_RX_GCP_OPSEL_2_SHIFT 4244#define AL_ETH_RX_GCP_OPSEL_3_MASK 0xF245#define AL_ETH_RX_GCP_OPSEL_3_SHIFT 8246#define AL_ETH_RX_GCP_OPSEL_4_MASK 0xF247#define AL_ETH_RX_GCP_OPSEL_4_SHIFT 12248249#define AL_ETH_MDIO_DELAY_PERIOD 1 /* micro seconds to wait when polling mdio status */250#define AL_ETH_MDIO_DELAY_COUNT 150 /* number of times to poll */251#define AL_ETH_S2M_UDMA_COMP_COAL_TIMEOUT 200 /* Rx descriptors coalescing timeout in SB clocks */252253#define AL_ETH_EPE_ENTRIES_NUM 26254static struct al_eth_epe_p_reg_entry al_eth_epe_p_regs[AL_ETH_EPE_ENTRIES_NUM] = {255{ 0x0, 0x0, 0x0 },256{ 0x0, 0x0, 0x1 },257{ 0x0, 0x0, 0x2 },258{ 0x0, 0x0, 0x3 },259{ 0x18100, 0xFFFFF, 0x80000004 },260{ 0x188A8, 0xFFFFF, 0x80000005 },261{ 0x99100, 0xFFFFF, 0x80000006 },262{ 0x98100, 0xFFFFF, 0x80000007 },263{ 0x10800, 0x7FFFF, 0x80000008 },264{ 0x20000, 0x73FFF, 0x80000009 },265{ 0x20000, 0x70000, 0x8000000A },266{ 0x186DD, 0x7FFFF, 0x8000000B },267{ 0x30600, 0x7FF00, 0x8000000C },268{ 0x31100, 0x7FF00, 0x8000000D },269{ 0x32F00, 0x7FF00, 0x8000000E },270{ 0x32900, 0x7FF00, 0x8000000F },271{ 0x105DC, 0x7FFFF, 0x80010010 },272{ 0x188E5, 0x7FFFF, 0x80000011 },273{ 0x72000, 0x72000, 0x80000012 },274{ 0x70000, 0x72000, 0x80000013 },275{ 0x46558, 0x7FFFF, 0x80000001 },276{ 0x18906, 0x7FFFF, 0x80000015 },277{ 0x18915, 0x7FFFF, 0x80000016 },278{ 0x31B00, 0x7FF00, 0x80000017 },279{ 0x30400, 0x7FF00, 0x80000018 },280{ 0x0, 0x0, 0x8000001F }281};282283284static struct al_eth_epe_control_entry al_eth_epe_control_table[AL_ETH_EPE_ENTRIES_NUM] = {285{{ 0x2800000, 0x0, 0x0, 0x0, 0x1, 0x400000 }},286{{ 0x280004C, 0x746000, 0xA46030, 0xE00000, 0x2, 0x400000 }},287{{ 0x2800054, 0x746000, 0xA46030, 0x1600000, 0x2, 0x400000 }},288{{ 0x280005C, 0x746000, 0xA46030, 0x1E00000, 0x2, 0x400000 }},289{{ 0x2800042, 0xD42000, 0x0, 0x400000, 0x1010412, 0x400000 }},290{{ 0x2800042, 0xD42000, 0x0, 0x400000, 0x1010412, 0x400000 }},291{{ 0x2800042, 0xE42000, 0x0, 0x400000, 0x2020002, 0x400000 }},292{{ 0x2800042, 0xE42000, 0x0, 0x400000, 0x2020002, 0x400000 }},293{{ 0x280B046, 0x0, 0x6C1008, 0x0, 0x4, 0x406800 }},294{{ 0x2800049, 0xF44060, 0x1744080, 0x14404, 0x6, 0x400011 }},295{{ 0x2015049, 0xF44060, 0x1744080, 0x14404, 0x8080007, 0x400011 }},296{{ 0x280B046, 0xF60040, 0x6C1004, 0x2800000, 0x6, 0x406811 }},297{{ 0x2815042, 0x1F42000, 0x2042010, 0x1414460, 0x10100009, 0x40B800 }},298{{ 0x2815042, 0x1F42000, 0x2042010, 0x800000, 0x10100009, 0x40B800 }},299{{ 0x280B042, 0x0, 0x0, 0x430400, 0x4040009, 0x0 }},300{{ 0x2815580, 0x0, 0x0, 0x0, 0x4040005, 0x0 }},301{{ 0x280B000, 0x0, 0x0, 0x0, 0x1, 0x400000 }},302{{ 0x2800040, 0x174E000, 0x0, 0x0, 0xE, 0x406800 }},303{{ 0x280B000, 0x0, 0x0, 0x600000, 0x1, 0x406800 }},304{{ 0x280B000, 0x0, 0x0, 0xE00000, 0x1, 0x406800 }},305{{ 0x2800000, 0x0, 0x0, 0x0, 0x1, 0x400000 }},306{{ 0x280B046, 0x0, 0x0, 0x2800000, 0x7, 0x400000 }},307{{ 0x280B046, 0xF60040, 0x6C1004, 0x2800000, 0x6, 0x406811 }},308{{ 0x2815042, 0x1F43028, 0x2000000, 0xC00000, 0x10100009, 0x40B800 }},309{{ 0x2815400, 0x0, 0x0, 0x0, 0x4040005, 0x0 }},310{{ 0x2800000, 0x0, 0x0, 0x0, 0x1, 0x400000 }}311};312313314#define AL_ETH_IS_1G_MAC(mac_mode) (((mac_mode) == AL_ETH_MAC_MODE_RGMII) || ((mac_mode) == AL_ETH_MAC_MODE_SGMII))315#define AL_ETH_IS_10G_MAC(mac_mode) (((mac_mode) == AL_ETH_MAC_MODE_10GbE_Serial) || \316((mac_mode) == AL_ETH_MAC_MODE_10G_SGMII) || \317((mac_mode) == AL_ETH_MAC_MODE_SGMII_2_5G))318#define AL_ETH_IS_25G_MAC(mac_mode) ((mac_mode) == AL_ETH_MAC_MODE_KR_LL_25G)319320static const char *al_eth_mac_mode_str(enum al_eth_mac_mode mode)321{322switch(mode) {323case AL_ETH_MAC_MODE_RGMII:324return "RGMII";325case AL_ETH_MAC_MODE_SGMII:326return "SGMII";327case AL_ETH_MAC_MODE_SGMII_2_5G:328return "SGMII_2_5G";329case AL_ETH_MAC_MODE_10GbE_Serial:330return "KR";331case AL_ETH_MAC_MODE_KR_LL_25G:332return "KR_LL_25G";333case AL_ETH_MAC_MODE_10G_SGMII:334return "10G_SGMII";335case AL_ETH_MAC_MODE_XLG_LL_40G:336return "40G_LL";337case AL_ETH_MAC_MODE_XLG_LL_50G:338return "50G_LL";339case AL_ETH_MAC_MODE_XLG_LL_25G:340return "25G_LL";341default:342return "N/A";343}344}345346/**347* change and wait udma state348*349* @param dma the udma to change its state350* @param new_state351*352* @return 0 on success. otherwise on failure.353*/354static int al_udma_state_set_wait(struct al_udma *dma, enum al_udma_state new_state)355{356enum al_udma_state state;357enum al_udma_state expected_state = new_state;358int count = 1000;359int rc;360361rc = al_udma_state_set(dma, new_state);362if (rc != 0) {363al_warn("[%s] warn: failed to change state, error %d\n", dma->name, rc);364return rc;365}366367if ((new_state == UDMA_NORMAL) || (new_state == UDMA_DISABLE))368expected_state = UDMA_IDLE;369370do {371state = al_udma_state_get(dma);372if (state == expected_state)373break;374al_udelay(1);375if (count-- == 0) {376al_warn("[%s] warn: dma state didn't change to %s\n",377dma->name, al_udma_states_name[new_state]);378return -ETIMEDOUT;379}380} while (1);381return 0;382}383384static void al_eth_epe_entry_set(struct al_hal_eth_adapter *adapter, uint32_t idx,385struct al_eth_epe_p_reg_entry *reg_entry,386struct al_eth_epe_control_entry *control_entry)387{388al_reg_write32(&adapter->ec_regs_base->epe_p[idx].comp_data, reg_entry->data);389al_reg_write32(&adapter->ec_regs_base->epe_p[idx].comp_mask, reg_entry->mask);390al_reg_write32(&adapter->ec_regs_base->epe_p[idx].comp_ctrl, reg_entry->ctrl);391392al_reg_write32(&adapter->ec_regs_base->msp_c[idx].p_comp_data, reg_entry->data);393al_reg_write32(&adapter->ec_regs_base->msp_c[idx].p_comp_mask, reg_entry->mask);394al_reg_write32(&adapter->ec_regs_base->msp_c[idx].p_comp_ctrl, reg_entry->ctrl);395396/*control table 0*/397al_reg_write32(&adapter->ec_regs_base->epe[0].act_table_addr, idx);398al_reg_write32(&adapter->ec_regs_base->epe[0].act_table_data_6,399control_entry->data[5]);400al_reg_write32(&adapter->ec_regs_base->epe[0].act_table_data_2,401control_entry->data[1]);402al_reg_write32(&adapter->ec_regs_base->epe[0].act_table_data_3,403control_entry->data[2]);404al_reg_write32(&adapter->ec_regs_base->epe[0].act_table_data_4,405control_entry->data[3]);406al_reg_write32(&adapter->ec_regs_base->epe[0].act_table_data_5,407control_entry->data[4]);408al_reg_write32(&adapter->ec_regs_base->epe[0].act_table_data_1,409control_entry->data[0]);410411/*control table 1*/412al_reg_write32(&adapter->ec_regs_base->epe[1].act_table_addr, idx);413al_reg_write32(&adapter->ec_regs_base->epe[1].act_table_data_6,414control_entry->data[5]);415al_reg_write32(&adapter->ec_regs_base->epe[1].act_table_data_2,416control_entry->data[1]);417al_reg_write32(&adapter->ec_regs_base->epe[1].act_table_data_3,418control_entry->data[2]);419al_reg_write32(&adapter->ec_regs_base->epe[1].act_table_data_4,420control_entry->data[3]);421al_reg_write32(&adapter->ec_regs_base->epe[1].act_table_data_5,422control_entry->data[4]);423al_reg_write32(&adapter->ec_regs_base->epe[1].act_table_data_1,424control_entry->data[0]);425}426427static void al_eth_epe_init(struct al_hal_eth_adapter *adapter)428{429int idx;430431if (adapter->enable_rx_parser == 0) {432al_dbg("eth [%s]: disable rx parser\n", adapter->name);433434al_reg_write32(&adapter->ec_regs_base->epe[0].res_def, 0x08000000);435al_reg_write32(&adapter->ec_regs_base->epe[0].res_in, 0x7);436437al_reg_write32(&adapter->ec_regs_base->epe[1].res_def, 0x08000000);438al_reg_write32(&adapter->ec_regs_base->epe[1].res_in, 0x7);439440return;441}442al_dbg("eth [%s]: enable rx parser\n", adapter->name);443for (idx = 0; idx < AL_ETH_EPE_ENTRIES_NUM; idx++)444al_eth_epe_entry_set(adapter, idx, &al_eth_epe_p_regs[idx], &al_eth_epe_control_table[idx]);445446al_reg_write32(&adapter->ec_regs_base->epe[0].res_def, 0x08000080);447al_reg_write32(&adapter->ec_regs_base->epe[0].res_in, 0x7);448449al_reg_write32(&adapter->ec_regs_base->epe[1].res_def, 0x08000080);450al_reg_write32(&adapter->ec_regs_base->epe[1].res_in, 0);451452/* header length as function of 4 bits value, for GRE, when C bit is set, the header len should be increase by 4*/453al_reg_write32(&adapter->ec_regs_base->epe_h[8].hdr_len, (4 << 16) | 4);454455/* select the outer information when writing the rx descriptor (l3 protocol index etc) */456al_reg_write32(&adapter->ec_regs_base->rfw.meta, EC_RFW_META_L3_LEN_CALC);457458al_reg_write32(&adapter->ec_regs_base->rfw.checksum, EC_RFW_CHECKSUM_HDR_SEL);459}460461/**462* read 40G MAC registers (indirect access)463*464* @param adapter pointer to the private structure465* @param reg_addr address in the an registers466*467* @return the register value468*/469static uint32_t al_eth_40g_mac_reg_read(470struct al_hal_eth_adapter *adapter,471uint32_t reg_addr)472{473uint32_t val;474475/* indirect access */476al_reg_write32(&adapter->mac_regs_base->gen_v3.mac_40g_ll_addr, reg_addr);477val = al_reg_read32(&adapter->mac_regs_base->gen_v3.mac_40g_ll_data);478479al_dbg("[%s]: %s - reg %d. val 0x%x",480adapter->name, __func__, reg_addr, val);481482return val;483}484485/**486* write 40G MAC registers (indirect access)487*488* @param adapter pointer to the private structure489* @param reg_addr address in the an registers490* @param reg_data value to write to the register491*492*/493static void al_eth_40g_mac_reg_write(494struct al_hal_eth_adapter *adapter,495uint32_t reg_addr,496uint32_t reg_data)497{498/* indirect access */499al_reg_write32(&adapter->mac_regs_base->gen_v3.mac_40g_ll_addr, reg_addr);500al_reg_write32(&adapter->mac_regs_base->gen_v3.mac_40g_ll_data, reg_data);501502al_dbg("[%s]: %s - reg %d. val 0x%x",503adapter->name, __func__, reg_addr, reg_data);504}505506/**507* read 40G PCS registers (indirect access)508*509* @param adapter pointer to the private structure510* @param reg_addr address in the an registers511*512* @return the register value513*/514static uint32_t al_eth_40g_pcs_reg_read(515struct al_hal_eth_adapter *adapter,516uint32_t reg_addr)517{518uint32_t val;519520/* indirect access */521al_reg_write32(&adapter->mac_regs_base->gen_v3.pcs_40g_ll_addr, reg_addr);522val = al_reg_read32(&adapter->mac_regs_base->gen_v3.pcs_40g_ll_data);523524al_dbg("[%s]: %s - reg %d. val 0x%x",525adapter->name, __func__, reg_addr, val);526527return val;528}529530/**531* write 40G PCS registers (indirect access)532*533* @param adapter pointer to the private structure534* @param reg_addr address in the an registers535* @param reg_data value to write to the register536*537*/538static void al_eth_40g_pcs_reg_write(539struct al_hal_eth_adapter *adapter,540uint32_t reg_addr,541uint32_t reg_data)542{543/* indirect access */544al_reg_write32(&adapter->mac_regs_base->gen_v3.pcs_40g_ll_addr, reg_addr);545al_reg_write32(&adapter->mac_regs_base->gen_v3.pcs_40g_ll_data, reg_data);546547al_dbg("[%s]: %s - reg %d. val 0x%x",548adapter->name, __func__, reg_addr, reg_data);549}550551/*****************************API Functions **********************************/552/*adapter management */553/**554* initialize the ethernet adapter's DMA555*/556int al_eth_adapter_init(struct al_hal_eth_adapter *adapter, struct al_eth_adapter_params *params)557{558struct al_udma_params udma_params;559struct al_udma_m2s_pkt_len_conf conf;560int i;561uint32_t reg;562int rc;563564al_dbg("eth [%s]: initialize controller's UDMA. id = %d\n", params->name, params->udma_id);565al_dbg("eth [%s]: UDMA base regs: %p\n", params->name, params->udma_regs_base);566al_dbg("eth [%s]: EC base regs: %p\n", params->name, params->ec_regs_base);567al_dbg("eth [%s]: MAC base regs: %p\n", params->name, params->mac_regs_base);568al_dbg("eth [%s]: enable_rx_parser: %x\n", params->name, params->enable_rx_parser);569570adapter->name = params->name;571adapter->rev_id = params->rev_id;572adapter->udma_id = params->udma_id;573adapter->udma_regs_base = params->udma_regs_base;574adapter->ec_regs_base = (struct al_ec_regs __iomem*)params->ec_regs_base;575adapter->mac_regs_base = (struct al_eth_mac_regs __iomem*)params->mac_regs_base;576adapter->unit_regs = (struct unit_regs __iomem *)params->udma_regs_base;577adapter->enable_rx_parser = params->enable_rx_parser;578adapter->serdes_lane = params->serdes_lane;579adapter->ec_ints_base = (uint8_t __iomem *)adapter->ec_regs_base + 0x1c00;580adapter->mac_ints_base = (struct interrupt_controller_ctrl __iomem *)581((uint8_t __iomem *)adapter->mac_regs_base + 0x800);582583/* initialize Tx udma */584udma_params.udma_regs_base = adapter->unit_regs;585udma_params.type = UDMA_TX;586udma_params.num_of_queues = AL_ETH_UDMA_TX_QUEUES;587udma_params.name = "eth tx";588rc = al_udma_init(&adapter->tx_udma, &udma_params);589590if (rc != 0) {591al_err("failed to initialize %s, error %d\n",592udma_params.name, rc);593return rc;594}595rc = al_udma_state_set_wait(&adapter->tx_udma, UDMA_NORMAL);596if (rc != 0) {597al_err("[%s]: failed to change state, error %d\n",598udma_params.name, rc);599return rc;600}601/* initialize Rx udma */602udma_params.udma_regs_base = adapter->unit_regs;603udma_params.type = UDMA_RX;604udma_params.num_of_queues = AL_ETH_UDMA_RX_QUEUES;605udma_params.name = "eth rx";606rc = al_udma_init(&adapter->rx_udma, &udma_params);607608if (rc != 0) {609al_err("failed to initialize %s, error %d\n",610udma_params.name, rc);611return rc;612}613614rc = al_udma_state_set_wait(&adapter->rx_udma, UDMA_NORMAL);615if (rc != 0) {616al_err("[%s]: failed to change state, error %d\n",617udma_params.name, rc);618return rc;619}620al_dbg("eth [%s]: controller's UDMA successfully initialized\n",621params->name);622623/* set max packet size to 1M (for TSO) */624conf.encode_64k_as_zero = AL_TRUE;625conf.max_pkt_size = 0xfffff;626al_udma_m2s_packet_size_cfg_set(&adapter->tx_udma, &conf);627628/* set m2s (tx) max descriptors to max data buffers number and one for629* meta descriptor630*/631al_udma_m2s_max_descs_set(&adapter->tx_udma, AL_ETH_PKT_MAX_BUFS + 1);632633/* set s2m (rx) max descriptors to max data buffers */634al_udma_s2m_max_descs_set(&adapter->rx_udma, AL_ETH_PKT_MAX_BUFS);635636/* set s2m burst lenght when writing completion descriptors to 64 bytes637*/638al_udma_s2m_compl_desc_burst_config(&adapter->rx_udma, 64);639640/* if pointer to ec regs provided, then init the tx meta cache of this udma*/641if (adapter->ec_regs_base != NULL) {642// INIT TX CACHE TABLE:643for (i = 0; i < 4; i++) {644al_reg_write32(&adapter->ec_regs_base->tso.cache_table_addr, i + (adapter->udma_id * 4));645al_reg_write32(&adapter->ec_regs_base->tso.cache_table_data_1, 0x00000000);646al_reg_write32(&adapter->ec_regs_base->tso.cache_table_data_2, 0x00000000);647al_reg_write32(&adapter->ec_regs_base->tso.cache_table_data_3, 0x00000000);648al_reg_write32(&adapter->ec_regs_base->tso.cache_table_data_4, 0x00000000);649}650}651// only udma 0 allowed to init ec652if (adapter->udma_id != 0) {653return 0;654}655/* enable Ethernet controller: */656/* enable internal machines*/657al_reg_write32(&adapter->ec_regs_base->gen.en, 0xffffffff);658al_reg_write32(&adapter->ec_regs_base->gen.fifo_en, 0xffffffff);659660if (adapter->rev_id > AL_ETH_REV_ID_0) {661/* enable A0 descriptor structure */662al_reg_write32_masked(&adapter->ec_regs_base->gen.en_ext,663EC_GEN_EN_EXT_CACHE_WORD_SPLIT,664EC_GEN_EN_EXT_CACHE_WORD_SPLIT);665666/* use mss value in the descriptor */667al_reg_write32(&adapter->ec_regs_base->tso.cfg_add_0,668EC_TSO_CFG_ADD_0_MSS_SEL);669670/* enable tunnel TSO */671al_reg_write32(&adapter->ec_regs_base->tso.cfg_tunnel,672(EC_TSO_CFG_TUNNEL_EN_TUNNEL_TSO |673EC_TSO_CFG_TUNNEL_EN_UDP_CHKSUM |674EC_TSO_CFG_TUNNEL_EN_UDP_LEN |675EC_TSO_CFG_TUNNEL_EN_IPV6_PLEN |676EC_TSO_CFG_TUNNEL_EN_IPV4_CHKSUM |677EC_TSO_CFG_TUNNEL_EN_IPV4_IDEN |678EC_TSO_CFG_TUNNEL_EN_IPV4_TLEN));679}680681/* swap input byts from MAC RX */682al_reg_write32(&adapter->ec_regs_base->mac.gen, 0x00000001);683/* swap output bytes to MAC TX*/684al_reg_write32(&adapter->ec_regs_base->tmi.tx_cfg, EC_TMI_TX_CFG_EN_FWD_TO_RX|EC_TMI_TX_CFG_SWAP_BYTES);685686/* TODO: check if we need this line*/687al_reg_write32(&adapter->ec_regs_base->tfw_udma[0].fwd_dec, 0x000003fb);688689/* RFW configuration: default 0 */690al_reg_write32(&adapter->ec_regs_base->rfw_default[0].opt_1, 0x00000001);691692/* VLAN table address*/693al_reg_write32(&adapter->ec_regs_base->rfw.vid_table_addr, 0x00000000);694/* VLAN table data*/695al_reg_write32(&adapter->ec_regs_base->rfw.vid_table_data, 0x00000000);696/* HASH config (select toeplitz and bits 7:0 of the thash result, enable697* symmetric hash) */698al_reg_write32(&adapter->ec_regs_base->rfw.thash_cfg_1,699EC_RFW_THASH_CFG_1_ENABLE_IP_SWAP |700EC_RFW_THASH_CFG_1_ENABLE_PORT_SWAP);701702al_eth_epe_init(adapter);703704/* disable TSO padding and use mac padding instead */705reg = al_reg_read32(&adapter->ec_regs_base->tso.in_cfg);706reg &= ~0x7F00; /*clear bits 14:8 */707al_reg_write32(&adapter->ec_regs_base->tso.in_cfg, reg);708709return 0;710}711712/*****************************API Functions **********************************/713/*adapter management */714/**715* enable the ec and mac interrupts716*/717int al_eth_ec_mac_ints_config(struct al_hal_eth_adapter *adapter)718{719720al_dbg("eth [%s]: enable ethernet and mac interrupts\n", adapter->name);721722// only udma 0 allowed to init ec723if (adapter->udma_id != 0)724return -EPERM;725726/* enable mac ints */727al_iofic_config(adapter->ec_ints_base, AL_INT_GROUP_A,728INT_CONTROL_GRP_SET_ON_POSEDGE | INT_CONTROL_GRP_CLEAR_ON_READ);729al_iofic_config(adapter->ec_ints_base, AL_INT_GROUP_B,730INT_CONTROL_GRP_SET_ON_POSEDGE | INT_CONTROL_GRP_CLEAR_ON_READ);731al_iofic_config(adapter->ec_ints_base, AL_INT_GROUP_C,732INT_CONTROL_GRP_SET_ON_POSEDGE | INT_CONTROL_GRP_CLEAR_ON_READ);733al_iofic_config(adapter->ec_ints_base, AL_INT_GROUP_D,734INT_CONTROL_GRP_SET_ON_POSEDGE | INT_CONTROL_GRP_CLEAR_ON_READ);735736/* unmask MAC int */737al_iofic_unmask(adapter->ec_ints_base, AL_INT_GROUP_A, 8);738739/* enable ec interrupts */740al_iofic_config(adapter->mac_ints_base, AL_INT_GROUP_A,741INT_CONTROL_GRP_SET_ON_POSEDGE | INT_CONTROL_GRP_CLEAR_ON_READ);742al_iofic_config(adapter->mac_ints_base, AL_INT_GROUP_B,743INT_CONTROL_GRP_SET_ON_POSEDGE | INT_CONTROL_GRP_CLEAR_ON_READ);744al_iofic_config(adapter->mac_ints_base, AL_INT_GROUP_C,745INT_CONTROL_GRP_SET_ON_POSEDGE | INT_CONTROL_GRP_CLEAR_ON_READ);746al_iofic_config(adapter->mac_ints_base, AL_INT_GROUP_D,747INT_CONTROL_GRP_SET_ON_POSEDGE | INT_CONTROL_GRP_CLEAR_ON_READ);748749/* eee active */750al_iofic_unmask(adapter->mac_ints_base, AL_INT_GROUP_B, AL_BIT(14));751752al_iofic_unmask(adapter->unit_regs, AL_INT_GROUP_D, AL_BIT(11));753return 0;754}755756/**757* ec and mac interrupt service routine758* read and print asserted interrupts759*760* @param adapter pointer to the private structure761*762* @return 0 on success. otherwise on failure.763*/764int al_eth_ec_mac_isr(struct al_hal_eth_adapter *adapter)765{766uint32_t cause;767al_dbg("[%s]: ethernet interrupts handler\n", adapter->name);768769// only udma 0 allowed to init ec770if (adapter->udma_id != 0)771return -EPERM;772773/* read ec cause */774cause = al_iofic_read_cause(adapter->ec_ints_base, AL_INT_GROUP_A);775al_dbg("[%s]: ethernet group A cause 0x%08x\n", adapter->name, cause);776if (cause & 1)777{778cause = al_iofic_read_cause(adapter->mac_ints_base, AL_INT_GROUP_A);779al_dbg("[%s]: mac group A cause 0x%08x\n", adapter->name, cause);780781cause = al_iofic_read_cause(adapter->mac_ints_base, AL_INT_GROUP_B);782al_dbg("[%s]: mac group B cause 0x%08x\n", adapter->name, cause);783784cause = al_iofic_read_cause(adapter->mac_ints_base, AL_INT_GROUP_C);785al_dbg("[%s]: mac group C cause 0x%08x\n", adapter->name, cause);786787cause = al_iofic_read_cause(adapter->mac_ints_base, AL_INT_GROUP_D);788al_dbg("[%s]: mac group D cause 0x%08x\n", adapter->name, cause);789}790cause = al_iofic_read_cause(adapter->ec_ints_base, AL_INT_GROUP_B);791al_dbg("[%s]: ethernet group B cause 0x%08x\n", adapter->name, cause);792cause = al_iofic_read_cause(adapter->ec_ints_base, AL_INT_GROUP_C);793al_dbg("[%s]: ethernet group C cause 0x%08x\n", adapter->name, cause);794cause = al_iofic_read_cause(adapter->ec_ints_base, AL_INT_GROUP_D);795al_dbg("[%s]: ethernet group D cause 0x%08x\n", adapter->name, cause);796797return 0;798}799800/**801* stop the DMA of the ethernet adapter802*/803int al_eth_adapter_stop(struct al_hal_eth_adapter *adapter)804{805int rc;806807al_dbg("eth [%s]: stop controller's UDMA\n", adapter->name);808809/* disable Tx dma*/810rc = al_udma_state_set_wait(&adapter->tx_udma, UDMA_DISABLE);811if (rc != 0) {812al_warn("[%s] warn: failed to change state, error %d\n",813adapter->tx_udma.name, rc);814return rc;815}816817al_dbg("eth [%s]: controller's TX UDMA stopped\n",818adapter->name);819/* disable Rx dma*/820rc = al_udma_state_set_wait(&adapter->rx_udma, UDMA_DISABLE);821if (rc != 0) {822al_warn("[%s] warn: failed to change state, error %d\n",823adapter->rx_udma.name, rc);824return rc;825}826827al_dbg("eth [%s]: controller's RX UDMA stopped\n",828adapter->name);829return 0;830}831832int al_eth_adapter_reset(struct al_hal_eth_adapter *adapter)833{834al_dbg("eth [%s]: reset controller's UDMA\n", adapter->name);835836return -EPERM;837}838839/* Q management */840/**841* Configure and enable a queue ring842*/843int al_eth_queue_config(struct al_hal_eth_adapter *adapter, enum al_udma_type type, uint32_t qid,844struct al_udma_q_params *q_params)845{846struct al_udma *udma;847int rc;848849al_dbg("eth [%s]: config UDMA %s queue %d\n", adapter->name,850type == UDMA_TX ? "Tx" : "Rx", qid);851852if (type == UDMA_TX) {853udma = &adapter->tx_udma;854} else {855udma = &adapter->rx_udma;856}857858q_params->adapter_rev_id = adapter->rev_id;859860rc = al_udma_q_init(udma, qid, q_params);861862if (rc)863return rc;864865if (type == UDMA_RX) {866rc = al_udma_s2m_q_compl_coal_config(&udma->udma_q[qid],867AL_TRUE, AL_ETH_S2M_UDMA_COMP_COAL_TIMEOUT);868869al_assert(q_params->cdesc_size <= 32);870871if (q_params->cdesc_size > 16)872al_reg_write32_masked(&adapter->ec_regs_base->rfw.out_cfg,873EC_RFW_OUT_CFG_META_CNT_MASK, 2);874}875return rc;876}877878int al_eth_queue_enable(struct al_hal_eth_adapter *adapter __attribute__((__unused__)),879enum al_udma_type type __attribute__((__unused__)),880uint32_t qid __attribute__((__unused__)))881{882return -EPERM;883}884int al_eth_queue_disable(struct al_hal_eth_adapter *adapter __attribute__((__unused__)),885enum al_udma_type type __attribute__((__unused__)),886uint32_t qid __attribute__((__unused__)))887{888return -EPERM;889}890891/* MAC layer */892int al_eth_rx_pkt_limit_config(struct al_hal_eth_adapter *adapter, uint32_t min_rx_len, uint32_t max_rx_len)893{894al_assert(max_rx_len <= AL_ETH_MAX_FRAME_LEN);895896/* EC minimum packet length [bytes] in RX */897al_reg_write32(&adapter->ec_regs_base->mac.min_pkt, min_rx_len);898/* EC maximum packet length [bytes] in RX */899al_reg_write32(&adapter->ec_regs_base->mac.max_pkt, max_rx_len);900901if (adapter->rev_id > AL_ETH_REV_ID_2) {902al_reg_write32(&adapter->mac_regs_base->gen_v3.rx_afifo_cfg_1, min_rx_len);903al_reg_write32(&adapter->mac_regs_base->gen_v3.rx_afifo_cfg_2, max_rx_len);904}905906/* configure the MAC's max rx length, add 16 bytes so the packet get907* trimmed by the EC/Async_fifo rather by the MAC908*/909if (AL_ETH_IS_1G_MAC(adapter->mac_mode))910al_reg_write32(&adapter->mac_regs_base->mac_1g.frm_len, max_rx_len + 16);911else if (AL_ETH_IS_10G_MAC(adapter->mac_mode) || AL_ETH_IS_25G_MAC(adapter->mac_mode))912/* 10G MAC control register */913al_reg_write32(&adapter->mac_regs_base->mac_10g.frm_len, (max_rx_len + 16));914else915al_eth_40g_mac_reg_write(adapter, ETH_MAC_GEN_V3_MAC_40G_FRM_LENGTH_ADDR, (max_rx_len + 16));916917return 0;918}919920/* configure the mac media type. */921int al_eth_mac_config(struct al_hal_eth_adapter *adapter, enum al_eth_mac_mode mode)922{923switch(mode) {924case AL_ETH_MAC_MODE_RGMII:925al_reg_write32(&adapter->mac_regs_base->gen.clk_cfg, 0x40003210);926927/* 1G MAC control register */928/* bit[0] - TX_ENA - zeroed by default. Should be asserted by al_eth_mac_start929* bit[1] - RX_ENA - zeroed by default. Should be asserted by al_eth_mac_start930* bit[3] - ETH_SPEED - zeroed to enable 10/100 Mbps Ethernet931* bit[4] - PROMIS_EN - asserted to enable MAC promiscuous mode932* bit[23] - CNTL_FRM-ENA - asserted to enable control frames933* bit[24] - NO_LGTH_CHECK - asserted to disable length checks, which is done in the controller934*/935al_reg_write32(&adapter->mac_regs_base->mac_1g.cmd_cfg, 0x01800010);936937/* RX_SECTION_EMPTY, */938al_reg_write32(&adapter->mac_regs_base->mac_1g.rx_section_empty, 0x00000000);939/* RX_SECTION_FULL, */940al_reg_write32(&adapter->mac_regs_base->mac_1g.rx_section_full, 0x0000000c); /* must be larger than almost empty */941/* RX_ALMOST_EMPTY, */942al_reg_write32(&adapter->mac_regs_base->mac_1g.rx_almost_empty, 0x00000008);943/* RX_ALMOST_FULL, */944al_reg_write32(&adapter->mac_regs_base->mac_1g.rx_almost_full, 0x00000008);945946947/* TX_SECTION_EMPTY, */948al_reg_write32(&adapter->mac_regs_base->mac_1g.tx_section_empty, 0x00000008); /* 8 ? */949/* TX_SECTION_FULL, 0 - store and forward, */950al_reg_write32(&adapter->mac_regs_base->mac_1g.tx_section_full, 0x0000000c);951/* TX_ALMOST_EMPTY, */952al_reg_write32(&adapter->mac_regs_base->mac_1g.tx_almost_empty, 0x00000008);953/* TX_ALMOST_FULL, */954al_reg_write32(&adapter->mac_regs_base->mac_1g.tx_almost_full, 0x00000008);955956/* XAUI MAC control register */957al_reg_write32(&adapter->mac_regs_base->gen.cfg, 0x00000000);958959/* 1G MACSET 1G */960/* taking sel_1000/sel_10 inputs from rgmii PHY, and not from register.961* disabling magic_packets detection in mac */962al_reg_write32(&adapter->mac_regs_base->gen.mac_1g_cfg, 0x00000002);963/* RGMII set 1G */964al_reg_write32_masked(&adapter->mac_regs_base->gen.mux_sel, ~ETH_MAC_GEN_MUX_SEL_KR_IN_MASK, 0x00063910);965al_reg_write32(&adapter->mac_regs_base->gen.rgmii_sel, 0xF);966break;967case AL_ETH_MAC_MODE_SGMII:968if (adapter->rev_id > AL_ETH_REV_ID_2) {969/* configure and enable the ASYNC FIFO between the MACs and the EC */970/* TX min packet size */971al_reg_write32(&adapter->mac_regs_base->gen_v3.tx_afifo_cfg_1, 0x00000010);972/* TX max packet size */973al_reg_write32(&adapter->mac_regs_base->gen_v3.tx_afifo_cfg_2, 0x00002800);974/* TX input bus configuration */975al_reg_write32(&adapter->mac_regs_base->gen_v3.tx_afifo_cfg_3, 0x00000080);976/* TX output bus configuration */977al_reg_write32(&adapter->mac_regs_base->gen_v3.tx_afifo_cfg_4, 0x00030020);978/* TX Valid/ready configuration */979al_reg_write32(&adapter->mac_regs_base->gen_v3.tx_afifo_cfg_5, 0x00000121);980/* RX min packet size */981/* al_reg_write32(&adapter->mac_regs_base->gen_v3.rx_afifo_cfg_1, 0x00000040); */982/* RX max packet size */983/* al_reg_write32(&adapter->mac_regs_base->gen_v3.rx_afifo_cfg_2, 0x00002800); */984/* RX input bus configuration */985al_reg_write32(&adapter->mac_regs_base->gen_v3.rx_afifo_cfg_3, 0x00030020);986/* RX output bus configuration */987al_reg_write32(&adapter->mac_regs_base->gen_v3.rx_afifo_cfg_4, 0x00000080);988/* RX Valid/ready configuration */989al_reg_write32(&adapter->mac_regs_base->gen_v3.rx_afifo_cfg_5, 0x00000212);990/* V3 additional MAC selection */991al_reg_write32(&adapter->mac_regs_base->gen_v3.mac_sel, 0x00000000);992al_reg_write32(&adapter->mac_regs_base->gen_v3.mac_10g_ll_cfg, 0x00000001);993al_reg_write32(&adapter->mac_regs_base->gen_v3.mac_10g_ll_ctrl, 0x00000000);994al_reg_write32(&adapter->mac_regs_base->gen_v3.pcs_10g_ll_cfg, 0x00000000);995/* ASYNC FIFO ENABLE */996al_reg_write32(&adapter->mac_regs_base->gen_v3.afifo_ctrl, 0x00003333);997/* Timestamp_configuration */998al_reg_write32(&adapter->mac_regs_base->gen_v3.spare,999ETH_MAC_GEN_V3_SPARE_CHICKEN_DISABLE_TIMESTAMP_STRETCH);1000}10011002al_reg_write32(&adapter->mac_regs_base->gen.clk_cfg, 0x40053210);10031004/* 1G MAC control register */1005/* bit[0] - TX_ENA - zeroed by default. Should be asserted by al_eth_mac_start1006* bit[1] - RX_ENA - zeroed by default. Should be asserted by al_eth_mac_start1007* bit[3] - ETH_SPEED - zeroed to enable 10/100 Mbps Ethernet1008* bit[4] - PROMIS_EN - asserted to enable MAC promiscuous mode1009* bit[23] - CNTL_FRM-ENA - asserted to enable control frames1010* bit[24] - NO_LGTH_CHECK - asserted to disable length checks, which is done in the controller1011*/1012al_reg_write32(&adapter->mac_regs_base->mac_1g.cmd_cfg, 0x01800010);10131014/* RX_SECTION_EMPTY, */1015al_reg_write32(&adapter->mac_regs_base->mac_1g.rx_section_empty, 0x00000000);1016/* RX_SECTION_FULL, */1017al_reg_write32(&adapter->mac_regs_base->mac_1g.rx_section_full, 0x0000000c); /* must be larger than almost empty */1018/* RX_ALMOST_EMPTY, */1019al_reg_write32(&adapter->mac_regs_base->mac_1g.rx_almost_empty, 0x00000008);1020/* RX_ALMOST_FULL, */1021al_reg_write32(&adapter->mac_regs_base->mac_1g.rx_almost_full, 0x00000008);102210231024/* TX_SECTION_EMPTY, */1025al_reg_write32(&adapter->mac_regs_base->mac_1g.tx_section_empty, 0x00000008); /* 8 ? */1026/* TX_SECTION_FULL, 0 - store and forward, */1027al_reg_write32(&adapter->mac_regs_base->mac_1g.tx_section_full, 0x0000000c);1028/* TX_ALMOST_EMPTY, */1029al_reg_write32(&adapter->mac_regs_base->mac_1g.tx_almost_empty, 0x00000008);1030/* TX_ALMOST_FULL, */1031al_reg_write32(&adapter->mac_regs_base->mac_1g.tx_almost_full, 0x00000008);10321033/* XAUI MAC control register */1034al_reg_write32(&adapter->mac_regs_base->gen.cfg, 0x000000c0);10351036/* 1G MACSET 1G */1037/* taking sel_1000/sel_10 inputs from rgmii_converter, and not from register.1038* disabling magic_packets detection in mac */1039al_reg_write32(&adapter->mac_regs_base->gen.mac_1g_cfg, 0x00000002);1040/* SerDes configuration */1041al_reg_write32_masked(&adapter->mac_regs_base->gen.mux_sel, ~ETH_MAC_GEN_MUX_SEL_KR_IN_MASK, 0x00063910);1042al_reg_write32(&adapter->mac_regs_base->gen.sd_fifo_ctrl, 0x000004f0);1043al_reg_write32(&adapter->mac_regs_base->gen.sd_fifo_ctrl, 0x00000401);10441045// FAST AN -- Testing only1046#ifdef AL_HAL_ETH_FAST_AN1047al_reg_write32(&adapter->mac_regs_base->sgmii.reg_addr, 0x00000012);1048al_reg_write32(&adapter->mac_regs_base->sgmii.reg_data, 0x00000040);1049al_reg_write32(&adapter->mac_regs_base->sgmii.reg_addr, 0x00000013);1050al_reg_write32(&adapter->mac_regs_base->sgmii.reg_data, 0x00000000);1051#endif10521053/* Setting PCS i/f mode to SGMII (instead of default 1000Base-X) */1054al_reg_write32(&adapter->mac_regs_base->sgmii.reg_addr, 0x00000014);1055al_reg_write32(&adapter->mac_regs_base->sgmii.reg_data, 0x0000000b);1056/* setting dev_ability to have speed of 1000Mb, [11:10] = 2'b10 */1057al_reg_write32(&adapter->mac_regs_base->sgmii.reg_addr, 0x00000004);1058al_reg_write32(&adapter->mac_regs_base->sgmii.reg_data, 0x000009A0);1059al_reg_write32_masked(&adapter->mac_regs_base->gen.led_cfg,1060ETH_MAC_GEN_LED_CFG_SEL_MASK,1061ETH_MAC_GEN_LED_CFG_SEL_DEFAULT_REG);1062break;10631064case AL_ETH_MAC_MODE_SGMII_2_5G:1065if (adapter->rev_id > AL_ETH_REV_ID_2) {1066/* configure and enable the ASYNC FIFO between the MACs and the EC */1067/* TX min packet size */1068al_reg_write32(&adapter->mac_regs_base->gen_v3.tx_afifo_cfg_1, 0x00000010);1069/* TX max packet size */1070al_reg_write32(&adapter->mac_regs_base->gen_v3.tx_afifo_cfg_2, 0x00002800);1071/* TX input bus configuration */1072al_reg_write32(&adapter->mac_regs_base->gen_v3.tx_afifo_cfg_3, 0x00000080);1073/* TX output bus configuration */1074al_reg_write32(&adapter->mac_regs_base->gen_v3.tx_afifo_cfg_4, 0x00030020);1075/* TX Valid/ready configuration */1076al_reg_write32(&adapter->mac_regs_base->gen_v3.tx_afifo_cfg_5, 0x00000023);1077/* RX input bus configuration */1078al_reg_write32(&adapter->mac_regs_base->gen_v3.rx_afifo_cfg_3, 0x00030020);1079/* RX output bus configuration */1080al_reg_write32(&adapter->mac_regs_base->gen_v3.rx_afifo_cfg_4, 0x00000080);1081/* RX Valid/ready configuration */1082al_reg_write32(&adapter->mac_regs_base->gen_v3.rx_afifo_cfg_5, 0x00000012);1083/* V3 additional MAC selection */1084al_reg_write32(&adapter->mac_regs_base->gen_v3.mac_sel, 0x00000000);1085al_reg_write32(&adapter->mac_regs_base->gen_v3.mac_10g_ll_cfg, 0x00000000);1086al_reg_write32(&adapter->mac_regs_base->gen_v3.mac_10g_ll_ctrl, 0x00000000);1087al_reg_write32(&adapter->mac_regs_base->gen_v3.pcs_10g_ll_cfg, 0x00000050);1088/* ASYNC FIFO ENABLE */1089al_reg_write32(&adapter->mac_regs_base->gen_v3.afifo_ctrl, 0x00003333);1090}10911092/* MAC register file */1093al_reg_write32(&adapter->mac_regs_base->mac_10g.cmd_cfg, 0x01022830);1094/* XAUI MAC control register */1095al_reg_write32(&adapter->mac_regs_base->gen.cfg, 0x00000001);1096al_reg_write32(&adapter->mac_regs_base->mac_10g.if_mode, 0x00000028);1097al_reg_write32(&adapter->mac_regs_base->mac_10g.control, 0x00001140);1098/* RXAUI MAC control register */1099al_reg_write32(&adapter->mac_regs_base->gen.xgmii_dfifo_32_64, 0x00000401);1100/* al_reg_write32(&adapter->mac_regs_base->gen.mac_res_1_out, 0x00000401); */1101al_reg_write32(&adapter->mac_regs_base->gen.xgmii_dfifo_64_32, 0x00000401);1102/* al_reg_write32(&adapter->mac_regs_base->gen.mac_res_1_in, 0x00000401); */1103al_reg_write32_masked(&adapter->mac_regs_base->gen.mux_sel,1104~ETH_MAC_GEN_MUX_SEL_KR_IN_MASK, 0x00063910);1105al_reg_write32(&adapter->mac_regs_base->gen.clk_cfg, 0x40003210);1106al_reg_write32(&adapter->mac_regs_base->gen.sd_fifo_ctrl, 0x000004f0);1107al_reg_write32(&adapter->mac_regs_base->gen.sd_fifo_ctrl, 0x00000401);11081109al_reg_write32_masked(&adapter->mac_regs_base->gen.led_cfg,1110ETH_MAC_GEN_LED_CFG_SEL_MASK,1111ETH_MAC_GEN_LED_CFG_SEL_DEFAULT_REG);1112break;11131114case AL_ETH_MAC_MODE_10GbE_Serial:1115if (adapter->rev_id > AL_ETH_REV_ID_2) {1116/* configure and enable the ASYNC FIFO between the MACs and the EC */1117/* TX min packet size */1118al_reg_write32(&adapter->mac_regs_base->gen_v3.tx_afifo_cfg_1, 0x00000010);1119/* TX max packet size */1120al_reg_write32(&adapter->mac_regs_base->gen_v3.tx_afifo_cfg_2, 0x00002800);1121/* TX input bus configuration */1122al_reg_write32(&adapter->mac_regs_base->gen_v3.tx_afifo_cfg_3, 0x00000080);1123/* TX output bus configuration */1124al_reg_write32(&adapter->mac_regs_base->gen_v3.tx_afifo_cfg_4, 0x00030020);1125/* TX Valid/ready configuration */1126al_reg_write32(&adapter->mac_regs_base->gen_v3.tx_afifo_cfg_5, 0x00000023);1127/* RX min packet size */1128/* al_reg_write32(&adapter->mac_regs_base->gen_v3.rx_afifo_cfg_1, 0x00000040); */1129/* RX max packet size */1130/* al_reg_write32(&adapter->mac_regs_base->gen_v3.rx_afifo_cfg_2, 0x00002800); */1131/* RX input bus configuration */1132al_reg_write32(&adapter->mac_regs_base->gen_v3.rx_afifo_cfg_3, 0x00030020);1133/* RX output bus configuration */1134al_reg_write32(&adapter->mac_regs_base->gen_v3.rx_afifo_cfg_4, 0x00000080);1135/* RX Valid/ready configuration */1136al_reg_write32(&adapter->mac_regs_base->gen_v3.rx_afifo_cfg_5, 0x00000012);1137/* V3 additional MAC selection */1138al_reg_write32(&adapter->mac_regs_base->gen_v3.mac_sel, 0x00000000);1139al_reg_write32(&adapter->mac_regs_base->gen_v3.mac_10g_ll_cfg, 0x00000000);1140al_reg_write32(&adapter->mac_regs_base->gen_v3.mac_10g_ll_ctrl, 0x00000000);1141al_reg_write32(&adapter->mac_regs_base->gen_v3.pcs_10g_ll_cfg, 0x00000050);1142/* ASYNC FIFO ENABLE */1143al_reg_write32(&adapter->mac_regs_base->gen_v3.afifo_ctrl, 0x00003333);1144}11451146/* MAC register file */1147al_reg_write32(&adapter->mac_regs_base->mac_10g.cmd_cfg, 0x01022810);1148/* XAUI MAC control register */1149al_reg_write32(&adapter->mac_regs_base->gen.cfg, 0x00000005);1150/* RXAUI MAC control register */1151al_reg_write32(&adapter->mac_regs_base->gen.rxaui_cfg, 0x00000007);1152al_reg_write32(&adapter->mac_regs_base->gen.sd_cfg, 0x000001F1);1153al_reg_write32(&adapter->mac_regs_base->gen.xgmii_dfifo_32_64, 0x00000401);1154/* al_reg_write32(&adapter->mac_regs_base->gen.mac_res_1_out, 0x00000401); */1155al_reg_write32(&adapter->mac_regs_base->gen.xgmii_dfifo_64_32, 0x00000401);1156/* al_reg_write32(&adapter->mac_regs_base->gen.mac_res_1_in, 0x00000401); */1157al_reg_write32_masked(&adapter->mac_regs_base->gen.mux_sel,1158~ETH_MAC_GEN_MUX_SEL_KR_IN_MASK, 0x00073910);1159al_reg_write32(&adapter->mac_regs_base->gen.clk_cfg, 0x10003210);1160al_reg_write32(&adapter->mac_regs_base->gen.sd_fifo_ctrl, 0x000004f0);1161al_reg_write32(&adapter->mac_regs_base->gen.sd_fifo_ctrl, 0x00000401);11621163al_reg_write32_masked(&adapter->mac_regs_base->gen.led_cfg,1164ETH_MAC_GEN_LED_CFG_SEL_MASK,1165ETH_MAC_GEN_LED_CFG_SEL_DEFAULT_REG);1166break;11671168case AL_ETH_MAC_MODE_KR_LL_25G:1169/* select 25G SERDES lane 0 and lane 1 */1170al_reg_write32(&adapter->mac_regs_base->gen_v3.ext_serdes_ctrl, 0x0002110f);11711172if (adapter->rev_id > AL_ETH_REV_ID_2) {1173/* configure and enable the ASYNC FIFO between the MACs and the EC */1174/* TX min packet size */1175al_reg_write32(&adapter->mac_regs_base->gen_v3.tx_afifo_cfg_1, 0x00000010);1176/* TX max packet size */1177al_reg_write32(&adapter->mac_regs_base->gen_v3.tx_afifo_cfg_2, 0x00002800);1178/* TX input bus configuration */1179al_reg_write32(&adapter->mac_regs_base->gen_v3.tx_afifo_cfg_3, 0x00000080);1180/* TX output bus configuration */1181al_reg_write32(&adapter->mac_regs_base->gen_v3.tx_afifo_cfg_4, 0x00030020);1182/* TX Valid/ready configuration */1183al_reg_write32(&adapter->mac_regs_base->gen_v3.tx_afifo_cfg_5, 0x00000023);1184/* RX min packet size */1185/* al_reg_write32(&adapter->mac_regs_base->gen_v3.rx_afifo_cfg_1, 0x00000040); */1186/* RX max packet size */1187/* al_reg_write32(&adapter->mac_regs_base->gen_v3.rx_afifo_cfg_2, 0x00002800); */1188/* RX input bus configuration */1189al_reg_write32(&adapter->mac_regs_base->gen_v3.rx_afifo_cfg_3, 0x00030020);1190/* RX output bus configuration */1191al_reg_write32(&adapter->mac_regs_base->gen_v3.rx_afifo_cfg_4, 0x00000080);1192/* RX Valid/ready configuration */1193al_reg_write32(&adapter->mac_regs_base->gen_v3.rx_afifo_cfg_5, 0x00000012);1194/* V3 additional MAC selection */1195al_reg_write32(&adapter->mac_regs_base->gen_v3.mac_sel, 0x00000000);1196al_reg_write32(&adapter->mac_regs_base->gen_v3.mac_10g_ll_cfg, 0x00000000);1197al_reg_write32(&adapter->mac_regs_base->gen_v3.mac_10g_ll_ctrl, 0x00000000);1198al_reg_write32(&adapter->mac_regs_base->gen_v3.pcs_10g_ll_cfg, 0x000000a0);1199/* ASYNC FIFO ENABLE */1200al_reg_write32(&adapter->mac_regs_base->gen_v3.afifo_ctrl, 0x00003333);1201}12021203/* MAC register file */1204al_reg_write32(&adapter->mac_regs_base->mac_10g.cmd_cfg, 0x01022810);1205/* XAUI MAC control register */1206al_reg_write32(&adapter->mac_regs_base->gen.cfg, 0x00000005);1207/* RXAUI MAC control register */1208al_reg_write32(&adapter->mac_regs_base->gen.rxaui_cfg, 0x00000007);1209al_reg_write32(&adapter->mac_regs_base->gen.sd_cfg, 0x000001F1);1210al_reg_write32(&adapter->mac_regs_base->gen.xgmii_dfifo_32_64, 0x00000401);1211/* al_reg_write32(&adapter->mac_regs_base->gen.mac_res_1_out, 0x00000401); */1212al_reg_write32(&adapter->mac_regs_base->gen.xgmii_dfifo_64_32, 0x00000401);1213/* al_reg_write32(&adapter->mac_regs_base->gen.mac_res_1_in, 0x00000401); */12141215if (adapter->serdes_lane == 0)1216al_reg_write32_masked(&adapter->mac_regs_base->gen.mux_sel,1217~ETH_MAC_GEN_MUX_SEL_KR_IN_MASK, 0x00073910);1218else1219al_reg_write32(&adapter->mac_regs_base->gen.mux_sel, 0x00077910);12201221if (adapter->serdes_lane == 0)1222al_reg_write32(&adapter->mac_regs_base->gen.clk_cfg, 0x10003210);1223else1224al_reg_write32(&adapter->mac_regs_base->gen.clk_cfg, 0x10000101);12251226al_reg_write32(&adapter->mac_regs_base->gen.sd_fifo_ctrl, 0x000004f0);1227al_reg_write32(&adapter->mac_regs_base->gen.sd_fifo_ctrl, 0x00000401);12281229al_reg_write32_masked(&adapter->mac_regs_base->gen.led_cfg,1230ETH_MAC_GEN_LED_CFG_SEL_MASK,1231ETH_MAC_GEN_LED_CFG_SEL_DEFAULT_REG);12321233if (adapter->serdes_lane == 1)1234al_reg_write32(&adapter->mac_regs_base->gen.los_sel, 0x101);123512361237break;12381239case AL_ETH_MAC_MODE_10G_SGMII:1240/* MAC register file */1241al_reg_write32(&adapter->mac_regs_base->mac_10g.cmd_cfg, 0x01022810);12421243/* XAUI MAC control register */1244al_reg_write32(&adapter->mac_regs_base->gen.cfg, 0x00000001);12451246al_reg_write32(&adapter->mac_regs_base->mac_10g.if_mode, 0x0000002b);1247al_reg_write32(&adapter->mac_regs_base->mac_10g.control, 0x00009140);1248// FAST AN -- Testing only1249#ifdef AL_HAL_ETH_FAST_AN1250al_reg_write32(&adapter->mac_regs_base->mac_10g.link_timer_lo, 0x00000040);1251al_reg_write32(&adapter->mac_regs_base->mac_10g.link_timer_hi, 0x00000000);1252#endif12531254/* RXAUI MAC control register */1255al_reg_write32(&adapter->mac_regs_base->gen.rxaui_cfg, 0x00000007);1256al_reg_write32(&adapter->mac_regs_base->gen.xgmii_dfifo_32_64, 0x00000401);1257/* al_reg_write32(&adapter->mac_regs_base->gen.mac_res_1_out, 0x00000401); */1258al_reg_write32(&adapter->mac_regs_base->gen.xgmii_dfifo_64_32, 0x00000401);1259/* al_reg_write32(&adapter->mac_regs_base->gen.mac_res_1_in, 0x00000401); */1260al_reg_write32_masked(&adapter->mac_regs_base->gen.mux_sel,1261~ETH_MAC_GEN_MUX_SEL_KR_IN_MASK, 0x00063910);1262al_reg_write32(&adapter->mac_regs_base->gen.clk_cfg, 0x40003210);1263al_reg_write32(&adapter->mac_regs_base->gen.sd_fifo_ctrl, 0x00000401);12641265al_reg_write32_masked(&adapter->mac_regs_base->gen.led_cfg,1266ETH_MAC_GEN_LED_CFG_SEL_MASK,1267ETH_MAC_GEN_LED_CFG_SEL_DEFAULT_REG);1268break;12691270case AL_ETH_MAC_MODE_XLG_LL_40G:1271/* configure and enable the ASYNC FIFO between the MACs and the EC */1272/* TX min packet size */1273al_reg_write32(&adapter->mac_regs_base->gen_v3.tx_afifo_cfg_1, 0x00000010);1274/* TX max packet size */1275al_reg_write32(&adapter->mac_regs_base->gen_v3.tx_afifo_cfg_2, 0x00002800);1276/* TX input bus configuration */1277al_reg_write32(&adapter->mac_regs_base->gen_v3.tx_afifo_cfg_3, 0x00000080);1278/* TX output bus configuration */1279al_reg_write32(&adapter->mac_regs_base->gen_v3.tx_afifo_cfg_4, 0x00010040);1280/* TX Valid/ready configuration */1281al_reg_write32(&adapter->mac_regs_base->gen_v3.tx_afifo_cfg_5, 0x00000023);1282/* RX min packet size */1283/* al_reg_write32(&adapter->mac_regs_base->gen_v3.rx_afifo_cfg_1, 0x00000040); */1284/* RX max packet size */1285/* al_reg_write32(&adapter->mac_regs_base->gen_v3.rx_afifo_cfg_2, 0x00002800); */1286/* RX input bus configuration */1287al_reg_write32(&adapter->mac_regs_base->gen_v3.rx_afifo_cfg_3, 0x00010040);1288/* RX output bus configuration */1289al_reg_write32(&adapter->mac_regs_base->gen_v3.rx_afifo_cfg_4, 0x00000080);1290/* RX Valid/ready configuration */1291al_reg_write32(&adapter->mac_regs_base->gen_v3.rx_afifo_cfg_5, 0x00000112);1292/* V3 additional MAC selection */1293al_reg_write32(&adapter->mac_regs_base->gen_v3.mac_sel, 0x00000010);1294al_reg_write32(&adapter->mac_regs_base->gen_v3.mac_10g_ll_cfg, 0x00000000);1295al_reg_write32(&adapter->mac_regs_base->gen_v3.mac_10g_ll_ctrl, 0x00000000);1296al_reg_write32(&adapter->mac_regs_base->gen_v3.pcs_10g_ll_cfg, 0x00000000);1297/* ASYNC FIFO ENABLE */1298al_reg_write32(&adapter->mac_regs_base->gen_v3.afifo_ctrl, 0x00003333);12991300/* cmd_cfg */1301al_reg_write32(&adapter->mac_regs_base->gen_v3.mac_40g_ll_addr, 0x00000008);1302al_reg_write32(&adapter->mac_regs_base->gen_v3.mac_40g_ll_data, 0x01022810);1303/* speed_ability //Read-Only */1304/* al_reg_write32(&adapter->mac_regs_base->gen_v3.pcs_40g_ll_addr, 0x00000008); */1305/* 40G capable */1306/* al_reg_write32(&adapter->mac_regs_base->gen_v3.pcs_40g_ll_data, 0x00000002); */13071308#ifdef AL_HAL_ETH_FAST_AN1309al_eth_40g_pcs_reg_write(adapter, 0x00010004, 1023);1310al_eth_40g_pcs_reg_write(adapter, 0x00000000, 0xA04c);1311al_eth_40g_pcs_reg_write(adapter, 0x00000000, 0x204c);13121313#endif13141315/* XAUI MAC control register */1316al_reg_write32_masked(&adapter->mac_regs_base->gen.mux_sel,1317~ETH_MAC_GEN_MUX_SEL_KR_IN_MASK, 0x06883910);1318al_reg_write32(&adapter->mac_regs_base->gen.sd_fifo_ctrl, 0x0000040f);13191320/* MAC register file */1321/* al_reg_write32(&adapter->mac_regs_base->mac_10g.cmd_cfg, 0x01022810); */1322/* XAUI MAC control register */1323al_reg_write32(&adapter->mac_regs_base->gen.cfg, 0x00000005);1324/* RXAUI MAC control register */1325al_reg_write32(&adapter->mac_regs_base->gen.rxaui_cfg, 0x00000007);1326al_reg_write32(&adapter->mac_regs_base->gen.sd_cfg, 0x000001F1);1327al_reg_write32(&adapter->mac_regs_base->gen.xgmii_dfifo_32_64, 0x00000401);1328/* al_reg_write32(&adapter->mac_regs_base->gen.mac_res_1_out, 0x00000401); */1329al_reg_write32(&adapter->mac_regs_base->gen.xgmii_dfifo_64_32, 0x00000401);1330/* al_reg_write32(&adapter->mac_regs_base->gen.mac_res_1_in, 0x00000401); */1331/* al_reg_write32_masked(&adapter->mac_regs_base->gen.mux_sel, ~ETH_MAC_GEN_MUX_SEL_KR_IN_MASK, 0x00073910); *//* XLG_LL_40G change */1332al_reg_write32(&adapter->mac_regs_base->gen.clk_cfg, 0x10003210);1333/* al_reg_write32(&adapter->mac_regs_base->gen.sd_fifo_ctrl, 0x000004f0); *//* XLG_LL_40G change */1334/* al_reg_write32(&adapter->mac_regs_base->gen.sd_fifo_ctrl, 0x00000401); *//* XLG_LL_40G change */13351336al_reg_write32_masked(&adapter->mac_regs_base->gen.led_cfg,1337ETH_MAC_GEN_LED_CFG_SEL_MASK,1338ETH_MAC_GEN_LED_CFG_SEL_DEFAULT_REG);1339break;13401341case AL_ETH_MAC_MODE_XLG_LL_25G:1342/* xgmii_mode: 0=xlgmii, 1=xgmii */1343al_reg_write32(&adapter->mac_regs_base->gen_v3.mac_40g_ll_addr, 0x0080);1344al_reg_write32(&adapter->mac_regs_base->gen_v3.mac_40g_ll_data, 0x00000001);13451346/* configure and enable the ASYNC FIFO between the MACs and the EC */1347/* TX min packet size */1348al_reg_write32(&adapter->mac_regs_base->gen_v3.tx_afifo_cfg_1, 0x00000010);1349/* TX max packet size */1350al_reg_write32(&adapter->mac_regs_base->gen_v3.tx_afifo_cfg_2, 0x00002800);1351/* TX input bus configuration */1352al_reg_write32(&adapter->mac_regs_base->gen_v3.tx_afifo_cfg_3, 0x00000080);1353/* TX output bus configuration */1354al_reg_write32(&adapter->mac_regs_base->gen_v3.tx_afifo_cfg_4, 0x00010040);1355/* TX Valid/ready configuration */1356al_reg_write32(&adapter->mac_regs_base->gen_v3.tx_afifo_cfg_5, 0x00000023);1357/* RX min packet size */1358/* al_reg_write32(&adapter->mac_regs_base->gen_v3.rx_afifo_cfg_1, 0x00000040); */1359/* RX max packet size */1360/* al_reg_write32(&adapter->mac_regs_base->gen_v3.rx_afifo_cfg_2, 0x00002800); */1361/* RX input bus configuration */1362al_reg_write32(&adapter->mac_regs_base->gen_v3.rx_afifo_cfg_3, 0x00010040);1363/* RX output bus configuration */1364al_reg_write32(&adapter->mac_regs_base->gen_v3.rx_afifo_cfg_4, 0x00000080);1365/* RX Valid/ready configuration */1366al_reg_write32(&adapter->mac_regs_base->gen_v3.rx_afifo_cfg_5, 0x00000112);1367/* V3 additional MAC selection */1368al_reg_write32(&adapter->mac_regs_base->gen_v3.mac_sel, 0x00000010);1369al_reg_write32(&adapter->mac_regs_base->gen_v3.mac_10g_ll_cfg, 0x00000000);1370al_reg_write32(&adapter->mac_regs_base->gen_v3.mac_10g_ll_ctrl, 0x00000000);1371al_reg_write32(&adapter->mac_regs_base->gen_v3.pcs_10g_ll_cfg, 0x00000000);1372/* ASYNC FIFO ENABLE */1373al_reg_write32(&adapter->mac_regs_base->gen_v3.afifo_ctrl, 0x00003333);13741375/* cmd_cfg */1376al_reg_write32(&adapter->mac_regs_base->gen_v3.mac_40g_ll_addr, 0x00000008);1377al_reg_write32(&adapter->mac_regs_base->gen_v3.mac_40g_ll_data, 0x01022810);1378/* speed_ability //Read-Only */1379/* al_reg_write32(&adapter->mac_regs_base->gen_v3.pcs_40g_ll_addr, 0x00000008); */1380/* 40G capable */1381/* al_reg_write32(&adapter->mac_regs_base->gen_v3.pcs_40g_ll_data, 0x00000002); */13821383/* select the 25G serdes for lanes 0/1 */1384al_reg_write32(&adapter->mac_regs_base->gen_v3.ext_serdes_ctrl, 0x0002110f);1385/* configure the PCS to work with 2 lanes */1386/* configure which two of the 4 PCS Lanes (VL) are combined to one RXLAUI lane */1387/* use VL 0-2 for RXLAUI lane 0, use VL 1-3 for RXLAUI lane 1 */1388al_eth_40g_pcs_reg_write(adapter, 0x00010008, 0x0d80);1389/* configure the PCS to work 32 bit interface */1390al_reg_write32(&adapter->mac_regs_base->gen_v3.pcs_40g_ll_cfg, 0x00440000);13911392/* disable MLD and move to clause 49 PCS: */1393al_reg_write32(&adapter->mac_regs_base->gen_v3.pcs_40g_ll_addr, 0xE);1394al_reg_write32(&adapter->mac_regs_base->gen_v3.pcs_40g_ll_data, 0);13951396#ifdef AL_HAL_ETH_FAST_AN1397al_eth_40g_pcs_reg_write(adapter, 0x00010004, 1023);1398al_eth_40g_pcs_reg_write(adapter, 0x00000000, 0xA04c);1399al_eth_40g_pcs_reg_write(adapter, 0x00000000, 0x204c);1400#endif14011402/* XAUI MAC control register */1403if (adapter->serdes_lane == 0)1404al_reg_write32_masked(&adapter->mac_regs_base->gen.mux_sel,1405~ETH_MAC_GEN_MUX_SEL_KR_IN_MASK, 0x06883910);1406else1407al_reg_write32(&adapter->mac_regs_base->gen.mux_sel, 0x06803950);14081409al_reg_write32(&adapter->mac_regs_base->gen.sd_fifo_ctrl, 0x0000040f);14101411/* XAUI MAC control register */1412al_reg_write32(&adapter->mac_regs_base->gen.cfg, 0x00000005);1413/* RXAUI MAC control register */1414al_reg_write32(&adapter->mac_regs_base->gen.rxaui_cfg, 0x00000007);1415al_reg_write32(&adapter->mac_regs_base->gen.sd_cfg, 0x000001F1);1416al_reg_write32(&adapter->mac_regs_base->gen.xgmii_dfifo_32_64, 0x00000401);1417al_reg_write32(&adapter->mac_regs_base->gen.xgmii_dfifo_64_32, 0x00000401);1418if (adapter->serdes_lane == 0)1419al_reg_write32(&adapter->mac_regs_base->gen.clk_cfg, 0x10003210);1420else1421al_reg_write32(&adapter->mac_regs_base->gen.clk_cfg, 0x10000101);14221423al_reg_write32_masked(&adapter->mac_regs_base->gen.led_cfg,1424ETH_MAC_GEN_LED_CFG_SEL_MASK,1425ETH_MAC_GEN_LED_CFG_SEL_DEFAULT_REG);14261427if (adapter->serdes_lane == 1)1428al_reg_write32(&adapter->mac_regs_base->gen.los_sel, 0x101);14291430break;14311432case AL_ETH_MAC_MODE_XLG_LL_50G:14331434/* configure and enable the ASYNC FIFO between the MACs and the EC */1435/* TX min packet size */1436al_reg_write32(&adapter->mac_regs_base->gen_v3.tx_afifo_cfg_1, 0x00000010);1437/* TX max packet size */1438al_reg_write32(&adapter->mac_regs_base->gen_v3.tx_afifo_cfg_2, 0x00002800);1439/* TX input bus configuration */1440al_reg_write32(&adapter->mac_regs_base->gen_v3.tx_afifo_cfg_3, 0x00000080);1441/* TX output bus configuration */1442al_reg_write32(&adapter->mac_regs_base->gen_v3.tx_afifo_cfg_4, 0x00010040);1443/* TX Valid/ready configuration */1444al_reg_write32(&adapter->mac_regs_base->gen_v3.tx_afifo_cfg_5, 0x00000023);1445/* RX min packet size */1446/* al_reg_write32(&adapter->mac_regs_base->gen_v3.rx_afifo_cfg_1, 0x00000040); */1447/* RX max packet size */1448/* al_reg_write32(&adapter->mac_regs_base->gen_v3.rx_afifo_cfg_2, 0x00002800); */1449/* RX input bus configuration */1450al_reg_write32(&adapter->mac_regs_base->gen_v3.rx_afifo_cfg_3, 0x00010040);1451/* RX output bus configuration */1452al_reg_write32(&adapter->mac_regs_base->gen_v3.rx_afifo_cfg_4, 0x00000080);1453/* RX Valid/ready configuration */1454al_reg_write32(&adapter->mac_regs_base->gen_v3.rx_afifo_cfg_5, 0x00000112);1455/* V3 additional MAC selection */1456al_reg_write32(&adapter->mac_regs_base->gen_v3.mac_sel, 0x00000010);1457al_reg_write32(&adapter->mac_regs_base->gen_v3.mac_10g_ll_cfg, 0x00000000);1458al_reg_write32(&adapter->mac_regs_base->gen_v3.mac_10g_ll_ctrl, 0x00000000);1459al_reg_write32(&adapter->mac_regs_base->gen_v3.pcs_10g_ll_cfg, 0x00000000);1460/* ASYNC FIFO ENABLE */1461al_reg_write32(&adapter->mac_regs_base->gen_v3.afifo_ctrl, 0x00003333);14621463/* cmd_cfg */1464al_reg_write32(&adapter->mac_regs_base->gen_v3.mac_40g_ll_addr, 0x00000008);1465al_reg_write32(&adapter->mac_regs_base->gen_v3.mac_40g_ll_data, 0x01022810);1466/* speed_ability //Read-Only */1467/* al_reg_write32(&adapter->mac_regs_base->gen_v3.pcs_40g_ll_addr, 0x00000008); */1468/* 40G capable */1469/* al_reg_write32(&adapter->mac_regs_base->gen_v3.pcs_40g_ll_data, 0x00000002); */14701471/* select the 25G serdes for lanes 0/1 */1472al_reg_write32(&adapter->mac_regs_base->gen_v3.ext_serdes_ctrl, 0x0382110F);1473/* configure the PCS to work with 2 lanes */1474/* configure which two of the 4 PCS Lanes (VL) are combined to one RXLAUI lane */1475/* use VL 0-2 for RXLAUI lane 0, use VL 1-3 for RXLAUI lane 1 */1476al_eth_40g_pcs_reg_write(adapter, 0x00010008, 0x0d81);1477/* configure the PCS to work 32 bit interface */1478al_reg_write32(&adapter->mac_regs_base->gen_v3.pcs_40g_ll_cfg, 0x00440000);147914801481#ifdef AL_HAL_ETH_FAST_AN1482al_eth_40g_pcs_reg_write(adapter, 0x00010004, 1023);1483al_eth_40g_pcs_reg_write(adapter, 0x00000000, 0xA04c);1484al_eth_40g_pcs_reg_write(adapter, 0x00000000, 0x204c);1485#endif14861487/* XAUI MAC control register */1488al_reg_write32_masked(&adapter->mac_regs_base->gen.mux_sel, ~ETH_MAC_GEN_MUX_SEL_KR_IN_MASK, 0x06883910);1489al_reg_write32(&adapter->mac_regs_base->gen.sd_fifo_ctrl, 0x0000040f);14901491/* MAC register file */1492/* al_reg_write32(&adapter->mac_regs_base->mac_10g.cmd_cfg, 0x01022810); */1493/* XAUI MAC control register */1494al_reg_write32(&adapter->mac_regs_base->gen.cfg, 0x00000005);1495/* RXAUI MAC control register */1496al_reg_write32(&adapter->mac_regs_base->gen.rxaui_cfg, 0x00000007);1497al_reg_write32(&adapter->mac_regs_base->gen.sd_cfg, 0x000001F1);1498al_reg_write32(&adapter->mac_regs_base->gen.xgmii_dfifo_32_64, 0x00000401);1499/* al_reg_write32(&adapter->mac_regs_base->gen.mac_res_1_out, 0x00000401); */1500al_reg_write32(&adapter->mac_regs_base->gen.xgmii_dfifo_64_32, 0x00000401);1501/* al_reg_write32(&adapter->mac_regs_base->gen.mac_res_1_in, 0x00000401); */1502/* al_reg_write32_masked(&adapter->mac_regs_base->gen.mux_sel, ~ETH_MAC_GEN_MUX_SEL_KR_IN_MASK, 0x00073910); *//* XLG_LL_40G change */1503al_reg_write32(&adapter->mac_regs_base->gen.clk_cfg, 0x10003210);1504/* al_reg_write32(&adapter->mac_regs_base->gen.sd_fifo_ctrl, 0x000004f0); *//* XLG_LL_40G change */1505/* al_reg_write32(&adapter->mac_regs_base->gen.sd_fifo_ctrl, 0x00000401); *//* XLG_LL_40G change */15061507al_reg_write32_masked(&adapter->mac_regs_base->gen.led_cfg,1508ETH_MAC_GEN_LED_CFG_SEL_MASK,1509ETH_MAC_GEN_LED_CFG_SEL_DEFAULT_REG);1510break;151115121513default:1514al_err("Eth: unsupported MAC mode %d", mode);1515return -EPERM;1516}1517adapter->mac_mode = mode;1518al_info("configured MAC to %s mode:\n", al_eth_mac_mode_str(mode));15191520return 0;1521}15221523/* start the mac */1524int al_eth_mac_start(struct al_hal_eth_adapter *adapter)1525{1526if (AL_ETH_IS_1G_MAC(adapter->mac_mode)) {1527/* 1G MAC control register */1528al_reg_write32_masked(&adapter->mac_regs_base->mac_1g.cmd_cfg,1529ETH_1G_MAC_CMD_CFG_TX_ENA | ETH_1G_MAC_CMD_CFG_RX_ENA,1530ETH_1G_MAC_CMD_CFG_TX_ENA | ETH_1G_MAC_CMD_CFG_RX_ENA);1531} else if (AL_ETH_IS_10G_MAC(adapter->mac_mode) || AL_ETH_IS_25G_MAC(adapter->mac_mode)) {1532/* 10G MAC control register */1533al_reg_write32_masked(&adapter->mac_regs_base->mac_10g.cmd_cfg,1534ETH_10G_MAC_CMD_CFG_TX_ENA | ETH_10G_MAC_CMD_CFG_RX_ENA,1535ETH_10G_MAC_CMD_CFG_TX_ENA | ETH_10G_MAC_CMD_CFG_RX_ENA);1536} else {1537uint32_t cmd_cfg;15381539cmd_cfg = al_eth_40g_mac_reg_read(adapter,1540ETH_MAC_GEN_V3_MAC_40G_COMMAND_CONFIG_ADDR);15411542cmd_cfg |= (ETH_MAC_GEN_V3_MAC_40G_COMMAND_CONFIG_TX_ENA |1543ETH_MAC_GEN_V3_MAC_40G_COMMAND_CONFIG_RX_ENA);15441545al_eth_40g_mac_reg_write(adapter,1546ETH_MAC_GEN_V3_MAC_40G_COMMAND_CONFIG_ADDR,1547cmd_cfg);1548}15491550return 0;1551}15521553/* stop the mac */1554int al_eth_mac_stop(struct al_hal_eth_adapter *adapter)1555{1556if (AL_ETH_IS_1G_MAC(adapter->mac_mode))1557/* 1G MAC control register */1558al_reg_write32_masked(&adapter->mac_regs_base->mac_1g.cmd_cfg,1559ETH_1G_MAC_CMD_CFG_TX_ENA | ETH_1G_MAC_CMD_CFG_RX_ENA,15600);1561else if (AL_ETH_IS_10G_MAC(adapter->mac_mode) || AL_ETH_IS_25G_MAC(adapter->mac_mode))1562/* 10G MAC control register */1563al_reg_write32_masked(&adapter->mac_regs_base->mac_10g.cmd_cfg,1564ETH_10G_MAC_CMD_CFG_TX_ENA | ETH_10G_MAC_CMD_CFG_RX_ENA,15650);1566else {1567uint32_t cmd_cfg;15681569cmd_cfg = al_eth_40g_mac_reg_read(adapter,1570ETH_MAC_GEN_V3_MAC_40G_COMMAND_CONFIG_ADDR);15711572cmd_cfg &= ~(ETH_MAC_GEN_V3_MAC_40G_COMMAND_CONFIG_TX_ENA |1573ETH_MAC_GEN_V3_MAC_40G_COMMAND_CONFIG_RX_ENA);15741575al_eth_40g_mac_reg_write(adapter,1576ETH_MAC_GEN_V3_MAC_40G_COMMAND_CONFIG_ADDR,1577cmd_cfg);1578}15791580return 0;1581}15821583void al_eth_gearbox_reset(struct al_hal_eth_adapter *adapter, al_bool tx_reset, al_bool rx_reset)1584{1585uint32_t reg, orig_val;15861587/* Gearbox is exist only from revision 3 */1588al_assert(adapter->rev_id > AL_ETH_REV_ID_2);15891590orig_val = al_reg_read32(&adapter->mac_regs_base->gen_v3.ext_serdes_ctrl);1591reg = orig_val;15921593if (tx_reset) {1594reg |= (ETH_MAC_GEN_V3_EXT_SERDES_CTRL_LANE_0_TX_25_GS_SW_RESET |1595ETH_MAC_GEN_V3_EXT_SERDES_CTRL_LANE_1_TX_25_GS_SW_RESET);1596}15971598if (rx_reset) {1599reg |= (ETH_MAC_GEN_V3_EXT_SERDES_CTRL_LANE_0_RX_25_GS_SW_RESET |1600ETH_MAC_GEN_V3_EXT_SERDES_CTRL_LANE_1_RX_25_GS_SW_RESET);1601}16021603al_dbg("%s: perform gearbox reset (Tx %d, Rx %d) \n", __func__, tx_reset, rx_reset);1604al_reg_write32(&adapter->mac_regs_base->gen_v3.ext_serdes_ctrl, reg);16051606al_udelay(10);16071608al_reg_write32(&adapter->mac_regs_base->gen_v3.ext_serdes_ctrl, orig_val);1609}16101611int al_eth_fec_enable(struct al_hal_eth_adapter *adapter, al_bool enable)1612{1613if (adapter->rev_id <= AL_ETH_REV_ID_2)1614return -1;16151616if (enable)1617al_reg_write32_masked(&adapter->mac_regs_base->gen_v3.pcs_10g_ll_cfg,1618(ETH_MAC_GEN_V3_PCS_10G_LL_CFG_FEC_EN_RX |1619ETH_MAC_GEN_V3_PCS_10G_LL_CFG_FEC_EN_TX),1620(ETH_MAC_GEN_V3_PCS_10G_LL_CFG_FEC_EN_RX |1621ETH_MAC_GEN_V3_PCS_10G_LL_CFG_FEC_EN_TX));1622else1623al_reg_write32_masked(&adapter->mac_regs_base->gen_v3.pcs_10g_ll_cfg,1624(ETH_MAC_GEN_V3_PCS_10G_LL_CFG_FEC_EN_RX |1625ETH_MAC_GEN_V3_PCS_10G_LL_CFG_FEC_EN_TX),16260);1627return 0;1628}16291630int al_eth_fec_stats_get(struct al_hal_eth_adapter *adapter,1631uint32_t *corrected, uint32_t *uncorrectable)1632{1633if (adapter->rev_id <= AL_ETH_REV_ID_2)1634return -1;16351636*corrected = al_reg_read32(&adapter->mac_regs_base->stat.v3_pcs_10g_ll_cerr);1637*uncorrectable = al_reg_read32(&adapter->mac_regs_base->stat.v3_pcs_10g_ll_ncerr);16381639return 0;1640}164116421643int al_eth_capabilities_get(struct al_hal_eth_adapter *adapter, struct al_eth_capabilities *caps)1644{1645al_assert(caps);16461647caps->speed_10_HD = AL_FALSE;1648caps->speed_10_FD = AL_FALSE;1649caps->speed_100_HD = AL_FALSE;1650caps->speed_100_FD = AL_FALSE;1651caps->speed_1000_HD = AL_FALSE;1652caps->speed_1000_FD = AL_FALSE;1653caps->speed_10000_HD = AL_FALSE;1654caps->speed_10000_FD = AL_FALSE;1655caps->pfc = AL_FALSE;1656caps->eee = AL_FALSE;16571658switch (adapter->mac_mode) {1659case AL_ETH_MAC_MODE_RGMII:1660case AL_ETH_MAC_MODE_SGMII:1661caps->speed_10_HD = AL_TRUE;1662caps->speed_10_FD = AL_TRUE;1663caps->speed_100_HD = AL_TRUE;1664caps->speed_100_FD = AL_TRUE;1665caps->speed_1000_FD = AL_TRUE;1666caps->eee = AL_TRUE;1667break;1668case AL_ETH_MAC_MODE_10GbE_Serial:1669caps->speed_10000_FD = AL_TRUE;1670caps->pfc = AL_TRUE;1671break;1672default:1673al_err("Eth: unsupported MAC mode %d", adapter->mac_mode);1674return -EPERM;1675}1676return 0;1677}16781679static void al_eth_mac_link_config_1g_mac(1680struct al_hal_eth_adapter *adapter,1681al_bool force_1000_base_x,1682al_bool an_enable,1683uint32_t speed,1684al_bool full_duplex)1685{1686uint32_t mac_ctrl;1687uint32_t sgmii_ctrl = 0;1688uint32_t sgmii_if_mode = 0;1689uint32_t rgmii_ctrl = 0;16901691mac_ctrl = al_reg_read32(&adapter->mac_regs_base->mac_1g.cmd_cfg);16921693if (adapter->mac_mode == AL_ETH_MAC_MODE_SGMII) {1694al_reg_write32(&adapter->mac_regs_base->sgmii.reg_addr,1695ETH_MAC_SGMII_REG_ADDR_CTRL_REG);1696sgmii_ctrl = al_reg_read32(&adapter->mac_regs_base->sgmii.reg_data);1697/*1698* in case bit 0 is off in sgmii_if_mode register all the other1699* bits are ignored.1700*/1701if (force_1000_base_x == AL_FALSE)1702sgmii_if_mode = ETH_MAC_SGMII_REG_DATA_IF_MODE_SGMII_EN;17031704if (an_enable == AL_TRUE) {1705sgmii_if_mode |= ETH_MAC_SGMII_REG_DATA_IF_MODE_SGMII_AN;1706sgmii_ctrl |= ETH_MAC_SGMII_REG_DATA_CTRL_AN_ENABLE;1707} else {1708sgmii_ctrl &= ~(ETH_MAC_SGMII_REG_DATA_CTRL_AN_ENABLE);1709}1710}17111712if (adapter->mac_mode == AL_ETH_MAC_MODE_RGMII) {1713/*1714* Use the speed provided by the MAC instead of the PHY1715*/1716rgmii_ctrl = al_reg_read32(&adapter->mac_regs_base->gen.rgmii_cfg);17171718AL_REG_MASK_CLEAR(rgmii_ctrl, ETH_MAC_GEN_RGMII_CFG_ENA_AUTO);1719AL_REG_MASK_CLEAR(rgmii_ctrl, ETH_MAC_GEN_RGMII_CFG_SET_1000_SEL);1720AL_REG_MASK_CLEAR(rgmii_ctrl, ETH_MAC_GEN_RGMII_CFG_SET_10_SEL);17211722al_reg_write32(&adapter->mac_regs_base->gen.rgmii_cfg, rgmii_ctrl);1723}17241725if (full_duplex == AL_TRUE) {1726AL_REG_MASK_CLEAR(mac_ctrl, ETH_1G_MAC_CMD_CFG_HD_EN);1727} else {1728AL_REG_MASK_SET(mac_ctrl, ETH_1G_MAC_CMD_CFG_HD_EN);1729sgmii_if_mode |= ETH_MAC_SGMII_REG_DATA_IF_MODE_SGMII_DUPLEX;1730}17311732if (speed == 1000) {1733AL_REG_MASK_SET(mac_ctrl, ETH_1G_MAC_CMD_CFG_1G_SPD);1734sgmii_if_mode |= ETH_MAC_SGMII_REG_DATA_IF_MODE_SGMII_SPEED_1000;1735} else {1736AL_REG_MASK_CLEAR(mac_ctrl, ETH_1G_MAC_CMD_CFG_1G_SPD);1737if (speed == 10) {1738AL_REG_MASK_SET(mac_ctrl, ETH_1G_MAC_CMD_CFG_10M_SPD);1739} else {1740sgmii_if_mode |= ETH_MAC_SGMII_REG_DATA_IF_MODE_SGMII_SPEED_100;1741AL_REG_MASK_CLEAR(mac_ctrl, ETH_1G_MAC_CMD_CFG_10M_SPD);1742}1743}17441745if (adapter->mac_mode == AL_ETH_MAC_MODE_SGMII) {1746al_reg_write32(&adapter->mac_regs_base->sgmii.reg_addr,1747ETH_MAC_SGMII_REG_ADDR_IF_MODE_REG);1748al_reg_write32(&adapter->mac_regs_base->sgmii.reg_data,1749sgmii_if_mode);17501751al_reg_write32(&adapter->mac_regs_base->sgmii.reg_addr,1752ETH_MAC_SGMII_REG_ADDR_CTRL_REG);1753al_reg_write32(&adapter->mac_regs_base->sgmii.reg_data,1754sgmii_ctrl);1755}17561757al_reg_write32(&adapter->mac_regs_base->mac_1g.cmd_cfg, mac_ctrl);1758}17591760static void al_eth_mac_link_config_10g_mac(1761struct al_hal_eth_adapter *adapter,1762al_bool force_1000_base_x,1763al_bool an_enable,1764uint32_t speed,1765al_bool full_duplex)1766{1767uint32_t if_mode;1768uint32_t val;17691770if_mode = al_reg_read32(&adapter->mac_regs_base->mac_10g.if_mode);17711772if (force_1000_base_x) {1773uint32_t control;17741775AL_REG_MASK_CLEAR(if_mode, ETH_10G_MAC_IF_MODE_SGMII_EN_MASK);17761777control = al_reg_read32(&adapter->mac_regs_base->mac_10g.control);17781779if (an_enable)1780AL_REG_MASK_SET(control, ETH_10G_MAC_CONTROL_AN_EN_MASK);1781else1782AL_REG_MASK_CLEAR(control, ETH_10G_MAC_CONTROL_AN_EN_MASK);17831784al_reg_write32(&adapter->mac_regs_base->mac_10g.control, control);17851786} else {1787AL_REG_MASK_SET(if_mode, ETH_10G_MAC_IF_MODE_SGMII_EN_MASK);1788if (an_enable) {1789AL_REG_MASK_SET(if_mode, ETH_10G_MAC_IF_MODE_SGMII_AN_MASK);1790} else {1791AL_REG_MASK_CLEAR(if_mode, ETH_10G_MAC_IF_MODE_SGMII_AN_MASK);17921793if (speed == 1000)1794val = ETH_10G_MAC_IF_MODE_SGMII_SPEED_1G;1795else if (speed == 100)1796val = ETH_10G_MAC_IF_MODE_SGMII_SPEED_100M;1797else1798val = ETH_10G_MAC_IF_MODE_SGMII_SPEED_10M;17991800AL_REG_FIELD_SET(if_mode,1801ETH_10G_MAC_IF_MODE_SGMII_SPEED_MASK,1802ETH_10G_MAC_IF_MODE_SGMII_SPEED_SHIFT,1803val);18041805AL_REG_FIELD_SET(if_mode,1806ETH_10G_MAC_IF_MODE_SGMII_DUPLEX_MASK,1807ETH_10G_MAC_IF_MODE_SGMII_DUPLEX_SHIFT,1808((full_duplex) ?1809ETH_10G_MAC_IF_MODE_SGMII_DUPLEX_FULL :1810ETH_10G_MAC_IF_MODE_SGMII_DUPLEX_HALF));1811}1812}18131814al_reg_write32(&adapter->mac_regs_base->mac_10g.if_mode, if_mode);1815}18161817/* update link speed and duplex mode */1818int al_eth_mac_link_config(struct al_hal_eth_adapter *adapter,1819al_bool force_1000_base_x,1820al_bool an_enable,1821uint32_t speed,1822al_bool full_duplex)1823{1824if ((!AL_ETH_IS_1G_MAC(adapter->mac_mode)) &&1825(adapter->mac_mode != AL_ETH_MAC_MODE_SGMII_2_5G)) {1826al_err("eth [%s]: this function not supported in this mac mode.\n",1827adapter->name);1828return -EINVAL;1829}18301831if ((adapter->mac_mode != AL_ETH_MAC_MODE_RGMII) && (an_enable)) {1832/*1833* an_enable is not relevant to RGMII mode.1834* in AN mode speed and duplex aren't relevant.1835*/1836al_info("eth [%s]: set auto negotiation to enable\n", adapter->name);1837} else {1838al_info("eth [%s]: set link speed to %dMbps. %s duplex.\n", adapter->name,1839speed, full_duplex == AL_TRUE ? "full" : "half");18401841if ((speed != 10) && (speed != 100) && (speed != 1000)) {1842al_err("eth [%s]: bad speed parameter (%d).\n",1843adapter->name, speed);1844return -EINVAL;1845}1846if ((speed == 1000) && (full_duplex == AL_FALSE)) {1847al_err("eth [%s]: half duplex in 1Gbps is not supported.\n",1848adapter->name);1849return -EINVAL;1850}1851}18521853if (AL_ETH_IS_1G_MAC(adapter->mac_mode))1854al_eth_mac_link_config_1g_mac(adapter,1855force_1000_base_x,1856an_enable,1857speed,1858full_duplex);1859else1860al_eth_mac_link_config_10g_mac(adapter,1861force_1000_base_x,1862an_enable,1863speed,1864full_duplex);18651866return 0;1867}18681869int al_eth_mac_loopback_config(struct al_hal_eth_adapter *adapter, int enable)1870{1871const char *state = (enable) ? "enable" : "disable";18721873al_dbg("eth [%s]: loopback %s\n", adapter->name, state);1874if (AL_ETH_IS_1G_MAC(adapter->mac_mode)) {1875uint32_t reg;1876reg = al_reg_read32(&adapter->mac_regs_base->mac_1g.cmd_cfg);1877if (enable)1878reg |= AL_BIT(15);1879else1880reg &= ~AL_BIT(15);1881al_reg_write32(&adapter->mac_regs_base->mac_1g.cmd_cfg, reg);1882} else if ((AL_ETH_IS_10G_MAC(adapter->mac_mode) || AL_ETH_IS_25G_MAC(adapter->mac_mode))1883&& (adapter->rev_id == AL_ETH_REV_ID_3)) {1884uint32_t reg;1885al_reg_write16(1886(uint16_t *)&adapter->mac_regs_base->kr.pcs_addr, ETH_MAC_KR_PCS_CONTROL_1_ADDR);1887reg = al_reg_read16(1888(uint16_t *)&adapter->mac_regs_base->kr.pcs_data);1889if (enable)1890reg |= AL_BIT(14);1891else1892reg &= ~AL_BIT(14);1893al_reg_write16(1894(uint16_t *)&adapter->mac_regs_base->kr.pcs_addr, ETH_MAC_KR_PCS_CONTROL_1_ADDR);1895al_reg_write16(1896(uint16_t *)&adapter->mac_regs_base->kr.pcs_data, reg);1897} else if (adapter->mac_mode == AL_ETH_MAC_MODE_XLG_LL_40G ||1898(adapter->mac_mode == AL_ETH_MAC_MODE_XLG_LL_50G)) {1899uint32_t reg;1900reg = al_eth_40g_pcs_reg_read(adapter, ETH_MAC_GEN_V3_PCS_40G_CONTROL_STATUS_ADDR);1901if (enable)1902reg |= AL_BIT(14);1903else1904reg &= ~AL_BIT(14);1905al_eth_40g_pcs_reg_write(adapter, ETH_MAC_GEN_V3_PCS_40G_CONTROL_STATUS_ADDR, reg);1906} else {1907al_err("Eth: mac loopback not supported in this mode %d", adapter->mac_mode);1908return -EPERM;1909}1910return 0;1911}19121913/* MDIO */1914int al_eth_mdio_config(1915struct al_hal_eth_adapter *adapter,1916enum al_eth_mdio_type mdio_type,1917al_bool shared_mdio_if,1918enum al_eth_ref_clk_freq ref_clk_freq,1919unsigned int mdio_clk_freq_khz)1920{1921enum al_eth_mdio_if mdio_if = AL_ETH_MDIO_IF_10G_MAC;1922const char *if_name = (mdio_if == AL_ETH_MDIO_IF_1G_MAC) ? "10/100/1G MAC" : "10G MAC";1923const char *type_name = (mdio_type == AL_ETH_MDIO_TYPE_CLAUSE_22) ? "Clause 22" : "Clause 45";1924const char *shared_name = (shared_mdio_if == AL_TRUE) ? "Yes" : "No";19251926unsigned int ref_clk_freq_khz;1927uint32_t val;19281929al_dbg("eth [%s]: mdio config: interface %s. type %s. shared: %s\n", adapter->name, if_name, type_name, shared_name);1930adapter->shared_mdio_if = shared_mdio_if;19311932val = al_reg_read32(&adapter->mac_regs_base->gen.cfg);1933al_dbg("eth [%s]: mdio config: 10G mac \n", adapter->name);19341935switch(mdio_if)1936{1937case AL_ETH_MDIO_IF_1G_MAC:1938val &= ~AL_BIT(10);1939break;1940case AL_ETH_MDIO_IF_10G_MAC:1941val |= AL_BIT(10);1942break;1943}1944al_reg_write32(&adapter->mac_regs_base->gen.cfg, val);1945adapter->mdio_if = mdio_if;194619471948if (mdio_if == AL_ETH_MDIO_IF_10G_MAC)1949{1950val = al_reg_read32(&adapter->mac_regs_base->mac_10g.mdio_cfg_status);1951switch(mdio_type)1952{1953case AL_ETH_MDIO_TYPE_CLAUSE_22:1954val &= ~AL_BIT(6);1955break;1956case AL_ETH_MDIO_TYPE_CLAUSE_45:1957val |= AL_BIT(6);1958break;1959}19601961/* set clock div to get 'mdio_clk_freq_khz' */1962switch (ref_clk_freq) {1963default:1964al_err("eth [%s]: %s: invalid reference clock frequency"1965" (%d)\n",1966adapter->name, __func__, ref_clk_freq);1967case AL_ETH_REF_FREQ_375_MHZ:1968ref_clk_freq_khz = 375000;1969break;1970case AL_ETH_REF_FREQ_187_5_MHZ:1971ref_clk_freq_khz = 187500;1972break;1973case AL_ETH_REF_FREQ_250_MHZ:1974ref_clk_freq_khz = 250000;1975break;1976case AL_ETH_REF_FREQ_500_MHZ:1977ref_clk_freq_khz = 500000;1978break;1979case AL_ETH_REF_FREQ_428_MHZ:1980ref_clk_freq_khz = 428000;1981break;1982};19831984val &= ~(0x1FF << 7);1985val |= (ref_clk_freq_khz / (2 * mdio_clk_freq_khz)) << 7;1986AL_REG_FIELD_SET(val, ETH_10G_MAC_MDIO_CFG_HOLD_TIME_MASK,1987ETH_10G_MAC_MDIO_CFG_HOLD_TIME_SHIFT,1988ETH_10G_MAC_MDIO_CFG_HOLD_TIME_7_CLK);1989al_reg_write32(&adapter->mac_regs_base->mac_10g.mdio_cfg_status, val);1990}else{1991if(mdio_type != AL_ETH_MDIO_TYPE_CLAUSE_22) {1992al_err("eth [%s] mdio type not supported for this interface\n",1993adapter->name);1994return -EINVAL;1995}1996}1997adapter->mdio_type = mdio_type;19981999return 0;2000}20012002static int al_eth_mdio_1g_mac_read(struct al_hal_eth_adapter *adapter,2003uint32_t phy_addr __attribute__((__unused__)),2004uint32_t reg, uint16_t *val)2005{2006*val = al_reg_read32(2007&adapter->mac_regs_base->mac_1g.phy_regs_base + reg);2008return 0;2009}20102011static int al_eth_mdio_1g_mac_write(struct al_hal_eth_adapter *adapter,2012uint32_t phy_addr __attribute__((__unused__)),2013uint32_t reg, uint16_t val)2014{2015al_reg_write32(2016&adapter->mac_regs_base->mac_1g.phy_regs_base + reg, val);2017return 0;2018}20192020static int al_eth_mdio_10g_mac_wait_busy(struct al_hal_eth_adapter *adapter)2021{2022int count = 0;2023uint32_t mdio_cfg_status;20242025do {2026mdio_cfg_status = al_reg_read32(&adapter->mac_regs_base->mac_10g.mdio_cfg_status);2027/*2028if (mdio_cfg_status & AL_BIT(1)){ //error2029al_err(" %s mdio read failed on error. phy_addr 0x%x reg 0x%x\n",2030udma_params.name, phy_addr, reg);2031return -EIO;2032}*/2033if (mdio_cfg_status & AL_BIT(0)){2034if (count > 0)2035al_dbg("eth [%s] mdio: still busy!\n", adapter->name);2036}else{2037return 0;2038}2039al_udelay(AL_ETH_MDIO_DELAY_PERIOD);2040}while(count++ < AL_ETH_MDIO_DELAY_COUNT);20412042return -ETIMEDOUT;2043}20442045static int al_eth_mdio_10g_mac_type22(2046struct al_hal_eth_adapter *adapter,2047int read, uint32_t phy_addr, uint32_t reg, uint16_t *val)2048{2049int rc;2050const char *op = (read == 1) ? "read":"write";2051uint32_t mdio_cfg_status;2052uint16_t mdio_cmd;20532054//wait if the HW is busy2055rc = al_eth_mdio_10g_mac_wait_busy(adapter);2056if (rc) {2057al_err(" eth [%s] mdio %s failed. HW is busy\n", adapter->name, op);2058return rc;2059}20602061mdio_cmd = (uint16_t)(0x1F & reg);2062mdio_cmd |= (0x1F & phy_addr) << 5;20632064if (read)2065mdio_cmd |= AL_BIT(15); //READ command20662067al_reg_write16(&adapter->mac_regs_base->mac_10g.mdio_cmd,2068mdio_cmd);2069if (!read)2070al_reg_write16(&adapter->mac_regs_base->mac_10g.mdio_data,2071*val);20722073//wait for the busy to clear2074rc = al_eth_mdio_10g_mac_wait_busy(adapter);2075if (rc != 0) {2076al_err(" %s mdio %s failed on timeout\n", adapter->name, op);2077return -ETIMEDOUT;2078}20792080mdio_cfg_status = al_reg_read32(&adapter->mac_regs_base->mac_10g.mdio_cfg_status);20812082if (mdio_cfg_status & AL_BIT(1)){ //error2083al_err(" %s mdio %s failed on error. phy_addr 0x%x reg 0x%x\n",2084adapter->name, op, phy_addr, reg);2085return -EIO;2086}2087if (read)2088*val = al_reg_read16(2089(uint16_t *)&adapter->mac_regs_base->mac_10g.mdio_data);2090return 0;2091}20922093static int al_eth_mdio_10g_mac_type45(2094struct al_hal_eth_adapter *adapter,2095int read, uint32_t port_addr, uint32_t device, uint32_t reg, uint16_t *val)2096{2097int rc;2098const char *op = (read == 1) ? "read":"write";2099uint32_t mdio_cfg_status;2100uint16_t mdio_cmd;21012102//wait if the HW is busy2103rc = al_eth_mdio_10g_mac_wait_busy(adapter);2104if (rc) {2105al_err(" %s mdio %s failed. HW is busy\n", adapter->name, op);2106return rc;2107}2108// set command register2109mdio_cmd = (uint16_t)(0x1F & device);2110mdio_cmd |= (0x1F & port_addr) << 5;2111al_reg_write16(&adapter->mac_regs_base->mac_10g.mdio_cmd,2112mdio_cmd);21132114// send address frame2115al_reg_write16(&adapter->mac_regs_base->mac_10g.mdio_regaddr, reg);2116//wait for the busy to clear2117rc = al_eth_mdio_10g_mac_wait_busy(adapter);2118if (rc) {2119al_err(" %s mdio %s (address frame) failed on timeout\n", adapter->name, op);2120return rc;2121}21222123// if read, write again to the command register with READ bit set2124if (read) {2125mdio_cmd |= AL_BIT(15); //READ command2126al_reg_write16(2127(uint16_t *)&adapter->mac_regs_base->mac_10g.mdio_cmd,2128mdio_cmd);2129} else {2130al_reg_write16(2131(uint16_t *)&adapter->mac_regs_base->mac_10g.mdio_data,2132*val);2133}2134//wait for the busy to clear2135rc = al_eth_mdio_10g_mac_wait_busy(adapter);2136if (rc) {2137al_err(" %s mdio %s failed on timeout\n", adapter->name, op);2138return rc;2139}21402141mdio_cfg_status = al_reg_read32(&adapter->mac_regs_base->mac_10g.mdio_cfg_status);21422143if (mdio_cfg_status & AL_BIT(1)){ //error2144al_err(" %s mdio %s failed on error. port 0x%x, device 0x%x reg 0x%x\n",2145adapter->name, op, port_addr, device, reg);2146return -EIO;2147}2148if (read)2149*val = al_reg_read16(2150(uint16_t *)&adapter->mac_regs_base->mac_10g.mdio_data);2151return 0;2152}21532154/**2155* acquire mdio interface ownership2156* when mdio interface shared between multiple eth controllers, this function waits until the ownership granted for this controller.2157* this function does nothing when the mdio interface is used only by this controller.2158*2159* @param adapter2160* @return 0 on success, -ETIMEDOUT on timeout.2161*/2162static int al_eth_mdio_lock(struct al_hal_eth_adapter *adapter)2163{2164int count = 0;2165uint32_t mdio_ctrl_1;21662167if (adapter->shared_mdio_if == AL_FALSE)2168return 0; /* nothing to do when interface is not shared */21692170do {2171mdio_ctrl_1 = al_reg_read32(&adapter->mac_regs_base->gen.mdio_ctrl_1);2172/*2173if (mdio_cfg_status & AL_BIT(1)){ //error2174al_err(" %s mdio read failed on error. phy_addr 0x%x reg 0x%x\n",2175udma_params.name, phy_addr, reg);2176return -EIO;2177}*/2178if (mdio_ctrl_1 & AL_BIT(0)){2179if (count > 0)2180al_dbg("eth %s mdio interface still busy!\n", adapter->name);2181}else{2182return 0;2183}2184al_udelay(AL_ETH_MDIO_DELAY_PERIOD);2185}while(count++ < (AL_ETH_MDIO_DELAY_COUNT * 4));2186al_err(" %s mdio failed to take ownership. MDIO info reg: 0x%08x\n",2187adapter->name, al_reg_read32(&adapter->mac_regs_base->gen.mdio_1));21882189return -ETIMEDOUT;2190}21912192/**2193* free mdio interface ownership2194* when mdio interface shared between multiple eth controllers, this function releases the ownership granted for this controller.2195* this function does nothing when the mdio interface is used only by this controller.2196*2197* @param adapter2198* @return 0.2199*/2200static int al_eth_mdio_free(struct al_hal_eth_adapter *adapter)2201{2202if (adapter->shared_mdio_if == AL_FALSE)2203return 0; /* nothing to do when interface is not shared */22042205al_reg_write32(&adapter->mac_regs_base->gen.mdio_ctrl_1, 0);22062207/*2208* Addressing RMN: 29172209*2210* RMN description:2211* The HW spin-lock is stateless and doesn't maintain any scheduling2212* policy.2213*2214* Software flow:2215* After getting the lock wait 2 times the delay period in order to give2216* the other port chance to take the lock and prevent starvation.2217* This is not scalable to more than two ports.2218*/2219al_udelay(2 * AL_ETH_MDIO_DELAY_PERIOD);22202221return 0;2222}22232224int al_eth_mdio_read(struct al_hal_eth_adapter *adapter, uint32_t phy_addr, uint32_t device, uint32_t reg, uint16_t *val)2225{2226int rc;2227rc = al_eth_mdio_lock(adapter);22282229/*"interface ownership taken"*/2230if (rc)2231return rc;22322233if (adapter->mdio_if == AL_ETH_MDIO_IF_1G_MAC)2234rc = al_eth_mdio_1g_mac_read(adapter, phy_addr, reg, val);2235else2236if (adapter->mdio_type == AL_ETH_MDIO_TYPE_CLAUSE_22)2237rc = al_eth_mdio_10g_mac_type22(adapter, 1, phy_addr, reg, val);2238else2239rc = al_eth_mdio_10g_mac_type45(adapter, 1, phy_addr, device, reg, val);22402241al_eth_mdio_free(adapter);2242al_dbg("eth mdio read: phy_addr %x, device %x, reg %x val %x\n", phy_addr, device, reg, *val);2243return rc;2244}22452246int al_eth_mdio_write(struct al_hal_eth_adapter *adapter, uint32_t phy_addr, uint32_t device, uint32_t reg, uint16_t val)2247{2248int rc;2249al_dbg("eth mdio write: phy_addr %x, device %x, reg %x, val %x\n", phy_addr, device, reg, val);2250rc = al_eth_mdio_lock(adapter);2251/* interface ownership taken */2252if (rc)2253return rc;22542255if (adapter->mdio_if == AL_ETH_MDIO_IF_1G_MAC)2256rc = al_eth_mdio_1g_mac_write(adapter, phy_addr, reg, val);2257else2258if (adapter->mdio_type == AL_ETH_MDIO_TYPE_CLAUSE_22)2259rc = al_eth_mdio_10g_mac_type22(adapter, 0, phy_addr, reg, &val);2260else2261rc = al_eth_mdio_10g_mac_type45(adapter, 0, phy_addr, device, reg, &val);22622263al_eth_mdio_free(adapter);2264return rc;2265}22662267static void al_dump_tx_desc(union al_udma_desc *tx_desc)2268{2269uint32_t *ptr = (uint32_t *)tx_desc;2270al_dbg("eth tx desc:\n");2271al_dbg("0x%08x\n", *(ptr++));2272al_dbg("0x%08x\n", *(ptr++));2273al_dbg("0x%08x\n", *(ptr++));2274al_dbg("0x%08x\n", *(ptr++));2275}22762277static void2278al_dump_tx_pkt(struct al_udma_q *tx_dma_q, struct al_eth_pkt *pkt)2279{2280const char *tso = (pkt->flags & AL_ETH_TX_FLAGS_TSO) ? "TSO" : "";2281const char *l3_csum = (pkt->flags & AL_ETH_TX_FLAGS_IPV4_L3_CSUM) ? "L3 CSUM" : "";2282const char *l4_csum = (pkt->flags & AL_ETH_TX_FLAGS_L4_CSUM) ?2283((pkt->flags & AL_ETH_TX_FLAGS_L4_PARTIAL_CSUM) ? "L4 PARTIAL CSUM" : "L4 FULL CSUM") : "";2284const char *fcs = (pkt->flags & AL_ETH_TX_FLAGS_L2_DIS_FCS) ? "Disable FCS" : "";2285const char *ptp = (pkt->flags & AL_ETH_TX_FLAGS_TS) ? "TX_PTP" : "";2286const char *l3_proto_name = "unknown";2287const char *l4_proto_name = "unknown";2288const char *outer_l3_proto_name = "N/A";2289const char *tunnel_mode = (((pkt->tunnel_mode &2290AL_ETH_TUNNEL_WITH_UDP) == AL_ETH_TUNNEL_WITH_UDP) ?2291"TUNNEL_WITH_UDP" :2292(((pkt->tunnel_mode &2293AL_ETH_TUNNEL_NO_UDP) == AL_ETH_TUNNEL_NO_UDP) ?2294"TUNNEL_NO_UDP" : ""));2295uint32_t total_len = 0;2296int i;22972298al_dbg("[%s %d]: flags: %s %s %s %s %s %s\n", tx_dma_q->udma->name, tx_dma_q->qid,2299tso, l3_csum, l4_csum, fcs, ptp, tunnel_mode);23002301switch (pkt->l3_proto_idx) {2302case AL_ETH_PROTO_ID_IPv4:2303l3_proto_name = "IPv4";2304break;2305case AL_ETH_PROTO_ID_IPv6:2306l3_proto_name = "IPv6";2307break;2308default:2309l3_proto_name = "unknown";2310break;2311}23122313switch (pkt->l4_proto_idx) {2314case AL_ETH_PROTO_ID_TCP:2315l4_proto_name = "TCP";2316break;2317case AL_ETH_PROTO_ID_UDP:2318l4_proto_name = "UDP";2319break;2320default:2321l4_proto_name = "unknown";2322break;2323}23242325switch (pkt->outer_l3_proto_idx) {2326case AL_ETH_PROTO_ID_IPv4:2327outer_l3_proto_name = "IPv4";2328break;2329case AL_ETH_PROTO_ID_IPv6:2330outer_l3_proto_name = "IPv6";2331break;2332default:2333outer_l3_proto_name = "N/A";2334break;2335}23362337al_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",2338tx_dma_q->udma->name, tx_dma_q->qid, pkt->l3_proto_idx,2339l3_proto_name, pkt->l4_proto_idx, l4_proto_name,2340pkt->outer_l3_proto_idx, outer_l3_proto_name,2341pkt->source_vlan_count, pkt->vlan_mod_add_count,2342pkt->vlan_mod_del_count);23432344if (pkt->meta) {2345const char * store = pkt->meta->store ? "Yes" : "No";2346const char *ptp_val = (pkt->flags & AL_ETH_TX_FLAGS_TS) ? "Yes" : "No";23472348al_dbg("[%s %d]: tx pkt with meta data. words valid %x\n",2349tx_dma_q->udma->name, tx_dma_q->qid,2350pkt->meta->words_valid);2351al_dbg("[%s %d]: meta: store to cache %s. l3 hdr len %d. l3 hdr offset %d. "2352"l4 hdr len %d. mss val %d ts_index %d ts_val:%s\n"2353, tx_dma_q->udma->name, tx_dma_q->qid, store,2354pkt->meta->l3_header_len, pkt->meta->l3_header_offset,2355pkt->meta->l4_header_len, pkt->meta->mss_val,2356pkt->meta->ts_index, ptp_val);2357al_dbg("outer_l3_hdr_offset %d. outer_l3_len %d.\n",2358pkt->meta->outer_l3_offset, pkt->meta->outer_l3_len);2359}23602361al_dbg("[%s %d]: num of bufs: %d\n", tx_dma_q->udma->name, tx_dma_q->qid,2362pkt->num_of_bufs);2363for (i = 0; i < pkt->num_of_bufs; i++) {2364al_dbg("eth [%s %d]: buf[%d]: len 0x%08x. address 0x%016llx\n", tx_dma_q->udma->name, tx_dma_q->qid,2365i, pkt->bufs[i].len, (unsigned long long)pkt->bufs[i].addr);2366total_len += pkt->bufs[i].len;2367}2368al_dbg("[%s %d]: total len: 0x%08x\n", tx_dma_q->udma->name, tx_dma_q->qid, total_len);23692370}23712372/* TX */2373/**2374* add packet to transmission queue2375*/2376int al_eth_tx_pkt_prepare(struct al_udma_q *tx_dma_q, struct al_eth_pkt *pkt)2377{2378union al_udma_desc *tx_desc;2379uint32_t tx_descs;2380uint32_t flags = AL_M2S_DESC_FIRST |2381AL_M2S_DESC_CONCAT |2382(pkt->flags & AL_ETH_TX_FLAGS_INT);2383uint64_t tgtid = ((uint64_t)pkt->tgtid) << AL_UDMA_DESC_TGTID_SHIFT;2384uint32_t meta_ctrl;2385uint32_t ring_id;2386int buf_idx;23872388al_dbg("[%s %d]: new tx pkt\n", tx_dma_q->udma->name, tx_dma_q->qid);23892390al_dump_tx_pkt(tx_dma_q, pkt);23912392tx_descs = pkt->num_of_bufs;2393if (pkt->meta) {2394tx_descs += 1;2395}2396#ifdef AL_ETH_EX2397al_assert((pkt->ext_meta_data == NULL) || (tx_dma_q->adapter_rev_id > AL_ETH_REV_ID_2));23982399tx_descs += al_eth_ext_metadata_needed_descs(pkt->ext_meta_data);2400al_dbg("[%s %d]: %d Descriptors: ext_meta (%d). meta (%d). buffer (%d) ",2401tx_dma_q->udma->name, tx_dma_q->qid, tx_descs,2402al_eth_ext_metadata_needed_descs(pkt->ext_meta_data),2403(pkt->meta != NULL), pkt->num_of_bufs);2404#endif24052406if (unlikely(al_udma_available_get(tx_dma_q) < tx_descs)) {2407al_dbg("[%s %d]: failed to allocate (%d) descriptors",2408tx_dma_q->udma->name, tx_dma_q->qid, tx_descs);2409return 0;2410}24112412#ifdef AL_ETH_EX2413if (pkt->ext_meta_data != NULL) {2414al_eth_ext_metadata_create(tx_dma_q, &flags, pkt->ext_meta_data);2415flags &= ~(AL_M2S_DESC_FIRST | AL_ETH_TX_FLAGS_INT);2416}2417#endif24182419if (pkt->meta) {2420uint32_t meta_word_0 = 0;2421uint32_t meta_word_1 = 0;2422uint32_t meta_word_2 = 0;2423uint32_t meta_word_3 = 0;24242425meta_word_0 |= flags | AL_M2S_DESC_META_DATA;2426meta_word_0 &= ~AL_M2S_DESC_CONCAT;2427flags &= ~(AL_M2S_DESC_FIRST | AL_ETH_TX_FLAGS_INT);24282429tx_desc = al_udma_desc_get(tx_dma_q);2430/* get ring id, and clear FIRST and Int flags */2431ring_id = al_udma_ring_id_get(tx_dma_q) <<2432AL_M2S_DESC_RING_ID_SHIFT;24332434meta_word_0 |= ring_id;2435meta_word_0 |= pkt->meta->words_valid << 12;24362437if (pkt->meta->store)2438meta_word_0 |= AL_ETH_TX_META_STORE;24392440if (pkt->meta->words_valid & 1) {2441meta_word_0 |= pkt->meta->vlan1_cfi_sel;2442meta_word_0 |= pkt->meta->vlan2_vid_sel << 2;2443meta_word_0 |= pkt->meta->vlan2_cfi_sel << 4;2444meta_word_0 |= pkt->meta->vlan2_pbits_sel << 6;2445meta_word_0 |= pkt->meta->vlan2_ether_sel << 8;2446}24472448if (pkt->meta->words_valid & 2) {2449meta_word_1 = pkt->meta->vlan1_new_vid;2450meta_word_1 |= pkt->meta->vlan1_new_cfi << 12;2451meta_word_1 |= pkt->meta->vlan1_new_pbits << 13;2452meta_word_1 |= pkt->meta->vlan2_new_vid << 16;2453meta_word_1 |= pkt->meta->vlan2_new_cfi << 28;2454meta_word_1 |= pkt->meta->vlan2_new_pbits << 29;2455}24562457if (pkt->meta->words_valid & 4) {2458uint32_t l3_offset;24592460meta_word_2 = pkt->meta->l3_header_len & AL_ETH_TX_META_L3_LEN_MASK;2461meta_word_2 |= (pkt->meta->l3_header_offset & AL_ETH_TX_META_L3_OFF_MASK) <<2462AL_ETH_TX_META_L3_OFF_SHIFT;2463meta_word_2 |= (pkt->meta->l4_header_len & 0x3f) << 16;24642465if (unlikely(pkt->flags & AL_ETH_TX_FLAGS_TS))2466meta_word_0 |= pkt->meta->ts_index <<2467AL_ETH_TX_META_MSS_MSB_TS_VAL_SHIFT;2468else2469meta_word_0 |= (((pkt->meta->mss_val & 0x3c00) >> 10)2470<< AL_ETH_TX_META_MSS_MSB_TS_VAL_SHIFT);2471meta_word_2 |= ((pkt->meta->mss_val & 0x03ff)2472<< AL_ETH_TX_META_MSS_LSB_VAL_SHIFT);24732474/*2475* move from bytes to multiplication of 2 as the HW2476* expect to get it2477*/2478l3_offset = (pkt->meta->outer_l3_offset >> 1);24792480meta_word_0 |=2481(((l3_offset &2482AL_ETH_TX_META_OUTER_L3_OFF_HIGH_MASK) >> 3)2483<< AL_ETH_TX_META_OUTER_L3_OFF_HIGH_SHIFT);24842485meta_word_3 |=2486((l3_offset &2487AL_ETH_TX_META_OUTER_L3_OFF_LOW_MASK)2488<< AL_ETH_TX_META_OUTER_L3_OFF_LOW_SHIFT);24892490/*2491* shift right 2 bits to work in multiplication of 42492* as the HW expect to get it2493*/2494meta_word_3 |=2495(((pkt->meta->outer_l3_len >> 2) &2496AL_ETH_TX_META_OUTER_L3_LEN_MASK)2497<< AL_ETH_TX_META_OUTER_L3_LEN_SHIFT);2498}24992500tx_desc->tx_meta.len_ctrl = swap32_to_le(meta_word_0);2501tx_desc->tx_meta.meta_ctrl = swap32_to_le(meta_word_1);2502tx_desc->tx_meta.meta1 = swap32_to_le(meta_word_2);2503tx_desc->tx_meta.meta2 = swap32_to_le(meta_word_3);2504al_dump_tx_desc(tx_desc);2505}25062507meta_ctrl = pkt->flags & AL_ETH_TX_PKT_META_FLAGS;25082509/* L4_PARTIAL_CSUM without L4_CSUM is invalid option */2510al_assert((pkt->flags & (AL_ETH_TX_FLAGS_L4_CSUM|AL_ETH_TX_FLAGS_L4_PARTIAL_CSUM)) !=2511AL_ETH_TX_FLAGS_L4_PARTIAL_CSUM);25122513/* TSO packets can't have Timestamp enabled */2514al_assert((pkt->flags & (AL_ETH_TX_FLAGS_TSO|AL_ETH_TX_FLAGS_TS)) !=2515(AL_ETH_TX_FLAGS_TSO|AL_ETH_TX_FLAGS_TS));25162517meta_ctrl |= pkt->l3_proto_idx;2518meta_ctrl |= pkt->l4_proto_idx << AL_ETH_TX_L4_PROTO_IDX_SHIFT;2519meta_ctrl |= pkt->source_vlan_count << AL_ETH_TX_SRC_VLAN_CNT_SHIFT;2520meta_ctrl |= pkt->vlan_mod_add_count << AL_ETH_TX_VLAN_MOD_ADD_SHIFT;2521meta_ctrl |= pkt->vlan_mod_del_count << AL_ETH_TX_VLAN_MOD_DEL_SHIFT;2522meta_ctrl |= pkt->vlan_mod_v1_ether_sel << AL_ETH_TX_VLAN_MOD_E_SEL_SHIFT;2523meta_ctrl |= pkt->vlan_mod_v1_vid_sel << AL_ETH_TX_VLAN_MOD_VID_SEL_SHIFT;2524meta_ctrl |= pkt->vlan_mod_v1_pbits_sel << AL_ETH_TX_VLAN_MOD_PBIT_SEL_SHIFT;25252526#ifdef AL_ETH_EX2527if ((pkt->ext_meta_data != NULL) && (pkt->ext_meta_data->tx_crypto_data != NULL))2528meta_ctrl |= AL_ETH_TX_FLAGS_ENCRYPT;2529#endif25302531meta_ctrl |= pkt->tunnel_mode << AL_ETH_TX_TUNNEL_MODE_SHIFT;2532if (pkt->outer_l3_proto_idx == AL_ETH_PROTO_ID_IPv4)2533meta_ctrl |= 1 << AL_ETH_TX_OUTER_L3_PROTO_SHIFT;25342535flags |= pkt->flags & AL_ETH_TX_PKT_UDMA_FLAGS;2536for(buf_idx = 0; buf_idx < pkt->num_of_bufs; buf_idx++ ) {2537uint32_t flags_len = flags;25382539tx_desc = al_udma_desc_get(tx_dma_q);2540/* get ring id, and clear FIRST and Int flags */2541ring_id = al_udma_ring_id_get(tx_dma_q) <<2542AL_M2S_DESC_RING_ID_SHIFT;25432544flags_len |= ring_id;25452546if (buf_idx == (pkt->num_of_bufs - 1))2547flags_len |= AL_M2S_DESC_LAST;25482549/* clear First and Int flags */2550flags &= AL_ETH_TX_FLAGS_NO_SNOOP;2551flags |= AL_M2S_DESC_CONCAT;25522553flags_len |= pkt->bufs[buf_idx].len & AL_M2S_DESC_LEN_MASK;2554tx_desc->tx.len_ctrl = swap32_to_le(flags_len);2555if (buf_idx == 0)2556tx_desc->tx.meta_ctrl = swap32_to_le(meta_ctrl);2557tx_desc->tx.buf_ptr = swap64_to_le(2558pkt->bufs[buf_idx].addr | tgtid);2559al_dump_tx_desc(tx_desc);2560}25612562al_dbg("[%s %d]: pkt descriptors written into the tx queue. descs num (%d)\n",2563tx_dma_q->udma->name, tx_dma_q->qid, tx_descs);25642565return tx_descs;2566}256725682569void al_eth_tx_dma_action(struct al_udma_q *tx_dma_q, uint32_t tx_descs)2570{2571/* add tx descriptors */2572al_udma_desc_action_add(tx_dma_q, tx_descs);2573}25742575/**2576* get number of completed tx descriptors, upper layer should derive from2577*/2578int al_eth_comp_tx_get(struct al_udma_q *tx_dma_q)2579{2580int rc;25812582rc = al_udma_cdesc_get_all(tx_dma_q, NULL);2583if (rc != 0) {2584al_udma_cdesc_ack(tx_dma_q, rc);2585al_dbg("[%s %d]: tx completion: descs (%d)\n",2586tx_dma_q->udma->name, tx_dma_q->qid, rc);2587}25882589return rc;2590}25912592/**2593* configure the TSO MSS val2594*/2595int al_eth_tso_mss_config(struct al_hal_eth_adapter *adapter, uint8_t idx, uint32_t mss_val)2596{25972598al_assert(idx <= 8); /*valid MSS index*/2599al_assert(mss_val <= AL_ETH_TSO_MSS_MAX_VAL); /*valid MSS val*/2600al_assert(mss_val >= AL_ETH_TSO_MSS_MIN_VAL); /*valid MSS val*/26012602al_reg_write32(&adapter->ec_regs_base->tso_sel[idx].mss, mss_val);2603return 0;2604}260526062607/* RX */2608/**2609* config the rx descriptor fields2610*/2611void al_eth_rx_desc_config(2612struct al_hal_eth_adapter *adapter,2613enum al_eth_rx_desc_lro_context_val_res lro_sel,2614enum al_eth_rx_desc_l4_offset_sel l4_offset_sel,2615enum al_eth_rx_desc_l3_offset_sel l3_offset_sel,2616enum al_eth_rx_desc_l4_chk_res_sel l4_sel,2617enum al_eth_rx_desc_l3_chk_res_sel l3_sel,2618enum al_eth_rx_desc_l3_proto_idx_sel l3_proto_sel,2619enum al_eth_rx_desc_l4_proto_idx_sel l4_proto_sel,2620enum al_eth_rx_desc_frag_sel frag_sel)2621{2622uint32_t reg_val = 0;26232624reg_val |= (lro_sel == AL_ETH_L4_OFFSET) ?2625EC_RFW_CFG_A_0_LRO_CONTEXT_SEL : 0;26262627reg_val |= (l4_sel == AL_ETH_L4_INNER_OUTER_CHK) ?2628EC_RFW_CFG_A_0_META_L4_CHK_RES_SEL : 0;26292630reg_val |= l3_sel << EC_RFW_CFG_A_0_META_L3_CHK_RES_SEL_SHIFT;26312632al_reg_write32(&adapter->ec_regs_base->rfw.cfg_a_0, reg_val);26332634reg_val = al_reg_read32(&adapter->ec_regs_base->rfw.meta);2635if (l3_proto_sel == AL_ETH_L3_PROTO_IDX_INNER)2636reg_val |= EC_RFW_META_L3_PROT_SEL;2637else2638reg_val &= ~EC_RFW_META_L3_PROT_SEL;26392640if (l4_proto_sel == AL_ETH_L4_PROTO_IDX_INNER)2641reg_val |= EC_RFW_META_L4_PROT_SEL;2642else2643reg_val &= ~EC_RFW_META_L4_PROT_SEL;26442645if (l4_offset_sel == AL_ETH_L4_OFFSET_INNER)2646reg_val |= EC_RFW_META_L4_OFFSET_SEL;2647else2648reg_val &= ~EC_RFW_META_L4_OFFSET_SEL;26492650if (l3_offset_sel == AL_ETH_L3_OFFSET_INNER)2651reg_val |= EC_RFW_META_L3_OFFSET_SEL;2652else2653reg_val &= ~EC_RFW_META_L3_OFFSET_SEL;26542655if (frag_sel == AL_ETH_FRAG_INNER)2656reg_val |= EC_RFW_META_FRAG_SEL;2657else2658reg_val &= ~EC_RFW_META_FRAG_SEL;265926602661al_reg_write32(&adapter->ec_regs_base->rfw.meta, reg_val);2662}26632664/**2665* Configure RX header split2666*/2667int al_eth_rx_header_split_config(struct al_hal_eth_adapter *adapter, al_bool enable, uint32_t header_len)2668{2669uint32_t reg;26702671reg = al_reg_read32(&adapter->ec_regs_base->rfw.hdr_split);2672if (enable == AL_TRUE)2673reg |= EC_RFW_HDR_SPLIT_EN;2674else2675reg &= ~EC_RFW_HDR_SPLIT_EN;26762677AL_REG_FIELD_SET(reg, EC_RFW_HDR_SPLIT_DEF_LEN_MASK, EC_RFW_HDR_SPLIT_DEF_LEN_SHIFT, header_len);2678al_reg_write32(&adapter->ec_regs_base->rfw.hdr_split, reg);2679return 0;2680}268126822683/**2684* enable / disable header split in the udma queue.2685* length will be taken from the udma configuration to enable different length per queue.2686*/2687int al_eth_rx_header_split_force_len_config(struct al_hal_eth_adapter *adapter,2688al_bool enable,2689uint32_t qid,2690uint32_t header_len)2691{2692al_udma_s2m_q_compl_hdr_split_config(&(adapter->rx_udma.udma_q[qid]), enable,2693AL_TRUE, header_len);26942695return 0;2696}269726982699/**2700* add buffer to receive queue2701*/2702int al_eth_rx_buffer_add(struct al_udma_q *rx_dma_q,2703struct al_buf *buf, uint32_t flags,2704struct al_buf *header_buf)2705{2706uint64_t tgtid = ((uint64_t)flags & AL_ETH_RX_FLAGS_TGTID_MASK) <<2707AL_UDMA_DESC_TGTID_SHIFT;2708uint32_t flags_len = flags & ~AL_ETH_RX_FLAGS_TGTID_MASK;2709union al_udma_desc *rx_desc;27102711al_dbg("[%s %d]: add rx buffer.\n", rx_dma_q->udma->name, rx_dma_q->qid);27122713#if 12714if (unlikely(al_udma_available_get(rx_dma_q) < 1)) {2715al_dbg("[%s]: rx q (%d) has no enough free descriptor",2716rx_dma_q->udma->name, rx_dma_q->qid);2717return -ENOSPC;2718}2719#endif2720rx_desc = al_udma_desc_get(rx_dma_q);27212722flags_len |= al_udma_ring_id_get(rx_dma_q) << AL_S2M_DESC_RING_ID_SHIFT;2723flags_len |= buf->len & AL_S2M_DESC_LEN_MASK;27242725if (flags & AL_S2M_DESC_DUAL_BUF) {2726al_assert(header_buf != NULL); /*header valid in dual buf */2727al_assert((rx_dma_q->udma->rev_id >= AL_UDMA_REV_ID_2) ||2728(AL_ADDR_HIGH(buf->addr) == AL_ADDR_HIGH(header_buf->addr)));27292730flags_len |= ((header_buf->len >> AL_S2M_DESC_LEN2_GRANULARITY_SHIFT)2731<< AL_S2M_DESC_LEN2_SHIFT) & AL_S2M_DESC_LEN2_MASK;2732rx_desc->rx.buf2_ptr_lo = swap32_to_le(AL_ADDR_LOW(header_buf->addr));2733}2734rx_desc->rx.len_ctrl = swap32_to_le(flags_len);2735rx_desc->rx.buf1_ptr = swap64_to_le(buf->addr | tgtid);27362737return 0;2738}27392740/**2741* notify the hw engine about rx descriptors that were added to the receive queue2742*/2743void al_eth_rx_buffer_action(struct al_udma_q *rx_dma_q, uint32_t descs_num)2744{2745al_dbg("[%s]: update the rx engine tail pointer: queue %d. descs %d\n",2746rx_dma_q->udma->name, rx_dma_q->qid, descs_num);27472748/* add rx descriptor */2749al_udma_desc_action_add(rx_dma_q, descs_num);2750}27512752/**2753* get packet from RX completion ring2754*/2755uint32_t al_eth_pkt_rx(struct al_udma_q *rx_dma_q,2756struct al_eth_pkt *pkt)2757{2758volatile union al_udma_cdesc *cdesc;2759volatile al_eth_rx_cdesc *rx_desc;2760uint32_t i;2761uint32_t rc;27622763rc = al_udma_cdesc_packet_get(rx_dma_q, &cdesc);2764if (rc == 0)2765return 0;27662767al_assert(rc <= AL_ETH_PKT_MAX_BUFS);27682769al_dbg("[%s]: fetch rx packet: queue %d.\n",2770rx_dma_q->udma->name, rx_dma_q->qid);27712772pkt->rx_header_len = 0;2773for (i = 0; i < rc; i++) {2774uint32_t buf1_len, buf2_len;27752776/* get next descriptor */2777rx_desc = (volatile al_eth_rx_cdesc *)al_cdesc_next(rx_dma_q, cdesc, i);27782779buf1_len = swap32_from_le(rx_desc->len);27802781if ((i == 0) && (swap32_from_le(rx_desc->word2) &2782AL_UDMA_CDESC_BUF2_USED)) {2783buf2_len = swap32_from_le(rx_desc->word2);2784pkt->rx_header_len = (buf2_len & AL_S2M_DESC_LEN2_MASK) >>2785AL_S2M_DESC_LEN2_SHIFT;2786}2787if ((swap32_from_le(rx_desc->ctrl_meta) & AL_UDMA_CDESC_BUF1_USED) &&2788((swap32_from_le(rx_desc->ctrl_meta) & AL_UDMA_CDESC_DDP) == 0))2789pkt->bufs[i].len = buf1_len & AL_S2M_DESC_LEN_MASK;2790else2791pkt->bufs[i].len = 0;2792}2793/* get flags from last desc */2794pkt->flags = swap32_from_le(rx_desc->ctrl_meta);2795#ifdef AL_ETH_RX_DESC_RAW_GET2796pkt->rx_desc_raw[0] = pkt->flags;2797pkt->rx_desc_raw[1] = swap32_from_le(rx_desc->len);2798pkt->rx_desc_raw[2] = swap32_from_le(rx_desc->word2);2799pkt->rx_desc_raw[3] = swap32_from_le(rx_desc->word3);2800#endif2801/* update L3/L4 proto index */2802pkt->l3_proto_idx = pkt->flags & AL_ETH_RX_L3_PROTO_IDX_MASK;2803pkt->l4_proto_idx = (pkt->flags >> AL_ETH_RX_L4_PROTO_IDX_SHIFT) &2804AL_ETH_RX_L4_PROTO_IDX_MASK;2805pkt->rxhash = (swap32_from_le(rx_desc->len) & AL_ETH_RX_HASH_MASK) >>2806AL_ETH_RX_HASH_SHIFT;2807pkt->l3_offset = (swap32_from_le(rx_desc->word2) & AL_ETH_RX_L3_OFFSET_MASK) >> AL_ETH_RX_L3_OFFSET_SHIFT;28082809al_udma_cdesc_ack(rx_dma_q, rc);2810return rc;2811}281228132814int al_eth_rx_parser_entry_update(struct al_hal_eth_adapter *adapter, uint32_t idx,2815struct al_eth_epe_p_reg_entry *reg_entry,2816struct al_eth_epe_control_entry *control_entry)2817{2818al_eth_epe_entry_set(adapter, idx, reg_entry, control_entry);2819return 0;2820}28212822#define AL_ETH_THASH_UDMA_SHIFT 02823#define AL_ETH_THASH_UDMA_MASK (0xF << AL_ETH_THASH_UDMA_SHIFT)28242825#define AL_ETH_THASH_Q_SHIFT 42826#define AL_ETH_THASH_Q_MASK (0x3 << AL_ETH_THASH_Q_SHIFT)28272828int al_eth_thash_table_set(struct al_hal_eth_adapter *adapter, uint32_t idx, uint8_t udma, uint32_t queue)2829{2830uint32_t entry;2831al_assert(idx < AL_ETH_RX_THASH_TABLE_SIZE); /*valid THASH index*/28322833entry = (udma << AL_ETH_THASH_UDMA_SHIFT) & AL_ETH_THASH_UDMA_MASK;2834entry |= (queue << AL_ETH_THASH_Q_SHIFT) & AL_ETH_THASH_Q_MASK;28352836al_reg_write32(&adapter->ec_regs_base->rfw.thash_table_addr, idx);2837al_reg_write32(&adapter->ec_regs_base->rfw.thash_table_data, entry);2838return 0;2839}28402841int al_eth_fsm_table_set(struct al_hal_eth_adapter *adapter, uint32_t idx, uint32_t entry)2842{28432844al_assert(idx < AL_ETH_RX_FSM_TABLE_SIZE); /*valid FSM index*/284528462847al_reg_write32(&adapter->ec_regs_base->rfw.fsm_table_addr, idx);2848al_reg_write32(&adapter->ec_regs_base->rfw.fsm_table_data, entry);2849return 0;2850}28512852static uint32_t al_eth_fwd_ctrl_entry_to_val(struct al_eth_fwd_ctrl_table_entry *entry)2853{2854uint32_t val = 0;2855AL_REG_FIELD_SET(val, AL_FIELD_MASK(3,0), 0, entry->prio_sel);2856AL_REG_FIELD_SET(val, AL_FIELD_MASK(7,4), 4, entry->queue_sel_1);2857AL_REG_FIELD_SET(val, AL_FIELD_MASK(9,8), 8, entry->queue_sel_2);2858AL_REG_FIELD_SET(val, AL_FIELD_MASK(13,10), 10, entry->udma_sel);2859AL_REG_FIELD_SET(val, AL_FIELD_MASK(17,15), 15, entry->hdr_split_len_sel);2860if (entry->hdr_split_len_sel != AL_ETH_CTRL_TABLE_HDR_SPLIT_LEN_SEL_0)2861val |= AL_BIT(18);2862AL_REG_BIT_VAL_SET(val, 19, !!(entry->filter == AL_TRUE));28632864return val;2865}28662867static int al_eth_ctrl_index_match(struct al_eth_fwd_ctrl_table_index *index, uint32_t i) {2868if ((index->vlan_table_out != AL_ETH_FWD_CTRL_IDX_VLAN_TABLE_OUT_ANY)2869&& (index->vlan_table_out != AL_REG_BIT_GET(i, 0)))2870return 0;2871if ((index->tunnel_exist != AL_ETH_FWD_CTRL_IDX_TUNNEL_ANY)2872&& (index->tunnel_exist != AL_REG_BIT_GET(i, 1)))2873return 0;2874if ((index->vlan_exist != AL_ETH_FWD_CTRL_IDX_VLAN_ANY)2875&& (index->vlan_exist != AL_REG_BIT_GET(i, 2)))2876return 0;2877if ((index->mac_table_match != AL_ETH_FWD_CTRL_IDX_MAC_TABLE_ANY)2878&& (index->mac_table_match != AL_REG_BIT_GET(i, 3)))2879return 0;2880if ((index->protocol_id != AL_ETH_PROTO_ID_ANY)2881&& (index->protocol_id != AL_REG_FIELD_GET(i, AL_FIELD_MASK(8,4),4)))2882return 0;2883if ((index->mac_type != AL_ETH_FWD_CTRL_IDX_MAC_DA_TYPE_ANY)2884&& (index->mac_type != AL_REG_FIELD_GET(i, AL_FIELD_MASK(10,9),9)))2885return 0;2886return 1;2887}28882889int al_eth_ctrl_table_set(struct al_hal_eth_adapter *adapter,2890struct al_eth_fwd_ctrl_table_index *index,2891struct al_eth_fwd_ctrl_table_entry *entry)2892{2893uint32_t val = al_eth_fwd_ctrl_entry_to_val(entry);2894uint32_t i;28952896for (i = 0; i < AL_ETH_RX_CTRL_TABLE_SIZE; i++) {2897if (al_eth_ctrl_index_match(index, i)) {2898al_reg_write32(&adapter->ec_regs_base->rfw.ctrl_table_addr, i);2899al_reg_write32(&adapter->ec_regs_base->rfw.ctrl_table_data, val);2900}2901}2902return 0;2903}29042905int al_eth_ctrl_table_def_set(struct al_hal_eth_adapter *adapter,2906al_bool use_table,2907struct al_eth_fwd_ctrl_table_entry *entry)2908{2909uint32_t val = al_eth_fwd_ctrl_entry_to_val(entry);29102911if (use_table)2912val |= EC_RFW_CTRL_TABLE_DEF_SEL;29132914al_reg_write32(&adapter->ec_regs_base->rfw.ctrl_table_def, val);29152916return 0;2917}29182919int al_eth_ctrl_table_raw_set(struct al_hal_eth_adapter *adapter, uint32_t idx, uint32_t entry)2920{29212922al_assert(idx < AL_ETH_RX_CTRL_TABLE_SIZE); /* valid CTRL index */292329242925al_reg_write32(&adapter->ec_regs_base->rfw.ctrl_table_addr, idx);2926al_reg_write32(&adapter->ec_regs_base->rfw.ctrl_table_data, entry);2927return 0;2928}29292930int al_eth_ctrl_table_def_raw_set(struct al_hal_eth_adapter *adapter, uint32_t val)2931{2932al_reg_write32(&adapter->ec_regs_base->rfw.ctrl_table_def, val);29332934return 0;2935}29362937int al_eth_hash_key_set(struct al_hal_eth_adapter *adapter, uint32_t idx, uint32_t val)2938{29392940al_assert(idx < AL_ETH_RX_HASH_KEY_NUM); /*valid CTRL index*/29412942al_reg_write32(&adapter->ec_regs_base->rfw_hash[idx].key, val);29432944return 0;2945}29462947static uint32_t al_eth_fwd_mac_table_entry_to_val(struct al_eth_fwd_mac_table_entry *entry)2948{2949uint32_t val = 0;29502951val |= (entry->filter == AL_TRUE) ? EC_FWD_MAC_CTRL_RX_VAL_DROP : 0;2952val |= ((entry->udma_mask << EC_FWD_MAC_CTRL_RX_VAL_UDMA_SHIFT) &2953EC_FWD_MAC_CTRL_RX_VAL_UDMA_MASK);29542955val |= ((entry->qid << EC_FWD_MAC_CTRL_RX_VAL_QID_SHIFT) &2956EC_FWD_MAC_CTRL_RX_VAL_QID_MASK);29572958val |= (entry->rx_valid == AL_TRUE) ? EC_FWD_MAC_CTRL_RX_VALID : 0;29592960val |= ((entry->tx_target << EC_FWD_MAC_CTRL_TX_VAL_SHIFT) &2961EC_FWD_MAC_CTRL_TX_VAL_MASK);29622963val |= (entry->tx_valid == AL_TRUE) ? EC_FWD_MAC_CTRL_TX_VALID : 0;29642965return val;2966}29672968int al_eth_fwd_mac_table_set(struct al_hal_eth_adapter *adapter, uint32_t idx,2969struct al_eth_fwd_mac_table_entry *entry)2970{2971uint32_t val;29722973al_assert(idx < AL_ETH_FWD_MAC_NUM); /*valid FWD MAC index */29742975val = (entry->addr[2] << 24) | (entry->addr[3] << 16) |2976(entry->addr[4] << 8) | entry->addr[5];2977al_reg_write32(&adapter->ec_regs_base->fwd_mac[idx].data_l, val);2978val = (entry->addr[0] << 8) | entry->addr[1];2979al_reg_write32(&adapter->ec_regs_base->fwd_mac[idx].data_h, val);2980val = (entry->mask[2] << 24) | (entry->mask[3] << 16) |2981(entry->mask[4] << 8) | entry->mask[5];2982al_reg_write32(&adapter->ec_regs_base->fwd_mac[idx].mask_l, val);2983val = (entry->mask[0] << 8) | entry->mask[1];2984al_reg_write32(&adapter->ec_regs_base->fwd_mac[idx].mask_h, val);29852986val = al_eth_fwd_mac_table_entry_to_val(entry);2987al_reg_write32(&adapter->ec_regs_base->fwd_mac[idx].ctrl, val);2988return 0;2989}2990299129922993int 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)2994{2995al_assert(idx < AL_ETH_FWD_MAC_NUM); /*valid FWD MAC index */29962997al_reg_write32(&adapter->ec_regs_base->fwd_mac[idx].data_l, addr_lo);2998al_reg_write32(&adapter->ec_regs_base->fwd_mac[idx].data_h, addr_hi);2999al_reg_write32(&adapter->ec_regs_base->fwd_mac[idx].mask_l, mask_lo);3000al_reg_write32(&adapter->ec_regs_base->fwd_mac[idx].mask_h, mask_hi);30013002return 0;3003}30043005int al_eth_fwd_mac_ctrl_raw_set(struct al_hal_eth_adapter *adapter, uint32_t idx, uint32_t ctrl)3006{3007al_assert(idx < AL_ETH_FWD_MAC_NUM); /*valid FWD MAC index */30083009al_reg_write32(&adapter->ec_regs_base->fwd_mac[idx].ctrl, ctrl);30103011return 0;3012}30133014int al_eth_mac_addr_store(void * __iomem ec_base, uint32_t idx, uint8_t *addr)3015{3016struct al_ec_regs __iomem *ec_regs_base = (struct al_ec_regs __iomem*)ec_base;3017uint32_t val;30183019al_assert(idx < AL_ETH_FWD_MAC_NUM); /*valid FWD MAC index */30203021val = (addr[2] << 24) | (addr[3] << 16) | (addr[4] << 8) | addr[5];3022al_reg_write32(&ec_regs_base->fwd_mac[idx].data_l, val);3023val = (addr[0] << 8) | addr[1];3024al_reg_write32(&ec_regs_base->fwd_mac[idx].data_h, val);3025return 0;3026}30273028int al_eth_mac_addr_read(void * __iomem ec_base, uint32_t idx, uint8_t *addr)3029{3030struct al_ec_regs __iomem *ec_regs_base = (struct al_ec_regs __iomem*)ec_base;3031uint32_t addr_lo = al_reg_read32(&ec_regs_base->fwd_mac[idx].data_l);3032uint16_t addr_hi = al_reg_read32(&ec_regs_base->fwd_mac[idx].data_h);30333034addr[5] = addr_lo & 0xff;3035addr[4] = (addr_lo >> 8) & 0xff;3036addr[3] = (addr_lo >> 16) & 0xff;3037addr[2] = (addr_lo >> 24) & 0xff;3038addr[1] = addr_hi & 0xff;3039addr[0] = (addr_hi >> 8) & 0xff;3040return 0;3041}30423043int al_eth_fwd_mhash_table_set(struct al_hal_eth_adapter *adapter, uint32_t idx, uint8_t udma_mask, uint8_t qid)3044{3045uint32_t val = 0;3046al_assert(idx < AL_ETH_FWD_MAC_HASH_NUM); /* valid MHASH index */30473048AL_REG_FIELD_SET(val, AL_FIELD_MASK(3,0), 0, udma_mask);3049AL_REG_FIELD_SET(val, AL_FIELD_MASK(5,4), 4, qid);30503051al_reg_write32(&adapter->ec_regs_base->rfw.mhash_table_addr, idx);3052al_reg_write32(&adapter->ec_regs_base->rfw.mhash_table_data, val);3053return 0;3054}3055static uint32_t al_eth_fwd_vid_entry_to_val(struct al_eth_fwd_vid_table_entry *entry)3056{3057uint32_t val = 0;3058AL_REG_BIT_VAL_SET(val, 0, entry->control);3059AL_REG_BIT_VAL_SET(val, 1, entry->filter);3060AL_REG_FIELD_SET(val, AL_FIELD_MASK(5,2), 2, entry->udma_mask);30613062return val;3063}30643065int al_eth_fwd_vid_config_set(struct al_hal_eth_adapter *adapter, al_bool use_table,3066struct al_eth_fwd_vid_table_entry *default_entry,3067uint32_t default_vlan)3068{3069uint32_t reg;30703071reg = al_eth_fwd_vid_entry_to_val(default_entry);3072if (use_table)3073reg |= EC_RFW_VID_TABLE_DEF_SEL;3074else3075reg &= ~EC_RFW_VID_TABLE_DEF_SEL;3076al_reg_write32(&adapter->ec_regs_base->rfw.vid_table_def, reg);3077al_reg_write32(&adapter->ec_regs_base->rfw.default_vlan, default_vlan);30783079return 0;3080}30813082int al_eth_fwd_vid_table_set(struct al_hal_eth_adapter *adapter, uint32_t idx,3083struct al_eth_fwd_vid_table_entry *entry)3084{3085uint32_t val;3086al_assert(idx < AL_ETH_FWD_VID_TABLE_NUM); /* valid VID index */30873088val = al_eth_fwd_vid_entry_to_val(entry);3089al_reg_write32(&adapter->ec_regs_base->rfw.vid_table_addr, idx);3090al_reg_write32(&adapter->ec_regs_base->rfw.vid_table_data, val);3091return 0;3092}30933094int al_eth_fwd_pbits_table_set(struct al_hal_eth_adapter *adapter, uint32_t idx, uint8_t prio)3095{30963097al_assert(idx < AL_ETH_FWD_PBITS_TABLE_NUM); /* valid PBIT index */3098al_assert(prio < AL_ETH_FWD_PRIO_TABLE_NUM); /* valid PRIO index */3099al_reg_write32(&adapter->ec_regs_base->rfw.pbits_table_addr, idx);3100al_reg_write32(&adapter->ec_regs_base->rfw.pbits_table_data, prio);3101return 0;3102}31033104int al_eth_fwd_priority_table_set(struct al_hal_eth_adapter *adapter, uint8_t prio, uint8_t qid)3105{3106al_assert(prio < AL_ETH_FWD_PRIO_TABLE_NUM); /* valid PRIO index */31073108al_reg_write32(&adapter->ec_regs_base->rfw_priority[prio].queue, qid);3109return 0;3110}311131123113int al_eth_fwd_dscp_table_set(struct al_hal_eth_adapter *adapter, uint32_t idx, uint8_t prio)3114{31153116al_assert(idx < AL_ETH_FWD_DSCP_TABLE_NUM); /* valid DSCP index */311731183119al_reg_write32(&adapter->ec_regs_base->rfw.dscp_table_addr, idx);3120al_reg_write32(&adapter->ec_regs_base->rfw.dscp_table_data, prio);3121return 0;3122}31233124int al_eth_fwd_tc_table_set(struct al_hal_eth_adapter *adapter, uint32_t idx, uint8_t prio)3125{31263127al_assert(idx < AL_ETH_FWD_TC_TABLE_NUM); /* valid TC index */312831293130al_reg_write32(&adapter->ec_regs_base->rfw.tc_table_addr, idx);3131al_reg_write32(&adapter->ec_regs_base->rfw.tc_table_data, prio);3132return 0;3133}31343135/** Configure default UDMA register */3136int al_eth_fwd_default_udma_config(struct al_hal_eth_adapter *adapter, uint32_t idx,3137uint8_t udma_mask)3138{3139al_reg_write32_masked(&adapter->ec_regs_base->rfw_default[idx].opt_1,3140EC_RFW_DEFAULT_OPT_1_UDMA_MASK,3141udma_mask << EC_RFW_DEFAULT_OPT_1_UDMA_SHIFT);3142return 0;3143}31443145/** Configure default queue register */3146int al_eth_fwd_default_queue_config(struct al_hal_eth_adapter *adapter, uint32_t idx,3147uint8_t qid)3148{3149al_reg_write32_masked(&adapter->ec_regs_base->rfw_default[idx].opt_1,3150EC_RFW_DEFAULT_OPT_1_QUEUE_MASK,3151qid << EC_RFW_DEFAULT_OPT_1_QUEUE_SHIFT);3152return 0;3153}31543155/** Configure default priority register */3156int al_eth_fwd_default_priority_config(struct al_hal_eth_adapter *adapter, uint32_t idx,3157uint8_t prio)3158{3159al_reg_write32_masked(&adapter->ec_regs_base->rfw_default[idx].opt_1,3160EC_RFW_DEFAULT_OPT_1_PRIORITY_MASK,3161prio << EC_RFW_DEFAULT_OPT_1_PRIORITY_SHIFT);3162return 0;3163}31643165int 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,3166enum al_eth_tx_switch_vid_sel_type vid_sel_type,3167enum al_eth_tx_switch_dec_type uc_dec,3168enum al_eth_tx_switch_dec_type mc_dec,3169enum al_eth_tx_switch_dec_type bc_dec)3170{3171uint32_t reg;31723173if (udma_id == 0) {3174reg = al_reg_read32(&adapter->ec_regs_base->tfw.tx_gen);3175if (forward_all_to_mac)3176reg |= EC_TFW_TX_GEN_FWD_ALL_TO_MAC;3177else3178reg &= ~EC_TFW_TX_GEN_FWD_ALL_TO_MAC;3179al_reg_write32(&adapter->ec_regs_base->tfw.tx_gen, reg);3180}31813182reg = enable_int_switching;3183reg |= (vid_sel_type & 7) << 1;3184reg |= (bc_dec & 3) << 4;3185reg |= (mc_dec & 3) << 6;3186reg |= (uc_dec & 3) << 8;3187al_reg_write32(&adapter->ec_regs_base->tfw_udma[udma_id].fwd_dec, reg);31883189return 0;3190}31913192#define AL_ETH_RFW_FILTER_SUPPORTED(rev_id) \3193(AL_ETH_RFW_FILTER_UNDET_MAC | \3194AL_ETH_RFW_FILTER_DET_MAC | \3195AL_ETH_RFW_FILTER_TAGGED | \3196AL_ETH_RFW_FILTER_UNTAGGED | \3197AL_ETH_RFW_FILTER_BC | \3198AL_ETH_RFW_FILTER_MC | \3199AL_ETH_RFW_FILTER_VLAN_VID | \3200AL_ETH_RFW_FILTER_CTRL_TABLE | \3201AL_ETH_RFW_FILTER_PROT_INDEX | \3202AL_ETH_RFW_FILTER_WOL | \3203AL_ETH_RFW_FILTER_PARSE)32043205/* Configure the receive filters */3206int al_eth_filter_config(struct al_hal_eth_adapter *adapter, struct al_eth_filter_params *params)3207{3208uint32_t reg;32093210al_assert(params); /* valid params pointer */32113212if (params->filters & ~(AL_ETH_RFW_FILTER_SUPPORTED(adapter->rev_id))) {3213al_err("[%s]: unsupported filter options (0x%08x)\n", adapter->name, params->filters);3214return -EINVAL;3215}32163217reg = al_reg_read32(&adapter->ec_regs_base->rfw.out_cfg);3218if (params->enable == AL_TRUE)3219AL_REG_MASK_SET(reg, EC_RFW_OUT_CFG_DROP_EN);3220else3221AL_REG_MASK_CLEAR(reg, EC_RFW_OUT_CFG_DROP_EN);3222al_reg_write32(&adapter->ec_regs_base->rfw.out_cfg, reg);32233224al_reg_write32_masked(3225&adapter->ec_regs_base->rfw.filter,3226AL_ETH_RFW_FILTER_SUPPORTED(adapter->rev_id),3227params->filters);3228if (params->filters & AL_ETH_RFW_FILTER_PROT_INDEX) {3229int i;3230for (i = 0; i < AL_ETH_PROTOCOLS_NUM; i++) {3231reg = al_reg_read32(&adapter->ec_regs_base->epe_a[i].prot_act);3232if (params->filter_proto[i] == AL_TRUE)3233AL_REG_MASK_SET(reg, EC_EPE_A_PROT_ACT_DROP);3234else3235AL_REG_MASK_CLEAR(reg, EC_EPE_A_PROT_ACT_DROP);3236al_reg_write32(&adapter->ec_regs_base->epe_a[i].prot_act, reg);3237}3238}3239return 0;3240}32413242/* Configure the receive override filters */3243int al_eth_filter_override_config(struct al_hal_eth_adapter *adapter,3244struct al_eth_filter_override_params *params)3245{3246uint32_t reg;32473248al_assert(params); /* valid params pointer */32493250if (params->filters & ~(AL_ETH_RFW_FILTER_SUPPORTED(adapter->rev_id))) {3251al_err("[%s]: unsupported override filter options (0x%08x)\n", adapter->name, params->filters);3252return -EINVAL;3253}32543255al_reg_write32_masked(3256&adapter->ec_regs_base->rfw.filter,3257AL_ETH_RFW_FILTER_SUPPORTED(adapter->rev_id) << 16,3258params->filters << 16);32593260reg = al_reg_read32(&adapter->ec_regs_base->rfw.default_or);3261AL_REG_FIELD_SET(reg, EC_RFW_DEFAULT_OR_UDMA_MASK, EC_RFW_DEFAULT_OR_UDMA_SHIFT, params->udma);3262AL_REG_FIELD_SET(reg, EC_RFW_DEFAULT_OR_QUEUE_MASK, EC_RFW_DEFAULT_OR_QUEUE_SHIFT, params->qid);3263al_reg_write32(&adapter->ec_regs_base->rfw.default_or, reg);3264return 0;3265}3266326732683269int al_eth_switching_default_bitmap_set(struct al_hal_eth_adapter *adapter, uint8_t udma_id, uint8_t udma_uc_bitmask,3270uint8_t udma_mc_bitmask,uint8_t udma_bc_bitmask)3271{3272al_reg_write32(&adapter->ec_regs_base->tfw_udma[udma_id].uc_udma, udma_uc_bitmask);3273al_reg_write32(&adapter->ec_regs_base->tfw_udma[udma_id].mc_udma, udma_mc_bitmask);3274al_reg_write32(&adapter->ec_regs_base->tfw_udma[udma_id].bc_udma, udma_bc_bitmask);32753276return 0;3277}32783279int al_eth_flow_control_config(struct al_hal_eth_adapter *adapter, struct al_eth_flow_control_params *params)3280{3281uint32_t reg;3282int i;3283al_assert(params); /* valid params pointer */32843285switch(params->type){3286case AL_ETH_FLOW_CONTROL_TYPE_LINK_PAUSE:3287al_dbg("[%s]: config flow control to link pause mode.\n", adapter->name);32883289/* config the mac */3290if (AL_ETH_IS_1G_MAC(adapter->mac_mode)) {3291/* set quanta value */3292al_reg_write32(3293&adapter->mac_regs_base->mac_1g.pause_quant,3294params->quanta);3295al_reg_write32(3296&adapter->ec_regs_base->efc.xoff_timer_1g,3297params->quanta_th);32983299} else if (AL_ETH_IS_10G_MAC(adapter->mac_mode) || AL_ETH_IS_25G_MAC(adapter->mac_mode)) {3300/* set quanta value */3301al_reg_write32(3302&adapter->mac_regs_base->mac_10g.cl01_pause_quanta,3303params->quanta);3304/* set quanta threshold value */3305al_reg_write32(3306&adapter->mac_regs_base->mac_10g.cl01_quanta_thresh,3307params->quanta_th);3308} else {3309/* set quanta value */3310al_eth_40g_mac_reg_write(adapter,3311ETH_MAC_GEN_V3_MAC_40G_CL01_PAUSE_QUANTA_ADDR,3312params->quanta);3313/* set quanta threshold value */3314al_eth_40g_mac_reg_write(adapter,3315ETH_MAC_GEN_V3_MAC_40G_CL01_QUANTA_THRESH_ADDR,3316params->quanta_th);3317}33183319if (params->obay_enable == AL_TRUE)3320/* Tx path FIFO, unmask pause_on from MAC when PAUSE packet received */3321al_reg_write32(&adapter->ec_regs_base->efc.ec_pause, 1);3322else3323al_reg_write32(&adapter->ec_regs_base->efc.ec_pause, 0);332433253326/* Rx path */3327if (params->gen_enable == AL_TRUE)3328/* enable generating xoff from ec fifo almost full indication in hysteresis mode */3329al_reg_write32(&adapter->ec_regs_base->efc.ec_xoff, 1 << EC_EFC_EC_XOFF_MASK_2_SHIFT);3330else3331al_reg_write32(&adapter->ec_regs_base->efc.ec_xoff, 0);33323333if (AL_ETH_IS_1G_MAC(adapter->mac_mode))3334/* in 1G mode, enable generating xon from ec fifo in hysteresis mode*/3335al_reg_write32(&adapter->ec_regs_base->efc.xon, EC_EFC_XON_MASK_2 | EC_EFC_XON_MASK_1);33363337/* set hysteresis mode thresholds */3338al_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));33393340for (i = 0; i < 4; i++) {3341if (params->obay_enable == AL_TRUE)3342/* Tx path UDMA, unmask pause_on for all queues */3343al_reg_write32(&adapter->ec_regs_base->fc_udma[i].q_pause_0,3344params->prio_q_map[i][0]);3345else3346al_reg_write32(&adapter->ec_regs_base->fc_udma[i].q_pause_0, 0);33473348if (params->gen_enable == AL_TRUE)3349/* Rx path UDMA, enable generating xoff from UDMA queue almost full indication */3350al_reg_write32(&adapter->ec_regs_base->fc_udma[i].q_xoff_0, params->prio_q_map[i][0]);3351else3352al_reg_write32(&adapter->ec_regs_base->fc_udma[i].q_xoff_0, 0);3353}3354break;3355case AL_ETH_FLOW_CONTROL_TYPE_PFC:3356al_dbg("[%s]: config flow control to PFC mode.\n", adapter->name);3357al_assert(!AL_ETH_IS_1G_MAC(adapter->mac_mode)); /* pfc not available for RGMII mode */;33583359for (i = 0; i < 4; i++) {3360int prio;3361for (prio = 0; prio < 8; prio++) {3362if (params->obay_enable == AL_TRUE)3363/* Tx path UDMA, unmask pause_on for all queues */3364al_reg_write32(&adapter->ec_regs_base->fc_udma[i].q_pause_0 + prio,3365params->prio_q_map[i][prio]);3366else3367al_reg_write32(&adapter->ec_regs_base->fc_udma[i].q_pause_0 + prio,33680);33693370if (params->gen_enable == AL_TRUE)3371al_reg_write32(&adapter->ec_regs_base->fc_udma[i].q_xoff_0 + prio,3372params->prio_q_map[i][prio]);3373else3374al_reg_write32(&adapter->ec_regs_base->fc_udma[i].q_xoff_0 + prio,33750);3376}3377}33783379/* Rx path */3380/* enable generating xoff from ec fifo almost full indication in hysteresis mode */3381if (params->gen_enable == AL_TRUE)3382al_reg_write32(&adapter->ec_regs_base->efc.ec_xoff, 0xFF << EC_EFC_EC_XOFF_MASK_2_SHIFT);3383else3384al_reg_write32(&adapter->ec_regs_base->efc.ec_xoff, 0);33853386/* set hysteresis mode thresholds */3387al_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));33883389if (AL_ETH_IS_10G_MAC(adapter->mac_mode) || AL_ETH_IS_25G_MAC(adapter->mac_mode)) {3390/* config the 10g_mac */3391/* set quanta value (same value for all prios) */3392reg = params->quanta | (params->quanta << 16);3393al_reg_write32(3394&adapter->mac_regs_base->mac_10g.cl01_pause_quanta, reg);3395al_reg_write32(3396&adapter->mac_regs_base->mac_10g.cl23_pause_quanta, reg);3397al_reg_write32(3398&adapter->mac_regs_base->mac_10g.cl45_pause_quanta, reg);3399al_reg_write32(3400&adapter->mac_regs_base->mac_10g.cl67_pause_quanta, reg);3401/* set quanta threshold value (same value for all prios) */3402reg = params->quanta_th | (params->quanta_th << 16);3403al_reg_write32(3404&adapter->mac_regs_base->mac_10g.cl01_quanta_thresh, reg);3405al_reg_write32(3406&adapter->mac_regs_base->mac_10g.cl23_quanta_thresh, reg);3407al_reg_write32(3408&adapter->mac_regs_base->mac_10g.cl45_quanta_thresh, reg);3409al_reg_write32(3410&adapter->mac_regs_base->mac_10g.cl67_quanta_thresh, reg);34113412/* enable PFC in the 10g_MAC */3413reg = al_reg_read32(&adapter->mac_regs_base->mac_10g.cmd_cfg);3414reg |= 1 << 19;3415al_reg_write32(&adapter->mac_regs_base->mac_10g.cmd_cfg, reg);3416} else {3417/* config the 40g_mac */3418/* set quanta value (same value for all prios) */3419reg = params->quanta | (params->quanta << 16);3420al_eth_40g_mac_reg_write(adapter,3421ETH_MAC_GEN_V3_MAC_40G_CL01_PAUSE_QUANTA_ADDR, reg);3422al_eth_40g_mac_reg_write(adapter,3423ETH_MAC_GEN_V3_MAC_40G_CL23_PAUSE_QUANTA_ADDR, reg);3424al_eth_40g_mac_reg_write(adapter,3425ETH_MAC_GEN_V3_MAC_40G_CL45_PAUSE_QUANTA_ADDR, reg);3426al_eth_40g_mac_reg_write(adapter,3427ETH_MAC_GEN_V3_MAC_40G_CL67_PAUSE_QUANTA_ADDR, reg);3428/* set quanta threshold value (same value for all prios) */3429reg = params->quanta_th | (params->quanta_th << 16);3430al_eth_40g_mac_reg_write(adapter,3431ETH_MAC_GEN_V3_MAC_40G_CL01_QUANTA_THRESH_ADDR, reg);3432al_eth_40g_mac_reg_write(adapter,3433ETH_MAC_GEN_V3_MAC_40G_CL23_QUANTA_THRESH_ADDR, reg);3434al_eth_40g_mac_reg_write(adapter,3435ETH_MAC_GEN_V3_MAC_40G_CL45_QUANTA_THRESH_ADDR, reg);3436al_eth_40g_mac_reg_write(adapter,3437ETH_MAC_GEN_V3_MAC_40G_CL67_QUANTA_THRESH_ADDR, reg);34383439/* enable PFC in the 40g_MAC */3440reg = al_reg_read32(&adapter->mac_regs_base->mac_10g.cmd_cfg);3441reg |= 1 << 19;3442al_reg_write32(&adapter->mac_regs_base->mac_10g.cmd_cfg, reg);3443reg = al_eth_40g_mac_reg_read(adapter, ETH_MAC_GEN_V3_MAC_40G_COMMAND_CONFIG_ADDR);34443445reg |= ETH_MAC_GEN_V3_MAC_40G_COMMAND_CONFIG_PFC_MODE;34463447al_eth_40g_mac_reg_write(adapter, ETH_MAC_GEN_V3_MAC_40G_COMMAND_CONFIG_ADDR, reg);3448}34493450break;3451default:3452al_err("[%s]: unsupported flow control type %d\n", adapter->name, params->type);3453return -EINVAL;34543455}3456return 0;3457}34583459int 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)3460{3461al_dbg("[%s]: config vlan modification registers. udma id %d.\n", adapter->name, udma_id);34623463al_reg_write32(&adapter->ec_regs_base->tpm_sel[udma_id].etype, udma_etype);3464al_reg_write32(&adapter->ec_regs_base->tpm_udma[udma_id].vlan_data, vlan1_data | (vlan2_data << 16));34653466return 0;3467}34683469int al_eth_eee_get(struct al_hal_eth_adapter *adapter, struct al_eth_eee_params *params)3470{3471uint32_t reg;34723473al_dbg("[%s]: getting eee.\n", adapter->name);34743475reg = al_reg_read32(&adapter->ec_regs_base->eee.cfg_e);3476params->enable = (reg & EC_EEE_CFG_E_ENABLE) ? AL_TRUE : AL_FALSE;34773478params->tx_eee_timer = al_reg_read32(&adapter->ec_regs_base->eee.pre_cnt);3479params->min_interval = al_reg_read32(&adapter->ec_regs_base->eee.post_cnt);3480params->stop_cnt = al_reg_read32(&adapter->ec_regs_base->eee.stop_cnt);34813482return 0;3483}348434853486int al_eth_eee_config(struct al_hal_eth_adapter *adapter, struct al_eth_eee_params *params)3487{3488uint32_t reg;3489al_dbg("[%s]: config eee.\n", adapter->name);34903491if (params->enable == 0) {3492al_dbg("[%s]: disable eee.\n", adapter->name);3493al_reg_write32(&adapter->ec_regs_base->eee.cfg_e, 0);3494return 0;3495}3496if (AL_ETH_IS_10G_MAC(adapter->mac_mode) || AL_ETH_IS_25G_MAC(adapter->mac_mode)) {3497al_reg_write32_masked(3498&adapter->mac_regs_base->kr.pcs_cfg,3499ETH_MAC_KR_PCS_CFG_EEE_TIMER_VAL_MASK,3500((AL_ETH_IS_10G_MAC(adapter->mac_mode)) ?3501ETH_MAC_KR_10_PCS_CFG_EEE_TIMER_VAL :3502ETH_MAC_KR_25_PCS_CFG_EEE_TIMER_VAL) <<3503ETH_MAC_KR_PCS_CFG_EEE_TIMER_VAL_SHIFT);3504}3505if ((adapter->mac_mode == AL_ETH_MAC_MODE_XLG_LL_40G) ||3506(adapter->mac_mode == AL_ETH_MAC_MODE_XLG_LL_50G)) {3507al_reg_write32_masked(3508&adapter->mac_regs_base->gen_v3.pcs_40g_ll_eee_cfg,3509ETH_MAC_GEN_V3_PCS_40G_LL_EEE_CFG_TIMER_VAL_MASK,3510((adapter->mac_mode == AL_ETH_MAC_MODE_XLG_LL_40G) ?3511ETH_MAC_XLG_40_PCS_CFG_EEE_TIMER_VAL :3512ETH_MAC_XLG_50_PCS_CFG_EEE_TIMER_VAL) <<3513ETH_MAC_GEN_V3_PCS_40G_LL_EEE_CFG_TIMER_VAL_SHIFT);3514/* set Deep sleep mode as the LPI function (instead of Fast wake mode) */3515al_eth_40g_pcs_reg_write(adapter, ETH_MAC_GEN_V3_PCS_40G_EEE_CONTROL_ADDR,3516params->fast_wake ? 1 : 0);3517}35183519al_reg_write32(&adapter->ec_regs_base->eee.pre_cnt, params->tx_eee_timer);3520al_reg_write32(&adapter->ec_regs_base->eee.post_cnt, params->min_interval);3521al_reg_write32(&adapter->ec_regs_base->eee.stop_cnt, params->stop_cnt);35223523reg = EC_EEE_CFG_E_MASK_EC_TMI_STOP | EC_EEE_CFG_E_MASK_MAC_EEE |3524EC_EEE_CFG_E_ENABLE |3525EC_EEE_CFG_E_USE_EC_TX_FIFO | EC_EEE_CFG_E_USE_EC_RX_FIFO;35263527/*3528* Addressing RMN: 37323529*3530* RMN description:3531* When the HW get into eee mode, it can't transmit any pause packet3532* (when flow control policy is enabled).3533* In such case, the HW has no way to handle extreme pushback from3534* the Rx_path fifos.3535*3536* Software flow:3537* Configure RX_FIFO empty as eee mode term.3538* That way, nothing will prevent pause packet transmittion in3539* case of extreme pushback from the Rx_path fifos.3540*3541*/35423543al_reg_write32(&adapter->ec_regs_base->eee.cfg_e, reg);35443545return 0;3546}35473548/* Timestamp */3549/* prepare the adapter for doing Timestamps for Rx packets. */3550int al_eth_ts_init(struct al_hal_eth_adapter *adapter)3551{3552uint32_t reg;35533554/*TODO:3555* return error when:3556* - working in 1G mode and MACSEC enabled3557* - RX completion descriptor is not 8 words3558*/3559reg = al_reg_read32(&adapter->ec_regs_base->gen.en_ext);3560if (AL_ETH_IS_1G_MAC(adapter->mac_mode))3561reg &= ~EC_GEN_EN_EXT_PTH_1_10_SEL;3562else3563reg |= EC_GEN_EN_EXT_PTH_1_10_SEL;3564/*3565* set completion bypass so tx timestamps won't be inserted to tx cmpl3566* (in order to disable unverified flow)3567*/3568reg |= EC_GEN_EN_EXT_PTH_COMPLETION_BYPASS;3569al_reg_write32(&adapter->ec_regs_base->gen.en_ext, reg);35703571/*TODO: add the following when we have updated regs file:3572* reg_rfw_out_cfg_timestamp_sample_out35730 (default) – use the timestamp from the SOP info (10G MAC)35741 – use the timestamp from the EOP (1G MAC) (noly when MACSEC is disabled)3575*/3576return 0;3577}35783579/* read Timestamp sample value of previously transmitted packet. */3580int al_eth_tx_ts_val_get(struct al_hal_eth_adapter *adapter, uint8_t ts_index,3581uint32_t *timestamp)3582{3583al_assert(ts_index < AL_ETH_PTH_TX_SAMPLES_NUM);35843585/* in 1G mode, only indexes 1-7 are allowed*/3586if (AL_ETH_IS_1G_MAC(adapter->mac_mode)) {3587al_assert(ts_index <= 7);3588al_assert(ts_index >= 1);3589}35903591/*TODO: check if sample is valid */3592*timestamp = al_reg_read32(&adapter->ec_regs_base->pth_db[ts_index].ts);3593return 0;3594}35953596/* Read the systime value */3597int al_eth_pth_systime_read(struct al_hal_eth_adapter *adapter,3598struct al_eth_pth_time *systime)3599{3600uint32_t reg;36013602/* first we must read the subseconds MSB so the seconds register will be3603* shadowed3604*/3605reg = al_reg_read32(&adapter->ec_regs_base->pth.system_time_subseconds_msb);3606systime->femto = (uint64_t)reg << 18;3607reg = al_reg_read32(&adapter->ec_regs_base->pth.system_time_seconds);3608systime->seconds = reg;36093610return 0;3611}36123613/* Set the clock period to a given value. */3614int al_eth_pth_clk_period_write(struct al_hal_eth_adapter *adapter,3615uint64_t clk_period)3616{3617uint32_t reg;3618/* first write the LSB so it will be shadowed */3619/* bits 31:14 of the clock period lsb register contains bits 17:0 of the3620* period.3621*/3622reg = (clk_period & AL_BIT_MASK(18)) << EC_PTH_CLOCK_PERIOD_LSB_VAL_SHIFT;3623al_reg_write32(&adapter->ec_regs_base->pth.clock_period_lsb, reg);3624reg = clk_period >> 18;3625al_reg_write32(&adapter->ec_regs_base->pth.clock_period_msb, reg);36263627return 0;3628}36293630/* Configure the systime internal update */3631int al_eth_pth_int_update_config(struct al_hal_eth_adapter *adapter,3632struct al_eth_pth_int_update_params *params)3633{3634uint32_t reg;36353636reg = al_reg_read32(&adapter->ec_regs_base->pth.int_update_ctrl);3637if (params->enable == AL_FALSE) {3638reg &= ~EC_PTH_INT_UPDATE_CTRL_INT_TRIG_EN;3639} else {3640reg |= EC_PTH_INT_UPDATE_CTRL_INT_TRIG_EN;3641AL_REG_FIELD_SET(reg, EC_PTH_INT_UPDATE_CTRL_UPDATE_METHOD_MASK,3642EC_PTH_INT_UPDATE_CTRL_UPDATE_METHOD_SHIFT,3643params->method);3644if (params->trigger == AL_ETH_PTH_INT_TRIG_REG_WRITE)3645reg |= EC_PTH_INT_UPDATE_CTRL_UPDATE_TRIG;3646else3647reg &= ~EC_PTH_INT_UPDATE_CTRL_UPDATE_TRIG;3648}3649al_reg_write32(&adapter->ec_regs_base->pth.int_update_ctrl, reg);3650return 0;3651}3652/* set internal update time */3653int al_eth_pth_int_update_time_set(struct al_hal_eth_adapter *adapter,3654struct al_eth_pth_time *time)3655{3656uint32_t reg;36573658al_reg_write32(&adapter->ec_regs_base->pth.int_update_seconds,3659time->seconds);3660reg = time->femto & AL_BIT_MASK(18);3661reg = reg << EC_PTH_INT_UPDATE_SUBSECONDS_LSB_VAL_SHIFT;3662al_reg_write32(&adapter->ec_regs_base->pth.int_update_subseconds_lsb,3663reg);3664reg = time->femto >> 18;3665al_reg_write32(&adapter->ec_regs_base->pth.int_update_subseconds_msb,3666reg);36673668return 0;3669}36703671/* Configure the systime external update */3672int al_eth_pth_ext_update_config(struct al_hal_eth_adapter *adapter,3673struct al_eth_pth_ext_update_params * params)3674{3675uint32_t reg;36763677reg = al_reg_read32(&adapter->ec_regs_base->pth.int_update_ctrl);3678AL_REG_FIELD_SET(reg, EC_PTH_INT_UPDATE_CTRL_UPDATE_METHOD_MASK,3679EC_PTH_INT_UPDATE_CTRL_UPDATE_METHOD_SHIFT,3680params->method);36813682AL_REG_FIELD_SET(reg, EC_PTH_EXT_UPDATE_CTRL_EXT_TRIG_EN_MASK,3683EC_PTH_EXT_UPDATE_CTRL_EXT_TRIG_EN_SHIFT,3684params->triggers);3685al_reg_write32(&adapter->ec_regs_base->pth.int_update_ctrl, reg);3686return 0;3687}36883689/* set external update time */3690int al_eth_pth_ext_update_time_set(struct al_hal_eth_adapter *adapter,3691struct al_eth_pth_time *time)3692{3693uint32_t reg;36943695al_reg_write32(&adapter->ec_regs_base->pth.ext_update_seconds,3696time->seconds);3697reg = time->femto & AL_BIT_MASK(18);3698reg = reg << EC_PTH_EXT_UPDATE_SUBSECONDS_LSB_VAL_SHIFT;3699al_reg_write32(&adapter->ec_regs_base->pth.ext_update_subseconds_lsb,3700reg);3701reg = time->femto >> 18;3702al_reg_write32(&adapter->ec_regs_base->pth.ext_update_subseconds_msb,3703reg);37043705return 0;3706};37073708/* set the read compensation delay */3709int al_eth_pth_read_compensation_set(struct al_hal_eth_adapter *adapter,3710uint64_t subseconds)3711{3712uint32_t reg;37133714/* first write to lsb to ensure atomicity */3715reg = (subseconds & AL_BIT_MASK(18)) << EC_PTH_READ_COMPENSATION_SUBSECONDS_LSB_VAL_SHIFT;3716al_reg_write32(&adapter->ec_regs_base->pth.read_compensation_subseconds_lsb, reg);37173718reg = subseconds >> 18;3719al_reg_write32(&adapter->ec_regs_base->pth.read_compensation_subseconds_msb, reg);3720return 0;3721}37223723/* set the internal write compensation delay */3724int al_eth_pth_int_write_compensation_set(struct al_hal_eth_adapter *adapter,3725uint64_t subseconds)3726{3727uint32_t reg;37283729/* first write to lsb to ensure atomicity */3730reg = (subseconds & AL_BIT_MASK(18)) << EC_PTH_INT_WRITE_COMPENSATION_SUBSECONDS_LSB_VAL_SHIFT;3731al_reg_write32(&adapter->ec_regs_base->pth.int_write_compensation_subseconds_lsb, reg);37323733reg = subseconds >> 18;3734al_reg_write32(&adapter->ec_regs_base->pth.int_write_compensation_subseconds_msb, reg);3735return 0;3736}37373738/* set the external write compensation delay */3739int al_eth_pth_ext_write_compensation_set(struct al_hal_eth_adapter *adapter,3740uint64_t subseconds)3741{3742uint32_t reg;37433744/* first write to lsb to ensure atomicity */3745reg = (subseconds & AL_BIT_MASK(18)) << EC_PTH_EXT_WRITE_COMPENSATION_SUBSECONDS_LSB_VAL_SHIFT;3746al_reg_write32(&adapter->ec_regs_base->pth.ext_write_compensation_subseconds_lsb, reg);37473748reg = subseconds >> 18;3749al_reg_write32(&adapter->ec_regs_base->pth.ext_write_compensation_subseconds_msb, reg);3750return 0;3751}37523753/* set the sync compensation delay */3754int al_eth_pth_sync_compensation_set(struct al_hal_eth_adapter *adapter,3755uint64_t subseconds)3756{3757uint32_t reg;37583759/* first write to lsb to ensure atomicity */3760reg = (subseconds & AL_BIT_MASK(18)) << EC_PTH_SYNC_COMPENSATION_SUBSECONDS_LSB_VAL_SHIFT;3761al_reg_write32(&adapter->ec_regs_base->pth.sync_compensation_subseconds_lsb, reg);37623763reg = subseconds >> 18;3764al_reg_write32(&adapter->ec_regs_base->pth.sync_compensation_subseconds_msb, reg);3765return 0;3766}37673768/* Configure an output pulse */3769int al_eth_pth_pulse_out_config(struct al_hal_eth_adapter *adapter,3770struct al_eth_pth_pulse_out_params *params)3771{3772uint32_t reg;37733774if (params->index >= AL_ETH_PTH_PULSE_OUT_NUM) {3775al_err("eth [%s] PTH out pulse index out of range\n",3776adapter->name);3777return -EINVAL;3778}3779reg = al_reg_read32(&adapter->ec_regs_base->pth_egress[params->index].trigger_ctrl);3780if (params->enable == AL_FALSE) {3781reg &= ~EC_PTH_EGRESS_TRIGGER_CTRL_EN;3782} else {3783reg |= EC_PTH_EGRESS_TRIGGER_CTRL_EN;3784if (params->periodic == AL_FALSE)3785reg &= ~EC_PTH_EGRESS_TRIGGER_CTRL_PERIODIC;3786else3787reg |= EC_PTH_EGRESS_TRIGGER_CTRL_PERIODIC;37883789AL_REG_FIELD_SET(reg, EC_PTH_EGRESS_TRIGGER_CTRL_PERIOD_SUBSEC_MASK,3790EC_PTH_EGRESS_TRIGGER_CTRL_PERIOD_SUBSEC_SHIFT,3791params->period_us);3792AL_REG_FIELD_SET(reg, EC_PTH_EGRESS_TRIGGER_CTRL_PERIOD_SEC_MASK,3793EC_PTH_EGRESS_TRIGGER_CTRL_PERIOD_SEC_SHIFT,3794params->period_sec);3795}3796al_reg_write32(&adapter->ec_regs_base->pth_egress[params->index].trigger_ctrl, reg);37973798/* set trigger time */3799al_reg_write32(&adapter->ec_regs_base->pth_egress[params->index].trigger_seconds,3800params->start_time.seconds);3801reg = params->start_time.femto & AL_BIT_MASK(18);3802reg = reg << EC_PTH_EGRESS_TRIGGER_SUBSECONDS_LSB_VAL_SHIFT;3803al_reg_write32(&adapter->ec_regs_base->pth_egress[params->index].trigger_subseconds_lsb,3804reg);3805reg = params->start_time.femto >> 18;3806al_reg_write32(&adapter->ec_regs_base->pth_egress[params->index].trigger_subseconds_msb,3807reg);38083809/* set pulse width */3810reg = params->pulse_width & AL_BIT_MASK(18);3811reg = reg << EC_PTH_EGRESS_PULSE_WIDTH_SUBSECONDS_LSB_VAL_SHIFT;3812al_reg_write32(&adapter->ec_regs_base->pth_egress[params->index].pulse_width_subseconds_lsb, reg);38133814reg = params->pulse_width >> 18;3815al_reg_write32(&adapter->ec_regs_base->pth_egress[params->index].pulse_width_subseconds_msb, reg);38163817return 0;3818}38193820/** get link status */3821int al_eth_link_status_get(struct al_hal_eth_adapter *adapter,3822struct al_eth_link_status *status)3823{3824uint32_t reg;38253826if (AL_ETH_IS_10G_MAC(adapter->mac_mode) || AL_ETH_IS_25G_MAC(adapter->mac_mode)) {3827status->link_up = AL_FALSE;3828status->local_fault = AL_TRUE;3829status->remote_fault = AL_TRUE;38303831al_reg_write32(&adapter->mac_regs_base->kr.pcs_addr, ETH_MAC_KR_PCS_BASE_R_STATUS2);3832reg = al_reg_read32(&adapter->mac_regs_base->kr.pcs_data);38333834if (reg & AL_BIT(15)) {3835reg = al_reg_read32(&adapter->mac_regs_base->mac_10g.status);38363837status->remote_fault = ((reg & ETH_MAC_GEN_MAC_10G_STAT_REM_FAULT) ?3838AL_TRUE : AL_FALSE);3839status->local_fault = ((reg & ETH_MAC_GEN_MAC_10G_STAT_LOC_FAULT) ?3840AL_TRUE : AL_FALSE);38413842status->link_up = ((status->remote_fault == AL_FALSE) &&3843(status->local_fault == AL_FALSE));3844}38453846} else if (adapter->mac_mode == AL_ETH_MAC_MODE_SGMII) {3847al_reg_write32(&adapter->mac_regs_base->sgmii.reg_addr, 1);3848/*3849* This register is latched low so need to read twice to get3850* the current link status3851*/3852reg = al_reg_read32(&adapter->mac_regs_base->sgmii.reg_data);3853reg = al_reg_read32(&adapter->mac_regs_base->sgmii.reg_data);38543855status->link_up = AL_FALSE;38563857if (reg & AL_BIT(2))3858status->link_up = AL_TRUE;38593860reg = al_reg_read32(&adapter->mac_regs_base->sgmii.link_stat);38613862if ((reg & AL_BIT(3)) == 0)3863status->link_up = AL_FALSE;38643865} else if (adapter->mac_mode == AL_ETH_MAC_MODE_RGMII) {3866reg = al_reg_read32(&adapter->mac_regs_base->gen.rgmii_stat);38673868status->link_up = AL_FALSE;38693870if (reg & AL_BIT(4))3871status->link_up = AL_TRUE;38723873} else if (adapter->mac_mode == AL_ETH_MAC_MODE_XLG_LL_25G) {3874status->link_up = AL_FALSE;3875status->local_fault = AL_TRUE;3876status->remote_fault = AL_TRUE;38773878reg = al_reg_read32(&adapter->mac_regs_base->gen_v3.pcs_40g_ll_status);38793880status->link_up = AL_FALSE;38813882if ((reg & 0xF) == 0xF) {3883reg = al_reg_read32(&adapter->mac_regs_base->gen_v3.mac_40g_ll_status);38843885status->remote_fault = ((reg & ETH_MAC_GEN_V3_MAC_40G_LL_STATUS_REM_FAULT) ?3886AL_TRUE : AL_FALSE);3887status->local_fault = ((reg & ETH_MAC_GEN_V3_MAC_40G_LL_STATUS_LOC_FAULT) ?3888AL_TRUE : AL_FALSE);38893890status->link_up = ((status->remote_fault == AL_FALSE) &&3891(status->local_fault == AL_FALSE));3892}38933894} else if ((adapter->mac_mode == AL_ETH_MAC_MODE_XLG_LL_40G) ||3895(adapter->mac_mode == AL_ETH_MAC_MODE_XLG_LL_50G)) {3896reg = al_reg_read32(&adapter->mac_regs_base->gen_v3.pcs_40g_ll_status);38973898status->link_up = AL_FALSE;38993900if ((reg & 0x1F) == 0x1F) {3901reg = al_reg_read32(&adapter->mac_regs_base->gen_v3.mac_40g_ll_status);3902if ((reg & (ETH_MAC_GEN_V3_MAC_40G_LL_STATUS_REM_FAULT |3903ETH_MAC_GEN_V3_MAC_40G_LL_STATUS_LOC_FAULT)) == 0)3904status->link_up = AL_TRUE;3905}39063907} else {3908/* not implemented yet */3909return -EPERM;3910}39113912al_dbg("[%s]: mac %s port. link_status: %s.\n", adapter->name,3913al_eth_mac_mode_str(adapter->mac_mode),3914(status->link_up == AL_TRUE) ? "LINK_UP" : "LINK_DOWN");39153916return 0;3917}39183919int al_eth_link_status_clear(struct al_hal_eth_adapter *adapter)3920{3921int status = 0;39223923if (AL_ETH_IS_10G_MAC(adapter->mac_mode) || AL_ETH_IS_25G_MAC(adapter->mac_mode)) {3924al_reg_write32(&adapter->mac_regs_base->kr.pcs_addr, ETH_MAC_KR_PCS_BASE_R_STATUS2);3925al_reg_read32(&adapter->mac_regs_base->kr.pcs_data);39263927al_reg_read32(&adapter->mac_regs_base->mac_10g.status);3928} else {3929status = -1;3930}39313932return status;3933}39343935/** set LED mode and value */3936int al_eth_led_set(struct al_hal_eth_adapter *adapter, al_bool link_is_up)3937{3938uint32_t reg = 0;3939uint32_t mode = ETH_MAC_GEN_LED_CFG_SEL_DEFAULT_REG;39403941if (link_is_up)3942mode = ETH_MAC_GEN_LED_CFG_SEL_LINK_ACTIVITY;39433944AL_REG_FIELD_SET(reg, ETH_MAC_GEN_LED_CFG_SEL_MASK,3945ETH_MAC_GEN_LED_CFG_SEL_SHIFT, mode);39463947AL_REG_FIELD_SET(reg, ETH_MAC_GEN_LED_CFG_BLINK_TIMER_MASK,3948ETH_MAC_GEN_LED_CFG_BLINK_TIMER_SHIFT,3949ETH_MAC_GEN_LED_CFG_BLINK_TIMER_VAL);39503951AL_REG_FIELD_SET(reg, ETH_MAC_GEN_LED_CFG_ACT_TIMER_MASK,3952ETH_MAC_GEN_LED_CFG_ACT_TIMER_SHIFT,3953ETH_MAC_GEN_LED_CFG_ACT_TIMER_VAL);39543955al_reg_write32(&adapter->mac_regs_base->gen.led_cfg, reg);39563957return 0;3958}39593960/* get statistics */3961int al_eth_mac_stats_get(struct al_hal_eth_adapter *adapter, struct al_eth_mac_stats *stats)3962{3963al_assert(stats);39643965al_memset(stats, 0, sizeof(struct al_eth_mac_stats));39663967if (AL_ETH_IS_1G_MAC(adapter->mac_mode)) {3968struct al_eth_mac_1g_stats __iomem *reg_stats =3969&adapter->mac_regs_base->mac_1g.stats;39703971stats->ifInUcastPkts = al_reg_read32(®_stats->ifInUcastPkts);3972stats->ifInMulticastPkts = al_reg_read32(®_stats->ifInMulticastPkts);3973stats->ifInBroadcastPkts = al_reg_read32(®_stats->ifInBroadcastPkts);3974stats->etherStatsPkts = al_reg_read32(®_stats->etherStatsPkts);3975stats->ifOutUcastPkts = al_reg_read32(®_stats->ifOutUcastPkts);3976stats->ifOutMulticastPkts = al_reg_read32(®_stats->ifOutMulticastPkts);3977stats->ifOutBroadcastPkts = al_reg_read32(®_stats->ifOutBroadcastPkts);3978stats->ifInErrors = al_reg_read32(®_stats->ifInErrors);3979stats->ifOutErrors = al_reg_read32(®_stats->ifOutErrors);3980stats->aFramesReceivedOK = al_reg_read32(®_stats->aFramesReceivedOK);3981stats->aFramesTransmittedOK = al_reg_read32(®_stats->aFramesTransmittedOK);3982stats->aOctetsReceivedOK = al_reg_read32(®_stats->aOctetsReceivedOK);3983stats->aOctetsTransmittedOK = al_reg_read32(®_stats->aOctetsTransmittedOK);3984stats->etherStatsUndersizePkts = al_reg_read32(®_stats->etherStatsUndersizePkts);3985stats->etherStatsFragments = al_reg_read32(®_stats->etherStatsFragments);3986stats->etherStatsJabbers = al_reg_read32(®_stats->etherStatsJabbers);3987stats->etherStatsOversizePkts = al_reg_read32(®_stats->etherStatsOversizePkts);3988stats->aFrameCheckSequenceErrors =3989al_reg_read32(®_stats->aFrameCheckSequenceErrors);3990stats->aAlignmentErrors = al_reg_read32(®_stats->aAlignmentErrors);3991stats->etherStatsDropEvents = al_reg_read32(®_stats->etherStatsDropEvents);3992stats->aPAUSEMACCtrlFramesTransmitted =3993al_reg_read32(®_stats->aPAUSEMACCtrlFramesTransmitted);3994stats->aPAUSEMACCtrlFramesReceived =3995al_reg_read32(®_stats->aPAUSEMACCtrlFramesReceived);3996stats->aFrameTooLongErrors = 0; /* N/A */3997stats->aInRangeLengthErrors = 0; /* N/A */3998stats->VLANTransmittedOK = 0; /* N/A */3999stats->VLANReceivedOK = 0; /* N/A */4000stats->etherStatsOctets = al_reg_read32(®_stats->etherStatsOctets);4001stats->etherStatsPkts64Octets = al_reg_read32(®_stats->etherStatsPkts64Octets);4002stats->etherStatsPkts65to127Octets =4003al_reg_read32(®_stats->etherStatsPkts65to127Octets);4004stats->etherStatsPkts128to255Octets =4005al_reg_read32(®_stats->etherStatsPkts128to255Octets);4006stats->etherStatsPkts256to511Octets =4007al_reg_read32(®_stats->etherStatsPkts256to511Octets);4008stats->etherStatsPkts512to1023Octets =4009al_reg_read32(®_stats->etherStatsPkts512to1023Octets);4010stats->etherStatsPkts1024to1518Octets =4011al_reg_read32(®_stats->etherStatsPkts1024to1518Octets);4012stats->etherStatsPkts1519toX = al_reg_read32(®_stats->etherStatsPkts1519toX);4013} else if (AL_ETH_IS_10G_MAC(adapter->mac_mode) || AL_ETH_IS_25G_MAC(adapter->mac_mode)) {4014if (adapter->rev_id < AL_ETH_REV_ID_3) {4015struct al_eth_mac_10g_stats_v2 __iomem *reg_stats =4016&adapter->mac_regs_base->mac_10g.stats.v2;4017uint64_t octets;40184019stats->ifInUcastPkts = al_reg_read32(®_stats->ifInUcastPkts);4020stats->ifInMulticastPkts = al_reg_read32(®_stats->ifInMulticastPkts);4021stats->ifInBroadcastPkts = al_reg_read32(®_stats->ifInBroadcastPkts);4022stats->etherStatsPkts = al_reg_read32(®_stats->etherStatsPkts);4023stats->ifOutUcastPkts = al_reg_read32(®_stats->ifOutUcastPkts);4024stats->ifOutMulticastPkts = al_reg_read32(®_stats->ifOutMulticastPkts);4025stats->ifOutBroadcastPkts = al_reg_read32(®_stats->ifOutBroadcastPkts);4026stats->ifInErrors = al_reg_read32(®_stats->ifInErrors);4027stats->ifOutErrors = al_reg_read32(®_stats->ifOutErrors);4028stats->aFramesReceivedOK = al_reg_read32(®_stats->aFramesReceivedOK);4029stats->aFramesTransmittedOK = al_reg_read32(®_stats->aFramesTransmittedOK);40304031/* aOctetsReceivedOK = ifInOctets - 18 * aFramesReceivedOK - 4 * VLANReceivedOK */4032octets = al_reg_read32(®_stats->ifInOctetsL);4033octets |= (uint64_t)(al_reg_read32(®_stats->ifInOctetsH)) << 32;4034octets -= 18 * stats->aFramesReceivedOK;4035octets -= 4 * al_reg_read32(®_stats->VLANReceivedOK);4036stats->aOctetsReceivedOK = octets;40374038/* aOctetsTransmittedOK = ifOutOctets - 18 * aFramesTransmittedOK - 4 * VLANTransmittedOK */4039octets = al_reg_read32(®_stats->ifOutOctetsL);4040octets |= (uint64_t)(al_reg_read32(®_stats->ifOutOctetsH)) << 32;4041octets -= 18 * stats->aFramesTransmittedOK;4042octets -= 4 * al_reg_read32(®_stats->VLANTransmittedOK);4043stats->aOctetsTransmittedOK = octets;40444045stats->etherStatsUndersizePkts = al_reg_read32(®_stats->etherStatsUndersizePkts);4046stats->etherStatsFragments = al_reg_read32(®_stats->etherStatsFragments);4047stats->etherStatsJabbers = al_reg_read32(®_stats->etherStatsJabbers);4048stats->etherStatsOversizePkts = al_reg_read32(®_stats->etherStatsOversizePkts);4049stats->aFrameCheckSequenceErrors = al_reg_read32(®_stats->aFrameCheckSequenceErrors);4050stats->aAlignmentErrors = al_reg_read32(®_stats->aAlignmentErrors);4051stats->etherStatsDropEvents = al_reg_read32(®_stats->etherStatsDropEvents);4052stats->aPAUSEMACCtrlFramesTransmitted = al_reg_read32(®_stats->aPAUSEMACCtrlFramesTransmitted);4053stats->aPAUSEMACCtrlFramesReceived = al_reg_read32(®_stats->aPAUSEMACCtrlFramesReceived);4054stats->aFrameTooLongErrors = al_reg_read32(®_stats->aFrameTooLongErrors);4055stats->aInRangeLengthErrors = al_reg_read32(®_stats->aInRangeLengthErrors);4056stats->VLANTransmittedOK = al_reg_read32(®_stats->VLANTransmittedOK);4057stats->VLANReceivedOK = al_reg_read32(®_stats->VLANReceivedOK);4058stats->etherStatsOctets = al_reg_read32(®_stats->etherStatsOctets);4059stats->etherStatsPkts64Octets = al_reg_read32(®_stats->etherStatsPkts64Octets);4060stats->etherStatsPkts65to127Octets = al_reg_read32(®_stats->etherStatsPkts65to127Octets);4061stats->etherStatsPkts128to255Octets = al_reg_read32(®_stats->etherStatsPkts128to255Octets);4062stats->etherStatsPkts256to511Octets = al_reg_read32(®_stats->etherStatsPkts256to511Octets);4063stats->etherStatsPkts512to1023Octets = al_reg_read32(®_stats->etherStatsPkts512to1023Octets);4064stats->etherStatsPkts1024to1518Octets = al_reg_read32(®_stats->etherStatsPkts1024to1518Octets);4065stats->etherStatsPkts1519toX = al_reg_read32(®_stats->etherStatsPkts1519toX);4066} else {4067struct al_eth_mac_10g_stats_v3_rx __iomem *reg_rx_stats =4068&adapter->mac_regs_base->mac_10g.stats.v3.rx;4069struct al_eth_mac_10g_stats_v3_tx __iomem *reg_tx_stats =4070&adapter->mac_regs_base->mac_10g.stats.v3.tx;4071uint64_t octets;40724073stats->ifInUcastPkts = al_reg_read32(®_rx_stats->ifInUcastPkts);4074stats->ifInMulticastPkts = al_reg_read32(®_rx_stats->ifInMulticastPkts);4075stats->ifInBroadcastPkts = al_reg_read32(®_rx_stats->ifInBroadcastPkts);4076stats->etherStatsPkts = al_reg_read32(®_rx_stats->etherStatsPkts);4077stats->ifOutUcastPkts = al_reg_read32(®_tx_stats->ifUcastPkts);4078stats->ifOutMulticastPkts = al_reg_read32(®_tx_stats->ifMulticastPkts);4079stats->ifOutBroadcastPkts = al_reg_read32(®_tx_stats->ifBroadcastPkts);4080stats->ifInErrors = al_reg_read32(®_rx_stats->ifInErrors);4081stats->ifOutErrors = al_reg_read32(®_tx_stats->ifOutErrors);4082stats->aFramesReceivedOK = al_reg_read32(®_rx_stats->FramesOK);4083stats->aFramesTransmittedOK = al_reg_read32(®_tx_stats->FramesOK);40844085/* aOctetsReceivedOK = ifInOctets - 18 * aFramesReceivedOK - 4 * VLANReceivedOK */4086octets = al_reg_read32(®_rx_stats->ifOctetsL);4087octets |= (uint64_t)(al_reg_read32(®_rx_stats->ifOctetsH)) << 32;4088octets -= 18 * stats->aFramesReceivedOK;4089octets -= 4 * al_reg_read32(®_rx_stats->VLANOK);4090stats->aOctetsReceivedOK = octets;40914092/* aOctetsTransmittedOK = ifOutOctets - 18 * aFramesTransmittedOK - 4 * VLANTransmittedOK */4093octets = al_reg_read32(®_tx_stats->ifOctetsL);4094octets |= (uint64_t)(al_reg_read32(®_tx_stats->ifOctetsH)) << 32;4095octets -= 18 * stats->aFramesTransmittedOK;4096octets -= 4 * al_reg_read32(®_tx_stats->VLANOK);4097stats->aOctetsTransmittedOK = octets;40984099stats->etherStatsUndersizePkts = al_reg_read32(®_rx_stats->etherStatsUndersizePkts);4100stats->etherStatsFragments = al_reg_read32(®_rx_stats->etherStatsFragments);4101stats->etherStatsJabbers = al_reg_read32(®_rx_stats->etherStatsJabbers);4102stats->etherStatsOversizePkts = al_reg_read32(®_rx_stats->etherStatsOversizePkts);4103stats->aFrameCheckSequenceErrors = al_reg_read32(®_rx_stats->CRCErrors);4104stats->aAlignmentErrors = al_reg_read32(®_rx_stats->aAlignmentErrors);4105stats->etherStatsDropEvents = al_reg_read32(®_rx_stats->etherStatsDropEvents);4106stats->aPAUSEMACCtrlFramesTransmitted = al_reg_read32(®_tx_stats->aPAUSEMACCtrlFrames);4107stats->aPAUSEMACCtrlFramesReceived = al_reg_read32(®_rx_stats->aPAUSEMACCtrlFrames);4108stats->aFrameTooLongErrors = al_reg_read32(®_rx_stats->aFrameTooLong);4109stats->aInRangeLengthErrors = al_reg_read32(®_rx_stats->aInRangeLengthErrors);4110stats->VLANTransmittedOK = al_reg_read32(®_tx_stats->VLANOK);4111stats->VLANReceivedOK = al_reg_read32(®_rx_stats->VLANOK);4112stats->etherStatsOctets = al_reg_read32(®_rx_stats->etherStatsOctets);4113stats->etherStatsPkts64Octets = al_reg_read32(®_rx_stats->etherStatsPkts64Octets);4114stats->etherStatsPkts65to127Octets = al_reg_read32(®_rx_stats->etherStatsPkts65to127Octets);4115stats->etherStatsPkts128to255Octets = al_reg_read32(®_rx_stats->etherStatsPkts128to255Octets);4116stats->etherStatsPkts256to511Octets = al_reg_read32(®_rx_stats->etherStatsPkts256to511Octets);4117stats->etherStatsPkts512to1023Octets = al_reg_read32(®_rx_stats->etherStatsPkts512to1023Octets);4118stats->etherStatsPkts1024to1518Octets = al_reg_read32(®_rx_stats->etherStatsPkts1024to1518Octets);4119stats->etherStatsPkts1519toX = al_reg_read32(®_rx_stats->etherStatsPkts1519toMax);4120}4121} else {4122struct al_eth_mac_10g_stats_v3_rx __iomem *reg_rx_stats =4123&adapter->mac_regs_base->mac_10g.stats.v3.rx;4124struct al_eth_mac_10g_stats_v3_tx __iomem *reg_tx_stats =4125&adapter->mac_regs_base->mac_10g.stats.v3.tx;4126uint64_t octets;41274128/* 40G MAC statistics registers are the same, only read indirectly */4129#define _40g_mac_reg_read32(field) al_eth_40g_mac_reg_read(adapter, \4130((uint8_t *)(field)) - ((uint8_t *)&adapter->mac_regs_base->mac_10g))41314132stats->ifInUcastPkts = _40g_mac_reg_read32(®_rx_stats->ifInUcastPkts);4133stats->ifInMulticastPkts = _40g_mac_reg_read32(®_rx_stats->ifInMulticastPkts);4134stats->ifInBroadcastPkts = _40g_mac_reg_read32(®_rx_stats->ifInBroadcastPkts);4135stats->etherStatsPkts = _40g_mac_reg_read32(®_rx_stats->etherStatsPkts);4136stats->ifOutUcastPkts = _40g_mac_reg_read32(®_tx_stats->ifUcastPkts);4137stats->ifOutMulticastPkts = _40g_mac_reg_read32(®_tx_stats->ifMulticastPkts);4138stats->ifOutBroadcastPkts = _40g_mac_reg_read32(®_tx_stats->ifBroadcastPkts);4139stats->ifInErrors = _40g_mac_reg_read32(®_rx_stats->ifInErrors);4140stats->ifOutErrors = _40g_mac_reg_read32(®_tx_stats->ifOutErrors);4141stats->aFramesReceivedOK = _40g_mac_reg_read32(®_rx_stats->FramesOK);4142stats->aFramesTransmittedOK = _40g_mac_reg_read32(®_tx_stats->FramesOK);41434144/* aOctetsReceivedOK = ifInOctets - 18 * aFramesReceivedOK - 4 * VLANReceivedOK */4145octets = _40g_mac_reg_read32(®_rx_stats->ifOctetsL);4146octets |= (uint64_t)(_40g_mac_reg_read32(®_rx_stats->ifOctetsH)) << 32;4147octets -= 18 * stats->aFramesReceivedOK;4148octets -= 4 * _40g_mac_reg_read32(®_rx_stats->VLANOK);4149stats->aOctetsReceivedOK = octets;41504151/* aOctetsTransmittedOK = ifOutOctets - 18 * aFramesTransmittedOK - 4 * VLANTransmittedOK */4152octets = _40g_mac_reg_read32(®_tx_stats->ifOctetsL);4153octets |= (uint64_t)(_40g_mac_reg_read32(®_tx_stats->ifOctetsH)) << 32;4154octets -= 18 * stats->aFramesTransmittedOK;4155octets -= 4 * _40g_mac_reg_read32(®_tx_stats->VLANOK);4156stats->aOctetsTransmittedOK = octets;41574158stats->etherStatsUndersizePkts = _40g_mac_reg_read32(®_rx_stats->etherStatsUndersizePkts);4159stats->etherStatsFragments = _40g_mac_reg_read32(®_rx_stats->etherStatsFragments);4160stats->etherStatsJabbers = _40g_mac_reg_read32(®_rx_stats->etherStatsJabbers);4161stats->etherStatsOversizePkts = _40g_mac_reg_read32(®_rx_stats->etherStatsOversizePkts);4162stats->aFrameCheckSequenceErrors = _40g_mac_reg_read32(®_rx_stats->CRCErrors);4163stats->aAlignmentErrors = _40g_mac_reg_read32(®_rx_stats->aAlignmentErrors);4164stats->etherStatsDropEvents = _40g_mac_reg_read32(®_rx_stats->etherStatsDropEvents);4165stats->aPAUSEMACCtrlFramesTransmitted = _40g_mac_reg_read32(®_tx_stats->aPAUSEMACCtrlFrames);4166stats->aPAUSEMACCtrlFramesReceived = _40g_mac_reg_read32(®_rx_stats->aPAUSEMACCtrlFrames);4167stats->aFrameTooLongErrors = _40g_mac_reg_read32(®_rx_stats->aFrameTooLong);4168stats->aInRangeLengthErrors = _40g_mac_reg_read32(®_rx_stats->aInRangeLengthErrors);4169stats->VLANTransmittedOK = _40g_mac_reg_read32(®_tx_stats->VLANOK);4170stats->VLANReceivedOK = _40g_mac_reg_read32(®_rx_stats->VLANOK);4171stats->etherStatsOctets = _40g_mac_reg_read32(®_rx_stats->etherStatsOctets);4172stats->etherStatsPkts64Octets = _40g_mac_reg_read32(®_rx_stats->etherStatsPkts64Octets);4173stats->etherStatsPkts65to127Octets = _40g_mac_reg_read32(®_rx_stats->etherStatsPkts65to127Octets);4174stats->etherStatsPkts128to255Octets = _40g_mac_reg_read32(®_rx_stats->etherStatsPkts128to255Octets);4175stats->etherStatsPkts256to511Octets = _40g_mac_reg_read32(®_rx_stats->etherStatsPkts256to511Octets);4176stats->etherStatsPkts512to1023Octets = _40g_mac_reg_read32(®_rx_stats->etherStatsPkts512to1023Octets);4177stats->etherStatsPkts1024to1518Octets = _40g_mac_reg_read32(®_rx_stats->etherStatsPkts1024to1518Octets);4178stats->etherStatsPkts1519toX = _40g_mac_reg_read32(®_rx_stats->etherStatsPkts1519toMax);4179}41804181stats->eee_in = al_reg_read32(&adapter->mac_regs_base->stat.eee_in);4182stats->eee_out = al_reg_read32(&adapter->mac_regs_base->stat.eee_out);41834184/* stats->etherStatsPkts = 1; */4185return 0;4186}41874188/**4189* read ec_stat_counters4190*/4191int al_eth_ec_stats_get(struct al_hal_eth_adapter *adapter, struct al_eth_ec_stats *stats)4192{4193al_assert(stats);4194stats->faf_in_rx_pkt = al_reg_read32(&adapter->ec_regs_base->stat.faf_in_rx_pkt);4195stats->faf_in_rx_short = al_reg_read32(&adapter->ec_regs_base->stat.faf_in_rx_short);4196stats->faf_in_rx_long = al_reg_read32(&adapter->ec_regs_base->stat.faf_in_rx_long);4197stats->faf_out_rx_pkt = al_reg_read32(&adapter->ec_regs_base->stat.faf_out_rx_pkt);4198stats->faf_out_rx_short = al_reg_read32(&adapter->ec_regs_base->stat.faf_out_rx_short);4199stats->faf_out_rx_long = al_reg_read32(&adapter->ec_regs_base->stat.faf_out_rx_long);4200stats->faf_out_drop = al_reg_read32(&adapter->ec_regs_base->stat.faf_out_drop);4201stats->rxf_in_rx_pkt = al_reg_read32(&adapter->ec_regs_base->stat.rxf_in_rx_pkt);4202stats->rxf_in_fifo_err = al_reg_read32(&adapter->ec_regs_base->stat.rxf_in_fifo_err);4203stats->lbf_in_rx_pkt = al_reg_read32(&adapter->ec_regs_base->stat.lbf_in_rx_pkt);4204stats->lbf_in_fifo_err = al_reg_read32(&adapter->ec_regs_base->stat.lbf_in_fifo_err);4205stats->rxf_out_rx_1_pkt = al_reg_read32(&adapter->ec_regs_base->stat.rxf_out_rx_1_pkt);4206stats->rxf_out_rx_2_pkt = al_reg_read32(&adapter->ec_regs_base->stat.rxf_out_rx_2_pkt);4207stats->rxf_out_drop_1_pkt = al_reg_read32(&adapter->ec_regs_base->stat.rxf_out_drop_1_pkt);4208stats->rxf_out_drop_2_pkt = al_reg_read32(&adapter->ec_regs_base->stat.rxf_out_drop_2_pkt);4209stats->rpe_1_in_rx_pkt = al_reg_read32(&adapter->ec_regs_base->stat.rpe_1_in_rx_pkt);4210stats->rpe_1_out_rx_pkt = al_reg_read32(&adapter->ec_regs_base->stat.rpe_1_out_rx_pkt);4211stats->rpe_2_in_rx_pkt = al_reg_read32(&adapter->ec_regs_base->stat.rpe_2_in_rx_pkt);4212stats->rpe_2_out_rx_pkt = al_reg_read32(&adapter->ec_regs_base->stat.rpe_2_out_rx_pkt);4213stats->rpe_3_in_rx_pkt = al_reg_read32(&adapter->ec_regs_base->stat.rpe_3_in_rx_pkt);4214stats->rpe_3_out_rx_pkt = al_reg_read32(&adapter->ec_regs_base->stat.rpe_3_out_rx_pkt);4215stats->tpe_in_tx_pkt = al_reg_read32(&adapter->ec_regs_base->stat.tpe_in_tx_pkt);4216stats->tpe_out_tx_pkt = al_reg_read32(&adapter->ec_regs_base->stat.tpe_out_tx_pkt);4217stats->tpm_tx_pkt = al_reg_read32(&adapter->ec_regs_base->stat.tpm_tx_pkt);4218stats->tfw_in_tx_pkt = al_reg_read32(&adapter->ec_regs_base->stat.tfw_in_tx_pkt);4219stats->tfw_out_tx_pkt = al_reg_read32(&adapter->ec_regs_base->stat.tfw_out_tx_pkt);4220stats->rfw_in_rx_pkt = al_reg_read32(&adapter->ec_regs_base->stat.rfw_in_rx_pkt);4221stats->rfw_in_vlan_drop = al_reg_read32(&adapter->ec_regs_base->stat.rfw_in_vlan_drop);4222stats->rfw_in_parse_drop = al_reg_read32(&adapter->ec_regs_base->stat.rfw_in_parse_drop);4223stats->rfw_in_mc = al_reg_read32(&adapter->ec_regs_base->stat.rfw_in_mc);4224stats->rfw_in_bc = al_reg_read32(&adapter->ec_regs_base->stat.rfw_in_bc);4225stats->rfw_in_vlan_exist = al_reg_read32(&adapter->ec_regs_base->stat.rfw_in_vlan_exist);4226stats->rfw_in_vlan_nexist = al_reg_read32(&adapter->ec_regs_base->stat.rfw_in_vlan_nexist);4227stats->rfw_in_mac_drop = al_reg_read32(&adapter->ec_regs_base->stat.rfw_in_mac_drop);4228stats->rfw_in_mac_ndet_drop = al_reg_read32(&adapter->ec_regs_base->stat.rfw_in_mac_ndet_drop);4229stats->rfw_in_ctrl_drop = al_reg_read32(&adapter->ec_regs_base->stat.rfw_in_ctrl_drop);4230stats->rfw_in_prot_i_drop = al_reg_read32(&adapter->ec_regs_base->stat.rfw_in_prot_i_drop);4231stats->eee_in = al_reg_read32(&adapter->ec_regs_base->stat.eee_in);4232return 0;4233}42344235/**4236* read per_udma_counters4237*/4238int al_eth_ec_stat_udma_get(struct al_hal_eth_adapter *adapter, uint8_t idx, struct al_eth_ec_stat_udma *stats)4239{42404241al_assert(idx <= 3); /*valid udma_id*/4242al_assert(stats);4243stats->rfw_out_rx_pkt = al_reg_read32(&adapter->ec_regs_base->stat_udma[idx].rfw_out_rx_pkt);4244stats->rfw_out_drop = al_reg_read32(&adapter->ec_regs_base->stat_udma[idx].rfw_out_drop);4245stats->msw_in_rx_pkt = al_reg_read32(&adapter->ec_regs_base->stat_udma[idx].msw_in_rx_pkt);4246stats->msw_drop_q_full = al_reg_read32(&adapter->ec_regs_base->stat_udma[idx].msw_drop_q_full);4247stats->msw_drop_sop = al_reg_read32(&adapter->ec_regs_base->stat_udma[idx].msw_drop_sop);4248stats->msw_drop_eop = al_reg_read32(&adapter->ec_regs_base->stat_udma[idx].msw_drop_eop);4249stats->msw_wr_eop = al_reg_read32(&adapter->ec_regs_base->stat_udma[idx].msw_wr_eop);4250stats->msw_out_rx_pkt = al_reg_read32(&adapter->ec_regs_base->stat_udma[idx].msw_out_rx_pkt);4251stats->tso_no_tso_pkt = al_reg_read32(&adapter->ec_regs_base->stat_udma[idx].tso_no_tso_pkt);4252stats->tso_tso_pkt = al_reg_read32(&adapter->ec_regs_base->stat_udma[idx].tso_tso_pkt);4253stats->tso_seg_pkt = al_reg_read32(&adapter->ec_regs_base->stat_udma[idx].tso_seg_pkt);4254stats->tso_pad_pkt = al_reg_read32(&adapter->ec_regs_base->stat_udma[idx].tso_pad_pkt);4255stats->tpm_tx_spoof = al_reg_read32(&adapter->ec_regs_base->stat_udma[idx].tpm_tx_spoof);4256stats->tmi_in_tx_pkt = al_reg_read32(&adapter->ec_regs_base->stat_udma[idx].tmi_in_tx_pkt);4257stats->tmi_out_to_mac = al_reg_read32(&adapter->ec_regs_base->stat_udma[idx].tmi_out_to_mac);4258stats->tmi_out_to_rx = al_reg_read32(&adapter->ec_regs_base->stat_udma[idx].tmi_out_to_rx);4259stats->tx_q0_bytes = al_reg_read32(&adapter->ec_regs_base->stat_udma[idx].tx_q0_bytes);4260stats->tx_q1_bytes = al_reg_read32(&adapter->ec_regs_base->stat_udma[idx].tx_q1_bytes);4261stats->tx_q2_bytes = al_reg_read32(&adapter->ec_regs_base->stat_udma[idx].tx_q2_bytes);4262stats->tx_q3_bytes = al_reg_read32(&adapter->ec_regs_base->stat_udma[idx].tx_q3_bytes);4263stats->tx_q0_pkts = al_reg_read32(&adapter->ec_regs_base->stat_udma[idx].tx_q0_pkts);4264stats->tx_q1_pkts = al_reg_read32(&adapter->ec_regs_base->stat_udma[idx].tx_q1_pkts);4265stats->tx_q2_pkts = al_reg_read32(&adapter->ec_regs_base->stat_udma[idx].tx_q2_pkts);4266stats->tx_q3_pkts = al_reg_read32(&adapter->ec_regs_base->stat_udma[idx].tx_q3_pkts);4267return 0;4268}42694270/* Traffic control */427142724273int al_eth_flr_rmn(int (* pci_read_config_u32)(void *handle, int where, uint32_t *val),4274int (* pci_write_config_u32)(void *handle, int where, uint32_t val),4275void *handle,4276void __iomem *mac_base)4277{4278struct al_eth_mac_regs __iomem *mac_regs_base =4279(struct al_eth_mac_regs __iomem *)mac_base;4280uint32_t cfg_reg_store[6];4281uint32_t reg;4282uint32_t mux_sel;4283int i = 0;42844285(*pci_read_config_u32)(handle, AL_ADAPTER_GENERIC_CONTROL_0, ®);42864287/* reset 1G mac */4288AL_REG_MASK_SET(reg, AL_ADAPTER_GENERIC_CONTROL_0_ETH_RESET_1GMAC);4289(*pci_write_config_u32)(handle, AL_ADAPTER_GENERIC_CONTROL_0, reg);4290al_udelay(1000);4291/* don't reset 1G mac */4292AL_REG_MASK_CLEAR(reg, AL_ADAPTER_GENERIC_CONTROL_0_ETH_RESET_1GMAC);4293/* prevent 1G mac reset on FLR */4294AL_REG_MASK_CLEAR(reg, AL_ADAPTER_GENERIC_CONTROL_0_ETH_RESET_1GMAC_ON_FLR);4295/* prevent adapter reset */4296(*pci_write_config_u32)(handle, AL_ADAPTER_GENERIC_CONTROL_0, reg);42974298mux_sel = al_reg_read32(&mac_regs_base->gen.mux_sel);42994300/* save pci register that get reset due to flr*/4301(*pci_read_config_u32)(handle, AL_PCI_COMMAND, &cfg_reg_store[i++]);4302(*pci_read_config_u32)(handle, 0xC, &cfg_reg_store[i++]);4303(*pci_read_config_u32)(handle, 0x10, &cfg_reg_store[i++]);4304(*pci_read_config_u32)(handle, 0x18, &cfg_reg_store[i++]);4305(*pci_read_config_u32)(handle, 0x20, &cfg_reg_store[i++]);4306(*pci_read_config_u32)(handle, 0x110, &cfg_reg_store[i++]);43074308/* do flr */4309(*pci_write_config_u32)(handle, AL_PCI_EXP_CAP_BASE + AL_PCI_EXP_DEVCTL, AL_PCI_EXP_DEVCTL_BCR_FLR);4310al_udelay(1000);4311/* restore command */4312i = 0;4313(*pci_write_config_u32)(handle, AL_PCI_COMMAND, cfg_reg_store[i++]);4314(*pci_write_config_u32)(handle, 0xC, cfg_reg_store[i++]);4315(*pci_write_config_u32)(handle, 0x10, cfg_reg_store[i++]);4316(*pci_write_config_u32)(handle, 0x18, cfg_reg_store[i++]);4317(*pci_write_config_u32)(handle, 0x20, cfg_reg_store[i++]);4318(*pci_write_config_u32)(handle, 0x110, cfg_reg_store[i++]);43194320al_reg_write32_masked(&mac_regs_base->gen.mux_sel, ETH_MAC_GEN_MUX_SEL_KR_IN_MASK, mux_sel);43214322/* set SGMII clock to 125MHz */4323al_reg_write32(&mac_regs_base->sgmii.clk_div, 0x03320501);43244325/* reset 1G mac */4326AL_REG_MASK_SET(reg, AL_ADAPTER_GENERIC_CONTROL_0_ETH_RESET_1GMAC);4327(*pci_write_config_u32)(handle, AL_ADAPTER_GENERIC_CONTROL_0, reg);43284329al_udelay(1000);43304331/* clear 1G mac reset */4332AL_REG_MASK_CLEAR(reg, AL_ADAPTER_GENERIC_CONTROL_0_ETH_RESET_1GMAC);4333(*pci_write_config_u32)(handle, AL_ADAPTER_GENERIC_CONTROL_0, reg);43344335/* reset SGMII mac clock to default */4336al_reg_write32(&mac_regs_base->sgmii.clk_div, 0x00320501);4337al_udelay(1000);4338/* reset async fifo */4339reg = al_reg_read32(&mac_regs_base->gen.sd_fifo_ctrl);4340AL_REG_MASK_SET(reg, 0xF0);4341al_reg_write32(&mac_regs_base->gen.sd_fifo_ctrl, reg);4342reg = al_reg_read32(&mac_regs_base->gen.sd_fifo_ctrl);4343AL_REG_MASK_CLEAR(reg, 0xF0);4344al_reg_write32(&mac_regs_base->gen.sd_fifo_ctrl, reg);43454346return 0;4347}43484349int al_eth_flr_rmn_restore_params(int (* pci_read_config_u32)(void *handle, int where, uint32_t *val),4350int (* pci_write_config_u32)(void *handle, int where, uint32_t val),4351void *handle,4352void __iomem *mac_base,4353void __iomem *ec_base,4354int mac_addresses_num4355)4356{4357struct al_eth_board_params params = { .media_type = 0 };4358uint8_t mac_addr[6];4359int rc;43604361/* not implemented yet */4362if (mac_addresses_num > 1)4363return -EPERM;43644365/* save board params so we restore it after reset */4366al_eth_board_params_get(mac_base, ¶ms);4367al_eth_mac_addr_read(ec_base, 0, mac_addr);43684369rc = al_eth_flr_rmn(pci_read_config_u32, pci_write_config_u32, handle, mac_base);4370al_eth_board_params_set(mac_base, ¶ms);4371al_eth_mac_addr_store(ec_base, 0, mac_addr);43724373return rc;4374}43754376/* board params register 1 */4377#define AL_HAL_ETH_MEDIA_TYPE_MASK (AL_FIELD_MASK(3, 0))4378#define AL_HAL_ETH_MEDIA_TYPE_SHIFT 04379#define AL_HAL_ETH_EXT_PHY_SHIFT 44380#define AL_HAL_ETH_PHY_ADDR_MASK (AL_FIELD_MASK(9, 5))4381#define AL_HAL_ETH_PHY_ADDR_SHIFT 54382#define AL_HAL_ETH_SFP_EXIST_SHIFT 104383#define AL_HAL_ETH_AN_ENABLE_SHIFT 114384#define AL_HAL_ETH_KR_LT_ENABLE_SHIFT 124385#define AL_HAL_ETH_KR_FEC_ENABLE_SHIFT 134386#define AL_HAL_ETH_MDIO_FREQ_MASK (AL_FIELD_MASK(15, 14))4387#define AL_HAL_ETH_MDIO_FREQ_SHIFT 144388#define AL_HAL_ETH_I2C_ADAPTER_ID_MASK (AL_FIELD_MASK(19, 16))4389#define AL_HAL_ETH_I2C_ADAPTER_ID_SHIFT 164390#define AL_HAL_ETH_EXT_PHY_IF_MASK (AL_FIELD_MASK(21, 20))4391#define AL_HAL_ETH_EXT_PHY_IF_SHIFT 204392#define AL_HAL_ETH_AUTO_NEG_MODE_SHIFT 224393#define AL_HAL_ETH_SERDES_GRP_2_SHIFT 234394#define AL_HAL_ETH_SERDES_GRP_MASK (AL_FIELD_MASK(26, 25))4395#define AL_HAL_ETH_SERDES_GRP_SHIFT 254396#define AL_HAL_ETH_SERDES_LANE_MASK (AL_FIELD_MASK(28, 27))4397#define AL_HAL_ETH_SERDES_LANE_SHIFT 274398#define AL_HAL_ETH_REF_CLK_FREQ_MASK (AL_FIELD_MASK(31, 29))4399#define AL_HAL_ETH_REF_CLK_FREQ_SHIFT 2944004401/* board params register 2 */4402#define AL_HAL_ETH_DONT_OVERRIDE_SERDES_SHIFT 04403#define AL_HAL_ETH_1000_BASE_X_SHIFT 14404#define AL_HAL_ETH_1G_AN_DISABLE_SHIFT 24405#define AL_HAL_ETH_1G_SPEED_MASK (AL_FIELD_MASK(4, 3))4406#define AL_HAL_ETH_1G_SPEED_SHIFT 34407#define AL_HAL_ETH_1G_HALF_DUPLEX_SHIFT 54408#define AL_HAL_ETH_1G_FC_DISABLE_SHIFT 64409#define AL_HAL_ETH_RETIMER_EXIST_SHIFT 74410#define AL_HAL_ETH_RETIMER_BUS_ID_MASK (AL_FIELD_MASK(11, 8))4411#define AL_HAL_ETH_RETIMER_BUS_ID_SHIFT 84412#define AL_HAL_ETH_RETIMER_I2C_ADDR_MASK (AL_FIELD_MASK(18, 12))4413#define AL_HAL_ETH_RETIMER_I2C_ADDR_SHIFT 124414#define AL_HAL_ETH_RETIMER_CHANNEL_SHIFT 194415#define AL_HAL_ETH_DAC_LENGTH_MASK (AL_FIELD_MASK(23, 20))4416#define AL_HAL_ETH_DAC_LENGTH_SHIFT 204417#define AL_HAL_ETH_DAC_SHIFT 244418#define AL_HAL_ETH_RETIMER_TYPE_MASK (AL_FIELD_MASK(26, 25))4419#define AL_HAL_ETH_RETIMER_TYPE_SHIFT 254420#define AL_HAL_ETH_RETIMER_CHANNEL_2_MASK (AL_FIELD_MASK(28, 27))4421#define AL_HAL_ETH_RETIMER_CHANNEL_2_SHIFT 274422#define AL_HAL_ETH_RETIMER_TX_CHANNEL_MASK (AL_FIELD_MASK(31, 29))4423#define AL_HAL_ETH_RETIMER_TX_CHANNEL_SHIFT 2944244425/* board params register 3 */4426#define AL_HAL_ETH_GPIO_SFP_PRESENT_MASK (AL_FIELD_MASK(5, 0))4427#define AL_HAL_ETH_GPIO_SFP_PRESENT_SHIFT 044284429int al_eth_board_params_set(void * __iomem mac_base, struct al_eth_board_params *params)4430{4431struct al_eth_mac_regs __iomem *mac_regs_base =4432(struct al_eth_mac_regs __iomem *)mac_base;4433uint32_t reg = 0;44344435/* ************* Setting Board params register 1 **************** */4436AL_REG_FIELD_SET(reg, AL_HAL_ETH_MEDIA_TYPE_MASK,4437AL_HAL_ETH_MEDIA_TYPE_SHIFT, params->media_type);4438AL_REG_BIT_VAL_SET(reg, AL_HAL_ETH_EXT_PHY_SHIFT, params->phy_exist == AL_TRUE);4439AL_REG_FIELD_SET(reg, AL_HAL_ETH_PHY_ADDR_MASK,4440AL_HAL_ETH_PHY_ADDR_SHIFT, params->phy_mdio_addr);44414442AL_REG_BIT_VAL_SET(reg, AL_HAL_ETH_SFP_EXIST_SHIFT, params->sfp_plus_module_exist == AL_TRUE);44434444AL_REG_BIT_VAL_SET(reg, AL_HAL_ETH_AN_ENABLE_SHIFT, params->autoneg_enable == AL_TRUE);4445AL_REG_BIT_VAL_SET(reg, AL_HAL_ETH_KR_LT_ENABLE_SHIFT, params->kr_lt_enable == AL_TRUE);4446AL_REG_BIT_VAL_SET(reg, AL_HAL_ETH_KR_FEC_ENABLE_SHIFT, params->kr_fec_enable == AL_TRUE);4447AL_REG_FIELD_SET(reg, AL_HAL_ETH_MDIO_FREQ_MASK,4448AL_HAL_ETH_MDIO_FREQ_SHIFT, params->mdio_freq);4449AL_REG_FIELD_SET(reg, AL_HAL_ETH_I2C_ADAPTER_ID_MASK,4450AL_HAL_ETH_I2C_ADAPTER_ID_SHIFT, params->i2c_adapter_id);4451AL_REG_FIELD_SET(reg, AL_HAL_ETH_EXT_PHY_IF_MASK,4452AL_HAL_ETH_EXT_PHY_IF_SHIFT, params->phy_if);44534454AL_REG_BIT_VAL_SET(reg, AL_HAL_ETH_AUTO_NEG_MODE_SHIFT,4455params->an_mode == AL_ETH_BOARD_AUTONEG_IN_BAND);44564457AL_REG_FIELD_SET(reg, AL_HAL_ETH_SERDES_GRP_MASK,4458AL_HAL_ETH_SERDES_GRP_SHIFT, params->serdes_grp);44594460AL_REG_BIT_VAL_SET(reg, AL_HAL_ETH_SERDES_GRP_2_SHIFT,4461(params->serdes_grp & AL_BIT(2)) ? 1 : 0);44624463AL_REG_FIELD_SET(reg, AL_HAL_ETH_SERDES_LANE_MASK,4464AL_HAL_ETH_SERDES_LANE_SHIFT, params->serdes_lane);44654466AL_REG_FIELD_SET(reg, AL_HAL_ETH_REF_CLK_FREQ_MASK,4467AL_HAL_ETH_REF_CLK_FREQ_SHIFT, params->ref_clk_freq);44684469al_assert(reg != 0);44704471al_reg_write32(&mac_regs_base->mac_1g.scratch, reg);44724473/* ************* Setting Board params register 2 **************** */4474reg = 0;4475AL_REG_BIT_VAL_SET(reg, AL_HAL_ETH_DONT_OVERRIDE_SERDES_SHIFT,4476params->dont_override_serdes == AL_TRUE);44774478AL_REG_BIT_VAL_SET(reg, AL_HAL_ETH_1000_BASE_X_SHIFT,4479params->force_1000_base_x == AL_TRUE);44804481AL_REG_BIT_VAL_SET(reg, AL_HAL_ETH_1G_AN_DISABLE_SHIFT,4482params->an_disable == AL_TRUE);44834484AL_REG_FIELD_SET(reg, AL_HAL_ETH_1G_SPEED_MASK,4485AL_HAL_ETH_1G_SPEED_SHIFT, params->speed);44864487AL_REG_BIT_VAL_SET(reg, AL_HAL_ETH_1G_HALF_DUPLEX_SHIFT,4488params->half_duplex == AL_TRUE);44894490AL_REG_BIT_VAL_SET(reg, AL_HAL_ETH_1G_FC_DISABLE_SHIFT,4491params->fc_disable == AL_TRUE);44924493AL_REG_BIT_VAL_SET(reg, AL_HAL_ETH_RETIMER_EXIST_SHIFT, params->retimer_exist == AL_TRUE);4494AL_REG_FIELD_SET(reg, AL_HAL_ETH_RETIMER_BUS_ID_MASK,4495AL_HAL_ETH_RETIMER_BUS_ID_SHIFT, params->retimer_bus_id);4496AL_REG_FIELD_SET(reg, AL_HAL_ETH_RETIMER_I2C_ADDR_MASK,4497AL_HAL_ETH_RETIMER_I2C_ADDR_SHIFT, params->retimer_i2c_addr);44984499AL_REG_BIT_VAL_SET(reg, AL_HAL_ETH_RETIMER_CHANNEL_SHIFT,4500(params->retimer_channel & AL_BIT(0)));45014502AL_REG_FIELD_SET(reg, AL_HAL_ETH_RETIMER_CHANNEL_2_MASK,4503AL_HAL_ETH_RETIMER_CHANNEL_2_SHIFT,4504(AL_REG_FIELD_GET(params->retimer_channel, 0x6, 1)));45054506AL_REG_FIELD_SET(reg, AL_HAL_ETH_DAC_LENGTH_MASK,4507AL_HAL_ETH_DAC_LENGTH_SHIFT, params->dac_len);4508AL_REG_BIT_VAL_SET(reg, AL_HAL_ETH_DAC_SHIFT, params->dac);45094510AL_REG_FIELD_SET(reg, AL_HAL_ETH_RETIMER_TYPE_MASK,4511AL_HAL_ETH_RETIMER_TYPE_SHIFT, params->retimer_type);45124513AL_REG_FIELD_SET(reg, AL_HAL_ETH_RETIMER_TX_CHANNEL_MASK,4514AL_HAL_ETH_RETIMER_TX_CHANNEL_SHIFT,4515params->retimer_tx_channel);45164517al_reg_write32(&mac_regs_base->mac_10g.scratch, reg);45184519/* ************* Setting Board params register 3 **************** */4520reg = 0;45214522AL_REG_FIELD_SET(reg, AL_HAL_ETH_GPIO_SFP_PRESENT_MASK,4523AL_HAL_ETH_GPIO_SFP_PRESENT_SHIFT,4524params->gpio_sfp_present);45254526al_reg_write32(&mac_regs_base->mac_1g.mac_0, reg);45274528return 0;4529}45304531int al_eth_board_params_get(void * __iomem mac_base, struct al_eth_board_params *params)4532{4533struct al_eth_mac_regs __iomem *mac_regs_base =4534(struct al_eth_mac_regs __iomem *)mac_base;4535uint32_t reg = al_reg_read32(&mac_regs_base->mac_1g.scratch);45364537/* check if the register was initialized, 0 is not a valid value */4538if (reg == 0)4539return -ENOENT;45404541/* ************* Getting Board params register 1 **************** */4542params->media_type = AL_REG_FIELD_GET(reg, AL_HAL_ETH_MEDIA_TYPE_MASK,4543AL_HAL_ETH_MEDIA_TYPE_SHIFT);4544if (AL_REG_BIT_GET(reg, AL_HAL_ETH_EXT_PHY_SHIFT))4545params->phy_exist = AL_TRUE;4546else4547params->phy_exist = AL_FALSE;45484549params->phy_mdio_addr = AL_REG_FIELD_GET(reg, AL_HAL_ETH_PHY_ADDR_MASK,4550AL_HAL_ETH_PHY_ADDR_SHIFT);45514552if (AL_REG_BIT_GET(reg, AL_HAL_ETH_SFP_EXIST_SHIFT))4553params->sfp_plus_module_exist = AL_TRUE;4554else4555params->sfp_plus_module_exist = AL_FALSE;45564557if (AL_REG_BIT_GET(reg, AL_HAL_ETH_AN_ENABLE_SHIFT))4558params->autoneg_enable = AL_TRUE;4559else4560params->autoneg_enable = AL_FALSE;45614562if (AL_REG_BIT_GET(reg, AL_HAL_ETH_KR_LT_ENABLE_SHIFT))4563params->kr_lt_enable = AL_TRUE;4564else4565params->kr_lt_enable = AL_FALSE;45664567if (AL_REG_BIT_GET(reg, AL_HAL_ETH_KR_FEC_ENABLE_SHIFT))4568params->kr_fec_enable = AL_TRUE;4569else4570params->kr_fec_enable = AL_FALSE;45714572params->mdio_freq = AL_REG_FIELD_GET(reg,4573AL_HAL_ETH_MDIO_FREQ_MASK,4574AL_HAL_ETH_MDIO_FREQ_SHIFT);45754576params->i2c_adapter_id = AL_REG_FIELD_GET(reg,4577AL_HAL_ETH_I2C_ADAPTER_ID_MASK,4578AL_HAL_ETH_I2C_ADAPTER_ID_SHIFT);45794580params->phy_if = AL_REG_FIELD_GET(reg,4581AL_HAL_ETH_EXT_PHY_IF_MASK,4582AL_HAL_ETH_EXT_PHY_IF_SHIFT);45834584if (AL_REG_BIT_GET(reg, AL_HAL_ETH_AUTO_NEG_MODE_SHIFT))4585params->an_mode = AL_TRUE;4586else4587params->an_mode = AL_FALSE;45884589params->serdes_grp = AL_REG_FIELD_GET(reg,4590AL_HAL_ETH_SERDES_GRP_MASK,4591AL_HAL_ETH_SERDES_GRP_SHIFT);45924593params->serdes_grp |= (AL_REG_BIT_GET(reg, AL_HAL_ETH_SERDES_GRP_2_SHIFT) ? AL_BIT(2) : 0);45944595params->serdes_lane = AL_REG_FIELD_GET(reg,4596AL_HAL_ETH_SERDES_LANE_MASK,4597AL_HAL_ETH_SERDES_LANE_SHIFT);45984599params->ref_clk_freq = AL_REG_FIELD_GET(reg,4600AL_HAL_ETH_REF_CLK_FREQ_MASK,4601AL_HAL_ETH_REF_CLK_FREQ_SHIFT);46024603/* ************* Getting Board params register 2 **************** */4604reg = al_reg_read32(&mac_regs_base->mac_10g.scratch);4605if (AL_REG_BIT_GET(reg, AL_HAL_ETH_DONT_OVERRIDE_SERDES_SHIFT))4606params->dont_override_serdes = AL_TRUE;4607else4608params->dont_override_serdes = AL_FALSE;46094610if (AL_REG_BIT_GET(reg, AL_HAL_ETH_1000_BASE_X_SHIFT))4611params->force_1000_base_x = AL_TRUE;4612else4613params->force_1000_base_x = AL_FALSE;46144615if (AL_REG_BIT_GET(reg, AL_HAL_ETH_1G_AN_DISABLE_SHIFT))4616params->an_disable = AL_TRUE;4617else4618params->an_disable = AL_FALSE;46194620params->speed = AL_REG_FIELD_GET(reg,4621AL_HAL_ETH_1G_SPEED_MASK,4622AL_HAL_ETH_1G_SPEED_SHIFT);46234624if (AL_REG_BIT_GET(reg, AL_HAL_ETH_1G_HALF_DUPLEX_SHIFT))4625params->half_duplex = AL_TRUE;4626else4627params->half_duplex = AL_FALSE;46284629if (AL_REG_BIT_GET(reg, AL_HAL_ETH_1G_FC_DISABLE_SHIFT))4630params->fc_disable = AL_TRUE;4631else4632params->fc_disable = AL_FALSE;46334634if (AL_REG_BIT_GET(reg, AL_HAL_ETH_RETIMER_EXIST_SHIFT))4635params->retimer_exist = AL_TRUE;4636else4637params->retimer_exist = AL_FALSE;46384639params->retimer_bus_id = AL_REG_FIELD_GET(reg,4640AL_HAL_ETH_RETIMER_BUS_ID_MASK,4641AL_HAL_ETH_RETIMER_BUS_ID_SHIFT);4642params->retimer_i2c_addr = AL_REG_FIELD_GET(reg,4643AL_HAL_ETH_RETIMER_I2C_ADDR_MASK,4644AL_HAL_ETH_RETIMER_I2C_ADDR_SHIFT);46454646params->retimer_channel =4647((AL_REG_BIT_GET(reg, AL_HAL_ETH_RETIMER_CHANNEL_SHIFT)) |4648(AL_REG_FIELD_GET(reg, AL_HAL_ETH_RETIMER_CHANNEL_2_MASK,4649AL_HAL_ETH_RETIMER_CHANNEL_2_SHIFT) << 1));46504651params->dac_len = AL_REG_FIELD_GET(reg,4652AL_HAL_ETH_DAC_LENGTH_MASK,4653AL_HAL_ETH_DAC_LENGTH_SHIFT);46544655if (AL_REG_BIT_GET(reg, AL_HAL_ETH_DAC_SHIFT))4656params->dac = AL_TRUE;4657else4658params->dac = AL_FALSE;46594660params->retimer_type = AL_REG_FIELD_GET(reg,4661AL_HAL_ETH_RETIMER_TYPE_MASK,4662AL_HAL_ETH_RETIMER_TYPE_SHIFT);46634664params->retimer_tx_channel = AL_REG_FIELD_GET(reg,4665AL_HAL_ETH_RETIMER_TX_CHANNEL_MASK,4666AL_HAL_ETH_RETIMER_TX_CHANNEL_SHIFT);46674668/* ************* Getting Board params register 3 **************** */4669reg = al_reg_read32(&mac_regs_base->mac_1g.mac_0);46704671params->gpio_sfp_present = AL_REG_FIELD_GET(reg,4672AL_HAL_ETH_GPIO_SFP_PRESENT_MASK,4673AL_HAL_ETH_GPIO_SFP_PRESENT_SHIFT);46744675return 0;4676}46774678/* Wake-On-Lan (WoL) */4679static inline void al_eth_byte_arr_to_reg(4680uint32_t *reg, uint8_t *arr, unsigned int num_bytes)4681{4682uint32_t mask = 0xff;4683unsigned int i;46844685al_assert(num_bytes <= 4);46864687*reg = 0;46884689for (i = 0 ; i < num_bytes ; i++) {4690AL_REG_FIELD_SET(*reg, mask, (sizeof(uint8_t) * i), arr[i]);4691mask = mask << sizeof(uint8_t);4692}4693}46944695int al_eth_wol_enable(4696struct al_hal_eth_adapter *adapter,4697struct al_eth_wol_params *wol)4698{4699uint32_t reg = 0;47004701if (wol->int_mask & AL_ETH_WOL_INT_MAGIC_PSWD) {4702al_assert(wol->pswd != NULL);47034704al_eth_byte_arr_to_reg(®, &wol->pswd[0], 4);4705al_reg_write32(&adapter->ec_regs_base->wol.magic_pswd_l, reg);47064707al_eth_byte_arr_to_reg(®, &wol->pswd[4], 2);4708al_reg_write32(&adapter->ec_regs_base->wol.magic_pswd_h, reg);4709}47104711if (wol->int_mask & AL_ETH_WOL_INT_IPV4) {4712al_assert(wol->ipv4 != NULL);47134714al_eth_byte_arr_to_reg(®, &wol->ipv4[0], 4);4715al_reg_write32(&adapter->ec_regs_base->wol.ipv4_dip, reg);4716}47174718if (wol->int_mask & AL_ETH_WOL_INT_IPV6) {4719al_assert(wol->ipv6 != NULL);47204721al_eth_byte_arr_to_reg(®, &wol->ipv6[0], 4);4722al_reg_write32(&adapter->ec_regs_base->wol.ipv6_dip_word0, reg);47234724al_eth_byte_arr_to_reg(®, &wol->ipv6[4], 4);4725al_reg_write32(&adapter->ec_regs_base->wol.ipv6_dip_word1, reg);47264727al_eth_byte_arr_to_reg(®, &wol->ipv6[8], 4);4728al_reg_write32(&adapter->ec_regs_base->wol.ipv6_dip_word2, reg);47294730al_eth_byte_arr_to_reg(®, &wol->ipv6[12], 4);4731al_reg_write32(&adapter->ec_regs_base->wol.ipv6_dip_word3, reg);4732}47334734if (wol->int_mask &4735(AL_ETH_WOL_INT_ETHERTYPE_BC | AL_ETH_WOL_INT_ETHERTYPE_DA)) {47364737reg = ((uint32_t)wol->ethr_type2 << 16);4738reg |= wol->ethr_type1;47394740al_reg_write32(&adapter->ec_regs_base->wol.ethertype, reg);4741}47424743/* make sure we dont forwarding packets without interrupt */4744al_assert((wol->forward_mask | wol->int_mask) == wol->int_mask);47454746reg = ((uint32_t)wol->forward_mask << 16);4747reg |= wol->int_mask;4748al_reg_write32(&adapter->ec_regs_base->wol.wol_en, reg);47494750return 0;4751}47524753int al_eth_wol_disable(4754struct al_hal_eth_adapter *adapter)4755{4756al_reg_write32(&adapter->ec_regs_base->wol.wol_en, 0);47574758return 0;4759}47604761int al_eth_tx_fwd_vid_table_set(struct al_hal_eth_adapter *adapter, uint32_t idx,4762uint8_t udma_mask, al_bool fwd_to_mac)4763{4764uint32_t val = 0;4765al_assert(idx < AL_ETH_FWD_VID_TABLE_NUM); /* valid VID index */4766AL_REG_FIELD_SET(val, AL_ETH_TX_VLAN_TABLE_UDMA_MASK, 0, udma_mask);4767AL_REG_FIELD_SET(val, AL_ETH_TX_VLAN_TABLE_FWD_TO_MAC, 4, fwd_to_mac);47684769al_reg_write32(&adapter->ec_regs_base->tfw.tx_vid_table_addr, idx);4770al_reg_write32(&adapter->ec_regs_base->tfw.tx_vid_table_data, val);4771return 0;4772}47734774int al_eth_tx_protocol_detect_table_entry_set(struct al_hal_eth_adapter *adapter, uint32_t idx,4775struct al_eth_tx_gpd_cam_entry *tx_gpd_entry)4776{4777uint64_t gpd_data;4778uint64_t gpd_mask;47794780gpd_data = ((uint64_t)tx_gpd_entry->l3_proto_idx & AL_ETH_TX_GPD_L3_PROTO_MASK) <<4781AL_ETH_TX_GPD_L3_PROTO_SHIFT;4782gpd_data |= ((uint64_t)tx_gpd_entry->l4_proto_idx & AL_ETH_TX_GPD_L4_PROTO_MASK) <<4783AL_ETH_TX_GPD_L4_PROTO_SHIFT;4784gpd_data |= ((uint64_t)tx_gpd_entry->tunnel_control & AL_ETH_TX_GPD_TUNNEL_CTRL_MASK) <<4785AL_ETH_TX_GPD_TUNNEL_CTRL_SHIFT;4786gpd_data |= ((uint64_t)tx_gpd_entry->source_vlan_count & AL_ETH_TX_GPD_SRC_VLAN_CNT_MASK) <<4787AL_ETH_TX_GPD_SRC_VLAN_CNT_SHIFT;4788gpd_mask = ((uint64_t)tx_gpd_entry->l3_proto_idx_mask & AL_ETH_TX_GPD_L3_PROTO_MASK) <<4789AL_ETH_TX_GPD_L3_PROTO_SHIFT;4790gpd_mask |= ((uint64_t)tx_gpd_entry->l4_proto_idx_mask & AL_ETH_TX_GPD_L4_PROTO_MASK) <<4791AL_ETH_TX_GPD_L4_PROTO_SHIFT;4792gpd_mask |= ((uint64_t)tx_gpd_entry->tunnel_control_mask & AL_ETH_TX_GPD_TUNNEL_CTRL_MASK) <<4793AL_ETH_TX_GPD_TUNNEL_CTRL_SHIFT;4794gpd_mask |= ((uint64_t)tx_gpd_entry->source_vlan_count_mask & AL_ETH_TX_GPD_SRC_VLAN_CNT_MASK) <<4795AL_ETH_TX_GPD_SRC_VLAN_CNT_SHIFT;47964797/* Tx Generic protocol detect Cam compare table */4798al_reg_write32(&adapter->ec_regs_base->tfw_v3.tx_gpd_cam_addr, idx);4799al_reg_write32(&adapter->ec_regs_base->tfw_v3.tx_gpd_cam_ctrl,4800(uint32_t)((tx_gpd_entry->tx_gpd_cam_ctrl) << AL_ETH_TX_GPD_CAM_CTRL_VALID_SHIFT));4801al_dbg("al_eth_tx_generic_crc_entry_set, line [%d], tx_gpd_cam_ctrl: %#x", idx, tx_gpd_entry->tx_gpd_cam_ctrl);4802al_reg_write32(&adapter->ec_regs_base->tfw_v3.tx_gpd_cam_mask_2,4803(uint32_t)(gpd_mask >> AL_ETH_TX_GPD_CAM_MASK_2_SHIFT));4804al_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));4805al_reg_write32(&adapter->ec_regs_base->tfw_v3.tx_gpd_cam_mask_1,4806(uint32_t)(gpd_mask));4807al_dbg("al_eth_tx_generic_crc_entry_set, line [%d], tx_gpd_cam_mask_1: %#x", idx, (uint32_t)(gpd_mask));4808al_reg_write32(&adapter->ec_regs_base->tfw_v3.tx_gpd_cam_data_2,4809(uint32_t)(gpd_data >> AL_ETH_TX_GPD_CAM_DATA_2_SHIFT));4810al_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));4811al_reg_write32(&adapter->ec_regs_base->tfw_v3.tx_gpd_cam_data_1,4812(uint32_t)(gpd_data));4813al_dbg("al_eth_tx_generic_crc_entry_set, line [%d], tx_gpd_cam_data_1: %#x", idx, (uint32_t)(gpd_data));4814return 0;4815}48164817int al_eth_tx_generic_crc_table_entry_set(struct al_hal_eth_adapter *adapter, uint32_t idx,4818struct al_eth_tx_gcp_table_entry *tx_gcp_entry)4819{4820uint32_t gcp_table_gen;4821uint32_t tx_alu_opcode;4822uint32_t tx_alu_opsel;48234824gcp_table_gen = (tx_gcp_entry->poly_sel & AL_ETH_TX_GCP_POLY_SEL_MASK) <<4825AL_ETH_TX_GCP_POLY_SEL_SHIFT;4826gcp_table_gen |= (tx_gcp_entry->crc32_bit_comp & AL_ETH_TX_GCP_CRC32_BIT_COMP_MASK) <<4827AL_ETH_TX_GCP_CRC32_BIT_COMP_SHIFT;4828gcp_table_gen |= (tx_gcp_entry->crc32_bit_swap & AL_ETH_TX_GCP_CRC32_BIT_SWAP_MASK) <<4829AL_ETH_TX_GCP_CRC32_BIT_SWAP_SHIFT;4830gcp_table_gen |= (tx_gcp_entry->crc32_byte_swap & AL_ETH_TX_GCP_CRC32_BYTE_SWAP_MASK) <<4831AL_ETH_TX_GCP_CRC32_BYTE_SWAP_SHIFT;4832gcp_table_gen |= (tx_gcp_entry->data_bit_swap & AL_ETH_TX_GCP_DATA_BIT_SWAP_MASK) <<4833AL_ETH_TX_GCP_DATA_BIT_SWAP_SHIFT;4834gcp_table_gen |= (tx_gcp_entry->data_byte_swap & AL_ETH_TX_GCP_DATA_BYTE_SWAP_MASK) <<4835AL_ETH_TX_GCP_DATA_BYTE_SWAP_SHIFT;4836gcp_table_gen |= (tx_gcp_entry->trail_size & AL_ETH_TX_GCP_TRAIL_SIZE_MASK) <<4837AL_ETH_TX_GCP_TRAIL_SIZE_SHIFT;4838gcp_table_gen |= (tx_gcp_entry->head_size & AL_ETH_TX_GCP_HEAD_SIZE_MASK) <<4839AL_ETH_TX_GCP_HEAD_SIZE_SHIFT;4840gcp_table_gen |= (tx_gcp_entry->head_calc & AL_ETH_TX_GCP_HEAD_CALC_MASK) <<4841AL_ETH_TX_GCP_HEAD_CALC_SHIFT;4842gcp_table_gen |= (tx_gcp_entry->mask_polarity & AL_ETH_TX_GCP_MASK_POLARITY_MASK) <<4843AL_ETH_TX_GCP_MASK_POLARITY_SHIFT;4844al_dbg("al_eth_tx_generic_crc_entry_set, line [%d], gcp_table_gen: %#x", idx, gcp_table_gen);48454846tx_alu_opcode = (tx_gcp_entry->tx_alu_opcode_1 & AL_ETH_TX_GCP_OPCODE_1_MASK) <<4847AL_ETH_TX_GCP_OPCODE_1_SHIFT;4848tx_alu_opcode |= (tx_gcp_entry->tx_alu_opcode_2 & AL_ETH_TX_GCP_OPCODE_2_MASK) <<4849AL_ETH_TX_GCP_OPCODE_2_SHIFT;4850tx_alu_opcode |= (tx_gcp_entry->tx_alu_opcode_3 & AL_ETH_TX_GCP_OPCODE_3_MASK) <<4851AL_ETH_TX_GCP_OPCODE_3_SHIFT;4852tx_alu_opsel = (tx_gcp_entry->tx_alu_opsel_1 & AL_ETH_TX_GCP_OPSEL_1_MASK) <<4853AL_ETH_TX_GCP_OPSEL_1_SHIFT;4854tx_alu_opsel |= (tx_gcp_entry->tx_alu_opsel_2 & AL_ETH_TX_GCP_OPSEL_2_MASK) <<4855AL_ETH_TX_GCP_OPSEL_2_SHIFT;4856tx_alu_opsel |= (tx_gcp_entry->tx_alu_opsel_3 & AL_ETH_TX_GCP_OPSEL_3_MASK) <<4857AL_ETH_TX_GCP_OPSEL_3_SHIFT;4858tx_alu_opsel |= (tx_gcp_entry->tx_alu_opsel_4 & AL_ETH_TX_GCP_OPSEL_4_MASK) <<4859AL_ETH_TX_GCP_OPSEL_4_SHIFT;48604861/* Tx Generic crc prameters table general */4862al_reg_write32(&adapter->ec_regs_base->tfw_v3.tx_gcp_table_addr, idx);4863al_reg_write32(&adapter->ec_regs_base->tfw_v3.tx_gcp_table_gen,4864gcp_table_gen);4865al_reg_write32(&adapter->ec_regs_base->tfw_v3.tx_gcp_table_mask_1,4866tx_gcp_entry->gcp_mask[0]);4867al_reg_write32(&adapter->ec_regs_base->tfw_v3.tx_gcp_table_mask_2,4868tx_gcp_entry->gcp_mask[1]);4869al_reg_write32(&adapter->ec_regs_base->tfw_v3.tx_gcp_table_mask_3,4870tx_gcp_entry->gcp_mask[2]);4871al_reg_write32(&adapter->ec_regs_base->tfw_v3.tx_gcp_table_mask_4,4872tx_gcp_entry->gcp_mask[3]);4873al_reg_write32(&adapter->ec_regs_base->tfw_v3.tx_gcp_table_mask_5,4874tx_gcp_entry->gcp_mask[4]);4875al_reg_write32(&adapter->ec_regs_base->tfw_v3.tx_gcp_table_mask_6,4876tx_gcp_entry->gcp_mask[5]);4877al_reg_write32(&adapter->ec_regs_base->tfw_v3.tx_gcp_table_crc_init,4878tx_gcp_entry->crc_init);4879al_reg_write32(&adapter->ec_regs_base->tfw_v3.tx_gcp_table_res,4880tx_gcp_entry->gcp_table_res);4881al_reg_write32(&adapter->ec_regs_base->tfw_v3.tx_gcp_table_alu_opcode,4882tx_alu_opcode);4883al_reg_write32(&adapter->ec_regs_base->tfw_v3.tx_gcp_table_alu_opsel,4884tx_alu_opsel);4885al_reg_write32(&adapter->ec_regs_base->tfw_v3.tx_gcp_table_alu_val,4886tx_gcp_entry->alu_val);4887return 0;4888}48894890int al_eth_tx_crc_chksum_replace_cmd_entry_set(struct al_hal_eth_adapter *adapter, uint32_t idx,4891struct al_eth_tx_crc_chksum_replace_cmd_for_protocol_num_entry *tx_replace_entry)4892{4893uint32_t replace_table_address;4894uint32_t tx_replace_cmd;48954896/* Tx crc_chksum_replace_cmd */4897replace_table_address = L4_CHECKSUM_DIS_AND_L3_CHECKSUM_DIS | idx;4898tx_replace_cmd = (uint32_t)(tx_replace_entry->l3_csum_en_00) << 0;4899tx_replace_cmd |= (uint32_t)(tx_replace_entry->l4_csum_en_00) << 1;4900tx_replace_cmd |= (uint32_t)(tx_replace_entry->crc_en_00) << 2;4901al_reg_write32(&adapter->ec_regs_base->tfw_v3.crc_csum_replace_table_addr, replace_table_address);4902al_reg_write32(&adapter->ec_regs_base->tfw_v3.crc_csum_replace_table,4903tx_replace_cmd);4904replace_table_address = L4_CHECKSUM_DIS_AND_L3_CHECKSUM_EN | idx;4905tx_replace_cmd = (uint32_t)(tx_replace_entry->l3_csum_en_01) << 0;4906tx_replace_cmd |= (uint32_t)(tx_replace_entry->l4_csum_en_01) << 1;4907tx_replace_cmd |= (uint32_t)(tx_replace_entry->crc_en_01) << 2;4908al_reg_write32(&adapter->ec_regs_base->tfw_v3.crc_csum_replace_table_addr, replace_table_address);4909al_reg_write32(&adapter->ec_regs_base->tfw_v3.crc_csum_replace_table,4910tx_replace_cmd);4911replace_table_address = L4_CHECKSUM_EN_AND_L3_CHECKSUM_DIS | idx;4912tx_replace_cmd = (uint32_t)(tx_replace_entry->l3_csum_en_10) << 0;4913tx_replace_cmd |= (uint32_t)(tx_replace_entry->l4_csum_en_10) << 1;4914tx_replace_cmd |= (uint32_t)(tx_replace_entry->crc_en_10) << 2;4915al_reg_write32(&adapter->ec_regs_base->tfw_v3.crc_csum_replace_table_addr, replace_table_address);4916al_reg_write32(&adapter->ec_regs_base->tfw_v3.crc_csum_replace_table,4917tx_replace_cmd);4918replace_table_address = L4_CHECKSUM_EN_AND_L3_CHECKSUM_EN | idx;4919tx_replace_cmd = (uint32_t)(tx_replace_entry->l3_csum_en_11) << 0;4920tx_replace_cmd |= (uint32_t)(tx_replace_entry->l4_csum_en_11) << 1;4921tx_replace_cmd |= (uint32_t)(tx_replace_entry->crc_en_11) << 2;4922al_reg_write32(&adapter->ec_regs_base->tfw_v3.crc_csum_replace_table_addr, replace_table_address);4923al_reg_write32(&adapter->ec_regs_base->tfw_v3.crc_csum_replace_table,4924tx_replace_cmd);49254926return 0;4927}49284929int al_eth_rx_protocol_detect_table_entry_set(struct al_hal_eth_adapter *adapter, uint32_t idx,4930struct al_eth_rx_gpd_cam_entry *rx_gpd_entry)4931{4932uint64_t gpd_data;4933uint64_t gpd_mask;49344935gpd_data = ((uint64_t)rx_gpd_entry->outer_l3_proto_idx & AL_ETH_RX_GPD_OUTER_L3_PROTO_MASK) <<4936AL_ETH_RX_GPD_OUTER_L3_PROTO_SHIFT;4937gpd_data |= ((uint64_t)rx_gpd_entry->outer_l4_proto_idx & AL_ETH_RX_GPD_OUTER_L4_PROTO_MASK) <<4938AL_ETH_RX_GPD_OUTER_L4_PROTO_SHIFT;4939gpd_data |= ((uint64_t)rx_gpd_entry->inner_l3_proto_idx & AL_ETH_RX_GPD_INNER_L3_PROTO_MASK) <<4940AL_ETH_RX_GPD_INNER_L3_PROTO_SHIFT;4941gpd_data |= ((uint64_t)rx_gpd_entry->inner_l4_proto_idx & AL_ETH_RX_GPD_INNER_L4_PROTO_MASK) <<4942AL_ETH_RX_GPD_INNER_L4_PROTO_SHIFT;4943gpd_data |= ((uint64_t)rx_gpd_entry->parse_ctrl & AL_ETH_RX_GPD_OUTER_PARSE_CTRL_MASK) <<4944AL_ETH_RX_GPD_OUTER_PARSE_CTRL_SHIFT;4945gpd_data |= ((uint64_t)rx_gpd_entry->outer_l3_len & AL_ETH_RX_GPD_INNER_PARSE_CTRL_MASK) <<4946AL_ETH_RX_GPD_INNER_PARSE_CTRL_SHIFT;4947gpd_data |= ((uint64_t)rx_gpd_entry->l3_priority & AL_ETH_RX_GPD_L3_PRIORITY_MASK) <<4948AL_ETH_RX_GPD_L3_PRIORITY_SHIFT;4949gpd_data |= ((uint64_t)rx_gpd_entry->l4_dst_port_lsb & AL_ETH_RX_GPD_L4_DST_PORT_LSB_MASK) <<4950AL_ETH_RX_GPD_L4_DST_PORT_LSB_SHIFT;49514952gpd_mask = ((uint64_t)rx_gpd_entry->outer_l3_proto_idx_mask & AL_ETH_RX_GPD_OUTER_L3_PROTO_MASK) <<4953AL_ETH_RX_GPD_OUTER_L3_PROTO_SHIFT;4954gpd_mask |= ((uint64_t)rx_gpd_entry->outer_l4_proto_idx_mask & AL_ETH_RX_GPD_OUTER_L4_PROTO_MASK) <<4955AL_ETH_RX_GPD_OUTER_L4_PROTO_SHIFT;4956gpd_mask |= ((uint64_t)rx_gpd_entry->inner_l3_proto_idx_mask & AL_ETH_RX_GPD_INNER_L3_PROTO_MASK) <<4957AL_ETH_RX_GPD_INNER_L3_PROTO_SHIFT;4958gpd_mask |= ((uint64_t)rx_gpd_entry->inner_l4_proto_idx_mask & AL_ETH_RX_GPD_INNER_L4_PROTO_MASK) <<4959AL_ETH_RX_GPD_INNER_L4_PROTO_SHIFT;4960gpd_mask |= ((uint64_t)rx_gpd_entry->parse_ctrl_mask & AL_ETH_RX_GPD_OUTER_PARSE_CTRL_MASK) <<4961AL_ETH_RX_GPD_OUTER_PARSE_CTRL_SHIFT;4962gpd_mask |= ((uint64_t)rx_gpd_entry->outer_l3_len_mask & AL_ETH_RX_GPD_INNER_PARSE_CTRL_MASK) <<4963AL_ETH_RX_GPD_INNER_PARSE_CTRL_SHIFT;4964gpd_mask |= ((uint64_t)rx_gpd_entry->l3_priority_mask & AL_ETH_RX_GPD_L3_PRIORITY_MASK) <<4965AL_ETH_RX_GPD_L3_PRIORITY_SHIFT;4966gpd_mask |= ((uint64_t)rx_gpd_entry->l4_dst_port_lsb_mask & AL_ETH_RX_GPD_L4_DST_PORT_LSB_MASK) <<4967AL_ETH_RX_GPD_L4_DST_PORT_LSB_SHIFT;49684969/* Rx Generic protocol detect Cam compare table */4970al_reg_write32(&adapter->ec_regs_base->rfw_v3.rx_gpd_cam_addr, idx);4971al_reg_write32(&adapter->ec_regs_base->rfw_v3.rx_gpd_cam_ctrl,4972(uint32_t)((rx_gpd_entry->rx_gpd_cam_ctrl) << AL_ETH_RX_GPD_CAM_CTRL_VALID_SHIFT));4973al_reg_write32(&adapter->ec_regs_base->rfw_v3.rx_gpd_cam_mask_2,4974(uint32_t)(gpd_mask >> AL_ETH_RX_GPD_CAM_MASK_2_SHIFT));4975al_reg_write32(&adapter->ec_regs_base->rfw_v3.rx_gpd_cam_mask_1,4976(uint32_t)(gpd_mask));4977al_reg_write32(&adapter->ec_regs_base->rfw_v3.rx_gpd_cam_data_2,4978(uint32_t)(gpd_data >> AL_ETH_RX_GPD_CAM_DATA_2_SHIFT));4979al_reg_write32(&adapter->ec_regs_base->rfw_v3.rx_gpd_cam_data_1,4980(uint32_t)(gpd_data));4981return 0;4982}49834984int al_eth_rx_generic_crc_table_entry_set(struct al_hal_eth_adapter *adapter, uint32_t idx,4985struct al_eth_rx_gcp_table_entry *rx_gcp_entry)4986{4987uint32_t gcp_table_gen;4988uint32_t rx_alu_opcode;4989uint32_t rx_alu_opsel;49904991gcp_table_gen = (rx_gcp_entry->poly_sel & AL_ETH_RX_GCP_POLY_SEL_MASK) <<4992AL_ETH_RX_GCP_POLY_SEL_SHIFT;4993gcp_table_gen |= (rx_gcp_entry->crc32_bit_comp & AL_ETH_RX_GCP_CRC32_BIT_COMP_MASK) <<4994AL_ETH_RX_GCP_CRC32_BIT_COMP_SHIFT;4995gcp_table_gen |= (rx_gcp_entry->crc32_bit_swap & AL_ETH_RX_GCP_CRC32_BIT_SWAP_MASK) <<4996AL_ETH_RX_GCP_CRC32_BIT_SWAP_SHIFT;4997gcp_table_gen |= (rx_gcp_entry->crc32_byte_swap & AL_ETH_RX_GCP_CRC32_BYTE_SWAP_MASK) <<4998AL_ETH_RX_GCP_CRC32_BYTE_SWAP_SHIFT;4999gcp_table_gen |= (rx_gcp_entry->data_bit_swap & AL_ETH_RX_GCP_DATA_BIT_SWAP_MASK) <<5000AL_ETH_RX_GCP_DATA_BIT_SWAP_SHIFT;5001gcp_table_gen |= (rx_gcp_entry->data_byte_swap & AL_ETH_RX_GCP_DATA_BYTE_SWAP_MASK) <<5002AL_ETH_RX_GCP_DATA_BYTE_SWAP_SHIFT;5003gcp_table_gen |= (rx_gcp_entry->trail_size & AL_ETH_RX_GCP_TRAIL_SIZE_MASK) <<5004AL_ETH_RX_GCP_TRAIL_SIZE_SHIFT;5005gcp_table_gen |= (rx_gcp_entry->head_size & AL_ETH_RX_GCP_HEAD_SIZE_MASK) <<5006AL_ETH_RX_GCP_HEAD_SIZE_SHIFT;5007gcp_table_gen |= (rx_gcp_entry->head_calc & AL_ETH_RX_GCP_HEAD_CALC_MASK) <<5008AL_ETH_RX_GCP_HEAD_CALC_SHIFT;5009gcp_table_gen |= (rx_gcp_entry->mask_polarity & AL_ETH_RX_GCP_MASK_POLARITY_MASK) <<5010AL_ETH_RX_GCP_MASK_POLARITY_SHIFT;50115012rx_alu_opcode = (rx_gcp_entry->rx_alu_opcode_1 & AL_ETH_RX_GCP_OPCODE_1_MASK) <<5013AL_ETH_RX_GCP_OPCODE_1_SHIFT;5014rx_alu_opcode |= (rx_gcp_entry->rx_alu_opcode_2 & AL_ETH_RX_GCP_OPCODE_2_MASK) <<5015AL_ETH_RX_GCP_OPCODE_2_SHIFT;5016rx_alu_opcode |= (rx_gcp_entry->rx_alu_opcode_3 & AL_ETH_RX_GCP_OPCODE_3_MASK) <<5017AL_ETH_RX_GCP_OPCODE_3_SHIFT;5018rx_alu_opsel = (rx_gcp_entry->rx_alu_opsel_1 & AL_ETH_RX_GCP_OPSEL_1_MASK) <<5019AL_ETH_RX_GCP_OPSEL_1_SHIFT;5020rx_alu_opsel |= (rx_gcp_entry->rx_alu_opsel_2 & AL_ETH_RX_GCP_OPSEL_2_MASK) <<5021AL_ETH_RX_GCP_OPSEL_2_SHIFT;5022rx_alu_opsel |= (rx_gcp_entry->rx_alu_opsel_3 & AL_ETH_RX_GCP_OPSEL_3_MASK) <<5023AL_ETH_RX_GCP_OPSEL_3_SHIFT;5024rx_alu_opsel |= (rx_gcp_entry->rx_alu_opsel_4 & AL_ETH_RX_GCP_OPSEL_4_MASK) <<5025AL_ETH_RX_GCP_OPSEL_4_SHIFT;50265027/* Rx Generic crc prameters table general */5028al_reg_write32(&adapter->ec_regs_base->rfw_v3.rx_gcp_table_addr, idx);5029al_reg_write32(&adapter->ec_regs_base->rfw_v3.rx_gcp_table_gen,5030gcp_table_gen);5031al_reg_write32(&adapter->ec_regs_base->rfw_v3.rx_gcp_table_mask_1,5032rx_gcp_entry->gcp_mask[0]);5033al_reg_write32(&adapter->ec_regs_base->rfw_v3.rx_gcp_table_mask_2,5034rx_gcp_entry->gcp_mask[1]);5035al_reg_write32(&adapter->ec_regs_base->rfw_v3.rx_gcp_table_mask_3,5036rx_gcp_entry->gcp_mask[2]);5037al_reg_write32(&adapter->ec_regs_base->rfw_v3.rx_gcp_table_mask_4,5038rx_gcp_entry->gcp_mask[3]);5039al_reg_write32(&adapter->ec_regs_base->rfw_v3.rx_gcp_table_mask_5,5040rx_gcp_entry->gcp_mask[4]);5041al_reg_write32(&adapter->ec_regs_base->rfw_v3.rx_gcp_table_mask_6,5042rx_gcp_entry->gcp_mask[5]);5043al_reg_write32(&adapter->ec_regs_base->rfw_v3.rx_gcp_table_crc_init,5044rx_gcp_entry->crc_init);5045al_reg_write32(&adapter->ec_regs_base->rfw_v3.rx_gcp_table_res,5046rx_gcp_entry->gcp_table_res);5047al_reg_write32(&adapter->ec_regs_base->rfw_v3.rx_gcp_table_alu_opcode,5048rx_alu_opcode);5049al_reg_write32(&adapter->ec_regs_base->rfw_v3.rx_gcp_table_alu_opsel,5050rx_alu_opsel);5051al_reg_write32(&adapter->ec_regs_base->rfw_v3.rx_gcp_table_alu_val,5052rx_gcp_entry->alu_val);5053return 0;5054}505550565057#define AL_ETH_TX_GENERIC_CRC_ENTRIES_NUM 95058#define AL_ETH_RX_PROTOCOL_DETECT_ENTRIES_NUM 3250595060static struct al_eth_tx_gpd_cam_entry5061al_eth_generic_tx_crc_gpd[AL_ETH_TX_GENERIC_CRC_ENTRIES_NUM] = {50625063/* [0] roce (with grh, bth) */5064{22, 0, 0, 0, 1,50650x1f, 0x0, 0x0, 0x0, },5066/* [1] fcoe */5067{21, 0, 0, 0, 1,50680x1f, 0x0, 0x0, 0x0, },5069/* [2] routable_roce that is refered as l4_protocol, over IPV4 (and udp) */5070{8, 23, 0, 0, 1,50710x1f, 0x1f, 0x0, 0x0, },5072/* [3] routable_roce that is refered as l4_protocol, over IPV6 (and udp) */5073{11, 23, 0, 0, 1,50740x1f, 0x1f, 0x0, 0x0, },5075/* [4] routable_roce that is refered as tunneled_packet, over outer IPV4 and udp */5076{23, 0, 5, 0, 1,50770x1f, 0x0, 0x5, 0x0, },5078/* [5] routable_roce that is refered as tunneled_packet, over outer IPV6 and udp */5079{23, 0, 3, 0, 1,50800x1f, 0x0, 0x5, 0x0 },5081/* [6] GENERIC_STORAGE_READ over IPV4 (and udp) */5082{8, 2, 0, 0, 1,50830x1f, 0x1f, 0x0, 0x0, },5084/* [7] GENERIC_STORAGE_READ over IPV6 (and udp) */5085{11, 2, 0, 0, 1,50860x1f, 0x1f, 0x0, 0x0, },5087/* [8] default match */5088{0, 0, 0, 0, 1,50890x0, 0x0, 0x0, 0x0 }5090};50915092static struct al_eth_tx_gcp_table_entry5093al_eth_generic_tx_crc_gcp[AL_ETH_TX_GENERIC_CRC_ENTRIES_NUM] = {50945095/* [0] roce (with grh, bth) */5096{0, 1, 1, 0, 1,50970, 4, 8, 0, 1,50980, 0, 0, 0, 0,50990, 0, {0xffff7f03, 0x00000000, 0x00000000,51000x00c00000, 0x00000000, 0x00000000}, 0xffffffff, 0x0,51010},5102/* [1] fcoe */5103{0, 1, 0, 0, 1,51040, 8, 14, 1, 1,51050, 0, 0, 0, 0,51060, 0, {0x00000000, 0x00000000, 0x00000000,51070x00000000, 0x00000000, 0x00000000}, 0xffffffff, 0x0,51080},5109/* [2] routable_roce that is refered as l4_protocol, over IPV4 (and udp) */5110{0, 1, 1, 0, 1,51110, 4, 0, 0, 1,51120, 0, 0, 0, 0,51130, 0, {0x3000cf00, 0x00000f00, 0xc0000000,51140x00000000, 0x00000000, 0x00000000}, 0xffffffff, 0x0,51150},5116/* [3] routable_roce that is refered as l4_protocol, over IPV6 (and udp) */5117{0, 1, 1, 0, 1,51180, 4, 0, 0, 1,51190, 0, 0, 0, 0,51200, 0, {0x7f030000, 0x00000000, 0x00000003,51210x00c00000, 0x00000000, 0x00000000}, 0xffffffff, 0x0,51220},5123/* [4] routable_roce that is refered as tunneled_packet, over outer IPV4 and udp */5124{0, 1, 1, 0, 1,51250, 4, 0, 0, 1,51262, 0, 0, 0, 10,51270, 0, {0x3000cf00, 0x00000f00, 0xc0000000,51280x00000000, 0x00000000, 0x00000000}, 0xffffffff, 0x0,512928},5130/* [5] routable_roce that is refered as tunneled_packet, over outer IPV6 and udp */5131{0, 1, 1, 0, 1,51320, 4, 0, 0, 1,51332, 0, 0, 0, 10,51340, 0, {0x7f030000, 0x00000000, 0x00000003,51350x00c00000, 0x00000000, 0x00000000}, 0xffffffff, 0x0,513648},5137/* [6] GENERIC_STORAGE_READ over IPV4 (and udp) */5138{1, 1, 1, 0, 1,51390, 4, 0, 0, 1,51401, 0, 1, 0, 2,514110, 0, {0x00000000, 0x00000000, 0x00000000,51420x00000000, 0x00000000, 0x00000000}, 0xffffffff, 0x0,51438},5144/* [7] GENERIC_STORAGE_READ over IPV6 (and udp) */5145{1, 1, 1, 0, 1,51460, 4, 0, 0, 1,51471, 0, 1, 0, 2,514810, 0, {0x00000000, 0x00000000, 0x00000000,51490x00000000, 0x00000000, 0x00000000}, 0xffffffff, 0x0,51508},5151/* [8] default match */5152{0, 0, 0, 0, 0,51530, 0, 0, 0, 0,51540, 0, 0, 0, 0,51550, 0, {0x00000000, 0x00000000, 0x00000000,51560x00000000, 0x00000000, 0x00000000}, 0x00000000, 0x0,51570}5158};51595160static struct al_eth_tx_crc_chksum_replace_cmd_for_protocol_num_entry5161al_eth_tx_crc_chksum_replace_cmd[AL_ETH_TX_GENERIC_CRC_ENTRIES_NUM] = {51625163/* [0] roce (with grh, bth) */5164{0,1,0,1, 0,0,0,0, 0,0,0,0},5165/* [1] fcoe */5166{0,1,0,1, 0,0,0,0, 0,0,0,0},5167/* [2] routable_roce that is refered as l4_protocol, over IPV4 (and udp) */5168{0,0,1,1, 0,0,0,0, 0,1,0,1},5169/* [3] routable_roce that is refered as l4_protocol, over IPV6 (and udp) */5170{0,0,1,1, 0,0,0,0, 0,0,0,0},5171/* [4] routable_roce that is refered as tunneled_packet, over outer IPV4 and udp */5172{0,1,0,1, 0,0,0,0, 0,0,0,0},5173/* [5] routable_roce that is refered as tunneled_packet, over outer IPV6 and udp */5174{0,1,0,1, 0,0,0,0, 0,0,0,0},5175/* [6] GENERIC_STORAGE_READ over IPV4 (and udp) */5176{0,0,1,1, 0,0,0,0, 0,1,0,1},5177/* [7] GENERIC_STORAGE_READ over IPV6 (and udp) */5178{0,0,1,1, 0,0,0,0, 0,0,0,0},5179/* [8] default match */5180{0,0,0,0, 0,0,1,1, 0,1,0,1}5181};51825183static struct al_eth_rx_gpd_cam_entry5184al_eth_generic_rx_crc_gpd[AL_ETH_RX_PROTOCOL_DETECT_ENTRIES_NUM] = {51855186/* [0] roce (with grh, bth) */5187{22, 0, 0, 0,51880, 0, 0, 0, 1,51890x1f, 0x0, 0x0, 0x0,51900x4, 0x0, 0x0, 0x0},5191/* [1] fcoe */5192{21, 0, 0, 0,51930, 0, 0, 0, 1,51940x1f, 0x0, 0x0, 0x0,51950x4, 0x0, 0x0, 0x0},5196/* [2] routable_roce that is refered as l4_protocol, over IPV4 (and udp) */5197{8, 23, 0, 0,51980, 0, 0, 0, 1,51990x1f, 0x1f, 0x0, 0x0,52000x4, 0x0, 0x0, 0x0},5201/* [3] routable_roce that is refered as l4_protocol, over IPV6 (and udp) */5202{11, 23, 0, 0,52030, 0, 0, 0, 1,52040x1f, 0x1f, 0x0, 0x0,52050x4, 0x0, 0x0, 0x0},5206/* [4] routable_roce that is refered as tunneled_packet, over outer IPV4 and udp */5207{8, 13, 23, 0,52080, 0, 0, 0, 1,52090x1f, 0x1f, 0x1f, 0x0,52100x4, 0x0, 0x0, 0x0},5211/* [5] routable_roce that is refered as tunneled_packet, over outer IPV6 and udp */5212{11, 13, 23, 0,52130, 0, 0, 0, 1,52140x1f, 0x1f, 0x1f, 0x0,52150x4, 0x0, 0x0, 0x0},5216/* [6] tunneled roce (with grh, bth) over GRE over IPV4 */5217{8, 0, 22, 0,52184, 0, 0, 0, 1,52190x1f, 0x0, 0x1f, 0x0,52200x4, 0x0, 0x0, 0x0},5221/* [7] tunneled roce (with grh, bth) over GRE over IPV6 */5222{11, 0, 22, 0,52234, 0, 0, 0, 1,52240x1f, 0x0, 0x1f, 0x0,52250x4, 0x0, 0x0, 0x0},5226/* [8] tunneled fcoe over IPV4 */5227{8, 0, 21, 0,52284, 0, 0, 0, 1,52290x1f, 0x0, 0x1f, 0x0,52300x4, 0x0, 0x0, 0x0},5231/* [9] tunneled fcoe over IPV6 */5232{11, 0, 21, 0,52334, 0, 0, 0, 1,52340x1f, 0x0, 0x1f, 0x0,52350x4, 0x0, 0x0, 0x0},5236/* [10] tunneled routable_roce that is refered as l4_protocol, over IPV4 (and udp) over IPV4 */5237{8, 0, 8, 23,52384, 0, 0, 0, 1,52390x1f, 0x0, 0x1f, 0x1f,52400x4, 0x0, 0x0, 0x0},5241/* [11] tunneled routable_roce that is refered as l4_protocol, over IPV4 (and udp) over IPV6 */5242{11, 0, 8, 23,52434, 0, 0, 0, 1,52440x1f, 0x0, 0x1f, 0x1f,52450x4, 0x0, 0x0, 0x0},5246/* [12] tunneled routable_roce that is refered as l4_protocol, over IPV6 (and udp) over IPV4 */5247{8, 0, 11, 23,52484, 0, 0, 0, 1,52490x1f, 0x0, 0x1f, 0x1f,52500x4, 0x0, 0x0, 0x0},5251/* [13] tunneled routable_roce that is refered as l4_protocol, over IPV6 (and udp) over IPV6 */5252{11, 0, 11, 23,52534, 0, 0, 0, 1,52540x1f, 0x0, 0x1f, 0x1f,52550x4, 0x0, 0x0, 0x0},5256/* [14] l3_pkt - IPV4 */5257{8, 0, 0, 0,52580, 0, 0, 0, 1,52590x1f, 0x1f, 0x0, 0x0,52600x4, 0x0, 0x0, 0x0},5261/* [15] l4_hdr over IPV4 */5262{8, 12, 0, 0,52630, 0, 0, 0, 1,52640x1f, 0x1e, 0x0, 0x0,52650x4, 0x0, 0x0, 0x0},5266/* [16] l3_pkt - IPV6 */5267{11, 0, 0, 0,52680, 0, 0, 0, 1,52690x1f, 0x1f, 0x0, 0x0,52700x4, 0x0, 0x0, 0x0},5271/* [17] l4_hdr over IPV6 */5272{11, 12, 0, 0,52730, 0, 0, 0, 1,52740x1f, 0x1e, 0x0, 0x0,52750x4, 0x0, 0x0, 0x0},5276/* [18] IPV4 over IPV4 */5277{8, 0, 8, 0,52784, 0, 0, 0, 1,52790x1f, 0x0, 0x1f, 0x1f,52800x4, 0x0, 0x0, 0x0},5281/* [19] l4_hdr over IPV4 over IPV4 */5282{8, 0, 8, 12,52834, 0, 0, 0, 1,52840x1f, 0x0, 0x1f, 0x1e,52850x4, 0x0, 0x0, 0x0},5286/* [20] IPV4 over IPV6 */5287{11, 0, 8, 0,52884, 0, 0, 0, 1,52890x1f, 0x0, 0x1f, 0x1f,52900x4, 0x0, 0x0, 0x0},5291/* [21] l4_hdr over IPV4 over IPV6 */5292{11, 0, 8, 12,52934, 0, 0, 0, 1,52940x1f, 0x0, 0x1f, 0x1e,52950x4, 0x0, 0x0, 0x0},5296/* [22] IPV6 over IPV4 */5297{8, 0, 11, 0,52984, 0, 0, 0, 1,52990x1f, 0x0, 0x1f, 0x1f,53000x4, 0x0, 0x0, 0x0},5301/* [23] l4_hdr over IPV6 over IPV4 */5302{8, 0, 11, 12,53034, 0, 0, 0, 1,53040x1f, 0x0, 0x1f, 0x1e,53050x4, 0x0, 0x0, 0x0},5306/* [24] IPV6 over IPV6 */5307{11, 0, 11, 0,53084, 0, 0, 0, 1,53090x1f, 0x0, 0x1f, 0x1f,53100x4, 0x0, 0x0, 0x0},5311/* [25] l4_hdr over IPV6 over IPV6 */5312{11, 0, 11, 12,53134, 0, 0, 0, 1,53140x1f, 0x0, 0x1f, 0x1e,53150x4, 0x0, 0x0, 0x0},5316/* [26] GENERIC_STORAGE_READ, over IPV4 (and udp) */5317{8, 2, 0, 0,53180, 0, 0, 0, 1,53190x1f, 0x1f, 0x0, 0x0,53200x4, 0x0, 0x0, 0x0},5321/* [27] GENERIC_STORAGE_READ, over IPV6 (and udp) */5322{11, 2, 0, 0,53230, 0, 0, 0, 1,53240x1f, 0x1f, 0x0, 0x0,53250x4, 0x0, 0x0, 0x0},5326/* [28] tunneled GENERIC_STORAGE_READ over IPV4 (and udp) over IPV4/IPV6 */5327{8, 0, 8, 2,53284, 0, 0, 0, 1,53290x18, 0x0, 0x1f, 0x1f,53300x4, 0x0, 0x0, 0x0},5331/* [29] tunneled GENERIC_STORAGE_READ over IPV6 (and udp) over IPV4/IPV6 */5332{8, 0, 11, 2,53334, 0, 0, 0, 1,53340x18, 0x0, 0x1f, 0x1f,53350x4, 0x0, 0x0, 0x0},5336/* [30] tunneled L2 over GRE over IPV4 */5337{8, 0, 0, 0,53384, 0, 0, 0, 1,53390x1f, 0x0, 0x1f, 0x0,53400x4, 0x0, 0x0, 0x0},5341/* [31] default match */5342{0, 0, 0, 0,53430, 0, 0, 0, 1,53440x0, 0x0, 0x0, 0x0,53450x0, 0x0, 0x0, 0x0}5346};53475348static struct al_eth_rx_gcp_table_entry5349al_eth_generic_rx_crc_gcp[AL_ETH_RX_PROTOCOL_DETECT_ENTRIES_NUM] = {53505351/* [0] roce (with grh, bth) */5352{0, 1, 1, 0, 1,53530, 4, 8, 0, 1,53540, 0, 0, 0, 0,53550, 0, {0xffff7f03, 0x00000000, 0x00000000,53560x00c00000, 0x00000000, 0x00000000}, 0xffffffff, 0x03000010,53570},5358/* [1] fcoe */5359{0, 1, 0, 0, 1,53600, 8, 14, 1, 1,53610, 0, 0, 0, 0,53620, 0, {0x00000000, 0x00000000, 0x00000000,53630x00000000, 0x00000000, 0x00000000}, 0xffffffff, 0x03000010,53640},5365/* [2] routable_roce that is refered as l4_protocol, over IPV4 (and udp) */5366{0, 1, 1, 0, 1,53670, 4, 0, 0, 1,53680, 0, 0, 0, 0,53690, 0, {0x3000cf00, 0x00000f00, 0xc0000000,53700x00000000, 0x00000000, 0x00000000}, 0xffffffff, 0x03000011,53710},5372/* [3] routable_roce that is refered as l4_protocol, over IPV6 (and udp) */5373{0, 1, 1, 0, 1,53740, 4, 0, 0, 1,53750, 0, 0, 0, 0,53760, 0, {0x7f030000, 0x00000000, 0x00000003,53770x00c00000, 0x00000000, 0x00000000}, 0xffffffff, 0x03000010,53780},5379/* [4] routable_roce that is refered as tunneled_packet, over outer IPV4 and udp */5380{0, 1, 1, 0, 1,53810, 4, 0, 0, 1,53822, 0, 0, 0, 10,53830, 0, {0x3000cf00, 0x00000f00, 0xc0000000,53840x00000000, 0x00000000, 0x00000000}, 0xffffffff, 0x0302201c,538528},5386/* [5] routable_roce that is refered as tunneled_packet, over outer IPV6 and udp */5387{0, 1, 1, 0, 1,53880, 4, 0, 0, 1,53892, 0, 0, 0, 10,53900, 0, {0x7f030000, 0x00000000, 0x00000003,53910x00c00000, 0x00000000, 0x00000000}, 0xffffffff, 0x03002018,539248},5393/* [6] tunneled roce (with grh, bth) over IPV4 */5394{0, 1, 1, 0, 1,53950, 4, 8, 0, 1,53960, 0, 0, 1, 0,53970, 0, {0xffff7f03, 0x00000000, 0x00000000,53980x00c00000, 0x00000000, 0x00000000}, 0xffffffff, 0x03020014,53990},5400/* [7] tunneled roce (with grh, bth) over IPV6 */5401{0, 1, 1, 0, 1,54020, 4, 8, 0, 1,54030, 0, 0, 1, 0,54040, 0, {0xffff7f03, 0x00000000, 0x00000000,54050x00c00000, 0x00000000, 0x00000000}, 0xffffffff, 0x03000010,54060},5407/* [8] tunneled fcoe over IPV4 */5408{0, 1, 0, 0, 1,54090, 8, 14, 1, 1,54100, 0, 0, 1, 0,54110, 0, {0x00000000, 0x00000000, 0x00000000,54120x00000000, 0x00000000, 0x00000000}, 0xffffffff, 0x03020014,54130},5414/* [9] tunneled fcoe over IPV6 */5415{0, 1, 0, 0, 1,54160, 8, 14, 1, 1,54170, 0, 0, 1, 0,54180, 0, {0x00000000, 0x00000000, 0x00000000,54190x00000000, 0x00000000, 0x00000000}, 0xffffffff, 0x03000010,54200},5421/* [10] tunneled routable_roce that is refered as l4_protocol, over IPV4 (and udp) over IPV4 */5422{0, 1, 1, 0, 1,54230, 4, 0, 0, 1,54240, 0, 0, 1, 0,54250, 0, {0x3000cf00, 0x00000f00, 0xc0000000,54260x00000000, 0x00000000, 0x00000000}, 0xffffffff, 0x03020015,54270},5428/* [11] tunneled routable_roce that is refered as l4_protocol, over IPV4 (and udp) over IPV6 */5429{0, 1, 1, 0, 1,54300, 4, 0, 0, 1,54310, 0, 0, 1, 0,54320, 0, {0x3000cf00, 0x00000f00, 0xc0000000,54330x00000000, 0x00000000, 0x00000000}, 0xffffffff, 0x03000011,54340},5435/* [12] tunneled routable_roce that is refered as l4_protocol, over IPV6 (and udp) over IPV4 */5436{0, 1, 1, 0, 1,54370, 4, 0, 0, 1,54380, 0, 0, 1, 0,54390, 0, {0x7f030000, 0x00000000, 0x00000003,54400x00c00000, 0x00000000, 0x00000000}, 0xffffffff, 0x03020014,54410},5442/* [13] tunneled routable_roce that is refered as l4_protocol, over IPV6 (and udp) over IPV6 */5443{0, 1, 1, 0, 1,54440, 4, 0, 0, 1,54450, 0, 0, 1, 0,54460, 0, {0x7f030000, 0x00000000, 0x00000003,54470x00c00000, 0x00000000, 0x00000000}, 0xffffffff, 0x03000010,54480},5449/* [14] l3_pkt - IPV4 */5450{0, 0, 0, 0, 0,54510, 0, 0, 0, 0,54520, 0, 0, 0, 0,54530, 0, {0x00000000, 0x00000000, 0x00000000,54540x00000000, 0x00000000, 0x00000000}, 0x00000000, 0x00000001,54550},5456/* [15] l4_hdr over IPV4 */5457{0, 0, 0, 0, 0,54580, 0, 0, 0, 0,54590, 0, 0, 0, 0,54600, 0, {0x00000000, 0x00000000, 0x00000000,54610x00000000, 0x00000000, 0x00000000}, 0x00000000, 0x00000003,54620},5463/* [16] l3_pkt - IPV6 */5464{0, 0, 0, 0, 0,54650, 0, 0, 0, 0,54660, 0, 0, 0, 0,54670, 0, {0x00000000, 0x00000000, 0x00000000,54680x00000000, 0x00000000, 0x00000000}, 0x00000000, 0x00000000,54690},5470/* [17] l4_hdr over IPV6 */5471{0, 0, 0, 0, 0,54720, 0, 0, 0, 0,54730, 0, 0, 0, 0,54740, 0, {0x00000000, 0x00000000, 0x00000000,54750x00000000, 0x00000000, 0x00000000}, 0x00000000, 0x00000002,54760},5477/* [18] IPV4 over IPV4 */5478{0, 0, 0, 0, 0,54790, 0, 0, 0, 0,54800, 0, 0, 0, 0,54810, 0, {0x00000000, 0x00000000, 0x00000000,54820x00000000, 0x00000000, 0x00000000}, 0x00000000, 0x00020005,54830},5484/* [19] l4_hdr over IPV4 over IPV4 */5485{0, 0, 0, 0, 0,54860, 0, 0, 0, 0,54870, 0, 0, 0, 0,54880, 0, {0x00000000, 0x00000000, 0x00000000,54890x00000000, 0x00000000, 0x00000000}, 0x00000000, 0x00020007,54900},5491/* [20] IPV4 over IPV6 */5492{0, 0, 0, 0, 0,54930, 0, 0, 0, 0,54940, 0, 0, 0, 0,54950, 0, {0x00000000, 0x00000000, 0x00000000,54960x00000000, 0x00000000, 0x00000000}, 0x00000000, 0x00000001,54970},5498/* [21] l4_hdr over IPV4 over IPV6 */5499{0, 0, 0, 0, 0,55000, 0, 0, 0, 0,55010, 0, 0, 0, 0,55020, 0, {0x00000000, 0x00000000, 0x00000000,55030x00000000, 0x00000000, 0x00000000}, 0x00000000, 0x00000003,55040},5505/* [22] IPV6 over IPV4 */5506{0, 0, 0, 0, 0,55070, 0, 0, 0, 0,55080, 0, 0, 0, 0,55090, 0, {0x00000000, 0x00000000, 0x00000000,55100x00000000, 0x00000000, 0x00000000}, 0x00000000, 0x00020004,55110},5512/* [23] l4_hdr over IPV6 over IPV4 */5513{0, 0, 0, 0, 0,55140, 0, 0, 0, 0,55150, 0, 0, 0, 0,55160, 0, {0x00000000, 0x00000000, 0x00000000,55170x00000000, 0x00000000, 0x00000000}, 0x00000000, 0x00020006,55180},5519/* [24] IPV6 over IPV6 */5520{0, 0, 0, 0, 0,55210, 0, 0, 0, 0,55220, 0, 0, 0, 0,55230, 0, {0x00000000, 0x00000000, 0x00000000,55240x00000000, 0x00000000, 0x00000000}, 0x00000000, 0x00000000,55250},5526/* [25] l4_hdr over IPV6 over IPV6 */5527{0, 0, 0, 0, 0,55280, 0, 0, 0, 0,55290, 0, 0, 0, 0,55300, 0, {0x00000000, 0x00000000, 0x00000000,55310x00000000, 0x00000000, 0x00000000}, 0x00000000, 0x00000002,55320},5533/* [26] GENERIC_STORAGE_READ, over IPV4 (and udp) */5534{1, 1, 1, 0, 1,55350, 4, 0, 0, 1,55360, 0, 0, 2, 0,55370, 0, {0x00000000, 0x00000000, 0x00000000,55380x00000000, 0x00000000, 0x00000000}, 0xffffffff, 0x03000011,55390},5540/* [27] GENERIC_STORAGE_READ, over IPV6 (and udp) */5541{1, 1, 1, 0, 1,55420, 4, 0, 0, 1,55430, 0, 0, 2, 0,55440, 0, {0x00000000, 0x00000000, 0x00000000,55450x00000000, 0x00000000, 0x00000000}, 0xffffffff, 0x03000010,55460},5547/* [28] tunneled GENERIC_STORAGE_READ over IPV4 (and udp) over IPV4/IPV6 */5548{1, 1, 1, 0, 1,55490, 4, 0, 0, 1,55500, 0, 0, 3, 0,55510, 0, {0x00000000, 0x00000000, 0x00000000,55520x00000000, 0x00000000, 0x00000000}, 0xffffffff, 0x03000011,55530},5554/* [29] tunneled GENERIC_STORAGE_READ over IPV6 (and udp) over IPV4/IPV6 */5555{1, 1, 1, 0, 1,55560, 4, 0, 0, 1,55570, 0, 0, 3, 0,55580, 0, {0x00000000, 0x00000000, 0x00000000,55590x00000000, 0x00000000, 0x00000000}, 0xffffffff, 0x03000010,55600},5561/* [30] tunneled L2 over GRE over IPV4 */5562{0, 0, 0, 0, 0,55630, 0, 0, 0, 0,55640, 0, 0, 0, 0,55650, 0, {0x00000000, 0x00000000, 0x00000000,55660x00000000, 0x00000000, 0x00000000}, 0x00000000, 0x00020004,55670},5568/* [31] default match */5569{0, 0, 0, 0, 0,55700, 0, 0, 0, 0,55710, 0, 0, 0, 0,55720, 0, {0x00000000, 0x00000000, 0x00000000,55730x00000000, 0x00000000, 0x00000000}, 0x00000000, 0x0,55740}5575};55765577int al_eth_tx_protocol_detect_table_init(struct al_hal_eth_adapter *adapter)5578{5579int idx;5580al_assert((adapter->rev_id > AL_ETH_REV_ID_2));55815582for (idx = 0; idx < AL_ETH_TX_GENERIC_CRC_ENTRIES_NUM; idx++)5583al_eth_tx_protocol_detect_table_entry_set(adapter, idx,5584&al_eth_generic_tx_crc_gpd[idx]);55855586return 0;5587}55885589int al_eth_tx_generic_crc_table_init(struct al_hal_eth_adapter *adapter)5590{5591int idx;5592al_assert((adapter->rev_id > AL_ETH_REV_ID_2));55935594al_dbg("eth [%s]: enable tx_generic_crc\n", adapter->name);5595al_reg_write32(&adapter->ec_regs_base->tfw_v3.tx_gcp_legacy, 0x0);5596al_reg_write32(&adapter->ec_regs_base->tfw_v3.crc_csum_replace, 0x0);5597for (idx = 0; idx < AL_ETH_TX_GENERIC_CRC_ENTRIES_NUM; idx++)5598al_eth_tx_generic_crc_table_entry_set(adapter, idx,5599&al_eth_generic_tx_crc_gcp[idx]);56005601return 0;5602}56035604int al_eth_tx_crc_chksum_replace_cmd_init(struct al_hal_eth_adapter *adapter)5605{5606int idx;5607al_assert((adapter->rev_id > AL_ETH_REV_ID_2));56085609for (idx = 0; idx < AL_ETH_TX_GENERIC_CRC_ENTRIES_NUM; idx++)5610al_eth_tx_crc_chksum_replace_cmd_entry_set(adapter, idx,5611&al_eth_tx_crc_chksum_replace_cmd[idx]);56125613return 0;5614}56155616int al_eth_rx_protocol_detect_table_init(struct al_hal_eth_adapter *adapter)5617{5618int idx;5619al_assert((adapter->rev_id > AL_ETH_REV_ID_2));5620al_reg_write32(&adapter->ec_regs_base->rfw_v3.gpd_p1,5621AL_ETH_RX_GPD_PARSE_RESULT_OUTER_L3_PROTO_IDX_OFFSET);5622al_reg_write32(&adapter->ec_regs_base->rfw_v3.gpd_p2,5623AL_ETH_RX_GPD_PARSE_RESULT_OUTER_L4_PROTO_IDX_OFFSET);5624al_reg_write32(&adapter->ec_regs_base->rfw_v3.gpd_p3,5625AL_ETH_RX_GPD_PARSE_RESULT_INNER_L3_PROTO_IDX_OFFSET);5626al_reg_write32(&adapter->ec_regs_base->rfw_v3.gpd_p4,5627AL_ETH_RX_GPD_PARSE_RESULT_INNER_L4_PROTO_IDX_OFFSET);5628al_reg_write32(&adapter->ec_regs_base->rfw_v3.gpd_p5,5629AL_ETH_RX_GPD_PARSE_RESULT_OUTER_PARSE_CTRL);5630al_reg_write32(&adapter->ec_regs_base->rfw_v3.gpd_p6,5631AL_ETH_RX_GPD_PARSE_RESULT_INNER_PARSE_CTRL);5632al_reg_write32(&adapter->ec_regs_base->rfw_v3.gpd_p7,5633AL_ETH_RX_GPD_PARSE_RESULT_L3_PRIORITY);5634al_reg_write32(&adapter->ec_regs_base->rfw_v3.gpd_p8,5635AL_ETH_RX_GPD_PARSE_RESULT_OUTER_L4_DST_PORT_LSB);56365637for (idx = 0; idx < AL_ETH_RX_PROTOCOL_DETECT_ENTRIES_NUM; idx++)5638al_eth_rx_protocol_detect_table_entry_set(adapter, idx,5639&al_eth_generic_rx_crc_gpd[idx]);5640return 0;5641}56425643int al_eth_rx_generic_crc_table_init(struct al_hal_eth_adapter *adapter)5644{5645int idx;5646uint32_t val;56475648al_assert((adapter->rev_id > AL_ETH_REV_ID_2));56495650al_dbg("eth [%s]: enable rx_generic_crc\n", adapter->name);5651al_reg_write32(&adapter->ec_regs_base->rfw_v3.rx_gcp_legacy, 0x0);56525653for (idx = 0; idx < AL_ETH_RX_PROTOCOL_DETECT_ENTRIES_NUM; idx++)5654al_eth_rx_generic_crc_table_entry_set(adapter, idx,5655&al_eth_generic_rx_crc_gcp[idx]);56565657val = EC_GEN_V3_RX_COMP_DESC_W3_DEC_STAT_15_CRC_RES_SEL |5658EC_GEN_V3_RX_COMP_DESC_W3_DEC_STAT_14_L3_CKS_RES_SEL |5659EC_GEN_V3_RX_COMP_DESC_W3_DEC_STAT_13_L4_CKS_RES_SEL |5660EC_GEN_V3_RX_COMP_DESC_W0_L3_CKS_RES_SEL;5661al_reg_write32_masked(&adapter->ec_regs_base->gen_v3.rx_comp_desc,5662val, val);5663return 0;5664}56655666/** @} end of Ethernet group */5667566856695670