-/* $OpenBSD: if_aq_pci.c,v 1.19 2023/04/23 22:57:23 jmatthew Exp $ */
+/* $OpenBSD: if_aq_pci.c,v 1.20 2023/04/24 09:18:55 jmatthew Exp $ */
/* $NetBSD: if_aq.c,v 1.27 2021/06/16 00:21:18 riastradh Exp $ */
/*
#define AQ_FW_SOFTRESET_RESET (1 << 15)
#define AQ_FW_VERSION_REG 0x0018
#define AQ_HW_REVISION_REG 0x001c
+#define AQ2_HW_FPGA_VERSION_REG 0x00f4
#define AQ_GLB_NVR_INTERFACE1_REG 0x0100
#define AQ_FW_MBOX_CMD_REG 0x0200
#define AQ_FW_MBOX_CMD_EXECUTE 0x00008000
#define AQ_FW_MBOX_VAL_REG 0x020C
#define AQ_FW_GLB_CPU_SEM_REG(i) (0x03a0 + (i) * 4)
#define AQ_FW_SEM_RAM_REG AQ_FW_GLB_CPU_SEM_REG(2)
+#define AQ2_ART_SEM_REG AQ_FW_GLB_CPU_SEM_REG(3)
#define AQ_FW_GLB_CTL2_REG 0x0404
#define AQ_GLB_GENERAL_PROVISIONING9_REG 0x0520
#define AQ_GLB_NVR_PROVISIONING2_REG 0x0534
#define RPF_L2UC_MSW_REG(i) (0x5114 + (i) * 8)
#define RPF_L2UC_MSW_MACADDR_HI 0xFFFF
#define RPF_L2UC_MSW_ACTION 0x70000
+#define RPF_L2UC_MSW_TAG 0x03c00000
#define RPF_L2UC_MSW_EN (1 << 31)
#define AQ_HW_MAC_NUM 34
#define TPB_TX_BUF_REG 0x7900
#define TPB_TX_BUF_EN (1 << 0)
#define TPB_TX_BUF_SCP_INS_EN (1 << 2)
+#define TPB_TX_BUF_CLK_GATE_EN (1 << 5)
#define TPB_TX_BUF_TC_MODE_EN (1 << 8)
+
/* TPB_TXB_BUFSIZE_REG[AQ_TRAFFICCLASS_NUM] 0x7910-7990 */
#define TPB_TXB_BUFSIZE_REG(i) (0x7910 + (i) * 0x10)
#define TPB_TXB_BUFSIZE (0xFF)
#define TX_INTR_MODERATION_CTL_MIN (0xFF << 8)
#define TX_INTR_MODERATION_CTL_MAX (0x1FF << 16)
+/* AQ2 registers */
+
+#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 (1 << 31)
+
+/* AQ2 action resolver table */
+#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
+
+/* index of aq2_filter_art_set() */
+#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 0x00000100
+#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 0x00000100
+
+#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_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
+
+#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_EXTERNAL_LOOPBACK (1 << 4)
+#define AQ2_FW_INTERFACE_IN_LINK_OPTIONS_INTERNAL_LOOPBACK (1 << 3)
+#define AQ2_FW_INTERFACE_IN_LINK_OPTIONS_MINIMAL_LINK_SPEED (1 << 2)
+#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
+
+#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_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)
+
#define __LOWEST_SET_BIT(__mask) (((((uint32_t)__mask) - 1) & ((uint32_t)__mask)) ^ ((uint32_t)__mask))
#define __SHIFTIN(__x, __mask) ((__x) * __LOWEST_SET_BIT(__mask))
#define AQ_READ_REG(sc, reg) \
bus_space_read_4((sc)->sc_iot, (sc)->sc_ioh, (reg))
+#define AQ_READ_REGS(sc, reg, p, cnt) \
+ bus_space_read_region_4((sc)->sc_iot, (sc)->sc_ioh, (reg), (p), (cnt));
#define AQ_WRITE_REG(sc, reg, val) \
bus_space_write_4((sc)->sc_iot, (sc)->sc_ioh, (reg), (val))
#define FEATURES_AQ1_REV_B1 0x04000000
#define FEATURES_AQ1_REV_B (FEATURES_AQ1_REV_B0|FEATURES_AQ1_REV_B1)
#define FEATURES_AQ1 (FEATURES_AQ1_REV_A|FEATURES_AQ1_REV_B)
+#define FEATURES_AQ2 0x10000000
+#define FEATURES_AQ2_IFACE_A0 0x20000000
+#define FEATURES_AQ2_IFACE_B0 0x40000000
#define HWTYPE_AQ1_P(sc) (((sc)->sc_features & FEATURES_AQ1) != 0)
+#define HWTYPE_AQ2_P(sc) (((sc)->sc_features & FEATURES_AQ2) != 0)
/* lock for firmware interface */
#define AQ_MPI_LOCK(sc) mtx_enter(&(sc)->sc_mpi_mutex);
enum aq_hwtype {
HWTYPE_AQ1,
+ HWTYPE_AQ2
};
enum aq_fw_bootloader_mode {
enum aq_link_speed {
AQ_LINK_NONE = 0,
- AQ_LINK_100M = (1 << 0),
- AQ_LINK_1G = (1 << 1),
- AQ_LINK_2G5 = (1 << 2),
- AQ_LINK_5G = (1 << 3),
- AQ_LINK_10G = (1 << 4)
+ AQ_LINK_10M = (1 << 0),
+ AQ_LINK_100M = (1 << 1),
+ AQ_LINK_1G = (1 << 2),
+ AQ_LINK_2G5 = (1 << 3),
+ AQ_LINK_5G = (1 << 4),
+ AQ_LINK_10G = (1 << 5)
};
#define AQ_LINK_ALL (AQ_LINK_100M | AQ_LINK_1G | AQ_LINK_2G5 | \
int sc_rbl_enabled;
int sc_fast_start_enabled;
int sc_flash_present;
+ int sc_art_filter_base_index;
uint32_t sc_fw_version;
const struct aq_firmware_ops *sc_fw_ops;
uint64_t sc_fw_caps;
{ PCI_VENDOR_AQUANTIA, PCI_PRODUCT_AQUANTIA_AQC109 },
{ PCI_VENDOR_AQUANTIA, PCI_PRODUCT_AQUANTIA_AQC111 },
{ PCI_VENDOR_AQUANTIA, PCI_PRODUCT_AQUANTIA_AQC112 },
+ { PCI_VENDOR_AQUANTIA, PCI_PRODUCT_AQUANTIA_AQC113 },
+ { PCI_VENDOR_AQUANTIA, PCI_PRODUCT_AQUANTIA_AQC113C },
+ { PCI_VENDOR_AQUANTIA, PCI_PRODUCT_AQUANTIA_AQC113CA },
+ { PCI_VENDOR_AQUANTIA, PCI_PRODUCT_AQUANTIA_AQC113CS },
+ { PCI_VENDOR_AQUANTIA, PCI_PRODUCT_AQUANTIA_AQC114CS },
+ { PCI_VENDOR_AQUANTIA, PCI_PRODUCT_AQUANTIA_AQC115C },
+ { PCI_VENDOR_AQUANTIA, PCI_PRODUCT_AQUANTIA_AQC116C },
{ PCI_VENDOR_AQUANTIA, PCI_PRODUCT_AQUANTIA_AQC100S },
{ PCI_VENDOR_AQUANTIA, PCI_PRODUCT_AQUANTIA_AQC107S },
{ PCI_VENDOR_AQUANTIA, PCI_PRODUCT_AQUANTIA_AQC108S },
{ PCI_VENDOR_AQUANTIA, PCI_PRODUCT_AQUANTIA_D109, HWTYPE_AQ1,
AQ_MEDIA_TYPE_TP, AQ_LINK_100M | AQ_LINK_1G | AQ_LINK_2G5
},
+
+{ PCI_VENDOR_AQUANTIA, PCI_PRODUCT_AQUANTIA_AQC113, HWTYPE_AQ2,
+ AQ_MEDIA_TYPE_TP, AQ_LINK_ALL | AQ_LINK_10M
+},
+{ PCI_VENDOR_AQUANTIA, PCI_PRODUCT_AQUANTIA_AQC113C, HWTYPE_AQ2,
+ AQ_MEDIA_TYPE_TP, AQ_LINK_ALL | AQ_LINK_10M
+},
+{ PCI_VENDOR_AQUANTIA, PCI_PRODUCT_AQUANTIA_AQC113CA, HWTYPE_AQ2,
+ AQ_MEDIA_TYPE_TP, AQ_LINK_ALL | AQ_LINK_10M
+},
+{ PCI_VENDOR_AQUANTIA, PCI_PRODUCT_AQUANTIA_AQC113CS, HWTYPE_AQ2,
+ AQ_MEDIA_TYPE_TP, AQ_LINK_ALL | AQ_LINK_10M
+},
+{ PCI_VENDOR_AQUANTIA, PCI_PRODUCT_AQUANTIA_AQC114CS, HWTYPE_AQ2,
+ AQ_MEDIA_TYPE_TP,
+ AQ_LINK_10M | AQ_LINK_100M | AQ_LINK_1G | AQ_LINK_2G5 | AQ_LINK_5G
+},
+{ PCI_VENDOR_AQUANTIA, PCI_PRODUCT_AQUANTIA_AQC115C, HWTYPE_AQ2,
+ AQ_MEDIA_TYPE_TP,
+ AQ_LINK_10M | AQ_LINK_100M | AQ_LINK_1G | AQ_LINK_2G5
+},
+{ PCI_VENDOR_AQUANTIA, PCI_PRODUCT_AQUANTIA_AQC116C, HWTYPE_AQ2,
+ AQ_MEDIA_TYPE_TP, AQ_LINK_10M | AQ_LINK_100M | AQ_LINK_1G
+},
};
int aq_match(struct device *, void *, void *);
int aq1_mac_soft_reset_flb(struct aq_softc *);
int aq1_fw_downld_dwords(struct aq_softc *, uint32_t, uint32_t *, uint32_t);
+int aq2_interface_buffer_read(struct aq_softc *, uint32_t, uint32_t *,
+ uint32_t);
+int aq2_fw_reboot(struct aq_softc *);
+int aq2_filter_art_set(struct aq_softc *, uint32_t, uint32_t, uint32_t,
+ uint32_t action);
+
void aq_refill(void *);
int aq_rx_fill(struct aq_softc *, struct aq_rxring *);
static inline unsigned int aq_rx_fill_slots(struct aq_softc *,
enum aq_link_speed, enum aq_link_fc, enum aq_link_eee);
int aq_fw2x_get_stats(struct aq_softc *, struct aq_hw_stats_s *);
+int aq2_fw_reset(struct aq_softc *);
+int aq2_get_mac_addr(struct aq_softc *);
+int aq2_fw_get_mode(struct aq_softc *, enum aq_hw_fw_mpi_state *,
+ enum aq_link_speed *, enum aq_link_fc *, enum aq_link_eee *);
+int aq2_fw_set_mode(struct aq_softc *, enum aq_hw_fw_mpi_state,
+ enum aq_link_speed, enum aq_link_fc, enum aq_link_eee);
+int aq2_fw_get_stats(struct aq_softc *, struct aq_hw_stats_s *);
+
const struct aq_firmware_ops aq_fw1x_ops = {
.reset = aq_fw1x_reset,
.get_mac_addr = aq1_get_mac_addr,
.get_stats = aq_fw2x_get_stats,
};
+const struct aq_firmware_ops aq2_fw_ops = {
+ .reset = aq2_fw_reset,
+ .get_mac_addr = aq2_get_mac_addr,
+ .set_mode = aq2_fw_set_mode,
+ .get_mode = aq2_fw_get_mode,
+ .get_stats = aq2_fw_get_stats
+};
+
const struct cfattach aq_ca = {
sizeof(struct aq_softc), aq_match, aq_attach, NULL,
aq_activate
if (pci_intr_map_msix(pa, 0, &ih) == 0) {
int nmsix = pci_intr_msix_count(pa);
- if (nmsix > 1) {
+ /* don't do rss on aq2 yet */
+ if (aqp->aq_hwtype == HWTYPE_AQ1 && nmsix > 1) {
nmsix--;
sc->sc_intrmap = intrmap_create(&sc->sc_dev,
nmsix, AQ_MAXQ, INTRMAP_POWEROF2);
if (aq1_fw_reboot(sc))
return;
break;
+ case HWTYPE_AQ2:
+ if (aq2_fw_reboot(sc))
+ return;
+ break;
default:
return;
}
ifmedia_init(&sc->sc_media, IFM_IMASK, aq_ifmedia_change,
aq_ifmedia_status);
+ if (sc->sc_available_rates & AQ_LINK_10M) {
+ ifmedia_add(&sc->sc_media, IFM_ETHER|IFM_10_T, 0, NULL);
+ ifmedia_add(&sc->sc_media, IFM_ETHER|IFM_10_T|IFM_FDX, 0,
+ NULL);
+ }
+
if (sc->sc_available_rates & AQ_LINK_100M) {
ifmedia_add(&sc->sc_media, IFM_ETHER|IFM_100_TX, 0, NULL);
ifmedia_add(&sc->sc_media, IFM_ETHER|IFM_100_TX|IFM_FDX, 0,
tx->tx_irq = irqnum++;
}
- AQ_WRITE_REG_BIT(sc, TX_INTR_MODERATION_CTL_REG(i),
- TX_INTR_MODERATION_CTL_MIN, txmin);
- AQ_WRITE_REG_BIT(sc, TX_INTR_MODERATION_CTL_REG(i),
- TX_INTR_MODERATION_CTL_MAX, txmax);
- AQ_WRITE_REG_BIT(sc, TX_INTR_MODERATION_CTL_REG(i),
- TX_INTR_MODERATION_CTL_EN, 1);
+ if (HWTYPE_AQ2_P(sc)) {
+ AQ_WRITE_REG_BIT(sc, AQ2_TX_INTR_MODERATION_CTL_REG(i),
+ AQ2_TX_INTR_MODERATION_CTL_MIN, txmin);
+ AQ_WRITE_REG_BIT(sc, AQ2_TX_INTR_MODERATION_CTL_REG(i),
+ AQ2_TX_INTR_MODERATION_CTL_MAX, txmax);
+ AQ_WRITE_REG_BIT(sc, AQ2_TX_INTR_MODERATION_CTL_REG(i),
+ AQ2_TX_INTR_MODERATION_CTL_EN, 1);
+ } else {
+ AQ_WRITE_REG_BIT(sc, TX_INTR_MODERATION_CTL_REG(i),
+ TX_INTR_MODERATION_CTL_MIN, txmin);
+ AQ_WRITE_REG_BIT(sc, TX_INTR_MODERATION_CTL_REG(i),
+ TX_INTR_MODERATION_CTL_MAX, txmax);
+ AQ_WRITE_REG_BIT(sc, TX_INTR_MODERATION_CTL_REG(i),
+ TX_INTR_MODERATION_CTL_EN, 1);
+ }
AQ_WRITE_REG_BIT(sc, RX_INTR_MODERATION_CTL_REG(i),
RX_INTR_MODERATION_CTL_MIN, rxmin);
AQ_WRITE_REG_BIT(sc, RX_INTR_MODERATION_CTL_REG(i),
return 0;
}
+int
+aq2_interface_buffer_read(struct aq_softc *sc, uint32_t reg0, uint32_t *data0,
+ uint32_t size0)
+{
+ uint32_t tid0, tid1, reg, *data, size;
+ int timo;
+
+ for (timo = 10000; timo > 0; timo--) {
+ tid0 = AQ_READ_REG(sc, AQ2_FW_INTERFACE_OUT_TRANSACTION_ID_REG);
+ if (((tid0 & AQ2_FW_INTERFACE_OUT_TRANSACTION_ID_A)
+ >> AQ2_FW_INTERFACE_OUT_TRANSACTION_ID_A_S) !=
+ ((tid0 & AQ2_FW_INTERFACE_OUT_TRANSACTION_ID_B)
+ >> AQ2_FW_INTERFACE_OUT_TRANSACTION_ID_B_S)) {
+ delay(10);
+ continue;
+ }
+
+ for (reg = reg0, data = data0, size = size0;
+ size >= 4; reg += 4, data++, size -= 4) {
+ *data = AQ_READ_REG(sc, reg);
+ }
+
+ tid1 = AQ_READ_REG(sc, AQ2_FW_INTERFACE_OUT_TRANSACTION_ID_REG);
+ if (tid0 == tid1)
+ break;
+ }
+ if (timo == 0) {
+ printf("%s: interface buffer read timeout\n", DEVNAME(sc));
+ return ETIMEDOUT;
+ }
+ return 0;
+}
+
+int
+aq2_fw_reboot(struct aq_softc *sc)
+{
+ uint32_t v;
+ int timo, err;
+ char buf[32];
+ uint32_t filter_caps[3];
+
+ sc->sc_fw_ops = &aq2_fw_ops;
+ sc->sc_features = FEATURES_AQ2;
+
+ AQ_WRITE_REG(sc, AQ2_MCP_HOST_REQ_INT_CLR_REG, 1);
+ AQ_WRITE_REG(sc, AQ2_MIF_BOOT_REG, 1); /* reboot request */
+ for (timo = 200000; timo > 0; timo--) {
+ v = AQ_READ_REG(sc, AQ2_MIF_BOOT_REG);
+ if ((v & AQ2_MIF_BOOT_BOOT_STARTED) && v != 0xffffffff)
+ break;
+ delay(10);
+ }
+ if (timo <= 0) {
+ printf(": FW reboot timeout\n");
+ return ETIMEDOUT;
+ }
+
+ for (timo = 2000000; timo > 0; timo--) {
+ v = AQ_READ_REG(sc, AQ2_MIF_BOOT_REG);
+ if ((v & AQ2_MIF_BOOT_FW_INIT_FAILED) ||
+ (v & AQ2_MIF_BOOT_FW_INIT_COMP_SUCCESS))
+ break;
+ v = AQ_READ_REG(sc, AQ2_MCP_HOST_REQ_INT_REG);
+ if (v & AQ2_MCP_HOST_REQ_INT_READY)
+ break;
+ delay(10);
+ }
+ if (timo <= 0) {
+ printf(": FW restart timeout\n");
+ return ETIMEDOUT;
+ }
+
+ v = AQ_READ_REG(sc, AQ2_MIF_BOOT_REG);
+ if (v & AQ2_MIF_BOOT_FW_INIT_FAILED) {
+ printf(": FW restart failed\n");
+ return ETIMEDOUT;
+ }
+
+ v = AQ_READ_REG(sc, AQ2_MCP_HOST_REQ_INT_REG);
+ if (v & AQ2_MCP_HOST_REQ_INT_READY) {
+ printf(": firmware required\n");
+ return ENXIO;
+ }
+
+ /*
+ * Get aq2 firmware version.
+ * Note that the bit layout and its meaning are different from aq1.
+ */
+ err = aq2_interface_buffer_read(sc, AQ2_FW_INTERFACE_OUT_VERSION_BUNDLE_REG,
+ (uint32_t *)&v, sizeof(v));
+ if (err != 0)
+ return err;
+
+ sc->sc_fw_version =
+ (((v & AQ2_FW_INTERFACE_OUT_VERSION_MAJOR) >>
+ AQ2_FW_INTERFACE_OUT_VERSION_MAJOR_S) << 24) |
+ (((v & AQ2_FW_INTERFACE_OUT_VERSION_MINOR) >>
+ AQ2_FW_INTERFACE_OUT_VERSION_MINOR_S) << 16) |
+ (((v & AQ2_FW_INTERFACE_OUT_VERSION_BUILD) >>
+ AQ2_FW_INTERFACE_OUT_VERSION_BUILD_S));
+
+ err = aq2_interface_buffer_read(sc, AQ2_FW_INTERFACE_OUT_VERSION_IFACE_REG,
+ (uint32_t *)&v, sizeof(v));
+ if (err != 0)
+ return err;
+
+ switch (v & AQ2_FW_INTERFACE_OUT_VERSION_IFACE_VER) {
+ case AQ2_FW_INTERFACE_OUT_VERSION_IFACE_VER_A0:
+ sc->sc_features |= FEATURES_AQ2_IFACE_A0;
+ strncpy(buf, "A0", sizeof(buf));
+ break;
+ case AQ2_FW_INTERFACE_OUT_VERSION_IFACE_VER_B0:
+ sc->sc_features |= FEATURES_AQ2_IFACE_B0;
+ strncpy(buf, "B0", sizeof(buf));
+ break;
+ default:
+ snprintf(buf, sizeof(buf), "(unknown 0x%08x)", v);
+ break;
+ }
+ printf(", Atlantic2 %s, F/W version %d.%d.%d\n", buf,
+ FW_VERSION_MAJOR(sc), FW_VERSION_MINOR(sc), FW_VERSION_BUILD(sc));
+
+ aq2_interface_buffer_read(sc, AQ2_FW_INTERFACE_OUT_FILTER_CAPS_REG,
+ filter_caps, sizeof(filter_caps));
+ sc->sc_art_filter_base_index = ((filter_caps[2] &
+ AQ2_FW_INTERFACE_OUT_FILTER_CAPS3_RESOLVER_BASE_INDEX) >>
+ AQ2_FW_INTERFACE_OUT_FILTER_CAPS3_RESOLVER_BASE_INDEX_SHIFT) * 8;
+
+ /* debug info */
+ v = AQ_READ_REG(sc, AQ_HW_REVISION_REG);
+ DPRINTF(("%s: HW Rev: 0x%08x\n", DEVNAME(sc), v));
+
+ return 0;
+}
+
int
aq_hw_reset(struct aq_softc *sc)
{
return 0;
}
+static int
+aq2_fw_wait_shared_ack(struct aq_softc *sc)
+{
+ int error;
+
+ AQ_WRITE_REG(sc, AQ2_MIF_HOST_FINISHED_STATUS_WRITE_REG,
+ AQ2_MIF_HOST_FINISHED_STATUS_ACK);
+ WAIT_FOR((AQ_READ_REG(sc, AQ2_MIF_HOST_FINISHED_STATUS_READ_REG) &
+ AQ2_MIF_HOST_FINISHED_STATUS_ACK) == 0, 100, 100000, &error);
+
+ return error;
+}
+
+int
+aq2_fw_reset(struct aq_softc *sc)
+{
+ uint32_t v;
+ int error;
+
+ AQ_WRITE_REG_BIT(sc, AQ2_FW_INTERFACE_IN_LINK_CONTROL_REG,
+ AQ2_FW_INTERFACE_IN_LINK_CONTROL_MODE,
+ AQ2_FW_INTERFACE_IN_LINK_CONTROL_MODE_ACTIVE);
+
+ AQ_WRITE_REG(sc, AQ2_FW_INTERFACE_IN_MTU_REG,
+ /*AQ2_JUMBO_MTU*/ MCLBYTES + sizeof(struct ether_header));
+
+ v = AQ_READ_REG(sc, AQ2_FW_INTERFACE_IN_REQUEST_POLICY_REG);
+ v |= AQ2_FW_INTERFACE_IN_REQUEST_POLICY_MCAST_QUEUE_OR_TC;
+ v &= ~AQ2_FW_INTERFACE_IN_REQUEST_POLICY_MCAST_RX_QUEUE_TC_INDEX;
+ v |= AQ2_FW_INTERFACE_IN_REQUEST_POLICY_MCAST_ACCEPT;
+ v |= AQ2_FW_INTERFACE_IN_REQUEST_POLICY_BCAST_QUEUE_OR_TC;
+ v &= AQ2_FW_INTERFACE_IN_REQUEST_POLICY_BCAST_RX_QUEUE_TC_INDEX;
+ v |= AQ2_FW_INTERFACE_IN_REQUEST_POLICY_BCAST_ACCEPT;
+ v |= AQ2_FW_INTERFACE_IN_REQUEST_POLICY_PROMISC_QUEUE_OR_TC;
+ v &= ~AQ2_FW_INTERFACE_IN_REQUEST_POLICY_PROMISC_RX_QUEUE_TX_INDEX;
+ AQ_WRITE_REG(sc, AQ2_FW_INTERFACE_IN_REQUEST_POLICY_REG, v);
+
+ error = aq2_fw_wait_shared_ack(sc);
+ if (error != 0)
+ printf(": reset timed out\n");
+ return error;
+}
+
+int
+aq2_get_mac_addr(struct aq_softc *sc)
+{
+ uint32_t mac_addr[2];
+
+ memset(mac_addr, 0, sizeof(mac_addr));
+ AQ_READ_REGS(sc, AQ2_FW_INTERFACE_IN_MAC_ADDRESS_REG,
+ mac_addr, nitems(mac_addr));
+
+ if (mac_addr[0] == 0 && mac_addr[1] == 0) {
+ printf(": mac address not found\n");
+ return ENXIO;
+ }
+
+ mac_addr[0] = htole32(mac_addr[0]);
+ mac_addr[1] = htole32(mac_addr[1]);
+
+ memcpy(sc->sc_enaddr.ether_addr_octet,
+ (uint8_t *)mac_addr, ETHER_ADDR_LEN);
+ return 0;
+}
+
+int
+aq2_fw_set_mode(struct aq_softc *sc, enum aq_hw_fw_mpi_state w,
+ enum aq_link_speed speed, enum aq_link_fc fc, enum aq_link_eee eee)
+{
+ uint32_t v, ov;
+ int error;
+
+ AQ_MPI_LOCK(sc);
+
+ v = AQ_READ_REG(sc, AQ2_FW_INTERFACE_IN_LINK_OPTIONS_REG);
+ v &= ~(
+ AQ2_FW_INTERFACE_IN_LINK_OPTIONS_RATE_10G |
+ AQ2_FW_INTERFACE_IN_LINK_OPTIONS_RATE_N5G |
+ AQ2_FW_INTERFACE_IN_LINK_OPTIONS_RATE_5G |
+ AQ2_FW_INTERFACE_IN_LINK_OPTIONS_RATE_N2G5 |
+ AQ2_FW_INTERFACE_IN_LINK_OPTIONS_RATE_2G5 |
+ AQ2_FW_INTERFACE_IN_LINK_OPTIONS_RATE_1G |
+ AQ2_FW_INTERFACE_IN_LINK_OPTIONS_RATE_100M |
+ AQ2_FW_INTERFACE_IN_LINK_OPTIONS_RATE_10M |
+ AQ2_FW_INTERFACE_IN_LINK_OPTIONS_RATE_1G_HD |
+ AQ2_FW_INTERFACE_IN_LINK_OPTIONS_RATE_100M_HD |
+ AQ2_FW_INTERFACE_IN_LINK_OPTIONS_RATE_10M_HD);
+
+ v &= ~AQ2_FW_INTERFACE_IN_LINK_OPTIONS_LINK_UP;
+ ov = v;
+
+ if (speed & AQ_LINK_10G)
+ v |= AQ2_FW_INTERFACE_IN_LINK_OPTIONS_RATE_10G;
+ if (speed & AQ_LINK_5G)
+ v |= AQ2_FW_INTERFACE_IN_LINK_OPTIONS_RATE_N5G |
+ AQ2_FW_INTERFACE_IN_LINK_OPTIONS_RATE_5G;
+ if (speed & AQ_LINK_2G5)
+ v |= AQ2_FW_INTERFACE_IN_LINK_OPTIONS_RATE_N2G5 |
+ AQ2_FW_INTERFACE_IN_LINK_OPTIONS_RATE_2G5;
+ if (speed & AQ_LINK_1G)
+ v |= AQ2_FW_INTERFACE_IN_LINK_OPTIONS_RATE_1G |
+ AQ2_FW_INTERFACE_IN_LINK_OPTIONS_RATE_1G_HD;
+ if (speed & AQ_LINK_100M)
+ v |= AQ2_FW_INTERFACE_IN_LINK_OPTIONS_RATE_100M |
+ AQ2_FW_INTERFACE_IN_LINK_OPTIONS_RATE_100M_HD;
+ if (speed & AQ_LINK_10M) {
+ v |= AQ2_FW_INTERFACE_IN_LINK_OPTIONS_RATE_10M |
+ AQ2_FW_INTERFACE_IN_LINK_OPTIONS_RATE_10M_HD;
+ }
+
+ /* flow control */
+ v &= ~(AQ2_FW_INTERFACE_IN_LINK_OPTIONS_PAUSE_TX |
+ AQ2_FW_INTERFACE_IN_LINK_OPTIONS_PAUSE_RX);
+ if (fc & AQ_FC_TX)
+ v |= AQ2_FW_INTERFACE_IN_LINK_OPTIONS_PAUSE_TX;
+ if (fc & AQ_FC_RX)
+ v |= AQ2_FW_INTERFACE_IN_LINK_OPTIONS_PAUSE_RX;
+
+ if (speed == AQ_LINK_NONE) {
+ AQ_WRITE_REG_BIT(sc, AQ2_FW_INTERFACE_IN_LINK_CONTROL_REG,
+ AQ2_FW_INTERFACE_IN_LINK_CONTROL_MODE,
+ AQ2_FW_INTERFACE_IN_LINK_CONTROL_MODE_SHUTDOWN);
+ } else {
+ AQ_WRITE_REG_BIT(sc, AQ2_FW_INTERFACE_IN_LINK_CONTROL_REG,
+ AQ2_FW_INTERFACE_IN_LINK_CONTROL_MODE,
+ AQ2_FW_INTERFACE_IN_LINK_CONTROL_MODE_ACTIVE);
+ v |= AQ2_FW_INTERFACE_IN_LINK_OPTIONS_LINK_UP;
+ }
+
+ AQ_WRITE_REG(sc, AQ2_FW_INTERFACE_IN_LINK_OPTIONS_REG, v);
+ error = aq2_fw_wait_shared_ack(sc);
+
+ AQ_MPI_UNLOCK(sc);
+ return error;
+}
+
+int
+aq2_fw_get_mode(struct aq_softc *sc, enum aq_hw_fw_mpi_state *modep,
+ enum aq_link_speed *speedp, enum aq_link_fc *fcp, enum aq_link_eee *eeep)
+{
+ uint32_t v;
+ enum aq_link_speed speed;
+ enum aq_link_fc fc = 0;
+ enum aq_link_eee eee;
+
+ if (modep != NULL)
+ *modep = MPI_INIT;
+
+ v = AQ_READ_REG(sc, AQ2_FW_INTERFACE_OUT_LINK_STATUS_REG);
+ switch ((v & AQ2_FW_INTERFACE_OUT_LINK_STATUS_RATE) >>
+ AQ2_FW_INTERFACE_OUT_LINK_STATUS_RATE_S) {
+ case AQ2_FW_INTERFACE_OUT_LINK_STATUS_RATE_10G:
+ speed = AQ_LINK_10G;
+ break;
+ case AQ2_FW_INTERFACE_OUT_LINK_STATUS_RATE_5G:
+ speed = AQ_LINK_5G;
+ break;
+ case AQ2_FW_INTERFACE_OUT_LINK_STATUS_RATE_2G5:
+ speed = AQ_LINK_2G5;
+ break;
+ case AQ2_FW_INTERFACE_OUT_LINK_STATUS_RATE_1G:
+ speed = AQ_LINK_1G;
+ break;
+ case AQ2_FW_INTERFACE_OUT_LINK_STATUS_RATE_100M:
+ speed = AQ_LINK_100M;
+ break;
+ case AQ2_FW_INTERFACE_OUT_LINK_STATUS_RATE_10M:
+ speed = AQ_LINK_10M;
+ break;
+ case AQ2_FW_INTERFACE_OUT_LINK_STATUS_RATE_INVALID:
+ default:
+ speed = AQ_LINK_NONE;
+ break;
+ }
+ if (speedp != NULL)
+ *speedp = speed;
+
+ if (v & AQ2_FW_INTERFACE_OUT_LINK_STATUS_PAUSE_TX)
+ fc |= AQ_FC_TX;
+ if (v & AQ2_FW_INTERFACE_OUT_LINK_STATUS_PAUSE_RX)
+ fc |= AQ_FC_RX;
+ if (fcp != NULL)
+ *fcp = fc;
+
+ eee = (v & AQ2_FW_INTERFACE_OUT_LINK_STATUS_EEE) ?
+ AQ_EEE_ENABLE : AQ_EEE_DISABLE;
+ if (eeep != NULL)
+ *eeep = eee;
+
+ return 0;
+}
+
+int
+aq2_fw_get_stats(struct aq_softc *sc, struct aq_hw_stats_s *w)
+{
+ return 0;
+}
+
void
aq_hw_l3_filter_set(struct aq_softc *sc)
{
{
uint32_t v;
- /* Force limit MRRS on RDM/TDM to 2K */
- v = AQ_READ_REG(sc, AQ_PCI_REG_CONTROL_6_REG);
- AQ_WRITE_REG(sc, AQ_PCI_REG_CONTROL_6_REG, (v & ~0x0707) | 0x0404);
+ if (HWTYPE_AQ1_P(sc)) {
+ /* Force limit MRRS on RDM/TDM to 2K */
+ v = AQ_READ_REG(sc, AQ_PCI_REG_CONTROL_6_REG);
+ AQ_WRITE_REG(sc, AQ_PCI_REG_CONTROL_6_REG,
+ (v & ~0x0707) | 0x0404);
- /*
- * 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_WRITE_REG(sc, AQ_HW_TX_DMA_TOTAL_REQ_LIMIT_REG, 24);
+ /*
+ * 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_WRITE_REG(sc, AQ_HW_TX_DMA_TOTAL_REQ_LIMIT_REG, 24);
+ }
+
+ if (HWTYPE_AQ2_P(sc)) {
+ uint32_t fpgaver, speed;
+ fpgaver = AQ_READ_REG(sc, AQ2_HW_FPGA_VERSION_REG);
+ if (fpgaver < 0x01000000)
+ speed = AQ2_LAUNCHTIME_CTRL_RATIO_SPEED_FULL;
+ else if (fpgaver >= 0x01008502)
+ speed = AQ2_LAUNCHTIME_CTRL_RATIO_SPEED_HALF;
+ else
+ speed = AQ2_LAUNCHTIME_CTRL_RATIO_SPEED_QUARTER;
+ AQ_WRITE_REG_BIT(sc, AQ2_LAUNCHTIME_CTRL_REG,
+ AQ2_LAUNCHTIME_CTRL_RATIO, speed);
+ }
aq_hw_init_tx_path(sc);
aq_hw_init_rx_path(sc);
aq_hw_qos_set(sc);
+ if (HWTYPE_AQ2_P(sc)) {
+ AQ_WRITE_REG_BIT(sc, AQ2_RPF_NEW_CTRL_REG,
+ AQ2_RPF_NEW_CTRL_ENABLE, 1);
+ }
+
/* Enable interrupt */
AQ_WRITE_REG(sc, AQ_INTR_CTRL_REG, AQ_INTR_CTRL_RESET_DIS);
AQ_WRITE_REG_BIT(sc, AQ_INTR_CTRL_REG, AQ_INTR_CTRL_MULTIVEC, multivec);
AQ_WRITE_REG_BIT(sc, TDM_DCA_REG, TDM_DCA_MODE, 0);
AQ_WRITE_REG_BIT(sc, TPB_TX_BUF_REG, TPB_TX_BUF_SCP_INS_EN, 1);
+
+ if ((sc->sc_features & FEATURES_AQ1_REV_B) || HWTYPE_AQ2_P(sc)) {
+ AQ_WRITE_REG_BIT(sc, TPB_TX_BUF_REG, TPB_TX_BUF_CLK_GATE_EN, 0);
+ }
}
void
/* clear setting */
AQ_WRITE_REG_BIT(sc, RPB_RPF_RX_REG, RPB_RPF_RX_TC_MODE, 0);
AQ_WRITE_REG_BIT(sc, RPB_RPF_RX_REG, RPB_RPF_RX_FC_MODE, 0);
- AQ_WRITE_REG(sc, RX_FLR_RSS_CONTROL1_REG, 0);
- for (i = 0; i < 32; i++) {
- AQ_WRITE_REG_BIT(sc, RPF_ETHERTYPE_FILTER_REG(i),
- RPF_ETHERTYPE_FILTER_EN, 0);
+
+ if (HWTYPE_AQ2_P(sc)) {
+ AQ_WRITE_REG_BIT(sc, AQ2_RPF_REDIR2_REG,
+ AQ2_RPF_REDIR2_HASHTYPE, AQ2_RPF_REDIR2_HASHTYPE_ALL);
}
if (sc->sc_nqueues > 1) {
AQ_WRITE_REG(sc, RX_FLR_RSS_CONTROL1_REG,
RX_FLR_RSS_CONTROL1_EN | bits);
+ } else {
+ AQ_WRITE_REG(sc, RX_FLR_RSS_CONTROL1_REG, 0);
+ }
+
+ if (HWTYPE_AQ1_P(sc)) {
+ for (i = 0; i < 32; i++) {
+ AQ_WRITE_REG_BIT(sc, RPF_ETHERTYPE_FILTER_REG(i),
+ RPF_ETHERTYPE_FILTER_EN, 0);
+ }
}
/* L2 and Multicast filters */
ETHERTYPE_VLAN);
AQ_WRITE_REG_BIT(sc, RPF_VLAN_MODE_REG, RPF_VLAN_MODE_PROMISC, 1);
- if (sc->sc_features & FEATURES_AQ1_REV_B) {
+ if ((sc->sc_features & FEATURES_AQ1_REV_B) || HWTYPE_AQ2_P(sc)) {
AQ_WRITE_REG_BIT(sc, RPF_VLAN_MODE_REG,
RPF_VLAN_MODE_ACCEPT_UNTAGGED, 1);
AQ_WRITE_REG_BIT(sc, RPF_VLAN_MODE_REG,
RPF_VLAN_MODE_UNTAGGED_ACTION, RPF_ACTION_HOST);
}
- if (sc->sc_features & FEATURES_RPF2)
- AQ_WRITE_REG(sc, RX_TCP_RSS_HASH_REG, RX_TCP_RSS_HASH_RPF2);
- else
- AQ_WRITE_REG(sc, RX_TCP_RSS_HASH_REG, 0);
+ if (HWTYPE_AQ2_P(sc)) {
+ AQ_WRITE_REG_BIT(sc, AQ2_RPF_REC_TAB_ENABLE_REG,
+ AQ2_RPF_REC_TAB_ENABLE_MASK, 0xffff);
+ AQ_WRITE_REG_BIT(sc, RPF_L2UC_MSW_REG(0),
+ RPF_L2UC_MSW_TAG, 1);
+ AQ_WRITE_REG_BIT(sc, AQ2_RPF_L2BC_TAG_REG,
+ AQ2_RPF_L2BC_TAG_MASK, 1);
+
+ aq2_filter_art_set(sc, AQ2_RPF_INDEX_L2_PROMISC_OFF,
+ 0, AQ2_RPF_TAG_UC_MASK | AQ2_RPF_TAG_ALLMC_MASK,
+ AQ2_ART_ACTION_DROP);
+ aq2_filter_art_set(sc, AQ2_RPF_INDEX_VLAN_PROMISC_OFF,
+ 0, AQ2_RPF_TAG_VLAN_MASK | AQ2_RPF_TAG_UNTAG_MASK,
+ AQ2_ART_ACTION_DROP);
+
+ for (int i = 0; i < 8; i++) {
+ aq2_filter_art_set(sc, AQ2_RPF_INDEX_PCP_TO_TC + i,
+ (i << AQ2_RPF_TAG_PCP_SHIFT), AQ2_RPF_TAG_PCP_MASK,
+ AQ2_ART_ACTION_ASSIGN_TC(i % sc->sc_nqueues));
+ }
- /* we might want to figure out what this magic number does */
- AQ_WRITE_REG_BIT(sc, RX_TCP_RSS_HASH_REG, RX_TCP_RSS_HASH_TYPE,
- 0x001e);
+ } else if (HWTYPE_AQ1_P(sc)) {
+ if (sc->sc_features & FEATURES_RPF2)
+ AQ_WRITE_REG(sc, RX_TCP_RSS_HASH_REG,
+ RX_TCP_RSS_HASH_RPF2);
+ else
+ AQ_WRITE_REG(sc, RX_TCP_RSS_HASH_REG, 0);
+
+ /* we might want to figure out what this magic number does */
+ AQ_WRITE_REG_BIT(sc, RX_TCP_RSS_HASH_REG,
+ RX_TCP_RSS_HASH_TYPE, 0x001e);
+ }
AQ_WRITE_REG_BIT(sc, RPF_L2BC_REG, RPF_L2BC_EN, 1);
AQ_WRITE_REG_BIT(sc, RPF_L2BC_REG, RPF_L2BC_ACTION, RPF_ACTION_HOST);
AQ_WRITE_REG(sc, RPF_L2UC_LSW_REG(index), l);
AQ_WRITE_REG_BIT(sc, RPF_L2UC_MSW_REG(index),
RPF_L2UC_MSW_MACADDR_HI, h);
- AQ_WRITE_REG_BIT(sc, RPF_L2UC_MSW_REG(index), RPF_L2UC_MSW_ACTION, 1);
+ AQ_WRITE_REG_BIT(sc, RPF_L2UC_MSW_REG(index),
+ RPF_L2UC_MSW_ACTION, RPF_ACTION_HOST);
+ if (HWTYPE_AQ2_P(sc))
+ AQ_WRITE_REG_BIT(sc, RPF_L2UC_MSW_REG(index),
+ RPF_L2UC_MSW_TAG, 1);
AQ_WRITE_REG_BIT(sc, RPF_L2UC_MSW_REG(index), RPF_L2UC_MSW_EN, 1);
return 0;
case AQ_LINK_100M:
media = IFM_100_TX;
break;
+ case AQ_LINK_10M:
+ media = IFM_10_T;
+ break;
case AQ_LINK_NONE:
media = 0;
break;
case IFM_NONE:
rate = AQ_LINK_NONE;
break;
+ case IFM_10_T:
+ rate = AQ_LINK_10M;
+ break;
case IFM_100_TX:
rate = AQ_LINK_100M;
break;
return error;
}
+int
+aq2_filter_art_set(struct aq_softc *sc, uint32_t idx,
+ uint32_t tag, uint32_t mask, uint32_t action)
+{
+ int error;
+
+ AQ_MPI_LOCK(sc);
+
+ WAIT_FOR(AQ_READ_REG(sc, AQ2_ART_SEM_REG) == 1, 10, 1000, &error);
+ if (error != 0) {
+ printf("%s: AQ2_ART_SEM_REG timeout\n", DEVNAME(sc));
+ goto out;
+ }
+
+ idx += sc->sc_art_filter_base_index;
+ AQ_WRITE_REG(sc, AQ2_RPF_ACT_ART_REQ_TAG_REG(idx), tag);
+ AQ_WRITE_REG(sc, AQ2_RPF_ACT_ART_REQ_MASK_REG(idx), mask);
+ AQ_WRITE_REG(sc, AQ2_RPF_ACT_ART_REQ_ACTION_REG(idx), action);
+
+ AQ_WRITE_REG(sc, AQ2_ART_SEM_REG, 1);
+
+ out:
+ AQ_MPI_UNLOCK(sc);
+ return error;
+}
+
void
aq_iff(struct aq_softc *sc)
{
struct arpcom *ac = &sc->sc_arpcom;
struct ether_multi *enm;
struct ether_multistep step;
+ uint32_t action;
int idx;
+ if (HWTYPE_AQ2_P(sc)) {
+ action = (ifp->if_flags & IFF_PROMISC) ?
+ AQ2_ART_ACTION_DISABLE : AQ2_ART_ACTION_DROP;
+ aq2_filter_art_set(sc, AQ2_RPF_INDEX_L2_PROMISC_OFF, 0,
+ AQ2_RPF_TAG_UC_MASK | AQ2_RPF_TAG_ALLMC_MASK, action);
+ aq2_filter_art_set(sc, AQ2_RPF_INDEX_VLAN_PROMISC_OFF, 0,
+ AQ2_RPF_TAG_VLAN_MASK | AQ2_RPF_TAG_UNTAG_MASK, action);
+ }
+
if (ifp->if_flags & IFF_PROMISC) {
ifp->if_flags |= IFF_ALLMULTI;
AQ_WRITE_REG_BIT(sc, RPF_L2BC_REG, RPF_L2BC_PROMISC, 1);