diff options
Diffstat (limited to 'drivers/net/ethernet/aquantia/atlantic')
34 files changed, 12002 insertions, 0 deletions
diff --git a/drivers/net/ethernet/aquantia/atlantic/Makefile b/drivers/net/ethernet/aquantia/atlantic/Makefile new file mode 100644 index 000000000..686f6d8c9 --- /dev/null +++ b/drivers/net/ethernet/aquantia/atlantic/Makefile @@ -0,0 +1,43 @@ +################################################################################ +# +# aQuantia Ethernet Controller AQtion Linux Driver +# Copyright(c) 2014-2017 aQuantia Corporation. +# +# This program is free software; you can redistribute it and/or modify it +# under the terms and conditions of the GNU General Public License, +# version 2, as published by the Free Software Foundation. +# +# This program is distributed in the hope it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +# more details. +# +# You should have received a copy of the GNU General Public License along +# with this program. If not, see <http://www.gnu.org/licenses/>. +# +# The full GNU General Public License is included in this distribution in +# the file called "COPYING". +# +# Contact Information: <rdc-drv@aquantia.com> +# aQuantia Corporation, 105 E. Tasman Dr. San Jose, CA 95134, USA +# +################################################################################ + +# +# Makefile for the AQtion(tm) Ethernet driver +# + +obj-$(CONFIG_AQTION) += atlantic.o + +atlantic-objs := aq_main.o \ + aq_nic.o \ + aq_pci_func.o \ + aq_vec.o \ + aq_ring.o \ + aq_hw_utils.o \ + aq_ethtool.o \ + hw_atl/hw_atl_a0.o \ + hw_atl/hw_atl_b0.o \ + hw_atl/hw_atl_utils.o \ + hw_atl/hw_atl_utils_fw2x.o \ + hw_atl/hw_atl_llh.o diff --git a/drivers/net/ethernet/aquantia/atlantic/aq_cfg.h b/drivers/net/ethernet/aquantia/atlantic/aq_cfg.h new file mode 100644 index 000000000..90a0e1d0d --- /dev/null +++ b/drivers/net/ethernet/aquantia/atlantic/aq_cfg.h @@ -0,0 +1,92 @@ +/* + * aQuantia Corporation Network Driver + * Copyright (C) 2014-2017 aQuantia Corporation. All rights reserved + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + */ + +/* File aq_cfg.h: Definition of configuration parameters and constants. */ + +#ifndef AQ_CFG_H +#define AQ_CFG_H + +#define AQ_CFG_VECS_DEF 4U +#define AQ_CFG_TCS_DEF 1U + +#define AQ_CFG_TXDS_DEF 4096U +#define AQ_CFG_RXDS_DEF 1024U + +#define AQ_CFG_IS_POLLING_DEF 0U + +#define AQ_CFG_FORCE_LEGACY_INT 0U + +#define AQ_CFG_INTERRUPT_MODERATION_OFF 0 +#define AQ_CFG_INTERRUPT_MODERATION_ON 1 +#define AQ_CFG_INTERRUPT_MODERATION_AUTO 0xFFFFU + +#define AQ_CFG_INTERRUPT_MODERATION_USEC_MAX (0x1FF * 2) + +#define AQ_CFG_IRQ_MASK 0x1FFU + +#define AQ_CFG_VECS_MAX 8U +#define AQ_CFG_TCS_MAX 8U + +#define AQ_CFG_TX_FRAME_MAX (16U * 1024U) +#define AQ_CFG_RX_FRAME_MAX (4U * 1024U) + +#define AQ_CFG_TX_CLEAN_BUDGET 256U + +/* LRO */ +#define AQ_CFG_IS_LRO_DEF 1U + +/* RSS */ +#define AQ_CFG_RSS_INDIRECTION_TABLE_MAX 64U +#define AQ_CFG_RSS_HASHKEY_SIZE 40U + +#define AQ_CFG_IS_RSS_DEF 1U +#define AQ_CFG_NUM_RSS_QUEUES_DEF AQ_CFG_VECS_DEF +#define AQ_CFG_RSS_BASE_CPU_NUM_DEF 0U + +#define AQ_CFG_PCI_FUNC_MSIX_IRQS 9U +#define AQ_CFG_PCI_FUNC_PORTS 2U + +#define AQ_CFG_SERVICE_TIMER_INTERVAL (1 * HZ) +#define AQ_CFG_POLLING_TIMER_INTERVAL ((unsigned int)(2 * HZ)) + +#define AQ_CFG_SKB_FRAGS_MAX 32U + +/* Number of descriptors available in one ring to resume this ring queue + */ +#define AQ_CFG_RESTART_DESC_THRES (AQ_CFG_SKB_FRAGS_MAX * 2) + +#define AQ_CFG_NAPI_WEIGHT 64U + +/*#define AQ_CFG_MAC_ADDR_PERMANENT {0x30, 0x0E, 0xE3, 0x12, 0x34, 0x56}*/ + +#define AQ_NIC_FC_OFF 0U +#define AQ_NIC_FC_TX 1U +#define AQ_NIC_FC_RX 2U +#define AQ_NIC_FC_FULL 3U +#define AQ_NIC_FC_AUTO 4U + +#define AQ_CFG_FC_MODE AQ_NIC_FC_FULL + +#define AQ_CFG_SPEED_MSK 0xFFFFU /* 0xFFFFU==auto_neg */ + +#define AQ_CFG_IS_AUTONEG_DEF 1U +#define AQ_CFG_MTU_DEF 1514U + +#define AQ_CFG_LOCK_TRYS 100U + +#define AQ_CFG_DRV_AUTHOR "aQuantia" +#define AQ_CFG_DRV_DESC "aQuantia Corporation(R) Network Driver" +#define AQ_CFG_DRV_NAME "atlantic" +#define AQ_CFG_DRV_VERSION __stringify(NIC_MAJOR_DRIVER_VERSION)"."\ + __stringify(NIC_MINOR_DRIVER_VERSION)"."\ + __stringify(NIC_BUILD_DRIVER_VERSION)"."\ + __stringify(NIC_REVISION_DRIVER_VERSION) \ + AQ_CFG_DRV_VERSION_SUFFIX + +#endif /* AQ_CFG_H */ diff --git a/drivers/net/ethernet/aquantia/atlantic/aq_common.h b/drivers/net/ethernet/aquantia/atlantic/aq_common.h new file mode 100644 index 000000000..d52b088ff --- /dev/null +++ b/drivers/net/ethernet/aquantia/atlantic/aq_common.h @@ -0,0 +1,60 @@ +/* + * aQuantia Corporation Network Driver + * Copyright (C) 2014-2017 aQuantia Corporation. All rights reserved + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + */ + +/* File aq_common.h: Basic includes for all files in project. */ + +#ifndef AQ_COMMON_H +#define AQ_COMMON_H + +#include <linux/etherdevice.h> +#include <linux/pci.h> + +#include "ver.h" +#include "aq_cfg.h" +#include "aq_utils.h" + +#define PCI_VENDOR_ID_AQUANTIA 0x1D6A + +#define AQ_DEVICE_ID_0001 0x0001 +#define AQ_DEVICE_ID_D100 0xD100 +#define AQ_DEVICE_ID_D107 0xD107 +#define AQ_DEVICE_ID_D108 0xD108 +#define AQ_DEVICE_ID_D109 0xD109 + +#define AQ_DEVICE_ID_AQC100 0x00B1 +#define AQ_DEVICE_ID_AQC107 0x07B1 +#define AQ_DEVICE_ID_AQC108 0x08B1 +#define AQ_DEVICE_ID_AQC109 0x09B1 +#define AQ_DEVICE_ID_AQC111 0x11B1 +#define AQ_DEVICE_ID_AQC112 0x12B1 + +#define AQ_DEVICE_ID_AQC100S 0x80B1 +#define AQ_DEVICE_ID_AQC107S 0x87B1 +#define AQ_DEVICE_ID_AQC108S 0x88B1 +#define AQ_DEVICE_ID_AQC109S 0x89B1 +#define AQ_DEVICE_ID_AQC111S 0x91B1 +#define AQ_DEVICE_ID_AQC112S 0x92B1 + +#define AQ_DEVICE_ID_AQC111E 0x51B1 +#define AQ_DEVICE_ID_AQC112E 0x52B1 + +#define HW_ATL_NIC_NAME "aQuantia AQtion 10Gbit Network Adapter" + +#define AQ_HWREV_ANY 0 +#define AQ_HWREV_1 1 +#define AQ_HWREV_2 2 + +#define AQ_NIC_RATE_10G BIT(0) +#define AQ_NIC_RATE_5G BIT(1) +#define AQ_NIC_RATE_5GSR BIT(2) +#define AQ_NIC_RATE_2GS BIT(3) +#define AQ_NIC_RATE_1G BIT(4) +#define AQ_NIC_RATE_100M BIT(5) + +#endif /* AQ_COMMON_H */ diff --git a/drivers/net/ethernet/aquantia/atlantic/aq_ethtool.c b/drivers/net/ethernet/aquantia/atlantic/aq_ethtool.c new file mode 100644 index 000000000..08c9fa6ca --- /dev/null +++ b/drivers/net/ethernet/aquantia/atlantic/aq_ethtool.c @@ -0,0 +1,420 @@ +/* + * aQuantia Corporation Network Driver + * Copyright (C) 2014-2017 aQuantia Corporation. All rights reserved + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + */ + +/* File aq_ethtool.c: Definition of ethertool related functions. */ + +#include "aq_ethtool.h" +#include "aq_nic.h" +#include "aq_vec.h" + +static void aq_ethtool_get_regs(struct net_device *ndev, + struct ethtool_regs *regs, void *p) +{ + struct aq_nic_s *aq_nic = netdev_priv(ndev); + u32 regs_count = aq_nic_get_regs_count(aq_nic); + + memset(p, 0, regs_count * sizeof(u32)); + aq_nic_get_regs(aq_nic, regs, p); +} + +static int aq_ethtool_get_regs_len(struct net_device *ndev) +{ + struct aq_nic_s *aq_nic = netdev_priv(ndev); + u32 regs_count = aq_nic_get_regs_count(aq_nic); + + return regs_count * sizeof(u32); +} + +static u32 aq_ethtool_get_link(struct net_device *ndev) +{ + return ethtool_op_get_link(ndev); +} + +static int aq_ethtool_get_link_ksettings(struct net_device *ndev, + struct ethtool_link_ksettings *cmd) +{ + struct aq_nic_s *aq_nic = netdev_priv(ndev); + + aq_nic_get_link_ksettings(aq_nic, cmd); + cmd->base.speed = netif_carrier_ok(ndev) ? + aq_nic_get_link_speed(aq_nic) : 0U; + + return 0; +} + +static int +aq_ethtool_set_link_ksettings(struct net_device *ndev, + const struct ethtool_link_ksettings *cmd) +{ + struct aq_nic_s *aq_nic = netdev_priv(ndev); + + return aq_nic_set_link_ksettings(aq_nic, cmd); +} + +static const char aq_ethtool_stat_names[][ETH_GSTRING_LEN] = { + "InPackets", + "InUCast", + "InMCast", + "InBCast", + "InErrors", + "OutPackets", + "OutUCast", + "OutMCast", + "OutBCast", + "InUCastOctets", + "OutUCastOctets", + "InMCastOctets", + "OutMCastOctets", + "InBCastOctets", + "OutBCastOctets", + "InOctets", + "OutOctets", + "InPacketsDma", + "OutPacketsDma", + "InOctetsDma", + "OutOctetsDma", + "InDroppedDma", +}; + +static const char aq_ethtool_queue_stat_names[][ETH_GSTRING_LEN] = { + "Queue[%d] InPackets", + "Queue[%d] OutPackets", + "Queue[%d] Restarts", + "Queue[%d] InJumboPackets", + "Queue[%d] InLroPackets", + "Queue[%d] InErrors", +}; + +static void aq_ethtool_stats(struct net_device *ndev, + struct ethtool_stats *stats, u64 *data) +{ + struct aq_nic_s *aq_nic = netdev_priv(ndev); + struct aq_nic_cfg_s *cfg = aq_nic_get_cfg(aq_nic); + + memset(data, 0, (ARRAY_SIZE(aq_ethtool_stat_names) + + ARRAY_SIZE(aq_ethtool_queue_stat_names) * + cfg->vecs) * sizeof(u64)); + aq_nic_get_stats(aq_nic, data); +} + +static void aq_ethtool_get_drvinfo(struct net_device *ndev, + struct ethtool_drvinfo *drvinfo) +{ + struct aq_nic_s *aq_nic = netdev_priv(ndev); + struct aq_nic_cfg_s *cfg = aq_nic_get_cfg(aq_nic); + struct pci_dev *pdev = to_pci_dev(ndev->dev.parent); + u32 firmware_version = aq_nic_get_fw_version(aq_nic); + u32 regs_count = aq_nic_get_regs_count(aq_nic); + + strlcat(drvinfo->driver, AQ_CFG_DRV_NAME, sizeof(drvinfo->driver)); + strlcat(drvinfo->version, AQ_CFG_DRV_VERSION, sizeof(drvinfo->version)); + + snprintf(drvinfo->fw_version, sizeof(drvinfo->fw_version), + "%u.%u.%u", firmware_version >> 24, + (firmware_version >> 16) & 0xFFU, firmware_version & 0xFFFFU); + + strlcpy(drvinfo->bus_info, pdev ? pci_name(pdev) : "", + sizeof(drvinfo->bus_info)); + drvinfo->n_stats = ARRAY_SIZE(aq_ethtool_stat_names) + + cfg->vecs * ARRAY_SIZE(aq_ethtool_queue_stat_names); + drvinfo->testinfo_len = 0; + drvinfo->regdump_len = regs_count; + drvinfo->eedump_len = 0; +} + +static void aq_ethtool_get_strings(struct net_device *ndev, + u32 stringset, u8 *data) +{ + int i, si; + struct aq_nic_s *aq_nic = netdev_priv(ndev); + struct aq_nic_cfg_s *cfg = aq_nic_get_cfg(aq_nic); + u8 *p = data; + + if (stringset == ETH_SS_STATS) { + memcpy(p, *aq_ethtool_stat_names, + sizeof(aq_ethtool_stat_names)); + p = p + sizeof(aq_ethtool_stat_names); + for (i = 0; i < cfg->vecs; i++) { + for (si = 0; + si < ARRAY_SIZE(aq_ethtool_queue_stat_names); + si++) { + snprintf(p, ETH_GSTRING_LEN, + aq_ethtool_queue_stat_names[si], i); + p += ETH_GSTRING_LEN; + } + } + } +} + +static int aq_ethtool_get_sset_count(struct net_device *ndev, int stringset) +{ + int ret = 0; + struct aq_nic_s *aq_nic = netdev_priv(ndev); + struct aq_nic_cfg_s *cfg = aq_nic_get_cfg(aq_nic); + + switch (stringset) { + case ETH_SS_STATS: + ret = ARRAY_SIZE(aq_ethtool_stat_names) + + cfg->vecs * ARRAY_SIZE(aq_ethtool_queue_stat_names); + break; + default: + ret = -EOPNOTSUPP; + } + return ret; +} + +static u32 aq_ethtool_get_rss_indir_size(struct net_device *ndev) +{ + return AQ_CFG_RSS_INDIRECTION_TABLE_MAX; +} + +static u32 aq_ethtool_get_rss_key_size(struct net_device *ndev) +{ + struct aq_nic_s *aq_nic = netdev_priv(ndev); + struct aq_nic_cfg_s *cfg = aq_nic_get_cfg(aq_nic); + + return sizeof(cfg->aq_rss.hash_secret_key); +} + +static int aq_ethtool_get_rss(struct net_device *ndev, u32 *indir, u8 *key, + u8 *hfunc) +{ + struct aq_nic_s *aq_nic = netdev_priv(ndev); + struct aq_nic_cfg_s *cfg = aq_nic_get_cfg(aq_nic); + unsigned int i = 0U; + + if (hfunc) + *hfunc = ETH_RSS_HASH_TOP; /* Toeplitz */ + if (indir) { + for (i = 0; i < AQ_CFG_RSS_INDIRECTION_TABLE_MAX; i++) + indir[i] = cfg->aq_rss.indirection_table[i]; + } + if (key) + memcpy(key, cfg->aq_rss.hash_secret_key, + sizeof(cfg->aq_rss.hash_secret_key)); + return 0; +} + +static int aq_ethtool_get_rxnfc(struct net_device *ndev, + struct ethtool_rxnfc *cmd, + u32 *rule_locs) +{ + struct aq_nic_s *aq_nic = netdev_priv(ndev); + struct aq_nic_cfg_s *cfg = aq_nic_get_cfg(aq_nic); + int err = 0; + + switch (cmd->cmd) { + case ETHTOOL_GRXRINGS: + cmd->data = cfg->vecs; + break; + + default: + err = -EOPNOTSUPP; + break; + } + + return err; +} + +static int aq_ethtool_get_coalesce(struct net_device *ndev, + struct ethtool_coalesce *coal) +{ + struct aq_nic_s *aq_nic = netdev_priv(ndev); + struct aq_nic_cfg_s *cfg = aq_nic_get_cfg(aq_nic); + + if (cfg->itr == AQ_CFG_INTERRUPT_MODERATION_ON || + cfg->itr == AQ_CFG_INTERRUPT_MODERATION_AUTO) { + coal->rx_coalesce_usecs = cfg->rx_itr; + coal->tx_coalesce_usecs = cfg->tx_itr; + coal->rx_max_coalesced_frames = 0; + coal->tx_max_coalesced_frames = 0; + } else { + coal->rx_coalesce_usecs = 0; + coal->tx_coalesce_usecs = 0; + coal->rx_max_coalesced_frames = 1; + coal->tx_max_coalesced_frames = 1; + } + return 0; +} + +static int aq_ethtool_set_coalesce(struct net_device *ndev, + struct ethtool_coalesce *coal) +{ + struct aq_nic_s *aq_nic = netdev_priv(ndev); + struct aq_nic_cfg_s *cfg = aq_nic_get_cfg(aq_nic); + + /* This is not yet supported + */ + if (coal->use_adaptive_rx_coalesce || coal->use_adaptive_tx_coalesce) + return -EOPNOTSUPP; + + /* Atlantic only supports timing based coalescing + */ + if (coal->rx_max_coalesced_frames > 1 || + coal->rx_coalesce_usecs_irq || + coal->rx_max_coalesced_frames_irq) + return -EOPNOTSUPP; + + if (coal->tx_max_coalesced_frames > 1 || + coal->tx_coalesce_usecs_irq || + coal->tx_max_coalesced_frames_irq) + return -EOPNOTSUPP; + + /* We do not support frame counting. Check this + */ + if (!(coal->rx_max_coalesced_frames == !coal->rx_coalesce_usecs)) + return -EOPNOTSUPP; + if (!(coal->tx_max_coalesced_frames == !coal->tx_coalesce_usecs)) + return -EOPNOTSUPP; + + if (coal->rx_coalesce_usecs > AQ_CFG_INTERRUPT_MODERATION_USEC_MAX || + coal->tx_coalesce_usecs > AQ_CFG_INTERRUPT_MODERATION_USEC_MAX) + return -EINVAL; + + cfg->itr = AQ_CFG_INTERRUPT_MODERATION_ON; + + cfg->rx_itr = coal->rx_coalesce_usecs; + cfg->tx_itr = coal->tx_coalesce_usecs; + + return aq_nic_update_interrupt_moderation_settings(aq_nic); +} + +static int aq_ethtool_nway_reset(struct net_device *ndev) +{ + struct aq_nic_s *aq_nic = netdev_priv(ndev); + + if (unlikely(!aq_nic->aq_fw_ops->renegotiate)) + return -EOPNOTSUPP; + + if (netif_running(ndev)) + return aq_nic->aq_fw_ops->renegotiate(aq_nic->aq_hw); + + return 0; +} + +static void aq_ethtool_get_pauseparam(struct net_device *ndev, + struct ethtool_pauseparam *pause) +{ + struct aq_nic_s *aq_nic = netdev_priv(ndev); + + pause->autoneg = 0; + + if (aq_nic->aq_hw->aq_nic_cfg->flow_control & AQ_NIC_FC_RX) + pause->rx_pause = 1; + if (aq_nic->aq_hw->aq_nic_cfg->flow_control & AQ_NIC_FC_TX) + pause->tx_pause = 1; +} + +static int aq_ethtool_set_pauseparam(struct net_device *ndev, + struct ethtool_pauseparam *pause) +{ + struct aq_nic_s *aq_nic = netdev_priv(ndev); + int err = 0; + + if (!aq_nic->aq_fw_ops->set_flow_control) + return -EOPNOTSUPP; + + if (pause->autoneg == AUTONEG_ENABLE) + return -EOPNOTSUPP; + + if (pause->rx_pause) + aq_nic->aq_hw->aq_nic_cfg->flow_control |= AQ_NIC_FC_RX; + else + aq_nic->aq_hw->aq_nic_cfg->flow_control &= ~AQ_NIC_FC_RX; + + if (pause->tx_pause) + aq_nic->aq_hw->aq_nic_cfg->flow_control |= AQ_NIC_FC_TX; + else + aq_nic->aq_hw->aq_nic_cfg->flow_control &= ~AQ_NIC_FC_TX; + + err = aq_nic->aq_fw_ops->set_flow_control(aq_nic->aq_hw); + + return err; +} + +static void aq_get_ringparam(struct net_device *ndev, + struct ethtool_ringparam *ring) +{ + struct aq_nic_s *aq_nic = netdev_priv(ndev); + struct aq_nic_cfg_s *aq_nic_cfg = aq_nic_get_cfg(aq_nic); + + ring->rx_pending = aq_nic_cfg->rxds; + ring->tx_pending = aq_nic_cfg->txds; + + ring->rx_max_pending = aq_nic_cfg->aq_hw_caps->rxds_max; + ring->tx_max_pending = aq_nic_cfg->aq_hw_caps->txds_max; +} + +static int aq_set_ringparam(struct net_device *ndev, + struct ethtool_ringparam *ring) +{ + int err = 0; + bool ndev_running = false; + struct aq_nic_s *aq_nic = netdev_priv(ndev); + struct aq_nic_cfg_s *aq_nic_cfg = aq_nic_get_cfg(aq_nic); + const struct aq_hw_caps_s *hw_caps = aq_nic_cfg->aq_hw_caps; + + if (ring->rx_mini_pending || ring->rx_jumbo_pending) { + err = -EOPNOTSUPP; + goto err_exit; + } + + if (netif_running(ndev)) { + ndev_running = true; + dev_close(ndev); + } + + aq_nic_free_vectors(aq_nic); + + aq_nic_cfg->rxds = max(ring->rx_pending, hw_caps->rxds_min); + aq_nic_cfg->rxds = min(aq_nic_cfg->rxds, hw_caps->rxds_max); + aq_nic_cfg->rxds = ALIGN(aq_nic_cfg->rxds, AQ_HW_RXD_MULTIPLE); + + aq_nic_cfg->txds = max(ring->tx_pending, hw_caps->txds_min); + aq_nic_cfg->txds = min(aq_nic_cfg->txds, hw_caps->txds_max); + aq_nic_cfg->txds = ALIGN(aq_nic_cfg->txds, AQ_HW_TXD_MULTIPLE); + + for (aq_nic->aq_vecs = 0; aq_nic->aq_vecs < aq_nic_cfg->vecs; + aq_nic->aq_vecs++) { + aq_nic->aq_vec[aq_nic->aq_vecs] = + aq_vec_alloc(aq_nic, aq_nic->aq_vecs, aq_nic_cfg); + if (unlikely(!aq_nic->aq_vec[aq_nic->aq_vecs])) { + err = -ENOMEM; + goto err_exit; + } + } + if (ndev_running) + err = dev_open(ndev); + +err_exit: + return err; +} + +const struct ethtool_ops aq_ethtool_ops = { + .get_link = aq_ethtool_get_link, + .get_regs_len = aq_ethtool_get_regs_len, + .get_regs = aq_ethtool_get_regs, + .get_drvinfo = aq_ethtool_get_drvinfo, + .get_strings = aq_ethtool_get_strings, + .get_rxfh_indir_size = aq_ethtool_get_rss_indir_size, + .nway_reset = aq_ethtool_nway_reset, + .get_ringparam = aq_get_ringparam, + .set_ringparam = aq_set_ringparam, + .get_pauseparam = aq_ethtool_get_pauseparam, + .set_pauseparam = aq_ethtool_set_pauseparam, + .get_rxfh_key_size = aq_ethtool_get_rss_key_size, + .get_rxfh = aq_ethtool_get_rss, + .get_rxnfc = aq_ethtool_get_rxnfc, + .get_sset_count = aq_ethtool_get_sset_count, + .get_ethtool_stats = aq_ethtool_stats, + .get_link_ksettings = aq_ethtool_get_link_ksettings, + .set_link_ksettings = aq_ethtool_set_link_ksettings, + .get_coalesce = aq_ethtool_get_coalesce, + .set_coalesce = aq_ethtool_set_coalesce, +}; diff --git a/drivers/net/ethernet/aquantia/atlantic/aq_ethtool.h b/drivers/net/ethernet/aquantia/atlantic/aq_ethtool.h new file mode 100644 index 000000000..21c126eeb --- /dev/null +++ b/drivers/net/ethernet/aquantia/atlantic/aq_ethtool.h @@ -0,0 +1,19 @@ +/* + * aQuantia Corporation Network Driver + * Copyright (C) 2014-2017 aQuantia Corporation. All rights reserved + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + */ + +/* File aq_ethtool.h: Declaration of ethertool related functions. */ + +#ifndef AQ_ETHTOOL_H +#define AQ_ETHTOOL_H + +#include "aq_common.h" + +extern const struct ethtool_ops aq_ethtool_ops; + +#endif /* AQ_ETHTOOL_H */ diff --git a/drivers/net/ethernet/aquantia/atlantic/aq_hw.h b/drivers/net/ethernet/aquantia/atlantic/aq_hw.h new file mode 100644 index 000000000..5c00671f2 --- /dev/null +++ b/drivers/net/ethernet/aquantia/atlantic/aq_hw.h @@ -0,0 +1,233 @@ +/* + * aQuantia Corporation Network Driver + * Copyright (C) 2014-2017 aQuantia Corporation. All rights reserved + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + */ + +/* File aq_hw.h: Declaration of abstract interface for NIC hardware specific + * functions. + */ + +#ifndef AQ_HW_H +#define AQ_HW_H + +#include "aq_common.h" +#include "aq_rss.h" +#include "hw_atl/hw_atl_utils.h" + +/* NIC H/W capabilities */ +struct aq_hw_caps_s { + u64 hw_features; + u64 link_speed_msk; + unsigned int hw_priv_flags; + u32 media_type; + u32 rxds_max; + u32 txds_max; + u32 rxds_min; + u32 txds_min; + u32 txhwb_alignment; + u32 irq_mask; + u32 vecs; + u32 mtu; + u32 mac_regs_count; + u32 hw_alive_check_addr; + u8 msix_irqs; + u8 tcs; + u8 rxd_alignment; + u8 rxd_size; + u8 txd_alignment; + u8 txd_size; + u8 tx_rings; + u8 rx_rings; + bool flow_control; + bool is_64_dma; +}; + +struct aq_hw_link_status_s { + unsigned int mbps; +}; + +struct aq_stats_s { + u64 uprc; + u64 mprc; + u64 bprc; + u64 erpt; + u64 uptc; + u64 mptc; + u64 bptc; + u64 erpr; + u64 mbtc; + u64 bbtc; + u64 mbrc; + u64 bbrc; + u64 ubrc; + u64 ubtc; + u64 dpc; + u64 dma_pkt_rc; + u64 dma_pkt_tc; + u64 dma_oct_rc; + u64 dma_oct_tc; +}; + +#define AQ_HW_IRQ_INVALID 0U +#define AQ_HW_IRQ_LEGACY 1U +#define AQ_HW_IRQ_MSI 2U +#define AQ_HW_IRQ_MSIX 3U + +#define AQ_HW_POWER_STATE_D0 0U +#define AQ_HW_POWER_STATE_D3 3U + +#define AQ_HW_FLAG_STARTED 0x00000004U +#define AQ_HW_FLAG_STOPPING 0x00000008U +#define AQ_HW_FLAG_RESETTING 0x00000010U +#define AQ_HW_FLAG_CLOSING 0x00000020U +#define AQ_HW_LINK_DOWN 0x04000000U +#define AQ_HW_FLAG_ERR_UNPLUG 0x40000000U +#define AQ_HW_FLAG_ERR_HW 0x80000000U + +#define AQ_HW_FLAG_ERRORS (AQ_HW_FLAG_ERR_HW | AQ_HW_FLAG_ERR_UNPLUG) + +#define AQ_NIC_FLAGS_IS_NOT_READY (AQ_NIC_FLAG_STOPPING | \ + AQ_NIC_FLAG_RESETTING | AQ_NIC_FLAG_CLOSING | \ + AQ_NIC_FLAG_ERR_UNPLUG | AQ_NIC_FLAG_ERR_HW) + +#define AQ_NIC_FLAGS_IS_NOT_TX_READY (AQ_NIC_FLAGS_IS_NOT_READY | \ + AQ_NIC_LINK_DOWN) + +#define AQ_HW_MEDIA_TYPE_TP 1U +#define AQ_HW_MEDIA_TYPE_FIBRE 2U + +#define AQ_HW_TXD_MULTIPLE 8U +#define AQ_HW_RXD_MULTIPLE 8U + +#define AQ_HW_MULTICAST_ADDRESS_MAX 32U + +struct aq_hw_s { + atomic_t flags; + u8 rbl_enabled:1; + struct aq_nic_cfg_s *aq_nic_cfg; + const struct aq_fw_ops *aq_fw_ops; + void __iomem *mmio; + struct aq_hw_link_status_s aq_link_status; + struct hw_aq_atl_utils_mbox mbox; + struct hw_atl_stats_s last_stats; + struct aq_stats_s curr_stats; + u64 speed; + u32 itr_tx; + u32 itr_rx; + unsigned int chip_features; + u32 fw_ver_actual; + atomic_t dpc; + u32 mbox_addr; + u32 rpc_addr; + u32 rpc_tid; + struct hw_aq_atl_utils_fw_rpc rpc; +}; + +struct aq_ring_s; +struct aq_ring_param_s; +struct sk_buff; + +struct aq_hw_ops { + + int (*hw_ring_tx_xmit)(struct aq_hw_s *self, struct aq_ring_s *aq_ring, + unsigned int frags); + + int (*hw_ring_rx_receive)(struct aq_hw_s *self, + struct aq_ring_s *aq_ring); + + int (*hw_ring_rx_fill)(struct aq_hw_s *self, struct aq_ring_s *aq_ring, + unsigned int sw_tail_old); + + int (*hw_ring_tx_head_update)(struct aq_hw_s *self, + struct aq_ring_s *aq_ring); + + int (*hw_set_mac_address)(struct aq_hw_s *self, u8 *mac_addr); + + int (*hw_reset)(struct aq_hw_s *self); + + int (*hw_init)(struct aq_hw_s *self, u8 *mac_addr); + + int (*hw_start)(struct aq_hw_s *self); + + int (*hw_stop)(struct aq_hw_s *self); + + int (*hw_ring_tx_init)(struct aq_hw_s *self, struct aq_ring_s *aq_ring, + struct aq_ring_param_s *aq_ring_param); + + int (*hw_ring_tx_start)(struct aq_hw_s *self, + struct aq_ring_s *aq_ring); + + int (*hw_ring_tx_stop)(struct aq_hw_s *self, + struct aq_ring_s *aq_ring); + + int (*hw_ring_rx_init)(struct aq_hw_s *self, + struct aq_ring_s *aq_ring, + struct aq_ring_param_s *aq_ring_param); + + int (*hw_ring_rx_start)(struct aq_hw_s *self, + struct aq_ring_s *aq_ring); + + int (*hw_ring_rx_stop)(struct aq_hw_s *self, + struct aq_ring_s *aq_ring); + + int (*hw_irq_enable)(struct aq_hw_s *self, u64 mask); + + int (*hw_irq_disable)(struct aq_hw_s *self, u64 mask); + + int (*hw_irq_read)(struct aq_hw_s *self, u64 *mask); + + int (*hw_packet_filter_set)(struct aq_hw_s *self, + unsigned int packet_filter); + + int (*hw_multicast_list_set)(struct aq_hw_s *self, + u8 ar_mac[AQ_HW_MULTICAST_ADDRESS_MAX] + [ETH_ALEN], + u32 count); + + int (*hw_interrupt_moderation_set)(struct aq_hw_s *self); + + int (*hw_rss_set)(struct aq_hw_s *self, + struct aq_rss_parameters *rss_params); + + int (*hw_rss_hash_set)(struct aq_hw_s *self, + struct aq_rss_parameters *rss_params); + + int (*hw_get_regs)(struct aq_hw_s *self, + const struct aq_hw_caps_s *aq_hw_caps, + u32 *regs_buff); + + struct aq_stats_s *(*hw_get_hw_stats)(struct aq_hw_s *self); + + int (*hw_get_fw_version)(struct aq_hw_s *self, u32 *fw_version); + + int (*hw_set_power)(struct aq_hw_s *self, unsigned int power_state); +}; + +struct aq_fw_ops { + int (*init)(struct aq_hw_s *self); + + int (*deinit)(struct aq_hw_s *self); + + int (*reset)(struct aq_hw_s *self); + + int (*renegotiate)(struct aq_hw_s *self); + + int (*get_mac_permanent)(struct aq_hw_s *self, u8 *mac); + + int (*set_link_speed)(struct aq_hw_s *self, u32 speed); + + int (*set_state)(struct aq_hw_s *self, + enum hal_atl_utils_fw_state_e state); + + int (*update_link_status)(struct aq_hw_s *self); + + int (*update_stats)(struct aq_hw_s *self); + + int (*set_flow_control)(struct aq_hw_s *self); +}; + +#endif /* AQ_HW_H */ diff --git a/drivers/net/ethernet/aquantia/atlantic/aq_hw_utils.c b/drivers/net/ethernet/aquantia/atlantic/aq_hw_utils.c new file mode 100644 index 000000000..d526c4f19 --- /dev/null +++ b/drivers/net/ethernet/aquantia/atlantic/aq_hw_utils.c @@ -0,0 +1,71 @@ +/* + * aQuantia Corporation Network Driver + * Copyright (C) 2014-2017 aQuantia Corporation. All rights reserved + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + */ + +/* File aq_hw_utils.c: Definitions of helper functions used across + * hardware layer. + */ + +#include "aq_hw_utils.h" +#include "aq_hw.h" +#include "aq_nic.h" + +void aq_hw_write_reg_bit(struct aq_hw_s *aq_hw, u32 addr, u32 msk, + u32 shift, u32 val) +{ + if (msk ^ ~0) { + u32 reg_old, reg_new; + + reg_old = aq_hw_read_reg(aq_hw, addr); + reg_new = (reg_old & (~msk)) | (val << shift); + + if (reg_old != reg_new) + aq_hw_write_reg(aq_hw, addr, reg_new); + } else { + aq_hw_write_reg(aq_hw, addr, val); + } +} + +u32 aq_hw_read_reg_bit(struct aq_hw_s *aq_hw, u32 addr, u32 msk, u32 shift) +{ + return ((aq_hw_read_reg(aq_hw, addr) & msk) >> shift); +} + +u32 aq_hw_read_reg(struct aq_hw_s *hw, u32 reg) +{ + u32 value = readl(hw->mmio + reg); + + if ((~0U) == value && + (~0U) == readl(hw->mmio + + hw->aq_nic_cfg->aq_hw_caps->hw_alive_check_addr)) + aq_utils_obj_set(&hw->flags, AQ_HW_FLAG_ERR_UNPLUG); + + return value; +} + +void aq_hw_write_reg(struct aq_hw_s *hw, u32 reg, u32 value) +{ + writel(value, hw->mmio + reg); +} + +int aq_hw_err_from_flags(struct aq_hw_s *hw) +{ + int err = 0; + + if (aq_utils_obj_test(&hw->flags, AQ_HW_FLAG_ERR_UNPLUG)) { + err = -ENXIO; + goto err_exit; + } + if (aq_utils_obj_test(&hw->flags, AQ_HW_FLAG_ERR_HW)) { + err = -EIO; + goto err_exit; + } + +err_exit: + return err; +} diff --git a/drivers/net/ethernet/aquantia/atlantic/aq_hw_utils.h b/drivers/net/ethernet/aquantia/atlantic/aq_hw_utils.h new file mode 100644 index 000000000..dc88a1221 --- /dev/null +++ b/drivers/net/ethernet/aquantia/atlantic/aq_hw_utils.h @@ -0,0 +1,50 @@ +/* + * aQuantia Corporation Network Driver + * Copyright (C) 2014-2017 aQuantia Corporation. All rights reserved + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + */ + +/* File aq_hw_utils.h: Declaration of helper functions used across hardware + * layer. + */ + +#ifndef AQ_HW_UTILS_H +#define AQ_HW_UTILS_H + +#include "aq_common.h" + +#ifndef HIDWORD +#define LODWORD(_qw) ((u32)(_qw)) +#define HIDWORD(_qw) ((u32)(((_qw) >> 32) & 0xffffffff)) +#endif + +#define AQ_HW_SLEEP(_US_) mdelay(_US_) + +#define AQ_HW_WAIT_FOR(_B_, _US_, _N_) \ +do { \ + unsigned int AQ_HW_WAIT_FOR_i; \ + for (AQ_HW_WAIT_FOR_i = _N_; (!(_B_)) && (AQ_HW_WAIT_FOR_i);\ + --AQ_HW_WAIT_FOR_i) {\ + udelay(_US_); \ + } \ + if (!AQ_HW_WAIT_FOR_i) {\ + err = -ETIME; \ + } \ +} while (0) + +#define aq_pr_err(...) pr_err(AQ_CFG_DRV_NAME ": " __VA_ARGS__) +#define aq_pr_trace(...) pr_info(AQ_CFG_DRV_NAME ": " __VA_ARGS__) + +struct aq_hw_s; + +void aq_hw_write_reg_bit(struct aq_hw_s *aq_hw, u32 addr, u32 msk, + u32 shift, u32 val); +u32 aq_hw_read_reg_bit(struct aq_hw_s *aq_hw, u32 addr, u32 msk, u32 shift); +u32 aq_hw_read_reg(struct aq_hw_s *hw, u32 reg); +void aq_hw_write_reg(struct aq_hw_s *hw, u32 reg, u32 value); +int aq_hw_err_from_flags(struct aq_hw_s *hw); + +#endif /* AQ_HW_UTILS_H */ diff --git a/drivers/net/ethernet/aquantia/atlantic/aq_main.c b/drivers/net/ethernet/aquantia/atlantic/aq_main.c new file mode 100644 index 000000000..daf841ae3 --- /dev/null +++ b/drivers/net/ethernet/aquantia/atlantic/aq_main.c @@ -0,0 +1,154 @@ +/* + * aQuantia Corporation Network Driver + * Copyright (C) 2014-2017 aQuantia Corporation. All rights reserved + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + */ + +/* File aq_main.c: Main file for aQuantia Linux driver. */ + +#include "aq_main.h" +#include "aq_nic.h" +#include "aq_pci_func.h" +#include "aq_ethtool.h" + +#include <linux/netdevice.h> +#include <linux/module.h> + +MODULE_LICENSE("GPL v2"); +MODULE_VERSION(AQ_CFG_DRV_VERSION); +MODULE_AUTHOR(AQ_CFG_DRV_AUTHOR); +MODULE_DESCRIPTION(AQ_CFG_DRV_DESC); + +static const struct net_device_ops aq_ndev_ops; + +struct net_device *aq_ndev_alloc(void) +{ + struct net_device *ndev = NULL; + struct aq_nic_s *aq_nic = NULL; + + ndev = alloc_etherdev_mq(sizeof(struct aq_nic_s), AQ_CFG_VECS_MAX); + if (!ndev) + return NULL; + + aq_nic = netdev_priv(ndev); + aq_nic->ndev = ndev; + ndev->netdev_ops = &aq_ndev_ops; + ndev->ethtool_ops = &aq_ethtool_ops; + + return ndev; +} + +static int aq_ndev_open(struct net_device *ndev) +{ + int err = 0; + struct aq_nic_s *aq_nic = netdev_priv(ndev); + + err = aq_nic_init(aq_nic); + if (err < 0) + goto err_exit; + err = aq_nic_start(aq_nic); + if (err < 0) { + aq_nic_stop(aq_nic); + goto err_exit; + } + +err_exit: + if (err < 0) + aq_nic_deinit(aq_nic); + return err; +} + +static int aq_ndev_close(struct net_device *ndev) +{ + int err = 0; + struct aq_nic_s *aq_nic = netdev_priv(ndev); + + err = aq_nic_stop(aq_nic); + if (err < 0) + goto err_exit; + aq_nic_deinit(aq_nic); + +err_exit: + return err; +} + +static int aq_ndev_start_xmit(struct sk_buff *skb, struct net_device *ndev) +{ + struct aq_nic_s *aq_nic = netdev_priv(ndev); + + return aq_nic_xmit(aq_nic, skb); +} + +static int aq_ndev_change_mtu(struct net_device *ndev, int new_mtu) +{ + struct aq_nic_s *aq_nic = netdev_priv(ndev); + int err = aq_nic_set_mtu(aq_nic, new_mtu + ETH_HLEN); + + if (err < 0) + goto err_exit; + ndev->mtu = new_mtu; + +err_exit: + return err; +} + +static int aq_ndev_set_features(struct net_device *ndev, + netdev_features_t features) +{ + struct aq_nic_s *aq_nic = netdev_priv(ndev); + struct aq_nic_cfg_s *aq_cfg = aq_nic_get_cfg(aq_nic); + bool is_lro = false; + + if (aq_cfg->hw_features & NETIF_F_LRO) { + is_lro = features & NETIF_F_LRO; + + if (aq_cfg->is_lro != is_lro) { + aq_cfg->is_lro = is_lro; + + if (netif_running(ndev)) { + aq_ndev_close(ndev); + aq_ndev_open(ndev); + } + } + } + + return 0; +} + +static int aq_ndev_set_mac_address(struct net_device *ndev, void *addr) +{ + struct aq_nic_s *aq_nic = netdev_priv(ndev); + int err = 0; + + err = eth_mac_addr(ndev, addr); + if (err < 0) + goto err_exit; + err = aq_nic_set_mac(aq_nic, ndev); + if (err < 0) + goto err_exit; + +err_exit: + return err; +} + +static void aq_ndev_set_multicast_settings(struct net_device *ndev) +{ + struct aq_nic_s *aq_nic = netdev_priv(ndev); + + aq_nic_set_packet_filter(aq_nic, ndev->flags); + + aq_nic_set_multicast_list(aq_nic, ndev); +} + +static const struct net_device_ops aq_ndev_ops = { + .ndo_open = aq_ndev_open, + .ndo_stop = aq_ndev_close, + .ndo_start_xmit = aq_ndev_start_xmit, + .ndo_set_rx_mode = aq_ndev_set_multicast_settings, + .ndo_change_mtu = aq_ndev_change_mtu, + .ndo_set_mac_address = aq_ndev_set_mac_address, + .ndo_set_features = aq_ndev_set_features +}; diff --git a/drivers/net/ethernet/aquantia/atlantic/aq_main.h b/drivers/net/ethernet/aquantia/atlantic/aq_main.h new file mode 100644 index 000000000..ce92152eb --- /dev/null +++ b/drivers/net/ethernet/aquantia/atlantic/aq_main.h @@ -0,0 +1,19 @@ +/* + * aQuantia Corporation Network Driver + * Copyright (C) 2014-2017 aQuantia Corporation. All rights reserved + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + */ + +/* File aq_main.h: Main file for aQuantia Linux driver. */ + +#ifndef AQ_MAIN_H +#define AQ_MAIN_H + +#include "aq_common.h" + +struct net_device *aq_ndev_alloc(void); + +#endif /* AQ_MAIN_H */ diff --git a/drivers/net/ethernet/aquantia/atlantic/aq_nic.c b/drivers/net/ethernet/aquantia/atlantic/aq_nic.c new file mode 100644 index 000000000..adac5df0d --- /dev/null +++ b/drivers/net/ethernet/aquantia/atlantic/aq_nic.c @@ -0,0 +1,981 @@ +/* + * aQuantia Corporation Network Driver + * Copyright (C) 2014-2017 aQuantia Corporation. All rights reserved + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + */ + +/* File aq_nic.c: Definition of common code for NIC. */ + +#include "aq_nic.h" +#include "aq_ring.h" +#include "aq_vec.h" +#include "aq_hw.h" +#include "aq_pci_func.h" + +#include <linux/moduleparam.h> +#include <linux/netdevice.h> +#include <linux/etherdevice.h> +#include <linux/timer.h> +#include <linux/cpu.h> +#include <linux/ip.h> +#include <linux/tcp.h> +#include <net/ip.h> + +static unsigned int aq_itr = AQ_CFG_INTERRUPT_MODERATION_AUTO; +module_param_named(aq_itr, aq_itr, uint, 0644); +MODULE_PARM_DESC(aq_itr, "Interrupt throttling mode"); + +static unsigned int aq_itr_tx; +module_param_named(aq_itr_tx, aq_itr_tx, uint, 0644); +MODULE_PARM_DESC(aq_itr_tx, "TX interrupt throttle rate"); + +static unsigned int aq_itr_rx; +module_param_named(aq_itr_rx, aq_itr_rx, uint, 0644); +MODULE_PARM_DESC(aq_itr_rx, "RX interrupt throttle rate"); + +static void aq_nic_update_ndev_stats(struct aq_nic_s *self); + +static void aq_nic_rss_init(struct aq_nic_s *self, unsigned int num_rss_queues) +{ + struct aq_nic_cfg_s *cfg = &self->aq_nic_cfg; + struct aq_rss_parameters *rss_params = &cfg->aq_rss; + int i = 0; + + static u8 rss_key[AQ_CFG_RSS_HASHKEY_SIZE] = { + 0x1e, 0xad, 0x71, 0x87, 0x65, 0xfc, 0x26, 0x7d, + 0x0d, 0x45, 0x67, 0x74, 0xcd, 0x06, 0x1a, 0x18, + 0xb6, 0xc1, 0xf0, 0xc7, 0xbb, 0x18, 0xbe, 0xf8, + 0x19, 0x13, 0x4b, 0xa9, 0xd0, 0x3e, 0xfe, 0x70, + 0x25, 0x03, 0xab, 0x50, 0x6a, 0x8b, 0x82, 0x0c + }; + + rss_params->hash_secret_key_size = sizeof(rss_key); + memcpy(rss_params->hash_secret_key, rss_key, sizeof(rss_key)); + rss_params->indirection_table_size = AQ_CFG_RSS_INDIRECTION_TABLE_MAX; + + for (i = rss_params->indirection_table_size; i--;) + rss_params->indirection_table[i] = i & (num_rss_queues - 1); +} + +/* Checks hw_caps and 'corrects' aq_nic_cfg in runtime */ +void aq_nic_cfg_start(struct aq_nic_s *self) +{ + struct aq_nic_cfg_s *cfg = &self->aq_nic_cfg; + + cfg->tcs = AQ_CFG_TCS_DEF; + + cfg->is_polling = AQ_CFG_IS_POLLING_DEF; + + cfg->itr = aq_itr; + cfg->tx_itr = aq_itr_tx; + cfg->rx_itr = aq_itr_rx; + + cfg->is_rss = AQ_CFG_IS_RSS_DEF; + cfg->num_rss_queues = AQ_CFG_NUM_RSS_QUEUES_DEF; + cfg->aq_rss.base_cpu_number = AQ_CFG_RSS_BASE_CPU_NUM_DEF; + cfg->flow_control = AQ_CFG_FC_MODE; + + cfg->mtu = AQ_CFG_MTU_DEF; + cfg->link_speed_msk = AQ_CFG_SPEED_MSK; + cfg->is_autoneg = AQ_CFG_IS_AUTONEG_DEF; + + cfg->is_lro = AQ_CFG_IS_LRO_DEF; + + cfg->vlan_id = 0U; + + aq_nic_rss_init(self, cfg->num_rss_queues); + + /*descriptors */ + cfg->rxds = min(cfg->aq_hw_caps->rxds_max, AQ_CFG_RXDS_DEF); + cfg->txds = min(cfg->aq_hw_caps->txds_max, AQ_CFG_TXDS_DEF); + + /*rss rings */ + cfg->vecs = min(cfg->aq_hw_caps->vecs, AQ_CFG_VECS_DEF); + cfg->vecs = min(cfg->vecs, num_online_cpus()); + cfg->vecs = min(cfg->vecs, self->irqvecs); + /* cfg->vecs should be power of 2 for RSS */ + if (cfg->vecs >= 8U) + cfg->vecs = 8U; + else if (cfg->vecs >= 4U) + cfg->vecs = 4U; + else if (cfg->vecs >= 2U) + cfg->vecs = 2U; + else + cfg->vecs = 1U; + + cfg->num_rss_queues = min(cfg->vecs, AQ_CFG_NUM_RSS_QUEUES_DEF); + + cfg->irq_type = aq_pci_func_get_irq_type(self); + + if ((cfg->irq_type == AQ_HW_IRQ_LEGACY) || + (cfg->aq_hw_caps->vecs == 1U) || + (cfg->vecs == 1U)) { + cfg->is_rss = 0U; + cfg->vecs = 1U; + } + + cfg->link_speed_msk &= cfg->aq_hw_caps->link_speed_msk; + cfg->hw_features = cfg->aq_hw_caps->hw_features; +} + +static int aq_nic_update_link_status(struct aq_nic_s *self) +{ + int err = self->aq_fw_ops->update_link_status(self->aq_hw); + + if (err) + return err; + + if (self->link_status.mbps != self->aq_hw->aq_link_status.mbps) { + pr_info("%s: link change old %d new %d\n", + AQ_CFG_DRV_NAME, self->link_status.mbps, + self->aq_hw->aq_link_status.mbps); + aq_nic_update_interrupt_moderation_settings(self); + } + + self->link_status = self->aq_hw->aq_link_status; + if (!netif_carrier_ok(self->ndev) && self->link_status.mbps) { + aq_utils_obj_set(&self->flags, + AQ_NIC_FLAG_STARTED); + aq_utils_obj_clear(&self->flags, + AQ_NIC_LINK_DOWN); + netif_carrier_on(self->ndev); + netif_tx_wake_all_queues(self->ndev); + } + if (netif_carrier_ok(self->ndev) && !self->link_status.mbps) { + netif_carrier_off(self->ndev); + netif_tx_disable(self->ndev); + aq_utils_obj_set(&self->flags, AQ_NIC_LINK_DOWN); + } + return 0; +} + +static void aq_nic_service_timer_cb(struct timer_list *t) +{ + struct aq_nic_s *self = from_timer(self, t, service_timer); + int ctimer = AQ_CFG_SERVICE_TIMER_INTERVAL; + int err = 0; + + if (aq_utils_obj_test(&self->flags, AQ_NIC_FLAGS_IS_NOT_READY)) + goto err_exit; + + err = aq_nic_update_link_status(self); + if (err) + goto err_exit; + + if (self->aq_fw_ops->update_stats) + self->aq_fw_ops->update_stats(self->aq_hw); + + aq_nic_update_ndev_stats(self); + + /* If no link - use faster timer rate to detect link up asap */ + if (!netif_carrier_ok(self->ndev)) + ctimer = max(ctimer / 2, 1); + +err_exit: + mod_timer(&self->service_timer, jiffies + ctimer); +} + +static void aq_nic_polling_timer_cb(struct timer_list *t) +{ + struct aq_nic_s *self = from_timer(self, t, polling_timer); + struct aq_vec_s *aq_vec = NULL; + unsigned int i = 0U; + + for (i = 0U, aq_vec = self->aq_vec[0]; + self->aq_vecs > i; ++i, aq_vec = self->aq_vec[i]) + aq_vec_isr(i, (void *)aq_vec); + + mod_timer(&self->polling_timer, jiffies + + AQ_CFG_POLLING_TIMER_INTERVAL); +} + +int aq_nic_ndev_register(struct aq_nic_s *self) +{ + int err = 0; + + if (!self->ndev) { + err = -EINVAL; + goto err_exit; + } + + err = hw_atl_utils_initfw(self->aq_hw, &self->aq_fw_ops); + if (err) + goto err_exit; + + err = self->aq_fw_ops->get_mac_permanent(self->aq_hw, + self->ndev->dev_addr); + if (err) + goto err_exit; + +#if defined(AQ_CFG_MAC_ADDR_PERMANENT) + { + static u8 mac_addr_permanent[] = AQ_CFG_MAC_ADDR_PERMANENT; + + ether_addr_copy(self->ndev->dev_addr, mac_addr_permanent); + } +#endif + + for (self->aq_vecs = 0; self->aq_vecs < aq_nic_get_cfg(self)->vecs; + self->aq_vecs++) { + self->aq_vec[self->aq_vecs] = + aq_vec_alloc(self, self->aq_vecs, aq_nic_get_cfg(self)); + if (!self->aq_vec[self->aq_vecs]) { + err = -ENOMEM; + goto err_exit; + } + } + + netif_carrier_off(self->ndev); + + netif_tx_disable(self->ndev); + + err = register_netdev(self->ndev); + if (err) + goto err_exit; + +err_exit: + return err; +} + +void aq_nic_ndev_init(struct aq_nic_s *self) +{ + const struct aq_hw_caps_s *aq_hw_caps = self->aq_nic_cfg.aq_hw_caps; + struct aq_nic_cfg_s *aq_nic_cfg = &self->aq_nic_cfg; + + self->ndev->hw_features |= aq_hw_caps->hw_features; + self->ndev->features = aq_hw_caps->hw_features; + self->ndev->vlan_features |= NETIF_F_HW_CSUM | NETIF_F_RXCSUM | + NETIF_F_RXHASH | NETIF_F_SG | NETIF_F_LRO; + self->ndev->priv_flags = aq_hw_caps->hw_priv_flags; + self->ndev->priv_flags |= IFF_LIVE_ADDR_CHANGE; + + self->ndev->mtu = aq_nic_cfg->mtu - ETH_HLEN; + self->ndev->max_mtu = aq_hw_caps->mtu - ETH_FCS_LEN - ETH_HLEN; + +} + +void aq_nic_set_tx_ring(struct aq_nic_s *self, unsigned int idx, + struct aq_ring_s *ring) +{ + self->aq_ring_tx[idx] = ring; +} + +struct net_device *aq_nic_get_ndev(struct aq_nic_s *self) +{ + return self->ndev; +} + +int aq_nic_init(struct aq_nic_s *self) +{ + struct aq_vec_s *aq_vec = NULL; + int err = 0; + unsigned int i = 0U; + + self->power_state = AQ_HW_POWER_STATE_D0; + err = self->aq_hw_ops->hw_reset(self->aq_hw); + if (err < 0) + goto err_exit; + + err = self->aq_hw_ops->hw_init(self->aq_hw, + aq_nic_get_ndev(self)->dev_addr); + if (err < 0) + goto err_exit; + + for (i = 0U, aq_vec = self->aq_vec[0]; + self->aq_vecs > i; ++i, aq_vec = self->aq_vec[i]) + aq_vec_init(aq_vec, self->aq_hw_ops, self->aq_hw); + + netif_carrier_off(self->ndev); + +err_exit: + return err; +} + +int aq_nic_start(struct aq_nic_s *self) +{ + struct aq_vec_s *aq_vec = NULL; + int err = 0; + unsigned int i = 0U; + + err = self->aq_hw_ops->hw_multicast_list_set(self->aq_hw, + self->mc_list.ar, + self->mc_list.count); + if (err < 0) + goto err_exit; + + err = self->aq_hw_ops->hw_packet_filter_set(self->aq_hw, + self->packet_filter); + if (err < 0) + goto err_exit; + + for (i = 0U, aq_vec = self->aq_vec[0]; + self->aq_vecs > i; ++i, aq_vec = self->aq_vec[i]) { + err = aq_vec_start(aq_vec); + if (err < 0) + goto err_exit; + } + + err = self->aq_hw_ops->hw_start(self->aq_hw); + if (err < 0) + goto err_exit; + + err = aq_nic_update_interrupt_moderation_settings(self); + if (err) + goto err_exit; + timer_setup(&self->service_timer, aq_nic_service_timer_cb, 0); + mod_timer(&self->service_timer, jiffies + + AQ_CFG_SERVICE_TIMER_INTERVAL); + + if (self->aq_nic_cfg.is_polling) { + timer_setup(&self->polling_timer, aq_nic_polling_timer_cb, 0); + mod_timer(&self->polling_timer, jiffies + + AQ_CFG_POLLING_TIMER_INTERVAL); + } else { + for (i = 0U, aq_vec = self->aq_vec[0]; + self->aq_vecs > i; ++i, aq_vec = self->aq_vec[i]) { + err = aq_pci_func_alloc_irq(self, i, + self->ndev->name, aq_vec, + aq_vec_get_affinity_mask(aq_vec)); + if (err < 0) + goto err_exit; + } + + err = self->aq_hw_ops->hw_irq_enable(self->aq_hw, + AQ_CFG_IRQ_MASK); + if (err < 0) + goto err_exit; + } + + err = netif_set_real_num_tx_queues(self->ndev, self->aq_vecs); + if (err < 0) + goto err_exit; + + err = netif_set_real_num_rx_queues(self->ndev, self->aq_vecs); + if (err < 0) + goto err_exit; + + netif_tx_start_all_queues(self->ndev); + +err_exit: + return err; +} + +static unsigned int aq_nic_map_skb(struct aq_nic_s *self, + struct sk_buff *skb, + struct aq_ring_s *ring) +{ + unsigned int ret = 0U; + unsigned int nr_frags = skb_shinfo(skb)->nr_frags; + unsigned int frag_count = 0U; + unsigned int dx = ring->sw_tail; + struct aq_ring_buff_s *first = NULL; + struct aq_ring_buff_s *dx_buff = &ring->buff_ring[dx]; + + if (unlikely(skb_is_gso(skb))) { + dx_buff->flags = 0U; + dx_buff->len_pkt = skb->len; + dx_buff->len_l2 = ETH_HLEN; + dx_buff->len_l3 = ip_hdrlen(skb); + dx_buff->len_l4 = tcp_hdrlen(skb); + dx_buff->mss = skb_shinfo(skb)->gso_size; + dx_buff->is_txc = 1U; + dx_buff->eop_index = 0xffffU; + + dx_buff->is_ipv6 = + (ip_hdr(skb)->version == 6) ? 1U : 0U; + + dx = aq_ring_next_dx(ring, dx); + dx_buff = &ring->buff_ring[dx]; + ++ret; + } + + dx_buff->flags = 0U; + dx_buff->len = skb_headlen(skb); + dx_buff->pa = dma_map_single(aq_nic_get_dev(self), + skb->data, + dx_buff->len, + DMA_TO_DEVICE); + + if (unlikely(dma_mapping_error(aq_nic_get_dev(self), dx_buff->pa))) { + ret = 0; + goto exit; + } + + first = dx_buff; + dx_buff->len_pkt = skb->len; + dx_buff->is_sop = 1U; + dx_buff->is_mapped = 1U; + ++ret; + + if (skb->ip_summed == CHECKSUM_PARTIAL) { + dx_buff->is_ip_cso = (htons(ETH_P_IP) == skb->protocol) ? + 1U : 0U; + + if (ip_hdr(skb)->version == 4) { + dx_buff->is_tcp_cso = + (ip_hdr(skb)->protocol == IPPROTO_TCP) ? + 1U : 0U; + dx_buff->is_udp_cso = + (ip_hdr(skb)->protocol == IPPROTO_UDP) ? + 1U : 0U; + } else if (ip_hdr(skb)->version == 6) { + dx_buff->is_tcp_cso = + (ipv6_hdr(skb)->nexthdr == NEXTHDR_TCP) ? + 1U : 0U; + dx_buff->is_udp_cso = + (ipv6_hdr(skb)->nexthdr == NEXTHDR_UDP) ? + 1U : 0U; + } + } + + for (; nr_frags--; ++frag_count) { + unsigned int frag_len = 0U; + unsigned int buff_offset = 0U; + unsigned int buff_size = 0U; + dma_addr_t frag_pa; + skb_frag_t *frag = &skb_shinfo(skb)->frags[frag_count]; + + frag_len = skb_frag_size(frag); + + while (frag_len) { + if (frag_len > AQ_CFG_TX_FRAME_MAX) + buff_size = AQ_CFG_TX_FRAME_MAX; + else + buff_size = frag_len; + + frag_pa = skb_frag_dma_map(aq_nic_get_dev(self), + frag, + buff_offset, + buff_size, + DMA_TO_DEVICE); + + if (unlikely(dma_mapping_error(aq_nic_get_dev(self), + frag_pa))) + goto mapping_error; + + dx = aq_ring_next_dx(ring, dx); + dx_buff = &ring->buff_ring[dx]; + + dx_buff->flags = 0U; + dx_buff->len = buff_size; + dx_buff->pa = frag_pa; + dx_buff->is_mapped = 1U; + dx_buff->eop_index = 0xffffU; + + frag_len -= buff_size; + buff_offset += buff_size; + + ++ret; + } + } + + first->eop_index = dx; + dx_buff->is_eop = 1U; + dx_buff->skb = skb; + goto exit; + +mapping_error: + for (dx = ring->sw_tail; + ret > 0; + --ret, dx = aq_ring_next_dx(ring, dx)) { + dx_buff = &ring->buff_ring[dx]; + + if (!dx_buff->is_txc && dx_buff->pa) { + if (unlikely(dx_buff->is_sop)) { + dma_unmap_single(aq_nic_get_dev(self), + dx_buff->pa, + dx_buff->len, + DMA_TO_DEVICE); + } else { + dma_unmap_page(aq_nic_get_dev(self), + dx_buff->pa, + dx_buff->len, + DMA_TO_DEVICE); + } + } + } + +exit: + return ret; +} + +int aq_nic_xmit(struct aq_nic_s *self, struct sk_buff *skb) +{ + struct aq_ring_s *ring = NULL; + unsigned int frags = 0U; + unsigned int vec = skb->queue_mapping % self->aq_nic_cfg.vecs; + unsigned int tc = 0U; + int err = NETDEV_TX_OK; + + frags = skb_shinfo(skb)->nr_frags + 1; + + ring = self->aq_ring_tx[AQ_NIC_TCVEC2RING(self, tc, vec)]; + + if (frags > AQ_CFG_SKB_FRAGS_MAX) { + dev_kfree_skb_any(skb); + goto err_exit; + } + + aq_ring_update_queue_state(ring); + + /* Above status update may stop the queue. Check this. */ + if (__netif_subqueue_stopped(self->ndev, ring->idx)) { + err = NETDEV_TX_BUSY; + goto err_exit; + } + + frags = aq_nic_map_skb(self, skb, ring); + + if (likely(frags)) { + err = self->aq_hw_ops->hw_ring_tx_xmit(self->aq_hw, + ring, frags); + } else { + err = NETDEV_TX_BUSY; + } + +err_exit: + return err; +} + +int aq_nic_update_interrupt_moderation_settings(struct aq_nic_s *self) +{ + return self->aq_hw_ops->hw_interrupt_moderation_set(self->aq_hw); +} + +int aq_nic_set_packet_filter(struct aq_nic_s *self, unsigned int flags) +{ + int err = 0; + + err = self->aq_hw_ops->hw_packet_filter_set(self->aq_hw, flags); + if (err < 0) + goto err_exit; + + self->packet_filter = flags; + +err_exit: + return err; +} + +int aq_nic_set_multicast_list(struct aq_nic_s *self, struct net_device *ndev) +{ + unsigned int packet_filter = self->packet_filter; + struct netdev_hw_addr *ha = NULL; + unsigned int i = 0U; + + self->mc_list.count = 0; + if (netdev_uc_count(ndev) > AQ_HW_MULTICAST_ADDRESS_MAX) { + packet_filter |= IFF_PROMISC; + } else { + netdev_for_each_uc_addr(ha, ndev) { + ether_addr_copy(self->mc_list.ar[i++], ha->addr); + + if (i >= AQ_HW_MULTICAST_ADDRESS_MAX) + break; + } + } + + if (i + netdev_mc_count(ndev) > AQ_HW_MULTICAST_ADDRESS_MAX) { + packet_filter |= IFF_ALLMULTI; + } else { + netdev_for_each_mc_addr(ha, ndev) { + ether_addr_copy(self->mc_list.ar[i++], ha->addr); + + if (i >= AQ_HW_MULTICAST_ADDRESS_MAX) + break; + } + } + + if (i > 0 && i <= AQ_HW_MULTICAST_ADDRESS_MAX) { + packet_filter |= IFF_MULTICAST; + self->mc_list.count = i; + self->aq_hw_ops->hw_multicast_list_set(self->aq_hw, + self->mc_list.ar, + self->mc_list.count); + } + return aq_nic_set_packet_filter(self, packet_filter); +} + +int aq_nic_set_mtu(struct aq_nic_s *self, int new_mtu) +{ + self->aq_nic_cfg.mtu = new_mtu; + + return 0; +} + +int aq_nic_set_mac(struct aq_nic_s *self, struct net_device *ndev) +{ + return self->aq_hw_ops->hw_set_mac_address(self->aq_hw, ndev->dev_addr); +} + +unsigned int aq_nic_get_link_speed(struct aq_nic_s *self) +{ + return self->link_status.mbps; +} + +int aq_nic_get_regs(struct aq_nic_s *self, struct ethtool_regs *regs, void *p) +{ + u32 *regs_buff = p; + int err = 0; + + if (unlikely(!self->aq_hw_ops->hw_get_regs)) + return -EOPNOTSUPP; + + regs->version = 1; + + err = self->aq_hw_ops->hw_get_regs(self->aq_hw, + self->aq_nic_cfg.aq_hw_caps, + regs_buff); + if (err < 0) + goto err_exit; + +err_exit: + return err; +} + +int aq_nic_get_regs_count(struct aq_nic_s *self) +{ + if (unlikely(!self->aq_hw_ops->hw_get_regs)) + return 0; + + return self->aq_nic_cfg.aq_hw_caps->mac_regs_count; +} + +void aq_nic_get_stats(struct aq_nic_s *self, u64 *data) +{ + unsigned int i = 0U; + unsigned int count = 0U; + struct aq_vec_s *aq_vec = NULL; + struct aq_stats_s *stats = self->aq_hw_ops->hw_get_hw_stats(self->aq_hw); + + if (!stats) + goto err_exit; + + data[i] = stats->uprc + stats->mprc + stats->bprc; + data[++i] = stats->uprc; + data[++i] = stats->mprc; + data[++i] = stats->bprc; + data[++i] = stats->erpt; + data[++i] = stats->uptc + stats->mptc + stats->bptc; + data[++i] = stats->uptc; + data[++i] = stats->mptc; + data[++i] = stats->bptc; + data[++i] = stats->ubrc; + data[++i] = stats->ubtc; + data[++i] = stats->mbrc; + data[++i] = stats->mbtc; + data[++i] = stats->bbrc; + data[++i] = stats->bbtc; + data[++i] = stats->ubrc + stats->mbrc + stats->bbrc; + data[++i] = stats->ubtc + stats->mbtc + stats->bbtc; + data[++i] = stats->dma_pkt_rc; + data[++i] = stats->dma_pkt_tc; + data[++i] = stats->dma_oct_rc; + data[++i] = stats->dma_oct_tc; + data[++i] = stats->dpc; + + i++; + + data += i; + + for (i = 0U, aq_vec = self->aq_vec[0]; + aq_vec && self->aq_vecs > i; ++i, aq_vec = self->aq_vec[i]) { + data += count; + aq_vec_get_sw_stats(aq_vec, data, &count); + } + +err_exit:; +} + +static void aq_nic_update_ndev_stats(struct aq_nic_s *self) +{ + struct net_device *ndev = self->ndev; + struct aq_stats_s *stats = self->aq_hw_ops->hw_get_hw_stats(self->aq_hw); + + ndev->stats.rx_packets = stats->uprc + stats->mprc + stats->bprc; + ndev->stats.rx_bytes = stats->ubrc + stats->mbrc + stats->bbrc; + ndev->stats.rx_errors = stats->erpr; + ndev->stats.tx_packets = stats->uptc + stats->mptc + stats->bptc; + ndev->stats.tx_bytes = stats->ubtc + stats->mbtc + stats->bbtc; + ndev->stats.tx_errors = stats->erpt; + ndev->stats.multicast = stats->mprc; +} + +void aq_nic_get_link_ksettings(struct aq_nic_s *self, + struct ethtool_link_ksettings *cmd) +{ + if (self->aq_nic_cfg.aq_hw_caps->media_type == AQ_HW_MEDIA_TYPE_FIBRE) + cmd->base.port = PORT_FIBRE; + else + cmd->base.port = PORT_TP; + /* This driver supports only 10G capable adapters, so DUPLEX_FULL */ + cmd->base.duplex = DUPLEX_FULL; + cmd->base.autoneg = self->aq_nic_cfg.is_autoneg; + + ethtool_link_ksettings_zero_link_mode(cmd, supported); + + if (self->aq_nic_cfg.aq_hw_caps->link_speed_msk & AQ_NIC_RATE_10G) + ethtool_link_ksettings_add_link_mode(cmd, supported, + 10000baseT_Full); + + if (self->aq_nic_cfg.aq_hw_caps->link_speed_msk & AQ_NIC_RATE_5G) + ethtool_link_ksettings_add_link_mode(cmd, supported, + 5000baseT_Full); + + if (self->aq_nic_cfg.aq_hw_caps->link_speed_msk & AQ_NIC_RATE_2GS) + ethtool_link_ksettings_add_link_mode(cmd, supported, + 2500baseT_Full); + + if (self->aq_nic_cfg.aq_hw_caps->link_speed_msk & AQ_NIC_RATE_1G) + ethtool_link_ksettings_add_link_mode(cmd, supported, + 1000baseT_Full); + + if (self->aq_nic_cfg.aq_hw_caps->link_speed_msk & AQ_NIC_RATE_100M) + ethtool_link_ksettings_add_link_mode(cmd, supported, + 100baseT_Full); + + if (self->aq_nic_cfg.aq_hw_caps->flow_control) + ethtool_link_ksettings_add_link_mode(cmd, supported, + Pause); + + ethtool_link_ksettings_add_link_mode(cmd, supported, Autoneg); + + if (self->aq_nic_cfg.aq_hw_caps->media_type == AQ_HW_MEDIA_TYPE_FIBRE) + ethtool_link_ksettings_add_link_mode(cmd, supported, FIBRE); + else + ethtool_link_ksettings_add_link_mode(cmd, supported, TP); + + ethtool_link_ksettings_zero_link_mode(cmd, advertising); + + if (self->aq_nic_cfg.is_autoneg) + ethtool_link_ksettings_add_link_mode(cmd, advertising, Autoneg); + + if (self->aq_nic_cfg.link_speed_msk & AQ_NIC_RATE_10G) + ethtool_link_ksettings_add_link_mode(cmd, advertising, + 10000baseT_Full); + + if (self->aq_nic_cfg.link_speed_msk & AQ_NIC_RATE_5G) + ethtool_link_ksettings_add_link_mode(cmd, advertising, + 5000baseT_Full); + + if (self->aq_nic_cfg.link_speed_msk & AQ_NIC_RATE_2GS) + ethtool_link_ksettings_add_link_mode(cmd, advertising, + 2500baseT_Full); + + if (self->aq_nic_cfg.link_speed_msk & AQ_NIC_RATE_1G) + ethtool_link_ksettings_add_link_mode(cmd, advertising, + 1000baseT_Full); + + if (self->aq_nic_cfg.link_speed_msk & AQ_NIC_RATE_100M) + ethtool_link_ksettings_add_link_mode(cmd, advertising, + 100baseT_Full); + + if (self->aq_nic_cfg.flow_control & AQ_NIC_FC_RX) + ethtool_link_ksettings_add_link_mode(cmd, advertising, + Pause); + + if (self->aq_nic_cfg.flow_control & AQ_NIC_FC_TX) + ethtool_link_ksettings_add_link_mode(cmd, advertising, + Asym_Pause); + + if (self->aq_nic_cfg.aq_hw_caps->media_type == AQ_HW_MEDIA_TYPE_FIBRE) + ethtool_link_ksettings_add_link_mode(cmd, advertising, FIBRE); + else + ethtool_link_ksettings_add_link_mode(cmd, advertising, TP); +} + +int aq_nic_set_link_ksettings(struct aq_nic_s *self, + const struct ethtool_link_ksettings *cmd) +{ + u32 speed = 0U; + u32 rate = 0U; + int err = 0; + + if (cmd->base.autoneg == AUTONEG_ENABLE) { + rate = self->aq_nic_cfg.aq_hw_caps->link_speed_msk; + self->aq_nic_cfg.is_autoneg = true; + } else { + speed = cmd->base.speed; + + switch (speed) { + case SPEED_100: + rate = AQ_NIC_RATE_100M; + break; + + case SPEED_1000: + rate = AQ_NIC_RATE_1G; + break; + + case SPEED_2500: + rate = AQ_NIC_RATE_2GS; + break; + + case SPEED_5000: + rate = AQ_NIC_RATE_5G; + break; + + case SPEED_10000: + rate = AQ_NIC_RATE_10G; + break; + + default: + err = -1; + goto err_exit; + break; + } + if (!(self->aq_nic_cfg.aq_hw_caps->link_speed_msk & rate)) { + err = -1; + goto err_exit; + } + + self->aq_nic_cfg.is_autoneg = false; + } + + err = self->aq_fw_ops->set_link_speed(self->aq_hw, rate); + if (err < 0) + goto err_exit; + + self->aq_nic_cfg.link_speed_msk = rate; + +err_exit: + return err; +} + +struct aq_nic_cfg_s *aq_nic_get_cfg(struct aq_nic_s *self) +{ + return &self->aq_nic_cfg; +} + +u32 aq_nic_get_fw_version(struct aq_nic_s *self) +{ + u32 fw_version = 0U; + + self->aq_hw_ops->hw_get_fw_version(self->aq_hw, &fw_version); + + return fw_version; +} + +int aq_nic_stop(struct aq_nic_s *self) +{ + struct aq_vec_s *aq_vec = NULL; + unsigned int i = 0U; + + netif_tx_disable(self->ndev); + netif_carrier_off(self->ndev); + + del_timer_sync(&self->service_timer); + + self->aq_hw_ops->hw_irq_disable(self->aq_hw, AQ_CFG_IRQ_MASK); + + if (self->aq_nic_cfg.is_polling) + del_timer_sync(&self->polling_timer); + else + aq_pci_func_free_irqs(self); + + for (i = 0U, aq_vec = self->aq_vec[0]; + self->aq_vecs > i; ++i, aq_vec = self->aq_vec[i]) + aq_vec_stop(aq_vec); + + return self->aq_hw_ops->hw_stop(self->aq_hw); +} + +void aq_nic_deinit(struct aq_nic_s *self) +{ + struct aq_vec_s *aq_vec = NULL; + unsigned int i = 0U; + + if (!self) + goto err_exit; + + for (i = 0U, aq_vec = self->aq_vec[0]; + self->aq_vecs > i; ++i, aq_vec = self->aq_vec[i]) + aq_vec_deinit(aq_vec); + + if (self->power_state == AQ_HW_POWER_STATE_D0) { + (void)self->aq_fw_ops->deinit(self->aq_hw); + } else { + (void)self->aq_hw_ops->hw_set_power(self->aq_hw, + self->power_state); + } + +err_exit:; +} + +void aq_nic_free_vectors(struct aq_nic_s *self) +{ + unsigned int i = 0U; + + if (!self) + goto err_exit; + + for (i = ARRAY_SIZE(self->aq_vec); i--;) { + if (self->aq_vec[i]) { + aq_vec_free(self->aq_vec[i]); + self->aq_vec[i] = NULL; + } + } + +err_exit:; +} + +int aq_nic_change_pm_state(struct aq_nic_s *self, pm_message_t *pm_msg) +{ + int err = 0; + + if (!netif_running(self->ndev)) { + err = 0; + goto out; + } + rtnl_lock(); + if (pm_msg->event & PM_EVENT_SLEEP || pm_msg->event & PM_EVENT_FREEZE) { + self->power_state = AQ_HW_POWER_STATE_D3; + netif_device_detach(self->ndev); + netif_tx_stop_all_queues(self->ndev); + + err = aq_nic_stop(self); + if (err < 0) + goto err_exit; + + aq_nic_deinit(self); + } else { + err = aq_nic_init(self); + if (err < 0) + goto err_exit; + + err = aq_nic_start(self); + if (err < 0) + goto err_exit; + + netif_device_attach(self->ndev); + netif_tx_start_all_queues(self->ndev); + } + +err_exit: + rtnl_unlock(); +out: + return err; +} + +void aq_nic_shutdown(struct aq_nic_s *self) +{ + int err = 0; + + if (!self->ndev) + return; + + rtnl_lock(); + + netif_device_detach(self->ndev); + + if (netif_running(self->ndev)) { + err = aq_nic_stop(self); + if (err < 0) + goto err_exit; + } + aq_nic_deinit(self); + +err_exit: + rtnl_unlock(); +}
\ No newline at end of file diff --git a/drivers/net/ethernet/aquantia/atlantic/aq_nic.h b/drivers/net/ethernet/aquantia/atlantic/aq_nic.h new file mode 100644 index 000000000..fecfc401f --- /dev/null +++ b/drivers/net/ethernet/aquantia/atlantic/aq_nic.h @@ -0,0 +1,124 @@ +/* + * aQuantia Corporation Network Driver + * Copyright (C) 2014-2017 aQuantia Corporation. All rights reserved + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + */ + +/* File aq_nic.h: Declaration of common code for NIC. */ + +#ifndef AQ_NIC_H +#define AQ_NIC_H + +#include "aq_common.h" +#include "aq_rss.h" +#include "aq_hw.h" + +struct aq_ring_s; +struct aq_hw_ops; +struct aq_fw_s; +struct aq_vec_s; + +struct aq_nic_cfg_s { + const struct aq_hw_caps_s *aq_hw_caps; + u64 hw_features; + u32 rxds; /* rx ring size, descriptors # */ + u32 txds; /* tx ring size, descriptors # */ + u32 vecs; /* vecs==allocated irqs */ + u32 irq_type; + u32 itr; + u16 rx_itr; + u16 tx_itr; + u32 num_rss_queues; + u32 mtu; + u32 flow_control; + u32 link_speed_msk; + u32 vlan_id; + u16 is_mc_list_enabled; + u16 mc_list_count; + bool is_autoneg; + bool is_polling; + bool is_rss; + bool is_lro; + u8 tcs; + struct aq_rss_parameters aq_rss; +}; + +#define AQ_NIC_FLAG_STARTED 0x00000004U +#define AQ_NIC_FLAG_STOPPING 0x00000008U +#define AQ_NIC_FLAG_RESETTING 0x00000010U +#define AQ_NIC_FLAG_CLOSING 0x00000020U +#define AQ_NIC_LINK_DOWN 0x04000000U +#define AQ_NIC_FLAG_ERR_UNPLUG 0x40000000U +#define AQ_NIC_FLAG_ERR_HW 0x80000000U + +#define AQ_NIC_TCVEC2RING(_NIC_, _TC_, _VEC_) \ + ((_TC_) * AQ_CFG_TCS_MAX + (_VEC_)) + +struct aq_nic_s { + atomic_t flags; + struct aq_vec_s *aq_vec[AQ_CFG_VECS_MAX]; + struct aq_ring_s *aq_ring_tx[AQ_CFG_VECS_MAX * AQ_CFG_TCS_MAX]; + struct aq_hw_s *aq_hw; + struct net_device *ndev; + unsigned int aq_vecs; + unsigned int packet_filter; + unsigned int power_state; + u8 port; + const struct aq_hw_ops *aq_hw_ops; + const struct aq_fw_ops *aq_fw_ops; + struct aq_nic_cfg_s aq_nic_cfg; + struct timer_list service_timer; + struct timer_list polling_timer; + struct aq_hw_link_status_s link_status; + struct { + u32 count; + u8 ar[AQ_HW_MULTICAST_ADDRESS_MAX][ETH_ALEN]; + } mc_list; + + struct pci_dev *pdev; + unsigned int msix_entry_mask; + u32 irqvecs; +}; + +static inline struct device *aq_nic_get_dev(struct aq_nic_s *self) +{ + return self->ndev->dev.parent; +} + +void aq_nic_ndev_init(struct aq_nic_s *self); +struct aq_nic_s *aq_nic_alloc_hot(struct net_device *ndev); +void aq_nic_set_tx_ring(struct aq_nic_s *self, unsigned int idx, + struct aq_ring_s *ring); +struct net_device *aq_nic_get_ndev(struct aq_nic_s *self); +int aq_nic_init(struct aq_nic_s *self); +void aq_nic_cfg_start(struct aq_nic_s *self); +int aq_nic_ndev_register(struct aq_nic_s *self); +void aq_nic_ndev_free(struct aq_nic_s *self); +int aq_nic_start(struct aq_nic_s *self); +int aq_nic_xmit(struct aq_nic_s *self, struct sk_buff *skb); +int aq_nic_get_regs(struct aq_nic_s *self, struct ethtool_regs *regs, void *p); +int aq_nic_get_regs_count(struct aq_nic_s *self); +void aq_nic_get_stats(struct aq_nic_s *self, u64 *data); +int aq_nic_stop(struct aq_nic_s *self); +void aq_nic_deinit(struct aq_nic_s *self); +void aq_nic_free_hot_resources(struct aq_nic_s *self); +void aq_nic_free_vectors(struct aq_nic_s *self); +int aq_nic_set_mtu(struct aq_nic_s *self, int new_mtu); +int aq_nic_set_mac(struct aq_nic_s *self, struct net_device *ndev); +int aq_nic_set_packet_filter(struct aq_nic_s *self, unsigned int flags); +int aq_nic_set_multicast_list(struct aq_nic_s *self, struct net_device *ndev); +unsigned int aq_nic_get_link_speed(struct aq_nic_s *self); +void aq_nic_get_link_ksettings(struct aq_nic_s *self, + struct ethtool_link_ksettings *cmd); +int aq_nic_set_link_ksettings(struct aq_nic_s *self, + const struct ethtool_link_ksettings *cmd); +struct aq_nic_cfg_s *aq_nic_get_cfg(struct aq_nic_s *self); +u32 aq_nic_get_fw_version(struct aq_nic_s *self); +int aq_nic_change_pm_state(struct aq_nic_s *self, pm_message_t *pm_msg); +int aq_nic_update_interrupt_moderation_settings(struct aq_nic_s *self); +void aq_nic_shutdown(struct aq_nic_s *self); + +#endif /* AQ_NIC_H */ diff --git a/drivers/net/ethernet/aquantia/atlantic/aq_pci_func.c b/drivers/net/ethernet/aquantia/atlantic/aq_pci_func.c new file mode 100644 index 000000000..43dbfb228 --- /dev/null +++ b/drivers/net/ethernet/aquantia/atlantic/aq_pci_func.c @@ -0,0 +1,364 @@ +/* + * aQuantia Corporation Network Driver + * Copyright (C) 2014-2017 aQuantia Corporation. All rights reserved + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + */ + +/* File aq_pci_func.c: Definition of PCI functions. */ + +#include <linux/interrupt.h> +#include <linux/module.h> + +#include "aq_main.h" +#include "aq_nic.h" +#include "aq_vec.h" +#include "aq_hw.h" +#include "aq_pci_func.h" +#include "hw_atl/hw_atl_a0.h" +#include "hw_atl/hw_atl_b0.h" + +static const struct pci_device_id aq_pci_tbl[] = { + { PCI_VDEVICE(AQUANTIA, AQ_DEVICE_ID_0001), }, + { PCI_VDEVICE(AQUANTIA, AQ_DEVICE_ID_D100), }, + { PCI_VDEVICE(AQUANTIA, AQ_DEVICE_ID_D107), }, + { PCI_VDEVICE(AQUANTIA, AQ_DEVICE_ID_D108), }, + { PCI_VDEVICE(AQUANTIA, AQ_DEVICE_ID_D109), }, + + { PCI_VDEVICE(AQUANTIA, AQ_DEVICE_ID_AQC100), }, + { PCI_VDEVICE(AQUANTIA, AQ_DEVICE_ID_AQC107), }, + { PCI_VDEVICE(AQUANTIA, AQ_DEVICE_ID_AQC108), }, + { PCI_VDEVICE(AQUANTIA, AQ_DEVICE_ID_AQC109), }, + { PCI_VDEVICE(AQUANTIA, AQ_DEVICE_ID_AQC111), }, + { PCI_VDEVICE(AQUANTIA, AQ_DEVICE_ID_AQC112), }, + + { PCI_VDEVICE(AQUANTIA, AQ_DEVICE_ID_AQC100S), }, + { PCI_VDEVICE(AQUANTIA, AQ_DEVICE_ID_AQC107S), }, + { PCI_VDEVICE(AQUANTIA, AQ_DEVICE_ID_AQC108S), }, + { PCI_VDEVICE(AQUANTIA, AQ_DEVICE_ID_AQC109S), }, + { PCI_VDEVICE(AQUANTIA, AQ_DEVICE_ID_AQC111S), }, + { PCI_VDEVICE(AQUANTIA, AQ_DEVICE_ID_AQC112S), }, + + { PCI_VDEVICE(AQUANTIA, AQ_DEVICE_ID_AQC111E), }, + { PCI_VDEVICE(AQUANTIA, AQ_DEVICE_ID_AQC112E), }, + + {} +}; + +static const struct aq_board_revision_s hw_atl_boards[] = { + { AQ_DEVICE_ID_0001, AQ_HWREV_1, &hw_atl_ops_a0, &hw_atl_a0_caps_aqc107, }, + { AQ_DEVICE_ID_D100, AQ_HWREV_1, &hw_atl_ops_a0, &hw_atl_a0_caps_aqc100, }, + { AQ_DEVICE_ID_D107, AQ_HWREV_1, &hw_atl_ops_a0, &hw_atl_a0_caps_aqc107, }, + { AQ_DEVICE_ID_D108, AQ_HWREV_1, &hw_atl_ops_a0, &hw_atl_a0_caps_aqc108, }, + { AQ_DEVICE_ID_D109, AQ_HWREV_1, &hw_atl_ops_a0, &hw_atl_a0_caps_aqc109, }, + + { AQ_DEVICE_ID_0001, AQ_HWREV_2, &hw_atl_ops_b0, &hw_atl_b0_caps_aqc107, }, + { AQ_DEVICE_ID_D100, AQ_HWREV_2, &hw_atl_ops_b0, &hw_atl_b0_caps_aqc100, }, + { AQ_DEVICE_ID_D107, AQ_HWREV_2, &hw_atl_ops_b0, &hw_atl_b0_caps_aqc107, }, + { AQ_DEVICE_ID_D108, AQ_HWREV_2, &hw_atl_ops_b0, &hw_atl_b0_caps_aqc108, }, + { AQ_DEVICE_ID_D109, AQ_HWREV_2, &hw_atl_ops_b0, &hw_atl_b0_caps_aqc109, }, + + { AQ_DEVICE_ID_AQC100, AQ_HWREV_ANY, &hw_atl_ops_b1, &hw_atl_b0_caps_aqc100, }, + { AQ_DEVICE_ID_AQC107, AQ_HWREV_ANY, &hw_atl_ops_b1, &hw_atl_b0_caps_aqc107, }, + { AQ_DEVICE_ID_AQC108, AQ_HWREV_ANY, &hw_atl_ops_b1, &hw_atl_b0_caps_aqc108, }, + { AQ_DEVICE_ID_AQC109, AQ_HWREV_ANY, &hw_atl_ops_b1, &hw_atl_b0_caps_aqc109, }, + { AQ_DEVICE_ID_AQC111, AQ_HWREV_ANY, &hw_atl_ops_b1, &hw_atl_b0_caps_aqc111, }, + { AQ_DEVICE_ID_AQC112, AQ_HWREV_ANY, &hw_atl_ops_b1, &hw_atl_b0_caps_aqc112, }, + + { AQ_DEVICE_ID_AQC100S, AQ_HWREV_ANY, &hw_atl_ops_b1, &hw_atl_b0_caps_aqc100s, }, + { AQ_DEVICE_ID_AQC107S, AQ_HWREV_ANY, &hw_atl_ops_b1, &hw_atl_b0_caps_aqc107s, }, + { AQ_DEVICE_ID_AQC108S, AQ_HWREV_ANY, &hw_atl_ops_b1, &hw_atl_b0_caps_aqc108s, }, + { AQ_DEVICE_ID_AQC109S, AQ_HWREV_ANY, &hw_atl_ops_b1, &hw_atl_b0_caps_aqc109s, }, + { AQ_DEVICE_ID_AQC111S, AQ_HWREV_ANY, &hw_atl_ops_b1, &hw_atl_b0_caps_aqc111s, }, + { AQ_DEVICE_ID_AQC112S, AQ_HWREV_ANY, &hw_atl_ops_b1, &hw_atl_b0_caps_aqc112s, }, + + { AQ_DEVICE_ID_AQC111E, AQ_HWREV_ANY, &hw_atl_ops_b1, &hw_atl_b0_caps_aqc111e, }, + { AQ_DEVICE_ID_AQC112E, AQ_HWREV_ANY, &hw_atl_ops_b1, &hw_atl_b0_caps_aqc112e, }, +}; + +MODULE_DEVICE_TABLE(pci, aq_pci_tbl); + +static int aq_pci_probe_get_hw_by_id(struct pci_dev *pdev, + const struct aq_hw_ops **ops, + const struct aq_hw_caps_s **caps) +{ + int i = 0; + + if (pdev->vendor != PCI_VENDOR_ID_AQUANTIA) + return -EINVAL; + + for (i = 0; i < ARRAY_SIZE(hw_atl_boards); i++) { + if (hw_atl_boards[i].devid == pdev->device && + (hw_atl_boards[i].revision == AQ_HWREV_ANY || + hw_atl_boards[i].revision == pdev->revision)) { + *ops = hw_atl_boards[i].ops; + *caps = hw_atl_boards[i].caps; + break; + } + } + + if (i == ARRAY_SIZE(hw_atl_boards)) + return -EINVAL; + + return 0; +} + +int aq_pci_func_init(struct pci_dev *pdev) +{ + int err = 0; + + err = pci_set_dma_mask(pdev, DMA_BIT_MASK(64)); + if (!err) { + err = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(64)); + + } + if (err) { + err = pci_set_dma_mask(pdev, DMA_BIT_MASK(32)); + if (!err) + err = pci_set_consistent_dma_mask(pdev, + DMA_BIT_MASK(32)); + } + if (err != 0) { + err = -ENOSR; + goto err_exit; + } + + err = pci_request_regions(pdev, AQ_CFG_DRV_NAME "_mmio"); + if (err < 0) + goto err_exit; + + pci_set_master(pdev); + + return 0; + +err_exit: + return err; +} + +int aq_pci_func_alloc_irq(struct aq_nic_s *self, unsigned int i, + char *name, void *aq_vec, cpumask_t *affinity_mask) +{ + struct pci_dev *pdev = self->pdev; + int err = 0; + + if (pdev->msix_enabled || pdev->msi_enabled) + err = request_irq(pci_irq_vector(pdev, i), aq_vec_isr, 0, + name, aq_vec); + else + err = request_irq(pci_irq_vector(pdev, i), aq_vec_isr_legacy, + IRQF_SHARED, name, aq_vec); + + if (err >= 0) { + self->msix_entry_mask |= (1 << i); + self->aq_vec[i] = aq_vec; + + if (pdev->msix_enabled) + irq_set_affinity_hint(pci_irq_vector(pdev, i), + affinity_mask); + } + return err; +} + +void aq_pci_func_free_irqs(struct aq_nic_s *self) +{ + struct pci_dev *pdev = self->pdev; + unsigned int i = 0U; + + for (i = 32U; i--;) { + if (!((1U << i) & self->msix_entry_mask)) + continue; + + if (pdev->msix_enabled) + irq_set_affinity_hint(pci_irq_vector(pdev, i), NULL); + free_irq(pci_irq_vector(pdev, i), self->aq_vec[i]); + self->msix_entry_mask &= ~(1U << i); + } +} + +unsigned int aq_pci_func_get_irq_type(struct aq_nic_s *self) +{ + if (self->pdev->msix_enabled) + return AQ_HW_IRQ_MSIX; + if (self->pdev->msi_enabled) + return AQ_HW_IRQ_MSIX; + return AQ_HW_IRQ_LEGACY; +} + +static void aq_pci_free_irq_vectors(struct aq_nic_s *self) +{ + pci_free_irq_vectors(self->pdev); +} + +static int aq_pci_probe(struct pci_dev *pdev, + const struct pci_device_id *pci_id) +{ + struct aq_nic_s *self = NULL; + int err = 0; + struct net_device *ndev; + resource_size_t mmio_pa; + u32 bar; + u32 numvecs; + + err = pci_enable_device(pdev); + if (err) + return err; + + err = aq_pci_func_init(pdev); + if (err) + goto err_pci_func; + + ndev = aq_ndev_alloc(); + if (!ndev) { + err = -ENOMEM; + goto err_ndev; + } + + self = netdev_priv(ndev); + self->pdev = pdev; + SET_NETDEV_DEV(ndev, &pdev->dev); + pci_set_drvdata(pdev, self); + + err = aq_pci_probe_get_hw_by_id(pdev, &self->aq_hw_ops, + &aq_nic_get_cfg(self)->aq_hw_caps); + if (err) + goto err_ioremap; + + self->aq_hw = kzalloc(sizeof(*self->aq_hw), GFP_KERNEL); + if (!self->aq_hw) { + err = -ENOMEM; + goto err_ioremap; + } + self->aq_hw->aq_nic_cfg = aq_nic_get_cfg(self); + + for (bar = 0; bar < 4; ++bar) { + if (IORESOURCE_MEM & pci_resource_flags(pdev, bar)) { + resource_size_t reg_sz; + + mmio_pa = pci_resource_start(pdev, bar); + if (mmio_pa == 0U) { + err = -EIO; + goto err_free_aq_hw; + } + + reg_sz = pci_resource_len(pdev, bar); + if ((reg_sz <= 24 /*ATL_REGS_SIZE*/)) { + err = -EIO; + goto err_free_aq_hw; + } + + self->aq_hw->mmio = ioremap_nocache(mmio_pa, reg_sz); + if (!self->aq_hw->mmio) { + err = -EIO; + goto err_free_aq_hw; + } + break; + } + } + + if (bar == 4) { + err = -EIO; + goto err_free_aq_hw; + } + + numvecs = min((u8)AQ_CFG_VECS_DEF, + aq_nic_get_cfg(self)->aq_hw_caps->msix_irqs); + numvecs = min(numvecs, num_online_cpus()); + /*enable interrupts */ +#if !AQ_CFG_FORCE_LEGACY_INT + err = pci_alloc_irq_vectors(self->pdev, 1, numvecs, + PCI_IRQ_MSIX | PCI_IRQ_MSI | + PCI_IRQ_LEGACY); + + if (err < 0) + goto err_hwinit; + numvecs = err; +#endif + self->irqvecs = numvecs; + + /* net device init */ + aq_nic_cfg_start(self); + + aq_nic_ndev_init(self); + + err = aq_nic_ndev_register(self); + if (err < 0) + goto err_register; + + return 0; + +err_register: + aq_nic_free_vectors(self); + aq_pci_free_irq_vectors(self); +err_hwinit: + iounmap(self->aq_hw->mmio); +err_free_aq_hw: + kfree(self->aq_hw); +err_ioremap: + free_netdev(ndev); +err_ndev: + pci_release_regions(pdev); +err_pci_func: + pci_disable_device(pdev); + return err; +} + +static void aq_pci_remove(struct pci_dev *pdev) +{ + struct aq_nic_s *self = pci_get_drvdata(pdev); + + if (self->ndev) { + if (self->ndev->reg_state == NETREG_REGISTERED) + unregister_netdev(self->ndev); + aq_nic_free_vectors(self); + aq_pci_free_irq_vectors(self); + iounmap(self->aq_hw->mmio); + kfree(self->aq_hw); + pci_release_regions(pdev); + free_netdev(self->ndev); + } + + pci_disable_device(pdev); +} + +static void aq_pci_shutdown(struct pci_dev *pdev) +{ + struct aq_nic_s *self = pci_get_drvdata(pdev); + + aq_nic_shutdown(self); + + pci_disable_device(pdev); + + if (system_state == SYSTEM_POWER_OFF) { + pci_wake_from_d3(pdev, false); + pci_set_power_state(pdev, PCI_D3hot); + } +} + +static int aq_pci_suspend(struct pci_dev *pdev, pm_message_t pm_msg) +{ + struct aq_nic_s *self = pci_get_drvdata(pdev); + + return aq_nic_change_pm_state(self, &pm_msg); +} + +static int aq_pci_resume(struct pci_dev *pdev) +{ + struct aq_nic_s *self = pci_get_drvdata(pdev); + pm_message_t pm_msg = PMSG_RESTORE; + + return aq_nic_change_pm_state(self, &pm_msg); +} + +static struct pci_driver aq_pci_ops = { + .name = AQ_CFG_DRV_NAME, + .id_table = aq_pci_tbl, + .probe = aq_pci_probe, + .remove = aq_pci_remove, + .suspend = aq_pci_suspend, + .resume = aq_pci_resume, + .shutdown = aq_pci_shutdown, +}; + +module_pci_driver(aq_pci_ops); diff --git a/drivers/net/ethernet/aquantia/atlantic/aq_pci_func.h b/drivers/net/ethernet/aquantia/atlantic/aq_pci_func.h new file mode 100644 index 000000000..aeee67bf6 --- /dev/null +++ b/drivers/net/ethernet/aquantia/atlantic/aq_pci_func.h @@ -0,0 +1,32 @@ +/* + * aQuantia Corporation Network Driver + * Copyright (C) 2014-2017 aQuantia Corporation. All rights reserved + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + */ + +/* File aq_pci_func.h: Declaration of PCI functions. */ + +#ifndef AQ_PCI_FUNC_H +#define AQ_PCI_FUNC_H + +#include "aq_common.h" +#include "aq_nic.h" + +struct aq_board_revision_s { + unsigned short devid; + unsigned short revision; + const struct aq_hw_ops *ops; + const struct aq_hw_caps_s *caps; +}; + +int aq_pci_func_init(struct pci_dev *pdev); +int aq_pci_func_alloc_irq(struct aq_nic_s *self, unsigned int i, + char *name, void *aq_vec, + cpumask_t *affinity_mask); +void aq_pci_func_free_irqs(struct aq_nic_s *self); +unsigned int aq_pci_func_get_irq_type(struct aq_nic_s *self); + +#endif /* AQ_PCI_FUNC_H */ diff --git a/drivers/net/ethernet/aquantia/atlantic/aq_ring.c b/drivers/net/ethernet/aquantia/atlantic/aq_ring.c new file mode 100644 index 000000000..b03e5fd43 --- /dev/null +++ b/drivers/net/ethernet/aquantia/atlantic/aq_ring.c @@ -0,0 +1,388 @@ +/* + * aQuantia Corporation Network Driver + * Copyright (C) 2014-2017 aQuantia Corporation. All rights reserved + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + */ + +/* File aq_ring.c: Definition of functions for Rx/Tx rings. */ + +#include "aq_ring.h" +#include "aq_nic.h" +#include "aq_hw.h" + +#include <linux/netdevice.h> +#include <linux/etherdevice.h> + +static struct aq_ring_s *aq_ring_alloc(struct aq_ring_s *self, + struct aq_nic_s *aq_nic) +{ + int err = 0; + + self->buff_ring = + kcalloc(self->size, sizeof(struct aq_ring_buff_s), GFP_KERNEL); + + if (!self->buff_ring) { + err = -ENOMEM; + goto err_exit; + } + self->dx_ring = dma_alloc_coherent(aq_nic_get_dev(aq_nic), + self->size * self->dx_size, + &self->dx_ring_pa, GFP_KERNEL); + if (!self->dx_ring) { + err = -ENOMEM; + goto err_exit; + } + +err_exit: + if (err < 0) { + aq_ring_free(self); + self = NULL; + } + return self; +} + +struct aq_ring_s *aq_ring_tx_alloc(struct aq_ring_s *self, + struct aq_nic_s *aq_nic, + unsigned int idx, + struct aq_nic_cfg_s *aq_nic_cfg) +{ + int err = 0; + + self->aq_nic = aq_nic; + self->idx = idx; + self->size = aq_nic_cfg->txds; + self->dx_size = aq_nic_cfg->aq_hw_caps->txd_size; + + self = aq_ring_alloc(self, aq_nic); + if (!self) { + err = -ENOMEM; + goto err_exit; + } + +err_exit: + if (err < 0) { + aq_ring_free(self); + self = NULL; + } + return self; +} + +struct aq_ring_s *aq_ring_rx_alloc(struct aq_ring_s *self, + struct aq_nic_s *aq_nic, + unsigned int idx, + struct aq_nic_cfg_s *aq_nic_cfg) +{ + int err = 0; + + self->aq_nic = aq_nic; + self->idx = idx; + self->size = aq_nic_cfg->rxds; + self->dx_size = aq_nic_cfg->aq_hw_caps->rxd_size; + + self = aq_ring_alloc(self, aq_nic); + if (!self) { + err = -ENOMEM; + goto err_exit; + } + +err_exit: + if (err < 0) { + aq_ring_free(self); + self = NULL; + } + return self; +} + +int aq_ring_init(struct aq_ring_s *self) +{ + self->hw_head = 0; + self->sw_head = 0; + self->sw_tail = 0; + return 0; +} + +static inline bool aq_ring_dx_in_range(unsigned int h, unsigned int i, + unsigned int t) +{ + return (h < t) ? ((h < i) && (i < t)) : ((h < i) || (i < t)); +} + +void aq_ring_update_queue_state(struct aq_ring_s *ring) +{ + if (aq_ring_avail_dx(ring) <= AQ_CFG_SKB_FRAGS_MAX) + aq_ring_queue_stop(ring); + else if (aq_ring_avail_dx(ring) > AQ_CFG_RESTART_DESC_THRES) + aq_ring_queue_wake(ring); +} + +void aq_ring_queue_wake(struct aq_ring_s *ring) +{ + struct net_device *ndev = aq_nic_get_ndev(ring->aq_nic); + + if (__netif_subqueue_stopped(ndev, ring->idx)) { + netif_wake_subqueue(ndev, ring->idx); + ring->stats.tx.queue_restarts++; + } +} + +void aq_ring_queue_stop(struct aq_ring_s *ring) +{ + struct net_device *ndev = aq_nic_get_ndev(ring->aq_nic); + + if (!__netif_subqueue_stopped(ndev, ring->idx)) + netif_stop_subqueue(ndev, ring->idx); +} + +bool aq_ring_tx_clean(struct aq_ring_s *self) +{ + struct device *dev = aq_nic_get_dev(self->aq_nic); + unsigned int budget; + + for (budget = AQ_CFG_TX_CLEAN_BUDGET; + budget && self->sw_head != self->hw_head; budget--) { + struct aq_ring_buff_s *buff = &self->buff_ring[self->sw_head]; + + if (likely(buff->is_mapped)) { + if (unlikely(buff->is_sop)) { + if (!buff->is_eop && + buff->eop_index != 0xffffU && + (!aq_ring_dx_in_range(self->sw_head, + buff->eop_index, + self->hw_head))) + break; + + dma_unmap_single(dev, buff->pa, buff->len, + DMA_TO_DEVICE); + } else { + dma_unmap_page(dev, buff->pa, buff->len, + DMA_TO_DEVICE); + } + } + + if (unlikely(buff->is_eop)) { + ++self->stats.rx.packets; + self->stats.tx.bytes += buff->skb->len; + + dev_kfree_skb_any(buff->skb); + } + buff->pa = 0U; + buff->eop_index = 0xffffU; + self->sw_head = aq_ring_next_dx(self, self->sw_head); + } + + return !!budget; +} + +static void aq_rx_checksum(struct aq_ring_s *self, + struct aq_ring_buff_s *buff, + struct sk_buff *skb) +{ + if (!(self->aq_nic->ndev->features & NETIF_F_RXCSUM)) + return; + + if (unlikely(buff->is_cso_err)) { + ++self->stats.rx.errors; + skb->ip_summed = CHECKSUM_NONE; + return; + } + if (buff->is_ip_cso) { + __skb_incr_checksum_unnecessary(skb); + } else { + skb->ip_summed = CHECKSUM_NONE; + } + + if (buff->is_udp_cso || buff->is_tcp_cso) + __skb_incr_checksum_unnecessary(skb); +} + +#define AQ_SKB_ALIGN SKB_DATA_ALIGN(sizeof(struct skb_shared_info)) +int aq_ring_rx_clean(struct aq_ring_s *self, + struct napi_struct *napi, + int *work_done, + int budget) +{ + struct net_device *ndev = aq_nic_get_ndev(self->aq_nic); + int err = 0; + bool is_rsc_completed = true; + + for (; (self->sw_head != self->hw_head) && budget; + self->sw_head = aq_ring_next_dx(self, self->sw_head), + --budget, ++(*work_done)) { + struct aq_ring_buff_s *buff = &self->buff_ring[self->sw_head]; + struct sk_buff *skb = NULL; + unsigned int next_ = 0U; + unsigned int i = 0U; + struct aq_ring_buff_s *buff_ = NULL; + + if (buff->is_error) { + __free_pages(buff->page, 0); + continue; + } + + if (buff->is_cleaned) + continue; + + if (!buff->is_eop) { + for (next_ = buff->next, + buff_ = &self->buff_ring[next_]; true; + next_ = buff_->next, + buff_ = &self->buff_ring[next_]) { + is_rsc_completed = + aq_ring_dx_in_range(self->sw_head, + next_, + self->hw_head); + + if (unlikely(!is_rsc_completed)) { + is_rsc_completed = false; + break; + } + + if (buff_->is_eop) + break; + } + + if (!is_rsc_completed) { + err = 0; + goto err_exit; + } + } + + /* for single fragment packets use build_skb() */ + if (buff->is_eop && + buff->len <= AQ_CFG_RX_FRAME_MAX - AQ_SKB_ALIGN) { + skb = build_skb(page_address(buff->page), + AQ_CFG_RX_FRAME_MAX); + if (unlikely(!skb)) { + err = -ENOMEM; + goto err_exit; + } + + skb_put(skb, buff->len); + } else { + skb = netdev_alloc_skb(ndev, ETH_HLEN); + if (unlikely(!skb)) { + err = -ENOMEM; + goto err_exit; + } + skb_put(skb, ETH_HLEN); + memcpy(skb->data, page_address(buff->page), ETH_HLEN); + + skb_add_rx_frag(skb, 0, buff->page, ETH_HLEN, + buff->len - ETH_HLEN, + SKB_TRUESIZE(buff->len - ETH_HLEN)); + + if (!buff->is_eop) { + for (i = 1U, next_ = buff->next, + buff_ = &self->buff_ring[next_]; + true; next_ = buff_->next, + buff_ = &self->buff_ring[next_], ++i) { + skb_add_rx_frag(skb, i, + buff_->page, 0, + buff_->len, + SKB_TRUESIZE(buff->len - + ETH_HLEN)); + buff_->is_cleaned = 1; + + if (buff_->is_eop) + break; + } + } + } + + skb->protocol = eth_type_trans(skb, ndev); + + aq_rx_checksum(self, buff, skb); + + skb_set_hash(skb, buff->rss_hash, + buff->is_hash_l4 ? PKT_HASH_TYPE_L4 : + PKT_HASH_TYPE_NONE); + + skb_record_rx_queue(skb, self->idx); + + ++self->stats.rx.packets; + self->stats.rx.bytes += skb->len; + + napi_gro_receive(napi, skb); + } + +err_exit: + return err; +} + +int aq_ring_rx_fill(struct aq_ring_s *self) +{ + unsigned int pages_order = fls(AQ_CFG_RX_FRAME_MAX / PAGE_SIZE + + (AQ_CFG_RX_FRAME_MAX % PAGE_SIZE ? 1 : 0)) - 1; + struct aq_ring_buff_s *buff = NULL; + int err = 0; + int i = 0; + + for (i = aq_ring_avail_dx(self); i--; + self->sw_tail = aq_ring_next_dx(self, self->sw_tail)) { + buff = &self->buff_ring[self->sw_tail]; + + buff->flags = 0U; + buff->len = AQ_CFG_RX_FRAME_MAX; + + buff->page = alloc_pages(GFP_ATOMIC | __GFP_COMP, pages_order); + if (!buff->page) { + err = -ENOMEM; + goto err_exit; + } + + buff->pa = dma_map_page(aq_nic_get_dev(self->aq_nic), + buff->page, 0, + AQ_CFG_RX_FRAME_MAX, DMA_FROM_DEVICE); + + if (dma_mapping_error(aq_nic_get_dev(self->aq_nic), buff->pa)) { + err = -ENOMEM; + goto err_exit; + } + + buff = NULL; + } + +err_exit: + if (err < 0) { + if (buff && buff->page) + __free_pages(buff->page, 0); + } + + return err; +} + +void aq_ring_rx_deinit(struct aq_ring_s *self) +{ + if (!self) + goto err_exit; + + for (; self->sw_head != self->sw_tail; + self->sw_head = aq_ring_next_dx(self, self->sw_head)) { + struct aq_ring_buff_s *buff = &self->buff_ring[self->sw_head]; + + dma_unmap_page(aq_nic_get_dev(self->aq_nic), buff->pa, + AQ_CFG_RX_FRAME_MAX, DMA_FROM_DEVICE); + + __free_pages(buff->page, 0); + } + +err_exit:; +} + +void aq_ring_free(struct aq_ring_s *self) +{ + if (!self) + goto err_exit; + + kfree(self->buff_ring); + + if (self->dx_ring) + dma_free_coherent(aq_nic_get_dev(self->aq_nic), + self->size * self->dx_size, self->dx_ring, + self->dx_ring_pa); + +err_exit:; +} diff --git a/drivers/net/ethernet/aquantia/atlantic/aq_ring.h b/drivers/net/ethernet/aquantia/atlantic/aq_ring.h new file mode 100644 index 000000000..ac1329f40 --- /dev/null +++ b/drivers/net/ethernet/aquantia/atlantic/aq_ring.h @@ -0,0 +1,163 @@ +/* + * aQuantia Corporation Network Driver + * Copyright (C) 2014-2017 aQuantia Corporation. All rights reserved + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + */ + +/* File aq_ring.h: Declaration of functions for Rx/Tx rings. */ + +#ifndef AQ_RING_H +#define AQ_RING_H + +#include "aq_common.h" + +struct page; +struct aq_nic_cfg_s; + +/* TxC SOP DX EOP + * +----------+----------+----------+----------- + * 8bytes|len l3,l4 | pa | pa | pa + * +----------+----------+----------+----------- + * 4/8bytes|len pkt |len pkt | | skb + * +----------+----------+----------+----------- + * 4/8bytes|is_txc |len,flags |len |len,is_eop + * +----------+----------+----------+----------- + * + * This aq_ring_buff_s doesn't have endianness dependency. + * It is __packed for cache line optimizations. + */ +struct __packed aq_ring_buff_s { + union { + /* RX */ + struct { + u32 rss_hash; + u16 next; + u8 is_hash_l4; + u8 rsvd1; + struct page *page; + }; + /* EOP */ + struct { + dma_addr_t pa_eop; + struct sk_buff *skb; + }; + /* DX */ + struct { + dma_addr_t pa; + }; + /* SOP */ + struct { + dma_addr_t pa_sop; + u32 len_pkt_sop; + }; + /* TxC */ + struct { + u32 mss; + u8 len_l2; + u8 len_l3; + u8 len_l4; + u8 is_ipv6:1; + u8 rsvd2:7; + u32 len_pkt; + }; + }; + union { + struct { + u16 len; + u32 is_ip_cso:1; + u32 is_udp_cso:1; + u32 is_tcp_cso:1; + u32 is_cso_err:1; + u32 is_sop:1; + u32 is_eop:1; + u32 is_txc:1; + u32 is_mapped:1; + u32 is_cleaned:1; + u32 is_error:1; + u32 rsvd3:6; + u16 eop_index; + u16 rsvd4; + }; + u64 flags; + }; +}; + +struct aq_ring_stats_rx_s { + u64 errors; + u64 packets; + u64 bytes; + u64 lro_packets; + u64 jumbo_packets; +}; + +struct aq_ring_stats_tx_s { + u64 errors; + u64 packets; + u64 bytes; + u64 queue_restarts; +}; + +union aq_ring_stats_s { + struct aq_ring_stats_rx_s rx; + struct aq_ring_stats_tx_s tx; +}; + +struct aq_ring_s { + struct aq_ring_buff_s *buff_ring; + u8 *dx_ring; /* descriptors ring, dma shared mem */ + struct aq_nic_s *aq_nic; + unsigned int idx; /* for HW layer registers operations */ + unsigned int hw_head; + unsigned int sw_head; + unsigned int sw_tail; + unsigned int size; /* descriptors number */ + unsigned int dx_size; /* TX or RX descriptor size, */ + /* stored here for fater math */ + union aq_ring_stats_s stats; + dma_addr_t dx_ring_pa; +}; + +struct aq_ring_param_s { + unsigned int vec_idx; + unsigned int cpu; + cpumask_t affinity_mask; +}; + +static inline unsigned int aq_ring_next_dx(struct aq_ring_s *self, + unsigned int dx) +{ + return (++dx >= self->size) ? 0U : dx; +} + +static inline unsigned int aq_ring_avail_dx(struct aq_ring_s *self) +{ + return (((self->sw_tail >= self->sw_head)) ? + (self->size - 1) - self->sw_tail + self->sw_head : + self->sw_head - self->sw_tail - 1); +} + +struct aq_ring_s *aq_ring_tx_alloc(struct aq_ring_s *self, + struct aq_nic_s *aq_nic, + unsigned int idx, + struct aq_nic_cfg_s *aq_nic_cfg); +struct aq_ring_s *aq_ring_rx_alloc(struct aq_ring_s *self, + struct aq_nic_s *aq_nic, + unsigned int idx, + struct aq_nic_cfg_s *aq_nic_cfg); +int aq_ring_init(struct aq_ring_s *self); +void aq_ring_rx_deinit(struct aq_ring_s *self); +void aq_ring_free(struct aq_ring_s *self); +void aq_ring_update_queue_state(struct aq_ring_s *ring); +void aq_ring_queue_wake(struct aq_ring_s *ring); +void aq_ring_queue_stop(struct aq_ring_s *ring); +bool aq_ring_tx_clean(struct aq_ring_s *self); +int aq_ring_rx_clean(struct aq_ring_s *self, + struct napi_struct *napi, + int *work_done, + int budget); +int aq_ring_rx_fill(struct aq_ring_s *self); + +#endif /* AQ_RING_H */ diff --git a/drivers/net/ethernet/aquantia/atlantic/aq_rss.h b/drivers/net/ethernet/aquantia/atlantic/aq_rss.h new file mode 100644 index 000000000..1db6eb20a --- /dev/null +++ b/drivers/net/ethernet/aquantia/atlantic/aq_rss.h @@ -0,0 +1,26 @@ +/* + * aQuantia Corporation Network Driver + * Copyright (C) 2014-2017 aQuantia Corporation. All rights reserved + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + */ + +/* File aq_rss.h: Receive Side Scaling definitions. */ + +#ifndef AQ_RSS_H +#define AQ_RSS_H + +#include "aq_common.h" +#include "aq_cfg.h" + +struct aq_rss_parameters { + u16 base_cpu_number; + u16 indirection_table_size; + u16 hash_secret_key_size; + u32 hash_secret_key[AQ_CFG_RSS_HASHKEY_SIZE / sizeof(u32)]; + u8 indirection_table[AQ_CFG_RSS_INDIRECTION_TABLE_MAX]; +}; + +#endif /* AQ_RSS_H */ diff --git a/drivers/net/ethernet/aquantia/atlantic/aq_utils.h b/drivers/net/ethernet/aquantia/atlantic/aq_utils.h new file mode 100644 index 000000000..786ea8187 --- /dev/null +++ b/drivers/net/ethernet/aquantia/atlantic/aq_utils.h @@ -0,0 +1,42 @@ +/* + * aQuantia Corporation Network Driver + * Copyright (C) 2014-2017 aQuantia Corporation. All rights reserved + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + */ + +/* File aq_utils.h: Useful macro and structures used in all layers of driver. */ + +#ifndef AQ_UTILS_H +#define AQ_UTILS_H + +#include "aq_common.h" + +static inline void aq_utils_obj_set(atomic_t *flags, u32 mask) +{ + unsigned long flags_old, flags_new; + + do { + flags_old = atomic_read(flags); + flags_new = flags_old | (mask); + } while (atomic_cmpxchg(flags, flags_old, flags_new) != flags_old); +} + +static inline void aq_utils_obj_clear(atomic_t *flags, u32 mask) +{ + unsigned long flags_old, flags_new; + + do { + flags_old = atomic_read(flags); + flags_new = flags_old & ~(mask); + } while (atomic_cmpxchg(flags, flags_old, flags_new) != flags_old); +} + +static inline bool aq_utils_obj_test(atomic_t *flags, u32 mask) +{ + return atomic_read(flags) & mask; +} + +#endif /* AQ_UTILS_H */ diff --git a/drivers/net/ethernet/aquantia/atlantic/aq_vec.c b/drivers/net/ethernet/aquantia/atlantic/aq_vec.c new file mode 100644 index 000000000..72aa2a4c4 --- /dev/null +++ b/drivers/net/ethernet/aquantia/atlantic/aq_vec.c @@ -0,0 +1,385 @@ +/* + * aQuantia Corporation Network Driver + * Copyright (C) 2014-2017 aQuantia Corporation. All rights reserved + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + */ + +/* File aq_vec.c: Definition of common structure for vector of Rx and Tx rings. + * Definition of functions for Rx and Tx rings. Friendly module for aq_nic. + */ + +#include "aq_vec.h" +#include "aq_nic.h" +#include "aq_ring.h" +#include "aq_hw.h" + +#include <linux/netdevice.h> + +struct aq_vec_s { + const struct aq_hw_ops *aq_hw_ops; + struct aq_hw_s *aq_hw; + struct aq_nic_s *aq_nic; + unsigned int tx_rings; + unsigned int rx_rings; + struct aq_ring_param_s aq_ring_param; + struct napi_struct napi; + struct aq_ring_s ring[AQ_CFG_TCS_MAX][2]; +}; + +#define AQ_VEC_TX_ID 0 +#define AQ_VEC_RX_ID 1 + +static int aq_vec_poll(struct napi_struct *napi, int budget) +{ + struct aq_vec_s *self = container_of(napi, struct aq_vec_s, napi); + unsigned int sw_tail_old = 0U; + struct aq_ring_s *ring = NULL; + bool was_tx_cleaned = true; + unsigned int i = 0U; + int work_done = 0; + int err = 0; + + if (!self) { + err = -EINVAL; + } else { + for (i = 0U, ring = self->ring[0]; + self->tx_rings > i; ++i, ring = self->ring[i]) { + if (self->aq_hw_ops->hw_ring_tx_head_update) { + err = self->aq_hw_ops->hw_ring_tx_head_update( + self->aq_hw, + &ring[AQ_VEC_TX_ID]); + if (err < 0) + goto err_exit; + } + + if (ring[AQ_VEC_TX_ID].sw_head != + ring[AQ_VEC_TX_ID].hw_head) { + was_tx_cleaned = aq_ring_tx_clean(&ring[AQ_VEC_TX_ID]); + aq_ring_update_queue_state(&ring[AQ_VEC_TX_ID]); + } + + err = self->aq_hw_ops->hw_ring_rx_receive(self->aq_hw, + &ring[AQ_VEC_RX_ID]); + if (err < 0) + goto err_exit; + + if (ring[AQ_VEC_RX_ID].sw_head != + ring[AQ_VEC_RX_ID].hw_head) { + err = aq_ring_rx_clean(&ring[AQ_VEC_RX_ID], + napi, + &work_done, + budget - work_done); + if (err < 0) + goto err_exit; + + sw_tail_old = ring[AQ_VEC_RX_ID].sw_tail; + + err = aq_ring_rx_fill(&ring[AQ_VEC_RX_ID]); + if (err < 0) + goto err_exit; + + err = self->aq_hw_ops->hw_ring_rx_fill( + self->aq_hw, + &ring[AQ_VEC_RX_ID], sw_tail_old); + if (err < 0) + goto err_exit; + } + } + +err_exit: + if (!was_tx_cleaned) + work_done = budget; + + if (work_done < budget) { + napi_complete_done(napi, work_done); + self->aq_hw_ops->hw_irq_enable(self->aq_hw, + 1U << self->aq_ring_param.vec_idx); + } + } + + return work_done; +} + +struct aq_vec_s *aq_vec_alloc(struct aq_nic_s *aq_nic, unsigned int idx, + struct aq_nic_cfg_s *aq_nic_cfg) +{ + struct aq_vec_s *self = NULL; + struct aq_ring_s *ring = NULL; + unsigned int i = 0U; + int err = 0; + + self = kzalloc(sizeof(*self), GFP_KERNEL); + if (!self) { + err = -ENOMEM; + goto err_exit; + } + + self->aq_nic = aq_nic; + self->aq_ring_param.vec_idx = idx; + self->aq_ring_param.cpu = + idx + aq_nic_cfg->aq_rss.base_cpu_number; + + cpumask_set_cpu(self->aq_ring_param.cpu, + &self->aq_ring_param.affinity_mask); + + self->tx_rings = 0; + self->rx_rings = 0; + + netif_napi_add(aq_nic_get_ndev(aq_nic), &self->napi, + aq_vec_poll, AQ_CFG_NAPI_WEIGHT); + + for (i = 0; i < aq_nic_cfg->tcs; ++i) { + unsigned int idx_ring = AQ_NIC_TCVEC2RING(self->nic, + self->tx_rings, + self->aq_ring_param.vec_idx); + + ring = aq_ring_tx_alloc(&self->ring[i][AQ_VEC_TX_ID], aq_nic, + idx_ring, aq_nic_cfg); + if (!ring) { + err = -ENOMEM; + goto err_exit; + } + + ++self->tx_rings; + + aq_nic_set_tx_ring(aq_nic, idx_ring, ring); + + ring = aq_ring_rx_alloc(&self->ring[i][AQ_VEC_RX_ID], aq_nic, + idx_ring, aq_nic_cfg); + if (!ring) { + err = -ENOMEM; + goto err_exit; + } + + ++self->rx_rings; + } + +err_exit: + if (err < 0) { + aq_vec_free(self); + self = NULL; + } + return self; +} + +int aq_vec_init(struct aq_vec_s *self, const struct aq_hw_ops *aq_hw_ops, + struct aq_hw_s *aq_hw) +{ + struct aq_ring_s *ring = NULL; + unsigned int i = 0U; + int err = 0; + + self->aq_hw_ops = aq_hw_ops; + self->aq_hw = aq_hw; + + for (i = 0U, ring = self->ring[0]; + self->tx_rings > i; ++i, ring = self->ring[i]) { + err = aq_ring_init(&ring[AQ_VEC_TX_ID]); + if (err < 0) + goto err_exit; + + err = self->aq_hw_ops->hw_ring_tx_init(self->aq_hw, + &ring[AQ_VEC_TX_ID], + &self->aq_ring_param); + if (err < 0) + goto err_exit; + + err = aq_ring_init(&ring[AQ_VEC_RX_ID]); + if (err < 0) + goto err_exit; + + err = self->aq_hw_ops->hw_ring_rx_init(self->aq_hw, + &ring[AQ_VEC_RX_ID], + &self->aq_ring_param); + if (err < 0) + goto err_exit; + + err = aq_ring_rx_fill(&ring[AQ_VEC_RX_ID]); + if (err < 0) + goto err_exit; + + err = self->aq_hw_ops->hw_ring_rx_fill(self->aq_hw, + &ring[AQ_VEC_RX_ID], 0U); + if (err < 0) + goto err_exit; + } + +err_exit: + return err; +} + +int aq_vec_start(struct aq_vec_s *self) +{ + struct aq_ring_s *ring = NULL; + unsigned int i = 0U; + int err = 0; + + for (i = 0U, ring = self->ring[0]; + self->tx_rings > i; ++i, ring = self->ring[i]) { + err = self->aq_hw_ops->hw_ring_tx_start(self->aq_hw, + &ring[AQ_VEC_TX_ID]); + if (err < 0) + goto err_exit; + + err = self->aq_hw_ops->hw_ring_rx_start(self->aq_hw, + &ring[AQ_VEC_RX_ID]); + if (err < 0) + goto err_exit; + } + + napi_enable(&self->napi); + +err_exit: + return err; +} + +void aq_vec_stop(struct aq_vec_s *self) +{ + struct aq_ring_s *ring = NULL; + unsigned int i = 0U; + + for (i = 0U, ring = self->ring[0]; + self->tx_rings > i; ++i, ring = self->ring[i]) { + self->aq_hw_ops->hw_ring_tx_stop(self->aq_hw, + &ring[AQ_VEC_TX_ID]); + + self->aq_hw_ops->hw_ring_rx_stop(self->aq_hw, + &ring[AQ_VEC_RX_ID]); + } + + napi_disable(&self->napi); +} + +void aq_vec_deinit(struct aq_vec_s *self) +{ + struct aq_ring_s *ring = NULL; + unsigned int i = 0U; + + if (!self) + goto err_exit; + + for (i = 0U, ring = self->ring[0]; + self->tx_rings > i; ++i, ring = self->ring[i]) { + aq_ring_tx_clean(&ring[AQ_VEC_TX_ID]); + aq_ring_rx_deinit(&ring[AQ_VEC_RX_ID]); + } +err_exit:; +} + +void aq_vec_free(struct aq_vec_s *self) +{ + struct aq_ring_s *ring = NULL; + unsigned int i = 0U; + + if (!self) + goto err_exit; + + for (i = 0U, ring = self->ring[0]; + self->tx_rings > i; ++i, ring = self->ring[i]) { + aq_ring_free(&ring[AQ_VEC_TX_ID]); + aq_ring_free(&ring[AQ_VEC_RX_ID]); + } + + netif_napi_del(&self->napi); + + kfree(self); + +err_exit:; +} + +irqreturn_t aq_vec_isr(int irq, void *private) +{ + struct aq_vec_s *self = private; + int err = 0; + + if (!self) { + err = -EINVAL; + goto err_exit; + } + napi_schedule(&self->napi); + +err_exit: + return err >= 0 ? IRQ_HANDLED : IRQ_NONE; +} + +irqreturn_t aq_vec_isr_legacy(int irq, void *private) +{ + struct aq_vec_s *self = private; + u64 irq_mask = 0U; + int err; + + if (!self) + return IRQ_NONE; + err = self->aq_hw_ops->hw_irq_read(self->aq_hw, &irq_mask); + if (err < 0) + return IRQ_NONE; + + if (irq_mask) { + self->aq_hw_ops->hw_irq_disable(self->aq_hw, + 1U << self->aq_ring_param.vec_idx); + napi_schedule(&self->napi); + } else { + self->aq_hw_ops->hw_irq_enable(self->aq_hw, 1U); + return IRQ_NONE; + } + + return IRQ_HANDLED; +} + +cpumask_t *aq_vec_get_affinity_mask(struct aq_vec_s *self) +{ + return &self->aq_ring_param.affinity_mask; +} + +void aq_vec_add_stats(struct aq_vec_s *self, + struct aq_ring_stats_rx_s *stats_rx, + struct aq_ring_stats_tx_s *stats_tx) +{ + struct aq_ring_s *ring = NULL; + unsigned int r = 0U; + + for (r = 0U, ring = self->ring[0]; + self->tx_rings > r; ++r, ring = self->ring[r]) { + struct aq_ring_stats_tx_s *tx = &ring[AQ_VEC_TX_ID].stats.tx; + struct aq_ring_stats_rx_s *rx = &ring[AQ_VEC_RX_ID].stats.rx; + + stats_rx->packets += rx->packets; + stats_rx->bytes += rx->bytes; + stats_rx->errors += rx->errors; + stats_rx->jumbo_packets += rx->jumbo_packets; + stats_rx->lro_packets += rx->lro_packets; + + stats_tx->packets += tx->packets; + stats_tx->bytes += tx->bytes; + stats_tx->errors += tx->errors; + stats_tx->queue_restarts += tx->queue_restarts; + } +} + +int aq_vec_get_sw_stats(struct aq_vec_s *self, u64 *data, unsigned int *p_count) +{ + unsigned int count = 0U; + struct aq_ring_stats_rx_s stats_rx; + struct aq_ring_stats_tx_s stats_tx; + + memset(&stats_rx, 0U, sizeof(struct aq_ring_stats_rx_s)); + memset(&stats_tx, 0U, sizeof(struct aq_ring_stats_tx_s)); + aq_vec_add_stats(self, &stats_rx, &stats_tx); + + /* This data should mimic aq_ethtool_queue_stat_names structure + */ + data[count] += stats_rx.packets; + data[++count] += stats_tx.packets; + data[++count] += stats_tx.queue_restarts; + data[++count] += stats_rx.jumbo_packets; + data[++count] += stats_rx.lro_packets; + data[++count] += stats_rx.errors; + + if (p_count) + *p_count = ++count; + + return 0; +} diff --git a/drivers/net/ethernet/aquantia/atlantic/aq_vec.h b/drivers/net/ethernet/aquantia/atlantic/aq_vec.h new file mode 100644 index 000000000..8bdf60bb3 --- /dev/null +++ b/drivers/net/ethernet/aquantia/atlantic/aq_vec.h @@ -0,0 +1,44 @@ +/* + * aQuantia Corporation Network Driver + * Copyright (C) 2014-2017 aQuantia Corporation. All rights reserved + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + */ + +/* File aq_vec.h: Definition of common structures for vector of Rx and Tx rings. + * Declaration of functions for Rx and Tx rings. + */ + +#ifndef AQ_VEC_H +#define AQ_VEC_H + +#include "aq_common.h" +#include <linux/irqreturn.h> + +struct aq_hw_s; +struct aq_hw_ops; +struct aq_nic_s; +struct aq_nic_cfg_s; +struct aq_ring_stats_rx_s; +struct aq_ring_stats_tx_s; + +irqreturn_t aq_vec_isr(int irq, void *private); +irqreturn_t aq_vec_isr_legacy(int irq, void *private); +struct aq_vec_s *aq_vec_alloc(struct aq_nic_s *aq_nic, unsigned int idx, + struct aq_nic_cfg_s *aq_nic_cfg); +int aq_vec_init(struct aq_vec_s *self, const struct aq_hw_ops *aq_hw_ops, + struct aq_hw_s *aq_hw); +void aq_vec_deinit(struct aq_vec_s *self); +void aq_vec_free(struct aq_vec_s *self); +int aq_vec_start(struct aq_vec_s *self); +void aq_vec_stop(struct aq_vec_s *self); +cpumask_t *aq_vec_get_affinity_mask(struct aq_vec_s *self); +int aq_vec_get_sw_stats(struct aq_vec_s *self, u64 *data, + unsigned int *p_count); +void aq_vec_add_stats(struct aq_vec_s *self, + struct aq_ring_stats_rx_s *stats_rx, + struct aq_ring_stats_tx_s *stats_tx); + +#endif /* AQ_VEC_H */ diff --git a/drivers/net/ethernet/aquantia/atlantic/hw_atl/Makefile b/drivers/net/ethernet/aquantia/atlantic/hw_atl/Makefile new file mode 100644 index 000000000..805fa28f3 --- /dev/null +++ b/drivers/net/ethernet/aquantia/atlantic/hw_atl/Makefile @@ -0,0 +1,2 @@ +# SPDX-License-Identifier: GPL-2.0 +# kbuild requires Makefile in a directory to build individual objects diff --git a/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_a0.c b/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_a0.c new file mode 100644 index 000000000..d48595470 --- /dev/null +++ b/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_a0.c @@ -0,0 +1,909 @@ +/* + * aQuantia Corporation Network Driver + * Copyright (C) 2014-2017 aQuantia Corporation. All rights reserved + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + */ + +/* File hw_atl_a0.c: Definition of Atlantic hardware specific functions. */ + +#include "../aq_hw.h" +#include "../aq_hw_utils.h" +#include "../aq_ring.h" +#include "../aq_nic.h" +#include "hw_atl_a0.h" +#include "hw_atl_utils.h" +#include "hw_atl_llh.h" +#include "hw_atl_a0_internal.h" + +#define DEFAULT_A0_BOARD_BASIC_CAPABILITIES \ + .is_64_dma = true, \ + .msix_irqs = 4U, \ + .irq_mask = ~0U, \ + .vecs = HW_ATL_A0_RSS_MAX, \ + .tcs = HW_ATL_A0_TC_MAX, \ + .rxd_alignment = 1U, \ + .rxd_size = HW_ATL_A0_RXD_SIZE, \ + .rxds_max = HW_ATL_A0_MAX_RXD, \ + .rxds_min = HW_ATL_A0_MIN_RXD, \ + .txd_alignment = 1U, \ + .txd_size = HW_ATL_A0_TXD_SIZE, \ + .txds_max = HW_ATL_A0_MAX_TXD, \ + .txds_min = HW_ATL_A0_MIN_RXD, \ + .txhwb_alignment = 4096U, \ + .tx_rings = HW_ATL_A0_TX_RINGS, \ + .rx_rings = HW_ATL_A0_RX_RINGS, \ + .hw_features = NETIF_F_HW_CSUM | \ + NETIF_F_RXHASH | \ + NETIF_F_RXCSUM | \ + NETIF_F_SG | \ + NETIF_F_TSO, \ + .hw_priv_flags = IFF_UNICAST_FLT, \ + .flow_control = true, \ + .mtu = HW_ATL_A0_MTU_JUMBO, \ + .mac_regs_count = 88, \ + .hw_alive_check_addr = 0x10U + +const struct aq_hw_caps_s hw_atl_a0_caps_aqc100 = { + DEFAULT_A0_BOARD_BASIC_CAPABILITIES, + .media_type = AQ_HW_MEDIA_TYPE_FIBRE, + .link_speed_msk = HW_ATL_A0_RATE_5G | + HW_ATL_A0_RATE_2G5 | + HW_ATL_A0_RATE_1G | + HW_ATL_A0_RATE_100M, +}; + +const struct aq_hw_caps_s hw_atl_a0_caps_aqc107 = { + DEFAULT_A0_BOARD_BASIC_CAPABILITIES, + .media_type = AQ_HW_MEDIA_TYPE_TP, + .link_speed_msk = HW_ATL_A0_RATE_10G | + HW_ATL_A0_RATE_5G | + HW_ATL_A0_RATE_2G5 | + HW_ATL_A0_RATE_1G | + HW_ATL_A0_RATE_100M, +}; + +const struct aq_hw_caps_s hw_atl_a0_caps_aqc108 = { + DEFAULT_A0_BOARD_BASIC_CAPABILITIES, + .media_type = AQ_HW_MEDIA_TYPE_TP, + .link_speed_msk = HW_ATL_A0_RATE_5G | + HW_ATL_A0_RATE_2G5 | + HW_ATL_A0_RATE_1G | + HW_ATL_A0_RATE_100M, +}; + +const struct aq_hw_caps_s hw_atl_a0_caps_aqc109 = { + DEFAULT_A0_BOARD_BASIC_CAPABILITIES, + .media_type = AQ_HW_MEDIA_TYPE_TP, + .link_speed_msk = HW_ATL_A0_RATE_2G5 | + HW_ATL_A0_RATE_1G | + HW_ATL_A0_RATE_100M, +}; + +static int hw_atl_a0_hw_reset(struct aq_hw_s *self) +{ + int err = 0; + + hw_atl_glb_glb_reg_res_dis_set(self, 1U); + hw_atl_pci_pci_reg_res_dis_set(self, 0U); + hw_atl_rx_rx_reg_res_dis_set(self, 0U); + hw_atl_tx_tx_reg_res_dis_set(self, 0U); + + HW_ATL_FLUSH(); + hw_atl_glb_soft_res_set(self, 1); + + /* check 10 times by 1ms */ + AQ_HW_WAIT_FOR(hw_atl_glb_soft_res_get(self) == 0, 1000U, 10U); + if (err < 0) + goto err_exit; + + hw_atl_itr_irq_reg_res_dis_set(self, 0U); + hw_atl_itr_res_irq_set(self, 1U); + + /* check 10 times by 1ms */ + AQ_HW_WAIT_FOR(hw_atl_itr_res_irq_get(self) == 0, 1000U, 10U); + if (err < 0) + goto err_exit; + + self->aq_fw_ops->set_state(self, MPI_RESET); + + err = aq_hw_err_from_flags(self); + +err_exit: + return err; +} + +static int hw_atl_a0_hw_qos_set(struct aq_hw_s *self) +{ + u32 tc = 0U; + u32 buff_size = 0U; + unsigned int i_priority = 0U; + bool is_rx_flow_control = false; + + /* TPS Descriptor rate init */ + hw_atl_tps_tx_pkt_shed_desc_rate_curr_time_res_set(self, 0x0U); + hw_atl_tps_tx_pkt_shed_desc_rate_lim_set(self, 0xA); + + /* TPS VM init */ + hw_atl_tps_tx_pkt_shed_desc_vm_arb_mode_set(self, 0U); + + /* TPS TC credits init */ + hw_atl_tps_tx_pkt_shed_desc_tc_arb_mode_set(self, 0U); + hw_atl_tps_tx_pkt_shed_data_arb_mode_set(self, 0U); + + hw_atl_tps_tx_pkt_shed_tc_data_max_credit_set(self, 0xFFF, 0U); + hw_atl_tps_tx_pkt_shed_tc_data_weight_set(self, 0x64, 0U); + hw_atl_tps_tx_pkt_shed_desc_tc_max_credit_set(self, 0x50, 0U); + hw_atl_tps_tx_pkt_shed_desc_tc_weight_set(self, 0x1E, 0U); + + /* Tx buf size */ + buff_size = HW_ATL_A0_TXBUF_MAX; + + hw_atl_tpb_tx_pkt_buff_size_per_tc_set(self, buff_size, tc); + hw_atl_tpb_tx_buff_hi_threshold_per_tc_set(self, + (buff_size * + (1024 / 32U) * 66U) / + 100U, tc); + hw_atl_tpb_tx_buff_lo_threshold_per_tc_set(self, + (buff_size * + (1024 / 32U) * 50U) / + 100U, tc); + + /* QoS Rx buf size per TC */ + tc = 0; + is_rx_flow_control = (AQ_NIC_FC_RX & self->aq_nic_cfg->flow_control); + buff_size = HW_ATL_A0_RXBUF_MAX; + + hw_atl_rpb_rx_pkt_buff_size_per_tc_set(self, buff_size, tc); + hw_atl_rpb_rx_buff_hi_threshold_per_tc_set(self, + (buff_size * + (1024U / 32U) * 66U) / + 100U, tc); + hw_atl_rpb_rx_buff_lo_threshold_per_tc_set(self, + (buff_size * + (1024U / 32U) * 50U) / + 100U, tc); + hw_atl_rpb_rx_xoff_en_per_tc_set(self, is_rx_flow_control ? 1U : 0U, tc); + + /* QoS 802.1p priority -> TC mapping */ + for (i_priority = 8U; i_priority--;) + hw_atl_rpf_rpb_user_priority_tc_map_set(self, i_priority, 0U); + + return aq_hw_err_from_flags(self); +} + +static int hw_atl_a0_hw_rss_hash_set(struct aq_hw_s *self, + struct aq_rss_parameters *rss_params) +{ + struct aq_nic_cfg_s *cfg = self->aq_nic_cfg; + int err = 0; + unsigned int i = 0U; + unsigned int addr = 0U; + + for (i = 10, addr = 0U; i--; ++addr) { + u32 key_data = cfg->is_rss ? + __swab32(rss_params->hash_secret_key[i]) : 0U; + hw_atl_rpf_rss_key_wr_data_set(self, key_data); + hw_atl_rpf_rss_key_addr_set(self, addr); + hw_atl_rpf_rss_key_wr_en_set(self, 1U); + AQ_HW_WAIT_FOR(hw_atl_rpf_rss_key_wr_en_get(self) == 0, + 1000U, 10U); + if (err < 0) + goto err_exit; + } + + err = aq_hw_err_from_flags(self); + +err_exit: + return err; +} + +static int hw_atl_a0_hw_rss_set(struct aq_hw_s *self, + struct aq_rss_parameters *rss_params) +{ + u8 *indirection_table = rss_params->indirection_table; + u32 i = 0U; + u32 num_rss_queues = max(1U, self->aq_nic_cfg->num_rss_queues); + int err = 0; + u16 bitary[1 + (HW_ATL_A0_RSS_REDIRECTION_MAX * + HW_ATL_A0_RSS_REDIRECTION_BITS / 16U)]; + + memset(bitary, 0, sizeof(bitary)); + + for (i = HW_ATL_A0_RSS_REDIRECTION_MAX; i--; ) { + (*(u32 *)(bitary + ((i * 3U) / 16U))) |= + ((indirection_table[i] % num_rss_queues) << + ((i * 3U) & 0xFU)); + } + + for (i = ARRAY_SIZE(bitary); i--;) { + hw_atl_rpf_rss_redir_tbl_wr_data_set(self, bitary[i]); + hw_atl_rpf_rss_redir_tbl_addr_set(self, i); + hw_atl_rpf_rss_redir_wr_en_set(self, 1U); + AQ_HW_WAIT_FOR(hw_atl_rpf_rss_redir_wr_en_get(self) == 0, + 1000U, 10U); + if (err < 0) + goto err_exit; + } + + err = aq_hw_err_from_flags(self); + +err_exit: + return err; +} + +static int hw_atl_a0_hw_offload_set(struct aq_hw_s *self, + struct aq_nic_cfg_s *aq_nic_cfg) +{ + /* TX checksums offloads*/ + hw_atl_tpo_ipv4header_crc_offload_en_set(self, 1); + hw_atl_tpo_tcp_udp_crc_offload_en_set(self, 1); + + /* RX checksums offloads*/ + hw_atl_rpo_ipv4header_crc_offload_en_set(self, 1); + hw_atl_rpo_tcp_udp_crc_offload_en_set(self, 1); + + /* LSO offloads*/ + hw_atl_tdm_large_send_offload_en_set(self, 0xFFFFFFFFU); + + return aq_hw_err_from_flags(self); +} + +static int hw_atl_a0_hw_init_tx_path(struct aq_hw_s *self) +{ + hw_atl_thm_lso_tcp_flag_of_first_pkt_set(self, 0x0FF6U); + hw_atl_thm_lso_tcp_flag_of_middle_pkt_set(self, 0x0FF6U); + hw_atl_thm_lso_tcp_flag_of_last_pkt_set(self, 0x0F7FU); + + /* Tx interrupts */ + hw_atl_tdm_tx_desc_wr_wb_irq_en_set(self, 1U); + + /* misc */ + aq_hw_write_reg(self, 0x00007040U, IS_CHIP_FEATURE(TPO2) ? + 0x00010000U : 0x00000000U); + hw_atl_tdm_tx_dca_en_set(self, 0U); + hw_atl_tdm_tx_dca_mode_set(self, 0U); + + hw_atl_tpb_tx_path_scp_ins_en_set(self, 1U); + + return aq_hw_err_from_flags(self); +} + +static int hw_atl_a0_hw_init_rx_path(struct aq_hw_s *self) +{ + struct aq_nic_cfg_s *cfg = self->aq_nic_cfg; + int i; + + /* Rx TC/RSS number config */ + hw_atl_rpb_rpf_rx_traf_class_mode_set(self, 1U); + + /* Rx flow control */ + hw_atl_rpb_rx_flow_ctl_mode_set(self, 1U); + + /* RSS Ring selection */ + hw_atl_reg_rx_flr_rss_control1set(self, cfg->is_rss ? + 0xB3333333U : 0x00000000U); + + /* Multicast filters */ + for (i = HW_ATL_A0_MAC_MAX; i--;) { + hw_atl_rpfl2_uc_flr_en_set(self, (i == 0U) ? 1U : 0U, i); + hw_atl_rpfl2unicast_flr_act_set(self, 1U, i); + } + + hw_atl_reg_rx_flr_mcst_flr_msk_set(self, 0x00000000U); + hw_atl_reg_rx_flr_mcst_flr_set(self, 0x00010FFFU, 0U); + + /* Vlan filters */ + hw_atl_rpf_vlan_outer_etht_set(self, 0x88A8U); + hw_atl_rpf_vlan_inner_etht_set(self, 0x8100U); + hw_atl_rpf_vlan_prom_mode_en_set(self, 1); + + /* Rx Interrupts */ + hw_atl_rdm_rx_desc_wr_wb_irq_en_set(self, 1U); + + /* misc */ + hw_atl_rpfl2broadcast_flr_act_set(self, 1U); + hw_atl_rpfl2broadcast_count_threshold_set(self, 0xFFFFU & (~0U / 256U)); + + hw_atl_rdm_rx_dca_en_set(self, 0U); + hw_atl_rdm_rx_dca_mode_set(self, 0U); + + return aq_hw_err_from_flags(self); +} + +static int hw_atl_a0_hw_mac_addr_set(struct aq_hw_s *self, u8 *mac_addr) +{ + int err = 0; + unsigned int h = 0U; + unsigned int l = 0U; + + if (!mac_addr) { + err = -EINVAL; + goto err_exit; + } + h = (mac_addr[0] << 8) | (mac_addr[1]); + l = (mac_addr[2] << 24) | (mac_addr[3] << 16) | + (mac_addr[4] << 8) | mac_addr[5]; + + hw_atl_rpfl2_uc_flr_en_set(self, 0U, HW_ATL_A0_MAC); + hw_atl_rpfl2unicast_dest_addresslsw_set(self, l, HW_ATL_A0_MAC); + hw_atl_rpfl2unicast_dest_addressmsw_set(self, h, HW_ATL_A0_MAC); + hw_atl_rpfl2_uc_flr_en_set(self, 1U, HW_ATL_A0_MAC); + + err = aq_hw_err_from_flags(self); + +err_exit: + return err; +} + +static int hw_atl_a0_hw_init(struct aq_hw_s *self, u8 *mac_addr) +{ + static u32 aq_hw_atl_igcr_table_[4][2] = { + { 0x20000000U, 0x20000000U }, /* AQ_IRQ_INVALID */ + { 0x20000080U, 0x20000080U }, /* AQ_IRQ_LEGACY */ + { 0x20000021U, 0x20000025U }, /* AQ_IRQ_MSI */ + { 0x20000022U, 0x20000026U } /* AQ_IRQ_MSIX */ + }; + + int err = 0; + + struct aq_nic_cfg_s *aq_nic_cfg = self->aq_nic_cfg; + + hw_atl_a0_hw_init_tx_path(self); + hw_atl_a0_hw_init_rx_path(self); + + hw_atl_a0_hw_mac_addr_set(self, mac_addr); + + self->aq_fw_ops->set_link_speed(self, aq_nic_cfg->link_speed_msk); + self->aq_fw_ops->set_state(self, MPI_INIT); + + hw_atl_reg_tx_dma_debug_ctl_set(self, 0x800000b8U); + hw_atl_reg_tx_dma_debug_ctl_set(self, 0x000000b8U); + + hw_atl_a0_hw_qos_set(self); + hw_atl_a0_hw_rss_set(self, &aq_nic_cfg->aq_rss); + hw_atl_a0_hw_rss_hash_set(self, &aq_nic_cfg->aq_rss); + + /* Reset link status and read out initial hardware counters */ + self->aq_link_status.mbps = 0; + self->aq_fw_ops->update_stats(self); + + err = aq_hw_err_from_flags(self); + if (err < 0) + goto err_exit; + + /* Interrupts */ + hw_atl_reg_irq_glb_ctl_set(self, + aq_hw_atl_igcr_table_[aq_nic_cfg->irq_type] + [(aq_nic_cfg->vecs > 1U) ? 1 : 0]); + + hw_atl_itr_irq_auto_masklsw_set(self, aq_nic_cfg->aq_hw_caps->irq_mask); + + /* Interrupts */ + hw_atl_reg_gen_irq_map_set(self, + ((HW_ATL_A0_ERR_INT << 0x18) | (1U << 0x1F)) | + ((HW_ATL_A0_ERR_INT << 0x10) | (1U << 0x17)) | + ((HW_ATL_A0_ERR_INT << 8) | (1U << 0xF)) | + ((HW_ATL_A0_ERR_INT) | (1U << 0x7)), 0U); + + hw_atl_a0_hw_offload_set(self, aq_nic_cfg); + +err_exit: + return err; +} + +static int hw_atl_a0_hw_ring_tx_start(struct aq_hw_s *self, + struct aq_ring_s *ring) +{ + hw_atl_tdm_tx_desc_en_set(self, 1, ring->idx); + return aq_hw_err_from_flags(self); +} + +static int hw_atl_a0_hw_ring_rx_start(struct aq_hw_s *self, + struct aq_ring_s *ring) +{ + hw_atl_rdm_rx_desc_en_set(self, 1, ring->idx); + return aq_hw_err_from_flags(self); +} + +static int hw_atl_a0_hw_start(struct aq_hw_s *self) +{ + hw_atl_tpb_tx_buff_en_set(self, 1); + hw_atl_rpb_rx_buff_en_set(self, 1); + return aq_hw_err_from_flags(self); +} + +static int hw_atl_a0_hw_tx_ring_tail_update(struct aq_hw_s *self, + struct aq_ring_s *ring) +{ + hw_atl_reg_tx_dma_desc_tail_ptr_set(self, ring->sw_tail, ring->idx); + return 0; +} + +static int hw_atl_a0_hw_ring_tx_xmit(struct aq_hw_s *self, + struct aq_ring_s *ring, + unsigned int frags) +{ + struct aq_ring_buff_s *buff = NULL; + struct hw_atl_txd_s *txd = NULL; + unsigned int buff_pa_len = 0U; + unsigned int pkt_len = 0U; + unsigned int frag_count = 0U; + bool is_gso = false; + + buff = &ring->buff_ring[ring->sw_tail]; + pkt_len = (buff->is_eop && buff->is_sop) ? buff->len : buff->len_pkt; + + for (frag_count = 0; frag_count < frags; frag_count++) { + txd = (struct hw_atl_txd_s *)&ring->dx_ring[ring->sw_tail * + HW_ATL_A0_TXD_SIZE]; + txd->ctl = 0; + txd->ctl2 = 0; + txd->buf_addr = 0; + + buff = &ring->buff_ring[ring->sw_tail]; + + if (buff->is_txc) { + txd->ctl |= (buff->len_l3 << 31) | + (buff->len_l2 << 24) | + HW_ATL_A0_TXD_CTL_CMD_TCP | + HW_ATL_A0_TXD_CTL_DESC_TYPE_TXC; + txd->ctl2 |= (buff->mss << 16) | + (buff->len_l4 << 8) | + (buff->len_l3 >> 1); + + pkt_len -= (buff->len_l4 + + buff->len_l3 + + buff->len_l2); + is_gso = true; + + if (buff->is_ipv6) + txd->ctl |= HW_ATL_A0_TXD_CTL_CMD_IPV6; + } else { + buff_pa_len = buff->len; + + txd->buf_addr = buff->pa; + txd->ctl |= (HW_ATL_A0_TXD_CTL_BLEN & + ((u32)buff_pa_len << 4)); + txd->ctl |= HW_ATL_A0_TXD_CTL_DESC_TYPE_TXD; + /* PAY_LEN */ + txd->ctl2 |= HW_ATL_A0_TXD_CTL2_LEN & (pkt_len << 14); + + if (is_gso) { + txd->ctl |= HW_ATL_A0_TXD_CTL_CMD_LSO; + txd->ctl2 |= HW_ATL_A0_TXD_CTL2_CTX_EN; + } + + /* Tx checksum offloads */ + if (buff->is_ip_cso) + txd->ctl |= HW_ATL_A0_TXD_CTL_CMD_IPCSO; + + if (buff->is_udp_cso || buff->is_tcp_cso) + txd->ctl |= HW_ATL_A0_TXD_CTL_CMD_TUCSO; + + if (unlikely(buff->is_eop)) { + txd->ctl |= HW_ATL_A0_TXD_CTL_EOP; + txd->ctl |= HW_ATL_A0_TXD_CTL_CMD_WB; + is_gso = false; + } + } + + ring->sw_tail = aq_ring_next_dx(ring, ring->sw_tail); + } + + hw_atl_a0_hw_tx_ring_tail_update(self, ring); + return aq_hw_err_from_flags(self); +} + +static int hw_atl_a0_hw_ring_rx_init(struct aq_hw_s *self, + struct aq_ring_s *aq_ring, + struct aq_ring_param_s *aq_ring_param) +{ + u32 dma_desc_addr_lsw = (u32)aq_ring->dx_ring_pa; + u32 dma_desc_addr_msw = (u32)(((u64)aq_ring->dx_ring_pa) >> 32); + + hw_atl_rdm_rx_desc_en_set(self, false, aq_ring->idx); + + hw_atl_rdm_rx_desc_head_splitting_set(self, 0U, aq_ring->idx); + + hw_atl_reg_rx_dma_desc_base_addresslswset(self, dma_desc_addr_lsw, + aq_ring->idx); + + hw_atl_reg_rx_dma_desc_base_addressmswset(self, + dma_desc_addr_msw, + aq_ring->idx); + + hw_atl_rdm_rx_desc_len_set(self, aq_ring->size / 8U, aq_ring->idx); + + hw_atl_rdm_rx_desc_data_buff_size_set(self, + AQ_CFG_RX_FRAME_MAX / 1024U, + aq_ring->idx); + + hw_atl_rdm_rx_desc_head_buff_size_set(self, 0U, aq_ring->idx); + hw_atl_rdm_rx_desc_head_splitting_set(self, 0U, aq_ring->idx); + hw_atl_rpo_rx_desc_vlan_stripping_set(self, 0U, aq_ring->idx); + + /* Rx ring set mode */ + + /* Mapping interrupt vector */ + hw_atl_itr_irq_map_rx_set(self, aq_ring_param->vec_idx, aq_ring->idx); + hw_atl_itr_irq_map_en_rx_set(self, true, aq_ring->idx); + + hw_atl_rdm_cpu_id_set(self, aq_ring_param->cpu, aq_ring->idx); + hw_atl_rdm_rx_desc_dca_en_set(self, 0U, aq_ring->idx); + hw_atl_rdm_rx_head_dca_en_set(self, 0U, aq_ring->idx); + hw_atl_rdm_rx_pld_dca_en_set(self, 0U, aq_ring->idx); + + return aq_hw_err_from_flags(self); +} + +static int hw_atl_a0_hw_ring_tx_init(struct aq_hw_s *self, + struct aq_ring_s *aq_ring, + struct aq_ring_param_s *aq_ring_param) +{ + u32 dma_desc_lsw_addr = (u32)aq_ring->dx_ring_pa; + u32 dma_desc_msw_addr = (u32)(((u64)aq_ring->dx_ring_pa) >> 32); + + hw_atl_reg_tx_dma_desc_base_addresslswset(self, dma_desc_lsw_addr, + aq_ring->idx); + + hw_atl_reg_tx_dma_desc_base_addressmswset(self, dma_desc_msw_addr, + aq_ring->idx); + + hw_atl_tdm_tx_desc_len_set(self, aq_ring->size / 8U, aq_ring->idx); + + hw_atl_a0_hw_tx_ring_tail_update(self, aq_ring); + + /* Set Tx threshold */ + hw_atl_tdm_tx_desc_wr_wb_threshold_set(self, 0U, aq_ring->idx); + + /* Mapping interrupt vector */ + hw_atl_itr_irq_map_tx_set(self, aq_ring_param->vec_idx, aq_ring->idx); + hw_atl_itr_irq_map_en_tx_set(self, true, aq_ring->idx); + + hw_atl_tdm_cpu_id_set(self, aq_ring_param->cpu, aq_ring->idx); + hw_atl_tdm_tx_desc_dca_en_set(self, 0U, aq_ring->idx); + + return aq_hw_err_from_flags(self); +} + +static int hw_atl_a0_hw_ring_rx_fill(struct aq_hw_s *self, + struct aq_ring_s *ring, + unsigned int sw_tail_old) +{ + for (; sw_tail_old != ring->sw_tail; + sw_tail_old = aq_ring_next_dx(ring, sw_tail_old)) { + struct hw_atl_rxd_s *rxd = + (struct hw_atl_rxd_s *)&ring->dx_ring[sw_tail_old * + HW_ATL_A0_RXD_SIZE]; + + struct aq_ring_buff_s *buff = &ring->buff_ring[sw_tail_old]; + + rxd->buf_addr = buff->pa; + rxd->hdr_addr = 0U; + } + + hw_atl_reg_rx_dma_desc_tail_ptr_set(self, sw_tail_old, ring->idx); + + return aq_hw_err_from_flags(self); +} + +static int hw_atl_a0_hw_ring_tx_head_update(struct aq_hw_s *self, + struct aq_ring_s *ring) +{ + int err = 0; + unsigned int hw_head = hw_atl_tdm_tx_desc_head_ptr_get(self, ring->idx); + + if (aq_utils_obj_test(&self->flags, AQ_HW_FLAG_ERR_UNPLUG)) { + err = -ENXIO; + goto err_exit; + } + ring->hw_head = hw_head; + err = aq_hw_err_from_flags(self); + +err_exit: + return err; +} + +static int hw_atl_a0_hw_ring_rx_receive(struct aq_hw_s *self, + struct aq_ring_s *ring) +{ + struct device *ndev = aq_nic_get_dev(ring->aq_nic); + + for (; ring->hw_head != ring->sw_tail; + ring->hw_head = aq_ring_next_dx(ring, ring->hw_head)) { + struct aq_ring_buff_s *buff = NULL; + struct hw_atl_rxd_wb_s *rxd_wb = (struct hw_atl_rxd_wb_s *) + &ring->dx_ring[ring->hw_head * HW_ATL_A0_RXD_SIZE]; + + unsigned int is_err = 1U; + unsigned int is_rx_check_sum_enabled = 0U; + unsigned int pkt_type = 0U; + + if (!(rxd_wb->status & 0x5U)) { /* RxD is not done */ + if ((1U << 4) & + hw_atl_reg_rx_dma_desc_status_get(self, ring->idx)) { + hw_atl_rdm_rx_desc_en_set(self, false, ring->idx); + hw_atl_rdm_rx_desc_res_set(self, true, ring->idx); + hw_atl_rdm_rx_desc_res_set(self, false, ring->idx); + hw_atl_rdm_rx_desc_en_set(self, true, ring->idx); + } + + if (ring->hw_head || + (hw_atl_rdm_rx_desc_head_ptr_get(self, + ring->idx) < 2U)) { + break; + } else if (!(rxd_wb->status & 0x1U)) { + struct hw_atl_rxd_wb_s *rxd_wb1 = + (struct hw_atl_rxd_wb_s *) + (&ring->dx_ring[(1U) * + HW_ATL_A0_RXD_SIZE]); + + if ((rxd_wb1->status & 0x1U)) { + rxd_wb->pkt_len = 1514U; + rxd_wb->status = 3U; + } else { + break; + } + } + } + + buff = &ring->buff_ring[ring->hw_head]; + + if (0x3U != (rxd_wb->status & 0x3U)) + rxd_wb->status |= 4; + + is_err = (0x0000001CU & rxd_wb->status); + is_rx_check_sum_enabled = (rxd_wb->type) & (0x3U << 19); + pkt_type = 0xFFU & (rxd_wb->type >> 4); + + if (is_rx_check_sum_enabled) { + if (0x0U == (pkt_type & 0x3U)) + buff->is_ip_cso = (is_err & 0x08U) ? 0 : 1; + + if (0x4U == (pkt_type & 0x1CU)) + buff->is_udp_cso = (is_err & 0x10U) ? 0 : 1; + else if (0x0U == (pkt_type & 0x1CU)) + buff->is_tcp_cso = (is_err & 0x10U) ? 0 : 1; + + /* Checksum offload workaround for small packets */ + if (rxd_wb->pkt_len <= 60) { + buff->is_ip_cso = 0U; + buff->is_cso_err = 0U; + } + } + + is_err &= ~0x18U; + is_err &= ~0x04U; + + dma_unmap_page(ndev, buff->pa, buff->len, DMA_FROM_DEVICE); + + if (is_err || rxd_wb->type & 0x1000U) { + /* status error or DMA error */ + buff->is_error = 1U; + } else { + if (self->aq_nic_cfg->is_rss) { + /* last 4 byte */ + u16 rss_type = rxd_wb->type & 0xFU; + + if (rss_type && rss_type < 0x8U) { + buff->is_hash_l4 = (rss_type == 0x4 || + rss_type == 0x5); + buff->rss_hash = rxd_wb->rss_hash; + } + } + + if (HW_ATL_A0_RXD_WB_STAT2_EOP & rxd_wb->status) { + buff->len = rxd_wb->pkt_len % + AQ_CFG_RX_FRAME_MAX; + buff->len = buff->len ? + buff->len : AQ_CFG_RX_FRAME_MAX; + buff->next = 0U; + buff->is_eop = 1U; + } else { + /* jumbo */ + buff->next = aq_ring_next_dx(ring, + ring->hw_head); + ++ring->stats.rx.jumbo_packets; + } + } + } + + return aq_hw_err_from_flags(self); +} + +static int hw_atl_a0_hw_irq_enable(struct aq_hw_s *self, u64 mask) +{ + hw_atl_itr_irq_msk_setlsw_set(self, LODWORD(mask) | + (1U << HW_ATL_A0_ERR_INT)); + return aq_hw_err_from_flags(self); +} + +static int hw_atl_a0_hw_irq_disable(struct aq_hw_s *self, u64 mask) +{ + hw_atl_itr_irq_msk_clearlsw_set(self, LODWORD(mask)); + hw_atl_itr_irq_status_clearlsw_set(self, LODWORD(mask)); + + if ((1U << 16) & hw_atl_reg_gen_irq_status_get(self)) + atomic_inc(&self->dpc); + + return aq_hw_err_from_flags(self); +} + +static int hw_atl_a0_hw_irq_read(struct aq_hw_s *self, u64 *mask) +{ + *mask = hw_atl_itr_irq_statuslsw_get(self); + return aq_hw_err_from_flags(self); +} + +#define IS_FILTER_ENABLED(_F_) ((packet_filter & (_F_)) ? 1U : 0U) + +static int hw_atl_a0_hw_packet_filter_set(struct aq_hw_s *self, + unsigned int packet_filter) +{ + unsigned int i = 0U; + + hw_atl_rpfl2promiscuous_mode_en_set(self, + IS_FILTER_ENABLED(IFF_PROMISC)); + hw_atl_rpfl2multicast_flr_en_set(self, + IS_FILTER_ENABLED(IFF_MULTICAST), 0); + hw_atl_rpfl2broadcast_en_set(self, IS_FILTER_ENABLED(IFF_BROADCAST)); + + self->aq_nic_cfg->is_mc_list_enabled = + IS_FILTER_ENABLED(IFF_MULTICAST); + + for (i = HW_ATL_A0_MAC_MIN; i < HW_ATL_A0_MAC_MAX; ++i) + hw_atl_rpfl2_uc_flr_en_set(self, + (self->aq_nic_cfg->is_mc_list_enabled && + (i <= self->aq_nic_cfg->mc_list_count)) ? + 1U : 0U, i); + + return aq_hw_err_from_flags(self); +} + +#undef IS_FILTER_ENABLED + +static int hw_atl_a0_hw_multicast_list_set(struct aq_hw_s *self, + u8 ar_mac + [AQ_HW_MULTICAST_ADDRESS_MAX] + [ETH_ALEN], + u32 count) +{ + int err = 0; + + if (count > (HW_ATL_A0_MAC_MAX - HW_ATL_A0_MAC_MIN)) { + err = -EBADRQC; + goto err_exit; + } + for (self->aq_nic_cfg->mc_list_count = 0U; + self->aq_nic_cfg->mc_list_count < count; + ++self->aq_nic_cfg->mc_list_count) { + u32 i = self->aq_nic_cfg->mc_list_count; + u32 h = (ar_mac[i][0] << 8) | (ar_mac[i][1]); + u32 l = (ar_mac[i][2] << 24) | (ar_mac[i][3] << 16) | + (ar_mac[i][4] << 8) | ar_mac[i][5]; + + hw_atl_rpfl2_uc_flr_en_set(self, 0U, HW_ATL_A0_MAC_MIN + i); + + hw_atl_rpfl2unicast_dest_addresslsw_set(self, + l, + HW_ATL_A0_MAC_MIN + i); + + hw_atl_rpfl2unicast_dest_addressmsw_set(self, + h, + HW_ATL_A0_MAC_MIN + i); + + hw_atl_rpfl2_uc_flr_en_set(self, + (self->aq_nic_cfg->is_mc_list_enabled), + HW_ATL_A0_MAC_MIN + i); + } + + err = aq_hw_err_from_flags(self); + +err_exit: + return err; +} + +static int hw_atl_a0_hw_interrupt_moderation_set(struct aq_hw_s *self) +{ + unsigned int i = 0U; + u32 itr_rx; + + if (self->aq_nic_cfg->itr) { + if (self->aq_nic_cfg->itr != AQ_CFG_INTERRUPT_MODERATION_AUTO) { + u32 itr_ = (self->aq_nic_cfg->itr >> 1); + + itr_ = min(AQ_CFG_IRQ_MASK, itr_); + + itr_rx = 0x80000000U | (itr_ << 0x10); + } else { + u32 n = 0xFFFFU & aq_hw_read_reg(self, 0x00002A00U); + + if (n < self->aq_link_status.mbps) { + itr_rx = 0U; + } else { + static unsigned int hw_timers_tbl_[] = { + 0x01CU, /* 10Gbit */ + 0x039U, /* 5Gbit */ + 0x039U, /* 5Gbit 5GS */ + 0x073U, /* 2.5Gbit */ + 0x120U, /* 1Gbit */ + 0x1FFU, /* 100Mbit */ + }; + + unsigned int speed_index = + hw_atl_utils_mbps_2_speed_index( + self->aq_link_status.mbps); + + itr_rx = 0x80000000U | + (hw_timers_tbl_[speed_index] << 0x10U); + } + + aq_hw_write_reg(self, 0x00002A00U, 0x40000000U); + aq_hw_write_reg(self, 0x00002A00U, 0x8D000000U); + } + } else { + itr_rx = 0U; + } + + for (i = HW_ATL_A0_RINGS_MAX; i--;) + hw_atl_reg_irq_thr_set(self, itr_rx, i); + + return aq_hw_err_from_flags(self); +} + +static int hw_atl_a0_hw_stop(struct aq_hw_s *self) +{ + hw_atl_a0_hw_irq_disable(self, HW_ATL_A0_INT_MASK); + return aq_hw_err_from_flags(self); +} + +static int hw_atl_a0_hw_ring_tx_stop(struct aq_hw_s *self, + struct aq_ring_s *ring) +{ + hw_atl_tdm_tx_desc_en_set(self, 0U, ring->idx); + return aq_hw_err_from_flags(self); +} + +static int hw_atl_a0_hw_ring_rx_stop(struct aq_hw_s *self, + struct aq_ring_s *ring) +{ + hw_atl_rdm_rx_desc_en_set(self, 0U, ring->idx); + return aq_hw_err_from_flags(self); +} + +const struct aq_hw_ops hw_atl_ops_a0 = { + .hw_set_mac_address = hw_atl_a0_hw_mac_addr_set, + .hw_init = hw_atl_a0_hw_init, + .hw_set_power = hw_atl_utils_hw_set_power, + .hw_reset = hw_atl_a0_hw_reset, + .hw_start = hw_atl_a0_hw_start, + .hw_ring_tx_start = hw_atl_a0_hw_ring_tx_start, + .hw_ring_tx_stop = hw_atl_a0_hw_ring_tx_stop, + .hw_ring_rx_start = hw_atl_a0_hw_ring_rx_start, + .hw_ring_rx_stop = hw_atl_a0_hw_ring_rx_stop, + .hw_stop = hw_atl_a0_hw_stop, + + .hw_ring_tx_xmit = hw_atl_a0_hw_ring_tx_xmit, + .hw_ring_tx_head_update = hw_atl_a0_hw_ring_tx_head_update, + + .hw_ring_rx_receive = hw_atl_a0_hw_ring_rx_receive, + .hw_ring_rx_fill = hw_atl_a0_hw_ring_rx_fill, + + .hw_irq_enable = hw_atl_a0_hw_irq_enable, + .hw_irq_disable = hw_atl_a0_hw_irq_disable, + .hw_irq_read = hw_atl_a0_hw_irq_read, + + .hw_ring_rx_init = hw_atl_a0_hw_ring_rx_init, + .hw_ring_tx_init = hw_atl_a0_hw_ring_tx_init, + .hw_packet_filter_set = hw_atl_a0_hw_packet_filter_set, + .hw_multicast_list_set = hw_atl_a0_hw_multicast_list_set, + .hw_interrupt_moderation_set = hw_atl_a0_hw_interrupt_moderation_set, + .hw_rss_set = hw_atl_a0_hw_rss_set, + .hw_rss_hash_set = hw_atl_a0_hw_rss_hash_set, + .hw_get_regs = hw_atl_utils_hw_get_regs, + .hw_get_hw_stats = hw_atl_utils_get_hw_stats, + .hw_get_fw_version = hw_atl_utils_get_fw_version, +}; diff --git a/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_a0.h b/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_a0.h new file mode 100644 index 000000000..25fe954de --- /dev/null +++ b/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_a0.h @@ -0,0 +1,26 @@ +/* + * aQuantia Corporation Network Driver + * Copyright (C) 2014-2017 aQuantia Corporation. All rights reserved + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + */ + +/* File hw_atl_a0.h: Declaration of abstract interface for Atlantic hardware + * specific functions. + */ + +#ifndef HW_ATL_A0_H +#define HW_ATL_A0_H + +#include "../aq_common.h" + +extern const struct aq_hw_caps_s hw_atl_a0_caps_aqc100; +extern const struct aq_hw_caps_s hw_atl_a0_caps_aqc107; +extern const struct aq_hw_caps_s hw_atl_a0_caps_aqc108; +extern const struct aq_hw_caps_s hw_atl_a0_caps_aqc109; + +extern const struct aq_hw_ops hw_atl_ops_a0; + +#endif /* HW_ATL_A0_H */ diff --git a/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_a0_internal.h b/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_a0_internal.h new file mode 100644 index 000000000..3c94cff57 --- /dev/null +++ b/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_a0_internal.h @@ -0,0 +1,99 @@ +/* + * aQuantia Corporation Network Driver + * Copyright (C) 2014-2017 aQuantia Corporation. All rights reserved + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + */ + +/* File hw_atl_a0_internal.h: Definition of Atlantic A0 chip specific + * constants. + */ + +#ifndef HW_ATL_A0_INTERNAL_H +#define HW_ATL_A0_INTERNAL_H + +#include "../aq_common.h" + +#define HW_ATL_A0_MTU_JUMBO 9014U + +#define HW_ATL_A0_TX_RINGS 4U +#define HW_ATL_A0_RX_RINGS 4U + +#define HW_ATL_A0_RINGS_MAX 32U +#define HW_ATL_A0_TXD_SIZE 16U +#define HW_ATL_A0_RXD_SIZE 16U + +#define HW_ATL_A0_MAC 0U +#define HW_ATL_A0_MAC_MIN 1U +#define HW_ATL_A0_MAC_MAX 33U + +/* interrupts */ +#define HW_ATL_A0_ERR_INT 8U +#define HW_ATL_A0_INT_MASK 0xFFFFFFFFU + +#define HW_ATL_A0_TXD_CTL2_LEN 0xFFFFC000U +#define HW_ATL_A0_TXD_CTL2_CTX_EN 0x00002000U +#define HW_ATL_A0_TXD_CTL2_CTX_IDX 0x00001000U + +#define HW_ATL_A0_TXD_CTL_DESC_TYPE_TXD 0x00000001U +#define HW_ATL_A0_TXD_CTL_DESC_TYPE_TXC 0x00000002U +#define HW_ATL_A0_TXD_CTL_BLEN 0x000FFFF0U +#define HW_ATL_A0_TXD_CTL_DD 0x00100000U +#define HW_ATL_A0_TXD_CTL_EOP 0x00200000U + +#define HW_ATL_A0_TXD_CTL_CMD_X 0x3FC00000U + +#define HW_ATL_A0_TXD_CTL_CMD_VLAN BIT(22) +#define HW_ATL_A0_TXD_CTL_CMD_FCS BIT(23) +#define HW_ATL_A0_TXD_CTL_CMD_IPCSO BIT(24) +#define HW_ATL_A0_TXD_CTL_CMD_TUCSO BIT(25) +#define HW_ATL_A0_TXD_CTL_CMD_LSO BIT(26) +#define HW_ATL_A0_TXD_CTL_CMD_WB BIT(27) +#define HW_ATL_A0_TXD_CTL_CMD_VXLAN BIT(28) + +#define HW_ATL_A0_TXD_CTL_CMD_IPV6 BIT(21) +#define HW_ATL_A0_TXD_CTL_CMD_TCP BIT(22) + +#define HW_ATL_A0_MPI_CONTROL_ADR 0x0368U +#define HW_ATL_A0_MPI_STATE_ADR 0x036CU + +#define HW_ATL_A0_MPI_SPEED_MSK 0xFFFFU +#define HW_ATL_A0_MPI_SPEED_SHIFT 16U + +#define HW_ATL_A0_RATE_10G BIT(0) +#define HW_ATL_A0_RATE_5G BIT(1) +#define HW_ATL_A0_RATE_2G5 BIT(3) +#define HW_ATL_A0_RATE_1G BIT(4) +#define HW_ATL_A0_RATE_100M BIT(5) + +#define HW_ATL_A0_TXBUF_MAX 160U +#define HW_ATL_A0_RXBUF_MAX 320U + +#define HW_ATL_A0_RSS_REDIRECTION_MAX 64U +#define HW_ATL_A0_RSS_REDIRECTION_BITS 3U + +#define HW_ATL_A0_TC_MAX 1U +#define HW_ATL_A0_RSS_MAX 8U + +#define HW_ATL_A0_FW_SEMA_RAM 0x2U + +#define HW_ATL_A0_RXD_DD 0x1U +#define HW_ATL_A0_RXD_NCEA0 0x1U + +#define HW_ATL_A0_RXD_WB_STAT2_EOP 0x0002U + +#define HW_ATL_A0_UCP_0X370_REG 0x370U + +#define HW_ATL_A0_FW_VER_EXPECTED 0x01050006U + +#define HW_ATL_A0_MIN_RXD \ + (ALIGN(AQ_CFG_SKB_FRAGS_MAX + 1U, AQ_HW_RXD_MULTIPLE)) +#define HW_ATL_A0_MIN_TXD \ + (ALIGN(AQ_CFG_SKB_FRAGS_MAX + 1U, AQ_HW_TXD_MULTIPLE)) + +#define HW_ATL_A0_MAX_RXD 8184U +#define HW_ATL_A0_MAX_TXD 8184U + +#endif /* HW_ATL_A0_INTERNAL_H */ diff --git a/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_b0.c b/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_b0.c new file mode 100644 index 000000000..bdb0b37c0 --- /dev/null +++ b/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_b0.c @@ -0,0 +1,983 @@ +/* + * aQuantia Corporation Network Driver + * Copyright (C) 2014-2017 aQuantia Corporation. All rights reserved + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + */ + +/* File hw_atl_b0.c: Definition of Atlantic hardware specific functions. */ + +#include "../aq_hw.h" +#include "../aq_hw_utils.h" +#include "../aq_ring.h" +#include "../aq_nic.h" +#include "hw_atl_b0.h" +#include "hw_atl_utils.h" +#include "hw_atl_llh.h" +#include "hw_atl_b0_internal.h" +#include "hw_atl_llh_internal.h" + +#define DEFAULT_B0_BOARD_BASIC_CAPABILITIES \ + .is_64_dma = true, \ + .msix_irqs = 4U, \ + .irq_mask = ~0U, \ + .vecs = HW_ATL_B0_RSS_MAX, \ + .tcs = HW_ATL_B0_TC_MAX, \ + .rxd_alignment = 1U, \ + .rxd_size = HW_ATL_B0_RXD_SIZE, \ + .rxds_max = HW_ATL_B0_MAX_RXD, \ + .rxds_min = HW_ATL_B0_MIN_RXD, \ + .txd_alignment = 1U, \ + .txd_size = HW_ATL_B0_TXD_SIZE, \ + .txds_max = HW_ATL_B0_MAX_TXD, \ + .txds_min = HW_ATL_B0_MIN_TXD, \ + .txhwb_alignment = 4096U, \ + .tx_rings = HW_ATL_B0_TX_RINGS, \ + .rx_rings = HW_ATL_B0_RX_RINGS, \ + .hw_features = NETIF_F_HW_CSUM | \ + NETIF_F_RXCSUM | \ + NETIF_F_RXHASH | \ + NETIF_F_SG | \ + NETIF_F_TSO | \ + NETIF_F_LRO, \ + .hw_priv_flags = IFF_UNICAST_FLT, \ + .flow_control = true, \ + .mtu = HW_ATL_B0_MTU_JUMBO, \ + .mac_regs_count = 88, \ + .hw_alive_check_addr = 0x10U + +const struct aq_hw_caps_s hw_atl_b0_caps_aqc100 = { + DEFAULT_B0_BOARD_BASIC_CAPABILITIES, + .media_type = AQ_HW_MEDIA_TYPE_FIBRE, + .link_speed_msk = HW_ATL_B0_RATE_10G | + HW_ATL_B0_RATE_5G | + HW_ATL_B0_RATE_2G5 | + HW_ATL_B0_RATE_1G | + HW_ATL_B0_RATE_100M, +}; + +const struct aq_hw_caps_s hw_atl_b0_caps_aqc107 = { + DEFAULT_B0_BOARD_BASIC_CAPABILITIES, + .media_type = AQ_HW_MEDIA_TYPE_TP, + .link_speed_msk = HW_ATL_B0_RATE_10G | + HW_ATL_B0_RATE_5G | + HW_ATL_B0_RATE_2G5 | + HW_ATL_B0_RATE_1G | + HW_ATL_B0_RATE_100M, +}; + +const struct aq_hw_caps_s hw_atl_b0_caps_aqc108 = { + DEFAULT_B0_BOARD_BASIC_CAPABILITIES, + .media_type = AQ_HW_MEDIA_TYPE_TP, + .link_speed_msk = HW_ATL_B0_RATE_5G | + HW_ATL_B0_RATE_2G5 | + HW_ATL_B0_RATE_1G | + HW_ATL_B0_RATE_100M, +}; + +const struct aq_hw_caps_s hw_atl_b0_caps_aqc109 = { + DEFAULT_B0_BOARD_BASIC_CAPABILITIES, + .media_type = AQ_HW_MEDIA_TYPE_TP, + .link_speed_msk = HW_ATL_B0_RATE_2G5 | + HW_ATL_B0_RATE_1G | + HW_ATL_B0_RATE_100M, +}; + +static int hw_atl_b0_hw_reset(struct aq_hw_s *self) +{ + int err = 0; + + err = hw_atl_utils_soft_reset(self); + if (err) + return err; + + self->aq_fw_ops->set_state(self, MPI_RESET); + + err = aq_hw_err_from_flags(self); + + return err; +} + +static int hw_atl_b0_hw_qos_set(struct aq_hw_s *self) +{ + u32 tc = 0U; + u32 buff_size = 0U; + unsigned int i_priority = 0U; + bool is_rx_flow_control = false; + + /* TPS Descriptor rate init */ + hw_atl_tps_tx_pkt_shed_desc_rate_curr_time_res_set(self, 0x0U); + hw_atl_tps_tx_pkt_shed_desc_rate_lim_set(self, 0xA); + + /* TPS VM init */ + hw_atl_tps_tx_pkt_shed_desc_vm_arb_mode_set(self, 0U); + + /* TPS TC credits init */ + hw_atl_tps_tx_pkt_shed_desc_tc_arb_mode_set(self, 0U); + hw_atl_tps_tx_pkt_shed_data_arb_mode_set(self, 0U); + + hw_atl_tps_tx_pkt_shed_tc_data_max_credit_set(self, 0xFFF, 0U); + hw_atl_tps_tx_pkt_shed_tc_data_weight_set(self, 0x64, 0U); + hw_atl_tps_tx_pkt_shed_desc_tc_max_credit_set(self, 0x50, 0U); + hw_atl_tps_tx_pkt_shed_desc_tc_weight_set(self, 0x1E, 0U); + + /* Tx buf size */ + buff_size = HW_ATL_B0_TXBUF_MAX; + + hw_atl_tpb_tx_pkt_buff_size_per_tc_set(self, buff_size, tc); + hw_atl_tpb_tx_buff_hi_threshold_per_tc_set(self, + (buff_size * + (1024 / 32U) * 66U) / + 100U, tc); + hw_atl_tpb_tx_buff_lo_threshold_per_tc_set(self, + (buff_size * + (1024 / 32U) * 50U) / + 100U, tc); + + /* QoS Rx buf size per TC */ + tc = 0; + is_rx_flow_control = (AQ_NIC_FC_RX & self->aq_nic_cfg->flow_control); + buff_size = HW_ATL_B0_RXBUF_MAX; + + hw_atl_rpb_rx_pkt_buff_size_per_tc_set(self, buff_size, tc); + hw_atl_rpb_rx_buff_hi_threshold_per_tc_set(self, + (buff_size * + (1024U / 32U) * 66U) / + 100U, tc); + hw_atl_rpb_rx_buff_lo_threshold_per_tc_set(self, + (buff_size * + (1024U / 32U) * 50U) / + 100U, tc); + hw_atl_rpb_rx_xoff_en_per_tc_set(self, is_rx_flow_control ? 1U : 0U, tc); + + /* QoS 802.1p priority -> TC mapping */ + for (i_priority = 8U; i_priority--;) + hw_atl_rpf_rpb_user_priority_tc_map_set(self, i_priority, 0U); + + return aq_hw_err_from_flags(self); +} + +static int hw_atl_b0_hw_rss_hash_set(struct aq_hw_s *self, + struct aq_rss_parameters *rss_params) +{ + struct aq_nic_cfg_s *cfg = self->aq_nic_cfg; + int err = 0; + unsigned int i = 0U; + unsigned int addr = 0U; + + for (i = 10, addr = 0U; i--; ++addr) { + u32 key_data = cfg->is_rss ? + __swab32(rss_params->hash_secret_key[i]) : 0U; + hw_atl_rpf_rss_key_wr_data_set(self, key_data); + hw_atl_rpf_rss_key_addr_set(self, addr); + hw_atl_rpf_rss_key_wr_en_set(self, 1U); + AQ_HW_WAIT_FOR(hw_atl_rpf_rss_key_wr_en_get(self) == 0, + 1000U, 10U); + if (err < 0) + goto err_exit; + } + + err = aq_hw_err_from_flags(self); + +err_exit: + return err; +} + +static int hw_atl_b0_hw_rss_set(struct aq_hw_s *self, + struct aq_rss_parameters *rss_params) +{ + u8 *indirection_table = rss_params->indirection_table; + u32 i = 0U; + u32 num_rss_queues = max(1U, self->aq_nic_cfg->num_rss_queues); + int err = 0; + u16 bitary[1 + (HW_ATL_B0_RSS_REDIRECTION_MAX * + HW_ATL_B0_RSS_REDIRECTION_BITS / 16U)]; + + memset(bitary, 0, sizeof(bitary)); + + for (i = HW_ATL_B0_RSS_REDIRECTION_MAX; i--;) { + (*(u32 *)(bitary + ((i * 3U) / 16U))) |= + ((indirection_table[i] % num_rss_queues) << + ((i * 3U) & 0xFU)); + } + + for (i = ARRAY_SIZE(bitary); i--;) { + hw_atl_rpf_rss_redir_tbl_wr_data_set(self, bitary[i]); + hw_atl_rpf_rss_redir_tbl_addr_set(self, i); + hw_atl_rpf_rss_redir_wr_en_set(self, 1U); + AQ_HW_WAIT_FOR(hw_atl_rpf_rss_redir_wr_en_get(self) == 0, + 1000U, 10U); + if (err < 0) + goto err_exit; + } + + err = aq_hw_err_from_flags(self); + +err_exit: + return err; +} + +static int hw_atl_b0_hw_offload_set(struct aq_hw_s *self, + struct aq_nic_cfg_s *aq_nic_cfg) +{ + unsigned int i; + + /* TX checksums offloads*/ + hw_atl_tpo_ipv4header_crc_offload_en_set(self, 1); + hw_atl_tpo_tcp_udp_crc_offload_en_set(self, 1); + + /* RX checksums offloads*/ + hw_atl_rpo_ipv4header_crc_offload_en_set(self, 1); + hw_atl_rpo_tcp_udp_crc_offload_en_set(self, 1); + + /* LSO offloads*/ + hw_atl_tdm_large_send_offload_en_set(self, 0xFFFFFFFFU); + +/* LRO offloads */ + { + unsigned int val = (8U < HW_ATL_B0_LRO_RXD_MAX) ? 0x3U : + ((4U < HW_ATL_B0_LRO_RXD_MAX) ? 0x2U : + ((2U < HW_ATL_B0_LRO_RXD_MAX) ? 0x1U : 0x0)); + + for (i = 0; i < HW_ATL_B0_RINGS_MAX; i++) + hw_atl_rpo_lro_max_num_of_descriptors_set(self, val, i); + + hw_atl_rpo_lro_time_base_divider_set(self, 0x61AU); + hw_atl_rpo_lro_inactive_interval_set(self, 0); + hw_atl_rpo_lro_max_coalescing_interval_set(self, 2); + + hw_atl_rpo_lro_qsessions_lim_set(self, 1U); + + hw_atl_rpo_lro_total_desc_lim_set(self, 2U); + + hw_atl_rpo_lro_patch_optimization_en_set(self, 0U); + + hw_atl_rpo_lro_min_pay_of_first_pkt_set(self, 10U); + + hw_atl_rpo_lro_pkt_lim_set(self, 1U); + + hw_atl_rpo_lro_en_set(self, + aq_nic_cfg->is_lro ? 0xFFFFFFFFU : 0U); + } + return aq_hw_err_from_flags(self); +} + +static int hw_atl_b0_hw_init_tx_path(struct aq_hw_s *self) +{ + hw_atl_thm_lso_tcp_flag_of_first_pkt_set(self, 0x0FF6U); + hw_atl_thm_lso_tcp_flag_of_middle_pkt_set(self, 0x0FF6U); + hw_atl_thm_lso_tcp_flag_of_last_pkt_set(self, 0x0F7FU); + + /* Tx interrupts */ + hw_atl_tdm_tx_desc_wr_wb_irq_en_set(self, 1U); + + /* misc */ + aq_hw_write_reg(self, 0x00007040U, IS_CHIP_FEATURE(TPO2) ? + 0x00010000U : 0x00000000U); + hw_atl_tdm_tx_dca_en_set(self, 0U); + hw_atl_tdm_tx_dca_mode_set(self, 0U); + + hw_atl_tpb_tx_path_scp_ins_en_set(self, 1U); + + return aq_hw_err_from_flags(self); +} + +static int hw_atl_b0_hw_init_rx_path(struct aq_hw_s *self) +{ + struct aq_nic_cfg_s *cfg = self->aq_nic_cfg; + int i; + + /* Rx TC/RSS number config */ + hw_atl_rpb_rpf_rx_traf_class_mode_set(self, 1U); + + /* Rx flow control */ + hw_atl_rpb_rx_flow_ctl_mode_set(self, 1U); + + /* RSS Ring selection */ + hw_atl_reg_rx_flr_rss_control1set(self, cfg->is_rss ? + 0xB3333333U : 0x00000000U); + + /* Multicast filters */ + for (i = HW_ATL_B0_MAC_MAX; i--;) { + hw_atl_rpfl2_uc_flr_en_set(self, (i == 0U) ? 1U : 0U, i); + hw_atl_rpfl2unicast_flr_act_set(self, 1U, i); + } + + hw_atl_reg_rx_flr_mcst_flr_msk_set(self, 0x00000000U); + hw_atl_reg_rx_flr_mcst_flr_set(self, 0x00010FFFU, 0U); + + /* Vlan filters */ + hw_atl_rpf_vlan_outer_etht_set(self, 0x88A8U); + hw_atl_rpf_vlan_inner_etht_set(self, 0x8100U); + + if (cfg->vlan_id) { + hw_atl_rpf_vlan_flr_act_set(self, 1U, 0U); + hw_atl_rpf_vlan_id_flr_set(self, 0U, 0U); + hw_atl_rpf_vlan_flr_en_set(self, 0U, 0U); + + hw_atl_rpf_vlan_accept_untagged_packets_set(self, 1U); + hw_atl_rpf_vlan_untagged_act_set(self, 1U); + + hw_atl_rpf_vlan_flr_act_set(self, 1U, 1U); + hw_atl_rpf_vlan_id_flr_set(self, cfg->vlan_id, 0U); + hw_atl_rpf_vlan_flr_en_set(self, 1U, 1U); + } else { + hw_atl_rpf_vlan_prom_mode_en_set(self, 1); + } + + /* Rx Interrupts */ + hw_atl_rdm_rx_desc_wr_wb_irq_en_set(self, 1U); + + /* misc */ + aq_hw_write_reg(self, 0x00005040U, + IS_CHIP_FEATURE(RPF2) ? 0x000F0000U : 0x00000000U); + + hw_atl_rpfl2broadcast_flr_act_set(self, 1U); + hw_atl_rpfl2broadcast_count_threshold_set(self, 0xFFFFU & (~0U / 256U)); + + hw_atl_rdm_rx_dca_en_set(self, 0U); + hw_atl_rdm_rx_dca_mode_set(self, 0U); + + return aq_hw_err_from_flags(self); +} + +static int hw_atl_b0_hw_mac_addr_set(struct aq_hw_s *self, u8 *mac_addr) +{ + int err = 0; + unsigned int h = 0U; + unsigned int l = 0U; + + if (!mac_addr) { + err = -EINVAL; + goto err_exit; + } + h = (mac_addr[0] << 8) | (mac_addr[1]); + l = (mac_addr[2] << 24) | (mac_addr[3] << 16) | + (mac_addr[4] << 8) | mac_addr[5]; + + hw_atl_rpfl2_uc_flr_en_set(self, 0U, HW_ATL_B0_MAC); + hw_atl_rpfl2unicast_dest_addresslsw_set(self, l, HW_ATL_B0_MAC); + hw_atl_rpfl2unicast_dest_addressmsw_set(self, h, HW_ATL_B0_MAC); + hw_atl_rpfl2_uc_flr_en_set(self, 1U, HW_ATL_B0_MAC); + + err = aq_hw_err_from_flags(self); + +err_exit: + return err; +} + +static int hw_atl_b0_hw_init(struct aq_hw_s *self, u8 *mac_addr) +{ + static u32 aq_hw_atl_igcr_table_[4][2] = { + { 0x20000000U, 0x20000000U }, /* AQ_IRQ_INVALID */ + { 0x20000080U, 0x20000080U }, /* AQ_IRQ_LEGACY */ + { 0x20000021U, 0x20000025U }, /* AQ_IRQ_MSI */ + { 0x20000022U, 0x20000026U } /* AQ_IRQ_MSIX */ + }; + + int err = 0; + u32 val; + + struct aq_nic_cfg_s *aq_nic_cfg = self->aq_nic_cfg; + + hw_atl_b0_hw_init_tx_path(self); + hw_atl_b0_hw_init_rx_path(self); + + hw_atl_b0_hw_mac_addr_set(self, mac_addr); + + self->aq_fw_ops->set_link_speed(self, aq_nic_cfg->link_speed_msk); + self->aq_fw_ops->set_state(self, MPI_INIT); + + hw_atl_b0_hw_qos_set(self); + hw_atl_b0_hw_rss_set(self, &aq_nic_cfg->aq_rss); + hw_atl_b0_hw_rss_hash_set(self, &aq_nic_cfg->aq_rss); + + /* Force limit MRRS on RDM/TDM to 2K */ + val = aq_hw_read_reg(self, HW_ATL_PCI_REG_CONTROL6_ADR); + aq_hw_write_reg(self, HW_ATL_PCI_REG_CONTROL6_ADR, + (val & ~0x707) | 0x404); + + /* TX DMA total request limit. B0 hardware is not capable to + * handle more than (8K-MRRS) incoming DMA data. + * Value 24 in 256byte units + */ + aq_hw_write_reg(self, HW_ATL_TX_DMA_TOTAL_REQ_LIMIT_ADR, 24); + + /* Reset link status and read out initial hardware counters */ + self->aq_link_status.mbps = 0; + self->aq_fw_ops->update_stats(self); + + err = aq_hw_err_from_flags(self); + if (err < 0) + goto err_exit; + + /* Interrupts */ + hw_atl_reg_irq_glb_ctl_set(self, + aq_hw_atl_igcr_table_[aq_nic_cfg->irq_type] + [(aq_nic_cfg->vecs > 1U) ? + 1 : 0]); + + hw_atl_itr_irq_auto_masklsw_set(self, aq_nic_cfg->aq_hw_caps->irq_mask); + + /* Interrupts */ + hw_atl_reg_gen_irq_map_set(self, + ((HW_ATL_B0_ERR_INT << 0x18) | (1U << 0x1F)) | + ((HW_ATL_B0_ERR_INT << 0x10) | (1U << 0x17)), 0U); + + hw_atl_b0_hw_offload_set(self, aq_nic_cfg); + +err_exit: + return err; +} + +static int hw_atl_b0_hw_ring_tx_start(struct aq_hw_s *self, + struct aq_ring_s *ring) +{ + hw_atl_tdm_tx_desc_en_set(self, 1, ring->idx); + return aq_hw_err_from_flags(self); +} + +static int hw_atl_b0_hw_ring_rx_start(struct aq_hw_s *self, + struct aq_ring_s *ring) +{ + hw_atl_rdm_rx_desc_en_set(self, 1, ring->idx); + return aq_hw_err_from_flags(self); +} + +static int hw_atl_b0_hw_start(struct aq_hw_s *self) +{ + hw_atl_tpb_tx_buff_en_set(self, 1); + hw_atl_rpb_rx_buff_en_set(self, 1); + return aq_hw_err_from_flags(self); +} + +static int hw_atl_b0_hw_tx_ring_tail_update(struct aq_hw_s *self, + struct aq_ring_s *ring) +{ + hw_atl_reg_tx_dma_desc_tail_ptr_set(self, ring->sw_tail, ring->idx); + return 0; +} + +static int hw_atl_b0_hw_ring_tx_xmit(struct aq_hw_s *self, + struct aq_ring_s *ring, + unsigned int frags) +{ + struct aq_ring_buff_s *buff = NULL; + struct hw_atl_txd_s *txd = NULL; + unsigned int buff_pa_len = 0U; + unsigned int pkt_len = 0U; + unsigned int frag_count = 0U; + bool is_gso = false; + + buff = &ring->buff_ring[ring->sw_tail]; + pkt_len = (buff->is_eop && buff->is_sop) ? buff->len : buff->len_pkt; + + for (frag_count = 0; frag_count < frags; frag_count++) { + txd = (struct hw_atl_txd_s *)&ring->dx_ring[ring->sw_tail * + HW_ATL_B0_TXD_SIZE]; + txd->ctl = 0; + txd->ctl2 = 0; + txd->buf_addr = 0; + + buff = &ring->buff_ring[ring->sw_tail]; + + if (buff->is_txc) { + txd->ctl |= (buff->len_l3 << 31) | + (buff->len_l2 << 24) | + HW_ATL_B0_TXD_CTL_CMD_TCP | + HW_ATL_B0_TXD_CTL_DESC_TYPE_TXC; + txd->ctl2 |= (buff->mss << 16) | + (buff->len_l4 << 8) | + (buff->len_l3 >> 1); + + pkt_len -= (buff->len_l4 + + buff->len_l3 + + buff->len_l2); + is_gso = true; + + if (buff->is_ipv6) + txd->ctl |= HW_ATL_B0_TXD_CTL_CMD_IPV6; + } else { + buff_pa_len = buff->len; + + txd->buf_addr = buff->pa; + txd->ctl |= (HW_ATL_B0_TXD_CTL_BLEN & + ((u32)buff_pa_len << 4)); + txd->ctl |= HW_ATL_B0_TXD_CTL_DESC_TYPE_TXD; + /* PAY_LEN */ + txd->ctl2 |= HW_ATL_B0_TXD_CTL2_LEN & (pkt_len << 14); + + if (is_gso) { + txd->ctl |= HW_ATL_B0_TXD_CTL_CMD_LSO; + txd->ctl2 |= HW_ATL_B0_TXD_CTL2_CTX_EN; + } + + /* Tx checksum offloads */ + if (buff->is_ip_cso) + txd->ctl |= HW_ATL_B0_TXD_CTL_CMD_IPCSO; + + if (buff->is_udp_cso || buff->is_tcp_cso) + txd->ctl |= HW_ATL_B0_TXD_CTL_CMD_TUCSO; + + if (unlikely(buff->is_eop)) { + txd->ctl |= HW_ATL_B0_TXD_CTL_EOP; + txd->ctl |= HW_ATL_B0_TXD_CTL_CMD_WB; + is_gso = false; + } + } + + ring->sw_tail = aq_ring_next_dx(ring, ring->sw_tail); + } + + hw_atl_b0_hw_tx_ring_tail_update(self, ring); + return aq_hw_err_from_flags(self); +} + +static int hw_atl_b0_hw_ring_rx_init(struct aq_hw_s *self, + struct aq_ring_s *aq_ring, + struct aq_ring_param_s *aq_ring_param) +{ + u32 dma_desc_addr_lsw = (u32)aq_ring->dx_ring_pa; + u32 dma_desc_addr_msw = (u32)(((u64)aq_ring->dx_ring_pa) >> 32); + + hw_atl_rdm_rx_desc_en_set(self, false, aq_ring->idx); + + hw_atl_rdm_rx_desc_head_splitting_set(self, 0U, aq_ring->idx); + + hw_atl_reg_rx_dma_desc_base_addresslswset(self, dma_desc_addr_lsw, + aq_ring->idx); + + hw_atl_reg_rx_dma_desc_base_addressmswset(self, + dma_desc_addr_msw, aq_ring->idx); + + hw_atl_rdm_rx_desc_len_set(self, aq_ring->size / 8U, aq_ring->idx); + + hw_atl_rdm_rx_desc_data_buff_size_set(self, + AQ_CFG_RX_FRAME_MAX / 1024U, + aq_ring->idx); + + hw_atl_rdm_rx_desc_head_buff_size_set(self, 0U, aq_ring->idx); + hw_atl_rdm_rx_desc_head_splitting_set(self, 0U, aq_ring->idx); + hw_atl_rpo_rx_desc_vlan_stripping_set(self, 0U, aq_ring->idx); + + /* Rx ring set mode */ + + /* Mapping interrupt vector */ + hw_atl_itr_irq_map_rx_set(self, aq_ring_param->vec_idx, aq_ring->idx); + hw_atl_itr_irq_map_en_rx_set(self, true, aq_ring->idx); + + hw_atl_rdm_cpu_id_set(self, aq_ring_param->cpu, aq_ring->idx); + hw_atl_rdm_rx_desc_dca_en_set(self, 0U, aq_ring->idx); + hw_atl_rdm_rx_head_dca_en_set(self, 0U, aq_ring->idx); + hw_atl_rdm_rx_pld_dca_en_set(self, 0U, aq_ring->idx); + + return aq_hw_err_from_flags(self); +} + +static int hw_atl_b0_hw_ring_tx_init(struct aq_hw_s *self, + struct aq_ring_s *aq_ring, + struct aq_ring_param_s *aq_ring_param) +{ + u32 dma_desc_lsw_addr = (u32)aq_ring->dx_ring_pa; + u32 dma_desc_msw_addr = (u32)(((u64)aq_ring->dx_ring_pa) >> 32); + + hw_atl_reg_tx_dma_desc_base_addresslswset(self, dma_desc_lsw_addr, + aq_ring->idx); + + hw_atl_reg_tx_dma_desc_base_addressmswset(self, dma_desc_msw_addr, + aq_ring->idx); + + hw_atl_tdm_tx_desc_len_set(self, aq_ring->size / 8U, aq_ring->idx); + + hw_atl_b0_hw_tx_ring_tail_update(self, aq_ring); + + /* Set Tx threshold */ + hw_atl_tdm_tx_desc_wr_wb_threshold_set(self, 0U, aq_ring->idx); + + /* Mapping interrupt vector */ + hw_atl_itr_irq_map_tx_set(self, aq_ring_param->vec_idx, aq_ring->idx); + hw_atl_itr_irq_map_en_tx_set(self, true, aq_ring->idx); + + hw_atl_tdm_cpu_id_set(self, aq_ring_param->cpu, aq_ring->idx); + hw_atl_tdm_tx_desc_dca_en_set(self, 0U, aq_ring->idx); + + return aq_hw_err_from_flags(self); +} + +static int hw_atl_b0_hw_ring_rx_fill(struct aq_hw_s *self, + struct aq_ring_s *ring, + unsigned int sw_tail_old) +{ + for (; sw_tail_old != ring->sw_tail; + sw_tail_old = aq_ring_next_dx(ring, sw_tail_old)) { + struct hw_atl_rxd_s *rxd = + (struct hw_atl_rxd_s *)&ring->dx_ring[sw_tail_old * + HW_ATL_B0_RXD_SIZE]; + + struct aq_ring_buff_s *buff = &ring->buff_ring[sw_tail_old]; + + rxd->buf_addr = buff->pa; + rxd->hdr_addr = 0U; + } + + hw_atl_reg_rx_dma_desc_tail_ptr_set(self, sw_tail_old, ring->idx); + + return aq_hw_err_from_flags(self); +} + +static int hw_atl_b0_hw_ring_tx_head_update(struct aq_hw_s *self, + struct aq_ring_s *ring) +{ + int err = 0; + unsigned int hw_head_ = hw_atl_tdm_tx_desc_head_ptr_get(self, ring->idx); + + if (aq_utils_obj_test(&self->flags, AQ_HW_FLAG_ERR_UNPLUG)) { + err = -ENXIO; + goto err_exit; + } + + /* Validate that the new hw_head_ is reasonable. */ + if (hw_head_ >= ring->size) { + err = -ENXIO; + goto err_exit; + } + + ring->hw_head = hw_head_; + err = aq_hw_err_from_flags(self); + +err_exit: + return err; +} + +static int hw_atl_b0_hw_ring_rx_receive(struct aq_hw_s *self, + struct aq_ring_s *ring) +{ + struct device *ndev = aq_nic_get_dev(ring->aq_nic); + + for (; ring->hw_head != ring->sw_tail; + ring->hw_head = aq_ring_next_dx(ring, ring->hw_head)) { + struct aq_ring_buff_s *buff = NULL; + struct hw_atl_rxd_wb_s *rxd_wb = (struct hw_atl_rxd_wb_s *) + &ring->dx_ring[ring->hw_head * HW_ATL_B0_RXD_SIZE]; + + unsigned int is_rx_check_sum_enabled = 0U; + unsigned int pkt_type = 0U; + u8 rx_stat = 0U; + + if (!(rxd_wb->status & 0x1U)) { /* RxD is not done */ + break; + } + + buff = &ring->buff_ring[ring->hw_head]; + + rx_stat = (0x0000003CU & rxd_wb->status) >> 2; + + is_rx_check_sum_enabled = (rxd_wb->type >> 19) & 0x3U; + + pkt_type = 0xFFU & (rxd_wb->type >> 4); + + if (is_rx_check_sum_enabled & BIT(0) && + (0x0U == (pkt_type & 0x3U))) + buff->is_ip_cso = (rx_stat & BIT(1)) ? 0U : 1U; + + if (is_rx_check_sum_enabled & BIT(1)) { + if (0x4U == (pkt_type & 0x1CU)) + buff->is_udp_cso = (rx_stat & BIT(2)) ? 0U : + !!(rx_stat & BIT(3)); + else if (0x0U == (pkt_type & 0x1CU)) + buff->is_tcp_cso = (rx_stat & BIT(2)) ? 0U : + !!(rx_stat & BIT(3)); + } + buff->is_cso_err = !!(rx_stat & 0x6); + /* Checksum offload workaround for small packets */ + if (unlikely(rxd_wb->pkt_len <= 60)) { + buff->is_ip_cso = 0U; + buff->is_cso_err = 0U; + } + + dma_unmap_page(ndev, buff->pa, buff->len, DMA_FROM_DEVICE); + + if ((rx_stat & BIT(0)) || rxd_wb->type & 0x1000U) { + /* MAC error or DMA error */ + buff->is_error = 1U; + } + if (self->aq_nic_cfg->is_rss) { + /* last 4 byte */ + u16 rss_type = rxd_wb->type & 0xFU; + + if (rss_type && rss_type < 0x8U) { + buff->is_hash_l4 = (rss_type == 0x4 || + rss_type == 0x5); + buff->rss_hash = rxd_wb->rss_hash; + } + } + + if (HW_ATL_B0_RXD_WB_STAT2_EOP & rxd_wb->status) { + buff->len = rxd_wb->pkt_len % + AQ_CFG_RX_FRAME_MAX; + buff->len = buff->len ? + buff->len : AQ_CFG_RX_FRAME_MAX; + buff->next = 0U; + buff->is_eop = 1U; + } else { + buff->len = + rxd_wb->pkt_len > AQ_CFG_RX_FRAME_MAX ? + AQ_CFG_RX_FRAME_MAX : rxd_wb->pkt_len; + + if (HW_ATL_B0_RXD_WB_STAT2_RSCCNT & + rxd_wb->status) { + /* LRO */ + buff->next = rxd_wb->next_desc_ptr; + ++ring->stats.rx.lro_packets; + } else { + /* jumbo */ + buff->next = + aq_ring_next_dx(ring, + ring->hw_head); + ++ring->stats.rx.jumbo_packets; + } + } + } + + return aq_hw_err_from_flags(self); +} + +static int hw_atl_b0_hw_irq_enable(struct aq_hw_s *self, u64 mask) +{ + hw_atl_itr_irq_msk_setlsw_set(self, LODWORD(mask)); + return aq_hw_err_from_flags(self); +} + +static int hw_atl_b0_hw_irq_disable(struct aq_hw_s *self, u64 mask) +{ + hw_atl_itr_irq_msk_clearlsw_set(self, LODWORD(mask)); + hw_atl_itr_irq_status_clearlsw_set(self, LODWORD(mask)); + + atomic_inc(&self->dpc); + return aq_hw_err_from_flags(self); +} + +static int hw_atl_b0_hw_irq_read(struct aq_hw_s *self, u64 *mask) +{ + *mask = hw_atl_itr_irq_statuslsw_get(self); + return aq_hw_err_from_flags(self); +} + +#define IS_FILTER_ENABLED(_F_) ((packet_filter & (_F_)) ? 1U : 0U) + +static int hw_atl_b0_hw_packet_filter_set(struct aq_hw_s *self, + unsigned int packet_filter) +{ + unsigned int i = 0U; + + hw_atl_rpfl2promiscuous_mode_en_set(self, IS_FILTER_ENABLED(IFF_PROMISC)); + hw_atl_rpfl2multicast_flr_en_set(self, + IS_FILTER_ENABLED(IFF_ALLMULTI), 0); + + hw_atl_rpfl2_accept_all_mc_packets_set(self, + IS_FILTER_ENABLED(IFF_ALLMULTI)); + + hw_atl_rpfl2broadcast_en_set(self, IS_FILTER_ENABLED(IFF_BROADCAST)); + + self->aq_nic_cfg->is_mc_list_enabled = IS_FILTER_ENABLED(IFF_MULTICAST); + + for (i = HW_ATL_B0_MAC_MIN; i < HW_ATL_B0_MAC_MAX; ++i) + hw_atl_rpfl2_uc_flr_en_set(self, + (self->aq_nic_cfg->is_mc_list_enabled && + (i <= self->aq_nic_cfg->mc_list_count)) ? + 1U : 0U, i); + + return aq_hw_err_from_flags(self); +} + +#undef IS_FILTER_ENABLED + +static int hw_atl_b0_hw_multicast_list_set(struct aq_hw_s *self, + u8 ar_mac + [AQ_HW_MULTICAST_ADDRESS_MAX] + [ETH_ALEN], + u32 count) +{ + int err = 0; + + if (count > (HW_ATL_B0_MAC_MAX - HW_ATL_B0_MAC_MIN)) { + err = -EBADRQC; + goto err_exit; + } + for (self->aq_nic_cfg->mc_list_count = 0U; + self->aq_nic_cfg->mc_list_count < count; + ++self->aq_nic_cfg->mc_list_count) { + u32 i = self->aq_nic_cfg->mc_list_count; + u32 h = (ar_mac[i][0] << 8) | (ar_mac[i][1]); + u32 l = (ar_mac[i][2] << 24) | (ar_mac[i][3] << 16) | + (ar_mac[i][4] << 8) | ar_mac[i][5]; + + hw_atl_rpfl2_uc_flr_en_set(self, 0U, HW_ATL_B0_MAC_MIN + i); + + hw_atl_rpfl2unicast_dest_addresslsw_set(self, + l, HW_ATL_B0_MAC_MIN + i); + + hw_atl_rpfl2unicast_dest_addressmsw_set(self, + h, HW_ATL_B0_MAC_MIN + i); + + hw_atl_rpfl2_uc_flr_en_set(self, + (self->aq_nic_cfg->is_mc_list_enabled), + HW_ATL_B0_MAC_MIN + i); + } + + err = aq_hw_err_from_flags(self); + +err_exit: + return err; +} + +static int hw_atl_b0_hw_interrupt_moderation_set(struct aq_hw_s *self) +{ + unsigned int i = 0U; + u32 itr_tx = 2U; + u32 itr_rx = 2U; + + switch (self->aq_nic_cfg->itr) { + case AQ_CFG_INTERRUPT_MODERATION_ON: + case AQ_CFG_INTERRUPT_MODERATION_AUTO: + hw_atl_tdm_tx_desc_wr_wb_irq_en_set(self, 0U); + hw_atl_tdm_tdm_intr_moder_en_set(self, 1U); + hw_atl_rdm_rx_desc_wr_wb_irq_en_set(self, 0U); + hw_atl_rdm_rdm_intr_moder_en_set(self, 1U); + + if (self->aq_nic_cfg->itr == AQ_CFG_INTERRUPT_MODERATION_ON) { + /* HW timers are in 2us units */ + int tx_max_timer = self->aq_nic_cfg->tx_itr / 2; + int tx_min_timer = tx_max_timer / 2; + + int rx_max_timer = self->aq_nic_cfg->rx_itr / 2; + int rx_min_timer = rx_max_timer / 2; + + tx_max_timer = min(HW_ATL_INTR_MODER_MAX, tx_max_timer); + tx_min_timer = min(HW_ATL_INTR_MODER_MIN, tx_min_timer); + rx_max_timer = min(HW_ATL_INTR_MODER_MAX, rx_max_timer); + rx_min_timer = min(HW_ATL_INTR_MODER_MIN, rx_min_timer); + + itr_tx |= tx_min_timer << 0x8U; + itr_tx |= tx_max_timer << 0x10U; + itr_rx |= rx_min_timer << 0x8U; + itr_rx |= rx_max_timer << 0x10U; + } else { + static unsigned int hw_atl_b0_timers_table_tx_[][2] = { + {0xfU, 0xffU}, /* 10Gbit */ + {0xfU, 0x1ffU}, /* 5Gbit */ + {0xfU, 0x1ffU}, /* 5Gbit 5GS */ + {0xfU, 0x1ffU}, /* 2.5Gbit */ + {0xfU, 0x1ffU}, /* 1Gbit */ + {0xfU, 0x1ffU}, /* 100Mbit */ + }; + + static unsigned int hw_atl_b0_timers_table_rx_[][2] = { + {0x6U, 0x38U},/* 10Gbit */ + {0xCU, 0x70U},/* 5Gbit */ + {0xCU, 0x70U},/* 5Gbit 5GS */ + {0x18U, 0xE0U},/* 2.5Gbit */ + {0x30U, 0x80U},/* 1Gbit */ + {0x4U, 0x50U},/* 100Mbit */ + }; + + unsigned int speed_index = + hw_atl_utils_mbps_2_speed_index( + self->aq_link_status.mbps); + + /* Update user visible ITR settings */ + self->aq_nic_cfg->tx_itr = hw_atl_b0_timers_table_tx_ + [speed_index][1] * 2; + self->aq_nic_cfg->rx_itr = hw_atl_b0_timers_table_rx_ + [speed_index][1] * 2; + + itr_tx |= hw_atl_b0_timers_table_tx_ + [speed_index][0] << 0x8U; + itr_tx |= hw_atl_b0_timers_table_tx_ + [speed_index][1] << 0x10U; + + itr_rx |= hw_atl_b0_timers_table_rx_ + [speed_index][0] << 0x8U; + itr_rx |= hw_atl_b0_timers_table_rx_ + [speed_index][1] << 0x10U; + } + break; + case AQ_CFG_INTERRUPT_MODERATION_OFF: + hw_atl_tdm_tx_desc_wr_wb_irq_en_set(self, 1U); + hw_atl_tdm_tdm_intr_moder_en_set(self, 0U); + hw_atl_rdm_rx_desc_wr_wb_irq_en_set(self, 1U); + hw_atl_rdm_rdm_intr_moder_en_set(self, 0U); + itr_tx = 0U; + itr_rx = 0U; + break; + } + + for (i = HW_ATL_B0_RINGS_MAX; i--;) { + hw_atl_reg_tx_intr_moder_ctrl_set(self, itr_tx, i); + hw_atl_reg_rx_intr_moder_ctrl_set(self, itr_rx, i); + } + + return aq_hw_err_from_flags(self); +} + +static int hw_atl_b0_hw_stop(struct aq_hw_s *self) +{ + hw_atl_b0_hw_irq_disable(self, HW_ATL_B0_INT_MASK); + + /* Invalidate Descriptor Cache to prevent writing to the cached + * descriptors and to the data pointer of those descriptors + */ + hw_atl_rdm_rx_dma_desc_cache_init_set(self, 1); + + return aq_hw_err_from_flags(self); +} + +static int hw_atl_b0_hw_ring_tx_stop(struct aq_hw_s *self, + struct aq_ring_s *ring) +{ + hw_atl_tdm_tx_desc_en_set(self, 0U, ring->idx); + return aq_hw_err_from_flags(self); +} + +static int hw_atl_b0_hw_ring_rx_stop(struct aq_hw_s *self, + struct aq_ring_s *ring) +{ + hw_atl_rdm_rx_desc_en_set(self, 0U, ring->idx); + return aq_hw_err_from_flags(self); +} + +const struct aq_hw_ops hw_atl_ops_b0 = { + .hw_set_mac_address = hw_atl_b0_hw_mac_addr_set, + .hw_init = hw_atl_b0_hw_init, + .hw_set_power = hw_atl_utils_hw_set_power, + .hw_reset = hw_atl_b0_hw_reset, + .hw_start = hw_atl_b0_hw_start, + .hw_ring_tx_start = hw_atl_b0_hw_ring_tx_start, + .hw_ring_tx_stop = hw_atl_b0_hw_ring_tx_stop, + .hw_ring_rx_start = hw_atl_b0_hw_ring_rx_start, + .hw_ring_rx_stop = hw_atl_b0_hw_ring_rx_stop, + .hw_stop = hw_atl_b0_hw_stop, + + .hw_ring_tx_xmit = hw_atl_b0_hw_ring_tx_xmit, + .hw_ring_tx_head_update = hw_atl_b0_hw_ring_tx_head_update, + + .hw_ring_rx_receive = hw_atl_b0_hw_ring_rx_receive, + .hw_ring_rx_fill = hw_atl_b0_hw_ring_rx_fill, + + .hw_irq_enable = hw_atl_b0_hw_irq_enable, + .hw_irq_disable = hw_atl_b0_hw_irq_disable, + .hw_irq_read = hw_atl_b0_hw_irq_read, + + .hw_ring_rx_init = hw_atl_b0_hw_ring_rx_init, + .hw_ring_tx_init = hw_atl_b0_hw_ring_tx_init, + .hw_packet_filter_set = hw_atl_b0_hw_packet_filter_set, + .hw_multicast_list_set = hw_atl_b0_hw_multicast_list_set, + .hw_interrupt_moderation_set = hw_atl_b0_hw_interrupt_moderation_set, + .hw_rss_set = hw_atl_b0_hw_rss_set, + .hw_rss_hash_set = hw_atl_b0_hw_rss_hash_set, + .hw_get_regs = hw_atl_utils_hw_get_regs, + .hw_get_hw_stats = hw_atl_utils_get_hw_stats, + .hw_get_fw_version = hw_atl_utils_get_fw_version, +}; diff --git a/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_b0.h b/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_b0.h new file mode 100644 index 000000000..2cc8dacfd --- /dev/null +++ b/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_b0.h @@ -0,0 +1,42 @@ +/* + * aQuantia Corporation Network Driver + * Copyright (C) 2014-2017 aQuantia Corporation. All rights reserved + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + */ + +/* File hw_atl_b0.h: Declaration of abstract interface for Atlantic hardware + * specific functions. + */ + +#ifndef HW_ATL_B0_H +#define HW_ATL_B0_H + +#include "../aq_common.h" + +extern const struct aq_hw_caps_s hw_atl_b0_caps_aqc100; +extern const struct aq_hw_caps_s hw_atl_b0_caps_aqc107; +extern const struct aq_hw_caps_s hw_atl_b0_caps_aqc108; +extern const struct aq_hw_caps_s hw_atl_b0_caps_aqc109; + +#define hw_atl_b0_caps_aqc111 hw_atl_b0_caps_aqc108 +#define hw_atl_b0_caps_aqc112 hw_atl_b0_caps_aqc109 + +#define hw_atl_b0_caps_aqc100s hw_atl_b0_caps_aqc100 +#define hw_atl_b0_caps_aqc107s hw_atl_b0_caps_aqc107 +#define hw_atl_b0_caps_aqc108s hw_atl_b0_caps_aqc108 +#define hw_atl_b0_caps_aqc109s hw_atl_b0_caps_aqc109 + +#define hw_atl_b0_caps_aqc111s hw_atl_b0_caps_aqc108 +#define hw_atl_b0_caps_aqc112s hw_atl_b0_caps_aqc109 + +#define hw_atl_b0_caps_aqc111e hw_atl_b0_caps_aqc108 +#define hw_atl_b0_caps_aqc112e hw_atl_b0_caps_aqc109 + +extern const struct aq_hw_ops hw_atl_ops_b0; + +#define hw_atl_ops_b1 hw_atl_ops_b0 + +#endif /* HW_ATL_B0_H */ diff --git a/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_b0_internal.h b/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_b0_internal.h new file mode 100644 index 000000000..28568f5fa --- /dev/null +++ b/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_b0_internal.h @@ -0,0 +1,155 @@ +/* + * aQuantia Corporation Network Driver + * Copyright (C) 2014-2017 aQuantia Corporation. All rights reserved + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + */ + +/* File hw_atl_b0_internal.h: Definition of Atlantic B0 chip specific + * constants. + */ + +#ifndef HW_ATL_B0_INTERNAL_H +#define HW_ATL_B0_INTERNAL_H + +#include "../aq_common.h" + +#define HW_ATL_B0_MTU_JUMBO 16352U +#define HW_ATL_B0_MTU 1514U + +#define HW_ATL_B0_TX_RINGS 4U +#define HW_ATL_B0_RX_RINGS 4U + +#define HW_ATL_B0_RINGS_MAX 32U +#define HW_ATL_B0_TXD_SIZE (16U) +#define HW_ATL_B0_RXD_SIZE (16U) + +#define HW_ATL_B0_MAC 0U +#define HW_ATL_B0_MAC_MIN 1U +#define HW_ATL_B0_MAC_MAX 33U + +/* UCAST/MCAST filters */ +#define HW_ATL_B0_UCAST_FILTERS_MAX 38 +#define HW_ATL_B0_MCAST_FILTERS_MAX 8 + +/* interrupts */ +#define HW_ATL_B0_ERR_INT 8U +#define HW_ATL_B0_INT_MASK (0xFFFFFFFFU) + +#define HW_ATL_B0_TXD_CTL2_LEN (0xFFFFC000) +#define HW_ATL_B0_TXD_CTL2_CTX_EN (0x00002000) +#define HW_ATL_B0_TXD_CTL2_CTX_IDX (0x00001000) + +#define HW_ATL_B0_TXD_CTL_DESC_TYPE_TXD (0x00000001) +#define HW_ATL_B0_TXD_CTL_DESC_TYPE_TXC (0x00000002) +#define HW_ATL_B0_TXD_CTL_BLEN (0x000FFFF0) +#define HW_ATL_B0_TXD_CTL_DD (0x00100000) +#define HW_ATL_B0_TXD_CTL_EOP (0x00200000) + +#define HW_ATL_B0_TXD_CTL_CMD_X (0x3FC00000) + +#define HW_ATL_B0_TXD_CTL_CMD_VLAN BIT(22) +#define HW_ATL_B0_TXD_CTL_CMD_FCS BIT(23) +#define HW_ATL_B0_TXD_CTL_CMD_IPCSO BIT(24) +#define HW_ATL_B0_TXD_CTL_CMD_TUCSO BIT(25) +#define HW_ATL_B0_TXD_CTL_CMD_LSO BIT(26) +#define HW_ATL_B0_TXD_CTL_CMD_WB BIT(27) +#define HW_ATL_B0_TXD_CTL_CMD_VXLAN BIT(28) + +#define HW_ATL_B0_TXD_CTL_CMD_IPV6 BIT(21) +#define HW_ATL_B0_TXD_CTL_CMD_TCP BIT(22) + +#define HW_ATL_B0_MPI_CONTROL_ADR 0x0368U +#define HW_ATL_B0_MPI_STATE_ADR 0x036CU + +#define HW_ATL_B0_MPI_SPEED_MSK 0xFFFFU +#define HW_ATL_B0_MPI_SPEED_SHIFT 16U + +#define HW_ATL_B0_RATE_10G BIT(0) +#define HW_ATL_B0_RATE_5G BIT(1) +#define HW_ATL_B0_RATE_2G5 BIT(3) +#define HW_ATL_B0_RATE_1G BIT(4) +#define HW_ATL_B0_RATE_100M BIT(5) + +#define HW_ATL_B0_TXBUF_MAX 160U +#define HW_ATL_B0_RXBUF_MAX 320U + +#define HW_ATL_B0_RSS_REDIRECTION_MAX 64U +#define HW_ATL_B0_RSS_REDIRECTION_BITS 3U +#define HW_ATL_B0_RSS_HASHKEY_BITS 320U + +#define HW_ATL_B0_TCRSS_4_8 1 +#define HW_ATL_B0_TC_MAX 1U +#define HW_ATL_B0_RSS_MAX 8U + +#define HW_ATL_B0_LRO_RXD_MAX 2U +#define HW_ATL_B0_RS_SLIP_ENABLED 0U + +/* (256k -1(max pay_len) - 54(header)) */ +#define HAL_ATL_B0_LSO_MAX_SEGMENT_SIZE 262089U + +/* (256k -1(max pay_len) - 74(header)) */ +#define HAL_ATL_B0_LSO_IPV6_MAX_SEGMENT_SIZE 262069U + +#define HW_ATL_B0_CHIP_REVISION_B0 0xA0U +#define HW_ATL_B0_CHIP_REVISION_UNKNOWN 0xFFU + +#define HW_ATL_B0_FW_SEMA_RAM 0x2U + +#define HW_ATL_B0_TXC_LEN_TUNLEN (0x0000FF00) +#define HW_ATL_B0_TXC_LEN_OUTLEN (0xFFFF0000) + +#define HW_ATL_B0_TXC_CTL_DESC_TYPE (0x00000007) +#define HW_ATL_B0_TXC_CTL_CTX_ID (0x00000008) +#define HW_ATL_B0_TXC_CTL_VLAN (0x000FFFF0) +#define HW_ATL_B0_TXC_CTL_CMD (0x00F00000) +#define HW_ATL_B0_TXC_CTL_L2LEN (0x7F000000) + +#define HW_ATL_B0_TXC_CTL_L3LEN (0x80000000) /* L3LEN lsb */ +#define HW_ATL_B0_TXC_LEN2_L3LEN (0x000000FF) /* L3LE upper bits */ +#define HW_ATL_B0_TXC_LEN2_L4LEN (0x0000FF00) +#define HW_ATL_B0_TXC_LEN2_MSSLEN (0xFFFF0000) + +#define HW_ATL_B0_RXD_DD (0x1) +#define HW_ATL_B0_RXD_NCEA0 (0x1) + +#define HW_ATL_B0_RXD_WB_STAT_RSSTYPE (0x0000000F) +#define HW_ATL_B0_RXD_WB_STAT_PKTTYPE (0x00000FF0) +#define HW_ATL_B0_RXD_WB_STAT_RXCTRL (0x00180000) +#define HW_ATL_B0_RXD_WB_STAT_SPLHDR (0x00200000) +#define HW_ATL_B0_RXD_WB_STAT_HDRLEN (0xFFC00000) + +#define HW_ATL_B0_RXD_WB_STAT2_DD (0x0001) +#define HW_ATL_B0_RXD_WB_STAT2_EOP (0x0002) +#define HW_ATL_B0_RXD_WB_STAT2_RXSTAT (0x003C) +#define HW_ATL_B0_RXD_WB_STAT2_MACERR (0x0004) +#define HW_ATL_B0_RXD_WB_STAT2_IP4ERR (0x0008) +#define HW_ATL_B0_RXD_WB_STAT2_TCPUPDERR (0x0010) +#define HW_ATL_B0_RXD_WB_STAT2_RXESTAT (0x0FC0) +#define HW_ATL_B0_RXD_WB_STAT2_RSCCNT (0xF000) + +#define L2_FILTER_ACTION_DISCARD (0x0) +#define L2_FILTER_ACTION_HOST (0x1) + +#define HW_ATL_B0_UCP_0X370_REG (0x370) + +#define HW_ATL_B0_FLUSH() AQ_HW_READ_REG(self, 0x10) + +#define HW_ATL_B0_FW_VER_EXPECTED 0x01050006U + +#define HW_ATL_INTR_MODER_MAX 0x1FF +#define HW_ATL_INTR_MODER_MIN 0xFF + +#define HW_ATL_B0_MIN_RXD \ + (ALIGN(AQ_CFG_SKB_FRAGS_MAX + 1U, AQ_HW_RXD_MULTIPLE)) +#define HW_ATL_B0_MIN_TXD \ + (ALIGN(AQ_CFG_SKB_FRAGS_MAX + 1U, AQ_HW_TXD_MULTIPLE)) + +#define HW_ATL_B0_MAX_RXD 8184U +#define HW_ATL_B0_MAX_TXD 8184U + +/* HW layer capabilities */ + +#endif /* HW_ATL_B0_INTERNAL_H */ diff --git a/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_llh.c b/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_llh.c new file mode 100644 index 000000000..5502ec5f0 --- /dev/null +++ b/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_llh.c @@ -0,0 +1,1478 @@ +/* + * aQuantia Corporation Network Driver + * Copyright (C) 2014-2017 aQuantia Corporation. All rights reserved + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + */ + +/* File hw_atl_llh.c: Definitions of bitfield and register access functions for + * Atlantic registers. + */ + +#include "hw_atl_llh.h" +#include "hw_atl_llh_internal.h" +#include "../aq_hw_utils.h" + +/* global */ +void hw_atl_reg_glb_cpu_sem_set(struct aq_hw_s *aq_hw, u32 glb_cpu_sem, + u32 semaphore) +{ + aq_hw_write_reg(aq_hw, HW_ATL_GLB_CPU_SEM_ADR(semaphore), glb_cpu_sem); +} + +u32 hw_atl_reg_glb_cpu_sem_get(struct aq_hw_s *aq_hw, u32 semaphore) +{ + return aq_hw_read_reg(aq_hw, HW_ATL_GLB_CPU_SEM_ADR(semaphore)); +} + +void hw_atl_glb_glb_reg_res_dis_set(struct aq_hw_s *aq_hw, u32 glb_reg_res_dis) +{ + aq_hw_write_reg_bit(aq_hw, HW_ATL_GLB_REG_RES_DIS_ADR, + HW_ATL_GLB_REG_RES_DIS_MSK, + HW_ATL_GLB_REG_RES_DIS_SHIFT, + glb_reg_res_dis); +} + +void hw_atl_glb_soft_res_set(struct aq_hw_s *aq_hw, u32 soft_res) +{ + aq_hw_write_reg_bit(aq_hw, HW_ATL_GLB_SOFT_RES_ADR, + HW_ATL_GLB_SOFT_RES_MSK, + HW_ATL_GLB_SOFT_RES_SHIFT, soft_res); +} + +u32 hw_atl_glb_soft_res_get(struct aq_hw_s *aq_hw) +{ + return aq_hw_read_reg_bit(aq_hw, HW_ATL_GLB_SOFT_RES_ADR, + HW_ATL_GLB_SOFT_RES_MSK, + HW_ATL_GLB_SOFT_RES_SHIFT); +} + +u32 hw_atl_reg_rx_dma_stat_counter7get(struct aq_hw_s *aq_hw) +{ + return aq_hw_read_reg(aq_hw, HW_ATL_RX_DMA_STAT_COUNTER7_ADR); +} + +u32 hw_atl_reg_glb_mif_id_get(struct aq_hw_s *aq_hw) +{ + return aq_hw_read_reg(aq_hw, HW_ATL_GLB_MIF_ID_ADR); +} + +/* stats */ +u32 hw_atl_rpb_rx_dma_drop_pkt_cnt_get(struct aq_hw_s *aq_hw) +{ + return aq_hw_read_reg(aq_hw, HW_ATL_RPB_RX_DMA_DROP_PKT_CNT_ADR); +} + +u32 hw_atl_stats_rx_dma_good_octet_counterlsw_get(struct aq_hw_s *aq_hw) +{ + return aq_hw_read_reg(aq_hw, HW_ATL_STATS_RX_DMA_GOOD_OCTET_COUNTERLSW); +} + +u32 hw_atl_stats_rx_dma_good_pkt_counterlsw_get(struct aq_hw_s *aq_hw) +{ + return aq_hw_read_reg(aq_hw, HW_ATL_STATS_RX_DMA_GOOD_PKT_COUNTERLSW); +} + +u32 hw_atl_stats_tx_dma_good_octet_counterlsw_get(struct aq_hw_s *aq_hw) +{ + return aq_hw_read_reg(aq_hw, HW_ATL_STATS_TX_DMA_GOOD_OCTET_COUNTERLSW); +} + +u32 hw_atl_stats_tx_dma_good_pkt_counterlsw_get(struct aq_hw_s *aq_hw) +{ + return aq_hw_read_reg(aq_hw, HW_ATL_STATS_TX_DMA_GOOD_PKT_COUNTERLSW); +} + +u32 hw_atl_stats_rx_dma_good_octet_countermsw_get(struct aq_hw_s *aq_hw) +{ + return aq_hw_read_reg(aq_hw, HW_ATL_STATS_RX_DMA_GOOD_OCTET_COUNTERMSW); +} + +u32 hw_atl_stats_rx_dma_good_pkt_countermsw_get(struct aq_hw_s *aq_hw) +{ + return aq_hw_read_reg(aq_hw, HW_ATL_STATS_RX_DMA_GOOD_PKT_COUNTERMSW); +} + +u32 hw_atl_stats_tx_dma_good_octet_countermsw_get(struct aq_hw_s *aq_hw) +{ + return aq_hw_read_reg(aq_hw, HW_ATL_STATS_TX_DMA_GOOD_OCTET_COUNTERMSW); +} + +u32 hw_atl_stats_tx_dma_good_pkt_countermsw_get(struct aq_hw_s *aq_hw) +{ + return aq_hw_read_reg(aq_hw, HW_ATL_STATS_TX_DMA_GOOD_PKT_COUNTERMSW); +} + +/* interrupt */ +void hw_atl_itr_irq_auto_masklsw_set(struct aq_hw_s *aq_hw, + u32 irq_auto_masklsw) +{ + aq_hw_write_reg(aq_hw, HW_ATL_ITR_IAMRLSW_ADR, irq_auto_masklsw); +} + +void hw_atl_itr_irq_map_en_rx_set(struct aq_hw_s *aq_hw, u32 irq_map_en_rx, + u32 rx) +{ +/* register address for bitfield imr_rx{r}_en */ + static u32 itr_imr_rxren_adr[32] = { + 0x00002100U, 0x00002100U, 0x00002104U, 0x00002104U, + 0x00002108U, 0x00002108U, 0x0000210CU, 0x0000210CU, + 0x00002110U, 0x00002110U, 0x00002114U, 0x00002114U, + 0x00002118U, 0x00002118U, 0x0000211CU, 0x0000211CU, + 0x00002120U, 0x00002120U, 0x00002124U, 0x00002124U, + 0x00002128U, 0x00002128U, 0x0000212CU, 0x0000212CU, + 0x00002130U, 0x00002130U, 0x00002134U, 0x00002134U, + 0x00002138U, 0x00002138U, 0x0000213CU, 0x0000213CU + }; + +/* bitmask for bitfield imr_rx{r}_en */ + static u32 itr_imr_rxren_msk[32] = { + 0x00008000U, 0x00000080U, 0x00008000U, 0x00000080U, + 0x00008000U, 0x00000080U, 0x00008000U, 0x00000080U, + 0x00008000U, 0x00000080U, 0x00008000U, 0x00000080U, + 0x00008000U, 0x00000080U, 0x00008000U, 0x00000080U, + 0x00008000U, 0x00000080U, 0x00008000U, 0x00000080U, + 0x00008000U, 0x00000080U, 0x00008000U, 0x00000080U, + 0x00008000U, 0x00000080U, 0x00008000U, 0x00000080U, + 0x00008000U, 0x00000080U, 0x00008000U, 0x00000080U + }; + +/* lower bit position of bitfield imr_rx{r}_en */ + static u32 itr_imr_rxren_shift[32] = { + 15U, 7U, 15U, 7U, 15U, 7U, 15U, 7U, + 15U, 7U, 15U, 7U, 15U, 7U, 15U, 7U, + 15U, 7U, 15U, 7U, 15U, 7U, 15U, 7U, + 15U, 7U, 15U, 7U, 15U, 7U, 15U, 7U + }; + + aq_hw_write_reg_bit(aq_hw, itr_imr_rxren_adr[rx], + itr_imr_rxren_msk[rx], + itr_imr_rxren_shift[rx], + irq_map_en_rx); +} + +void hw_atl_itr_irq_map_en_tx_set(struct aq_hw_s *aq_hw, u32 irq_map_en_tx, + u32 tx) +{ +/* register address for bitfield imr_tx{t}_en */ + static u32 itr_imr_txten_adr[32] = { + 0x00002100U, 0x00002100U, 0x00002104U, 0x00002104U, + 0x00002108U, 0x00002108U, 0x0000210CU, 0x0000210CU, + 0x00002110U, 0x00002110U, 0x00002114U, 0x00002114U, + 0x00002118U, 0x00002118U, 0x0000211CU, 0x0000211CU, + 0x00002120U, 0x00002120U, 0x00002124U, 0x00002124U, + 0x00002128U, 0x00002128U, 0x0000212CU, 0x0000212CU, + 0x00002130U, 0x00002130U, 0x00002134U, 0x00002134U, + 0x00002138U, 0x00002138U, 0x0000213CU, 0x0000213CU + }; + +/* bitmask for bitfield imr_tx{t}_en */ + static u32 itr_imr_txten_msk[32] = { + 0x80000000U, 0x00800000U, 0x80000000U, 0x00800000U, + 0x80000000U, 0x00800000U, 0x80000000U, 0x00800000U, + 0x80000000U, 0x00800000U, 0x80000000U, 0x00800000U, + 0x80000000U, 0x00800000U, 0x80000000U, 0x00800000U, + 0x80000000U, 0x00800000U, 0x80000000U, 0x00800000U, + 0x80000000U, 0x00800000U, 0x80000000U, 0x00800000U, + 0x80000000U, 0x00800000U, 0x80000000U, 0x00800000U, + 0x80000000U, 0x00800000U, 0x80000000U, 0x00800000U + }; + +/* lower bit position of bitfield imr_tx{t}_en */ + static u32 itr_imr_txten_shift[32] = { + 31U, 23U, 31U, 23U, 31U, 23U, 31U, 23U, + 31U, 23U, 31U, 23U, 31U, 23U, 31U, 23U, + 31U, 23U, 31U, 23U, 31U, 23U, 31U, 23U, + 31U, 23U, 31U, 23U, 31U, 23U, 31U, 23U + }; + + aq_hw_write_reg_bit(aq_hw, itr_imr_txten_adr[tx], + itr_imr_txten_msk[tx], + itr_imr_txten_shift[tx], + irq_map_en_tx); +} + +void hw_atl_itr_irq_map_rx_set(struct aq_hw_s *aq_hw, u32 irq_map_rx, u32 rx) +{ +/* register address for bitfield imr_rx{r}[4:0] */ + static u32 itr_imr_rxr_adr[32] = { + 0x00002100U, 0x00002100U, 0x00002104U, 0x00002104U, + 0x00002108U, 0x00002108U, 0x0000210CU, 0x0000210CU, + 0x00002110U, 0x00002110U, 0x00002114U, 0x00002114U, + 0x00002118U, 0x00002118U, 0x0000211CU, 0x0000211CU, + 0x00002120U, 0x00002120U, 0x00002124U, 0x00002124U, + 0x00002128U, 0x00002128U, 0x0000212CU, 0x0000212CU, + 0x00002130U, 0x00002130U, 0x00002134U, 0x00002134U, + 0x00002138U, 0x00002138U, 0x0000213CU, 0x0000213CU + }; + +/* bitmask for bitfield imr_rx{r}[4:0] */ + static u32 itr_imr_rxr_msk[32] = { + 0x00001f00U, 0x0000001FU, 0x00001F00U, 0x0000001FU, + 0x00001f00U, 0x0000001FU, 0x00001F00U, 0x0000001FU, + 0x00001f00U, 0x0000001FU, 0x00001F00U, 0x0000001FU, + 0x00001f00U, 0x0000001FU, 0x00001F00U, 0x0000001FU, + 0x00001f00U, 0x0000001FU, 0x00001F00U, 0x0000001FU, + 0x00001f00U, 0x0000001FU, 0x00001F00U, 0x0000001FU, + 0x00001f00U, 0x0000001FU, 0x00001F00U, 0x0000001FU, + 0x00001f00U, 0x0000001FU, 0x00001F00U, 0x0000001FU + }; + +/* lower bit position of bitfield imr_rx{r}[4:0] */ + static u32 itr_imr_rxr_shift[32] = { + 8U, 0U, 8U, 0U, 8U, 0U, 8U, 0U, + 8U, 0U, 8U, 0U, 8U, 0U, 8U, 0U, + 8U, 0U, 8U, 0U, 8U, 0U, 8U, 0U, + 8U, 0U, 8U, 0U, 8U, 0U, 8U, 0U + }; + + aq_hw_write_reg_bit(aq_hw, itr_imr_rxr_adr[rx], + itr_imr_rxr_msk[rx], + itr_imr_rxr_shift[rx], + irq_map_rx); +} + +void hw_atl_itr_irq_map_tx_set(struct aq_hw_s *aq_hw, u32 irq_map_tx, u32 tx) +{ +/* register address for bitfield imr_tx{t}[4:0] */ + static u32 itr_imr_txt_adr[32] = { + 0x00002100U, 0x00002100U, 0x00002104U, 0x00002104U, + 0x00002108U, 0x00002108U, 0x0000210CU, 0x0000210CU, + 0x00002110U, 0x00002110U, 0x00002114U, 0x00002114U, + 0x00002118U, 0x00002118U, 0x0000211CU, 0x0000211CU, + 0x00002120U, 0x00002120U, 0x00002124U, 0x00002124U, + 0x00002128U, 0x00002128U, 0x0000212CU, 0x0000212CU, + 0x00002130U, 0x00002130U, 0x00002134U, 0x00002134U, + 0x00002138U, 0x00002138U, 0x0000213CU, 0x0000213CU + }; + +/* bitmask for bitfield imr_tx{t}[4:0] */ + static u32 itr_imr_txt_msk[32] = { + 0x1f000000U, 0x001F0000U, 0x1F000000U, 0x001F0000U, + 0x1f000000U, 0x001F0000U, 0x1F000000U, 0x001F0000U, + 0x1f000000U, 0x001F0000U, 0x1F000000U, 0x001F0000U, + 0x1f000000U, 0x001F0000U, 0x1F000000U, 0x001F0000U, + 0x1f000000U, 0x001F0000U, 0x1F000000U, 0x001F0000U, + 0x1f000000U, 0x001F0000U, 0x1F000000U, 0x001F0000U, + 0x1f000000U, 0x001F0000U, 0x1F000000U, 0x001F0000U, + 0x1f000000U, 0x001F0000U, 0x1F000000U, 0x001F0000U + }; + +/* lower bit position of bitfield imr_tx{t}[4:0] */ + static u32 itr_imr_txt_shift[32] = { + 24U, 16U, 24U, 16U, 24U, 16U, 24U, 16U, + 24U, 16U, 24U, 16U, 24U, 16U, 24U, 16U, + 24U, 16U, 24U, 16U, 24U, 16U, 24U, 16U, + 24U, 16U, 24U, 16U, 24U, 16U, 24U, 16U + }; + + aq_hw_write_reg_bit(aq_hw, itr_imr_txt_adr[tx], + itr_imr_txt_msk[tx], + itr_imr_txt_shift[tx], + irq_map_tx); +} + +void hw_atl_itr_irq_msk_clearlsw_set(struct aq_hw_s *aq_hw, + u32 irq_msk_clearlsw) +{ + aq_hw_write_reg(aq_hw, HW_ATL_ITR_IMCRLSW_ADR, irq_msk_clearlsw); +} + +void hw_atl_itr_irq_msk_setlsw_set(struct aq_hw_s *aq_hw, u32 irq_msk_setlsw) +{ + aq_hw_write_reg(aq_hw, HW_ATL_ITR_IMSRLSW_ADR, irq_msk_setlsw); +} + +void hw_atl_itr_irq_reg_res_dis_set(struct aq_hw_s *aq_hw, u32 irq_reg_res_dis) +{ + aq_hw_write_reg_bit(aq_hw, HW_ATL_ITR_REG_RES_DSBL_ADR, + HW_ATL_ITR_REG_RES_DSBL_MSK, + HW_ATL_ITR_REG_RES_DSBL_SHIFT, irq_reg_res_dis); +} + +void hw_atl_itr_irq_status_clearlsw_set(struct aq_hw_s *aq_hw, + u32 irq_status_clearlsw) +{ + aq_hw_write_reg(aq_hw, HW_ATL_ITR_ISCRLSW_ADR, irq_status_clearlsw); +} + +u32 hw_atl_itr_irq_statuslsw_get(struct aq_hw_s *aq_hw) +{ + return aq_hw_read_reg(aq_hw, HW_ATL_ITR_ISRLSW_ADR); +} + +u32 hw_atl_itr_res_irq_get(struct aq_hw_s *aq_hw) +{ + return aq_hw_read_reg_bit(aq_hw, HW_ATL_ITR_RES_ADR, HW_ATL_ITR_RES_MSK, + HW_ATL_ITR_RES_SHIFT); +} + +void hw_atl_itr_res_irq_set(struct aq_hw_s *aq_hw, u32 res_irq) +{ + aq_hw_write_reg_bit(aq_hw, HW_ATL_ITR_RES_ADR, HW_ATL_ITR_RES_MSK, + HW_ATL_ITR_RES_SHIFT, res_irq); +} + +/* rdm */ +void hw_atl_rdm_cpu_id_set(struct aq_hw_s *aq_hw, u32 cpuid, u32 dca) +{ + aq_hw_write_reg_bit(aq_hw, HW_ATL_RDM_DCADCPUID_ADR(dca), + HW_ATL_RDM_DCADCPUID_MSK, + HW_ATL_RDM_DCADCPUID_SHIFT, cpuid); +} + +void hw_atl_rdm_rx_dca_en_set(struct aq_hw_s *aq_hw, u32 rx_dca_en) +{ + aq_hw_write_reg_bit(aq_hw, HW_ATL_RDM_DCA_EN_ADR, HW_ATL_RDM_DCA_EN_MSK, + HW_ATL_RDM_DCA_EN_SHIFT, rx_dca_en); +} + +void hw_atl_rdm_rx_dca_mode_set(struct aq_hw_s *aq_hw, u32 rx_dca_mode) +{ + aq_hw_write_reg_bit(aq_hw, HW_ATL_RDM_DCA_MODE_ADR, + HW_ATL_RDM_DCA_MODE_MSK, + HW_ATL_RDM_DCA_MODE_SHIFT, rx_dca_mode); +} + +void hw_atl_rdm_rx_desc_data_buff_size_set(struct aq_hw_s *aq_hw, + u32 rx_desc_data_buff_size, + u32 descriptor) +{ + aq_hw_write_reg_bit(aq_hw, HW_ATL_RDM_DESCDDATA_SIZE_ADR(descriptor), + HW_ATL_RDM_DESCDDATA_SIZE_MSK, + HW_ATL_RDM_DESCDDATA_SIZE_SHIFT, + rx_desc_data_buff_size); +} + +void hw_atl_rdm_rx_desc_dca_en_set(struct aq_hw_s *aq_hw, u32 rx_desc_dca_en, + u32 dca) +{ + aq_hw_write_reg_bit(aq_hw, HW_ATL_RDM_DCADDESC_EN_ADR(dca), + HW_ATL_RDM_DCADDESC_EN_MSK, + HW_ATL_RDM_DCADDESC_EN_SHIFT, + rx_desc_dca_en); +} + +void hw_atl_rdm_rx_desc_en_set(struct aq_hw_s *aq_hw, u32 rx_desc_en, + u32 descriptor) +{ + aq_hw_write_reg_bit(aq_hw, HW_ATL_RDM_DESCDEN_ADR(descriptor), + HW_ATL_RDM_DESCDEN_MSK, + HW_ATL_RDM_DESCDEN_SHIFT, + rx_desc_en); +} + +void hw_atl_rdm_rx_desc_head_buff_size_set(struct aq_hw_s *aq_hw, + u32 rx_desc_head_buff_size, + u32 descriptor) +{ + aq_hw_write_reg_bit(aq_hw, HW_ATL_RDM_DESCDHDR_SIZE_ADR(descriptor), + HW_ATL_RDM_DESCDHDR_SIZE_MSK, + HW_ATL_RDM_DESCDHDR_SIZE_SHIFT, + rx_desc_head_buff_size); +} + +void hw_atl_rdm_rx_desc_head_splitting_set(struct aq_hw_s *aq_hw, + u32 rx_desc_head_splitting, + u32 descriptor) +{ + aq_hw_write_reg_bit(aq_hw, HW_ATL_RDM_DESCDHDR_SPLIT_ADR(descriptor), + HW_ATL_RDM_DESCDHDR_SPLIT_MSK, + HW_ATL_RDM_DESCDHDR_SPLIT_SHIFT, + rx_desc_head_splitting); +} + +u32 hw_atl_rdm_rx_desc_head_ptr_get(struct aq_hw_s *aq_hw, u32 descriptor) +{ + return aq_hw_read_reg_bit(aq_hw, HW_ATL_RDM_DESCDHD_ADR(descriptor), + HW_ATL_RDM_DESCDHD_MSK, + HW_ATL_RDM_DESCDHD_SHIFT); +} + +void hw_atl_rdm_rx_desc_len_set(struct aq_hw_s *aq_hw, u32 rx_desc_len, + u32 descriptor) +{ + aq_hw_write_reg_bit(aq_hw, HW_ATL_RDM_DESCDLEN_ADR(descriptor), + HW_ATL_RDM_DESCDLEN_MSK, HW_ATL_RDM_DESCDLEN_SHIFT, + rx_desc_len); +} + +void hw_atl_rdm_rx_desc_res_set(struct aq_hw_s *aq_hw, u32 rx_desc_res, + u32 descriptor) +{ + aq_hw_write_reg_bit(aq_hw, HW_ATL_RDM_DESCDRESET_ADR(descriptor), + HW_ATL_RDM_DESCDRESET_MSK, + HW_ATL_RDM_DESCDRESET_SHIFT, + rx_desc_res); +} + +void hw_atl_rdm_rx_desc_wr_wb_irq_en_set(struct aq_hw_s *aq_hw, + u32 rx_desc_wr_wb_irq_en) +{ + aq_hw_write_reg_bit(aq_hw, HW_ATL_RDM_INT_DESC_WRB_EN_ADR, + HW_ATL_RDM_INT_DESC_WRB_EN_MSK, + HW_ATL_RDM_INT_DESC_WRB_EN_SHIFT, + rx_desc_wr_wb_irq_en); +} + +void hw_atl_rdm_rx_head_dca_en_set(struct aq_hw_s *aq_hw, u32 rx_head_dca_en, + u32 dca) +{ + aq_hw_write_reg_bit(aq_hw, HW_ATL_RDM_DCADHDR_EN_ADR(dca), + HW_ATL_RDM_DCADHDR_EN_MSK, + HW_ATL_RDM_DCADHDR_EN_SHIFT, + rx_head_dca_en); +} + +void hw_atl_rdm_rx_pld_dca_en_set(struct aq_hw_s *aq_hw, u32 rx_pld_dca_en, + u32 dca) +{ + aq_hw_write_reg_bit(aq_hw, HW_ATL_RDM_DCADPAY_EN_ADR(dca), + HW_ATL_RDM_DCADPAY_EN_MSK, + HW_ATL_RDM_DCADPAY_EN_SHIFT, + rx_pld_dca_en); +} + +void hw_atl_rdm_rdm_intr_moder_en_set(struct aq_hw_s *aq_hw, + u32 rdm_intr_moder_en) +{ + aq_hw_write_reg_bit(aq_hw, HW_ATL_RDM_INT_RIM_EN_ADR, + HW_ATL_RDM_INT_RIM_EN_MSK, + HW_ATL_RDM_INT_RIM_EN_SHIFT, + rdm_intr_moder_en); +} + +/* reg */ +void hw_atl_reg_gen_irq_map_set(struct aq_hw_s *aq_hw, u32 gen_intr_map, + u32 regidx) +{ + aq_hw_write_reg(aq_hw, HW_ATL_GEN_INTR_MAP_ADR(regidx), gen_intr_map); +} + +u32 hw_atl_reg_gen_irq_status_get(struct aq_hw_s *aq_hw) +{ + return aq_hw_read_reg(aq_hw, HW_ATL_GEN_INTR_STAT_ADR); +} + +void hw_atl_reg_irq_glb_ctl_set(struct aq_hw_s *aq_hw, u32 intr_glb_ctl) +{ + aq_hw_write_reg(aq_hw, HW_ATL_INTR_GLB_CTL_ADR, intr_glb_ctl); +} + +void hw_atl_reg_irq_thr_set(struct aq_hw_s *aq_hw, u32 intr_thr, u32 throttle) +{ + aq_hw_write_reg(aq_hw, HW_ATL_INTR_THR_ADR(throttle), intr_thr); +} + +void hw_atl_reg_rx_dma_desc_base_addresslswset(struct aq_hw_s *aq_hw, + u32 rx_dma_desc_base_addrlsw, + u32 descriptor) +{ + aq_hw_write_reg(aq_hw, HW_ATL_RX_DMA_DESC_BASE_ADDRLSW_ADR(descriptor), + rx_dma_desc_base_addrlsw); +} + +void hw_atl_reg_rx_dma_desc_base_addressmswset(struct aq_hw_s *aq_hw, + u32 rx_dma_desc_base_addrmsw, + u32 descriptor) +{ + aq_hw_write_reg(aq_hw, HW_ATL_RX_DMA_DESC_BASE_ADDRMSW_ADR(descriptor), + rx_dma_desc_base_addrmsw); +} + +u32 hw_atl_reg_rx_dma_desc_status_get(struct aq_hw_s *aq_hw, u32 descriptor) +{ + return aq_hw_read_reg(aq_hw, HW_ATL_RX_DMA_DESC_STAT_ADR(descriptor)); +} + +void hw_atl_reg_rx_dma_desc_tail_ptr_set(struct aq_hw_s *aq_hw, + u32 rx_dma_desc_tail_ptr, + u32 descriptor) +{ + aq_hw_write_reg(aq_hw, HW_ATL_RX_DMA_DESC_TAIL_PTR_ADR(descriptor), + rx_dma_desc_tail_ptr); +} + +void hw_atl_reg_rx_flr_mcst_flr_msk_set(struct aq_hw_s *aq_hw, + u32 rx_flr_mcst_flr_msk) +{ + aq_hw_write_reg(aq_hw, HW_ATL_RX_FLR_MCST_FLR_MSK_ADR, + rx_flr_mcst_flr_msk); +} + +void hw_atl_reg_rx_flr_mcst_flr_set(struct aq_hw_s *aq_hw, u32 rx_flr_mcst_flr, + u32 filter) +{ + aq_hw_write_reg(aq_hw, HW_ATL_RX_FLR_MCST_FLR_ADR(filter), + rx_flr_mcst_flr); +} + +void hw_atl_reg_rx_flr_rss_control1set(struct aq_hw_s *aq_hw, + u32 rx_flr_rss_control1) +{ + aq_hw_write_reg(aq_hw, HW_ATL_RX_FLR_RSS_CONTROL1_ADR, + rx_flr_rss_control1); +} + +void hw_atl_reg_rx_flr_control2_set(struct aq_hw_s *aq_hw, + u32 rx_filter_control2) +{ + aq_hw_write_reg(aq_hw, HW_ATL_RX_FLR_CONTROL2_ADR, rx_filter_control2); +} + +void hw_atl_reg_rx_intr_moder_ctrl_set(struct aq_hw_s *aq_hw, + u32 rx_intr_moderation_ctl, + u32 queue) +{ + aq_hw_write_reg(aq_hw, HW_ATL_RX_INTR_MODERATION_CTL_ADR(queue), + rx_intr_moderation_ctl); +} + +void hw_atl_reg_tx_dma_debug_ctl_set(struct aq_hw_s *aq_hw, + u32 tx_dma_debug_ctl) +{ + aq_hw_write_reg(aq_hw, HW_ATL_TX_DMA_DEBUG_CTL_ADR, tx_dma_debug_ctl); +} + +void hw_atl_reg_tx_dma_desc_base_addresslswset(struct aq_hw_s *aq_hw, + u32 tx_dma_desc_base_addrlsw, + u32 descriptor) +{ + aq_hw_write_reg(aq_hw, HW_ATL_TX_DMA_DESC_BASE_ADDRLSW_ADR(descriptor), + tx_dma_desc_base_addrlsw); +} + +void hw_atl_reg_tx_dma_desc_base_addressmswset(struct aq_hw_s *aq_hw, + u32 tx_dma_desc_base_addrmsw, + u32 descriptor) +{ + aq_hw_write_reg(aq_hw, HW_ATL_TX_DMA_DESC_BASE_ADDRMSW_ADR(descriptor), + tx_dma_desc_base_addrmsw); +} + +void hw_atl_reg_tx_dma_desc_tail_ptr_set(struct aq_hw_s *aq_hw, + u32 tx_dma_desc_tail_ptr, + u32 descriptor) +{ + aq_hw_write_reg(aq_hw, HW_ATL_TX_DMA_DESC_TAIL_PTR_ADR(descriptor), + tx_dma_desc_tail_ptr); +} + +void hw_atl_reg_tx_intr_moder_ctrl_set(struct aq_hw_s *aq_hw, + u32 tx_intr_moderation_ctl, + u32 queue) +{ + aq_hw_write_reg(aq_hw, HW_ATL_TX_INTR_MODERATION_CTL_ADR(queue), + tx_intr_moderation_ctl); +} + +/* RPB: rx packet buffer */ +void hw_atl_rpb_dma_sys_lbk_set(struct aq_hw_s *aq_hw, u32 dma_sys_lbk) +{ + aq_hw_write_reg_bit(aq_hw, HW_ATL_RPB_DMA_SYS_LBK_ADR, + HW_ATL_RPB_DMA_SYS_LBK_MSK, + HW_ATL_RPB_DMA_SYS_LBK_SHIFT, dma_sys_lbk); +} + +void hw_atl_rpb_rpf_rx_traf_class_mode_set(struct aq_hw_s *aq_hw, + u32 rx_traf_class_mode) +{ + aq_hw_write_reg_bit(aq_hw, HW_ATL_RPB_RPF_RX_TC_MODE_ADR, + HW_ATL_RPB_RPF_RX_TC_MODE_MSK, + HW_ATL_RPB_RPF_RX_TC_MODE_SHIFT, + rx_traf_class_mode); +} + +void hw_atl_rpb_rx_buff_en_set(struct aq_hw_s *aq_hw, u32 rx_buff_en) +{ + aq_hw_write_reg_bit(aq_hw, HW_ATL_RPB_RX_BUF_EN_ADR, + HW_ATL_RPB_RX_BUF_EN_MSK, + HW_ATL_RPB_RX_BUF_EN_SHIFT, rx_buff_en); +} + +void hw_atl_rpb_rx_buff_hi_threshold_per_tc_set(struct aq_hw_s *aq_hw, + u32 rx_buff_hi_threshold_per_tc, + u32 buffer) +{ + aq_hw_write_reg_bit(aq_hw, HW_ATL_RPB_RXBHI_THRESH_ADR(buffer), + HW_ATL_RPB_RXBHI_THRESH_MSK, + HW_ATL_RPB_RXBHI_THRESH_SHIFT, + rx_buff_hi_threshold_per_tc); +} + +void hw_atl_rpb_rx_buff_lo_threshold_per_tc_set(struct aq_hw_s *aq_hw, + u32 rx_buff_lo_threshold_per_tc, + u32 buffer) +{ + aq_hw_write_reg_bit(aq_hw, HW_ATL_RPB_RXBLO_THRESH_ADR(buffer), + HW_ATL_RPB_RXBLO_THRESH_MSK, + HW_ATL_RPB_RXBLO_THRESH_SHIFT, + rx_buff_lo_threshold_per_tc); +} + +void hw_atl_rpb_rx_flow_ctl_mode_set(struct aq_hw_s *aq_hw, u32 rx_flow_ctl_mode) +{ + aq_hw_write_reg_bit(aq_hw, HW_ATL_RPB_RX_FC_MODE_ADR, + HW_ATL_RPB_RX_FC_MODE_MSK, + HW_ATL_RPB_RX_FC_MODE_SHIFT, rx_flow_ctl_mode); +} + +void hw_atl_rdm_rx_dma_desc_cache_init_set(struct aq_hw_s *aq_hw, u32 init) +{ + aq_hw_write_reg_bit(aq_hw, HW_ATL_RDM_RX_DMA_DESC_CACHE_INIT_ADR, + HW_ATL_RDM_RX_DMA_DESC_CACHE_INIT_MSK, + HW_ATL_RDM_RX_DMA_DESC_CACHE_INIT_SHIFT, + init); +} + +void hw_atl_rpb_rx_pkt_buff_size_per_tc_set(struct aq_hw_s *aq_hw, + u32 rx_pkt_buff_size_per_tc, u32 buffer) +{ + aq_hw_write_reg_bit(aq_hw, HW_ATL_RPB_RXBBUF_SIZE_ADR(buffer), + HW_ATL_RPB_RXBBUF_SIZE_MSK, + HW_ATL_RPB_RXBBUF_SIZE_SHIFT, + rx_pkt_buff_size_per_tc); +} + +void hw_atl_rpb_rx_xoff_en_per_tc_set(struct aq_hw_s *aq_hw, u32 rx_xoff_en_per_tc, + u32 buffer) +{ + aq_hw_write_reg_bit(aq_hw, HW_ATL_RPB_RXBXOFF_EN_ADR(buffer), + HW_ATL_RPB_RXBXOFF_EN_MSK, + HW_ATL_RPB_RXBXOFF_EN_SHIFT, + rx_xoff_en_per_tc); +} + +/* rpf */ + +void hw_atl_rpfl2broadcast_count_threshold_set(struct aq_hw_s *aq_hw, + u32 l2broadcast_count_threshold) +{ + aq_hw_write_reg_bit(aq_hw, HW_ATL_RPFL2BC_THRESH_ADR, + HW_ATL_RPFL2BC_THRESH_MSK, + HW_ATL_RPFL2BC_THRESH_SHIFT, + l2broadcast_count_threshold); +} + +void hw_atl_rpfl2broadcast_en_set(struct aq_hw_s *aq_hw, u32 l2broadcast_en) +{ + aq_hw_write_reg_bit(aq_hw, HW_ATL_RPFL2BC_EN_ADR, HW_ATL_RPFL2BC_EN_MSK, + HW_ATL_RPFL2BC_EN_SHIFT, l2broadcast_en); +} + +void hw_atl_rpfl2broadcast_flr_act_set(struct aq_hw_s *aq_hw, + u32 l2broadcast_flr_act) +{ + aq_hw_write_reg_bit(aq_hw, HW_ATL_RPFL2BC_ACT_ADR, + HW_ATL_RPFL2BC_ACT_MSK, + HW_ATL_RPFL2BC_ACT_SHIFT, l2broadcast_flr_act); +} + +void hw_atl_rpfl2multicast_flr_en_set(struct aq_hw_s *aq_hw, + u32 l2multicast_flr_en, + u32 filter) +{ + aq_hw_write_reg_bit(aq_hw, HW_ATL_RPFL2MC_ENF_ADR(filter), + HW_ATL_RPFL2MC_ENF_MSK, + HW_ATL_RPFL2MC_ENF_SHIFT, l2multicast_flr_en); +} + +void hw_atl_rpfl2promiscuous_mode_en_set(struct aq_hw_s *aq_hw, + u32 l2promiscuous_mode_en) +{ + aq_hw_write_reg_bit(aq_hw, HW_ATL_RPFL2PROMIS_MODE_ADR, + HW_ATL_RPFL2PROMIS_MODE_MSK, + HW_ATL_RPFL2PROMIS_MODE_SHIFT, + l2promiscuous_mode_en); +} + +void hw_atl_rpfl2unicast_flr_act_set(struct aq_hw_s *aq_hw, + u32 l2unicast_flr_act, + u32 filter) +{ + aq_hw_write_reg_bit(aq_hw, HW_ATL_RPFL2UC_ACTF_ADR(filter), + HW_ATL_RPFL2UC_ACTF_MSK, HW_ATL_RPFL2UC_ACTF_SHIFT, + l2unicast_flr_act); +} + +void hw_atl_rpfl2_uc_flr_en_set(struct aq_hw_s *aq_hw, u32 l2unicast_flr_en, + u32 filter) +{ + aq_hw_write_reg_bit(aq_hw, HW_ATL_RPFL2UC_ENF_ADR(filter), + HW_ATL_RPFL2UC_ENF_MSK, + HW_ATL_RPFL2UC_ENF_SHIFT, l2unicast_flr_en); +} + +void hw_atl_rpfl2unicast_dest_addresslsw_set(struct aq_hw_s *aq_hw, + u32 l2unicast_dest_addresslsw, + u32 filter) +{ + aq_hw_write_reg(aq_hw, HW_ATL_RPFL2UC_DAFLSW_ADR(filter), + l2unicast_dest_addresslsw); +} + +void hw_atl_rpfl2unicast_dest_addressmsw_set(struct aq_hw_s *aq_hw, + u32 l2unicast_dest_addressmsw, + u32 filter) +{ + aq_hw_write_reg_bit(aq_hw, HW_ATL_RPFL2UC_DAFMSW_ADR(filter), + HW_ATL_RPFL2UC_DAFMSW_MSK, + HW_ATL_RPFL2UC_DAFMSW_SHIFT, + l2unicast_dest_addressmsw); +} + +void hw_atl_rpfl2_accept_all_mc_packets_set(struct aq_hw_s *aq_hw, + u32 l2_accept_all_mc_packets) +{ + aq_hw_write_reg_bit(aq_hw, HW_ATL_RPFL2MC_ACCEPT_ALL_ADR, + HW_ATL_RPFL2MC_ACCEPT_ALL_MSK, + HW_ATL_RPFL2MC_ACCEPT_ALL_SHIFT, + l2_accept_all_mc_packets); +} + +void hw_atl_rpf_rpb_user_priority_tc_map_set(struct aq_hw_s *aq_hw, + u32 user_priority_tc_map, u32 tc) +{ +/* register address for bitfield rx_tc_up{t}[2:0] */ + static u32 rpf_rpb_rx_tc_upt_adr[8] = { + 0x000054c4U, 0x000054C4U, 0x000054C4U, 0x000054C4U, + 0x000054c4U, 0x000054C4U, 0x000054C4U, 0x000054C4U + }; + +/* bitmask for bitfield rx_tc_up{t}[2:0] */ + static u32 rpf_rpb_rx_tc_upt_msk[8] = { + 0x00000007U, 0x00000070U, 0x00000700U, 0x00007000U, + 0x00070000U, 0x00700000U, 0x07000000U, 0x70000000U + }; + +/* lower bit position of bitfield rx_tc_up{t}[2:0] */ + static u32 rpf_rpb_rx_tc_upt_shft[8] = { + 0U, 4U, 8U, 12U, 16U, 20U, 24U, 28U + }; + + aq_hw_write_reg_bit(aq_hw, rpf_rpb_rx_tc_upt_adr[tc], + rpf_rpb_rx_tc_upt_msk[tc], + rpf_rpb_rx_tc_upt_shft[tc], + user_priority_tc_map); +} + +void hw_atl_rpf_rss_key_addr_set(struct aq_hw_s *aq_hw, u32 rss_key_addr) +{ + aq_hw_write_reg_bit(aq_hw, HW_ATL_RPF_RSS_KEY_ADDR_ADR, + HW_ATL_RPF_RSS_KEY_ADDR_MSK, + HW_ATL_RPF_RSS_KEY_ADDR_SHIFT, + rss_key_addr); +} + +void hw_atl_rpf_rss_key_wr_data_set(struct aq_hw_s *aq_hw, u32 rss_key_wr_data) +{ + aq_hw_write_reg(aq_hw, HW_ATL_RPF_RSS_KEY_WR_DATA_ADR, + rss_key_wr_data); +} + +u32 hw_atl_rpf_rss_key_wr_en_get(struct aq_hw_s *aq_hw) +{ + return aq_hw_read_reg_bit(aq_hw, HW_ATL_RPF_RSS_KEY_WR_ENI_ADR, + HW_ATL_RPF_RSS_KEY_WR_ENI_MSK, + HW_ATL_RPF_RSS_KEY_WR_ENI_SHIFT); +} + +void hw_atl_rpf_rss_key_wr_en_set(struct aq_hw_s *aq_hw, u32 rss_key_wr_en) +{ + aq_hw_write_reg_bit(aq_hw, HW_ATL_RPF_RSS_KEY_WR_ENI_ADR, + HW_ATL_RPF_RSS_KEY_WR_ENI_MSK, + HW_ATL_RPF_RSS_KEY_WR_ENI_SHIFT, + rss_key_wr_en); +} + +void hw_atl_rpf_rss_redir_tbl_addr_set(struct aq_hw_s *aq_hw, + u32 rss_redir_tbl_addr) +{ + aq_hw_write_reg_bit(aq_hw, HW_ATL_RPF_RSS_REDIR_ADDR_ADR, + HW_ATL_RPF_RSS_REDIR_ADDR_MSK, + HW_ATL_RPF_RSS_REDIR_ADDR_SHIFT, + rss_redir_tbl_addr); +} + +void hw_atl_rpf_rss_redir_tbl_wr_data_set(struct aq_hw_s *aq_hw, + u32 rss_redir_tbl_wr_data) +{ + aq_hw_write_reg_bit(aq_hw, HW_ATL_RPF_RSS_REDIR_WR_DATA_ADR, + HW_ATL_RPF_RSS_REDIR_WR_DATA_MSK, + HW_ATL_RPF_RSS_REDIR_WR_DATA_SHIFT, + rss_redir_tbl_wr_data); +} + +u32 hw_atl_rpf_rss_redir_wr_en_get(struct aq_hw_s *aq_hw) +{ + return aq_hw_read_reg_bit(aq_hw, HW_ATL_RPF_RSS_REDIR_WR_ENI_ADR, + HW_ATL_RPF_RSS_REDIR_WR_ENI_MSK, + HW_ATL_RPF_RSS_REDIR_WR_ENI_SHIFT); +} + +void hw_atl_rpf_rss_redir_wr_en_set(struct aq_hw_s *aq_hw, u32 rss_redir_wr_en) +{ + aq_hw_write_reg_bit(aq_hw, HW_ATL_RPF_RSS_REDIR_WR_ENI_ADR, + HW_ATL_RPF_RSS_REDIR_WR_ENI_MSK, + HW_ATL_RPF_RSS_REDIR_WR_ENI_SHIFT, rss_redir_wr_en); +} + +void hw_atl_rpf_tpo_to_rpf_sys_lbk_set(struct aq_hw_s *aq_hw, + u32 tpo_to_rpf_sys_lbk) +{ + aq_hw_write_reg_bit(aq_hw, HW_ATL_RPF_TPO_RPF_SYS_LBK_ADR, + HW_ATL_RPF_TPO_RPF_SYS_LBK_MSK, + HW_ATL_RPF_TPO_RPF_SYS_LBK_SHIFT, + tpo_to_rpf_sys_lbk); +} + +void hw_atl_rpf_vlan_inner_etht_set(struct aq_hw_s *aq_hw, u32 vlan_inner_etht) +{ + aq_hw_write_reg_bit(aq_hw, HW_ATL_RPF_VL_INNER_TPID_ADR, + HW_ATL_RPF_VL_INNER_TPID_MSK, + HW_ATL_RPF_VL_INNER_TPID_SHIFT, + vlan_inner_etht); +} + +void hw_atl_rpf_vlan_outer_etht_set(struct aq_hw_s *aq_hw, u32 vlan_outer_etht) +{ + aq_hw_write_reg_bit(aq_hw, HW_ATL_RPF_VL_OUTER_TPID_ADR, + HW_ATL_RPF_VL_OUTER_TPID_MSK, + HW_ATL_RPF_VL_OUTER_TPID_SHIFT, + vlan_outer_etht); +} + +void hw_atl_rpf_vlan_prom_mode_en_set(struct aq_hw_s *aq_hw, + u32 vlan_prom_mode_en) +{ + aq_hw_write_reg_bit(aq_hw, HW_ATL_RPF_VL_PROMIS_MODE_ADR, + HW_ATL_RPF_VL_PROMIS_MODE_MSK, + HW_ATL_RPF_VL_PROMIS_MODE_SHIFT, + vlan_prom_mode_en); +} + +void hw_atl_rpf_vlan_accept_untagged_packets_set(struct aq_hw_s *aq_hw, + u32 vlan_acc_untagged_packets) +{ + aq_hw_write_reg_bit(aq_hw, HW_ATL_RPF_VL_ACCEPT_UNTAGGED_MODE_ADR, + HW_ATL_RPF_VL_ACCEPT_UNTAGGED_MODE_MSK, + HW_ATL_RPF_VL_ACCEPT_UNTAGGED_MODE_SHIFT, + vlan_acc_untagged_packets); +} + +void hw_atl_rpf_vlan_untagged_act_set(struct aq_hw_s *aq_hw, + u32 vlan_untagged_act) +{ + aq_hw_write_reg_bit(aq_hw, HW_ATL_RPF_VL_UNTAGGED_ACT_ADR, + HW_ATL_RPF_VL_UNTAGGED_ACT_MSK, + HW_ATL_RPF_VL_UNTAGGED_ACT_SHIFT, + vlan_untagged_act); +} + +void hw_atl_rpf_vlan_flr_en_set(struct aq_hw_s *aq_hw, u32 vlan_flr_en, + u32 filter) +{ + aq_hw_write_reg_bit(aq_hw, HW_ATL_RPF_VL_EN_F_ADR(filter), + HW_ATL_RPF_VL_EN_F_MSK, + HW_ATL_RPF_VL_EN_F_SHIFT, + vlan_flr_en); +} + +void hw_atl_rpf_vlan_flr_act_set(struct aq_hw_s *aq_hw, u32 vlan_flr_act, + u32 filter) +{ + aq_hw_write_reg_bit(aq_hw, HW_ATL_RPF_VL_ACT_F_ADR(filter), + HW_ATL_RPF_VL_ACT_F_MSK, + HW_ATL_RPF_VL_ACT_F_SHIFT, + vlan_flr_act); +} + +void hw_atl_rpf_vlan_id_flr_set(struct aq_hw_s *aq_hw, u32 vlan_id_flr, + u32 filter) +{ + aq_hw_write_reg_bit(aq_hw, HW_ATL_RPF_VL_ID_F_ADR(filter), + HW_ATL_RPF_VL_ID_F_MSK, + HW_ATL_RPF_VL_ID_F_SHIFT, + vlan_id_flr); +} + +void hw_atl_rpf_etht_flr_en_set(struct aq_hw_s *aq_hw, u32 etht_flr_en, + u32 filter) +{ + aq_hw_write_reg_bit(aq_hw, HW_ATL_RPF_ET_ENF_ADR(filter), + HW_ATL_RPF_ET_ENF_MSK, + HW_ATL_RPF_ET_ENF_SHIFT, etht_flr_en); +} + +void hw_atl_rpf_etht_user_priority_en_set(struct aq_hw_s *aq_hw, + u32 etht_user_priority_en, u32 filter) +{ + aq_hw_write_reg_bit(aq_hw, HW_ATL_RPF_ET_UPFEN_ADR(filter), + HW_ATL_RPF_ET_UPFEN_MSK, HW_ATL_RPF_ET_UPFEN_SHIFT, + etht_user_priority_en); +} + +void hw_atl_rpf_etht_rx_queue_en_set(struct aq_hw_s *aq_hw, + u32 etht_rx_queue_en, + u32 filter) +{ + aq_hw_write_reg_bit(aq_hw, HW_ATL_RPF_ET_RXQFEN_ADR(filter), + HW_ATL_RPF_ET_RXQFEN_MSK, + HW_ATL_RPF_ET_RXQFEN_SHIFT, + etht_rx_queue_en); +} + +void hw_atl_rpf_etht_user_priority_set(struct aq_hw_s *aq_hw, + u32 etht_user_priority, + u32 filter) +{ + aq_hw_write_reg_bit(aq_hw, HW_ATL_RPF_ET_UPF_ADR(filter), + HW_ATL_RPF_ET_UPF_MSK, + HW_ATL_RPF_ET_UPF_SHIFT, etht_user_priority); +} + +void hw_atl_rpf_etht_rx_queue_set(struct aq_hw_s *aq_hw, u32 etht_rx_queue, + u32 filter) +{ + aq_hw_write_reg_bit(aq_hw, HW_ATL_RPF_ET_RXQF_ADR(filter), + HW_ATL_RPF_ET_RXQF_MSK, + HW_ATL_RPF_ET_RXQF_SHIFT, etht_rx_queue); +} + +void hw_atl_rpf_etht_mgt_queue_set(struct aq_hw_s *aq_hw, u32 etht_mgt_queue, + u32 filter) +{ + aq_hw_write_reg_bit(aq_hw, HW_ATL_RPF_ET_MNG_RXQF_ADR(filter), + HW_ATL_RPF_ET_MNG_RXQF_MSK, + HW_ATL_RPF_ET_MNG_RXQF_SHIFT, + etht_mgt_queue); +} + +void hw_atl_rpf_etht_flr_act_set(struct aq_hw_s *aq_hw, u32 etht_flr_act, + u32 filter) +{ + aq_hw_write_reg_bit(aq_hw, HW_ATL_RPF_ET_ACTF_ADR(filter), + HW_ATL_RPF_ET_ACTF_MSK, + HW_ATL_RPF_ET_ACTF_SHIFT, etht_flr_act); +} + +void hw_atl_rpf_etht_flr_set(struct aq_hw_s *aq_hw, u32 etht_flr, u32 filter) +{ + aq_hw_write_reg_bit(aq_hw, HW_ATL_RPF_ET_VALF_ADR(filter), + HW_ATL_RPF_ET_VALF_MSK, + HW_ATL_RPF_ET_VALF_SHIFT, etht_flr); +} + +/* RPO: rx packet offload */ +void hw_atl_rpo_ipv4header_crc_offload_en_set(struct aq_hw_s *aq_hw, + u32 ipv4header_crc_offload_en) +{ + aq_hw_write_reg_bit(aq_hw, HW_ATL_RPO_IPV4CHK_EN_ADR, + HW_ATL_RPO_IPV4CHK_EN_MSK, + HW_ATL_RPO_IPV4CHK_EN_SHIFT, + ipv4header_crc_offload_en); +} + +void hw_atl_rpo_rx_desc_vlan_stripping_set(struct aq_hw_s *aq_hw, + u32 rx_desc_vlan_stripping, + u32 descriptor) +{ + aq_hw_write_reg_bit(aq_hw, HW_ATL_RPO_DESCDVL_STRIP_ADR(descriptor), + HW_ATL_RPO_DESCDVL_STRIP_MSK, + HW_ATL_RPO_DESCDVL_STRIP_SHIFT, + rx_desc_vlan_stripping); +} + +void hw_atl_rpo_tcp_udp_crc_offload_en_set(struct aq_hw_s *aq_hw, + u32 tcp_udp_crc_offload_en) +{ + aq_hw_write_reg_bit(aq_hw, HW_ATL_RPOL4CHK_EN_ADR, + HW_ATL_RPOL4CHK_EN_MSK, + HW_ATL_RPOL4CHK_EN_SHIFT, tcp_udp_crc_offload_en); +} + +void hw_atl_rpo_lro_en_set(struct aq_hw_s *aq_hw, u32 lro_en) +{ + aq_hw_write_reg(aq_hw, HW_ATL_RPO_LRO_EN_ADR, lro_en); +} + +void hw_atl_rpo_lro_patch_optimization_en_set(struct aq_hw_s *aq_hw, + u32 lro_patch_optimization_en) +{ + aq_hw_write_reg_bit(aq_hw, HW_ATL_RPO_LRO_PTOPT_EN_ADR, + HW_ATL_RPO_LRO_PTOPT_EN_MSK, + HW_ATL_RPO_LRO_PTOPT_EN_SHIFT, + lro_patch_optimization_en); +} + +void hw_atl_rpo_lro_qsessions_lim_set(struct aq_hw_s *aq_hw, + u32 lro_qsessions_lim) +{ + aq_hw_write_reg_bit(aq_hw, HW_ATL_RPO_LRO_QSES_LMT_ADR, + HW_ATL_RPO_LRO_QSES_LMT_MSK, + HW_ATL_RPO_LRO_QSES_LMT_SHIFT, + lro_qsessions_lim); +} + +void hw_atl_rpo_lro_total_desc_lim_set(struct aq_hw_s *aq_hw, + u32 lro_total_desc_lim) +{ + aq_hw_write_reg_bit(aq_hw, HW_ATL_RPO_LRO_TOT_DSC_LMT_ADR, + HW_ATL_RPO_LRO_TOT_DSC_LMT_MSK, + HW_ATL_RPO_LRO_TOT_DSC_LMT_SHIFT, + lro_total_desc_lim); +} + +void hw_atl_rpo_lro_min_pay_of_first_pkt_set(struct aq_hw_s *aq_hw, + u32 lro_min_pld_of_first_pkt) +{ + aq_hw_write_reg_bit(aq_hw, HW_ATL_RPO_LRO_PKT_MIN_ADR, + HW_ATL_RPO_LRO_PKT_MIN_MSK, + HW_ATL_RPO_LRO_PKT_MIN_SHIFT, + lro_min_pld_of_first_pkt); +} + +void hw_atl_rpo_lro_pkt_lim_set(struct aq_hw_s *aq_hw, u32 lro_pkt_lim) +{ + aq_hw_write_reg(aq_hw, HW_ATL_RPO_LRO_RSC_MAX_ADR, lro_pkt_lim); +} + +void hw_atl_rpo_lro_max_num_of_descriptors_set(struct aq_hw_s *aq_hw, + u32 lro_max_number_of_descriptors, + u32 lro) +{ +/* Register address for bitfield lro{L}_des_max[1:0] */ + static u32 rpo_lro_ldes_max_adr[32] = { + 0x000055A0U, 0x000055A0U, 0x000055A0U, 0x000055A0U, + 0x000055A0U, 0x000055A0U, 0x000055A0U, 0x000055A0U, + 0x000055A4U, 0x000055A4U, 0x000055A4U, 0x000055A4U, + 0x000055A4U, 0x000055A4U, 0x000055A4U, 0x000055A4U, + 0x000055A8U, 0x000055A8U, 0x000055A8U, 0x000055A8U, + 0x000055A8U, 0x000055A8U, 0x000055A8U, 0x000055A8U, + 0x000055ACU, 0x000055ACU, 0x000055ACU, 0x000055ACU, + 0x000055ACU, 0x000055ACU, 0x000055ACU, 0x000055ACU + }; + +/* Bitmask for bitfield lro{L}_des_max[1:0] */ + static u32 rpo_lro_ldes_max_msk[32] = { + 0x00000003U, 0x00000030U, 0x00000300U, 0x00003000U, + 0x00030000U, 0x00300000U, 0x03000000U, 0x30000000U, + 0x00000003U, 0x00000030U, 0x00000300U, 0x00003000U, + 0x00030000U, 0x00300000U, 0x03000000U, 0x30000000U, + 0x00000003U, 0x00000030U, 0x00000300U, 0x00003000U, + 0x00030000U, 0x00300000U, 0x03000000U, 0x30000000U, + 0x00000003U, 0x00000030U, 0x00000300U, 0x00003000U, + 0x00030000U, 0x00300000U, 0x03000000U, 0x30000000U + }; + +/* Lower bit position of bitfield lro{L}_des_max[1:0] */ + static u32 rpo_lro_ldes_max_shift[32] = { + 0U, 4U, 8U, 12U, 16U, 20U, 24U, 28U, + 0U, 4U, 8U, 12U, 16U, 20U, 24U, 28U, + 0U, 4U, 8U, 12U, 16U, 20U, 24U, 28U, + 0U, 4U, 8U, 12U, 16U, 20U, 24U, 28U + }; + + aq_hw_write_reg_bit(aq_hw, rpo_lro_ldes_max_adr[lro], + rpo_lro_ldes_max_msk[lro], + rpo_lro_ldes_max_shift[lro], + lro_max_number_of_descriptors); +} + +void hw_atl_rpo_lro_time_base_divider_set(struct aq_hw_s *aq_hw, + u32 lro_time_base_divider) +{ + aq_hw_write_reg_bit(aq_hw, HW_ATL_RPO_LRO_TB_DIV_ADR, + HW_ATL_RPO_LRO_TB_DIV_MSK, + HW_ATL_RPO_LRO_TB_DIV_SHIFT, + lro_time_base_divider); +} + +void hw_atl_rpo_lro_inactive_interval_set(struct aq_hw_s *aq_hw, + u32 lro_inactive_interval) +{ + aq_hw_write_reg_bit(aq_hw, HW_ATL_RPO_LRO_INA_IVAL_ADR, + HW_ATL_RPO_LRO_INA_IVAL_MSK, + HW_ATL_RPO_LRO_INA_IVAL_SHIFT, + lro_inactive_interval); +} + +void hw_atl_rpo_lro_max_coalescing_interval_set(struct aq_hw_s *aq_hw, + u32 lro_max_coal_interval) +{ + aq_hw_write_reg_bit(aq_hw, HW_ATL_RPO_LRO_MAX_IVAL_ADR, + HW_ATL_RPO_LRO_MAX_IVAL_MSK, + HW_ATL_RPO_LRO_MAX_IVAL_SHIFT, + lro_max_coal_interval); +} + +/* rx */ +void hw_atl_rx_rx_reg_res_dis_set(struct aq_hw_s *aq_hw, u32 rx_reg_res_dis) +{ + aq_hw_write_reg_bit(aq_hw, HW_ATL_RX_REG_RES_DSBL_ADR, + HW_ATL_RX_REG_RES_DSBL_MSK, + HW_ATL_RX_REG_RES_DSBL_SHIFT, + rx_reg_res_dis); +} + +/* tdm */ +void hw_atl_tdm_cpu_id_set(struct aq_hw_s *aq_hw, u32 cpuid, u32 dca) +{ + aq_hw_write_reg_bit(aq_hw, HW_ATL_TDM_DCADCPUID_ADR(dca), + HW_ATL_TDM_DCADCPUID_MSK, + HW_ATL_TDM_DCADCPUID_SHIFT, cpuid); +} + +void hw_atl_tdm_large_send_offload_en_set(struct aq_hw_s *aq_hw, + u32 large_send_offload_en) +{ + aq_hw_write_reg(aq_hw, HW_ATL_TDM_LSO_EN_ADR, large_send_offload_en); +} + +void hw_atl_tdm_tx_dca_en_set(struct aq_hw_s *aq_hw, u32 tx_dca_en) +{ + aq_hw_write_reg_bit(aq_hw, HW_ATL_TDM_DCA_EN_ADR, HW_ATL_TDM_DCA_EN_MSK, + HW_ATL_TDM_DCA_EN_SHIFT, tx_dca_en); +} + +void hw_atl_tdm_tx_dca_mode_set(struct aq_hw_s *aq_hw, u32 tx_dca_mode) +{ + aq_hw_write_reg_bit(aq_hw, HW_ATL_TDM_DCA_MODE_ADR, + HW_ATL_TDM_DCA_MODE_MSK, + HW_ATL_TDM_DCA_MODE_SHIFT, tx_dca_mode); +} + +void hw_atl_tdm_tx_desc_dca_en_set(struct aq_hw_s *aq_hw, u32 tx_desc_dca_en, + u32 dca) +{ + aq_hw_write_reg_bit(aq_hw, HW_ATL_TDM_DCADDESC_EN_ADR(dca), + HW_ATL_TDM_DCADDESC_EN_MSK, + HW_ATL_TDM_DCADDESC_EN_SHIFT, + tx_desc_dca_en); +} + +void hw_atl_tdm_tx_desc_en_set(struct aq_hw_s *aq_hw, u32 tx_desc_en, + u32 descriptor) +{ + aq_hw_write_reg_bit(aq_hw, HW_ATL_TDM_DESCDEN_ADR(descriptor), + HW_ATL_TDM_DESCDEN_MSK, + HW_ATL_TDM_DESCDEN_SHIFT, + tx_desc_en); +} + +u32 hw_atl_tdm_tx_desc_head_ptr_get(struct aq_hw_s *aq_hw, u32 descriptor) +{ + return aq_hw_read_reg_bit(aq_hw, HW_ATL_TDM_DESCDHD_ADR(descriptor), + HW_ATL_TDM_DESCDHD_MSK, + HW_ATL_TDM_DESCDHD_SHIFT); +} + +void hw_atl_tdm_tx_desc_len_set(struct aq_hw_s *aq_hw, u32 tx_desc_len, + u32 descriptor) +{ + aq_hw_write_reg_bit(aq_hw, HW_ATL_TDM_DESCDLEN_ADR(descriptor), + HW_ATL_TDM_DESCDLEN_MSK, + HW_ATL_TDM_DESCDLEN_SHIFT, + tx_desc_len); +} + +void hw_atl_tdm_tx_desc_wr_wb_irq_en_set(struct aq_hw_s *aq_hw, + u32 tx_desc_wr_wb_irq_en) +{ + aq_hw_write_reg_bit(aq_hw, HW_ATL_TDM_INT_DESC_WRB_EN_ADR, + HW_ATL_TDM_INT_DESC_WRB_EN_MSK, + HW_ATL_TDM_INT_DESC_WRB_EN_SHIFT, + tx_desc_wr_wb_irq_en); +} + +void hw_atl_tdm_tx_desc_wr_wb_threshold_set(struct aq_hw_s *aq_hw, + u32 tx_desc_wr_wb_threshold, + u32 descriptor) +{ + aq_hw_write_reg_bit(aq_hw, HW_ATL_TDM_DESCDWRB_THRESH_ADR(descriptor), + HW_ATL_TDM_DESCDWRB_THRESH_MSK, + HW_ATL_TDM_DESCDWRB_THRESH_SHIFT, + tx_desc_wr_wb_threshold); +} + +void hw_atl_tdm_tdm_intr_moder_en_set(struct aq_hw_s *aq_hw, + u32 tdm_irq_moderation_en) +{ + aq_hw_write_reg_bit(aq_hw, HW_ATL_TDM_INT_MOD_EN_ADR, + HW_ATL_TDM_INT_MOD_EN_MSK, + HW_ATL_TDM_INT_MOD_EN_SHIFT, + tdm_irq_moderation_en); +} + +/* thm */ +void hw_atl_thm_lso_tcp_flag_of_first_pkt_set(struct aq_hw_s *aq_hw, + u32 lso_tcp_flag_of_first_pkt) +{ + aq_hw_write_reg_bit(aq_hw, HW_ATL_THM_LSO_TCP_FLAG_FIRST_ADR, + HW_ATL_THM_LSO_TCP_FLAG_FIRST_MSK, + HW_ATL_THM_LSO_TCP_FLAG_FIRST_SHIFT, + lso_tcp_flag_of_first_pkt); +} + +void hw_atl_thm_lso_tcp_flag_of_last_pkt_set(struct aq_hw_s *aq_hw, + u32 lso_tcp_flag_of_last_pkt) +{ + aq_hw_write_reg_bit(aq_hw, HW_ATL_THM_LSO_TCP_FLAG_LAST_ADR, + HW_ATL_THM_LSO_TCP_FLAG_LAST_MSK, + HW_ATL_THM_LSO_TCP_FLAG_LAST_SHIFT, + lso_tcp_flag_of_last_pkt); +} + +void hw_atl_thm_lso_tcp_flag_of_middle_pkt_set(struct aq_hw_s *aq_hw, + u32 lso_tcp_flag_of_middle_pkt) +{ + aq_hw_write_reg_bit(aq_hw, HW_ATL_THM_LSO_TCP_FLAG_MID_ADR, + HW_ATL_THM_LSO_TCP_FLAG_MID_MSK, + HW_ATL_THM_LSO_TCP_FLAG_MID_SHIFT, + lso_tcp_flag_of_middle_pkt); +} + +/* TPB: tx packet buffer */ +void hw_atl_tpb_tx_buff_en_set(struct aq_hw_s *aq_hw, u32 tx_buff_en) +{ + aq_hw_write_reg_bit(aq_hw, HW_ATL_TPB_TX_BUF_EN_ADR, + HW_ATL_TPB_TX_BUF_EN_MSK, + HW_ATL_TPB_TX_BUF_EN_SHIFT, tx_buff_en); +} + +void hw_atl_tpb_tx_buff_hi_threshold_per_tc_set(struct aq_hw_s *aq_hw, + u32 tx_buff_hi_threshold_per_tc, + u32 buffer) +{ + aq_hw_write_reg_bit(aq_hw, HW_ATL_TPB_TXBHI_THRESH_ADR(buffer), + HW_ATL_TPB_TXBHI_THRESH_MSK, + HW_ATL_TPB_TXBHI_THRESH_SHIFT, + tx_buff_hi_threshold_per_tc); +} + +void hw_atl_tpb_tx_buff_lo_threshold_per_tc_set(struct aq_hw_s *aq_hw, + u32 tx_buff_lo_threshold_per_tc, + u32 buffer) +{ + aq_hw_write_reg_bit(aq_hw, HW_ATL_TPB_TXBLO_THRESH_ADR(buffer), + HW_ATL_TPB_TXBLO_THRESH_MSK, + HW_ATL_TPB_TXBLO_THRESH_SHIFT, + tx_buff_lo_threshold_per_tc); +} + +void hw_atl_tpb_tx_dma_sys_lbk_en_set(struct aq_hw_s *aq_hw, u32 tx_dma_sys_lbk_en) +{ + aq_hw_write_reg_bit(aq_hw, HW_ATL_TPB_DMA_SYS_LBK_ADR, + HW_ATL_TPB_DMA_SYS_LBK_MSK, + HW_ATL_TPB_DMA_SYS_LBK_SHIFT, + tx_dma_sys_lbk_en); +} + +void hw_atl_tpb_tx_pkt_buff_size_per_tc_set(struct aq_hw_s *aq_hw, + u32 tx_pkt_buff_size_per_tc, u32 buffer) +{ + aq_hw_write_reg_bit(aq_hw, HW_ATL_TPB_TXBBUF_SIZE_ADR(buffer), + HW_ATL_TPB_TXBBUF_SIZE_MSK, + HW_ATL_TPB_TXBBUF_SIZE_SHIFT, + tx_pkt_buff_size_per_tc); +} + +void hw_atl_tpb_tx_path_scp_ins_en_set(struct aq_hw_s *aq_hw, u32 tx_path_scp_ins_en) +{ + aq_hw_write_reg_bit(aq_hw, HW_ATL_TPB_TX_SCP_INS_EN_ADR, + HW_ATL_TPB_TX_SCP_INS_EN_MSK, + HW_ATL_TPB_TX_SCP_INS_EN_SHIFT, + tx_path_scp_ins_en); +} + +/* TPO: tx packet offload */ +void hw_atl_tpo_ipv4header_crc_offload_en_set(struct aq_hw_s *aq_hw, + u32 ipv4header_crc_offload_en) +{ + aq_hw_write_reg_bit(aq_hw, HW_ATL_TPO_IPV4CHK_EN_ADR, + HW_ATL_TPO_IPV4CHK_EN_MSK, + HW_ATL_TPO_IPV4CHK_EN_SHIFT, + ipv4header_crc_offload_en); +} + +void hw_atl_tpo_tcp_udp_crc_offload_en_set(struct aq_hw_s *aq_hw, + u32 tcp_udp_crc_offload_en) +{ + aq_hw_write_reg_bit(aq_hw, HW_ATL_TPOL4CHK_EN_ADR, + HW_ATL_TPOL4CHK_EN_MSK, + HW_ATL_TPOL4CHK_EN_SHIFT, + tcp_udp_crc_offload_en); +} + +void hw_atl_tpo_tx_pkt_sys_lbk_en_set(struct aq_hw_s *aq_hw, + u32 tx_pkt_sys_lbk_en) +{ + aq_hw_write_reg_bit(aq_hw, HW_ATL_TPO_PKT_SYS_LBK_ADR, + HW_ATL_TPO_PKT_SYS_LBK_MSK, + HW_ATL_TPO_PKT_SYS_LBK_SHIFT, + tx_pkt_sys_lbk_en); +} + +/* TPS: tx packet scheduler */ +void hw_atl_tps_tx_pkt_shed_data_arb_mode_set(struct aq_hw_s *aq_hw, + u32 tx_pkt_shed_data_arb_mode) +{ + aq_hw_write_reg_bit(aq_hw, HW_ATL_TPS_DATA_TC_ARB_MODE_ADR, + HW_ATL_TPS_DATA_TC_ARB_MODE_MSK, + HW_ATL_TPS_DATA_TC_ARB_MODE_SHIFT, + tx_pkt_shed_data_arb_mode); +} + +void hw_atl_tps_tx_pkt_shed_desc_rate_curr_time_res_set(struct aq_hw_s *aq_hw, + u32 curr_time_res) +{ + aq_hw_write_reg_bit(aq_hw, HW_ATL_TPS_DESC_RATE_TA_RST_ADR, + HW_ATL_TPS_DESC_RATE_TA_RST_MSK, + HW_ATL_TPS_DESC_RATE_TA_RST_SHIFT, + curr_time_res); +} + +void hw_atl_tps_tx_pkt_shed_desc_rate_lim_set(struct aq_hw_s *aq_hw, + u32 tx_pkt_shed_desc_rate_lim) +{ + aq_hw_write_reg_bit(aq_hw, HW_ATL_TPS_DESC_RATE_LIM_ADR, + HW_ATL_TPS_DESC_RATE_LIM_MSK, + HW_ATL_TPS_DESC_RATE_LIM_SHIFT, + tx_pkt_shed_desc_rate_lim); +} + +void hw_atl_tps_tx_pkt_shed_desc_tc_arb_mode_set(struct aq_hw_s *aq_hw, + u32 arb_mode) +{ + aq_hw_write_reg_bit(aq_hw, HW_ATL_TPS_DESC_TC_ARB_MODE_ADR, + HW_ATL_TPS_DESC_TC_ARB_MODE_MSK, + HW_ATL_TPS_DESC_TC_ARB_MODE_SHIFT, + arb_mode); +} + +void hw_atl_tps_tx_pkt_shed_desc_tc_max_credit_set(struct aq_hw_s *aq_hw, + u32 max_credit, + u32 tc) +{ + aq_hw_write_reg_bit(aq_hw, HW_ATL_TPS_DESC_TCTCREDIT_MAX_ADR(tc), + HW_ATL_TPS_DESC_TCTCREDIT_MAX_MSK, + HW_ATL_TPS_DESC_TCTCREDIT_MAX_SHIFT, + max_credit); +} + +void hw_atl_tps_tx_pkt_shed_desc_tc_weight_set(struct aq_hw_s *aq_hw, + u32 tx_pkt_shed_desc_tc_weight, + u32 tc) +{ + aq_hw_write_reg_bit(aq_hw, HW_ATL_TPS_DESC_TCTWEIGHT_ADR(tc), + HW_ATL_TPS_DESC_TCTWEIGHT_MSK, + HW_ATL_TPS_DESC_TCTWEIGHT_SHIFT, + tx_pkt_shed_desc_tc_weight); +} + +void hw_atl_tps_tx_pkt_shed_desc_vm_arb_mode_set(struct aq_hw_s *aq_hw, + u32 arb_mode) +{ + aq_hw_write_reg_bit(aq_hw, HW_ATL_TPS_DESC_VM_ARB_MODE_ADR, + HW_ATL_TPS_DESC_VM_ARB_MODE_MSK, + HW_ATL_TPS_DESC_VM_ARB_MODE_SHIFT, + arb_mode); +} + +void hw_atl_tps_tx_pkt_shed_tc_data_max_credit_set(struct aq_hw_s *aq_hw, + u32 max_credit, + u32 tc) +{ + aq_hw_write_reg_bit(aq_hw, HW_ATL_TPS_DATA_TCTCREDIT_MAX_ADR(tc), + HW_ATL_TPS_DATA_TCTCREDIT_MAX_MSK, + HW_ATL_TPS_DATA_TCTCREDIT_MAX_SHIFT, + max_credit); +} + +void hw_atl_tps_tx_pkt_shed_tc_data_weight_set(struct aq_hw_s *aq_hw, + u32 tx_pkt_shed_tc_data_weight, + u32 tc) +{ + aq_hw_write_reg_bit(aq_hw, HW_ATL_TPS_DATA_TCTWEIGHT_ADR(tc), + HW_ATL_TPS_DATA_TCTWEIGHT_MSK, + HW_ATL_TPS_DATA_TCTWEIGHT_SHIFT, + tx_pkt_shed_tc_data_weight); +} + +/* tx */ +void hw_atl_tx_tx_reg_res_dis_set(struct aq_hw_s *aq_hw, u32 tx_reg_res_dis) +{ + aq_hw_write_reg_bit(aq_hw, HW_ATL_TX_REG_RES_DSBL_ADR, + HW_ATL_TX_REG_RES_DSBL_MSK, + HW_ATL_TX_REG_RES_DSBL_SHIFT, tx_reg_res_dis); +} + +/* msm */ +u32 hw_atl_msm_reg_access_status_get(struct aq_hw_s *aq_hw) +{ + return aq_hw_read_reg_bit(aq_hw, HW_ATL_MSM_REG_ACCESS_BUSY_ADR, + HW_ATL_MSM_REG_ACCESS_BUSY_MSK, + HW_ATL_MSM_REG_ACCESS_BUSY_SHIFT); +} + +void hw_atl_msm_reg_addr_for_indirect_addr_set(struct aq_hw_s *aq_hw, + u32 reg_addr_for_indirect_addr) +{ + aq_hw_write_reg_bit(aq_hw, HW_ATL_MSM_REG_ADDR_ADR, + HW_ATL_MSM_REG_ADDR_MSK, + HW_ATL_MSM_REG_ADDR_SHIFT, + reg_addr_for_indirect_addr); +} + +void hw_atl_msm_reg_rd_strobe_set(struct aq_hw_s *aq_hw, u32 reg_rd_strobe) +{ + aq_hw_write_reg_bit(aq_hw, HW_ATL_MSM_REG_RD_STROBE_ADR, + HW_ATL_MSM_REG_RD_STROBE_MSK, + HW_ATL_MSM_REG_RD_STROBE_SHIFT, + reg_rd_strobe); +} + +u32 hw_atl_msm_reg_rd_data_get(struct aq_hw_s *aq_hw) +{ + return aq_hw_read_reg(aq_hw, HW_ATL_MSM_REG_RD_DATA_ADR); +} + +void hw_atl_msm_reg_wr_data_set(struct aq_hw_s *aq_hw, u32 reg_wr_data) +{ + aq_hw_write_reg(aq_hw, HW_ATL_MSM_REG_WR_DATA_ADR, reg_wr_data); +} + +void hw_atl_msm_reg_wr_strobe_set(struct aq_hw_s *aq_hw, u32 reg_wr_strobe) +{ + aq_hw_write_reg_bit(aq_hw, HW_ATL_MSM_REG_WR_STROBE_ADR, + HW_ATL_MSM_REG_WR_STROBE_MSK, + HW_ATL_MSM_REG_WR_STROBE_SHIFT, + reg_wr_strobe); +} + +/* pci */ +void hw_atl_pci_pci_reg_res_dis_set(struct aq_hw_s *aq_hw, u32 pci_reg_res_dis) +{ + aq_hw_write_reg_bit(aq_hw, HW_ATL_PCI_REG_RES_DSBL_ADR, + HW_ATL_PCI_REG_RES_DSBL_MSK, + HW_ATL_PCI_REG_RES_DSBL_SHIFT, + pci_reg_res_dis); +} + +void hw_atl_reg_glb_cpu_scratch_scp_set(struct aq_hw_s *aq_hw, + u32 glb_cpu_scratch_scp, + u32 scratch_scp) +{ + aq_hw_write_reg(aq_hw, HW_ATL_GLB_CPU_SCRATCH_SCP_ADR(scratch_scp), + glb_cpu_scratch_scp); +} + +void hw_atl_mcp_up_force_intr_set(struct aq_hw_s *aq_hw, u32 up_force_intr) +{ + aq_hw_write_reg_bit(aq_hw, HW_ATL_MCP_UP_FORCE_INTERRUPT_ADR, + HW_ATL_MCP_UP_FORCE_INTERRUPT_MSK, + HW_ATL_MCP_UP_FORCE_INTERRUPT_SHIFT, + up_force_intr); +} diff --git a/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_llh.h b/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_llh.h new file mode 100644 index 000000000..41f239928 --- /dev/null +++ b/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_llh.h @@ -0,0 +1,707 @@ +/* + * aQuantia Corporation Network Driver + * Copyright (C) 2014-2017 aQuantia Corporation. All rights reserved + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + */ + +/* File hw_atl_llh.h: Declarations of bitfield and register access functions for + * Atlantic registers. + */ + +#ifndef HW_ATL_LLH_H +#define HW_ATL_LLH_H + +#include <linux/types.h> + +struct aq_hw_s; + +/* global */ + +/* set global microprocessor semaphore */ +void hw_atl_reg_glb_cpu_sem_set(struct aq_hw_s *aq_hw, u32 glb_cpu_sem, + u32 semaphore); + +/* get global microprocessor semaphore */ +u32 hw_atl_reg_glb_cpu_sem_get(struct aq_hw_s *aq_hw, u32 semaphore); + +/* set global register reset disable */ +void hw_atl_glb_glb_reg_res_dis_set(struct aq_hw_s *aq_hw, u32 glb_reg_res_dis); + +/* set soft reset */ +void hw_atl_glb_soft_res_set(struct aq_hw_s *aq_hw, u32 soft_res); + +/* get soft reset */ +u32 hw_atl_glb_soft_res_get(struct aq_hw_s *aq_hw); + +/* stats */ + +u32 hw_atl_rpb_rx_dma_drop_pkt_cnt_get(struct aq_hw_s *aq_hw); + +/* get rx dma good octet counter lsw */ +u32 hw_atl_stats_rx_dma_good_octet_counterlsw_get(struct aq_hw_s *aq_hw); + +/* get rx dma good packet counter lsw */ +u32 hw_atl_stats_rx_dma_good_pkt_counterlsw_get(struct aq_hw_s *aq_hw); + +/* get tx dma good octet counter lsw */ +u32 hw_atl_stats_tx_dma_good_octet_counterlsw_get(struct aq_hw_s *aq_hw); + +/* get tx dma good packet counter lsw */ +u32 hw_atl_stats_tx_dma_good_pkt_counterlsw_get(struct aq_hw_s *aq_hw); + +/* get rx dma good octet counter msw */ +u32 hw_atl_stats_rx_dma_good_octet_countermsw_get(struct aq_hw_s *aq_hw); + +/* get rx dma good packet counter msw */ +u32 hw_atl_stats_rx_dma_good_pkt_countermsw_get(struct aq_hw_s *aq_hw); + +/* get tx dma good octet counter msw */ +u32 hw_atl_stats_tx_dma_good_octet_countermsw_get(struct aq_hw_s *aq_hw); + +/* get tx dma good packet counter msw */ +u32 hw_atl_stats_tx_dma_good_pkt_countermsw_get(struct aq_hw_s *aq_hw); + +/* get msm rx errors counter register */ +u32 hw_atl_reg_mac_msm_rx_errs_cnt_get(struct aq_hw_s *aq_hw); + +/* get msm rx unicast frames counter register */ +u32 hw_atl_reg_mac_msm_rx_ucst_frm_cnt_get(struct aq_hw_s *aq_hw); + +/* get msm rx multicast frames counter register */ +u32 hw_atl_reg_mac_msm_rx_mcst_frm_cnt_get(struct aq_hw_s *aq_hw); + +/* get msm rx broadcast frames counter register */ +u32 hw_atl_reg_mac_msm_rx_bcst_frm_cnt_get(struct aq_hw_s *aq_hw); + +/* get msm rx broadcast octets counter register 1 */ +u32 hw_atl_reg_mac_msm_rx_bcst_octets_counter1get(struct aq_hw_s *aq_hw); + +/* get msm rx unicast octets counter register 0 */ +u32 hw_atl_reg_mac_msm_rx_ucst_octets_counter0get(struct aq_hw_s *aq_hw); + +/* get rx dma statistics counter 7 */ +u32 hw_atl_reg_rx_dma_stat_counter7get(struct aq_hw_s *aq_hw); + +/* get msm tx errors counter register */ +u32 hw_atl_reg_mac_msm_tx_errs_cnt_get(struct aq_hw_s *aq_hw); + +/* get msm tx unicast frames counter register */ +u32 hw_atl_reg_mac_msm_tx_ucst_frm_cnt_get(struct aq_hw_s *aq_hw); + +/* get msm tx multicast frames counter register */ +u32 hw_atl_reg_mac_msm_tx_mcst_frm_cnt_get(struct aq_hw_s *aq_hw); + +/* get msm tx broadcast frames counter register */ +u32 hw_atl_reg_mac_msm_tx_bcst_frm_cnt_get(struct aq_hw_s *aq_hw); + +/* get msm tx multicast octets counter register 1 */ +u32 hw_atl_reg_mac_msm_tx_mcst_octets_counter1get(struct aq_hw_s *aq_hw); + +/* get msm tx broadcast octets counter register 1 */ +u32 hw_atl_reg_mac_msm_tx_bcst_octets_counter1get(struct aq_hw_s *aq_hw); + +/* get msm tx unicast octets counter register 0 */ +u32 hw_atl_reg_mac_msm_tx_ucst_octets_counter0get(struct aq_hw_s *aq_hw); + +/* get global mif identification */ +u32 hw_atl_reg_glb_mif_id_get(struct aq_hw_s *aq_hw); + +/* interrupt */ + +/* set interrupt auto mask lsw */ +void hw_atl_itr_irq_auto_masklsw_set(struct aq_hw_s *aq_hw, + u32 irq_auto_masklsw); + +/* set interrupt mapping enable rx */ +void hw_atl_itr_irq_map_en_rx_set(struct aq_hw_s *aq_hw, u32 irq_map_en_rx, + u32 rx); + +/* set interrupt mapping enable tx */ +void hw_atl_itr_irq_map_en_tx_set(struct aq_hw_s *aq_hw, u32 irq_map_en_tx, + u32 tx); + +/* set interrupt mapping rx */ +void hw_atl_itr_irq_map_rx_set(struct aq_hw_s *aq_hw, u32 irq_map_rx, u32 rx); + +/* set interrupt mapping tx */ +void hw_atl_itr_irq_map_tx_set(struct aq_hw_s *aq_hw, u32 irq_map_tx, u32 tx); + +/* set interrupt mask clear lsw */ +void hw_atl_itr_irq_msk_clearlsw_set(struct aq_hw_s *aq_hw, + u32 irq_msk_clearlsw); + +/* set interrupt mask set lsw */ +void hw_atl_itr_irq_msk_setlsw_set(struct aq_hw_s *aq_hw, u32 irq_msk_setlsw); + +/* set interrupt register reset disable */ +void hw_atl_itr_irq_reg_res_dis_set(struct aq_hw_s *aq_hw, u32 irq_reg_res_dis); + +/* set interrupt status clear lsw */ +void hw_atl_itr_irq_status_clearlsw_set(struct aq_hw_s *aq_hw, + u32 irq_status_clearlsw); + +/* get interrupt status lsw */ +u32 hw_atl_itr_irq_statuslsw_get(struct aq_hw_s *aq_hw); + +/* get reset interrupt */ +u32 hw_atl_itr_res_irq_get(struct aq_hw_s *aq_hw); + +/* set reset interrupt */ +void hw_atl_itr_res_irq_set(struct aq_hw_s *aq_hw, u32 res_irq); + +/* rdm */ + +/* set cpu id */ +void hw_atl_rdm_cpu_id_set(struct aq_hw_s *aq_hw, u32 cpuid, u32 dca); + +/* set rx dca enable */ +void hw_atl_rdm_rx_dca_en_set(struct aq_hw_s *aq_hw, u32 rx_dca_en); + +/* set rx dca mode */ +void hw_atl_rdm_rx_dca_mode_set(struct aq_hw_s *aq_hw, u32 rx_dca_mode); + +/* set rx descriptor data buffer size */ +void hw_atl_rdm_rx_desc_data_buff_size_set(struct aq_hw_s *aq_hw, + u32 rx_desc_data_buff_size, + u32 descriptor); + +/* set rx descriptor dca enable */ +void hw_atl_rdm_rx_desc_dca_en_set(struct aq_hw_s *aq_hw, u32 rx_desc_dca_en, + u32 dca); + +/* set rx descriptor enable */ +void hw_atl_rdm_rx_desc_en_set(struct aq_hw_s *aq_hw, u32 rx_desc_en, + u32 descriptor); + +/* set rx descriptor header splitting */ +void hw_atl_rdm_rx_desc_head_splitting_set(struct aq_hw_s *aq_hw, + u32 rx_desc_head_splitting, + u32 descriptor); + +/* get rx descriptor head pointer */ +u32 hw_atl_rdm_rx_desc_head_ptr_get(struct aq_hw_s *aq_hw, u32 descriptor); + +/* set rx descriptor length */ +void hw_atl_rdm_rx_desc_len_set(struct aq_hw_s *aq_hw, u32 rx_desc_len, + u32 descriptor); + +/* set rx descriptor write-back interrupt enable */ +void hw_atl_rdm_rx_desc_wr_wb_irq_en_set(struct aq_hw_s *aq_hw, + u32 rx_desc_wr_wb_irq_en); + +/* set rx header dca enable */ +void hw_atl_rdm_rx_head_dca_en_set(struct aq_hw_s *aq_hw, u32 rx_head_dca_en, + u32 dca); + +/* set rx payload dca enable */ +void hw_atl_rdm_rx_pld_dca_en_set(struct aq_hw_s *aq_hw, u32 rx_pld_dca_en, + u32 dca); + +/* set rx descriptor header buffer size */ +void hw_atl_rdm_rx_desc_head_buff_size_set(struct aq_hw_s *aq_hw, + u32 rx_desc_head_buff_size, + u32 descriptor); + +/* set rx descriptor reset */ +void hw_atl_rdm_rx_desc_res_set(struct aq_hw_s *aq_hw, u32 rx_desc_res, + u32 descriptor); + +/* Set RDM Interrupt Moderation Enable */ +void hw_atl_rdm_rdm_intr_moder_en_set(struct aq_hw_s *aq_hw, + u32 rdm_intr_moder_en); + +/* reg */ + +/* set general interrupt mapping register */ +void hw_atl_reg_gen_irq_map_set(struct aq_hw_s *aq_hw, u32 gen_intr_map, + u32 regidx); + +/* get general interrupt status register */ +u32 hw_atl_reg_gen_irq_status_get(struct aq_hw_s *aq_hw); + +/* set interrupt global control register */ +void hw_atl_reg_irq_glb_ctl_set(struct aq_hw_s *aq_hw, u32 intr_glb_ctl); + +/* set interrupt throttle register */ +void hw_atl_reg_irq_thr_set(struct aq_hw_s *aq_hw, u32 intr_thr, u32 throttle); + +/* set rx dma descriptor base address lsw */ +void hw_atl_reg_rx_dma_desc_base_addresslswset(struct aq_hw_s *aq_hw, + u32 rx_dma_desc_base_addrlsw, + u32 descriptor); + +/* set rx dma descriptor base address msw */ +void hw_atl_reg_rx_dma_desc_base_addressmswset(struct aq_hw_s *aq_hw, + u32 rx_dma_desc_base_addrmsw, + u32 descriptor); + +/* get rx dma descriptor status register */ +u32 hw_atl_reg_rx_dma_desc_status_get(struct aq_hw_s *aq_hw, u32 descriptor); + +/* set rx dma descriptor tail pointer register */ +void hw_atl_reg_rx_dma_desc_tail_ptr_set(struct aq_hw_s *aq_hw, + u32 rx_dma_desc_tail_ptr, + u32 descriptor); + +/* set rx filter multicast filter mask register */ +void hw_atl_reg_rx_flr_mcst_flr_msk_set(struct aq_hw_s *aq_hw, + u32 rx_flr_mcst_flr_msk); + +/* set rx filter multicast filter register */ +void hw_atl_reg_rx_flr_mcst_flr_set(struct aq_hw_s *aq_hw, u32 rx_flr_mcst_flr, + u32 filter); + +/* set rx filter rss control register 1 */ +void hw_atl_reg_rx_flr_rss_control1set(struct aq_hw_s *aq_hw, + u32 rx_flr_rss_control1); + +/* Set RX Filter Control Register 2 */ +void hw_atl_reg_rx_flr_control2_set(struct aq_hw_s *aq_hw, u32 rx_flr_control2); + +/* Set RX Interrupt Moderation Control Register */ +void hw_atl_reg_rx_intr_moder_ctrl_set(struct aq_hw_s *aq_hw, + u32 rx_intr_moderation_ctl, + u32 queue); + +/* set tx dma debug control */ +void hw_atl_reg_tx_dma_debug_ctl_set(struct aq_hw_s *aq_hw, + u32 tx_dma_debug_ctl); + +/* set tx dma descriptor base address lsw */ +void hw_atl_reg_tx_dma_desc_base_addresslswset(struct aq_hw_s *aq_hw, + u32 tx_dma_desc_base_addrlsw, + u32 descriptor); + +/* set tx dma descriptor base address msw */ +void hw_atl_reg_tx_dma_desc_base_addressmswset(struct aq_hw_s *aq_hw, + u32 tx_dma_desc_base_addrmsw, + u32 descriptor); + +/* set tx dma descriptor tail pointer register */ +void hw_atl_reg_tx_dma_desc_tail_ptr_set(struct aq_hw_s *aq_hw, + u32 tx_dma_desc_tail_ptr, + u32 descriptor); + +/* Set TX Interrupt Moderation Control Register */ +void hw_atl_reg_tx_intr_moder_ctrl_set(struct aq_hw_s *aq_hw, + u32 tx_intr_moderation_ctl, + u32 queue); + +/* set global microprocessor scratch pad */ +void hw_atl_reg_glb_cpu_scratch_scp_set(struct aq_hw_s *aq_hw, + u32 glb_cpu_scratch_scp, + u32 scratch_scp); + +/* rpb */ + +/* set dma system loopback */ +void hw_atl_rpb_dma_sys_lbk_set(struct aq_hw_s *aq_hw, u32 dma_sys_lbk); + +/* set rx traffic class mode */ +void hw_atl_rpb_rpf_rx_traf_class_mode_set(struct aq_hw_s *aq_hw, + u32 rx_traf_class_mode); + +/* set rx buffer enable */ +void hw_atl_rpb_rx_buff_en_set(struct aq_hw_s *aq_hw, u32 rx_buff_en); + +/* set rx buffer high threshold (per tc) */ +void hw_atl_rpb_rx_buff_hi_threshold_per_tc_set(struct aq_hw_s *aq_hw, + u32 rx_buff_hi_threshold_per_tc, + u32 buffer); + +/* set rx buffer low threshold (per tc) */ +void hw_atl_rpb_rx_buff_lo_threshold_per_tc_set(struct aq_hw_s *aq_hw, + u32 rx_buff_lo_threshold_per_tc, + u32 buffer); + +/* set rx flow control mode */ +void hw_atl_rpb_rx_flow_ctl_mode_set(struct aq_hw_s *aq_hw, u32 rx_flow_ctl_mode); + +/* set rx packet buffer size (per tc) */ +void hw_atl_rpb_rx_pkt_buff_size_per_tc_set(struct aq_hw_s *aq_hw, + u32 rx_pkt_buff_size_per_tc, + u32 buffer); + +/* set rdm rx dma descriptor cache init */ +void hw_atl_rdm_rx_dma_desc_cache_init_set(struct aq_hw_s *aq_hw, u32 init); + +/* set rx xoff enable (per tc) */ +void hw_atl_rpb_rx_xoff_en_per_tc_set(struct aq_hw_s *aq_hw, u32 rx_xoff_en_per_tc, + u32 buffer); + +/* rpf */ + +/* set l2 broadcast count threshold */ +void hw_atl_rpfl2broadcast_count_threshold_set(struct aq_hw_s *aq_hw, + u32 l2broadcast_count_threshold); + +/* set l2 broadcast enable */ +void hw_atl_rpfl2broadcast_en_set(struct aq_hw_s *aq_hw, u32 l2broadcast_en); + +/* set l2 broadcast filter action */ +void hw_atl_rpfl2broadcast_flr_act_set(struct aq_hw_s *aq_hw, + u32 l2broadcast_flr_act); + +/* set l2 multicast filter enable */ +void hw_atl_rpfl2multicast_flr_en_set(struct aq_hw_s *aq_hw, + u32 l2multicast_flr_en, + u32 filter); + +/* set l2 promiscuous mode enable */ +void hw_atl_rpfl2promiscuous_mode_en_set(struct aq_hw_s *aq_hw, + u32 l2promiscuous_mode_en); + +/* set l2 unicast filter action */ +void hw_atl_rpfl2unicast_flr_act_set(struct aq_hw_s *aq_hw, + u32 l2unicast_flr_act, + u32 filter); + +/* set l2 unicast filter enable */ +void hw_atl_rpfl2_uc_flr_en_set(struct aq_hw_s *aq_hw, u32 l2unicast_flr_en, + u32 filter); + +/* set l2 unicast destination address lsw */ +void hw_atl_rpfl2unicast_dest_addresslsw_set(struct aq_hw_s *aq_hw, + u32 l2unicast_dest_addresslsw, + u32 filter); + +/* set l2 unicast destination address msw */ +void hw_atl_rpfl2unicast_dest_addressmsw_set(struct aq_hw_s *aq_hw, + u32 l2unicast_dest_addressmsw, + u32 filter); + +/* Set L2 Accept all Multicast packets */ +void hw_atl_rpfl2_accept_all_mc_packets_set(struct aq_hw_s *aq_hw, + u32 l2_accept_all_mc_packets); + +/* set user-priority tc mapping */ +void hw_atl_rpf_rpb_user_priority_tc_map_set(struct aq_hw_s *aq_hw, + u32 user_priority_tc_map, u32 tc); + +/* set rss key address */ +void hw_atl_rpf_rss_key_addr_set(struct aq_hw_s *aq_hw, u32 rss_key_addr); + +/* set rss key write data */ +void hw_atl_rpf_rss_key_wr_data_set(struct aq_hw_s *aq_hw, u32 rss_key_wr_data); + +/* get rss key write enable */ +u32 hw_atl_rpf_rss_key_wr_en_get(struct aq_hw_s *aq_hw); + +/* set rss key write enable */ +void hw_atl_rpf_rss_key_wr_en_set(struct aq_hw_s *aq_hw, u32 rss_key_wr_en); + +/* set rss redirection table address */ +void hw_atl_rpf_rss_redir_tbl_addr_set(struct aq_hw_s *aq_hw, + u32 rss_redir_tbl_addr); + +/* set rss redirection table write data */ +void hw_atl_rpf_rss_redir_tbl_wr_data_set(struct aq_hw_s *aq_hw, + u32 rss_redir_tbl_wr_data); + +/* get rss redirection write enable */ +u32 hw_atl_rpf_rss_redir_wr_en_get(struct aq_hw_s *aq_hw); + +/* set rss redirection write enable */ +void hw_atl_rpf_rss_redir_wr_en_set(struct aq_hw_s *aq_hw, u32 rss_redir_wr_en); + +/* set tpo to rpf system loopback */ +void hw_atl_rpf_tpo_to_rpf_sys_lbk_set(struct aq_hw_s *aq_hw, + u32 tpo_to_rpf_sys_lbk); + +/* set vlan inner ethertype */ +void hw_atl_rpf_vlan_inner_etht_set(struct aq_hw_s *aq_hw, u32 vlan_inner_etht); + +/* set vlan outer ethertype */ +void hw_atl_rpf_vlan_outer_etht_set(struct aq_hw_s *aq_hw, u32 vlan_outer_etht); + +/* set vlan promiscuous mode enable */ +void hw_atl_rpf_vlan_prom_mode_en_set(struct aq_hw_s *aq_hw, + u32 vlan_prom_mode_en); + +/* Set VLAN untagged action */ +void hw_atl_rpf_vlan_untagged_act_set(struct aq_hw_s *aq_hw, + u32 vlan_untagged_act); + +/* Set VLAN accept untagged packets */ +void hw_atl_rpf_vlan_accept_untagged_packets_set(struct aq_hw_s *aq_hw, + u32 vlan_acc_untagged_packets); + +/* Set VLAN filter enable */ +void hw_atl_rpf_vlan_flr_en_set(struct aq_hw_s *aq_hw, u32 vlan_flr_en, + u32 filter); + +/* Set VLAN Filter Action */ +void hw_atl_rpf_vlan_flr_act_set(struct aq_hw_s *aq_hw, u32 vlan_filter_act, + u32 filter); + +/* Set VLAN ID Filter */ +void hw_atl_rpf_vlan_id_flr_set(struct aq_hw_s *aq_hw, u32 vlan_id_flr, + u32 filter); + +/* set ethertype filter enable */ +void hw_atl_rpf_etht_flr_en_set(struct aq_hw_s *aq_hw, u32 etht_flr_en, + u32 filter); + +/* set ethertype user-priority enable */ +void hw_atl_rpf_etht_user_priority_en_set(struct aq_hw_s *aq_hw, + u32 etht_user_priority_en, + u32 filter); + +/* set ethertype rx queue enable */ +void hw_atl_rpf_etht_rx_queue_en_set(struct aq_hw_s *aq_hw, + u32 etht_rx_queue_en, + u32 filter); + +/* set ethertype rx queue */ +void hw_atl_rpf_etht_rx_queue_set(struct aq_hw_s *aq_hw, u32 etht_rx_queue, + u32 filter); + +/* set ethertype user-priority */ +void hw_atl_rpf_etht_user_priority_set(struct aq_hw_s *aq_hw, + u32 etht_user_priority, + u32 filter); + +/* set ethertype management queue */ +void hw_atl_rpf_etht_mgt_queue_set(struct aq_hw_s *aq_hw, u32 etht_mgt_queue, + u32 filter); + +/* set ethertype filter action */ +void hw_atl_rpf_etht_flr_act_set(struct aq_hw_s *aq_hw, u32 etht_flr_act, + u32 filter); + +/* set ethertype filter */ +void hw_atl_rpf_etht_flr_set(struct aq_hw_s *aq_hw, u32 etht_flr, u32 filter); + +/* rpo */ + +/* set ipv4 header checksum offload enable */ +void hw_atl_rpo_ipv4header_crc_offload_en_set(struct aq_hw_s *aq_hw, + u32 ipv4header_crc_offload_en); + +/* set rx descriptor vlan stripping */ +void hw_atl_rpo_rx_desc_vlan_stripping_set(struct aq_hw_s *aq_hw, + u32 rx_desc_vlan_stripping, + u32 descriptor); + +/* set tcp/udp checksum offload enable */ +void hw_atl_rpo_tcp_udp_crc_offload_en_set(struct aq_hw_s *aq_hw, + u32 tcp_udp_crc_offload_en); + +/* Set LRO Patch Optimization Enable. */ +void hw_atl_rpo_lro_patch_optimization_en_set(struct aq_hw_s *aq_hw, + u32 lro_patch_optimization_en); + +/* Set Large Receive Offload Enable */ +void hw_atl_rpo_lro_en_set(struct aq_hw_s *aq_hw, u32 lro_en); + +/* Set LRO Q Sessions Limit */ +void hw_atl_rpo_lro_qsessions_lim_set(struct aq_hw_s *aq_hw, + u32 lro_qsessions_lim); + +/* Set LRO Total Descriptor Limit */ +void hw_atl_rpo_lro_total_desc_lim_set(struct aq_hw_s *aq_hw, + u32 lro_total_desc_lim); + +/* Set LRO Min Payload of First Packet */ +void hw_atl_rpo_lro_min_pay_of_first_pkt_set(struct aq_hw_s *aq_hw, + u32 lro_min_pld_of_first_pkt); + +/* Set LRO Packet Limit */ +void hw_atl_rpo_lro_pkt_lim_set(struct aq_hw_s *aq_hw, u32 lro_packet_lim); + +/* Set LRO Max Number of Descriptors */ +void hw_atl_rpo_lro_max_num_of_descriptors_set(struct aq_hw_s *aq_hw, + u32 lro_max_desc_num, u32 lro); + +/* Set LRO Time Base Divider */ +void hw_atl_rpo_lro_time_base_divider_set(struct aq_hw_s *aq_hw, + u32 lro_time_base_divider); + +/*Set LRO Inactive Interval */ +void hw_atl_rpo_lro_inactive_interval_set(struct aq_hw_s *aq_hw, + u32 lro_inactive_interval); + +/*Set LRO Max Coalescing Interval */ +void hw_atl_rpo_lro_max_coalescing_interval_set(struct aq_hw_s *aq_hw, + u32 lro_max_coal_interval); + +/* rx */ + +/* set rx register reset disable */ +void hw_atl_rx_rx_reg_res_dis_set(struct aq_hw_s *aq_hw, u32 rx_reg_res_dis); + +/* tdm */ + +/* set cpu id */ +void hw_atl_tdm_cpu_id_set(struct aq_hw_s *aq_hw, u32 cpuid, u32 dca); + +/* set large send offload enable */ +void hw_atl_tdm_large_send_offload_en_set(struct aq_hw_s *aq_hw, + u32 large_send_offload_en); + +/* set tx descriptor enable */ +void hw_atl_tdm_tx_desc_en_set(struct aq_hw_s *aq_hw, u32 tx_desc_en, + u32 descriptor); + +/* set tx dca enable */ +void hw_atl_tdm_tx_dca_en_set(struct aq_hw_s *aq_hw, u32 tx_dca_en); + +/* set tx dca mode */ +void hw_atl_tdm_tx_dca_mode_set(struct aq_hw_s *aq_hw, u32 tx_dca_mode); + +/* set tx descriptor dca enable */ +void hw_atl_tdm_tx_desc_dca_en_set(struct aq_hw_s *aq_hw, u32 tx_desc_dca_en, + u32 dca); + +/* get tx descriptor head pointer */ +u32 hw_atl_tdm_tx_desc_head_ptr_get(struct aq_hw_s *aq_hw, u32 descriptor); + +/* set tx descriptor length */ +void hw_atl_tdm_tx_desc_len_set(struct aq_hw_s *aq_hw, u32 tx_desc_len, + u32 descriptor); + +/* set tx descriptor write-back interrupt enable */ +void hw_atl_tdm_tx_desc_wr_wb_irq_en_set(struct aq_hw_s *aq_hw, + u32 tx_desc_wr_wb_irq_en); + +/* set tx descriptor write-back threshold */ +void hw_atl_tdm_tx_desc_wr_wb_threshold_set(struct aq_hw_s *aq_hw, + u32 tx_desc_wr_wb_threshold, + u32 descriptor); + +/* Set TDM Interrupt Moderation Enable */ +void hw_atl_tdm_tdm_intr_moder_en_set(struct aq_hw_s *aq_hw, + u32 tdm_irq_moderation_en); +/* thm */ + +/* set lso tcp flag of first packet */ +void hw_atl_thm_lso_tcp_flag_of_first_pkt_set(struct aq_hw_s *aq_hw, + u32 lso_tcp_flag_of_first_pkt); + +/* set lso tcp flag of last packet */ +void hw_atl_thm_lso_tcp_flag_of_last_pkt_set(struct aq_hw_s *aq_hw, + u32 lso_tcp_flag_of_last_pkt); + +/* set lso tcp flag of middle packet */ +void hw_atl_thm_lso_tcp_flag_of_middle_pkt_set(struct aq_hw_s *aq_hw, + u32 lso_tcp_flag_of_middle_pkt); + +/* tpb */ + +/* set tx buffer enable */ +void hw_atl_tpb_tx_buff_en_set(struct aq_hw_s *aq_hw, u32 tx_buff_en); + +/* set tx buffer high threshold (per tc) */ +void hw_atl_tpb_tx_buff_hi_threshold_per_tc_set(struct aq_hw_s *aq_hw, + u32 tx_buff_hi_threshold_per_tc, + u32 buffer); + +/* set tx buffer low threshold (per tc) */ +void hw_atl_tpb_tx_buff_lo_threshold_per_tc_set(struct aq_hw_s *aq_hw, + u32 tx_buff_lo_threshold_per_tc, + u32 buffer); + +/* set tx dma system loopback enable */ +void hw_atl_tpb_tx_dma_sys_lbk_en_set(struct aq_hw_s *aq_hw, u32 tx_dma_sys_lbk_en); + +/* set tx packet buffer size (per tc) */ +void hw_atl_tpb_tx_pkt_buff_size_per_tc_set(struct aq_hw_s *aq_hw, + u32 tx_pkt_buff_size_per_tc, u32 buffer); + +/* set tx path pad insert enable */ +void hw_atl_tpb_tx_path_scp_ins_en_set(struct aq_hw_s *aq_hw, u32 tx_path_scp_ins_en); + +/* tpo */ + +/* set ipv4 header checksum offload enable */ +void hw_atl_tpo_ipv4header_crc_offload_en_set(struct aq_hw_s *aq_hw, + u32 ipv4header_crc_offload_en); + +/* set tcp/udp checksum offload enable */ +void hw_atl_tpo_tcp_udp_crc_offload_en_set(struct aq_hw_s *aq_hw, + u32 tcp_udp_crc_offload_en); + +/* set tx pkt system loopback enable */ +void hw_atl_tpo_tx_pkt_sys_lbk_en_set(struct aq_hw_s *aq_hw, + u32 tx_pkt_sys_lbk_en); + +/* tps */ + +/* set tx packet scheduler data arbitration mode */ +void hw_atl_tps_tx_pkt_shed_data_arb_mode_set(struct aq_hw_s *aq_hw, + u32 tx_pkt_shed_data_arb_mode); + +/* set tx packet scheduler descriptor rate current time reset */ +void hw_atl_tps_tx_pkt_shed_desc_rate_curr_time_res_set(struct aq_hw_s *aq_hw, + u32 curr_time_res); + +/* set tx packet scheduler descriptor rate limit */ +void hw_atl_tps_tx_pkt_shed_desc_rate_lim_set(struct aq_hw_s *aq_hw, + u32 tx_pkt_shed_desc_rate_lim); + +/* set tx packet scheduler descriptor tc arbitration mode */ +void hw_atl_tps_tx_pkt_shed_desc_tc_arb_mode_set(struct aq_hw_s *aq_hw, + u32 arb_mode); + +/* set tx packet scheduler descriptor tc max credit */ +void hw_atl_tps_tx_pkt_shed_desc_tc_max_credit_set(struct aq_hw_s *aq_hw, + u32 max_credit, + u32 tc); + +/* set tx packet scheduler descriptor tc weight */ +void hw_atl_tps_tx_pkt_shed_desc_tc_weight_set(struct aq_hw_s *aq_hw, + u32 tx_pkt_shed_desc_tc_weight, + u32 tc); + +/* set tx packet scheduler descriptor vm arbitration mode */ +void hw_atl_tps_tx_pkt_shed_desc_vm_arb_mode_set(struct aq_hw_s *aq_hw, + u32 arb_mode); + +/* set tx packet scheduler tc data max credit */ +void hw_atl_tps_tx_pkt_shed_tc_data_max_credit_set(struct aq_hw_s *aq_hw, + u32 max_credit, + u32 tc); + +/* set tx packet scheduler tc data weight */ +void hw_atl_tps_tx_pkt_shed_tc_data_weight_set(struct aq_hw_s *aq_hw, + u32 tx_pkt_shed_tc_data_weight, + u32 tc); + +/* tx */ + +/* set tx register reset disable */ +void hw_atl_tx_tx_reg_res_dis_set(struct aq_hw_s *aq_hw, u32 tx_reg_res_dis); + +/* msm */ + +/* get register access status */ +u32 hw_atl_msm_reg_access_status_get(struct aq_hw_s *aq_hw); + +/* set register address for indirect address */ +void hw_atl_msm_reg_addr_for_indirect_addr_set(struct aq_hw_s *aq_hw, + u32 reg_addr_for_indirect_addr); + +/* set register read strobe */ +void hw_atl_msm_reg_rd_strobe_set(struct aq_hw_s *aq_hw, u32 reg_rd_strobe); + +/* get register read data */ +u32 hw_atl_msm_reg_rd_data_get(struct aq_hw_s *aq_hw); + +/* set register write data */ +void hw_atl_msm_reg_wr_data_set(struct aq_hw_s *aq_hw, u32 reg_wr_data); + +/* set register write strobe */ +void hw_atl_msm_reg_wr_strobe_set(struct aq_hw_s *aq_hw, u32 reg_wr_strobe); + +/* pci */ + +/* set pci register reset disable */ +void hw_atl_pci_pci_reg_res_dis_set(struct aq_hw_s *aq_hw, u32 pci_reg_res_dis); + +/* set uP Force Interrupt */ +void hw_atl_mcp_up_force_intr_set(struct aq_hw_s *aq_hw, u32 up_force_intr); + +#endif /* HW_ATL_LLH_H */ diff --git a/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_llh_internal.h b/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_llh_internal.h new file mode 100644 index 000000000..a715fa317 --- /dev/null +++ b/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_llh_internal.h @@ -0,0 +1,2421 @@ +/* + * aQuantia Corporation Network Driver + * Copyright (C) 2014-2017 aQuantia Corporation. All rights reserved + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + */ + +/* File hw_atl_llh_internal.h: Preprocessor definitions + * for Atlantic registers. + */ + +#ifndef HW_ATL_LLH_INTERNAL_H +#define HW_ATL_LLH_INTERNAL_H + +/* global microprocessor semaphore definitions + * base address: 0x000003a0 + * parameter: semaphore {s} | stride size 0x4 | range [0, 15] + */ +#define HW_ATL_GLB_CPU_SEM_ADR(semaphore) (0x000003a0u + (semaphore) * 0x4) +/* register address for bitfield rx dma good octet counter lsw [1f:0] */ +#define HW_ATL_STATS_RX_DMA_GOOD_OCTET_COUNTERLSW 0x00006808 +/* register address for bitfield rx dma good packet counter lsw [1f:0] */ +#define HW_ATL_STATS_RX_DMA_GOOD_PKT_COUNTERLSW 0x00006800 +/* register address for bitfield tx dma good octet counter lsw [1f:0] */ +#define HW_ATL_STATS_TX_DMA_GOOD_OCTET_COUNTERLSW 0x00008808 +/* register address for bitfield tx dma good packet counter lsw [1f:0] */ +#define HW_ATL_STATS_TX_DMA_GOOD_PKT_COUNTERLSW 0x00008800 + +/* register address for bitfield rx dma good octet counter msw [3f:20] */ +#define HW_ATL_STATS_RX_DMA_GOOD_OCTET_COUNTERMSW 0x0000680c +/* register address for bitfield rx dma good packet counter msw [3f:20] */ +#define HW_ATL_STATS_RX_DMA_GOOD_PKT_COUNTERMSW 0x00006804 +/* register address for bitfield tx dma good octet counter msw [3f:20] */ +#define HW_ATL_STATS_TX_DMA_GOOD_OCTET_COUNTERMSW 0x0000880c +/* register address for bitfield tx dma good packet counter msw [3f:20] */ +#define HW_ATL_STATS_TX_DMA_GOOD_PKT_COUNTERMSW 0x00008804 + +/* preprocessor definitions for msm rx errors counter register */ +#define HW_ATL_MAC_MSM_RX_ERRS_CNT_ADR 0x00000120u + +/* preprocessor definitions for msm rx unicast frames counter register */ +#define HW_ATL_MAC_MSM_RX_UCST_FRM_CNT_ADR 0x000000e0u + +/* preprocessor definitions for msm rx multicast frames counter register */ +#define HW_ATL_MAC_MSM_RX_MCST_FRM_CNT_ADR 0x000000e8u + +/* preprocessor definitions for msm rx broadcast frames counter register */ +#define HW_ATL_MAC_MSM_RX_BCST_FRM_CNT_ADR 0x000000f0u + +/* preprocessor definitions for msm rx broadcast octets counter register 1 */ +#define HW_ATL_MAC_MSM_RX_BCST_OCTETS_COUNTER1_ADR 0x000001b0u + +/* preprocessor definitions for msm rx broadcast octets counter register 2 */ +#define HW_ATL_MAC_MSM_RX_BCST_OCTETS_COUNTER2_ADR 0x000001b4u + +/* preprocessor definitions for msm rx unicast octets counter register 0 */ +#define HW_ATL_MAC_MSM_RX_UCST_OCTETS_COUNTER0_ADR 0x000001b8u + +/* preprocessor definitions for rx dma statistics counter 7 */ +#define HW_ATL_RX_DMA_STAT_COUNTER7_ADR 0x00006818u + +/* preprocessor definitions for msm tx unicast frames counter register */ +#define HW_ATL_MAC_MSM_TX_UCST_FRM_CNT_ADR 0x00000108u + +/* preprocessor definitions for msm tx multicast frames counter register */ +#define HW_ATL_MAC_MSM_TX_MCST_FRM_CNT_ADR 0x00000110u + +/* preprocessor definitions for global mif identification */ +#define HW_ATL_GLB_MIF_ID_ADR 0x0000001cu + +/* register address for bitfield iamr_lsw[1f:0] */ +#define HW_ATL_ITR_IAMRLSW_ADR 0x00002090 +/* register address for bitfield rx dma drop packet counter [1f:0] */ +#define HW_ATL_RPB_RX_DMA_DROP_PKT_CNT_ADR 0x00006818 + +/* register address for bitfield imcr_lsw[1f:0] */ +#define HW_ATL_ITR_IMCRLSW_ADR 0x00002070 +/* register address for bitfield imsr_lsw[1f:0] */ +#define HW_ATL_ITR_IMSRLSW_ADR 0x00002060 +/* register address for bitfield itr_reg_res_dsbl */ +#define HW_ATL_ITR_REG_RES_DSBL_ADR 0x00002300 +/* bitmask for bitfield itr_reg_res_dsbl */ +#define HW_ATL_ITR_REG_RES_DSBL_MSK 0x20000000 +/* lower bit position of bitfield itr_reg_res_dsbl */ +#define HW_ATL_ITR_REG_RES_DSBL_SHIFT 29 +/* register address for bitfield iscr_lsw[1f:0] */ +#define HW_ATL_ITR_ISCRLSW_ADR 0x00002050 +/* register address for bitfield isr_lsw[1f:0] */ +#define HW_ATL_ITR_ISRLSW_ADR 0x00002000 +/* register address for bitfield itr_reset */ +#define HW_ATL_ITR_RES_ADR 0x00002300 +/* bitmask for bitfield itr_reset */ +#define HW_ATL_ITR_RES_MSK 0x80000000 +/* lower bit position of bitfield itr_reset */ +#define HW_ATL_ITR_RES_SHIFT 31 +/* register address for bitfield dca{d}_cpuid[7:0] */ +#define HW_ATL_RDM_DCADCPUID_ADR(dca) (0x00006100 + (dca) * 0x4) +/* bitmask for bitfield dca{d}_cpuid[7:0] */ +#define HW_ATL_RDM_DCADCPUID_MSK 0x000000ff +/* lower bit position of bitfield dca{d}_cpuid[7:0] */ +#define HW_ATL_RDM_DCADCPUID_SHIFT 0 +/* register address for bitfield dca_en */ +#define HW_ATL_RDM_DCA_EN_ADR 0x00006180 + +/* rx dca_en bitfield definitions + * preprocessor definitions for the bitfield "dca_en". + * port="pif_rdm_dca_en_i" + */ + +/* register address for bitfield dca_en */ +#define HW_ATL_RDM_DCA_EN_ADR 0x00006180 +/* bitmask for bitfield dca_en */ +#define HW_ATL_RDM_DCA_EN_MSK 0x80000000 +/* inverted bitmask for bitfield dca_en */ +#define HW_ATL_RDM_DCA_EN_MSKN 0x7fffffff +/* lower bit position of bitfield dca_en */ +#define HW_ATL_RDM_DCA_EN_SHIFT 31 +/* width of bitfield dca_en */ +#define HW_ATL_RDM_DCA_EN_WIDTH 1 +/* default value of bitfield dca_en */ +#define HW_ATL_RDM_DCA_EN_DEFAULT 0x1 + +/* rx dca_mode[3:0] bitfield definitions + * preprocessor definitions for the bitfield "dca_mode[3:0]". + * port="pif_rdm_dca_mode_i[3:0]" + */ + +/* register address for bitfield dca_mode[3:0] */ +#define HW_ATL_RDM_DCA_MODE_ADR 0x00006180 +/* bitmask for bitfield dca_mode[3:0] */ +#define HW_ATL_RDM_DCA_MODE_MSK 0x0000000f +/* inverted bitmask for bitfield dca_mode[3:0] */ +#define HW_ATL_RDM_DCA_MODE_MSKN 0xfffffff0 +/* lower bit position of bitfield dca_mode[3:0] */ +#define HW_ATL_RDM_DCA_MODE_SHIFT 0 +/* width of bitfield dca_mode[3:0] */ +#define HW_ATL_RDM_DCA_MODE_WIDTH 4 +/* default value of bitfield dca_mode[3:0] */ +#define HW_ATL_RDM_DCA_MODE_DEFAULT 0x0 + +/* rx desc{d}_data_size[4:0] bitfield definitions + * preprocessor definitions for the bitfield "desc{d}_data_size[4:0]". + * parameter: descriptor {d} | stride size 0x20 | range [0, 31] + * port="pif_rdm_desc0_data_size_i[4:0]" + */ + +/* register address for bitfield desc{d}_data_size[4:0] */ +#define HW_ATL_RDM_DESCDDATA_SIZE_ADR(descriptor) \ + (0x00005b18 + (descriptor) * 0x20) +/* bitmask for bitfield desc{d}_data_size[4:0] */ +#define HW_ATL_RDM_DESCDDATA_SIZE_MSK 0x0000001f +/* inverted bitmask for bitfield desc{d}_data_size[4:0] */ +#define HW_ATL_RDM_DESCDDATA_SIZE_MSKN 0xffffffe0 +/* lower bit position of bitfield desc{d}_data_size[4:0] */ +#define HW_ATL_RDM_DESCDDATA_SIZE_SHIFT 0 +/* width of bitfield desc{d}_data_size[4:0] */ +#define HW_ATL_RDM_DESCDDATA_SIZE_WIDTH 5 +/* default value of bitfield desc{d}_data_size[4:0] */ +#define HW_ATL_RDM_DESCDDATA_SIZE_DEFAULT 0x0 + +/* rx dca{d}_desc_en bitfield definitions + * preprocessor definitions for the bitfield "dca{d}_desc_en". + * parameter: dca {d} | stride size 0x4 | range [0, 31] + * port="pif_rdm_dca_desc_en_i[0]" + */ + +/* register address for bitfield dca{d}_desc_en */ +#define HW_ATL_RDM_DCADDESC_EN_ADR(dca) (0x00006100 + (dca) * 0x4) +/* bitmask for bitfield dca{d}_desc_en */ +#define HW_ATL_RDM_DCADDESC_EN_MSK 0x80000000 +/* inverted bitmask for bitfield dca{d}_desc_en */ +#define HW_ATL_RDM_DCADDESC_EN_MSKN 0x7fffffff +/* lower bit position of bitfield dca{d}_desc_en */ +#define HW_ATL_RDM_DCADDESC_EN_SHIFT 31 +/* width of bitfield dca{d}_desc_en */ +#define HW_ATL_RDM_DCADDESC_EN_WIDTH 1 +/* default value of bitfield dca{d}_desc_en */ +#define HW_ATL_RDM_DCADDESC_EN_DEFAULT 0x0 + +/* rx desc{d}_en bitfield definitions + * preprocessor definitions for the bitfield "desc{d}_en". + * parameter: descriptor {d} | stride size 0x20 | range [0, 31] + * port="pif_rdm_desc_en_i[0]" + */ + +/* register address for bitfield desc{d}_en */ +#define HW_ATL_RDM_DESCDEN_ADR(descriptor) (0x00005b08 + (descriptor) * 0x20) +/* bitmask for bitfield desc{d}_en */ +#define HW_ATL_RDM_DESCDEN_MSK 0x80000000 +/* inverted bitmask for bitfield desc{d}_en */ +#define HW_ATL_RDM_DESCDEN_MSKN 0x7fffffff +/* lower bit position of bitfield desc{d}_en */ +#define HW_ATL_RDM_DESCDEN_SHIFT 31 +/* width of bitfield desc{d}_en */ +#define HW_ATL_RDM_DESCDEN_WIDTH 1 +/* default value of bitfield desc{d}_en */ +#define HW_ATL_RDM_DESCDEN_DEFAULT 0x0 + +/* rx desc{d}_hdr_size[4:0] bitfield definitions + * preprocessor definitions for the bitfield "desc{d}_hdr_size[4:0]". + * parameter: descriptor {d} | stride size 0x20 | range [0, 31] + * port="pif_rdm_desc0_hdr_size_i[4:0]" + */ + +/* register address for bitfield desc{d}_hdr_size[4:0] */ +#define HW_ATL_RDM_DESCDHDR_SIZE_ADR(descriptor) \ + (0x00005b18 + (descriptor) * 0x20) +/* bitmask for bitfield desc{d}_hdr_size[4:0] */ +#define HW_ATL_RDM_DESCDHDR_SIZE_MSK 0x00001f00 +/* inverted bitmask for bitfield desc{d}_hdr_size[4:0] */ +#define HW_ATL_RDM_DESCDHDR_SIZE_MSKN 0xffffe0ff +/* lower bit position of bitfield desc{d}_hdr_size[4:0] */ +#define HW_ATL_RDM_DESCDHDR_SIZE_SHIFT 8 +/* width of bitfield desc{d}_hdr_size[4:0] */ +#define HW_ATL_RDM_DESCDHDR_SIZE_WIDTH 5 +/* default value of bitfield desc{d}_hdr_size[4:0] */ +#define HW_ATL_RDM_DESCDHDR_SIZE_DEFAULT 0x0 + +/* rx desc{d}_hdr_split bitfield definitions + * preprocessor definitions for the bitfield "desc{d}_hdr_split". + * parameter: descriptor {d} | stride size 0x20 | range [0, 31] + * port="pif_rdm_desc_hdr_split_i[0]" + */ + +/* register address for bitfield desc{d}_hdr_split */ +#define HW_ATL_RDM_DESCDHDR_SPLIT_ADR(descriptor) \ + (0x00005b08 + (descriptor) * 0x20) +/* bitmask for bitfield desc{d}_hdr_split */ +#define HW_ATL_RDM_DESCDHDR_SPLIT_MSK 0x10000000 +/* inverted bitmask for bitfield desc{d}_hdr_split */ +#define HW_ATL_RDM_DESCDHDR_SPLIT_MSKN 0xefffffff +/* lower bit position of bitfield desc{d}_hdr_split */ +#define HW_ATL_RDM_DESCDHDR_SPLIT_SHIFT 28 +/* width of bitfield desc{d}_hdr_split */ +#define HW_ATL_RDM_DESCDHDR_SPLIT_WIDTH 1 +/* default value of bitfield desc{d}_hdr_split */ +#define HW_ATL_RDM_DESCDHDR_SPLIT_DEFAULT 0x0 + +/* rx desc{d}_hd[c:0] bitfield definitions + * preprocessor definitions for the bitfield "desc{d}_hd[c:0]". + * parameter: descriptor {d} | stride size 0x20 | range [0, 31] + * port="rdm_pif_desc0_hd_o[12:0]" + */ + +/* register address for bitfield desc{d}_hd[c:0] */ +#define HW_ATL_RDM_DESCDHD_ADR(descriptor) (0x00005b0c + (descriptor) * 0x20) +/* bitmask for bitfield desc{d}_hd[c:0] */ +#define HW_ATL_RDM_DESCDHD_MSK 0x00001fff +/* inverted bitmask for bitfield desc{d}_hd[c:0] */ +#define HW_ATL_RDM_DESCDHD_MSKN 0xffffe000 +/* lower bit position of bitfield desc{d}_hd[c:0] */ +#define HW_ATL_RDM_DESCDHD_SHIFT 0 +/* width of bitfield desc{d}_hd[c:0] */ +#define HW_ATL_RDM_DESCDHD_WIDTH 13 + +/* rx desc{d}_len[9:0] bitfield definitions + * preprocessor definitions for the bitfield "desc{d}_len[9:0]". + * parameter: descriptor {d} | stride size 0x20 | range [0, 31] + * port="pif_rdm_desc0_len_i[9:0]" + */ + +/* register address for bitfield desc{d}_len[9:0] */ +#define HW_ATL_RDM_DESCDLEN_ADR(descriptor) (0x00005b08 + (descriptor) * 0x20) +/* bitmask for bitfield desc{d}_len[9:0] */ +#define HW_ATL_RDM_DESCDLEN_MSK 0x00001ff8 +/* inverted bitmask for bitfield desc{d}_len[9:0] */ +#define HW_ATL_RDM_DESCDLEN_MSKN 0xffffe007 +/* lower bit position of bitfield desc{d}_len[9:0] */ +#define HW_ATL_RDM_DESCDLEN_SHIFT 3 +/* width of bitfield desc{d}_len[9:0] */ +#define HW_ATL_RDM_DESCDLEN_WIDTH 10 +/* default value of bitfield desc{d}_len[9:0] */ +#define HW_ATL_RDM_DESCDLEN_DEFAULT 0x0 + +/* rx desc{d}_reset bitfield definitions + * preprocessor definitions for the bitfield "desc{d}_reset". + * parameter: descriptor {d} | stride size 0x20 | range [0, 31] + * port="pif_rdm_q_pf_res_i[0]" + */ + +/* register address for bitfield desc{d}_reset */ +#define HW_ATL_RDM_DESCDRESET_ADR(descriptor) (0x00005b08 + (descriptor) * 0x20) +/* bitmask for bitfield desc{d}_reset */ +#define HW_ATL_RDM_DESCDRESET_MSK 0x02000000 +/* inverted bitmask for bitfield desc{d}_reset */ +#define HW_ATL_RDM_DESCDRESET_MSKN 0xfdffffff +/* lower bit position of bitfield desc{d}_reset */ +#define HW_ATL_RDM_DESCDRESET_SHIFT 25 +/* width of bitfield desc{d}_reset */ +#define HW_ATL_RDM_DESCDRESET_WIDTH 1 +/* default value of bitfield desc{d}_reset */ +#define HW_ATL_RDM_DESCDRESET_DEFAULT 0x0 + +/* rdm_desc_init_i bitfield definitions + * preprocessor definitions for the bitfield rdm_desc_init_i. + * port="pif_rdm_desc_init_i" + */ + +/* register address for bitfield rdm_desc_init_i */ +#define HW_ATL_RDM_RX_DMA_DESC_CACHE_INIT_ADR 0x00005a00 +/* bitmask for bitfield rdm_desc_init_i */ +#define HW_ATL_RDM_RX_DMA_DESC_CACHE_INIT_MSK 0xffffffff +/* inverted bitmask for bitfield rdm_desc_init_i */ +#define HW_ATL_RDM_RX_DMA_DESC_CACHE_INIT_MSKN 0x00000000 +/* lower bit position of bitfield rdm_desc_init_i */ +#define HW_ATL_RDM_RX_DMA_DESC_CACHE_INIT_SHIFT 0 +/* width of bitfield rdm_desc_init_i */ +#define HW_ATL_RDM_RX_DMA_DESC_CACHE_INIT_WIDTH 32 +/* default value of bitfield rdm_desc_init_i */ +#define HW_ATL_RDM_RX_DMA_DESC_CACHE_INIT_DEFAULT 0x0 + +/* rx int_desc_wrb_en bitfield definitions + * preprocessor definitions for the bitfield "int_desc_wrb_en". + * port="pif_rdm_int_desc_wrb_en_i" + */ + +/* register address for bitfield int_desc_wrb_en */ +#define HW_ATL_RDM_INT_DESC_WRB_EN_ADR 0x00005a30 +/* bitmask for bitfield int_desc_wrb_en */ +#define HW_ATL_RDM_INT_DESC_WRB_EN_MSK 0x00000004 +/* inverted bitmask for bitfield int_desc_wrb_en */ +#define HW_ATL_RDM_INT_DESC_WRB_EN_MSKN 0xfffffffb +/* lower bit position of bitfield int_desc_wrb_en */ +#define HW_ATL_RDM_INT_DESC_WRB_EN_SHIFT 2 +/* width of bitfield int_desc_wrb_en */ +#define HW_ATL_RDM_INT_DESC_WRB_EN_WIDTH 1 +/* default value of bitfield int_desc_wrb_en */ +#define HW_ATL_RDM_INT_DESC_WRB_EN_DEFAULT 0x0 + +/* rx dca{d}_hdr_en bitfield definitions + * preprocessor definitions for the bitfield "dca{d}_hdr_en". + * parameter: dca {d} | stride size 0x4 | range [0, 31] + * port="pif_rdm_dca_hdr_en_i[0]" + */ + +/* register address for bitfield dca{d}_hdr_en */ +#define HW_ATL_RDM_DCADHDR_EN_ADR(dca) (0x00006100 + (dca) * 0x4) +/* bitmask for bitfield dca{d}_hdr_en */ +#define HW_ATL_RDM_DCADHDR_EN_MSK 0x40000000 +/* inverted bitmask for bitfield dca{d}_hdr_en */ +#define HW_ATL_RDM_DCADHDR_EN_MSKN 0xbfffffff +/* lower bit position of bitfield dca{d}_hdr_en */ +#define HW_ATL_RDM_DCADHDR_EN_SHIFT 30 +/* width of bitfield dca{d}_hdr_en */ +#define HW_ATL_RDM_DCADHDR_EN_WIDTH 1 +/* default value of bitfield dca{d}_hdr_en */ +#define HW_ATL_RDM_DCADHDR_EN_DEFAULT 0x0 + +/* rx dca{d}_pay_en bitfield definitions + * preprocessor definitions for the bitfield "dca{d}_pay_en". + * parameter: dca {d} | stride size 0x4 | range [0, 31] + * port="pif_rdm_dca_pay_en_i[0]" + */ + +/* register address for bitfield dca{d}_pay_en */ +#define HW_ATL_RDM_DCADPAY_EN_ADR(dca) (0x00006100 + (dca) * 0x4) +/* bitmask for bitfield dca{d}_pay_en */ +#define HW_ATL_RDM_DCADPAY_EN_MSK 0x20000000 +/* inverted bitmask for bitfield dca{d}_pay_en */ +#define HW_ATL_RDM_DCADPAY_EN_MSKN 0xdfffffff +/* lower bit position of bitfield dca{d}_pay_en */ +#define HW_ATL_RDM_DCADPAY_EN_SHIFT 29 +/* width of bitfield dca{d}_pay_en */ +#define HW_ATL_RDM_DCADPAY_EN_WIDTH 1 +/* default value of bitfield dca{d}_pay_en */ +#define HW_ATL_RDM_DCADPAY_EN_DEFAULT 0x0 + +/* RX rdm_int_rim_en Bitfield Definitions + * Preprocessor definitions for the bitfield "rdm_int_rim_en". + * PORT="pif_rdm_int_rim_en_i" + */ + +/* Register address for bitfield rdm_int_rim_en */ +#define HW_ATL_RDM_INT_RIM_EN_ADR 0x00005A30 +/* Bitmask for bitfield rdm_int_rim_en */ +#define HW_ATL_RDM_INT_RIM_EN_MSK 0x00000008 +/* Inverted bitmask for bitfield rdm_int_rim_en */ +#define HW_ATL_RDM_INT_RIM_EN_MSKN 0xFFFFFFF7 +/* Lower bit position of bitfield rdm_int_rim_en */ +#define HW_ATL_RDM_INT_RIM_EN_SHIFT 3 +/* Width of bitfield rdm_int_rim_en */ +#define HW_ATL_RDM_INT_RIM_EN_WIDTH 1 +/* Default value of bitfield rdm_int_rim_en */ +#define HW_ATL_RDM_INT_RIM_EN_DEFAULT 0x0 + +/* general interrupt mapping register definitions + * preprocessor definitions for general interrupt mapping register + * base address: 0x00002180 + * parameter: regidx {f} | stride size 0x4 | range [0, 3] + */ +#define HW_ATL_GEN_INTR_MAP_ADR(regidx) (0x00002180u + (regidx) * 0x4) + +/* general interrupt status register definitions + * preprocessor definitions for general interrupt status register + * address: 0x000021A0 + */ + +#define HW_ATL_GEN_INTR_STAT_ADR 0x000021A4U + +/* interrupt global control register definitions + * preprocessor definitions for interrupt global control register + * address: 0x00002300 + */ +#define HW_ATL_INTR_GLB_CTL_ADR 0x00002300u + +/* interrupt throttle register definitions + * preprocessor definitions for interrupt throttle register + * base address: 0x00002800 + * parameter: throttle {t} | stride size 0x4 | range [0, 31] + */ +#define HW_ATL_INTR_THR_ADR(throttle) (0x00002800u + (throttle) * 0x4) + +/* rx dma descriptor base address lsw definitions + * preprocessor definitions for rx dma descriptor base address lsw + * base address: 0x00005b00 + * parameter: descriptor {d} | stride size 0x20 | range [0, 31] + */ +#define HW_ATL_RX_DMA_DESC_BASE_ADDRLSW_ADR(descriptor) \ +(0x00005b00u + (descriptor) * 0x20) + +/* rx dma descriptor base address msw definitions + * preprocessor definitions for rx dma descriptor base address msw + * base address: 0x00005b04 + * parameter: descriptor {d} | stride size 0x20 | range [0, 31] + */ +#define HW_ATL_RX_DMA_DESC_BASE_ADDRMSW_ADR(descriptor) \ +(0x00005b04u + (descriptor) * 0x20) + +/* rx dma descriptor status register definitions + * preprocessor definitions for rx dma descriptor status register + * base address: 0x00005b14 + * parameter: descriptor {d} | stride size 0x20 | range [0, 31] + */ +#define HW_ATL_RX_DMA_DESC_STAT_ADR(descriptor) \ + (0x00005b14u + (descriptor) * 0x20) + +/* rx dma descriptor tail pointer register definitions + * preprocessor definitions for rx dma descriptor tail pointer register + * base address: 0x00005b10 + * parameter: descriptor {d} | stride size 0x20 | range [0, 31] + */ +#define HW_ATL_RX_DMA_DESC_TAIL_PTR_ADR(descriptor) \ + (0x00005b10u + (descriptor) * 0x20) + +/* rx interrupt moderation control register definitions + * Preprocessor definitions for RX Interrupt Moderation Control Register + * Base Address: 0x00005A40 + * Parameter: RIM {R} | stride size 0x4 | range [0, 31] + */ +#define HW_ATL_RX_INTR_MODERATION_CTL_ADR(rim) (0x00005A40u + (rim) * 0x4) + +/* rx filter multicast filter mask register definitions + * preprocessor definitions for rx filter multicast filter mask register + * address: 0x00005270 + */ +#define HW_ATL_RX_FLR_MCST_FLR_MSK_ADR 0x00005270u + +/* rx filter multicast filter register definitions + * preprocessor definitions for rx filter multicast filter register + * base address: 0x00005250 + * parameter: filter {f} | stride size 0x4 | range [0, 7] + */ +#define HW_ATL_RX_FLR_MCST_FLR_ADR(filter) (0x00005250u + (filter) * 0x4) + +/* RX Filter RSS Control Register 1 Definitions + * Preprocessor definitions for RX Filter RSS Control Register 1 + * Address: 0x000054C0 + */ +#define HW_ATL_RX_FLR_RSS_CONTROL1_ADR 0x000054C0u + +/* RX Filter Control Register 2 Definitions + * Preprocessor definitions for RX Filter Control Register 2 + * Address: 0x00005104 + */ +#define HW_ATL_RX_FLR_CONTROL2_ADR 0x00005104u + +/* tx tx dma debug control [1f:0] bitfield definitions + * preprocessor definitions for the bitfield "tx dma debug control [1f:0]". + * port="pif_tdm_debug_cntl_i[31:0]" + */ + +/* register address for bitfield tx dma debug control [1f:0] */ +#define HW_ATL_TDM_TX_DMA_DEBUG_CTL_ADR 0x00008920 +/* bitmask for bitfield tx dma debug control [1f:0] */ +#define HW_ATL_TDM_TX_DMA_DEBUG_CTL_MSK 0xffffffff +/* inverted bitmask for bitfield tx dma debug control [1f:0] */ +#define HW_ATL_TDM_TX_DMA_DEBUG_CTL_MSKN 0x00000000 +/* lower bit position of bitfield tx dma debug control [1f:0] */ +#define HW_ATL_TDM_TX_DMA_DEBUG_CTL_SHIFT 0 +/* width of bitfield tx dma debug control [1f:0] */ +#define HW_ATL_TDM_TX_DMA_DEBUG_CTL_WIDTH 32 +/* default value of bitfield tx dma debug control [1f:0] */ +#define HW_ATL_TDM_TX_DMA_DEBUG_CTL_DEFAULT 0x0 + +/* tx dma descriptor base address lsw definitions + * preprocessor definitions for tx dma descriptor base address lsw + * base address: 0x00007c00 + * parameter: descriptor {d} | stride size 0x40 | range [0, 31] + */ +#define HW_ATL_TX_DMA_DESC_BASE_ADDRLSW_ADR(descriptor) \ + (0x00007c00u + (descriptor) * 0x40) + +/* tx dma descriptor tail pointer register definitions + * preprocessor definitions for tx dma descriptor tail pointer register + * base address: 0x00007c10 + * parameter: descriptor {d} | stride size 0x40 | range [0, 31] + */ +#define HW_ATL_TX_DMA_DESC_TAIL_PTR_ADR(descriptor) \ + (0x00007c10u + (descriptor) * 0x40) + +/* rx dma_sys_loopback bitfield definitions + * preprocessor definitions for the bitfield "dma_sys_loopback". + * port="pif_rpb_dma_sys_lbk_i" + */ + +/* register address for bitfield dma_sys_loopback */ +#define HW_ATL_RPB_DMA_SYS_LBK_ADR 0x00005000 +/* bitmask for bitfield dma_sys_loopback */ +#define HW_ATL_RPB_DMA_SYS_LBK_MSK 0x00000040 +/* inverted bitmask for bitfield dma_sys_loopback */ +#define HW_ATL_RPB_DMA_SYS_LBK_MSKN 0xffffffbf +/* lower bit position of bitfield dma_sys_loopback */ +#define HW_ATL_RPB_DMA_SYS_LBK_SHIFT 6 +/* width of bitfield dma_sys_loopback */ +#define HW_ATL_RPB_DMA_SYS_LBK_WIDTH 1 +/* default value of bitfield dma_sys_loopback */ +#define HW_ATL_RPB_DMA_SYS_LBK_DEFAULT 0x0 + +/* rx rx_tc_mode bitfield definitions + * preprocessor definitions for the bitfield "rx_tc_mode". + * port="pif_rpb_rx_tc_mode_i,pif_rpf_rx_tc_mode_i" + */ + +/* register address for bitfield rx_tc_mode */ +#define HW_ATL_RPB_RPF_RX_TC_MODE_ADR 0x00005700 +/* bitmask for bitfield rx_tc_mode */ +#define HW_ATL_RPB_RPF_RX_TC_MODE_MSK 0x00000100 +/* inverted bitmask for bitfield rx_tc_mode */ +#define HW_ATL_RPB_RPF_RX_TC_MODE_MSKN 0xfffffeff +/* lower bit position of bitfield rx_tc_mode */ +#define HW_ATL_RPB_RPF_RX_TC_MODE_SHIFT 8 +/* width of bitfield rx_tc_mode */ +#define HW_ATL_RPB_RPF_RX_TC_MODE_WIDTH 1 +/* default value of bitfield rx_tc_mode */ +#define HW_ATL_RPB_RPF_RX_TC_MODE_DEFAULT 0x0 + +/* rx rx_buf_en bitfield definitions + * preprocessor definitions for the bitfield "rx_buf_en". + * port="pif_rpb_rx_buf_en_i" + */ + +/* register address for bitfield rx_buf_en */ +#define HW_ATL_RPB_RX_BUF_EN_ADR 0x00005700 +/* bitmask for bitfield rx_buf_en */ +#define HW_ATL_RPB_RX_BUF_EN_MSK 0x00000001 +/* inverted bitmask for bitfield rx_buf_en */ +#define HW_ATL_RPB_RX_BUF_EN_MSKN 0xfffffffe +/* lower bit position of bitfield rx_buf_en */ +#define HW_ATL_RPB_RX_BUF_EN_SHIFT 0 +/* width of bitfield rx_buf_en */ +#define HW_ATL_RPB_RX_BUF_EN_WIDTH 1 +/* default value of bitfield rx_buf_en */ +#define HW_ATL_RPB_RX_BUF_EN_DEFAULT 0x0 + +/* rx rx{b}_hi_thresh[d:0] bitfield definitions + * preprocessor definitions for the bitfield "rx{b}_hi_thresh[d:0]". + * parameter: buffer {b} | stride size 0x10 | range [0, 7] + * port="pif_rpb_rx0_hi_thresh_i[13:0]" + */ + +/* register address for bitfield rx{b}_hi_thresh[d:0] */ +#define HW_ATL_RPB_RXBHI_THRESH_ADR(buffer) (0x00005714 + (buffer) * 0x10) +/* bitmask for bitfield rx{b}_hi_thresh[d:0] */ +#define HW_ATL_RPB_RXBHI_THRESH_MSK 0x3fff0000 +/* inverted bitmask for bitfield rx{b}_hi_thresh[d:0] */ +#define HW_ATL_RPB_RXBHI_THRESH_MSKN 0xc000ffff +/* lower bit position of bitfield rx{b}_hi_thresh[d:0] */ +#define HW_ATL_RPB_RXBHI_THRESH_SHIFT 16 +/* width of bitfield rx{b}_hi_thresh[d:0] */ +#define HW_ATL_RPB_RXBHI_THRESH_WIDTH 14 +/* default value of bitfield rx{b}_hi_thresh[d:0] */ +#define HW_ATL_RPB_RXBHI_THRESH_DEFAULT 0x0 + +/* rx rx{b}_lo_thresh[d:0] bitfield definitions + * preprocessor definitions for the bitfield "rx{b}_lo_thresh[d:0]". + * parameter: buffer {b} | stride size 0x10 | range [0, 7] + * port="pif_rpb_rx0_lo_thresh_i[13:0]" + */ + +/* register address for bitfield rx{b}_lo_thresh[d:0] */ +#define HW_ATL_RPB_RXBLO_THRESH_ADR(buffer) (0x00005714 + (buffer) * 0x10) +/* bitmask for bitfield rx{b}_lo_thresh[d:0] */ +#define HW_ATL_RPB_RXBLO_THRESH_MSK 0x00003fff +/* inverted bitmask for bitfield rx{b}_lo_thresh[d:0] */ +#define HW_ATL_RPB_RXBLO_THRESH_MSKN 0xffffc000 +/* lower bit position of bitfield rx{b}_lo_thresh[d:0] */ +#define HW_ATL_RPB_RXBLO_THRESH_SHIFT 0 +/* width of bitfield rx{b}_lo_thresh[d:0] */ +#define HW_ATL_RPB_RXBLO_THRESH_WIDTH 14 +/* default value of bitfield rx{b}_lo_thresh[d:0] */ +#define HW_ATL_RPB_RXBLO_THRESH_DEFAULT 0x0 + +/* rx rx_fc_mode[1:0] bitfield definitions + * preprocessor definitions for the bitfield "rx_fc_mode[1:0]". + * port="pif_rpb_rx_fc_mode_i[1:0]" + */ + +/* register address for bitfield rx_fc_mode[1:0] */ +#define HW_ATL_RPB_RX_FC_MODE_ADR 0x00005700 +/* bitmask for bitfield rx_fc_mode[1:0] */ +#define HW_ATL_RPB_RX_FC_MODE_MSK 0x00000030 +/* inverted bitmask for bitfield rx_fc_mode[1:0] */ +#define HW_ATL_RPB_RX_FC_MODE_MSKN 0xffffffcf +/* lower bit position of bitfield rx_fc_mode[1:0] */ +#define HW_ATL_RPB_RX_FC_MODE_SHIFT 4 +/* width of bitfield rx_fc_mode[1:0] */ +#define HW_ATL_RPB_RX_FC_MODE_WIDTH 2 +/* default value of bitfield rx_fc_mode[1:0] */ +#define HW_ATL_RPB_RX_FC_MODE_DEFAULT 0x0 + +/* rx rx{b}_buf_size[8:0] bitfield definitions + * preprocessor definitions for the bitfield "rx{b}_buf_size[8:0]". + * parameter: buffer {b} | stride size 0x10 | range [0, 7] + * port="pif_rpb_rx0_buf_size_i[8:0]" + */ + +/* register address for bitfield rx{b}_buf_size[8:0] */ +#define HW_ATL_RPB_RXBBUF_SIZE_ADR(buffer) (0x00005710 + (buffer) * 0x10) +/* bitmask for bitfield rx{b}_buf_size[8:0] */ +#define HW_ATL_RPB_RXBBUF_SIZE_MSK 0x000001ff +/* inverted bitmask for bitfield rx{b}_buf_size[8:0] */ +#define HW_ATL_RPB_RXBBUF_SIZE_MSKN 0xfffffe00 +/* lower bit position of bitfield rx{b}_buf_size[8:0] */ +#define HW_ATL_RPB_RXBBUF_SIZE_SHIFT 0 +/* width of bitfield rx{b}_buf_size[8:0] */ +#define HW_ATL_RPB_RXBBUF_SIZE_WIDTH 9 +/* default value of bitfield rx{b}_buf_size[8:0] */ +#define HW_ATL_RPB_RXBBUF_SIZE_DEFAULT 0x0 + +/* rx rx{b}_xoff_en bitfield definitions + * preprocessor definitions for the bitfield "rx{b}_xoff_en". + * parameter: buffer {b} | stride size 0x10 | range [0, 7] + * port="pif_rpb_rx_xoff_en_i[0]" + */ + +/* register address for bitfield rx{b}_xoff_en */ +#define HW_ATL_RPB_RXBXOFF_EN_ADR(buffer) (0x00005714 + (buffer) * 0x10) +/* bitmask for bitfield rx{b}_xoff_en */ +#define HW_ATL_RPB_RXBXOFF_EN_MSK 0x80000000 +/* inverted bitmask for bitfield rx{b}_xoff_en */ +#define HW_ATL_RPB_RXBXOFF_EN_MSKN 0x7fffffff +/* lower bit position of bitfield rx{b}_xoff_en */ +#define HW_ATL_RPB_RXBXOFF_EN_SHIFT 31 +/* width of bitfield rx{b}_xoff_en */ +#define HW_ATL_RPB_RXBXOFF_EN_WIDTH 1 +/* default value of bitfield rx{b}_xoff_en */ +#define HW_ATL_RPB_RXBXOFF_EN_DEFAULT 0x0 + +/* rx l2_bc_thresh[f:0] bitfield definitions + * preprocessor definitions for the bitfield "l2_bc_thresh[f:0]". + * port="pif_rpf_l2_bc_thresh_i[15:0]" + */ + +/* register address for bitfield l2_bc_thresh[f:0] */ +#define HW_ATL_RPFL2BC_THRESH_ADR 0x00005100 +/* bitmask for bitfield l2_bc_thresh[f:0] */ +#define HW_ATL_RPFL2BC_THRESH_MSK 0xffff0000 +/* inverted bitmask for bitfield l2_bc_thresh[f:0] */ +#define HW_ATL_RPFL2BC_THRESH_MSKN 0x0000ffff +/* lower bit position of bitfield l2_bc_thresh[f:0] */ +#define HW_ATL_RPFL2BC_THRESH_SHIFT 16 +/* width of bitfield l2_bc_thresh[f:0] */ +#define HW_ATL_RPFL2BC_THRESH_WIDTH 16 +/* default value of bitfield l2_bc_thresh[f:0] */ +#define HW_ATL_RPFL2BC_THRESH_DEFAULT 0x0 + +/* rx l2_bc_en bitfield definitions + * preprocessor definitions for the bitfield "l2_bc_en". + * port="pif_rpf_l2_bc_en_i" + */ + +/* register address for bitfield l2_bc_en */ +#define HW_ATL_RPFL2BC_EN_ADR 0x00005100 +/* bitmask for bitfield l2_bc_en */ +#define HW_ATL_RPFL2BC_EN_MSK 0x00000001 +/* inverted bitmask for bitfield l2_bc_en */ +#define HW_ATL_RPFL2BC_EN_MSKN 0xfffffffe +/* lower bit position of bitfield l2_bc_en */ +#define HW_ATL_RPFL2BC_EN_SHIFT 0 +/* width of bitfield l2_bc_en */ +#define HW_ATL_RPFL2BC_EN_WIDTH 1 +/* default value of bitfield l2_bc_en */ +#define HW_ATL_RPFL2BC_EN_DEFAULT 0x0 + +/* rx l2_bc_act[2:0] bitfield definitions + * preprocessor definitions for the bitfield "l2_bc_act[2:0]". + * port="pif_rpf_l2_bc_act_i[2:0]" + */ + +/* register address for bitfield l2_bc_act[2:0] */ +#define HW_ATL_RPFL2BC_ACT_ADR 0x00005100 +/* bitmask for bitfield l2_bc_act[2:0] */ +#define HW_ATL_RPFL2BC_ACT_MSK 0x00007000 +/* inverted bitmask for bitfield l2_bc_act[2:0] */ +#define HW_ATL_RPFL2BC_ACT_MSKN 0xffff8fff +/* lower bit position of bitfield l2_bc_act[2:0] */ +#define HW_ATL_RPFL2BC_ACT_SHIFT 12 +/* width of bitfield l2_bc_act[2:0] */ +#define HW_ATL_RPFL2BC_ACT_WIDTH 3 +/* default value of bitfield l2_bc_act[2:0] */ +#define HW_ATL_RPFL2BC_ACT_DEFAULT 0x0 + +/* rx l2_mc_en{f} bitfield definitions + * preprocessor definitions for the bitfield "l2_mc_en{f}". + * parameter: filter {f} | stride size 0x4 | range [0, 7] + * port="pif_rpf_l2_mc_en_i[0]" + */ + +/* register address for bitfield l2_mc_en{f} */ +#define HW_ATL_RPFL2MC_ENF_ADR(filter) (0x00005250 + (filter) * 0x4) +/* bitmask for bitfield l2_mc_en{f} */ +#define HW_ATL_RPFL2MC_ENF_MSK 0x80000000 +/* inverted bitmask for bitfield l2_mc_en{f} */ +#define HW_ATL_RPFL2MC_ENF_MSKN 0x7fffffff +/* lower bit position of bitfield l2_mc_en{f} */ +#define HW_ATL_RPFL2MC_ENF_SHIFT 31 +/* width of bitfield l2_mc_en{f} */ +#define HW_ATL_RPFL2MC_ENF_WIDTH 1 +/* default value of bitfield l2_mc_en{f} */ +#define HW_ATL_RPFL2MC_ENF_DEFAULT 0x0 + +/* rx l2_promis_mode bitfield definitions + * preprocessor definitions for the bitfield "l2_promis_mode". + * port="pif_rpf_l2_promis_mode_i" + */ + +/* register address for bitfield l2_promis_mode */ +#define HW_ATL_RPFL2PROMIS_MODE_ADR 0x00005100 +/* bitmask for bitfield l2_promis_mode */ +#define HW_ATL_RPFL2PROMIS_MODE_MSK 0x00000008 +/* inverted bitmask for bitfield l2_promis_mode */ +#define HW_ATL_RPFL2PROMIS_MODE_MSKN 0xfffffff7 +/* lower bit position of bitfield l2_promis_mode */ +#define HW_ATL_RPFL2PROMIS_MODE_SHIFT 3 +/* width of bitfield l2_promis_mode */ +#define HW_ATL_RPFL2PROMIS_MODE_WIDTH 1 +/* default value of bitfield l2_promis_mode */ +#define HW_ATL_RPFL2PROMIS_MODE_DEFAULT 0x0 + +/* rx l2_uc_act{f}[2:0] bitfield definitions + * preprocessor definitions for the bitfield "l2_uc_act{f}[2:0]". + * parameter: filter {f} | stride size 0x8 | range [0, 37] + * port="pif_rpf_l2_uc_act0_i[2:0]" + */ + +/* register address for bitfield l2_uc_act{f}[2:0] */ +#define HW_ATL_RPFL2UC_ACTF_ADR(filter) (0x00005114 + (filter) * 0x8) +/* bitmask for bitfield l2_uc_act{f}[2:0] */ +#define HW_ATL_RPFL2UC_ACTF_MSK 0x00070000 +/* inverted bitmask for bitfield l2_uc_act{f}[2:0] */ +#define HW_ATL_RPFL2UC_ACTF_MSKN 0xfff8ffff +/* lower bit position of bitfield l2_uc_act{f}[2:0] */ +#define HW_ATL_RPFL2UC_ACTF_SHIFT 16 +/* width of bitfield l2_uc_act{f}[2:0] */ +#define HW_ATL_RPFL2UC_ACTF_WIDTH 3 +/* default value of bitfield l2_uc_act{f}[2:0] */ +#define HW_ATL_RPFL2UC_ACTF_DEFAULT 0x0 + +/* rx l2_uc_en{f} bitfield definitions + * preprocessor definitions for the bitfield "l2_uc_en{f}". + * parameter: filter {f} | stride size 0x8 | range [0, 37] + * port="pif_rpf_l2_uc_en_i[0]" + */ + +/* register address for bitfield l2_uc_en{f} */ +#define HW_ATL_RPFL2UC_ENF_ADR(filter) (0x00005114 + (filter) * 0x8) +/* bitmask for bitfield l2_uc_en{f} */ +#define HW_ATL_RPFL2UC_ENF_MSK 0x80000000 +/* inverted bitmask for bitfield l2_uc_en{f} */ +#define HW_ATL_RPFL2UC_ENF_MSKN 0x7fffffff +/* lower bit position of bitfield l2_uc_en{f} */ +#define HW_ATL_RPFL2UC_ENF_SHIFT 31 +/* width of bitfield l2_uc_en{f} */ +#define HW_ATL_RPFL2UC_ENF_WIDTH 1 +/* default value of bitfield l2_uc_en{f} */ +#define HW_ATL_RPFL2UC_ENF_DEFAULT 0x0 + +/* register address for bitfield l2_uc_da{f}_lsw[1f:0] */ +#define HW_ATL_RPFL2UC_DAFLSW_ADR(filter) (0x00005110 + (filter) * 0x8) +/* register address for bitfield l2_uc_da{f}_msw[f:0] */ +#define HW_ATL_RPFL2UC_DAFMSW_ADR(filter) (0x00005114 + (filter) * 0x8) +/* bitmask for bitfield l2_uc_da{f}_msw[f:0] */ +#define HW_ATL_RPFL2UC_DAFMSW_MSK 0x0000ffff +/* lower bit position of bitfield l2_uc_da{f}_msw[f:0] */ +#define HW_ATL_RPFL2UC_DAFMSW_SHIFT 0 + +/* rx l2_mc_accept_all bitfield definitions + * Preprocessor definitions for the bitfield "l2_mc_accept_all". + * PORT="pif_rpf_l2_mc_all_accept_i" + */ + +/* Register address for bitfield l2_mc_accept_all */ +#define HW_ATL_RPFL2MC_ACCEPT_ALL_ADR 0x00005270 +/* Bitmask for bitfield l2_mc_accept_all */ +#define HW_ATL_RPFL2MC_ACCEPT_ALL_MSK 0x00004000 +/* Inverted bitmask for bitfield l2_mc_accept_all */ +#define HW_ATL_RPFL2MC_ACCEPT_ALL_MSKN 0xFFFFBFFF +/* Lower bit position of bitfield l2_mc_accept_all */ +#define HW_ATL_RPFL2MC_ACCEPT_ALL_SHIFT 14 +/* Width of bitfield l2_mc_accept_all */ +#define HW_ATL_RPFL2MC_ACCEPT_ALL_WIDTH 1 +/* Default value of bitfield l2_mc_accept_all */ +#define HW_ATL_RPFL2MC_ACCEPT_ALL_DEFAULT 0x0 + +/* width of bitfield rx_tc_up{t}[2:0] */ +#define HW_ATL_RPF_RPB_RX_TC_UPT_WIDTH 3 +/* default value of bitfield rx_tc_up{t}[2:0] */ +#define HW_ATL_RPF_RPB_RX_TC_UPT_DEFAULT 0x0 + +/* rx rss_key_addr[4:0] bitfield definitions + * preprocessor definitions for the bitfield "rss_key_addr[4:0]". + * port="pif_rpf_rss_key_addr_i[4:0]" + */ + +/* register address for bitfield rss_key_addr[4:0] */ +#define HW_ATL_RPF_RSS_KEY_ADDR_ADR 0x000054d0 +/* bitmask for bitfield rss_key_addr[4:0] */ +#define HW_ATL_RPF_RSS_KEY_ADDR_MSK 0x0000001f +/* inverted bitmask for bitfield rss_key_addr[4:0] */ +#define HW_ATL_RPF_RSS_KEY_ADDR_MSKN 0xffffffe0 +/* lower bit position of bitfield rss_key_addr[4:0] */ +#define HW_ATL_RPF_RSS_KEY_ADDR_SHIFT 0 +/* width of bitfield rss_key_addr[4:0] */ +#define HW_ATL_RPF_RSS_KEY_ADDR_WIDTH 5 +/* default value of bitfield rss_key_addr[4:0] */ +#define HW_ATL_RPF_RSS_KEY_ADDR_DEFAULT 0x0 + +/* rx rss_key_wr_data[1f:0] bitfield definitions + * preprocessor definitions for the bitfield "rss_key_wr_data[1f:0]". + * port="pif_rpf_rss_key_wr_data_i[31:0]" + */ + +/* register address for bitfield rss_key_wr_data[1f:0] */ +#define HW_ATL_RPF_RSS_KEY_WR_DATA_ADR 0x000054d4 +/* bitmask for bitfield rss_key_wr_data[1f:0] */ +#define HW_ATL_RPF_RSS_KEY_WR_DATA_MSK 0xffffffff +/* inverted bitmask for bitfield rss_key_wr_data[1f:0] */ +#define HW_ATL_RPF_RSS_KEY_WR_DATA_MSKN 0x00000000 +/* lower bit position of bitfield rss_key_wr_data[1f:0] */ +#define HW_ATL_RPF_RSS_KEY_WR_DATA_SHIFT 0 +/* width of bitfield rss_key_wr_data[1f:0] */ +#define HW_ATL_RPF_RSS_KEY_WR_DATA_WIDTH 32 +/* default value of bitfield rss_key_wr_data[1f:0] */ +#define HW_ATL_RPF_RSS_KEY_WR_DATA_DEFAULT 0x0 + +/* rx rss_key_wr_en_i bitfield definitions + * preprocessor definitions for the bitfield "rss_key_wr_en_i". + * port="pif_rpf_rss_key_wr_en_i" + */ + +/* register address for bitfield rss_key_wr_en_i */ +#define HW_ATL_RPF_RSS_KEY_WR_ENI_ADR 0x000054d0 +/* bitmask for bitfield rss_key_wr_en_i */ +#define HW_ATL_RPF_RSS_KEY_WR_ENI_MSK 0x00000020 +/* inverted bitmask for bitfield rss_key_wr_en_i */ +#define HW_ATL_RPF_RSS_KEY_WR_ENI_MSKN 0xffffffdf +/* lower bit position of bitfield rss_key_wr_en_i */ +#define HW_ATL_RPF_RSS_KEY_WR_ENI_SHIFT 5 +/* width of bitfield rss_key_wr_en_i */ +#define HW_ATL_RPF_RSS_KEY_WR_ENI_WIDTH 1 +/* default value of bitfield rss_key_wr_en_i */ +#define HW_ATL_RPF_RSS_KEY_WR_ENI_DEFAULT 0x0 + +/* rx rss_redir_addr[3:0] bitfield definitions + * preprocessor definitions for the bitfield "rss_redir_addr[3:0]". + * port="pif_rpf_rss_redir_addr_i[3:0]" + */ + +/* register address for bitfield rss_redir_addr[3:0] */ +#define HW_ATL_RPF_RSS_REDIR_ADDR_ADR 0x000054e0 +/* bitmask for bitfield rss_redir_addr[3:0] */ +#define HW_ATL_RPF_RSS_REDIR_ADDR_MSK 0x0000000f +/* inverted bitmask for bitfield rss_redir_addr[3:0] */ +#define HW_ATL_RPF_RSS_REDIR_ADDR_MSKN 0xfffffff0 +/* lower bit position of bitfield rss_redir_addr[3:0] */ +#define HW_ATL_RPF_RSS_REDIR_ADDR_SHIFT 0 +/* width of bitfield rss_redir_addr[3:0] */ +#define HW_ATL_RPF_RSS_REDIR_ADDR_WIDTH 4 +/* default value of bitfield rss_redir_addr[3:0] */ +#define HW_ATL_RPF_RSS_REDIR_ADDR_DEFAULT 0x0 + +/* rx rss_redir_wr_data[f:0] bitfield definitions + * preprocessor definitions for the bitfield "rss_redir_wr_data[f:0]". + * port="pif_rpf_rss_redir_wr_data_i[15:0]" + */ + +/* register address for bitfield rss_redir_wr_data[f:0] */ +#define HW_ATL_RPF_RSS_REDIR_WR_DATA_ADR 0x000054e4 +/* bitmask for bitfield rss_redir_wr_data[f:0] */ +#define HW_ATL_RPF_RSS_REDIR_WR_DATA_MSK 0x0000ffff +/* inverted bitmask for bitfield rss_redir_wr_data[f:0] */ +#define HW_ATL_RPF_RSS_REDIR_WR_DATA_MSKN 0xffff0000 +/* lower bit position of bitfield rss_redir_wr_data[f:0] */ +#define HW_ATL_RPF_RSS_REDIR_WR_DATA_SHIFT 0 +/* width of bitfield rss_redir_wr_data[f:0] */ +#define HW_ATL_RPF_RSS_REDIR_WR_DATA_WIDTH 16 +/* default value of bitfield rss_redir_wr_data[f:0] */ +#define HW_ATL_RPF_RSS_REDIR_WR_DATA_DEFAULT 0x0 + +/* rx rss_redir_wr_en_i bitfield definitions + * preprocessor definitions for the bitfield "rss_redir_wr_en_i". + * port="pif_rpf_rss_redir_wr_en_i" + */ + +/* register address for bitfield rss_redir_wr_en_i */ +#define HW_ATL_RPF_RSS_REDIR_WR_ENI_ADR 0x000054e0 +/* bitmask for bitfield rss_redir_wr_en_i */ +#define HW_ATL_RPF_RSS_REDIR_WR_ENI_MSK 0x00000010 +/* inverted bitmask for bitfield rss_redir_wr_en_i */ +#define HW_ATL_RPF_RSS_REDIR_WR_ENI_MSKN 0xffffffef +/* lower bit position of bitfield rss_redir_wr_en_i */ +#define HW_ATL_RPF_RSS_REDIR_WR_ENI_SHIFT 4 +/* width of bitfield rss_redir_wr_en_i */ +#define HW_ATL_RPF_RSS_REDIR_WR_ENI_WIDTH 1 +/* default value of bitfield rss_redir_wr_en_i */ +#define HW_ATL_RPF_RSS_REDIR_WR_ENI_DEFAULT 0x0 + +/* rx tpo_rpf_sys_loopback bitfield definitions + * preprocessor definitions for the bitfield "tpo_rpf_sys_loopback". + * port="pif_rpf_tpo_pkt_sys_lbk_i" + */ + +/* register address for bitfield tpo_rpf_sys_loopback */ +#define HW_ATL_RPF_TPO_RPF_SYS_LBK_ADR 0x00005000 +/* bitmask for bitfield tpo_rpf_sys_loopback */ +#define HW_ATL_RPF_TPO_RPF_SYS_LBK_MSK 0x00000100 +/* inverted bitmask for bitfield tpo_rpf_sys_loopback */ +#define HW_ATL_RPF_TPO_RPF_SYS_LBK_MSKN 0xfffffeff +/* lower bit position of bitfield tpo_rpf_sys_loopback */ +#define HW_ATL_RPF_TPO_RPF_SYS_LBK_SHIFT 8 +/* width of bitfield tpo_rpf_sys_loopback */ +#define HW_ATL_RPF_TPO_RPF_SYS_LBK_WIDTH 1 +/* default value of bitfield tpo_rpf_sys_loopback */ +#define HW_ATL_RPF_TPO_RPF_SYS_LBK_DEFAULT 0x0 + +/* rx vl_inner_tpid[f:0] bitfield definitions + * preprocessor definitions for the bitfield "vl_inner_tpid[f:0]". + * port="pif_rpf_vl_inner_tpid_i[15:0]" + */ + +/* register address for bitfield vl_inner_tpid[f:0] */ +#define HW_ATL_RPF_VL_INNER_TPID_ADR 0x00005284 +/* bitmask for bitfield vl_inner_tpid[f:0] */ +#define HW_ATL_RPF_VL_INNER_TPID_MSK 0x0000ffff +/* inverted bitmask for bitfield vl_inner_tpid[f:0] */ +#define HW_ATL_RPF_VL_INNER_TPID_MSKN 0xffff0000 +/* lower bit position of bitfield vl_inner_tpid[f:0] */ +#define HW_ATL_RPF_VL_INNER_TPID_SHIFT 0 +/* width of bitfield vl_inner_tpid[f:0] */ +#define HW_ATL_RPF_VL_INNER_TPID_WIDTH 16 +/* default value of bitfield vl_inner_tpid[f:0] */ +#define HW_ATL_RPF_VL_INNER_TPID_DEFAULT 0x8100 + +/* rx vl_outer_tpid[f:0] bitfield definitions + * preprocessor definitions for the bitfield "vl_outer_tpid[f:0]". + * port="pif_rpf_vl_outer_tpid_i[15:0]" + */ + +/* register address for bitfield vl_outer_tpid[f:0] */ +#define HW_ATL_RPF_VL_OUTER_TPID_ADR 0x00005284 +/* bitmask for bitfield vl_outer_tpid[f:0] */ +#define HW_ATL_RPF_VL_OUTER_TPID_MSK 0xffff0000 +/* inverted bitmask for bitfield vl_outer_tpid[f:0] */ +#define HW_ATL_RPF_VL_OUTER_TPID_MSKN 0x0000ffff +/* lower bit position of bitfield vl_outer_tpid[f:0] */ +#define HW_ATL_RPF_VL_OUTER_TPID_SHIFT 16 +/* width of bitfield vl_outer_tpid[f:0] */ +#define HW_ATL_RPF_VL_OUTER_TPID_WIDTH 16 +/* default value of bitfield vl_outer_tpid[f:0] */ +#define HW_ATL_RPF_VL_OUTER_TPID_DEFAULT 0x88a8 + +/* rx vl_promis_mode bitfield definitions + * preprocessor definitions for the bitfield "vl_promis_mode". + * port="pif_rpf_vl_promis_mode_i" + */ + +/* register address for bitfield vl_promis_mode */ +#define HW_ATL_RPF_VL_PROMIS_MODE_ADR 0x00005280 +/* bitmask for bitfield vl_promis_mode */ +#define HW_ATL_RPF_VL_PROMIS_MODE_MSK 0x00000002 +/* inverted bitmask for bitfield vl_promis_mode */ +#define HW_ATL_RPF_VL_PROMIS_MODE_MSKN 0xfffffffd +/* lower bit position of bitfield vl_promis_mode */ +#define HW_ATL_RPF_VL_PROMIS_MODE_SHIFT 1 +/* width of bitfield vl_promis_mode */ +#define HW_ATL_RPF_VL_PROMIS_MODE_WIDTH 1 +/* default value of bitfield vl_promis_mode */ +#define HW_ATL_RPF_VL_PROMIS_MODE_DEFAULT 0x0 + +/* RX vl_accept_untagged_mode Bitfield Definitions + * Preprocessor definitions for the bitfield "vl_accept_untagged_mode". + * PORT="pif_rpf_vl_accept_untagged_i" + */ + +/* Register address for bitfield vl_accept_untagged_mode */ +#define HW_ATL_RPF_VL_ACCEPT_UNTAGGED_MODE_ADR 0x00005280 +/* Bitmask for bitfield vl_accept_untagged_mode */ +#define HW_ATL_RPF_VL_ACCEPT_UNTAGGED_MODE_MSK 0x00000004 +/* Inverted bitmask for bitfield vl_accept_untagged_mode */ +#define HW_ATL_RPF_VL_ACCEPT_UNTAGGED_MODE_MSKN 0xFFFFFFFB +/* Lower bit position of bitfield vl_accept_untagged_mode */ +#define HW_ATL_RPF_VL_ACCEPT_UNTAGGED_MODE_SHIFT 2 +/* Width of bitfield vl_accept_untagged_mode */ +#define HW_ATL_RPF_VL_ACCEPT_UNTAGGED_MODE_WIDTH 1 +/* Default value of bitfield vl_accept_untagged_mode */ +#define HW_ATL_RPF_VL_ACCEPT_UNTAGGED_MODE_DEFAULT 0x0 + +/* rX vl_untagged_act[2:0] Bitfield Definitions + * Preprocessor definitions for the bitfield "vl_untagged_act[2:0]". + * PORT="pif_rpf_vl_untagged_act_i[2:0]" + */ + +/* Register address for bitfield vl_untagged_act[2:0] */ +#define HW_ATL_RPF_VL_UNTAGGED_ACT_ADR 0x00005280 +/* Bitmask for bitfield vl_untagged_act[2:0] */ +#define HW_ATL_RPF_VL_UNTAGGED_ACT_MSK 0x00000038 +/* Inverted bitmask for bitfield vl_untagged_act[2:0] */ +#define HW_ATL_RPF_VL_UNTAGGED_ACT_MSKN 0xFFFFFFC7 +/* Lower bit position of bitfield vl_untagged_act[2:0] */ +#define HW_ATL_RPF_VL_UNTAGGED_ACT_SHIFT 3 +/* Width of bitfield vl_untagged_act[2:0] */ +#define HW_ATL_RPF_VL_UNTAGGED_ACT_WIDTH 3 +/* Default value of bitfield vl_untagged_act[2:0] */ +#define HW_ATL_RPF_VL_UNTAGGED_ACT_DEFAULT 0x0 + +/* RX vl_en{F} Bitfield Definitions + * Preprocessor definitions for the bitfield "vl_en{F}". + * Parameter: filter {F} | stride size 0x4 | range [0, 15] + * PORT="pif_rpf_vl_en_i[0]" + */ + +/* Register address for bitfield vl_en{F} */ +#define HW_ATL_RPF_VL_EN_F_ADR(filter) (0x00005290 + (filter) * 0x4) +/* Bitmask for bitfield vl_en{F} */ +#define HW_ATL_RPF_VL_EN_F_MSK 0x80000000 +/* Inverted bitmask for bitfield vl_en{F} */ +#define HW_ATL_RPF_VL_EN_F_MSKN 0x7FFFFFFF +/* Lower bit position of bitfield vl_en{F} */ +#define HW_ATL_RPF_VL_EN_F_SHIFT 31 +/* Width of bitfield vl_en{F} */ +#define HW_ATL_RPF_VL_EN_F_WIDTH 1 +/* Default value of bitfield vl_en{F} */ +#define HW_ATL_RPF_VL_EN_F_DEFAULT 0x0 + +/* RX vl_act{F}[2:0] Bitfield Definitions + * Preprocessor definitions for the bitfield "vl_act{F}[2:0]". + * Parameter: filter {F} | stride size 0x4 | range [0, 15] + * PORT="pif_rpf_vl_act0_i[2:0]" + */ + +/* Register address for bitfield vl_act{F}[2:0] */ +#define HW_ATL_RPF_VL_ACT_F_ADR(filter) (0x00005290 + (filter) * 0x4) +/* Bitmask for bitfield vl_act{F}[2:0] */ +#define HW_ATL_RPF_VL_ACT_F_MSK 0x00070000 +/* Inverted bitmask for bitfield vl_act{F}[2:0] */ +#define HW_ATL_RPF_VL_ACT_F_MSKN 0xFFF8FFFF +/* Lower bit position of bitfield vl_act{F}[2:0] */ +#define HW_ATL_RPF_VL_ACT_F_SHIFT 16 +/* Width of bitfield vl_act{F}[2:0] */ +#define HW_ATL_RPF_VL_ACT_F_WIDTH 3 +/* Default value of bitfield vl_act{F}[2:0] */ +#define HW_ATL_RPF_VL_ACT_F_DEFAULT 0x0 + +/* RX vl_id{F}[B:0] Bitfield Definitions + * Preprocessor definitions for the bitfield "vl_id{F}[B:0]". + * Parameter: filter {F} | stride size 0x4 | range [0, 15] + * PORT="pif_rpf_vl_id0_i[11:0]" + */ + +/* Register address for bitfield vl_id{F}[B:0] */ +#define HW_ATL_RPF_VL_ID_F_ADR(filter) (0x00005290 + (filter) * 0x4) +/* Bitmask for bitfield vl_id{F}[B:0] */ +#define HW_ATL_RPF_VL_ID_F_MSK 0x00000FFF +/* Inverted bitmask for bitfield vl_id{F}[B:0] */ +#define HW_ATL_RPF_VL_ID_F_MSKN 0xFFFFF000 +/* Lower bit position of bitfield vl_id{F}[B:0] */ +#define HW_ATL_RPF_VL_ID_F_SHIFT 0 +/* Width of bitfield vl_id{F}[B:0] */ +#define HW_ATL_RPF_VL_ID_F_WIDTH 12 +/* Default value of bitfield vl_id{F}[B:0] */ +#define HW_ATL_RPF_VL_ID_F_DEFAULT 0x0 + +/* RX et_en{F} Bitfield Definitions + * Preprocessor definitions for the bitfield "et_en{F}". + * Parameter: filter {F} | stride size 0x4 | range [0, 15] + * PORT="pif_rpf_et_en_i[0]" + */ + +/* Register address for bitfield et_en{F} */ +#define HW_ATL_RPF_ET_EN_F_ADR(filter) (0x00005300 + (filter) * 0x4) +/* Bitmask for bitfield et_en{F} */ +#define HW_ATL_RPF_ET_EN_F_MSK 0x80000000 +/* Inverted bitmask for bitfield et_en{F} */ +#define HW_ATL_RPF_ET_EN_F_MSKN 0x7FFFFFFF +/* Lower bit position of bitfield et_en{F} */ +#define HW_ATL_RPF_ET_EN_F_SHIFT 31 +/* Width of bitfield et_en{F} */ +#define HW_ATL_RPF_ET_EN_F_WIDTH 1 +/* Default value of bitfield et_en{F} */ +#define HW_ATL_RPF_ET_EN_F_DEFAULT 0x0 + +/* rx et_en{f} bitfield definitions + * preprocessor definitions for the bitfield "et_en{f}". + * parameter: filter {f} | stride size 0x4 | range [0, 15] + * port="pif_rpf_et_en_i[0]" + */ + +/* register address for bitfield et_en{f} */ +#define HW_ATL_RPF_ET_ENF_ADR(filter) (0x00005300 + (filter) * 0x4) +/* bitmask for bitfield et_en{f} */ +#define HW_ATL_RPF_ET_ENF_MSK 0x80000000 +/* inverted bitmask for bitfield et_en{f} */ +#define HW_ATL_RPF_ET_ENF_MSKN 0x7fffffff +/* lower bit position of bitfield et_en{f} */ +#define HW_ATL_RPF_ET_ENF_SHIFT 31 +/* width of bitfield et_en{f} */ +#define HW_ATL_RPF_ET_ENF_WIDTH 1 +/* default value of bitfield et_en{f} */ +#define HW_ATL_RPF_ET_ENF_DEFAULT 0x0 + +/* rx et_up{f}_en bitfield definitions + * preprocessor definitions for the bitfield "et_up{f}_en". + * parameter: filter {f} | stride size 0x4 | range [0, 15] + * port="pif_rpf_et_up_en_i[0]" + */ + +/* register address for bitfield et_up{f}_en */ +#define HW_ATL_RPF_ET_UPFEN_ADR(filter) (0x00005300 + (filter) * 0x4) +/* bitmask for bitfield et_up{f}_en */ +#define HW_ATL_RPF_ET_UPFEN_MSK 0x40000000 +/* inverted bitmask for bitfield et_up{f}_en */ +#define HW_ATL_RPF_ET_UPFEN_MSKN 0xbfffffff +/* lower bit position of bitfield et_up{f}_en */ +#define HW_ATL_RPF_ET_UPFEN_SHIFT 30 +/* width of bitfield et_up{f}_en */ +#define HW_ATL_RPF_ET_UPFEN_WIDTH 1 +/* default value of bitfield et_up{f}_en */ +#define HW_ATL_RPF_ET_UPFEN_DEFAULT 0x0 + +/* rx et_rxq{f}_en bitfield definitions + * preprocessor definitions for the bitfield "et_rxq{f}_en". + * parameter: filter {f} | stride size 0x4 | range [0, 15] + * port="pif_rpf_et_rxq_en_i[0]" + */ + +/* register address for bitfield et_rxq{f}_en */ +#define HW_ATL_RPF_ET_RXQFEN_ADR(filter) (0x00005300 + (filter) * 0x4) +/* bitmask for bitfield et_rxq{f}_en */ +#define HW_ATL_RPF_ET_RXQFEN_MSK 0x20000000 +/* inverted bitmask for bitfield et_rxq{f}_en */ +#define HW_ATL_RPF_ET_RXQFEN_MSKN 0xdfffffff +/* lower bit position of bitfield et_rxq{f}_en */ +#define HW_ATL_RPF_ET_RXQFEN_SHIFT 29 +/* width of bitfield et_rxq{f}_en */ +#define HW_ATL_RPF_ET_RXQFEN_WIDTH 1 +/* default value of bitfield et_rxq{f}_en */ +#define HW_ATL_RPF_ET_RXQFEN_DEFAULT 0x0 + +/* rx et_up{f}[2:0] bitfield definitions + * preprocessor definitions for the bitfield "et_up{f}[2:0]". + * parameter: filter {f} | stride size 0x4 | range [0, 15] + * port="pif_rpf_et_up0_i[2:0]" + */ + +/* register address for bitfield et_up{f}[2:0] */ +#define HW_ATL_RPF_ET_UPF_ADR(filter) (0x00005300 + (filter) * 0x4) +/* bitmask for bitfield et_up{f}[2:0] */ +#define HW_ATL_RPF_ET_UPF_MSK 0x1c000000 +/* inverted bitmask for bitfield et_up{f}[2:0] */ +#define HW_ATL_RPF_ET_UPF_MSKN 0xe3ffffff +/* lower bit position of bitfield et_up{f}[2:0] */ +#define HW_ATL_RPF_ET_UPF_SHIFT 26 +/* width of bitfield et_up{f}[2:0] */ +#define HW_ATL_RPF_ET_UPF_WIDTH 3 +/* default value of bitfield et_up{f}[2:0] */ +#define HW_ATL_RPF_ET_UPF_DEFAULT 0x0 + +/* rx et_rxq{f}[4:0] bitfield definitions + * preprocessor definitions for the bitfield "et_rxq{f}[4:0]". + * parameter: filter {f} | stride size 0x4 | range [0, 15] + * port="pif_rpf_et_rxq0_i[4:0]" + */ + +/* register address for bitfield et_rxq{f}[4:0] */ +#define HW_ATL_RPF_ET_RXQF_ADR(filter) (0x00005300 + (filter) * 0x4) +/* bitmask for bitfield et_rxq{f}[4:0] */ +#define HW_ATL_RPF_ET_RXQF_MSK 0x01f00000 +/* inverted bitmask for bitfield et_rxq{f}[4:0] */ +#define HW_ATL_RPF_ET_RXQF_MSKN 0xfe0fffff +/* lower bit position of bitfield et_rxq{f}[4:0] */ +#define HW_ATL_RPF_ET_RXQF_SHIFT 20 +/* width of bitfield et_rxq{f}[4:0] */ +#define HW_ATL_RPF_ET_RXQF_WIDTH 5 +/* default value of bitfield et_rxq{f}[4:0] */ +#define HW_ATL_RPF_ET_RXQF_DEFAULT 0x0 + +/* rx et_mng_rxq{f} bitfield definitions + * preprocessor definitions for the bitfield "et_mng_rxq{f}". + * parameter: filter {f} | stride size 0x4 | range [0, 15] + * port="pif_rpf_et_mng_rxq_i[0]" + */ + +/* register address for bitfield et_mng_rxq{f} */ +#define HW_ATL_RPF_ET_MNG_RXQF_ADR(filter) (0x00005300 + (filter) * 0x4) +/* bitmask for bitfield et_mng_rxq{f} */ +#define HW_ATL_RPF_ET_MNG_RXQF_MSK 0x00080000 +/* inverted bitmask for bitfield et_mng_rxq{f} */ +#define HW_ATL_RPF_ET_MNG_RXQF_MSKN 0xfff7ffff +/* lower bit position of bitfield et_mng_rxq{f} */ +#define HW_ATL_RPF_ET_MNG_RXQF_SHIFT 19 +/* width of bitfield et_mng_rxq{f} */ +#define HW_ATL_RPF_ET_MNG_RXQF_WIDTH 1 +/* default value of bitfield et_mng_rxq{f} */ +#define HW_ATL_RPF_ET_MNG_RXQF_DEFAULT 0x0 + +/* rx et_act{f}[2:0] bitfield definitions + * preprocessor definitions for the bitfield "et_act{f}[2:0]". + * parameter: filter {f} | stride size 0x4 | range [0, 15] + * port="pif_rpf_et_act0_i[2:0]" + */ + +/* register address for bitfield et_act{f}[2:0] */ +#define HW_ATL_RPF_ET_ACTF_ADR(filter) (0x00005300 + (filter) * 0x4) +/* bitmask for bitfield et_act{f}[2:0] */ +#define HW_ATL_RPF_ET_ACTF_MSK 0x00070000 +/* inverted bitmask for bitfield et_act{f}[2:0] */ +#define HW_ATL_RPF_ET_ACTF_MSKN 0xfff8ffff +/* lower bit position of bitfield et_act{f}[2:0] */ +#define HW_ATL_RPF_ET_ACTF_SHIFT 16 +/* width of bitfield et_act{f}[2:0] */ +#define HW_ATL_RPF_ET_ACTF_WIDTH 3 +/* default value of bitfield et_act{f}[2:0] */ +#define HW_ATL_RPF_ET_ACTF_DEFAULT 0x0 + +/* rx et_val{f}[f:0] bitfield definitions + * preprocessor definitions for the bitfield "et_val{f}[f:0]". + * parameter: filter {f} | stride size 0x4 | range [0, 15] + * port="pif_rpf_et_val0_i[15:0]" + */ + +/* register address for bitfield et_val{f}[f:0] */ +#define HW_ATL_RPF_ET_VALF_ADR(filter) (0x00005300 + (filter) * 0x4) +/* bitmask for bitfield et_val{f}[f:0] */ +#define HW_ATL_RPF_ET_VALF_MSK 0x0000ffff +/* inverted bitmask for bitfield et_val{f}[f:0] */ +#define HW_ATL_RPF_ET_VALF_MSKN 0xffff0000 +/* lower bit position of bitfield et_val{f}[f:0] */ +#define HW_ATL_RPF_ET_VALF_SHIFT 0 +/* width of bitfield et_val{f}[f:0] */ +#define HW_ATL_RPF_ET_VALF_WIDTH 16 +/* default value of bitfield et_val{f}[f:0] */ +#define HW_ATL_RPF_ET_VALF_DEFAULT 0x0 + +/* rx ipv4_chk_en bitfield definitions + * preprocessor definitions for the bitfield "ipv4_chk_en". + * port="pif_rpo_ipv4_chk_en_i" + */ + +/* register address for bitfield ipv4_chk_en */ +#define HW_ATL_RPO_IPV4CHK_EN_ADR 0x00005580 +/* bitmask for bitfield ipv4_chk_en */ +#define HW_ATL_RPO_IPV4CHK_EN_MSK 0x00000002 +/* inverted bitmask for bitfield ipv4_chk_en */ +#define HW_ATL_RPO_IPV4CHK_EN_MSKN 0xfffffffd +/* lower bit position of bitfield ipv4_chk_en */ +#define HW_ATL_RPO_IPV4CHK_EN_SHIFT 1 +/* width of bitfield ipv4_chk_en */ +#define HW_ATL_RPO_IPV4CHK_EN_WIDTH 1 +/* default value of bitfield ipv4_chk_en */ +#define HW_ATL_RPO_IPV4CHK_EN_DEFAULT 0x0 + +/* rx desc{d}_vl_strip bitfield definitions + * preprocessor definitions for the bitfield "desc{d}_vl_strip". + * parameter: descriptor {d} | stride size 0x20 | range [0, 31] + * port="pif_rpo_desc_vl_strip_i[0]" + */ + +/* register address for bitfield desc{d}_vl_strip */ +#define HW_ATL_RPO_DESCDVL_STRIP_ADR(descriptor) \ + (0x00005b08 + (descriptor) * 0x20) +/* bitmask for bitfield desc{d}_vl_strip */ +#define HW_ATL_RPO_DESCDVL_STRIP_MSK 0x20000000 +/* inverted bitmask for bitfield desc{d}_vl_strip */ +#define HW_ATL_RPO_DESCDVL_STRIP_MSKN 0xdfffffff +/* lower bit position of bitfield desc{d}_vl_strip */ +#define HW_ATL_RPO_DESCDVL_STRIP_SHIFT 29 +/* width of bitfield desc{d}_vl_strip */ +#define HW_ATL_RPO_DESCDVL_STRIP_WIDTH 1 +/* default value of bitfield desc{d}_vl_strip */ +#define HW_ATL_RPO_DESCDVL_STRIP_DEFAULT 0x0 + +/* rx l4_chk_en bitfield definitions + * preprocessor definitions for the bitfield "l4_chk_en". + * port="pif_rpo_l4_chk_en_i" + */ + +/* register address for bitfield l4_chk_en */ +#define HW_ATL_RPOL4CHK_EN_ADR 0x00005580 +/* bitmask for bitfield l4_chk_en */ +#define HW_ATL_RPOL4CHK_EN_MSK 0x00000001 +/* inverted bitmask for bitfield l4_chk_en */ +#define HW_ATL_RPOL4CHK_EN_MSKN 0xfffffffe +/* lower bit position of bitfield l4_chk_en */ +#define HW_ATL_RPOL4CHK_EN_SHIFT 0 +/* width of bitfield l4_chk_en */ +#define HW_ATL_RPOL4CHK_EN_WIDTH 1 +/* default value of bitfield l4_chk_en */ +#define HW_ATL_RPOL4CHK_EN_DEFAULT 0x0 + +/* rx reg_res_dsbl bitfield definitions + * preprocessor definitions for the bitfield "reg_res_dsbl". + * port="pif_rx_reg_res_dsbl_i" + */ + +/* register address for bitfield reg_res_dsbl */ +#define HW_ATL_RX_REG_RES_DSBL_ADR 0x00005000 +/* bitmask for bitfield reg_res_dsbl */ +#define HW_ATL_RX_REG_RES_DSBL_MSK 0x20000000 +/* inverted bitmask for bitfield reg_res_dsbl */ +#define HW_ATL_RX_REG_RES_DSBL_MSKN 0xdfffffff +/* lower bit position of bitfield reg_res_dsbl */ +#define HW_ATL_RX_REG_RES_DSBL_SHIFT 29 +/* width of bitfield reg_res_dsbl */ +#define HW_ATL_RX_REG_RES_DSBL_WIDTH 1 +/* default value of bitfield reg_res_dsbl */ +#define HW_ATL_RX_REG_RES_DSBL_DEFAULT 0x1 + +/* tx dca{d}_cpuid[7:0] bitfield definitions + * preprocessor definitions for the bitfield "dca{d}_cpuid[7:0]". + * parameter: dca {d} | stride size 0x4 | range [0, 31] + * port="pif_tdm_dca0_cpuid_i[7:0]" + */ + +/* register address for bitfield dca{d}_cpuid[7:0] */ +#define HW_ATL_TDM_DCADCPUID_ADR(dca) (0x00008400 + (dca) * 0x4) +/* bitmask for bitfield dca{d}_cpuid[7:0] */ +#define HW_ATL_TDM_DCADCPUID_MSK 0x000000ff +/* inverted bitmask for bitfield dca{d}_cpuid[7:0] */ +#define HW_ATL_TDM_DCADCPUID_MSKN 0xffffff00 +/* lower bit position of bitfield dca{d}_cpuid[7:0] */ +#define HW_ATL_TDM_DCADCPUID_SHIFT 0 +/* width of bitfield dca{d}_cpuid[7:0] */ +#define HW_ATL_TDM_DCADCPUID_WIDTH 8 +/* default value of bitfield dca{d}_cpuid[7:0] */ +#define HW_ATL_TDM_DCADCPUID_DEFAULT 0x0 + +/* tx lso_en[1f:0] bitfield definitions + * preprocessor definitions for the bitfield "lso_en[1f:0]". + * port="pif_tdm_lso_en_i[31:0]" + */ + +/* register address for bitfield lso_en[1f:0] */ +#define HW_ATL_TDM_LSO_EN_ADR 0x00007810 +/* bitmask for bitfield lso_en[1f:0] */ +#define HW_ATL_TDM_LSO_EN_MSK 0xffffffff +/* inverted bitmask for bitfield lso_en[1f:0] */ +#define HW_ATL_TDM_LSO_EN_MSKN 0x00000000 +/* lower bit position of bitfield lso_en[1f:0] */ +#define HW_ATL_TDM_LSO_EN_SHIFT 0 +/* width of bitfield lso_en[1f:0] */ +#define HW_ATL_TDM_LSO_EN_WIDTH 32 +/* default value of bitfield lso_en[1f:0] */ +#define HW_ATL_TDM_LSO_EN_DEFAULT 0x0 + +/* tx dca_en bitfield definitions + * preprocessor definitions for the bitfield "dca_en". + * port="pif_tdm_dca_en_i" + */ + +/* register address for bitfield dca_en */ +#define HW_ATL_TDM_DCA_EN_ADR 0x00008480 +/* bitmask for bitfield dca_en */ +#define HW_ATL_TDM_DCA_EN_MSK 0x80000000 +/* inverted bitmask for bitfield dca_en */ +#define HW_ATL_TDM_DCA_EN_MSKN 0x7fffffff +/* lower bit position of bitfield dca_en */ +#define HW_ATL_TDM_DCA_EN_SHIFT 31 +/* width of bitfield dca_en */ +#define HW_ATL_TDM_DCA_EN_WIDTH 1 +/* default value of bitfield dca_en */ +#define HW_ATL_TDM_DCA_EN_DEFAULT 0x1 + +/* tx dca_mode[3:0] bitfield definitions + * preprocessor definitions for the bitfield "dca_mode[3:0]". + * port="pif_tdm_dca_mode_i[3:0]" + */ + +/* register address for bitfield dca_mode[3:0] */ +#define HW_ATL_TDM_DCA_MODE_ADR 0x00008480 +/* bitmask for bitfield dca_mode[3:0] */ +#define HW_ATL_TDM_DCA_MODE_MSK 0x0000000f +/* inverted bitmask for bitfield dca_mode[3:0] */ +#define HW_ATL_TDM_DCA_MODE_MSKN 0xfffffff0 +/* lower bit position of bitfield dca_mode[3:0] */ +#define HW_ATL_TDM_DCA_MODE_SHIFT 0 +/* width of bitfield dca_mode[3:0] */ +#define HW_ATL_TDM_DCA_MODE_WIDTH 4 +/* default value of bitfield dca_mode[3:0] */ +#define HW_ATL_TDM_DCA_MODE_DEFAULT 0x0 + +/* tx dca{d}_desc_en bitfield definitions + * preprocessor definitions for the bitfield "dca{d}_desc_en". + * parameter: dca {d} | stride size 0x4 | range [0, 31] + * port="pif_tdm_dca_desc_en_i[0]" + */ + +/* register address for bitfield dca{d}_desc_en */ +#define HW_ATL_TDM_DCADDESC_EN_ADR(dca) (0x00008400 + (dca) * 0x4) +/* bitmask for bitfield dca{d}_desc_en */ +#define HW_ATL_TDM_DCADDESC_EN_MSK 0x80000000 +/* inverted bitmask for bitfield dca{d}_desc_en */ +#define HW_ATL_TDM_DCADDESC_EN_MSKN 0x7fffffff +/* lower bit position of bitfield dca{d}_desc_en */ +#define HW_ATL_TDM_DCADDESC_EN_SHIFT 31 +/* width of bitfield dca{d}_desc_en */ +#define HW_ATL_TDM_DCADDESC_EN_WIDTH 1 +/* default value of bitfield dca{d}_desc_en */ +#define HW_ATL_TDM_DCADDESC_EN_DEFAULT 0x0 + +/* tx desc{d}_en bitfield definitions + * preprocessor definitions for the bitfield "desc{d}_en". + * parameter: descriptor {d} | stride size 0x40 | range [0, 31] + * port="pif_tdm_desc_en_i[0]" + */ + +/* register address for bitfield desc{d}_en */ +#define HW_ATL_TDM_DESCDEN_ADR(descriptor) (0x00007c08 + (descriptor) * 0x40) +/* bitmask for bitfield desc{d}_en */ +#define HW_ATL_TDM_DESCDEN_MSK 0x80000000 +/* inverted bitmask for bitfield desc{d}_en */ +#define HW_ATL_TDM_DESCDEN_MSKN 0x7fffffff +/* lower bit position of bitfield desc{d}_en */ +#define HW_ATL_TDM_DESCDEN_SHIFT 31 +/* width of bitfield desc{d}_en */ +#define HW_ATL_TDM_DESCDEN_WIDTH 1 +/* default value of bitfield desc{d}_en */ +#define HW_ATL_TDM_DESCDEN_DEFAULT 0x0 + +/* tx desc{d}_hd[c:0] bitfield definitions + * preprocessor definitions for the bitfield "desc{d}_hd[c:0]". + * parameter: descriptor {d} | stride size 0x40 | range [0, 31] + * port="tdm_pif_desc0_hd_o[12:0]" + */ + +/* register address for bitfield desc{d}_hd[c:0] */ +#define HW_ATL_TDM_DESCDHD_ADR(descriptor) (0x00007c0c + (descriptor) * 0x40) +/* bitmask for bitfield desc{d}_hd[c:0] */ +#define HW_ATL_TDM_DESCDHD_MSK 0x00001fff +/* inverted bitmask for bitfield desc{d}_hd[c:0] */ +#define HW_ATL_TDM_DESCDHD_MSKN 0xffffe000 +/* lower bit position of bitfield desc{d}_hd[c:0] */ +#define HW_ATL_TDM_DESCDHD_SHIFT 0 +/* width of bitfield desc{d}_hd[c:0] */ +#define HW_ATL_TDM_DESCDHD_WIDTH 13 + +/* tx desc{d}_len[9:0] bitfield definitions + * preprocessor definitions for the bitfield "desc{d}_len[9:0]". + * parameter: descriptor {d} | stride size 0x40 | range [0, 31] + * port="pif_tdm_desc0_len_i[9:0]" + */ + +/* register address for bitfield desc{d}_len[9:0] */ +#define HW_ATL_TDM_DESCDLEN_ADR(descriptor) (0x00007c08 + (descriptor) * 0x40) +/* bitmask for bitfield desc{d}_len[9:0] */ +#define HW_ATL_TDM_DESCDLEN_MSK 0x00001ff8 +/* inverted bitmask for bitfield desc{d}_len[9:0] */ +#define HW_ATL_TDM_DESCDLEN_MSKN 0xffffe007 +/* lower bit position of bitfield desc{d}_len[9:0] */ +#define HW_ATL_TDM_DESCDLEN_SHIFT 3 +/* width of bitfield desc{d}_len[9:0] */ +#define HW_ATL_TDM_DESCDLEN_WIDTH 10 +/* default value of bitfield desc{d}_len[9:0] */ +#define HW_ATL_TDM_DESCDLEN_DEFAULT 0x0 + +/* tx int_desc_wrb_en bitfield definitions + * preprocessor definitions for the bitfield "int_desc_wrb_en". + * port="pif_tdm_int_desc_wrb_en_i" + */ + +/* register address for bitfield int_desc_wrb_en */ +#define HW_ATL_TDM_INT_DESC_WRB_EN_ADR 0x00007b40 +/* bitmask for bitfield int_desc_wrb_en */ +#define HW_ATL_TDM_INT_DESC_WRB_EN_MSK 0x00000002 +/* inverted bitmask for bitfield int_desc_wrb_en */ +#define HW_ATL_TDM_INT_DESC_WRB_EN_MSKN 0xfffffffd +/* lower bit position of bitfield int_desc_wrb_en */ +#define HW_ATL_TDM_INT_DESC_WRB_EN_SHIFT 1 +/* width of bitfield int_desc_wrb_en */ +#define HW_ATL_TDM_INT_DESC_WRB_EN_WIDTH 1 +/* default value of bitfield int_desc_wrb_en */ +#define HW_ATL_TDM_INT_DESC_WRB_EN_DEFAULT 0x0 + +/* tx desc{d}_wrb_thresh[6:0] bitfield definitions + * preprocessor definitions for the bitfield "desc{d}_wrb_thresh[6:0]". + * parameter: descriptor {d} | stride size 0x40 | range [0, 31] + * port="pif_tdm_desc0_wrb_thresh_i[6:0]" + */ + +/* register address for bitfield desc{d}_wrb_thresh[6:0] */ +#define HW_ATL_TDM_DESCDWRB_THRESH_ADR(descriptor) \ + (0x00007c18 + (descriptor) * 0x40) +/* bitmask for bitfield desc{d}_wrb_thresh[6:0] */ +#define HW_ATL_TDM_DESCDWRB_THRESH_MSK 0x00007f00 +/* inverted bitmask for bitfield desc{d}_wrb_thresh[6:0] */ +#define HW_ATL_TDM_DESCDWRB_THRESH_MSKN 0xffff80ff +/* lower bit position of bitfield desc{d}_wrb_thresh[6:0] */ +#define HW_ATL_TDM_DESCDWRB_THRESH_SHIFT 8 +/* width of bitfield desc{d}_wrb_thresh[6:0] */ +#define HW_ATL_TDM_DESCDWRB_THRESH_WIDTH 7 +/* default value of bitfield desc{d}_wrb_thresh[6:0] */ +#define HW_ATL_TDM_DESCDWRB_THRESH_DEFAULT 0x0 + +/* tx lso_tcp_flag_first[b:0] bitfield definitions + * preprocessor definitions for the bitfield "lso_tcp_flag_first[b:0]". + * port="pif_thm_lso_tcp_flag_first_i[11:0]" + */ + +/* register address for bitfield lso_tcp_flag_first[b:0] */ +#define HW_ATL_THM_LSO_TCP_FLAG_FIRST_ADR 0x00007820 +/* bitmask for bitfield lso_tcp_flag_first[b:0] */ +#define HW_ATL_THM_LSO_TCP_FLAG_FIRST_MSK 0x00000fff +/* inverted bitmask for bitfield lso_tcp_flag_first[b:0] */ +#define HW_ATL_THM_LSO_TCP_FLAG_FIRST_MSKN 0xfffff000 +/* lower bit position of bitfield lso_tcp_flag_first[b:0] */ +#define HW_ATL_THM_LSO_TCP_FLAG_FIRST_SHIFT 0 +/* width of bitfield lso_tcp_flag_first[b:0] */ +#define HW_ATL_THM_LSO_TCP_FLAG_FIRST_WIDTH 12 +/* default value of bitfield lso_tcp_flag_first[b:0] */ +#define HW_ATL_THM_LSO_TCP_FLAG_FIRST_DEFAULT 0x0 + +/* tx lso_tcp_flag_last[b:0] bitfield definitions + * preprocessor definitions for the bitfield "lso_tcp_flag_last[b:0]". + * port="pif_thm_lso_tcp_flag_last_i[11:0]" + */ + +/* register address for bitfield lso_tcp_flag_last[b:0] */ +#define HW_ATL_THM_LSO_TCP_FLAG_LAST_ADR 0x00007824 +/* bitmask for bitfield lso_tcp_flag_last[b:0] */ +#define HW_ATL_THM_LSO_TCP_FLAG_LAST_MSK 0x00000fff +/* inverted bitmask for bitfield lso_tcp_flag_last[b:0] */ +#define HW_ATL_THM_LSO_TCP_FLAG_LAST_MSKN 0xfffff000 +/* lower bit position of bitfield lso_tcp_flag_last[b:0] */ +#define HW_ATL_THM_LSO_TCP_FLAG_LAST_SHIFT 0 +/* width of bitfield lso_tcp_flag_last[b:0] */ +#define HW_ATL_THM_LSO_TCP_FLAG_LAST_WIDTH 12 +/* default value of bitfield lso_tcp_flag_last[b:0] */ +#define HW_ATL_THM_LSO_TCP_FLAG_LAST_DEFAULT 0x0 + +/* tx lso_tcp_flag_mid[b:0] bitfield definitions + * preprocessor definitions for the bitfield "lso_tcp_flag_mid[b:0]". + * port="pif_thm_lso_tcp_flag_mid_i[11:0]" + */ + +/* Register address for bitfield lro_rsc_max[1F:0] */ +#define HW_ATL_RPO_LRO_RSC_MAX_ADR 0x00005598 +/* Bitmask for bitfield lro_rsc_max[1F:0] */ +#define HW_ATL_RPO_LRO_RSC_MAX_MSK 0xFFFFFFFF +/* Inverted bitmask for bitfield lro_rsc_max[1F:0] */ +#define HW_ATL_RPO_LRO_RSC_MAX_MSKN 0x00000000 +/* Lower bit position of bitfield lro_rsc_max[1F:0] */ +#define HW_ATL_RPO_LRO_RSC_MAX_SHIFT 0 +/* Width of bitfield lro_rsc_max[1F:0] */ +#define HW_ATL_RPO_LRO_RSC_MAX_WIDTH 32 +/* Default value of bitfield lro_rsc_max[1F:0] */ +#define HW_ATL_RPO_LRO_RSC_MAX_DEFAULT 0x0 + +/* RX lro_en[1F:0] Bitfield Definitions + * Preprocessor definitions for the bitfield "lro_en[1F:0]". + * PORT="pif_rpo_lro_en_i[31:0]" + */ + +/* Register address for bitfield lro_en[1F:0] */ +#define HW_ATL_RPO_LRO_EN_ADR 0x00005590 +/* Bitmask for bitfield lro_en[1F:0] */ +#define HW_ATL_RPO_LRO_EN_MSK 0xFFFFFFFF +/* Inverted bitmask for bitfield lro_en[1F:0] */ +#define HW_ATL_RPO_LRO_EN_MSKN 0x00000000 +/* Lower bit position of bitfield lro_en[1F:0] */ +#define HW_ATL_RPO_LRO_EN_SHIFT 0 +/* Width of bitfield lro_en[1F:0] */ +#define HW_ATL_RPO_LRO_EN_WIDTH 32 +/* Default value of bitfield lro_en[1F:0] */ +#define HW_ATL_RPO_LRO_EN_DEFAULT 0x0 + +/* RX lro_ptopt_en Bitfield Definitions + * Preprocessor definitions for the bitfield "lro_ptopt_en". + * PORT="pif_rpo_lro_ptopt_en_i" + */ + +/* Register address for bitfield lro_ptopt_en */ +#define HW_ATL_RPO_LRO_PTOPT_EN_ADR 0x00005594 +/* Bitmask for bitfield lro_ptopt_en */ +#define HW_ATL_RPO_LRO_PTOPT_EN_MSK 0x00008000 +/* Inverted bitmask for bitfield lro_ptopt_en */ +#define HW_ATL_RPO_LRO_PTOPT_EN_MSKN 0xFFFF7FFF +/* Lower bit position of bitfield lro_ptopt_en */ +#define HW_ATL_RPO_LRO_PTOPT_EN_SHIFT 15 +/* Width of bitfield lro_ptopt_en */ +#define HW_ATL_RPO_LRO_PTOPT_EN_WIDTH 1 +/* Default value of bitfield lro_ptopt_en */ +#define HW_ATL_RPO_LRO_PTOPT_EN_DEFALT 0x1 + +/* RX lro_q_ses_lmt Bitfield Definitions + * Preprocessor definitions for the bitfield "lro_q_ses_lmt". + * PORT="pif_rpo_lro_q_ses_lmt_i[1:0]" + */ + +/* Register address for bitfield lro_q_ses_lmt */ +#define HW_ATL_RPO_LRO_QSES_LMT_ADR 0x00005594 +/* Bitmask for bitfield lro_q_ses_lmt */ +#define HW_ATL_RPO_LRO_QSES_LMT_MSK 0x00003000 +/* Inverted bitmask for bitfield lro_q_ses_lmt */ +#define HW_ATL_RPO_LRO_QSES_LMT_MSKN 0xFFFFCFFF +/* Lower bit position of bitfield lro_q_ses_lmt */ +#define HW_ATL_RPO_LRO_QSES_LMT_SHIFT 12 +/* Width of bitfield lro_q_ses_lmt */ +#define HW_ATL_RPO_LRO_QSES_LMT_WIDTH 2 +/* Default value of bitfield lro_q_ses_lmt */ +#define HW_ATL_RPO_LRO_QSES_LMT_DEFAULT 0x1 + +/* RX lro_tot_dsc_lmt[1:0] Bitfield Definitions + * Preprocessor definitions for the bitfield "lro_tot_dsc_lmt[1:0]". + * PORT="pif_rpo_lro_tot_dsc_lmt_i[1:0]" + */ + +/* Register address for bitfield lro_tot_dsc_lmt[1:0] */ +#define HW_ATL_RPO_LRO_TOT_DSC_LMT_ADR 0x00005594 +/* Bitmask for bitfield lro_tot_dsc_lmt[1:0] */ +#define HW_ATL_RPO_LRO_TOT_DSC_LMT_MSK 0x00000060 +/* Inverted bitmask for bitfield lro_tot_dsc_lmt[1:0] */ +#define HW_ATL_RPO_LRO_TOT_DSC_LMT_MSKN 0xFFFFFF9F +/* Lower bit position of bitfield lro_tot_dsc_lmt[1:0] */ +#define HW_ATL_RPO_LRO_TOT_DSC_LMT_SHIFT 5 +/* Width of bitfield lro_tot_dsc_lmt[1:0] */ +#define HW_ATL_RPO_LRO_TOT_DSC_LMT_WIDTH 2 +/* Default value of bitfield lro_tot_dsc_lmt[1:0] */ +#define HW_ATL_RPO_LRO_TOT_DSC_LMT_DEFALT 0x1 + +/* RX lro_pkt_min[4:0] Bitfield Definitions + * Preprocessor definitions for the bitfield "lro_pkt_min[4:0]". + * PORT="pif_rpo_lro_pkt_min_i[4:0]" + */ + +/* Register address for bitfield lro_pkt_min[4:0] */ +#define HW_ATL_RPO_LRO_PKT_MIN_ADR 0x00005594 +/* Bitmask for bitfield lro_pkt_min[4:0] */ +#define HW_ATL_RPO_LRO_PKT_MIN_MSK 0x0000001F +/* Inverted bitmask for bitfield lro_pkt_min[4:0] */ +#define HW_ATL_RPO_LRO_PKT_MIN_MSKN 0xFFFFFFE0 +/* Lower bit position of bitfield lro_pkt_min[4:0] */ +#define HW_ATL_RPO_LRO_PKT_MIN_SHIFT 0 +/* Width of bitfield lro_pkt_min[4:0] */ +#define HW_ATL_RPO_LRO_PKT_MIN_WIDTH 5 +/* Default value of bitfield lro_pkt_min[4:0] */ +#define HW_ATL_RPO_LRO_PKT_MIN_DEFAULT 0x8 + +/* Width of bitfield lro{L}_des_max[1:0] */ +#define HW_ATL_RPO_LRO_LDES_MAX_WIDTH 2 +/* Default value of bitfield lro{L}_des_max[1:0] */ +#define HW_ATL_RPO_LRO_LDES_MAX_DEFAULT 0x0 + +/* RX lro_tb_div[11:0] Bitfield Definitions + * Preprocessor definitions for the bitfield "lro_tb_div[11:0]". + * PORT="pif_rpo_lro_tb_div_i[11:0]" + */ + +/* Register address for bitfield lro_tb_div[11:0] */ +#define HW_ATL_RPO_LRO_TB_DIV_ADR 0x00005620 +/* Bitmask for bitfield lro_tb_div[11:0] */ +#define HW_ATL_RPO_LRO_TB_DIV_MSK 0xFFF00000 +/* Inverted bitmask for bitfield lro_tb_div[11:0] */ +#define HW_ATL_RPO_LRO_TB_DIV_MSKN 0x000FFFFF +/* Lower bit position of bitfield lro_tb_div[11:0] */ +#define HW_ATL_RPO_LRO_TB_DIV_SHIFT 20 +/* Width of bitfield lro_tb_div[11:0] */ +#define HW_ATL_RPO_LRO_TB_DIV_WIDTH 12 +/* Default value of bitfield lro_tb_div[11:0] */ +#define HW_ATL_RPO_LRO_TB_DIV_DEFAULT 0xC35 + +/* RX lro_ina_ival[9:0] Bitfield Definitions + * Preprocessor definitions for the bitfield "lro_ina_ival[9:0]". + * PORT="pif_rpo_lro_ina_ival_i[9:0]" + */ + +/* Register address for bitfield lro_ina_ival[9:0] */ +#define HW_ATL_RPO_LRO_INA_IVAL_ADR 0x00005620 +/* Bitmask for bitfield lro_ina_ival[9:0] */ +#define HW_ATL_RPO_LRO_INA_IVAL_MSK 0x000FFC00 +/* Inverted bitmask for bitfield lro_ina_ival[9:0] */ +#define HW_ATL_RPO_LRO_INA_IVAL_MSKN 0xFFF003FF +/* Lower bit position of bitfield lro_ina_ival[9:0] */ +#define HW_ATL_RPO_LRO_INA_IVAL_SHIFT 10 +/* Width of bitfield lro_ina_ival[9:0] */ +#define HW_ATL_RPO_LRO_INA_IVAL_WIDTH 10 +/* Default value of bitfield lro_ina_ival[9:0] */ +#define HW_ATL_RPO_LRO_INA_IVAL_DEFAULT 0xA + +/* RX lro_max_ival[9:0] Bitfield Definitions + * Preprocessor definitions for the bitfield "lro_max_ival[9:0]". + * PORT="pif_rpo_lro_max_ival_i[9:0]" + */ + +/* Register address for bitfield lro_max_ival[9:0] */ +#define HW_ATL_RPO_LRO_MAX_IVAL_ADR 0x00005620 +/* Bitmask for bitfield lro_max_ival[9:0] */ +#define HW_ATL_RPO_LRO_MAX_IVAL_MSK 0x000003FF +/* Inverted bitmask for bitfield lro_max_ival[9:0] */ +#define HW_ATL_RPO_LRO_MAX_IVAL_MSKN 0xFFFFFC00 +/* Lower bit position of bitfield lro_max_ival[9:0] */ +#define HW_ATL_RPO_LRO_MAX_IVAL_SHIFT 0 +/* Width of bitfield lro_max_ival[9:0] */ +#define HW_ATL_RPO_LRO_MAX_IVAL_WIDTH 10 +/* Default value of bitfield lro_max_ival[9:0] */ +#define HW_ATL_RPO_LRO_MAX_IVAL_DEFAULT 0x19 + +/* TX dca{D}_cpuid[7:0] Bitfield Definitions + * Preprocessor definitions for the bitfield "dca{D}_cpuid[7:0]". + * Parameter: DCA {D} | stride size 0x4 | range [0, 31] + * PORT="pif_tdm_dca0_cpuid_i[7:0]" + */ + +/* Register address for bitfield dca{D}_cpuid[7:0] */ +#define HW_ATL_TDM_DCA_DCPUID_ADR(dca) (0x00008400 + (dca) * 0x4) +/* Bitmask for bitfield dca{D}_cpuid[7:0] */ +#define HW_ATL_TDM_DCA_DCPUID_MSK 0x000000FF +/* Inverted bitmask for bitfield dca{D}_cpuid[7:0] */ +#define HW_ATL_TDM_DCA_DCPUID_MSKN 0xFFFFFF00 +/* Lower bit position of bitfield dca{D}_cpuid[7:0] */ +#define HW_ATL_TDM_DCA_DCPUID_SHIFT 0 +/* Width of bitfield dca{D}_cpuid[7:0] */ +#define HW_ATL_TDM_DCA_DCPUID_WIDTH 8 +/* Default value of bitfield dca{D}_cpuid[7:0] */ +#define HW_ATL_TDM_DCA_DCPUID_DEFAULT 0x0 + +/* TX dca{D}_desc_en Bitfield Definitions + * Preprocessor definitions for the bitfield "dca{D}_desc_en". + * Parameter: DCA {D} | stride size 0x4 | range [0, 31] + * PORT="pif_tdm_dca_desc_en_i[0]" + */ + +/* Register address for bitfield dca{D}_desc_en */ +#define HW_ATL_TDM_DCA_DDESC_EN_ADR(dca) (0x00008400 + (dca) * 0x4) +/* Bitmask for bitfield dca{D}_desc_en */ +#define HW_ATL_TDM_DCA_DDESC_EN_MSK 0x80000000 +/* Inverted bitmask for bitfield dca{D}_desc_en */ +#define HW_ATL_TDM_DCA_DDESC_EN_MSKN 0x7FFFFFFF +/* Lower bit position of bitfield dca{D}_desc_en */ +#define HW_ATL_TDM_DCA_DDESC_EN_SHIFT 31 +/* Width of bitfield dca{D}_desc_en */ +#define HW_ATL_TDM_DCA_DDESC_EN_WIDTH 1 +/* Default value of bitfield dca{D}_desc_en */ +#define HW_ATL_TDM_DCA_DDESC_EN_DEFAULT 0x0 + +/* TX desc{D}_en Bitfield Definitions + * Preprocessor definitions for the bitfield "desc{D}_en". + * Parameter: descriptor {D} | stride size 0x40 | range [0, 31] + * PORT="pif_tdm_desc_en_i[0]" + */ + +/* Register address for bitfield desc{D}_en */ +#define HW_ATL_TDM_DESC_DEN_ADR(descriptor) (0x00007C08 + (descriptor) * 0x40) +/* Bitmask for bitfield desc{D}_en */ +#define HW_ATL_TDM_DESC_DEN_MSK 0x80000000 +/* Inverted bitmask for bitfield desc{D}_en */ +#define HW_ATL_TDM_DESC_DEN_MSKN 0x7FFFFFFF +/* Lower bit position of bitfield desc{D}_en */ +#define HW_ATL_TDM_DESC_DEN_SHIFT 31 +/* Width of bitfield desc{D}_en */ +#define HW_ATL_TDM_DESC_DEN_WIDTH 1 +/* Default value of bitfield desc{D}_en */ +#define HW_ATL_TDM_DESC_DEN_DEFAULT 0x0 + +/* TX desc{D}_hd[C:0] Bitfield Definitions + * Preprocessor definitions for the bitfield "desc{D}_hd[C:0]". + * Parameter: descriptor {D} | stride size 0x40 | range [0, 31] + * PORT="tdm_pif_desc0_hd_o[12:0]" + */ + +/* Register address for bitfield desc{D}_hd[C:0] */ +#define HW_ATL_TDM_DESC_DHD_ADR(descriptor) (0x00007C0C + (descriptor) * 0x40) +/* Bitmask for bitfield desc{D}_hd[C:0] */ +#define HW_ATL_TDM_DESC_DHD_MSK 0x00001FFF +/* Inverted bitmask for bitfield desc{D}_hd[C:0] */ +#define HW_ATL_TDM_DESC_DHD_MSKN 0xFFFFE000 +/* Lower bit position of bitfield desc{D}_hd[C:0] */ +#define HW_ATL_TDM_DESC_DHD_SHIFT 0 +/* Width of bitfield desc{D}_hd[C:0] */ +#define HW_ATL_TDM_DESC_DHD_WIDTH 13 + +/* TX desc{D}_len[9:0] Bitfield Definitions + * Preprocessor definitions for the bitfield "desc{D}_len[9:0]". + * Parameter: descriptor {D} | stride size 0x40 | range [0, 31] + * PORT="pif_tdm_desc0_len_i[9:0]" + */ + +/* Register address for bitfield desc{D}_len[9:0] */ +#define HW_ATL_TDM_DESC_DLEN_ADR(descriptor) (0x00007C08 + (descriptor) * 0x40) +/* Bitmask for bitfield desc{D}_len[9:0] */ +#define HW_ATL_TDM_DESC_DLEN_MSK 0x00001FF8 +/* Inverted bitmask for bitfield desc{D}_len[9:0] */ +#define HW_ATL_TDM_DESC_DLEN_MSKN 0xFFFFE007 +/* Lower bit position of bitfield desc{D}_len[9:0] */ +#define HW_ATL_TDM_DESC_DLEN_SHIFT 3 +/* Width of bitfield desc{D}_len[9:0] */ +#define HW_ATL_TDM_DESC_DLEN_WIDTH 10 +/* Default value of bitfield desc{D}_len[9:0] */ +#define HW_ATL_TDM_DESC_DLEN_DEFAULT 0x0 + +/* TX desc{D}_wrb_thresh[6:0] Bitfield Definitions + * Preprocessor definitions for the bitfield "desc{D}_wrb_thresh[6:0]". + * Parameter: descriptor {D} | stride size 0x40 | range [0, 31] + * PORT="pif_tdm_desc0_wrb_thresh_i[6:0]" + */ + +/* Register address for bitfield desc{D}_wrb_thresh[6:0] */ +#define HW_ATL_TDM_DESC_DWRB_THRESH_ADR(descriptor) \ + (0x00007C18 + (descriptor) * 0x40) +/* Bitmask for bitfield desc{D}_wrb_thresh[6:0] */ +#define HW_ATL_TDM_DESC_DWRB_THRESH_MSK 0x00007F00 +/* Inverted bitmask for bitfield desc{D}_wrb_thresh[6:0] */ +#define HW_ATL_TDM_DESC_DWRB_THRESH_MSKN 0xFFFF80FF +/* Lower bit position of bitfield desc{D}_wrb_thresh[6:0] */ +#define HW_ATL_TDM_DESC_DWRB_THRESH_SHIFT 8 +/* Width of bitfield desc{D}_wrb_thresh[6:0] */ +#define HW_ATL_TDM_DESC_DWRB_THRESH_WIDTH 7 +/* Default value of bitfield desc{D}_wrb_thresh[6:0] */ +#define HW_ATL_TDM_DESC_DWRB_THRESH_DEFAULT 0x0 + +/* TX tdm_int_mod_en Bitfield Definitions + * Preprocessor definitions for the bitfield "tdm_int_mod_en". + * PORT="pif_tdm_int_mod_en_i" + */ + +/* Register address for bitfield tdm_int_mod_en */ +#define HW_ATL_TDM_INT_MOD_EN_ADR 0x00007B40 +/* Bitmask for bitfield tdm_int_mod_en */ +#define HW_ATL_TDM_INT_MOD_EN_MSK 0x00000010 +/* Inverted bitmask for bitfield tdm_int_mod_en */ +#define HW_ATL_TDM_INT_MOD_EN_MSKN 0xFFFFFFEF +/* Lower bit position of bitfield tdm_int_mod_en */ +#define HW_ATL_TDM_INT_MOD_EN_SHIFT 4 +/* Width of bitfield tdm_int_mod_en */ +#define HW_ATL_TDM_INT_MOD_EN_WIDTH 1 +/* Default value of bitfield tdm_int_mod_en */ +#define HW_ATL_TDM_INT_MOD_EN_DEFAULT 0x0 + +/* TX lso_tcp_flag_mid[B:0] Bitfield Definitions + * Preprocessor definitions for the bitfield "lso_tcp_flag_mid[B:0]". + * PORT="pif_thm_lso_tcp_flag_mid_i[11:0]" + */ +/* register address for bitfield lso_tcp_flag_mid[b:0] */ +#define HW_ATL_THM_LSO_TCP_FLAG_MID_ADR 0x00007820 +/* bitmask for bitfield lso_tcp_flag_mid[b:0] */ +#define HW_ATL_THM_LSO_TCP_FLAG_MID_MSK 0x0fff0000 +/* inverted bitmask for bitfield lso_tcp_flag_mid[b:0] */ +#define HW_ATL_THM_LSO_TCP_FLAG_MID_MSKN 0xf000ffff +/* lower bit position of bitfield lso_tcp_flag_mid[b:0] */ +#define HW_ATL_THM_LSO_TCP_FLAG_MID_SHIFT 16 +/* width of bitfield lso_tcp_flag_mid[b:0] */ +#define HW_ATL_THM_LSO_TCP_FLAG_MID_WIDTH 12 +/* default value of bitfield lso_tcp_flag_mid[b:0] */ +#define HW_ATL_THM_LSO_TCP_FLAG_MID_DEFAULT 0x0 + +/* tx tx_buf_en bitfield definitions + * preprocessor definitions for the bitfield "tx_buf_en". + * port="pif_tpb_tx_buf_en_i" + */ + +/* register address for bitfield tx_buf_en */ +#define HW_ATL_TPB_TX_BUF_EN_ADR 0x00007900 +/* bitmask for bitfield tx_buf_en */ +#define HW_ATL_TPB_TX_BUF_EN_MSK 0x00000001 +/* inverted bitmask for bitfield tx_buf_en */ +#define HW_ATL_TPB_TX_BUF_EN_MSKN 0xfffffffe +/* lower bit position of bitfield tx_buf_en */ +#define HW_ATL_TPB_TX_BUF_EN_SHIFT 0 +/* width of bitfield tx_buf_en */ +#define HW_ATL_TPB_TX_BUF_EN_WIDTH 1 +/* default value of bitfield tx_buf_en */ +#define HW_ATL_TPB_TX_BUF_EN_DEFAULT 0x0 + +/* tx tx{b}_hi_thresh[c:0] bitfield definitions + * preprocessor definitions for the bitfield "tx{b}_hi_thresh[c:0]". + * parameter: buffer {b} | stride size 0x10 | range [0, 7] + * port="pif_tpb_tx0_hi_thresh_i[12:0]" + */ + +/* register address for bitfield tx{b}_hi_thresh[c:0] */ +#define HW_ATL_TPB_TXBHI_THRESH_ADR(buffer) (0x00007914 + (buffer) * 0x10) +/* bitmask for bitfield tx{b}_hi_thresh[c:0] */ +#define HW_ATL_TPB_TXBHI_THRESH_MSK 0x1fff0000 +/* inverted bitmask for bitfield tx{b}_hi_thresh[c:0] */ +#define HW_ATL_TPB_TXBHI_THRESH_MSKN 0xe000ffff +/* lower bit position of bitfield tx{b}_hi_thresh[c:0] */ +#define HW_ATL_TPB_TXBHI_THRESH_SHIFT 16 +/* width of bitfield tx{b}_hi_thresh[c:0] */ +#define HW_ATL_TPB_TXBHI_THRESH_WIDTH 13 +/* default value of bitfield tx{b}_hi_thresh[c:0] */ +#define HW_ATL_TPB_TXBHI_THRESH_DEFAULT 0x0 + +/* tx tx{b}_lo_thresh[c:0] bitfield definitions + * preprocessor definitions for the bitfield "tx{b}_lo_thresh[c:0]". + * parameter: buffer {b} | stride size 0x10 | range [0, 7] + * port="pif_tpb_tx0_lo_thresh_i[12:0]" + */ + +/* register address for bitfield tx{b}_lo_thresh[c:0] */ +#define HW_ATL_TPB_TXBLO_THRESH_ADR(buffer) (0x00007914 + (buffer) * 0x10) +/* bitmask for bitfield tx{b}_lo_thresh[c:0] */ +#define HW_ATL_TPB_TXBLO_THRESH_MSK 0x00001fff +/* inverted bitmask for bitfield tx{b}_lo_thresh[c:0] */ +#define HW_ATL_TPB_TXBLO_THRESH_MSKN 0xffffe000 +/* lower bit position of bitfield tx{b}_lo_thresh[c:0] */ +#define HW_ATL_TPB_TXBLO_THRESH_SHIFT 0 +/* width of bitfield tx{b}_lo_thresh[c:0] */ +#define HW_ATL_TPB_TXBLO_THRESH_WIDTH 13 +/* default value of bitfield tx{b}_lo_thresh[c:0] */ +#define HW_ATL_TPB_TXBLO_THRESH_DEFAULT 0x0 + +/* tx dma_sys_loopback bitfield definitions + * preprocessor definitions for the bitfield "dma_sys_loopback". + * port="pif_tpb_dma_sys_lbk_i" + */ + +/* register address for bitfield dma_sys_loopback */ +#define HW_ATL_TPB_DMA_SYS_LBK_ADR 0x00007000 +/* bitmask for bitfield dma_sys_loopback */ +#define HW_ATL_TPB_DMA_SYS_LBK_MSK 0x00000040 +/* inverted bitmask for bitfield dma_sys_loopback */ +#define HW_ATL_TPB_DMA_SYS_LBK_MSKN 0xffffffbf +/* lower bit position of bitfield dma_sys_loopback */ +#define HW_ATL_TPB_DMA_SYS_LBK_SHIFT 6 +/* width of bitfield dma_sys_loopback */ +#define HW_ATL_TPB_DMA_SYS_LBK_WIDTH 1 +/* default value of bitfield dma_sys_loopback */ +#define HW_ATL_TPB_DMA_SYS_LBK_DEFAULT 0x0 + +/* tx tx{b}_buf_size[7:0] bitfield definitions + * preprocessor definitions for the bitfield "tx{b}_buf_size[7:0]". + * parameter: buffer {b} | stride size 0x10 | range [0, 7] + * port="pif_tpb_tx0_buf_size_i[7:0]" + */ + +/* register address for bitfield tx{b}_buf_size[7:0] */ +#define HW_ATL_TPB_TXBBUF_SIZE_ADR(buffer) (0x00007910 + (buffer) * 0x10) +/* bitmask for bitfield tx{b}_buf_size[7:0] */ +#define HW_ATL_TPB_TXBBUF_SIZE_MSK 0x000000ff +/* inverted bitmask for bitfield tx{b}_buf_size[7:0] */ +#define HW_ATL_TPB_TXBBUF_SIZE_MSKN 0xffffff00 +/* lower bit position of bitfield tx{b}_buf_size[7:0] */ +#define HW_ATL_TPB_TXBBUF_SIZE_SHIFT 0 +/* width of bitfield tx{b}_buf_size[7:0] */ +#define HW_ATL_TPB_TXBBUF_SIZE_WIDTH 8 +/* default value of bitfield tx{b}_buf_size[7:0] */ +#define HW_ATL_TPB_TXBBUF_SIZE_DEFAULT 0x0 + +/* tx tx_scp_ins_en bitfield definitions + * preprocessor definitions for the bitfield "tx_scp_ins_en". + * port="pif_tpb_scp_ins_en_i" + */ + +/* register address for bitfield tx_scp_ins_en */ +#define HW_ATL_TPB_TX_SCP_INS_EN_ADR 0x00007900 +/* bitmask for bitfield tx_scp_ins_en */ +#define HW_ATL_TPB_TX_SCP_INS_EN_MSK 0x00000004 +/* inverted bitmask for bitfield tx_scp_ins_en */ +#define HW_ATL_TPB_TX_SCP_INS_EN_MSKN 0xfffffffb +/* lower bit position of bitfield tx_scp_ins_en */ +#define HW_ATL_TPB_TX_SCP_INS_EN_SHIFT 2 +/* width of bitfield tx_scp_ins_en */ +#define HW_ATL_TPB_TX_SCP_INS_EN_WIDTH 1 +/* default value of bitfield tx_scp_ins_en */ +#define HW_ATL_TPB_TX_SCP_INS_EN_DEFAULT 0x0 + +/* tx ipv4_chk_en bitfield definitions + * preprocessor definitions for the bitfield "ipv4_chk_en". + * port="pif_tpo_ipv4_chk_en_i" + */ + +/* register address for bitfield ipv4_chk_en */ +#define HW_ATL_TPO_IPV4CHK_EN_ADR 0x00007800 +/* bitmask for bitfield ipv4_chk_en */ +#define HW_ATL_TPO_IPV4CHK_EN_MSK 0x00000002 +/* inverted bitmask for bitfield ipv4_chk_en */ +#define HW_ATL_TPO_IPV4CHK_EN_MSKN 0xfffffffd +/* lower bit position of bitfield ipv4_chk_en */ +#define HW_ATL_TPO_IPV4CHK_EN_SHIFT 1 +/* width of bitfield ipv4_chk_en */ +#define HW_ATL_TPO_IPV4CHK_EN_WIDTH 1 +/* default value of bitfield ipv4_chk_en */ +#define HW_ATL_TPO_IPV4CHK_EN_DEFAULT 0x0 + +/* tx l4_chk_en bitfield definitions + * preprocessor definitions for the bitfield "l4_chk_en". + * port="pif_tpo_l4_chk_en_i" + */ + +/* register address for bitfield l4_chk_en */ +#define HW_ATL_TPOL4CHK_EN_ADR 0x00007800 +/* bitmask for bitfield l4_chk_en */ +#define HW_ATL_TPOL4CHK_EN_MSK 0x00000001 +/* inverted bitmask for bitfield l4_chk_en */ +#define HW_ATL_TPOL4CHK_EN_MSKN 0xfffffffe +/* lower bit position of bitfield l4_chk_en */ +#define HW_ATL_TPOL4CHK_EN_SHIFT 0 +/* width of bitfield l4_chk_en */ +#define HW_ATL_TPOL4CHK_EN_WIDTH 1 +/* default value of bitfield l4_chk_en */ +#define HW_ATL_TPOL4CHK_EN_DEFAULT 0x0 + +/* tx pkt_sys_loopback bitfield definitions + * preprocessor definitions for the bitfield "pkt_sys_loopback". + * port="pif_tpo_pkt_sys_lbk_i" + */ + +/* register address for bitfield pkt_sys_loopback */ +#define HW_ATL_TPO_PKT_SYS_LBK_ADR 0x00007000 +/* bitmask for bitfield pkt_sys_loopback */ +#define HW_ATL_TPO_PKT_SYS_LBK_MSK 0x00000080 +/* inverted bitmask for bitfield pkt_sys_loopback */ +#define HW_ATL_TPO_PKT_SYS_LBK_MSKN 0xffffff7f +/* lower bit position of bitfield pkt_sys_loopback */ +#define HW_ATL_TPO_PKT_SYS_LBK_SHIFT 7 +/* width of bitfield pkt_sys_loopback */ +#define HW_ATL_TPO_PKT_SYS_LBK_WIDTH 1 +/* default value of bitfield pkt_sys_loopback */ +#define HW_ATL_TPO_PKT_SYS_LBK_DEFAULT 0x0 + +/* tx data_tc_arb_mode bitfield definitions + * preprocessor definitions for the bitfield "data_tc_arb_mode". + * port="pif_tps_data_tc_arb_mode_i" + */ + +/* register address for bitfield data_tc_arb_mode */ +#define HW_ATL_TPS_DATA_TC_ARB_MODE_ADR 0x00007100 +/* bitmask for bitfield data_tc_arb_mode */ +#define HW_ATL_TPS_DATA_TC_ARB_MODE_MSK 0x00000001 +/* inverted bitmask for bitfield data_tc_arb_mode */ +#define HW_ATL_TPS_DATA_TC_ARB_MODE_MSKN 0xfffffffe +/* lower bit position of bitfield data_tc_arb_mode */ +#define HW_ATL_TPS_DATA_TC_ARB_MODE_SHIFT 0 +/* width of bitfield data_tc_arb_mode */ +#define HW_ATL_TPS_DATA_TC_ARB_MODE_WIDTH 1 +/* default value of bitfield data_tc_arb_mode */ +#define HW_ATL_TPS_DATA_TC_ARB_MODE_DEFAULT 0x0 + +/* tx desc_rate_ta_rst bitfield definitions + * preprocessor definitions for the bitfield "desc_rate_ta_rst". + * port="pif_tps_desc_rate_ta_rst_i" + */ + +/* register address for bitfield desc_rate_ta_rst */ +#define HW_ATL_TPS_DESC_RATE_TA_RST_ADR 0x00007310 +/* bitmask for bitfield desc_rate_ta_rst */ +#define HW_ATL_TPS_DESC_RATE_TA_RST_MSK 0x80000000 +/* inverted bitmask for bitfield desc_rate_ta_rst */ +#define HW_ATL_TPS_DESC_RATE_TA_RST_MSKN 0x7fffffff +/* lower bit position of bitfield desc_rate_ta_rst */ +#define HW_ATL_TPS_DESC_RATE_TA_RST_SHIFT 31 +/* width of bitfield desc_rate_ta_rst */ +#define HW_ATL_TPS_DESC_RATE_TA_RST_WIDTH 1 +/* default value of bitfield desc_rate_ta_rst */ +#define HW_ATL_TPS_DESC_RATE_TA_RST_DEFAULT 0x0 + +/* tx desc_rate_limit[a:0] bitfield definitions + * preprocessor definitions for the bitfield "desc_rate_limit[a:0]". + * port="pif_tps_desc_rate_lim_i[10:0]" + */ + +/* register address for bitfield desc_rate_limit[a:0] */ +#define HW_ATL_TPS_DESC_RATE_LIM_ADR 0x00007310 +/* bitmask for bitfield desc_rate_limit[a:0] */ +#define HW_ATL_TPS_DESC_RATE_LIM_MSK 0x000007ff +/* inverted bitmask for bitfield desc_rate_limit[a:0] */ +#define HW_ATL_TPS_DESC_RATE_LIM_MSKN 0xfffff800 +/* lower bit position of bitfield desc_rate_limit[a:0] */ +#define HW_ATL_TPS_DESC_RATE_LIM_SHIFT 0 +/* width of bitfield desc_rate_limit[a:0] */ +#define HW_ATL_TPS_DESC_RATE_LIM_WIDTH 11 +/* default value of bitfield desc_rate_limit[a:0] */ +#define HW_ATL_TPS_DESC_RATE_LIM_DEFAULT 0x0 + +/* tx desc_tc_arb_mode[1:0] bitfield definitions + * preprocessor definitions for the bitfield "desc_tc_arb_mode[1:0]". + * port="pif_tps_desc_tc_arb_mode_i[1:0]" + */ + +/* register address for bitfield desc_tc_arb_mode[1:0] */ +#define HW_ATL_TPS_DESC_TC_ARB_MODE_ADR 0x00007200 +/* bitmask for bitfield desc_tc_arb_mode[1:0] */ +#define HW_ATL_TPS_DESC_TC_ARB_MODE_MSK 0x00000003 +/* inverted bitmask for bitfield desc_tc_arb_mode[1:0] */ +#define HW_ATL_TPS_DESC_TC_ARB_MODE_MSKN 0xfffffffc +/* lower bit position of bitfield desc_tc_arb_mode[1:0] */ +#define HW_ATL_TPS_DESC_TC_ARB_MODE_SHIFT 0 +/* width of bitfield desc_tc_arb_mode[1:0] */ +#define HW_ATL_TPS_DESC_TC_ARB_MODE_WIDTH 2 +/* default value of bitfield desc_tc_arb_mode[1:0] */ +#define HW_ATL_TPS_DESC_TC_ARB_MODE_DEFAULT 0x0 + +/* tx desc_tc{t}_credit_max[b:0] bitfield definitions + * preprocessor definitions for the bitfield "desc_tc{t}_credit_max[b:0]". + * parameter: tc {t} | stride size 0x4 | range [0, 7] + * port="pif_tps_desc_tc0_credit_max_i[11:0]" + */ + +/* register address for bitfield desc_tc{t}_credit_max[b:0] */ +#define HW_ATL_TPS_DESC_TCTCREDIT_MAX_ADR(tc) (0x00007210 + (tc) * 0x4) +/* bitmask for bitfield desc_tc{t}_credit_max[b:0] */ +#define HW_ATL_TPS_DESC_TCTCREDIT_MAX_MSK 0x0fff0000 +/* inverted bitmask for bitfield desc_tc{t}_credit_max[b:0] */ +#define HW_ATL_TPS_DESC_TCTCREDIT_MAX_MSKN 0xf000ffff +/* lower bit position of bitfield desc_tc{t}_credit_max[b:0] */ +#define HW_ATL_TPS_DESC_TCTCREDIT_MAX_SHIFT 16 +/* width of bitfield desc_tc{t}_credit_max[b:0] */ +#define HW_ATL_TPS_DESC_TCTCREDIT_MAX_WIDTH 12 +/* default value of bitfield desc_tc{t}_credit_max[b:0] */ +#define HW_ATL_TPS_DESC_TCTCREDIT_MAX_DEFAULT 0x0 + +/* tx desc_tc{t}_weight[8:0] bitfield definitions + * preprocessor definitions for the bitfield "desc_tc{t}_weight[8:0]". + * parameter: tc {t} | stride size 0x4 | range [0, 7] + * port="pif_tps_desc_tc0_weight_i[8:0]" + */ + +/* register address for bitfield desc_tc{t}_weight[8:0] */ +#define HW_ATL_TPS_DESC_TCTWEIGHT_ADR(tc) (0x00007210 + (tc) * 0x4) +/* bitmask for bitfield desc_tc{t}_weight[8:0] */ +#define HW_ATL_TPS_DESC_TCTWEIGHT_MSK 0x000001ff +/* inverted bitmask for bitfield desc_tc{t}_weight[8:0] */ +#define HW_ATL_TPS_DESC_TCTWEIGHT_MSKN 0xfffffe00 +/* lower bit position of bitfield desc_tc{t}_weight[8:0] */ +#define HW_ATL_TPS_DESC_TCTWEIGHT_SHIFT 0 +/* width of bitfield desc_tc{t}_weight[8:0] */ +#define HW_ATL_TPS_DESC_TCTWEIGHT_WIDTH 9 +/* default value of bitfield desc_tc{t}_weight[8:0] */ +#define HW_ATL_TPS_DESC_TCTWEIGHT_DEFAULT 0x0 + +/* tx desc_vm_arb_mode bitfield definitions + * preprocessor definitions for the bitfield "desc_vm_arb_mode". + * port="pif_tps_desc_vm_arb_mode_i" + */ + +/* register address for bitfield desc_vm_arb_mode */ +#define HW_ATL_TPS_DESC_VM_ARB_MODE_ADR 0x00007300 +/* bitmask for bitfield desc_vm_arb_mode */ +#define HW_ATL_TPS_DESC_VM_ARB_MODE_MSK 0x00000001 +/* inverted bitmask for bitfield desc_vm_arb_mode */ +#define HW_ATL_TPS_DESC_VM_ARB_MODE_MSKN 0xfffffffe +/* lower bit position of bitfield desc_vm_arb_mode */ +#define HW_ATL_TPS_DESC_VM_ARB_MODE_SHIFT 0 +/* width of bitfield desc_vm_arb_mode */ +#define HW_ATL_TPS_DESC_VM_ARB_MODE_WIDTH 1 +/* default value of bitfield desc_vm_arb_mode */ +#define HW_ATL_TPS_DESC_VM_ARB_MODE_DEFAULT 0x0 + +/* tx data_tc{t}_credit_max[b:0] bitfield definitions + * preprocessor definitions for the bitfield "data_tc{t}_credit_max[b:0]". + * parameter: tc {t} | stride size 0x4 | range [0, 7] + * port="pif_tps_data_tc0_credit_max_i[11:0]" + */ + +/* register address for bitfield data_tc{t}_credit_max[b:0] */ +#define HW_ATL_TPS_DATA_TCTCREDIT_MAX_ADR(tc) (0x00007110 + (tc) * 0x4) +/* bitmask for bitfield data_tc{t}_credit_max[b:0] */ +#define HW_ATL_TPS_DATA_TCTCREDIT_MAX_MSK 0x0fff0000 +/* inverted bitmask for bitfield data_tc{t}_credit_max[b:0] */ +#define HW_ATL_TPS_DATA_TCTCREDIT_MAX_MSKN 0xf000ffff +/* lower bit position of bitfield data_tc{t}_credit_max[b:0] */ +#define HW_ATL_TPS_DATA_TCTCREDIT_MAX_SHIFT 16 +/* width of bitfield data_tc{t}_credit_max[b:0] */ +#define HW_ATL_TPS_DATA_TCTCREDIT_MAX_WIDTH 12 +/* default value of bitfield data_tc{t}_credit_max[b:0] */ +#define HW_ATL_TPS_DATA_TCTCREDIT_MAX_DEFAULT 0x0 + +/* tx data_tc{t}_weight[8:0] bitfield definitions + * preprocessor definitions for the bitfield "data_tc{t}_weight[8:0]". + * parameter: tc {t} | stride size 0x4 | range [0, 7] + * port="pif_tps_data_tc0_weight_i[8:0]" + */ + +/* register address for bitfield data_tc{t}_weight[8:0] */ +#define HW_ATL_TPS_DATA_TCTWEIGHT_ADR(tc) (0x00007110 + (tc) * 0x4) +/* bitmask for bitfield data_tc{t}_weight[8:0] */ +#define HW_ATL_TPS_DATA_TCTWEIGHT_MSK 0x000001ff +/* inverted bitmask for bitfield data_tc{t}_weight[8:0] */ +#define HW_ATL_TPS_DATA_TCTWEIGHT_MSKN 0xfffffe00 +/* lower bit position of bitfield data_tc{t}_weight[8:0] */ +#define HW_ATL_TPS_DATA_TCTWEIGHT_SHIFT 0 +/* width of bitfield data_tc{t}_weight[8:0] */ +#define HW_ATL_TPS_DATA_TCTWEIGHT_WIDTH 9 +/* default value of bitfield data_tc{t}_weight[8:0] */ +#define HW_ATL_TPS_DATA_TCTWEIGHT_DEFAULT 0x0 + +/* tx reg_res_dsbl bitfield definitions + * preprocessor definitions for the bitfield "reg_res_dsbl". + * port="pif_tx_reg_res_dsbl_i" + */ + +/* register address for bitfield reg_res_dsbl */ +#define HW_ATL_TX_REG_RES_DSBL_ADR 0x00007000 +/* bitmask for bitfield reg_res_dsbl */ +#define HW_ATL_TX_REG_RES_DSBL_MSK 0x20000000 +/* inverted bitmask for bitfield reg_res_dsbl */ +#define HW_ATL_TX_REG_RES_DSBL_MSKN 0xdfffffff +/* lower bit position of bitfield reg_res_dsbl */ +#define HW_ATL_TX_REG_RES_DSBL_SHIFT 29 +/* width of bitfield reg_res_dsbl */ +#define HW_ATL_TX_REG_RES_DSBL_WIDTH 1 +/* default value of bitfield reg_res_dsbl */ +#define HW_ATL_TX_REG_RES_DSBL_DEFAULT 0x1 + +/* mac_phy register access busy bitfield definitions + * preprocessor definitions for the bitfield "register access busy". + * port="msm_pif_reg_busy_o" + */ + +/* register address for bitfield register access busy */ +#define HW_ATL_MSM_REG_ACCESS_BUSY_ADR 0x00004400 +/* bitmask for bitfield register access busy */ +#define HW_ATL_MSM_REG_ACCESS_BUSY_MSK 0x00001000 +/* inverted bitmask for bitfield register access busy */ +#define HW_ATL_MSM_REG_ACCESS_BUSY_MSKN 0xffffefff +/* lower bit position of bitfield register access busy */ +#define HW_ATL_MSM_REG_ACCESS_BUSY_SHIFT 12 +/* width of bitfield register access busy */ +#define HW_ATL_MSM_REG_ACCESS_BUSY_WIDTH 1 + +/* mac_phy msm register address[7:0] bitfield definitions + * preprocessor definitions for the bitfield "msm register address[7:0]". + * port="pif_msm_reg_addr_i[7:0]" + */ + +/* register address for bitfield msm register address[7:0] */ +#define HW_ATL_MSM_REG_ADDR_ADR 0x00004400 +/* bitmask for bitfield msm register address[7:0] */ +#define HW_ATL_MSM_REG_ADDR_MSK 0x000000ff +/* inverted bitmask for bitfield msm register address[7:0] */ +#define HW_ATL_MSM_REG_ADDR_MSKN 0xffffff00 +/* lower bit position of bitfield msm register address[7:0] */ +#define HW_ATL_MSM_REG_ADDR_SHIFT 0 +/* width of bitfield msm register address[7:0] */ +#define HW_ATL_MSM_REG_ADDR_WIDTH 8 +/* default value of bitfield msm register address[7:0] */ +#define HW_ATL_MSM_REG_ADDR_DEFAULT 0x0 + +/* mac_phy register read strobe bitfield definitions + * preprocessor definitions for the bitfield "register read strobe". + * port="pif_msm_reg_rden_i" + */ + +/* register address for bitfield register read strobe */ +#define HW_ATL_MSM_REG_RD_STROBE_ADR 0x00004400 +/* bitmask for bitfield register read strobe */ +#define HW_ATL_MSM_REG_RD_STROBE_MSK 0x00000200 +/* inverted bitmask for bitfield register read strobe */ +#define HW_ATL_MSM_REG_RD_STROBE_MSKN 0xfffffdff +/* lower bit position of bitfield register read strobe */ +#define HW_ATL_MSM_REG_RD_STROBE_SHIFT 9 +/* width of bitfield register read strobe */ +#define HW_ATL_MSM_REG_RD_STROBE_WIDTH 1 +/* default value of bitfield register read strobe */ +#define HW_ATL_MSM_REG_RD_STROBE_DEFAULT 0x0 + +/* mac_phy msm register read data[31:0] bitfield definitions + * preprocessor definitions for the bitfield "msm register read data[31:0]". + * port="msm_pif_reg_rd_data_o[31:0]" + */ + +/* register address for bitfield msm register read data[31:0] */ +#define HW_ATL_MSM_REG_RD_DATA_ADR 0x00004408 +/* bitmask for bitfield msm register read data[31:0] */ +#define HW_ATL_MSM_REG_RD_DATA_MSK 0xffffffff +/* inverted bitmask for bitfield msm register read data[31:0] */ +#define HW_ATL_MSM_REG_RD_DATA_MSKN 0x00000000 +/* lower bit position of bitfield msm register read data[31:0] */ +#define HW_ATL_MSM_REG_RD_DATA_SHIFT 0 +/* width of bitfield msm register read data[31:0] */ +#define HW_ATL_MSM_REG_RD_DATA_WIDTH 32 + +/* mac_phy msm register write data[31:0] bitfield definitions + * preprocessor definitions for the bitfield "msm register write data[31:0]". + * port="pif_msm_reg_wr_data_i[31:0]" + */ + +/* register address for bitfield msm register write data[31:0] */ +#define HW_ATL_MSM_REG_WR_DATA_ADR 0x00004404 +/* bitmask for bitfield msm register write data[31:0] */ +#define HW_ATL_MSM_REG_WR_DATA_MSK 0xffffffff +/* inverted bitmask for bitfield msm register write data[31:0] */ +#define HW_ATL_MSM_REG_WR_DATA_MSKN 0x00000000 +/* lower bit position of bitfield msm register write data[31:0] */ +#define HW_ATL_MSM_REG_WR_DATA_SHIFT 0 +/* width of bitfield msm register write data[31:0] */ +#define HW_ATL_MSM_REG_WR_DATA_WIDTH 32 +/* default value of bitfield msm register write data[31:0] */ +#define HW_ATL_MSM_REG_WR_DATA_DEFAULT 0x0 + +/* mac_phy register write strobe bitfield definitions + * preprocessor definitions for the bitfield "register write strobe". + * port="pif_msm_reg_wren_i" + */ + +/* register address for bitfield register write strobe */ +#define HW_ATL_MSM_REG_WR_STROBE_ADR 0x00004400 +/* bitmask for bitfield register write strobe */ +#define HW_ATL_MSM_REG_WR_STROBE_MSK 0x00000100 +/* inverted bitmask for bitfield register write strobe */ +#define HW_ATL_MSM_REG_WR_STROBE_MSKN 0xfffffeff +/* lower bit position of bitfield register write strobe */ +#define HW_ATL_MSM_REG_WR_STROBE_SHIFT 8 +/* width of bitfield register write strobe */ +#define HW_ATL_MSM_REG_WR_STROBE_WIDTH 1 +/* default value of bitfield register write strobe */ +#define HW_ATL_MSM_REG_WR_STROBE_DEFAULT 0x0 + +/* mif soft reset bitfield definitions + * preprocessor definitions for the bitfield "soft reset". + * port="pif_glb_res_i" + */ + +/* register address for bitfield soft reset */ +#define HW_ATL_GLB_SOFT_RES_ADR 0x00000000 +/* bitmask for bitfield soft reset */ +#define HW_ATL_GLB_SOFT_RES_MSK 0x00008000 +/* inverted bitmask for bitfield soft reset */ +#define HW_ATL_GLB_SOFT_RES_MSKN 0xffff7fff +/* lower bit position of bitfield soft reset */ +#define HW_ATL_GLB_SOFT_RES_SHIFT 15 +/* width of bitfield soft reset */ +#define HW_ATL_GLB_SOFT_RES_WIDTH 1 +/* default value of bitfield soft reset */ +#define HW_ATL_GLB_SOFT_RES_DEFAULT 0x0 + +/* mif register reset disable bitfield definitions + * preprocessor definitions for the bitfield "register reset disable". + * port="pif_glb_reg_res_dsbl_i" + */ + +/* register address for bitfield register reset disable */ +#define HW_ATL_GLB_REG_RES_DIS_ADR 0x00000000 +/* bitmask for bitfield register reset disable */ +#define HW_ATL_GLB_REG_RES_DIS_MSK 0x00004000 +/* inverted bitmask for bitfield register reset disable */ +#define HW_ATL_GLB_REG_RES_DIS_MSKN 0xffffbfff +/* lower bit position of bitfield register reset disable */ +#define HW_ATL_GLB_REG_RES_DIS_SHIFT 14 +/* width of bitfield register reset disable */ +#define HW_ATL_GLB_REG_RES_DIS_WIDTH 1 +/* default value of bitfield register reset disable */ +#define HW_ATL_GLB_REG_RES_DIS_DEFAULT 0x1 + +/* tx dma debug control definitions */ +#define HW_ATL_TX_DMA_DEBUG_CTL_ADR 0x00008920u + +/* tx dma descriptor base address msw definitions */ +#define HW_ATL_TX_DMA_DESC_BASE_ADDRMSW_ADR(descriptor) \ + (0x00007c04u + (descriptor) * 0x40) + +/* tx dma total request limit */ +#define HW_ATL_TX_DMA_TOTAL_REQ_LIMIT_ADR 0x00007b20u + +/* tx interrupt moderation control register definitions + * Preprocessor definitions for TX Interrupt Moderation Control Register + * Base Address: 0x00008980 + * Parameter: queue {Q} | stride size 0x4 | range [0, 31] + */ + +#define HW_ATL_TX_INTR_MODERATION_CTL_ADR(queue) (0x00008980u + (queue) * 0x4) + +/* pcie reg_res_dsbl bitfield definitions + * preprocessor definitions for the bitfield "reg_res_dsbl". + * port="pif_pci_reg_res_dsbl_i" + */ + +/* register address for bitfield reg_res_dsbl */ +#define HW_ATL_PCI_REG_RES_DSBL_ADR 0x00001000 +/* bitmask for bitfield reg_res_dsbl */ +#define HW_ATL_PCI_REG_RES_DSBL_MSK 0x20000000 +/* inverted bitmask for bitfield reg_res_dsbl */ +#define HW_ATL_PCI_REG_RES_DSBL_MSKN 0xdfffffff +/* lower bit position of bitfield reg_res_dsbl */ +#define HW_ATL_PCI_REG_RES_DSBL_SHIFT 29 +/* width of bitfield reg_res_dsbl */ +#define HW_ATL_PCI_REG_RES_DSBL_WIDTH 1 +/* default value of bitfield reg_res_dsbl */ +#define HW_ATL_PCI_REG_RES_DSBL_DEFAULT 0x1 + +/* PCI core control register */ +#define HW_ATL_PCI_REG_CONTROL6_ADR 0x1014u + +/* global microprocessor scratch pad definitions */ +#define HW_ATL_GLB_CPU_SCRATCH_SCP_ADR(scratch_scp) \ + (0x00000300u + (scratch_scp) * 0x4) + +/* register address for bitfield uP Force Interrupt */ +#define HW_ATL_MCP_UP_FORCE_INTERRUPT_ADR 0x00000404 +/* bitmask for bitfield uP Force Interrupt */ +#define HW_ATL_MCP_UP_FORCE_INTERRUPT_MSK 0x00000002 +/* inverted bitmask for bitfield uP Force Interrupt */ +#define HW_ATL_MCP_UP_FORCE_INTERRUPT_MSKN 0xFFFFFFFD +/* lower bit position of bitfield uP Force Interrupt */ +#define HW_ATL_MCP_UP_FORCE_INTERRUPT_SHIFT 1 +/* width of bitfield uP Force Interrupt */ +#define HW_ATL_MCP_UP_FORCE_INTERRUPT_WIDTH 1 +/* default value of bitfield uP Force Interrupt */ +#define HW_ATL_MCP_UP_FORCE_INTERRUPT_DEFAULT 0x0 + +#endif /* HW_ATL_LLH_INTERNAL_H */ diff --git a/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_utils.c b/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_utils.c new file mode 100644 index 000000000..49c80bac9 --- /dev/null +++ b/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_utils.c @@ -0,0 +1,864 @@ +/* + * aQuantia Corporation Network Driver + * Copyright (C) 2014-2017 aQuantia Corporation. All rights reserved + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + */ + +/* File hw_atl_utils.c: Definition of common functions for Atlantic hardware + * abstraction layer. + */ + +#include "../aq_nic.h" +#include "../aq_hw_utils.h" +#include "hw_atl_utils.h" +#include "hw_atl_llh.h" +#include "hw_atl_llh_internal.h" + +#include <linux/random.h> + +#define HW_ATL_UCP_0X370_REG 0x0370U + +#define HW_ATL_MIF_CMD 0x0200U +#define HW_ATL_MIF_ADDR 0x0208U +#define HW_ATL_MIF_VAL 0x020CU + +#define HW_ATL_FW_SM_RAM 0x2U +#define HW_ATL_MPI_FW_VERSION 0x18 +#define HW_ATL_MPI_CONTROL_ADR 0x0368U +#define HW_ATL_MPI_STATE_ADR 0x036CU + +#define HW_ATL_MPI_STATE_MSK 0x00FFU +#define HW_ATL_MPI_STATE_SHIFT 0U +#define HW_ATL_MPI_SPEED_MSK 0x00FF0000U +#define HW_ATL_MPI_SPEED_SHIFT 16U +#define HW_ATL_MPI_DIRTY_WAKE_MSK 0x02000000U + +#define HW_ATL_MPI_DAISY_CHAIN_STATUS 0x704 +#define HW_ATL_MPI_BOOT_EXIT_CODE 0x388 + +#define HW_ATL_MAC_PHY_CONTROL 0x4000 +#define HW_ATL_MAC_PHY_MPI_RESET_BIT 0x1D + +#define HW_ATL_FW_VER_1X 0x01050006U +#define HW_ATL_FW_VER_2X 0x02000000U +#define HW_ATL_FW_VER_3X 0x03000000U + +#define FORCE_FLASHLESS 0 + +static int hw_atl_utils_ver_match(u32 ver_expected, u32 ver_actual); +static int hw_atl_utils_mpi_set_state(struct aq_hw_s *self, + enum hal_atl_utils_fw_state_e state); + +int hw_atl_utils_initfw(struct aq_hw_s *self, const struct aq_fw_ops **fw_ops) +{ + int err = 0; + + err = hw_atl_utils_soft_reset(self); + if (err) + return err; + + hw_atl_utils_hw_chip_features_init(self, + &self->chip_features); + + hw_atl_utils_get_fw_version(self, &self->fw_ver_actual); + + if (hw_atl_utils_ver_match(HW_ATL_FW_VER_1X, + self->fw_ver_actual) == 0) { + *fw_ops = &aq_fw_1x_ops; + } else if (hw_atl_utils_ver_match(HW_ATL_FW_VER_2X, + self->fw_ver_actual) == 0) { + *fw_ops = &aq_fw_2x_ops; + } else if (hw_atl_utils_ver_match(HW_ATL_FW_VER_3X, + self->fw_ver_actual) == 0) { + *fw_ops = &aq_fw_2x_ops; + } else { + aq_pr_err("Bad FW version detected: %x\n", + self->fw_ver_actual); + return -EOPNOTSUPP; + } + self->aq_fw_ops = *fw_ops; + err = self->aq_fw_ops->init(self); + return err; +} + +static int hw_atl_utils_soft_reset_flb(struct aq_hw_s *self) +{ + u32 gsr, val; + int k = 0; + + aq_hw_write_reg(self, 0x404, 0x40e1); + AQ_HW_SLEEP(50); + + /* Cleanup SPI */ + val = aq_hw_read_reg(self, 0x53C); + aq_hw_write_reg(self, 0x53C, val | 0x10); + + gsr = aq_hw_read_reg(self, HW_ATL_GLB_SOFT_RES_ADR); + aq_hw_write_reg(self, HW_ATL_GLB_SOFT_RES_ADR, (gsr & 0xBFFF) | 0x8000); + + /* Kickstart MAC */ + aq_hw_write_reg(self, 0x404, 0x80e0); + aq_hw_write_reg(self, 0x32a8, 0x0); + aq_hw_write_reg(self, 0x520, 0x1); + + /* Reset SPI again because of possible interrupted SPI burst */ + val = aq_hw_read_reg(self, 0x53C); + aq_hw_write_reg(self, 0x53C, val | 0x10); + AQ_HW_SLEEP(10); + /* Clear SPI reset state */ + aq_hw_write_reg(self, 0x53C, val & ~0x10); + + aq_hw_write_reg(self, 0x404, 0x180e0); + + for (k = 0; k < 1000; k++) { + u32 flb_status = aq_hw_read_reg(self, + HW_ATL_MPI_DAISY_CHAIN_STATUS); + + flb_status = flb_status & 0x10; + if (flb_status) + break; + AQ_HW_SLEEP(10); + } + if (k == 1000) { + aq_pr_err("MAC kickstart failed\n"); + return -EIO; + } + + /* FW reset */ + aq_hw_write_reg(self, 0x404, 0x80e0); + AQ_HW_SLEEP(50); + aq_hw_write_reg(self, 0x3a0, 0x1); + + /* Kickstart PHY - skipped */ + + /* Global software reset*/ + hw_atl_rx_rx_reg_res_dis_set(self, 0U); + hw_atl_tx_tx_reg_res_dis_set(self, 0U); + aq_hw_write_reg_bit(self, HW_ATL_MAC_PHY_CONTROL, + BIT(HW_ATL_MAC_PHY_MPI_RESET_BIT), + HW_ATL_MAC_PHY_MPI_RESET_BIT, 0x0); + gsr = aq_hw_read_reg(self, HW_ATL_GLB_SOFT_RES_ADR); + aq_hw_write_reg(self, HW_ATL_GLB_SOFT_RES_ADR, (gsr & 0xBFFF) | 0x8000); + + for (k = 0; k < 1000; k++) { + u32 fw_state = aq_hw_read_reg(self, HW_ATL_MPI_FW_VERSION); + + if (fw_state) + break; + AQ_HW_SLEEP(10); + } + if (k == 1000) { + aq_pr_err("FW kickstart failed\n"); + return -EIO; + } + /* Old FW requires fixed delay after init */ + AQ_HW_SLEEP(15); + + return 0; +} + +static int hw_atl_utils_soft_reset_rbl(struct aq_hw_s *self) +{ + u32 gsr, val, rbl_status; + int k; + + aq_hw_write_reg(self, 0x404, 0x40e1); + aq_hw_write_reg(self, 0x3a0, 0x1); + aq_hw_write_reg(self, 0x32a8, 0x0); + + /* Alter RBL status */ + aq_hw_write_reg(self, 0x388, 0xDEAD); + + /* Cleanup SPI */ + val = aq_hw_read_reg(self, 0x53C); + aq_hw_write_reg(self, 0x53C, val | 0x10); + + /* Global software reset*/ + hw_atl_rx_rx_reg_res_dis_set(self, 0U); + hw_atl_tx_tx_reg_res_dis_set(self, 0U); + aq_hw_write_reg_bit(self, HW_ATL_MAC_PHY_CONTROL, + BIT(HW_ATL_MAC_PHY_MPI_RESET_BIT), + HW_ATL_MAC_PHY_MPI_RESET_BIT, 0x0); + gsr = aq_hw_read_reg(self, HW_ATL_GLB_SOFT_RES_ADR); + aq_hw_write_reg(self, HW_ATL_GLB_SOFT_RES_ADR, + (gsr & 0xFFFFBFFF) | 0x8000); + + if (FORCE_FLASHLESS) + aq_hw_write_reg(self, 0x534, 0x0); + + aq_hw_write_reg(self, 0x404, 0x40e0); + + /* Wait for RBL boot */ + for (k = 0; k < 1000; k++) { + rbl_status = aq_hw_read_reg(self, 0x388) & 0xFFFF; + if (rbl_status && rbl_status != 0xDEAD) + break; + AQ_HW_SLEEP(10); + } + if (!rbl_status || rbl_status == 0xDEAD) { + aq_pr_err("RBL Restart failed"); + return -EIO; + } + + /* Restore NVR */ + if (FORCE_FLASHLESS) + aq_hw_write_reg(self, 0x534, 0xA0); + + if (rbl_status == 0xF1A7) { + aq_pr_err("No FW detected. Dynamic FW load not implemented\n"); + return -ENOTSUPP; + } + + for (k = 0; k < 1000; k++) { + u32 fw_state = aq_hw_read_reg(self, HW_ATL_MPI_FW_VERSION); + + if (fw_state) + break; + AQ_HW_SLEEP(10); + } + if (k == 1000) { + aq_pr_err("FW kickstart failed\n"); + return -EIO; + } + /* Old FW requires fixed delay after init */ + AQ_HW_SLEEP(15); + + return 0; +} + +int hw_atl_utils_soft_reset(struct aq_hw_s *self) +{ + int k; + u32 boot_exit_code = 0; + + for (k = 0; k < 1000; ++k) { + u32 flb_status = aq_hw_read_reg(self, + HW_ATL_MPI_DAISY_CHAIN_STATUS); + boot_exit_code = aq_hw_read_reg(self, + HW_ATL_MPI_BOOT_EXIT_CODE); + if (flb_status != 0x06000000 || boot_exit_code != 0) + break; + } + + if (k == 1000) { + aq_pr_err("Neither RBL nor FLB firmware started\n"); + return -EOPNOTSUPP; + } + + self->rbl_enabled = (boot_exit_code != 0); + + /* FW 1.x may bootup in an invalid POWER state (WOL feature). + * We should work around this by forcing its state back to DEINIT + */ + if (!hw_atl_utils_ver_match(HW_ATL_FW_VER_1X, + aq_hw_read_reg(self, + HW_ATL_MPI_FW_VERSION))) { + int err = 0; + + hw_atl_utils_mpi_set_state(self, MPI_DEINIT); + AQ_HW_WAIT_FOR((aq_hw_read_reg(self, HW_ATL_MPI_STATE_ADR) & + HW_ATL_MPI_STATE_MSK) == MPI_DEINIT, + 10, 1000U); + if (err) + return err; + } + + if (self->rbl_enabled) + return hw_atl_utils_soft_reset_rbl(self); + else + return hw_atl_utils_soft_reset_flb(self); +} + +int hw_atl_utils_fw_downld_dwords(struct aq_hw_s *self, u32 a, + u32 *p, u32 cnt) +{ + int err = 0; + + AQ_HW_WAIT_FOR(hw_atl_reg_glb_cpu_sem_get(self, + HW_ATL_FW_SM_RAM) == 1U, + 1U, 10000U); + + if (err < 0) { + bool is_locked; + + hw_atl_reg_glb_cpu_sem_set(self, 1U, HW_ATL_FW_SM_RAM); + is_locked = hw_atl_reg_glb_cpu_sem_get(self, HW_ATL_FW_SM_RAM); + if (!is_locked) { + err = -ETIME; + goto err_exit; + } + } + + aq_hw_write_reg(self, HW_ATL_MIF_ADDR, a); + + for (++cnt; --cnt && !err;) { + aq_hw_write_reg(self, HW_ATL_MIF_CMD, 0x00008000U); + + if (IS_CHIP_FEATURE(REVISION_B1)) + AQ_HW_WAIT_FOR(a != aq_hw_read_reg(self, + HW_ATL_MIF_ADDR), + 1, 1000U); + else + AQ_HW_WAIT_FOR(!(0x100 & aq_hw_read_reg(self, + HW_ATL_MIF_CMD)), + 1, 1000U); + + *(p++) = aq_hw_read_reg(self, HW_ATL_MIF_VAL); + a += 4; + } + + hw_atl_reg_glb_cpu_sem_set(self, 1U, HW_ATL_FW_SM_RAM); + +err_exit: + return err; +} + +static int hw_atl_utils_fw_upload_dwords(struct aq_hw_s *self, u32 a, u32 *p, + u32 cnt) +{ + int err = 0; + bool is_locked; + + is_locked = hw_atl_reg_glb_cpu_sem_get(self, HW_ATL_FW_SM_RAM); + if (!is_locked) { + err = -ETIME; + goto err_exit; + } + if (IS_CHIP_FEATURE(REVISION_B1)) { + u32 offset = 0; + + for (; offset < cnt; ++offset) { + aq_hw_write_reg(self, 0x328, p[offset]); + aq_hw_write_reg(self, 0x32C, + (0x80000000 | (0xFFFF & (offset * 4)))); + hw_atl_mcp_up_force_intr_set(self, 1); + /* 1000 times by 10us = 10ms */ + AQ_HW_WAIT_FOR((aq_hw_read_reg(self, + 0x32C) & 0xF0000000) != + 0x80000000, + 10, 1000); + } + } else { + u32 offset = 0; + + aq_hw_write_reg(self, 0x208, a); + + for (; offset < cnt; ++offset) { + aq_hw_write_reg(self, 0x20C, p[offset]); + aq_hw_write_reg(self, 0x200, 0xC000); + + AQ_HW_WAIT_FOR((aq_hw_read_reg(self, 0x200U) & + 0x100) == 0, 10, 1000); + } + } + + hw_atl_reg_glb_cpu_sem_set(self, 1U, HW_ATL_FW_SM_RAM); + +err_exit: + return err; +} + +static int hw_atl_utils_ver_match(u32 ver_expected, u32 ver_actual) +{ + int err = 0; + const u32 dw_major_mask = 0xff000000U; + const u32 dw_minor_mask = 0x00ffffffU; + + err = (dw_major_mask & (ver_expected ^ ver_actual)) ? -EOPNOTSUPP : 0; + if (err < 0) + goto err_exit; + err = ((dw_minor_mask & ver_expected) > (dw_minor_mask & ver_actual)) ? + -EOPNOTSUPP : 0; +err_exit: + return err; +} + +static int hw_atl_utils_init_ucp(struct aq_hw_s *self, + const struct aq_hw_caps_s *aq_hw_caps) +{ + int err = 0; + + if (!aq_hw_read_reg(self, 0x370U)) { + unsigned int rnd = 0U; + unsigned int ucp_0x370 = 0U; + + get_random_bytes(&rnd, sizeof(unsigned int)); + + ucp_0x370 = 0x02020202U | (0xFEFEFEFEU & rnd); + aq_hw_write_reg(self, HW_ATL_UCP_0X370_REG, ucp_0x370); + } + + hw_atl_reg_glb_cpu_scratch_scp_set(self, 0x00000000U, 25U); + + /* check 10 times by 1ms */ + AQ_HW_WAIT_FOR(0U != (self->mbox_addr = + aq_hw_read_reg(self, 0x360U)), 1000U, 10U); + + return err; +} + +#define HW_ATL_RPC_CONTROL_ADR 0x0338U +#define HW_ATL_RPC_STATE_ADR 0x033CU + +struct aq_hw_atl_utils_fw_rpc_tid_s { + union { + u32 val; + struct { + u16 tid; + u16 len; + }; + }; +}; + +#define hw_atl_utils_fw_rpc_init(_H_) hw_atl_utils_fw_rpc_wait(_H_, NULL) + +int hw_atl_utils_fw_rpc_call(struct aq_hw_s *self, unsigned int rpc_size) +{ + int err = 0; + struct aq_hw_atl_utils_fw_rpc_tid_s sw; + + if (!IS_CHIP_FEATURE(MIPS)) { + err = -1; + goto err_exit; + } + err = hw_atl_utils_fw_upload_dwords(self, self->rpc_addr, + (u32 *)(void *)&self->rpc, + (rpc_size + sizeof(u32) - + sizeof(u8)) / sizeof(u32)); + if (err < 0) + goto err_exit; + + sw.tid = 0xFFFFU & (++self->rpc_tid); + sw.len = (u16)rpc_size; + aq_hw_write_reg(self, HW_ATL_RPC_CONTROL_ADR, sw.val); + +err_exit: + return err; +} + +int hw_atl_utils_fw_rpc_wait(struct aq_hw_s *self, + struct hw_aq_atl_utils_fw_rpc **rpc) +{ + int err = 0; + struct aq_hw_atl_utils_fw_rpc_tid_s sw; + struct aq_hw_atl_utils_fw_rpc_tid_s fw; + + do { + sw.val = aq_hw_read_reg(self, HW_ATL_RPC_CONTROL_ADR); + + self->rpc_tid = sw.tid; + + AQ_HW_WAIT_FOR(sw.tid == + (fw.val = + aq_hw_read_reg(self, HW_ATL_RPC_STATE_ADR), + fw.tid), 1000U, 100U); + if (err < 0) + goto err_exit; + + if (fw.len == 0xFFFFU) { + if (sw.len > sizeof(self->rpc)) { + printk(KERN_INFO "Invalid sw len: %x\n", sw.len); + err = -EINVAL; + goto err_exit; + } + err = hw_atl_utils_fw_rpc_call(self, sw.len); + if (err < 0) + goto err_exit; + } + } while (sw.tid != fw.tid || 0xFFFFU == fw.len); + if (err < 0) + goto err_exit; + + if (rpc) { + if (fw.len) { + if (fw.len > sizeof(self->rpc)) { + printk(KERN_INFO "Invalid fw len: %x\n", fw.len); + err = -EINVAL; + goto err_exit; + } + err = + hw_atl_utils_fw_downld_dwords(self, + self->rpc_addr, + (u32 *)(void *) + &self->rpc, + (fw.len + sizeof(u32) - + sizeof(u8)) / + sizeof(u32)); + if (err < 0) + goto err_exit; + } + + *rpc = &self->rpc; + } + +err_exit: + return err; +} + +static int hw_atl_utils_mpi_create(struct aq_hw_s *self) +{ + int err = 0; + + err = hw_atl_utils_init_ucp(self, self->aq_nic_cfg->aq_hw_caps); + if (err < 0) + goto err_exit; + + err = hw_atl_utils_fw_rpc_init(self); + if (err < 0) + goto err_exit; + +err_exit: + return err; +} + +int hw_atl_utils_mpi_read_mbox(struct aq_hw_s *self, + struct hw_aq_atl_utils_mbox_header *pmbox) +{ + return hw_atl_utils_fw_downld_dwords(self, + self->mbox_addr, + (u32 *)(void *)pmbox, + sizeof(*pmbox) / sizeof(u32)); +} + +void hw_atl_utils_mpi_read_stats(struct aq_hw_s *self, + struct hw_aq_atl_utils_mbox *pmbox) +{ + int err = 0; + + err = hw_atl_utils_fw_downld_dwords(self, + self->mbox_addr, + (u32 *)(void *)pmbox, + sizeof(*pmbox) / sizeof(u32)); + if (err < 0) + goto err_exit; + + if (IS_CHIP_FEATURE(REVISION_A0)) { + unsigned int mtu = self->aq_nic_cfg ? + self->aq_nic_cfg->mtu : 1514U; + pmbox->stats.ubrc = pmbox->stats.uprc * mtu; + pmbox->stats.ubtc = pmbox->stats.uptc * mtu; + pmbox->stats.dpc = atomic_read(&self->dpc); + } else { + pmbox->stats.dpc = hw_atl_reg_rx_dma_stat_counter7get(self); + } + +err_exit:; +} + +static int hw_atl_utils_mpi_set_speed(struct aq_hw_s *self, u32 speed) +{ + u32 val = aq_hw_read_reg(self, HW_ATL_MPI_CONTROL_ADR); + + val = val & ~HW_ATL_MPI_SPEED_MSK; + val |= speed << HW_ATL_MPI_SPEED_SHIFT; + aq_hw_write_reg(self, HW_ATL_MPI_CONTROL_ADR, val); + + return 0; +} + +static int hw_atl_utils_mpi_set_state(struct aq_hw_s *self, + enum hal_atl_utils_fw_state_e state) +{ + int err = 0; + u32 transaction_id = 0; + struct hw_aq_atl_utils_mbox_header mbox; + u32 val = aq_hw_read_reg(self, HW_ATL_MPI_CONTROL_ADR); + + if (state == MPI_RESET) { + hw_atl_utils_mpi_read_mbox(self, &mbox); + + transaction_id = mbox.transaction_id; + + AQ_HW_WAIT_FOR(transaction_id != + (hw_atl_utils_mpi_read_mbox(self, &mbox), + mbox.transaction_id), + 1000U, 100U); + if (err < 0) + goto err_exit; + } + /* On interface DEINIT we disable DW (raise bit) + * Otherwise enable DW (clear bit) + */ + if (state == MPI_DEINIT || state == MPI_POWER) + val |= HW_ATL_MPI_DIRTY_WAKE_MSK; + else + val &= ~HW_ATL_MPI_DIRTY_WAKE_MSK; + + /* Set new state bits */ + val = val & ~HW_ATL_MPI_STATE_MSK; + val |= state & HW_ATL_MPI_STATE_MSK; + + aq_hw_write_reg(self, HW_ATL_MPI_CONTROL_ADR, val); +err_exit: + return err; +} + +int hw_atl_utils_mpi_get_link_status(struct aq_hw_s *self) +{ + u32 cp0x036C = aq_hw_read_reg(self, HW_ATL_MPI_STATE_ADR); + u32 link_speed_mask = cp0x036C >> HW_ATL_MPI_SPEED_SHIFT; + struct aq_hw_link_status_s *link_status = &self->aq_link_status; + + if (!link_speed_mask) { + link_status->mbps = 0U; + } else { + switch (link_speed_mask) { + case HAL_ATLANTIC_RATE_10G: + link_status->mbps = 10000U; + break; + + case HAL_ATLANTIC_RATE_5G: + case HAL_ATLANTIC_RATE_5GSR: + link_status->mbps = 5000U; + break; + + case HAL_ATLANTIC_RATE_2GS: + link_status->mbps = 2500U; + break; + + case HAL_ATLANTIC_RATE_1G: + link_status->mbps = 1000U; + break; + + case HAL_ATLANTIC_RATE_100M: + link_status->mbps = 100U; + break; + + default: + return -EBUSY; + } + } + + return 0; +} + +int hw_atl_utils_get_mac_permanent(struct aq_hw_s *self, + u8 *mac) +{ + int err = 0; + u32 h = 0U; + u32 l = 0U; + u32 mac_addr[2]; + + if (!aq_hw_read_reg(self, HW_ATL_UCP_0X370_REG)) { + unsigned int rnd = 0; + unsigned int ucp_0x370 = 0; + + get_random_bytes(&rnd, sizeof(unsigned int)); + + ucp_0x370 = 0x02020202 | (0xFEFEFEFE & rnd); + aq_hw_write_reg(self, HW_ATL_UCP_0X370_REG, ucp_0x370); + } + + err = hw_atl_utils_fw_downld_dwords(self, + aq_hw_read_reg(self, 0x00000374U) + + (40U * 4U), + mac_addr, + ARRAY_SIZE(mac_addr)); + if (err < 0) { + mac_addr[0] = 0U; + mac_addr[1] = 0U; + err = 0; + } else { + mac_addr[0] = __swab32(mac_addr[0]); + mac_addr[1] = __swab32(mac_addr[1]); + } + + ether_addr_copy(mac, (u8 *)mac_addr); + + if ((mac[0] & 0x01U) || ((mac[0] | mac[1] | mac[2]) == 0x00U)) { + /* chip revision */ + l = 0xE3000000U + | (0xFFFFU & aq_hw_read_reg(self, HW_ATL_UCP_0X370_REG)) + | (0x00 << 16); + h = 0x8001300EU; + + mac[5] = (u8)(0xFFU & l); + l >>= 8; + mac[4] = (u8)(0xFFU & l); + l >>= 8; + mac[3] = (u8)(0xFFU & l); + l >>= 8; + mac[2] = (u8)(0xFFU & l); + mac[1] = (u8)(0xFFU & h); + h >>= 8; + mac[0] = (u8)(0xFFU & h); + } + + return err; +} + +unsigned int hw_atl_utils_mbps_2_speed_index(unsigned int mbps) +{ + unsigned int ret = 0U; + + switch (mbps) { + case 100U: + ret = 5U; + break; + + case 1000U: + ret = 4U; + break; + + case 2500U: + ret = 3U; + break; + + case 5000U: + ret = 1U; + break; + + case 10000U: + ret = 0U; + break; + + default: + break; + } + return ret; +} + +void hw_atl_utils_hw_chip_features_init(struct aq_hw_s *self, u32 *p) +{ + u32 chip_features = 0U; + u32 val = hw_atl_reg_glb_mif_id_get(self); + u32 mif_rev = val & 0xFFU; + + if ((0xFU & mif_rev) == 1U) { + chip_features |= HAL_ATLANTIC_UTILS_CHIP_REVISION_A0 | + HAL_ATLANTIC_UTILS_CHIP_MPI_AQ | + HAL_ATLANTIC_UTILS_CHIP_MIPS; + } else if ((0xFU & mif_rev) == 2U) { + chip_features |= HAL_ATLANTIC_UTILS_CHIP_REVISION_B0 | + HAL_ATLANTIC_UTILS_CHIP_MPI_AQ | + HAL_ATLANTIC_UTILS_CHIP_MIPS | + HAL_ATLANTIC_UTILS_CHIP_TPO2 | + HAL_ATLANTIC_UTILS_CHIP_RPF2; + } else if ((0xFU & mif_rev) == 0xAU) { + chip_features |= HAL_ATLANTIC_UTILS_CHIP_REVISION_B1 | + HAL_ATLANTIC_UTILS_CHIP_MPI_AQ | + HAL_ATLANTIC_UTILS_CHIP_MIPS | + HAL_ATLANTIC_UTILS_CHIP_TPO2 | + HAL_ATLANTIC_UTILS_CHIP_RPF2; + } + + *p = chip_features; +} + +static int hw_atl_fw1x_deinit(struct aq_hw_s *self) +{ + hw_atl_utils_mpi_set_speed(self, 0); + hw_atl_utils_mpi_set_state(self, MPI_DEINIT); + return 0; +} + +int hw_atl_utils_hw_set_power(struct aq_hw_s *self, + unsigned int power_state) +{ + hw_atl_utils_mpi_set_speed(self, 0); + hw_atl_utils_mpi_set_state(self, MPI_POWER); + return 0; +} + +int hw_atl_utils_update_stats(struct aq_hw_s *self) +{ + struct hw_aq_atl_utils_mbox mbox; + + hw_atl_utils_mpi_read_stats(self, &mbox); + +#define AQ_SDELTA(_N_) (self->curr_stats._N_ += \ + mbox.stats._N_ - self->last_stats._N_) + + if (self->aq_link_status.mbps) { + AQ_SDELTA(uprc); + AQ_SDELTA(mprc); + AQ_SDELTA(bprc); + AQ_SDELTA(erpt); + + AQ_SDELTA(uptc); + AQ_SDELTA(mptc); + AQ_SDELTA(bptc); + AQ_SDELTA(erpr); + + AQ_SDELTA(ubrc); + AQ_SDELTA(ubtc); + AQ_SDELTA(mbrc); + AQ_SDELTA(mbtc); + AQ_SDELTA(bbrc); + AQ_SDELTA(bbtc); + AQ_SDELTA(dpc); + } +#undef AQ_SDELTA + self->curr_stats.dma_pkt_rc = hw_atl_stats_rx_dma_good_pkt_counterlsw_get(self); + self->curr_stats.dma_pkt_tc = hw_atl_stats_tx_dma_good_pkt_counterlsw_get(self); + self->curr_stats.dma_oct_rc = hw_atl_stats_rx_dma_good_octet_counterlsw_get(self); + self->curr_stats.dma_oct_tc = hw_atl_stats_tx_dma_good_octet_counterlsw_get(self); + + memcpy(&self->last_stats, &mbox.stats, sizeof(mbox.stats)); + + return 0; +} + +struct aq_stats_s *hw_atl_utils_get_hw_stats(struct aq_hw_s *self) +{ + return &self->curr_stats; +} + +static const u32 hw_atl_utils_hw_mac_regs[] = { + 0x00005580U, 0x00005590U, 0x000055B0U, 0x000055B4U, + 0x000055C0U, 0x00005B00U, 0x00005B04U, 0x00005B08U, + 0x00005B0CU, 0x00005B10U, 0x00005B14U, 0x00005B18U, + 0x00005B1CU, 0x00005B20U, 0x00005B24U, 0x00005B28U, + 0x00005B2CU, 0x00005B30U, 0x00005B34U, 0x00005B38U, + 0x00005B3CU, 0x00005B40U, 0x00005B44U, 0x00005B48U, + 0x00005B4CU, 0x00005B50U, 0x00005B54U, 0x00005B58U, + 0x00005B5CU, 0x00005B60U, 0x00005B64U, 0x00005B68U, + 0x00005B6CU, 0x00005B70U, 0x00005B74U, 0x00005B78U, + 0x00005B7CU, 0x00007C00U, 0x00007C04U, 0x00007C08U, + 0x00007C0CU, 0x00007C10U, 0x00007C14U, 0x00007C18U, + 0x00007C1CU, 0x00007C20U, 0x00007C40U, 0x00007C44U, + 0x00007C48U, 0x00007C4CU, 0x00007C50U, 0x00007C54U, + 0x00007C58U, 0x00007C5CU, 0x00007C60U, 0x00007C80U, + 0x00007C84U, 0x00007C88U, 0x00007C8CU, 0x00007C90U, + 0x00007C94U, 0x00007C98U, 0x00007C9CU, 0x00007CA0U, + 0x00007CC0U, 0x00007CC4U, 0x00007CC8U, 0x00007CCCU, + 0x00007CD0U, 0x00007CD4U, 0x00007CD8U, 0x00007CDCU, + 0x00007CE0U, 0x00000300U, 0x00000304U, 0x00000308U, + 0x0000030cU, 0x00000310U, 0x00000314U, 0x00000318U, + 0x0000031cU, 0x00000360U, 0x00000364U, 0x00000368U, + 0x0000036cU, 0x00000370U, 0x00000374U, 0x00006900U, +}; + +int hw_atl_utils_hw_get_regs(struct aq_hw_s *self, + const struct aq_hw_caps_s *aq_hw_caps, + u32 *regs_buff) +{ + unsigned int i = 0U; + + for (i = 0; i < aq_hw_caps->mac_regs_count; i++) + regs_buff[i] = aq_hw_read_reg(self, + hw_atl_utils_hw_mac_regs[i]); + return 0; +} + +int hw_atl_utils_get_fw_version(struct aq_hw_s *self, u32 *fw_version) +{ + *fw_version = aq_hw_read_reg(self, 0x18U); + return 0; +} + +const struct aq_fw_ops aq_fw_1x_ops = { + .init = hw_atl_utils_mpi_create, + .deinit = hw_atl_fw1x_deinit, + .reset = NULL, + .get_mac_permanent = hw_atl_utils_get_mac_permanent, + .set_link_speed = hw_atl_utils_mpi_set_speed, + .set_state = hw_atl_utils_mpi_set_state, + .update_link_status = hw_atl_utils_mpi_get_link_status, + .update_stats = hw_atl_utils_update_stats, + .set_flow_control = NULL, +}; diff --git a/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_utils.h b/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_utils.h new file mode 100644 index 000000000..505c8a2ab --- /dev/null +++ b/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_utils.h @@ -0,0 +1,330 @@ +/* + * aQuantia Corporation Network Driver + * Copyright (C) 2014-2017 aQuantia Corporation. All rights reserved + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + */ + +/* File hw_atl_utils.h: Declaration of common functions for Atlantic hardware + * abstraction layer. + */ + +#ifndef HW_ATL_UTILS_H +#define HW_ATL_UTILS_H + +#define HW_ATL_FLUSH() { (void)aq_hw_read_reg(self, 0x10); } + +/* Hardware tx descriptor */ +struct __packed hw_atl_txd_s { + u64 buf_addr; + u32 ctl; + u32 ctl2; /* 63..46 - payload length, 45 - ctx enable, 44 - ctx index */ +}; + +/* Hardware tx context descriptor */ +struct __packed hw_atl_txc_s { + u32 rsvd; + u32 len; + u32 ctl; + u32 len2; +}; + +/* Hardware rx descriptor */ +struct __packed hw_atl_rxd_s { + u64 buf_addr; + u64 hdr_addr; +}; + +/* Hardware rx descriptor writeback */ +struct __packed hw_atl_rxd_wb_s { + u32 type; + u32 rss_hash; + u16 status; + u16 pkt_len; + u16 next_desc_ptr; + u16 vlan; +}; + +struct __packed hw_atl_stats_s { + u32 uprc; + u32 mprc; + u32 bprc; + u32 erpt; + u32 uptc; + u32 mptc; + u32 bptc; + u32 erpr; + u32 mbtc; + u32 bbtc; + u32 mbrc; + u32 bbrc; + u32 ubrc; + u32 ubtc; + u32 dpc; +}; + +union __packed ip_addr { + struct { + u8 addr[16]; + } v6; + struct { + u8 padding[12]; + u8 addr[4]; + } v4; +}; + +struct __packed hw_aq_atl_utils_fw_rpc { + u32 msg_id; + + union { + struct { + u32 pong; + } msg_ping; + + struct { + u8 mac_addr[6]; + u32 ip_addr_cnt; + + struct { + union ip_addr addr; + union ip_addr mask; + } ip[1]; + } msg_arp; + + struct { + u32 len; + u8 packet[1514U]; + } msg_inject; + + struct { + u32 priority; + u32 wol_packet_type; + u16 friendly_name_len; + u16 friendly_name[65]; + u32 pattern_id; + u32 next_wol_pattern_offset; + + union { + struct { + u32 flags; + u8 ipv4_source_address[4]; + u8 ipv4_dest_address[4]; + u16 tcp_source_port_number; + u16 tcp_dest_port_number; + } ipv4_tcp_syn_parameters; + + struct { + u32 flags; + u8 ipv6_source_address[16]; + u8 ipv6_dest_address[16]; + u16 tcp_source_port_number; + u16 tcp_dest_port_number; + } ipv6_tcp_syn_parameters; + + struct { + u32 flags; + } eapol_request_id_message_parameters; + + struct { + u32 flags; + u32 mask_offset; + u32 mask_size; + u32 pattern_offset; + u32 pattern_size; + } wol_bit_map_pattern; + } wol_pattern; + } msg_wol; + + struct { + u32 is_wake_on_link_down; + u32 is_wake_on_link_up; + } msg_wolink; + }; +}; + +struct __packed hw_aq_atl_utils_mbox_header { + u32 version; + u32 transaction_id; + u32 error; +}; + +struct __packed hw_aq_atl_utils_mbox { + struct hw_aq_atl_utils_mbox_header header; + struct hw_atl_stats_s stats; +}; + +#define HAL_ATLANTIC_UTILS_CHIP_MIPS 0x00000001U +#define HAL_ATLANTIC_UTILS_CHIP_TPO2 0x00000002U +#define HAL_ATLANTIC_UTILS_CHIP_RPF2 0x00000004U +#define HAL_ATLANTIC_UTILS_CHIP_MPI_AQ 0x00000010U +#define HAL_ATLANTIC_UTILS_CHIP_REVISION_A0 0x01000000U +#define HAL_ATLANTIC_UTILS_CHIP_REVISION_B0 0x02000000U +#define HAL_ATLANTIC_UTILS_CHIP_REVISION_B1 0x04000000U + +#define IS_CHIP_FEATURE(_F_) (HAL_ATLANTIC_UTILS_CHIP_##_F_ & \ + self->chip_features) + +enum hal_atl_utils_fw_state_e { + MPI_DEINIT = 0, + MPI_RESET = 1, + MPI_INIT = 2, + MPI_POWER = 4, +}; + +#define HAL_ATLANTIC_RATE_10G BIT(0) +#define HAL_ATLANTIC_RATE_5G BIT(1) +#define HAL_ATLANTIC_RATE_5GSR BIT(2) +#define HAL_ATLANTIC_RATE_2GS BIT(3) +#define HAL_ATLANTIC_RATE_1G BIT(4) +#define HAL_ATLANTIC_RATE_100M BIT(5) +#define HAL_ATLANTIC_RATE_INVALID BIT(6) + +enum hw_atl_fw2x_rate { + FW2X_RATE_100M = 0x20, + FW2X_RATE_1G = 0x100, + FW2X_RATE_2G5 = 0x200, + FW2X_RATE_5G = 0x400, + FW2X_RATE_10G = 0x800, +}; + +enum hw_atl_fw2x_caps_lo { + CAPS_LO_10BASET_HD = 0x00, + CAPS_LO_10BASET_FD, + CAPS_LO_100BASETX_HD, + CAPS_LO_100BASET4_HD, + CAPS_LO_100BASET2_HD, + CAPS_LO_100BASETX_FD, + CAPS_LO_100BASET2_FD, + CAPS_LO_1000BASET_HD, + CAPS_LO_1000BASET_FD, + CAPS_LO_2P5GBASET_FD, + CAPS_LO_5GBASET_FD, + CAPS_LO_10GBASET_FD, +}; + +enum hw_atl_fw2x_caps_hi { + CAPS_HI_RESERVED1 = 0x00, + CAPS_HI_10BASET_EEE, + CAPS_HI_RESERVED2, + CAPS_HI_PAUSE, + CAPS_HI_ASYMMETRIC_PAUSE, + CAPS_HI_100BASETX_EEE, + CAPS_HI_RESERVED3, + CAPS_HI_RESERVED4, + CAPS_HI_1000BASET_FD_EEE, + CAPS_HI_2P5GBASET_FD_EEE, + CAPS_HI_5GBASET_FD_EEE, + CAPS_HI_10GBASET_FD_EEE, + CAPS_HI_RESERVED5, + CAPS_HI_RESERVED6, + CAPS_HI_RESERVED7, + CAPS_HI_RESERVED8, + CAPS_HI_RESERVED9, + CAPS_HI_CABLE_DIAG, + CAPS_HI_TEMPERATURE, + CAPS_HI_DOWNSHIFT, + CAPS_HI_PTP_AVB_EN, + CAPS_HI_MEDIA_DETECT, + CAPS_HI_LINK_DROP, + CAPS_HI_SLEEP_PROXY, + CAPS_HI_WOL, + CAPS_HI_MAC_STOP, + CAPS_HI_EXT_LOOPBACK, + CAPS_HI_INT_LOOPBACK, + CAPS_HI_EFUSE_AGENT, + CAPS_HI_WOL_TIMER, + CAPS_HI_STATISTICS, + CAPS_HI_TRANSACTION_ID, +}; + +enum hw_atl_fw2x_ctrl { + CTRL_RESERVED1 = 0x00, + CTRL_RESERVED2, + CTRL_RESERVED3, + CTRL_PAUSE, + CTRL_ASYMMETRIC_PAUSE, + CTRL_RESERVED4, + CTRL_RESERVED5, + CTRL_RESERVED6, + CTRL_1GBASET_FD_EEE, + CTRL_2P5GBASET_FD_EEE, + CTRL_5GBASET_FD_EEE, + CTRL_10GBASET_FD_EEE, + CTRL_THERMAL_SHUTDOWN, + CTRL_PHY_LOGS, + CTRL_EEE_AUTO_DISABLE, + CTRL_PFC, + CTRL_WAKE_ON_LINK, + CTRL_CABLE_DIAG, + CTRL_TEMPERATURE, + CTRL_DOWNSHIFT, + CTRL_PTP_AVB, + CTRL_RESERVED7, + CTRL_LINK_DROP, + CTRL_SLEEP_PROXY, + CTRL_WOL, + CTRL_MAC_STOP, + CTRL_EXT_LOOPBACK, + CTRL_INT_LOOPBACK, + CTRL_RESERVED8, + CTRL_WOL_TIMER, + CTRL_STATISTICS, + CTRL_FORCE_RECONNECT, +}; + +struct aq_hw_s; +struct aq_fw_ops; +struct aq_hw_caps_s; +struct aq_hw_link_status_s; + +int hw_atl_utils_initfw(struct aq_hw_s *self, const struct aq_fw_ops **fw_ops); + +int hw_atl_utils_soft_reset(struct aq_hw_s *self); + +void hw_atl_utils_hw_chip_features_init(struct aq_hw_s *self, u32 *p); + +int hw_atl_utils_mpi_read_mbox(struct aq_hw_s *self, + struct hw_aq_atl_utils_mbox_header *pmbox); + +void hw_atl_utils_mpi_read_stats(struct aq_hw_s *self, + struct hw_aq_atl_utils_mbox *pmbox); + +void hw_atl_utils_mpi_set(struct aq_hw_s *self, + enum hal_atl_utils_fw_state_e state, + u32 speed); + +int hw_atl_utils_mpi_get_link_status(struct aq_hw_s *self); + +int hw_atl_utils_get_mac_permanent(struct aq_hw_s *self, + u8 *mac); + +unsigned int hw_atl_utils_mbps_2_speed_index(unsigned int mbps); + +int hw_atl_utils_hw_get_regs(struct aq_hw_s *self, + const struct aq_hw_caps_s *aq_hw_caps, + u32 *regs_buff); + +int hw_atl_utils_hw_set_power(struct aq_hw_s *self, + unsigned int power_state); + +int hw_atl_utils_hw_deinit(struct aq_hw_s *self); + +int hw_atl_utils_get_fw_version(struct aq_hw_s *self, u32 *fw_version); + +int hw_atl_utils_update_stats(struct aq_hw_s *self); + +struct aq_stats_s *hw_atl_utils_get_hw_stats(struct aq_hw_s *self); +int hw_atl_utils_fw_downld_dwords(struct aq_hw_s *self, u32 a, + u32 *p, u32 cnt); + +int hw_atl_utils_fw_rpc_call(struct aq_hw_s *self, unsigned int rpc_size); + +int hw_atl_utils_fw_rpc_wait(struct aq_hw_s *self, + struct hw_aq_atl_utils_fw_rpc **rpc); + +extern const struct aq_fw_ops aq_fw_1x_ops; +extern const struct aq_fw_ops aq_fw_2x_ops; + +#endif /* HW_ATL_UTILS_H */ diff --git a/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_utils_fw2x.c b/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_utils_fw2x.c new file mode 100644 index 000000000..6300d94c9 --- /dev/null +++ b/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_utils_fw2x.c @@ -0,0 +1,256 @@ +/* + * aQuantia Corporation Network Driver + * Copyright (C) 2014-2017 aQuantia Corporation. All rights reserved + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + */ + +/* File hw_atl_utils_fw2x.c: Definition of firmware 2.x functions for + * Atlantic hardware abstraction layer. + */ + +#include "../aq_hw.h" +#include "../aq_hw_utils.h" +#include "../aq_pci_func.h" +#include "../aq_ring.h" +#include "../aq_vec.h" +#include "hw_atl_utils.h" +#include "hw_atl_llh.h" + +#define HW_ATL_FW2X_MPI_EFUSE_ADDR 0x364 +#define HW_ATL_FW2X_MPI_MBOX_ADDR 0x360 +#define HW_ATL_FW2X_MPI_RPC_ADDR 0x334 + +#define HW_ATL_FW2X_MPI_CONTROL_ADDR 0x368 +#define HW_ATL_FW2X_MPI_CONTROL2_ADDR 0x36C + +#define HW_ATL_FW2X_MPI_STATE_ADDR 0x370 +#define HW_ATL_FW2X_MPI_STATE2_ADDR 0x374 + +static int aq_fw2x_set_link_speed(struct aq_hw_s *self, u32 speed); +static int aq_fw2x_set_state(struct aq_hw_s *self, + enum hal_atl_utils_fw_state_e state); + +static int aq_fw2x_init(struct aq_hw_s *self) +{ + int err = 0; + + /* check 10 times by 1ms */ + AQ_HW_WAIT_FOR(0U != (self->mbox_addr = + aq_hw_read_reg(self, HW_ATL_FW2X_MPI_MBOX_ADDR)), + 1000U, 10U); + AQ_HW_WAIT_FOR(0U != (self->rpc_addr = + aq_hw_read_reg(self, HW_ATL_FW2X_MPI_RPC_ADDR)), + 1000U, 100U); + + return err; +} + +static int aq_fw2x_deinit(struct aq_hw_s *self) +{ + int err = aq_fw2x_set_link_speed(self, 0); + + if (!err) + err = aq_fw2x_set_state(self, MPI_DEINIT); + + return err; +} + +static enum hw_atl_fw2x_rate link_speed_mask_2fw2x_ratemask(u32 speed) +{ + enum hw_atl_fw2x_rate rate = 0; + + if (speed & AQ_NIC_RATE_10G) + rate |= FW2X_RATE_10G; + + if (speed & AQ_NIC_RATE_5G) + rate |= FW2X_RATE_5G; + + if (speed & AQ_NIC_RATE_5GSR) + rate |= FW2X_RATE_5G; + + if (speed & AQ_NIC_RATE_2GS) + rate |= FW2X_RATE_2G5; + + if (speed & AQ_NIC_RATE_1G) + rate |= FW2X_RATE_1G; + + if (speed & AQ_NIC_RATE_100M) + rate |= FW2X_RATE_100M; + + return rate; +} + +static int aq_fw2x_set_link_speed(struct aq_hw_s *self, u32 speed) +{ + u32 val = link_speed_mask_2fw2x_ratemask(speed); + + aq_hw_write_reg(self, HW_ATL_FW2X_MPI_CONTROL_ADDR, val); + + return 0; +} + +static void aq_fw2x_set_mpi_flow_control(struct aq_hw_s *self, u32 *mpi_state) +{ + if (self->aq_nic_cfg->flow_control & AQ_NIC_FC_RX) + *mpi_state |= BIT(CAPS_HI_PAUSE); + else + *mpi_state &= ~BIT(CAPS_HI_PAUSE); + + if (self->aq_nic_cfg->flow_control & AQ_NIC_FC_TX) + *mpi_state |= BIT(CAPS_HI_ASYMMETRIC_PAUSE); + else + *mpi_state &= ~BIT(CAPS_HI_ASYMMETRIC_PAUSE); +} + +static int aq_fw2x_set_state(struct aq_hw_s *self, + enum hal_atl_utils_fw_state_e state) +{ + u32 mpi_state = aq_hw_read_reg(self, HW_ATL_FW2X_MPI_CONTROL2_ADDR); + + switch (state) { + case MPI_INIT: + mpi_state &= ~BIT(CAPS_HI_LINK_DROP); + aq_fw2x_set_mpi_flow_control(self, &mpi_state); + break; + case MPI_DEINIT: + mpi_state |= BIT(CAPS_HI_LINK_DROP); + break; + case MPI_RESET: + case MPI_POWER: + /* No actions */ + break; + } + aq_hw_write_reg(self, HW_ATL_FW2X_MPI_CONTROL2_ADDR, mpi_state); + return 0; +} + +static int aq_fw2x_update_link_status(struct aq_hw_s *self) +{ + u32 mpi_state = aq_hw_read_reg(self, HW_ATL_FW2X_MPI_STATE_ADDR); + u32 speed = mpi_state & (FW2X_RATE_100M | FW2X_RATE_1G | + FW2X_RATE_2G5 | FW2X_RATE_5G | FW2X_RATE_10G); + struct aq_hw_link_status_s *link_status = &self->aq_link_status; + + if (speed) { + if (speed & FW2X_RATE_10G) + link_status->mbps = 10000; + else if (speed & FW2X_RATE_5G) + link_status->mbps = 5000; + else if (speed & FW2X_RATE_2G5) + link_status->mbps = 2500; + else if (speed & FW2X_RATE_1G) + link_status->mbps = 1000; + else if (speed & FW2X_RATE_100M) + link_status->mbps = 100; + else + link_status->mbps = 10000; + } else { + link_status->mbps = 0; + } + + return 0; +} + +static int aq_fw2x_get_mac_permanent(struct aq_hw_s *self, u8 *mac) +{ + int err = 0; + u32 h = 0U; + u32 l = 0U; + u32 mac_addr[2] = { 0 }; + u32 efuse_addr = aq_hw_read_reg(self, HW_ATL_FW2X_MPI_EFUSE_ADDR); + + if (efuse_addr != 0) { + err = hw_atl_utils_fw_downld_dwords(self, + efuse_addr + (40U * 4U), + mac_addr, + ARRAY_SIZE(mac_addr)); + if (err) + return err; + mac_addr[0] = __swab32(mac_addr[0]); + mac_addr[1] = __swab32(mac_addr[1]); + } + + ether_addr_copy(mac, (u8 *)mac_addr); + + if ((mac[0] & 0x01U) || ((mac[0] | mac[1] | mac[2]) == 0x00U)) { + unsigned int rnd = 0; + + get_random_bytes(&rnd, sizeof(unsigned int)); + + l = 0xE3000000U + | (0xFFFFU & rnd) + | (0x00 << 16); + h = 0x8001300EU; + + mac[5] = (u8)(0xFFU & l); + l >>= 8; + mac[4] = (u8)(0xFFU & l); + l >>= 8; + mac[3] = (u8)(0xFFU & l); + l >>= 8; + mac[2] = (u8)(0xFFU & l); + mac[1] = (u8)(0xFFU & h); + h >>= 8; + mac[0] = (u8)(0xFFU & h); + } + return err; +} + +static int aq_fw2x_update_stats(struct aq_hw_s *self) +{ + int err = 0; + u32 mpi_opts = aq_hw_read_reg(self, HW_ATL_FW2X_MPI_CONTROL2_ADDR); + u32 orig_stats_val = mpi_opts & BIT(CAPS_HI_STATISTICS); + + /* Toggle statistics bit for FW to update */ + mpi_opts = mpi_opts ^ BIT(CAPS_HI_STATISTICS); + aq_hw_write_reg(self, HW_ATL_FW2X_MPI_CONTROL2_ADDR, mpi_opts); + + /* Wait FW to report back */ + AQ_HW_WAIT_FOR(orig_stats_val != + (aq_hw_read_reg(self, HW_ATL_FW2X_MPI_STATE2_ADDR) & + BIT(CAPS_HI_STATISTICS)), + 1U, 10000U); + if (err) + return err; + + return hw_atl_utils_update_stats(self); +} + +static int aq_fw2x_renegotiate(struct aq_hw_s *self) +{ + u32 mpi_opts = aq_hw_read_reg(self, HW_ATL_FW2X_MPI_CONTROL2_ADDR); + + mpi_opts |= BIT(CTRL_FORCE_RECONNECT); + + aq_hw_write_reg(self, HW_ATL_FW2X_MPI_CONTROL2_ADDR, mpi_opts); + + return 0; +} + +static int aq_fw2x_set_flow_control(struct aq_hw_s *self) +{ + u32 mpi_state = aq_hw_read_reg(self, HW_ATL_FW2X_MPI_CONTROL2_ADDR); + + aq_fw2x_set_mpi_flow_control(self, &mpi_state); + + aq_hw_write_reg(self, HW_ATL_FW2X_MPI_CONTROL2_ADDR, mpi_state); + + return 0; +} + +const struct aq_fw_ops aq_fw_2x_ops = { + .init = aq_fw2x_init, + .deinit = aq_fw2x_deinit, + .reset = NULL, + .renegotiate = aq_fw2x_renegotiate, + .get_mac_permanent = aq_fw2x_get_mac_permanent, + .set_link_speed = aq_fw2x_set_link_speed, + .set_state = aq_fw2x_set_state, + .update_link_status = aq_fw2x_update_link_status, + .update_stats = aq_fw2x_update_stats, + .set_flow_control = aq_fw2x_set_flow_control, +}; diff --git a/drivers/net/ethernet/aquantia/atlantic/ver.h b/drivers/net/ethernet/aquantia/atlantic/ver.h new file mode 100644 index 000000000..94efc6477 --- /dev/null +++ b/drivers/net/ethernet/aquantia/atlantic/ver.h @@ -0,0 +1,20 @@ +/* + * aQuantia Corporation Network Driver + * Copyright (C) 2014-2017 aQuantia Corporation. All rights reserved + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + */ + +#ifndef VER_H +#define VER_H + +#define NIC_MAJOR_DRIVER_VERSION 2 +#define NIC_MINOR_DRIVER_VERSION 0 +#define NIC_BUILD_DRIVER_VERSION 3 +#define NIC_REVISION_DRIVER_VERSION 0 + +#define AQ_CFG_DRV_VERSION_SUFFIX "-kern" + +#endif /* VER_H */ |