root/sys/dev/aq/aq2_hw.h
/*-
 * Atlantic 2 (AQC113/114/115/116) register definitions for aq(4).
 *
 * Register layout and field definitions adapted from the OpenBSD/NetBSD
 * if_aq driver:
 *
 * Copyright (c) 2021 Jonathan Matthew <jonathan@d14n.org>
 * Copyright (c) 2021 Mike Larkin <mlarkin@openbsd.org>
 *
 * Permission to use, copy, modify, and distribute this software for any
 * purpose with or without fee is hereby granted, provided that the above
 * copyright notice and this permission notice appear in all copies.
 *
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 */

#ifndef AQ2_HW_H
#define AQ2_HW_H

/* Atlantic 2 PCI device IDs (Aquantia/Marvell). */
#define AQ_DEVICE_ID_AQC113     0x04C0
#define AQ_DEVICE_ID_AQC113C    0x14C0
#define AQ_DEVICE_ID_AQC113CA   0x34C0
#define AQ_DEVICE_ID_AQC113CS   0x94C0
#define AQ_DEVICE_ID_AQC114CS   0x93C0
#define AQ_DEVICE_ID_AQC115C    0x12C0
#define AQ_DEVICE_ID_AQC116C    0x11C0

static __inline bool
aq_is_atlantic2(uint16_t device_id)
{
        switch (device_id) {
        case AQ_DEVICE_ID_AQC113:
        case AQ_DEVICE_ID_AQC113C:
        case AQ_DEVICE_ID_AQC113CA:
        case AQ_DEVICE_ID_AQC113CS:
        case AQ_DEVICE_ID_AQC114CS:
        case AQ_DEVICE_ID_AQC115C:
        case AQ_DEVICE_ID_AQC116C:
                return (true);
        default:
                return (false);
        }
}

/* Atlantic 2 host packet-buffer sizes (Atlantic 1 uses 160/320). */
#define AQ2_HW_TXBUF_MAX        128
#define AQ2_HW_RXBUF_MAX        192

/* A2 firmware handshake registers (host <-> MCP). */
#define AQ2_MIF_HOST_FINISHED_STATUS_WRITE_REG  0x0e00
#define AQ2_MIF_HOST_FINISHED_STATUS_READ_REG   0x0e04
#define  AQ2_MIF_HOST_FINISHED_STATUS_ACK       (1 << 0)

#define AQ2_MCP_HOST_REQ_INT_REG                0x0f00
#define  AQ2_MCP_HOST_REQ_INT_READY             (1 << 0)
#define AQ2_MCP_HOST_REQ_INT_SET_REG            0x0f04
#define AQ2_MCP_HOST_REQ_INT_CLR_REG            0x0f08

#define AQ2_MIF_BOOT_REG                        0x3040
#define  AQ2_MIF_BOOT_HOST_DATA_LOADED          (1 << 16)
#define  AQ2_MIF_BOOT_BOOT_STARTED              (1 << 24)
#define  AQ2_MIF_BOOT_CRASH_INIT                (1 << 27)
#define  AQ2_MIF_BOOT_BOOT_CODE_FAILED          (1 << 28)
#define  AQ2_MIF_BOOT_FW_INIT_FAILED            (1 << 29)
#define  AQ2_MIF_BOOT_FW_INIT_COMP_SUCCESS      (1U << 31)
#define  AQ2_MIF_BOOT_FAILED \
        (AQ2_MIF_BOOT_CRASH_INIT | AQ2_MIF_BOOT_BOOT_CODE_FAILED | \
            AQ2_MIF_BOOT_FW_INIT_FAILED)
#define  AQ2_MIF_BOOT_COMPLETE \
        (AQ2_MIF_BOOT_FAILED | AQ2_MIF_BOOT_FW_INIT_COMP_SUCCESS)

/* The ART semaphore is global CPU semaphore index 3. */
#define AQ2_ART_SEM_INDEX                       3

/* Action Resolver Table (replaces Atlantic 1's discrete RPF filters). */
#define AQ2_ART_ACTION_ACT_SHIFT                8
#define AQ2_ART_ACTION_RSS                      0x0080
#define AQ2_ART_ACTION_INDEX_SHIFT              2
#define AQ2_ART_ACTION_ENABLE                   0x0001
#define AQ2_ART_ACTION(act, rss, idx, en)               \
        (((act) << AQ2_ART_ACTION_ACT_SHIFT) |          \
        ((rss) ? AQ2_ART_ACTION_RSS : 0) |              \
        ((idx) << AQ2_ART_ACTION_INDEX_SHIFT) |         \
        ((en) ? AQ2_ART_ACTION_ENABLE : 0))
#define AQ2_ART_ACTION_DROP                     AQ2_ART_ACTION(0, 0, 0, 1)
#define AQ2_ART_ACTION_DISABLE                  AQ2_ART_ACTION(0, 0, 0, 0)
#define AQ2_ART_ACTION_ASSIGN_QUEUE(q)          AQ2_ART_ACTION(1, 0, (q), 1)
#define AQ2_ART_ACTION_ASSIGN_TC(tc)            AQ2_ART_ACTION(1, 1, (tc), 1)

#define AQ2_RPF_TAG_PCP_MASK                    0xe0000000
#define AQ2_RPF_TAG_PCP_SHIFT                   29
#define AQ2_RPF_TAG_FLEX_MASK                   0x18000000
#define AQ2_RPF_TAG_UNKNOWN_MASK                0x07000000
#define AQ2_RPF_TAG_L4_MASK                     0x00e00000
#define AQ2_RPF_TAG_L3_V6_MASK                  0x001c0000
#define AQ2_RPF_TAG_L3_V4_MASK                  0x00038000
#define AQ2_RPF_TAG_UNTAG_MASK                  0x00004000
#define AQ2_RPF_TAG_VLAN_MASK                   0x00003c00
#define AQ2_RPF_TAG_ET_MASK                     0x00000380
#define AQ2_RPF_TAG_ALLMC_MASK                  0x00000040
#define AQ2_RPF_TAG_UC_MASK                     0x0000002f

/* Logical ART row indices (before adding sc_art_filter_base_index). */
#define AQ2_RPF_INDEX_L2_PROMISC_OFF            0
#define AQ2_RPF_INDEX_VLAN_PROMISC_OFF          1
#define AQ2_RPF_INDEX_L3L4_USER                 8
#define AQ2_RPF_INDEX_ET_PCP_USER               24
#define AQ2_RPF_INDEX_VLAN_USER                 40
#define AQ2_RPF_INDEX_PCP_TO_TC                 56

#define AQ2_RPF_L2BC_TAG_REG                    0x50f0
#define  AQ2_RPF_L2BC_TAG_MASK                  0x0000003f

#define AQ2_RPF_NEW_CTRL_REG                    0x5104
#define  AQ2_RPF_NEW_CTRL_ENABLE                (1 << 11)

#define AQ2_RPF_REDIR2_REG                      0x54c8
#define  AQ2_RPF_REDIR2_INDEX                   (1 << 12)
#define  AQ2_RPF_REDIR2_HASHTYPE                0x000001FF
#define  AQ2_RPF_REDIR2_HASHTYPE_NONE           0
#define  AQ2_RPF_REDIR2_HASHTYPE_IP             (1 << 0)
#define  AQ2_RPF_REDIR2_HASHTYPE_TCP4           (1 << 1)
#define  AQ2_RPF_REDIR2_HASHTYPE_UDP4           (1 << 2)
#define  AQ2_RPF_REDIR2_HASHTYPE_IP6            (1 << 3)
#define  AQ2_RPF_REDIR2_HASHTYPE_TCP6           (1 << 4)
#define  AQ2_RPF_REDIR2_HASHTYPE_UDP6           (1 << 5)
#define  AQ2_RPF_REDIR2_HASHTYPE_IP6EX          (1 << 6)
#define  AQ2_RPF_REDIR2_HASHTYPE_TCP6EX         (1 << 7)
#define  AQ2_RPF_REDIR2_HASHTYPE_UDP6EX         (1 << 8)
#define  AQ2_RPF_REDIR2_HASHTYPE_ALL            0x000001FF

#define AQ2_RX_Q_TC_MAP_REG(i)                  (0x5900 + (i) * 4)
#define AQ2_TX_Q_TC_MAP_REG(i)                  (0x799c + (i) * 4)

#define AQ2_RPF_RSS_REDIR_MAX                   64
#define AQ2_RPF_RSS_REDIR_REG(tc, i)            \
         (0x6200 + (0x100 * ((tc) >> 2)) + (i) * 4)

#define AQ2_RPF_REC_TAB_ENABLE_REG              0x6ff0
#define  AQ2_RPF_REC_TAB_ENABLE_MASK            0x0000ffff

#define AQ2_LAUNCHTIME_CTRL_REG                 0x7a1c
#define  AQ2_LAUNCHTIME_CTRL_RATIO              0x0000ff00
#define  AQ2_LAUNCHTIME_CTRL_RATIO_SPEED_QUARTER 4
#define  AQ2_LAUNCHTIME_CTRL_RATIO_SPEED_HALF   2
#define  AQ2_LAUNCHTIME_CTRL_RATIO_SPEED_FULL   1

#define AQ2_HW_FPGA_VERSION_REG                 0x00f4

#define AQ2_TX_INTR_MODERATION_CTL_REG(i)       (0x7c28 + (i) * 0x40)
#define  AQ2_TX_INTR_MODERATION_CTL_EN          (1 << 1)
#define  AQ2_TX_INTR_MODERATION_CTL_MIN         0x0000ff00
#define  AQ2_TX_INTR_MODERATION_CTL_MAX         0x01ff0000

/* Firmware interface IN window (host -> MCP). */
#define AQ2_FW_INTERFACE_IN_MTU_REG             0x12000
#define AQ2_FW_INTERFACE_IN_MAC_ADDRESS_REG     0x12008

#define AQ2_FW_INTERFACE_IN_LINK_CONTROL_REG    0x12010
#define  AQ2_FW_INTERFACE_IN_LINK_CONTROL_MODE  0x0000000f
#define  AQ2_FW_INTERFACE_IN_LINK_CONTROL_MODE_INVALID  0
#define  AQ2_FW_INTERFACE_IN_LINK_CONTROL_MODE_ACTIVE   1
#define  AQ2_FW_INTERFACE_IN_LINK_CONTROL_MODE_SLEEP_PROXY 2
#define  AQ2_FW_INTERFACE_IN_LINK_CONTROL_MODE_LOWPOWER 3
#define  AQ2_FW_INTERFACE_IN_LINK_CONTROL_MODE_SHUTDOWN 4

#define AQ2_FW_INTERFACE_IN_LINK_OPTIONS_REG    0x12018
#define  AQ2_FW_INTERFACE_IN_LINK_OPTIONS_DOWNSHIFT     (1 << 27)
#define  AQ2_FW_INTERFACE_IN_LINK_OPTIONS_PAUSE_TX      (1 << 25)
#define  AQ2_FW_INTERFACE_IN_LINK_OPTIONS_PAUSE_RX      (1 << 24)
#define  AQ2_FW_INTERFACE_IN_LINK_OPTIONS_EEE_10G       (1 << 20)
#define  AQ2_FW_INTERFACE_IN_LINK_OPTIONS_EEE_5G        (1 << 19)
#define  AQ2_FW_INTERFACE_IN_LINK_OPTIONS_EEE_2G5       (1 << 18)
#define  AQ2_FW_INTERFACE_IN_LINK_OPTIONS_EEE_1G        (1 << 17)
#define  AQ2_FW_INTERFACE_IN_LINK_OPTIONS_EEE_100M      (1 << 16)
#define  AQ2_FW_INTERFACE_IN_LINK_OPTIONS_RATE_10G      (1 << 15)
#define  AQ2_FW_INTERFACE_IN_LINK_OPTIONS_RATE_N5G      (1 << 14)
#define  AQ2_FW_INTERFACE_IN_LINK_OPTIONS_RATE_5G       (1 << 13)
#define  AQ2_FW_INTERFACE_IN_LINK_OPTIONS_RATE_N2G5     (1 << 12)
#define  AQ2_FW_INTERFACE_IN_LINK_OPTIONS_RATE_2G5      (1 << 11)
#define  AQ2_FW_INTERFACE_IN_LINK_OPTIONS_RATE_1G       (1 << 10)
#define  AQ2_FW_INTERFACE_IN_LINK_OPTIONS_RATE_100M     (1 << 9)
#define  AQ2_FW_INTERFACE_IN_LINK_OPTIONS_RATE_10M      (1 << 8)
#define  AQ2_FW_INTERFACE_IN_LINK_OPTIONS_RATE_1G_HD    (1 << 7)
#define  AQ2_FW_INTERFACE_IN_LINK_OPTIONS_RATE_100M_HD  (1 << 6)
#define  AQ2_FW_INTERFACE_IN_LINK_OPTIONS_RATE_10M_HD   (1 << 5)
#define  AQ2_FW_INTERFACE_IN_LINK_OPTIONS_LINK_RENEGOTIATE (1 << 1)
#define  AQ2_FW_INTERFACE_IN_LINK_OPTIONS_LINK_UP       (1 << 0)

#define AQ2_FW_INTERFACE_IN_REQUEST_POLICY_REG  0x12a58
#define  AQ2_FW_INTERFACE_IN_REQUEST_POLICY_MCAST_QUEUE_OR_TC   0x00800000
#define  AQ2_FW_INTERFACE_IN_REQUEST_POLICY_MCAST_RX_QUEUE_TC_INDEX 0x007c0000
#define  AQ2_FW_INTERFACE_IN_REQUEST_POLICY_MCAST_ACCEPT        0x00010000
#define  AQ2_FW_INTERFACE_IN_REQUEST_POLICY_BCAST_QUEUE_OR_TC   0x00008000
#define  AQ2_FW_INTERFACE_IN_REQUEST_POLICY_BCAST_RX_QUEUE_TC_INDEX 0x00007c00
#define  AQ2_FW_INTERFACE_IN_REQUEST_POLICY_BCAST_ACCEPT        0x00000100
#define  AQ2_FW_INTERFACE_IN_REQUEST_POLICY_PROMISC_QUEUE_OR_TC 0x00000080
#define  AQ2_FW_INTERFACE_IN_REQUEST_POLICY_PROMISC_RX_QUEUE_TX_INDEX 0x0000007c
#define  AQ2_FW_INTERFACE_IN_REQUEST_POLICY_PROMISC_MCAST       0x00000002
#define  AQ2_FW_INTERFACE_IN_REQUEST_POLICY_PROMISC_ALL         0x00000001

/* Firmware interface OUT window (MCP -> host). */
#define AQ2_FW_INTERFACE_OUT_TRANSACTION_ID_REG 0x13000
#define  AQ2_FW_INTERFACE_OUT_TRANSACTION_ID_B  0xffff0000
#define  AQ2_FW_INTERFACE_OUT_TRANSACTION_ID_B_S 16
#define  AQ2_FW_INTERFACE_OUT_TRANSACTION_ID_A  0x0000ffff
#define  AQ2_FW_INTERFACE_OUT_TRANSACTION_ID_A_S 0

#define AQ2_FW_INTERFACE_OUT_VERSION_BUNDLE_REG 0x13004
#define AQ2_FW_INTERFACE_OUT_VERSION_MAC_REG    0x13008

#define AQ2_FW_INTERFACE_OUT_VERSION_PHY_REG    0x1300c
#define  AQ2_FW_INTERFACE_OUT_VERSION_BUILD     0xffff0000
#define  AQ2_FW_INTERFACE_OUT_VERSION_BUILD_S   16
#define  AQ2_FW_INTERFACE_OUT_VERSION_MINOR     0x0000ff00
#define  AQ2_FW_INTERFACE_OUT_VERSION_MINOR_S   8
#define  AQ2_FW_INTERFACE_OUT_VERSION_MAJOR     0x000000ff
#define  AQ2_FW_INTERFACE_OUT_VERSION_MAJOR_S   0

#define AQ2_FW_INTERFACE_OUT_VERSION_IFACE_REG  0x13010
#define  AQ2_FW_INTERFACE_OUT_VERSION_IFACE_VER 0x0000000f
#define  AQ2_FW_INTERFACE_OUT_VERSION_IFACE_VER_A0 0
#define  AQ2_FW_INTERFACE_OUT_VERSION_IFACE_VER_B0 1

#define AQ2_FW_INTERFACE_OUT_STATS_REG          0x13700

#define AQ2_FW_INTERFACE_OUT_LINK_STATUS_REG    0x13014
#define  AQ2_FW_INTERFACE_OUT_LINK_STATUS_DUPLEX        (1 << 11)
#define  AQ2_FW_INTERFACE_OUT_LINK_STATUS_EEE           (1 << 10)
#define  AQ2_FW_INTERFACE_OUT_LINK_STATUS_PAUSE_RX      (1 << 9)
#define  AQ2_FW_INTERFACE_OUT_LINK_STATUS_PAUSE_TX      (1 << 8)
#define  AQ2_FW_INTERFACE_OUT_LINK_STATUS_RATE          0x000000f0
#define  AQ2_FW_INTERFACE_OUT_LINK_STATUS_RATE_S        4
#define  AQ2_FW_INTERFACE_OUT_LINK_STATUS_RATE_10G      6
#define  AQ2_FW_INTERFACE_OUT_LINK_STATUS_RATE_5G       5
#define  AQ2_FW_INTERFACE_OUT_LINK_STATUS_RATE_2G5      4
#define  AQ2_FW_INTERFACE_OUT_LINK_STATUS_RATE_1G       3
#define  AQ2_FW_INTERFACE_OUT_LINK_STATUS_RATE_100M     2
#define  AQ2_FW_INTERFACE_OUT_LINK_STATUS_RATE_10M      1
#define  AQ2_FW_INTERFACE_OUT_LINK_STATUS_RATE_INVALID  0
#define  AQ2_FW_INTERFACE_OUT_LINK_STATUS_STATE         0x0000000f

#define AQ2_FW_INTERFACE_OUT_FILTER_CAPS_REG    0x13774
#define  AQ2_FW_INTERFACE_OUT_FILTER_CAPS3_RESOLVER_BASE_INDEX 0x00ff0000
#define  AQ2_FW_INTERFACE_OUT_FILTER_CAPS3_RESOLVER_BASE_INDEX_SHIFT 16

#define AQ2_RPF_ACT_ART_REQ_TAG_REG(i)          (0x14000 + (i) * 0x10)
#define AQ2_RPF_ACT_ART_REQ_MASK_REG(i)         (0x14004 + (i) * 0x10)
#define AQ2_RPF_ACT_ART_REQ_ACTION_REG(i)       (0x14008 + (i) * 0x10)

/*
 * L2 unicast filter MSW register (shared with Atlantic 1).  Atlantic 2 sets
 * the TAG field so unicast frames are classified into the resolver table.
 */
#define AQ2_RPF_VLAN_FLR_TAG_REG(i)             (0x5290 + (i) * 4)
#define  AQ2_RPF_VLAN_FLR_TAG                   0x0000F000
#define  AQ2_RPF_VLAN_FLR_TAG_SHIFT             12

#define RPF_L2UC_MSW_REG(i)                     (0x5114 + (i) * 8)
#define  RPF_L2UC_MSW_TAG                       0x03c00000
#define  RPF_L2UC_MSW_TAG_SHIFT                 22

/*
 * Tx packet-scheduler data-TC credit/weight (shared register, but the
 * Atlantic 2 fields are wider than Atlantic 1's), and the Tx buffer control
 * register whose randomized ring->TC map Atlantic 2 enables.
 */
#define TPS_DATA_TCT_REG(i)                     (0x7110 + (i) * 4)
#define  TPS2_DATA_TCT_CREDIT_MAX               0xffff0000
#define  TPS2_DATA_TCT_CREDIT_MAX_SHIFT         16
#define  TPS2_DATA_TCT_WEIGHT                   0x00007fff
#define  TPS2_DATA_TCT_WEIGHT_SHIFT             0

#define TPB_TX_BUF_REG                          0x7900
#define  TPB_TX_BUF_TC_Q_RAND_MAP_EN            (1 << 9)
#define  TPB_TX_BUF_TC_Q_RAND_MAP_EN_SHIFT      9

#endif /* AQ2_HW_H */