summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sys/dev/fdt/files.fdt8
-rw-r--r--sys/dev/fdt/if_mvpp.c4122
-rw-r--r--sys/dev/fdt/if_mvppreg.h2077
3 files changed, 6206 insertions, 1 deletions
diff --git a/sys/dev/fdt/files.fdt b/sys/dev/fdt/files.fdt
index 8e516ff8b67..d1bfe1e2959 100644
--- a/sys/dev/fdt/files.fdt
+++ b/sys/dev/fdt/files.fdt
@@ -1,4 +1,4 @@
-# $OpenBSD: files.fdt,v 1.140 2020/06/20 18:13:18 kettenis Exp $
+# $OpenBSD: files.fdt,v 1.141 2020/06/25 12:09:11 patrick Exp $
#
# Config file and device description for machine-independent FDT code.
# Included by ports that need it.
@@ -406,6 +406,12 @@ device mvneta: ether, ifnet, mii, ifmedia
attach mvneta at fdt
file dev/fdt/if_mvneta.c mvneta
+device mvppc {}
+attach mvppc at fdt
+device mvpp: ether, ifnet, mii, ifmedia
+attach mvpp at mvppc
+file dev/fdt/if_mvpp.c mvppc | mvpp
+
device mvrng
attach mvrng at fdt
file dev/fdt/mvrng.c mvrng
diff --git a/sys/dev/fdt/if_mvpp.c b/sys/dev/fdt/if_mvpp.c
new file mode 100644
index 00000000000..f48d17188e3
--- /dev/null
+++ b/sys/dev/fdt/if_mvpp.c
@@ -0,0 +1,4122 @@
+/* $OpenBSD: if_mvpp.c,v 1.1 2020/06/25 12:09:11 patrick Exp $ */
+/*
+ * Copyright (c) 2008, 2019 Mark Kettenis <kettenis@openbsd.org>
+ * Copyright (c) 2017, 2020 Patrick Wildt <patrick@blueri.se>
+ *
+ * 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.
+ */
+/*
+ * Copyright (C) 2016 Marvell International Ltd.
+ *
+ * Marvell BSD License Option
+ *
+ * If you received this File from Marvell, you may opt to use, redistribute
+ * and/or modify this File under the following licensing terms.
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * * Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * * Neither the name of Marvell nor the names of its contributors may be
+ * used to endorse or promote products derived from this software without
+ * specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "bpfilter.h"
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/device.h>
+#include <sys/kernel.h>
+#include <sys/malloc.h>
+#include <sys/mbuf.h>
+#include <sys/queue.h>
+#include <sys/socket.h>
+#include <sys/sockio.h>
+#include <sys/timeout.h>
+
+#include <machine/bus.h>
+#include <machine/fdt.h>
+
+#include <net/if.h>
+#include <net/if_media.h>
+
+#include <dev/ofw/openfirm.h>
+#include <dev/ofw/ofw_clock.h>
+#include <dev/ofw/ofw_gpio.h>
+#include <dev/ofw/ofw_misc.h>
+#include <dev/ofw/ofw_pinctrl.h>
+#include <dev/ofw/ofw_regulator.h>
+#include <dev/ofw/fdt.h>
+
+#include <dev/mii/mii.h>
+#include <dev/mii/miivar.h>
+
+#if NBPFILTER > 0
+#include <net/bpf.h>
+#endif
+
+#include <netinet/in.h>
+#include <netinet/ip.h>
+#include <netinet/if_ether.h>
+
+#include <netinet6/in6_var.h>
+#include <netinet/ip6.h>
+
+#include <dev/fdt/if_mvppreg.h>
+
+struct mvpp2_buf {
+ bus_dmamap_t mb_map;
+ struct mbuf *mb_m;
+};
+
+#define MVPP2_NTXDESC 512
+#define MVPP2_NTXSEGS 16
+#define MVPP2_NRXDESC 512
+
+struct mvpp2_bm_pool {
+ struct mvpp2_dmamem *bm_mem;
+ struct mvpp2_buf *rxbuf;
+};
+
+#define MVPP2_BM_SIZE 64
+#define MVPP2_BM_POOL_PTR_ALIGN 128
+#define MVPP2_BM_POOLS_NUM 8
+#define MVPP2_BM_ALIGN 32
+#define MVPP2_MAX_PORT 3
+
+struct mvpp2_tx_queue {
+ uint8_t id;
+ uint8_t log_id;
+ struct mvpp2_dmamem *ring;
+ struct mvpp2_buf *buf;
+ struct mvpp2_tx_desc *descs;
+ int prod;
+ int cnt;
+ int cons;
+
+ uint32_t done_pkts_coal;
+};
+
+struct mvpp2_rx_queue {
+ uint8_t id;
+ struct mvpp2_dmamem *ring;
+ struct mvpp2_rx_desc *descs;
+ int prod;
+ struct if_rxring rxring;
+ int cons;
+
+ uint32_t pkts_coal;
+ uint32_t time_coal;
+};
+
+struct mvpp2_dmamem {
+ bus_dmamap_t mdm_map;
+ bus_dma_segment_t mdm_seg;
+ size_t mdm_size;
+ caddr_t mdm_kva;
+};
+#define MVPP2_DMA_MAP(_mdm) ((_mdm)->mdm_map)
+#define MVPP2_DMA_LEN(_mdm) ((_mdm)->mdm_size)
+#define MVPP2_DMA_DVA(_mdm) ((_mdm)->mdm_map->dm_segs[0].ds_addr)
+#define MVPP2_DMA_KVA(_mdm) ((void *)(_mdm)->mdm_kva)
+
+struct mvpp2_port;
+struct mvpp2_softc {
+ struct device sc_dev;
+ int sc_node;
+ bus_space_tag_t sc_iot;
+ bus_space_handle_t sc_ioh_base;
+ bus_space_handle_t sc_ioh_iface;
+ bus_size_t sc_iosize_base;
+ bus_size_t sc_iosize_iface;
+ bus_dma_tag_t sc_dmat;
+
+ uint32_t sc_tclk;
+
+ struct mvpp2_bm_pool sc_bm_pools[MVPP2_MAX_PORT];
+
+ struct mvpp2_prs_shadow *sc_prs_shadow;
+ uint8_t *sc_prs_double_vlans;
+
+ int sc_aggr_ntxq;
+ struct mvpp2_tx_queue *sc_aggr_txqs;
+
+ struct mvpp2_port **sc_ports;
+};
+
+struct mvpp2_port {
+ struct device sc_dev;
+ struct mvpp2_softc *sc;
+ int sc_node;
+ bus_dma_tag_t sc_dmat;
+ int sc_id;
+ int sc_gop_id;
+
+ struct arpcom sc_ac;
+#define sc_lladdr sc_ac.ac_enaddr
+ struct mii_data sc_mii;
+#define sc_media sc_mii.mii_media
+ struct mii_device *sc_mdio;
+ char sc_cur_lladdr[ETHER_ADDR_LEN];
+
+ enum {
+ PHY_MODE_XAUI,
+ PHY_MODE_10GBASER,
+ PHY_MODE_2500BASEX,
+ PHY_MODE_1000BASEX,
+ PHY_MODE_SGMII,
+ PHY_MODE_RGMII,
+ PHY_MODE_RGMII_ID,
+ PHY_MODE_RGMII_RXID,
+ PHY_MODE_RGMII_TXID,
+ } sc_phy_mode;
+ int sc_fixed_link;
+ int sc_inband_status;
+ int sc_link;
+ int sc_phyloc;
+ int sc_sfp;
+
+ int sc_ntxq;
+ int sc_nrxq;
+
+ struct mvpp2_tx_queue *sc_txqs;
+ struct mvpp2_rx_queue *sc_rxqs;
+
+ struct timeout sc_tick;
+
+ uint32_t sc_tx_time_coal;
+};
+
+#define MVPP2_MAX_PORTS 4
+
+struct mvpp2_attach_args {
+ int ma_node;
+ bus_dma_tag_t ma_dmat;
+};
+
+#define DEVNAME(_s) ((_s)->sc_dev.dv_xname)
+
+static struct rwlock mvpp2_sff_lock = RWLOCK_INITIALIZER("mvpp2sff");
+
+int mvpp2_match(struct device *, void *, void *);
+void mvpp2_attach(struct device *, struct device *, void *);
+void mvpp2_attach_deferred(struct device *);
+
+struct cfattach mvppc_ca = {
+ sizeof(struct mvpp2_softc), mvpp2_match, mvpp2_attach
+};
+
+struct cfdriver mvppc_cd = {
+ NULL, "mvppc", DV_DULL
+};
+
+int mvpp2_port_match(struct device *, void *, void *);
+void mvpp2_port_attach(struct device *, struct device *, void *);
+
+struct cfattach mvpp_ca = {
+ sizeof(struct mvpp2_port), mvpp2_port_match, mvpp2_port_attach
+};
+
+struct cfdriver mvpp_cd = {
+ NULL, "mvpp", DV_IFNET
+};
+
+uint32_t mvpp2_read(struct mvpp2_softc *, bus_addr_t);
+void mvpp2_write(struct mvpp2_softc *, bus_addr_t, uint32_t);
+uint32_t mvpp2_gmac_read(struct mvpp2_port *, bus_addr_t);
+void mvpp2_gmac_write(struct mvpp2_port *, bus_addr_t, uint32_t);
+uint32_t mvpp2_xlg_read(struct mvpp2_port *, bus_addr_t);
+void mvpp2_xlg_write(struct mvpp2_port *, bus_addr_t, uint32_t);
+uint32_t mvpp2_xpcs_read(struct mvpp2_port *, bus_addr_t);
+void mvpp2_xpcs_write(struct mvpp2_port *, bus_addr_t, uint32_t);
+uint32_t mvpp2_mpcs_read(struct mvpp2_port *, bus_addr_t);
+void mvpp2_mpcs_write(struct mvpp2_port *, bus_addr_t, uint32_t);
+
+int mvpp2_ioctl(struct ifnet *, u_long, caddr_t);
+void mvpp2_start(struct ifnet *);
+int mvpp2_rxrinfo(struct mvpp2_port *, struct if_rxrinfo *);
+void mvpp2_watchdog(struct ifnet *);
+
+int mvpp2_media_change(struct ifnet *);
+void mvpp2_media_status(struct ifnet *, struct ifmediareq *);
+
+int mvpp2_mii_readreg(struct device *, int, int);
+void mvpp2_mii_writereg(struct device *, int, int, int);
+void mvpp2_mii_statchg(struct device *);
+void mvpp2_inband_statchg(struct mvpp2_port *);
+void mvpp2_port_change(struct mvpp2_port *);
+
+void mvpp2_tick(void *);
+void mvpp2_rxtick(void *);
+
+int mvpp2_link_intr(void *);
+int mvpp2_intr(void *);
+void mvpp2_tx_proc(struct mvpp2_port *, uint8_t);
+void mvpp2_rx_proc(struct mvpp2_port *, uint8_t);
+void mvpp2_rxq_proc(struct mvpp2_port *, struct mvpp2_rx_queue *);
+
+void mvpp2_up(struct mvpp2_port *);
+void mvpp2_down(struct mvpp2_port *);
+void mvpp2_iff(struct mvpp2_port *);
+int mvpp2_encap(struct mvpp2_port *, struct mbuf *, int *);
+
+void mvpp2_aggr_txq_hw_init(struct mvpp2_softc *, struct mvpp2_tx_queue *);
+void mvpp2_txq_hw_init(struct mvpp2_port *, struct mvpp2_tx_queue *);
+void mvpp2_rxq_hw_init(struct mvpp2_port *, struct mvpp2_rx_queue *);
+void mvpp2_txq_hw_deinit(struct mvpp2_port *, struct mvpp2_tx_queue *);
+void mvpp2_rxq_hw_deinit(struct mvpp2_port *, struct mvpp2_rx_queue *);
+void mvpp2_rxq_long_pool_set(struct mvpp2_port *, int, int);
+void mvpp2_rxq_short_pool_set(struct mvpp2_port *, int, int);
+
+void mvpp2_mac_config(struct mvpp2_port *);
+void mvpp2_xlg_config(struct mvpp2_port *);
+void mvpp2_gmac_config(struct mvpp2_port *);
+
+struct mvpp2_dmamem *
+ mvpp2_dmamem_alloc(struct mvpp2_softc *, bus_size_t, bus_size_t);
+void mvpp2_dmamem_free(struct mvpp2_softc *, struct mvpp2_dmamem *);
+struct mbuf *mvpp2_alloc_mbuf(struct mvpp2_softc *, bus_dmamap_t);
+void mvpp2_fill_rx_ring(struct mvpp2_softc *);
+
+void mvpp2_interrupts_enable(struct mvpp2_port *, int);
+void mvpp2_interrupts_disable(struct mvpp2_port *, int);
+int mvpp2_egress_port(struct mvpp2_port *);
+int mvpp2_txq_phys(int, int);
+void mvpp2_defaults_set(struct mvpp2_port *);
+void mvpp2_ingress_enable(struct mvpp2_port *);
+void mvpp2_ingress_disable(struct mvpp2_port *);
+void mvpp2_egress_enable(struct mvpp2_port *);
+void mvpp2_egress_disable(struct mvpp2_port *);
+void mvpp2_port_enable(struct mvpp2_port *);
+void mvpp2_port_disable(struct mvpp2_port *);
+void mvpp2_rxq_status_update(struct mvpp2_port *, int, int, int);
+int mvpp2_rxq_received(struct mvpp2_port *, int);
+void mvpp2_rxq_offset_set(struct mvpp2_port *, int, int);
+void mvpp2_txp_max_tx_size_set(struct mvpp2_port *);
+void mvpp2_rx_pkts_coal_set(struct mvpp2_port *, struct mvpp2_rx_queue *,
+ uint32_t);
+void mvpp2_tx_pkts_coal_set(struct mvpp2_port *, struct mvpp2_tx_queue *,
+ uint32_t);
+void mvpp2_rx_time_coal_set(struct mvpp2_port *, struct mvpp2_rx_queue *,
+ uint32_t);
+void mvpp2_tx_time_coal_set(struct mvpp2_port *, uint32_t);
+
+void mvpp2_axi_config(struct mvpp2_softc *);
+void mvpp2_bm_pool_init(struct mvpp2_softc *);
+void mvpp2_rx_fifo_init(struct mvpp2_softc *);
+void mvpp2_tx_fifo_init(struct mvpp2_softc *);
+int mvpp2_prs_default_init(struct mvpp2_softc *);
+void mvpp2_prs_hw_inv(struct mvpp2_softc *, int);
+void mvpp2_prs_hw_port_init(struct mvpp2_softc *, int, int, int, int);
+void mvpp2_prs_def_flow_init(struct mvpp2_softc *);
+void mvpp2_prs_mh_init(struct mvpp2_softc *);
+void mvpp2_prs_mac_init(struct mvpp2_softc *);
+void mvpp2_prs_dsa_init(struct mvpp2_softc *);
+int mvpp2_prs_etype_init(struct mvpp2_softc *);
+int mvpp2_prs_vlan_init(struct mvpp2_softc *);
+int mvpp2_prs_pppoe_init(struct mvpp2_softc *);
+int mvpp2_prs_ip6_init(struct mvpp2_softc *);
+int mvpp2_prs_ip4_init(struct mvpp2_softc *);
+void mvpp2_prs_shadow_ri_set(struct mvpp2_softc *, int,
+ uint32_t, uint32_t);
+void mvpp2_prs_tcam_lu_set(struct mvpp2_prs_entry *, uint32_t);
+void mvpp2_prs_tcam_port_set(struct mvpp2_prs_entry *, uint32_t, int);
+void mvpp2_prs_tcam_port_map_set(struct mvpp2_prs_entry *, uint32_t);
+uint32_t mvpp2_prs_tcam_port_map_get(struct mvpp2_prs_entry *);
+void mvpp2_prs_tcam_data_byte_set(struct mvpp2_prs_entry *, uint32_t,
+ uint8_t, uint8_t);
+void mvpp2_prs_tcam_data_byte_get(struct mvpp2_prs_entry *, uint32_t,
+ uint8_t *, uint8_t *);
+int mvpp2_prs_tcam_data_cmp(struct mvpp2_prs_entry *, int, uint16_t);
+void mvpp2_prs_tcam_ai_update(struct mvpp2_prs_entry *, uint32_t, uint32_t);
+int mvpp2_prs_sram_ai_get(struct mvpp2_prs_entry *);
+int mvpp2_prs_tcam_ai_get(struct mvpp2_prs_entry *);
+void mvpp2_prs_tcam_data_word_get(struct mvpp2_prs_entry *, uint32_t,
+ uint32_t *, uint32_t *);
+void mvpp2_prs_match_etype(struct mvpp2_prs_entry *, uint32_t, uint16_t);
+int mvpp2_prs_sram_ri_get(struct mvpp2_prs_entry *);
+void mvpp2_prs_sram_ai_update(struct mvpp2_prs_entry *, uint32_t, uint32_t);
+void mvpp2_prs_sram_ri_update(struct mvpp2_prs_entry *, uint32_t, uint32_t);
+void mvpp2_prs_sram_bits_set(struct mvpp2_prs_entry *, uint32_t, uint32_t);
+void mvpp2_prs_sram_bits_clear(struct mvpp2_prs_entry *, uint32_t, uint32_t);
+void mvpp2_prs_sram_shift_set(struct mvpp2_prs_entry *, int, uint32_t);
+void mvpp2_prs_sram_offset_set(struct mvpp2_prs_entry *, uint32_t, int,
+ uint32_t);
+void mvpp2_prs_sram_next_lu_set(struct mvpp2_prs_entry *, uint32_t);
+void mvpp2_prs_shadow_set(struct mvpp2_softc *, int, uint32_t);
+int mvpp2_prs_hw_write(struct mvpp2_softc *, struct mvpp2_prs_entry *);
+int mvpp2_prs_hw_read(struct mvpp2_softc *, struct mvpp2_prs_entry *);
+struct mvpp2_prs_entry *mvpp2_prs_flow_find(struct mvpp2_softc *, int);
+int mvpp2_prs_tcam_first_free(struct mvpp2_softc *, uint8_t, uint8_t);
+void mvpp2_prs_mac_drop_all_set(struct mvpp2_softc *, uint32_t, int);
+void mvpp2_prs_mac_promisc_set(struct mvpp2_softc *, uint32_t, int);
+void mvpp2_prs_mac_multi_set(struct mvpp2_softc *, uint32_t, uint32_t, int);
+void mvpp2_prs_dsa_tag_set(struct mvpp2_softc *, uint32_t, int, int, int);
+void mvpp2_prs_dsa_tag_ethertype_set(struct mvpp2_softc *, uint32_t,
+ int, int, int);
+struct mvpp2_prs_entry *mvpp2_prs_vlan_find(struct mvpp2_softc *, uint16_t,
+ int);
+int mvpp2_prs_vlan_add(struct mvpp2_softc *, uint16_t, int, uint32_t);
+int mvpp2_prs_double_vlan_ai_free_get(struct mvpp2_softc *);
+struct mvpp2_prs_entry *mvpp2_prs_double_vlan_find(struct mvpp2_softc *,
+ uint16_t, uint16_t);
+int mvpp2_prs_double_vlan_add(struct mvpp2_softc *, uint16_t, uint16_t,
+ uint32_t);
+int mvpp2_prs_ip4_proto(struct mvpp2_softc *, uint16_t, uint32_t, uint32_t);
+int mvpp2_prs_ip4_cast(struct mvpp2_softc *, uint16_t);
+int mvpp2_prs_ip6_proto(struct mvpp2_softc *, uint16_t, uint32_t, uint32_t);
+int mvpp2_prs_ip6_cast(struct mvpp2_softc *, uint16_t);
+struct mvpp2_prs_entry *mvpp2_prs_mac_da_range_find(struct mvpp2_softc *, int,
+ const uint8_t *, uint8_t *, int);
+int mvpp2_prs_mac_range_equals(struct mvpp2_prs_entry *, const uint8_t *,
+ uint8_t *);
+int mvpp2_prs_mac_da_accept(struct mvpp2_softc *, int, const uint8_t *, int);
+int mvpp2_prs_tag_mode_set(struct mvpp2_softc *, int, int);
+int mvpp2_prs_def_flow(struct mvpp2_port *);
+void mvpp2_cls_flow_write(struct mvpp2_softc *, struct mvpp2_cls_flow_entry *);
+void mvpp2_cls_lookup_write(struct mvpp2_softc *, struct mvpp2_cls_lookup_entry *);
+void mvpp2_cls_init(struct mvpp2_softc *);
+void mvpp2_cls_port_config(struct mvpp2_port *);
+void mvpp2_cls_oversize_rxq_set(struct mvpp2_port *);
+
+int
+mvpp2_match(struct device *parent, void *cfdata, void *aux)
+{
+ struct fdt_attach_args *faa = aux;
+
+ return OF_is_compatible(faa->fa_node, "marvell,armada-7k-pp22");
+}
+
+void
+mvpp2_attach(struct device *parent, struct device *self, void *aux)
+{
+ struct mvpp2_softc *sc = (void *)self;
+ struct fdt_attach_args *faa = aux;
+
+ if (faa->fa_nreg < 2) {
+ printf(": no registers\n");
+ return;
+ }
+
+ sc->sc_node = faa->fa_node;
+ sc->sc_iot = faa->fa_iot;
+ sc->sc_dmat = faa->fa_dmat;
+
+ if (bus_space_map(sc->sc_iot, faa->fa_reg[0].addr,
+ faa->fa_reg[0].size, 0, &sc->sc_ioh_base)) {
+ printf(": can't map registers\n");
+ return;
+ }
+ sc->sc_iosize_base = faa->fa_reg[0].size;
+
+ if (bus_space_map(sc->sc_iot, faa->fa_reg[1].addr,
+ faa->fa_reg[1].size, 0, &sc->sc_ioh_iface)) {
+ printf(": can't map registers\n");
+ bus_space_unmap(sc->sc_iot, sc->sc_ioh_base,
+ sc->sc_iosize_base);
+ return;
+ }
+ sc->sc_iosize_iface = faa->fa_reg[1].size;
+
+ clock_enable_all(faa->fa_node);
+ sc->sc_tclk = clock_get_frequency(faa->fa_node, "pp_clk");
+
+ printf("\n");
+
+ config_defer(self, mvpp2_attach_deferred);
+}
+
+void
+mvpp2_attach_deferred(struct device *self)
+{
+ struct mvpp2_softc *sc = (void *)self;
+ struct mvpp2_attach_args maa;
+ struct mvpp2_tx_queue *txq;
+ int i, node;
+
+ mvpp2_axi_config(sc);
+
+ sc->sc_aggr_ntxq = 1;
+ sc->sc_aggr_txqs = mallocarray(sc->sc_aggr_ntxq,
+ sizeof(*sc->sc_aggr_txqs), M_DEVBUF, M_WAITOK | M_ZERO);
+
+ for (i = 0; i < sc->sc_aggr_ntxq; i++) {
+ txq = &sc->sc_aggr_txqs[i];
+ txq->id = i;
+ mvpp2_aggr_txq_hw_init(sc, txq);
+ }
+
+ mvpp2_rx_fifo_init(sc);
+ mvpp2_tx_fifo_init(sc);
+
+ mvpp2_write(sc, MVPP2_TX_SNOOP_REG, 0x1);
+
+ mvpp2_bm_pool_init(sc);
+
+ sc->sc_prs_shadow = mallocarray(MVPP2_PRS_TCAM_SRAM_SIZE,
+ sizeof(*sc->sc_prs_shadow), M_DEVBUF, M_WAITOK | M_ZERO);
+
+ mvpp2_prs_default_init(sc);
+ mvpp2_cls_init(sc);
+
+ memset(&maa, 0, sizeof(maa));
+ for (node = OF_child(sc->sc_node); node; node = OF_peer(node)) {
+ maa.ma_node = node;
+ maa.ma_dmat = sc->sc_dmat;
+ config_found(self, &maa, NULL);
+ }
+}
+
+void
+mvpp2_axi_config(struct mvpp2_softc *sc)
+{
+ uint32_t reg;
+
+ mvpp2_write(sc, MVPP22_BM_PHY_VIRT_HIGH_RLS_REG, 0);
+
+ reg = (MVPP22_AXI_CODE_CACHE_WR_CACHE << MVPP22_AXI_ATTR_CACHE_OFFS) |
+ (MVPP22_AXI_CODE_DOMAIN_OUTER_DOM << MVPP22_AXI_ATTR_DOMAIN_OFFS);
+ mvpp2_write(sc, MVPP22_AXI_BM_WR_ATTR_REG, reg);
+ mvpp2_write(sc, MVPP22_AXI_TXQ_DESCR_WR_ATTR_REG, reg);
+ mvpp2_write(sc, MVPP22_AXI_RXQ_DESCR_WR_ATTR_REG, reg);
+ mvpp2_write(sc, MVPP22_AXI_RX_DATA_WR_ATTR_REG, reg);
+
+ reg = (MVPP22_AXI_CODE_CACHE_RD_CACHE << MVPP22_AXI_ATTR_CACHE_OFFS) |
+ (MVPP22_AXI_CODE_DOMAIN_OUTER_DOM << MVPP22_AXI_ATTR_DOMAIN_OFFS);
+ mvpp2_write(sc, MVPP22_AXI_BM_RD_ATTR_REG, reg);
+ mvpp2_write(sc, MVPP22_AXI_AGGRQ_DESCR_RD_ATTR_REG, reg);
+ mvpp2_write(sc, MVPP22_AXI_TXQ_DESCR_RD_ATTR_REG, reg);
+ mvpp2_write(sc, MVPP22_AXI_TX_DATA_RD_ATTR_REG, reg);
+
+ reg = (MVPP22_AXI_CODE_CACHE_NON_CACHE << MVPP22_AXI_CODE_CACHE_OFFS) |
+ (MVPP22_AXI_CODE_DOMAIN_SYSTEM << MVPP22_AXI_CODE_DOMAIN_OFFS);
+ mvpp2_write(sc, MVPP22_AXI_RD_NORMAL_CODE_REG, reg);
+ mvpp2_write(sc, MVPP22_AXI_WR_NORMAL_CODE_REG, reg);
+
+ reg = (MVPP22_AXI_CODE_CACHE_RD_CACHE << MVPP22_AXI_CODE_CACHE_OFFS) |
+ (MVPP22_AXI_CODE_DOMAIN_OUTER_DOM << MVPP22_AXI_CODE_DOMAIN_OFFS);
+ mvpp2_write(sc, MVPP22_AXI_RD_SNOOP_CODE_REG, reg);
+
+ reg = (MVPP22_AXI_CODE_CACHE_WR_CACHE << MVPP22_AXI_CODE_CACHE_OFFS) |
+ (MVPP22_AXI_CODE_DOMAIN_OUTER_DOM << MVPP22_AXI_CODE_DOMAIN_OFFS);
+ mvpp2_write(sc, MVPP22_AXI_WR_SNOOP_CODE_REG, reg);
+}
+
+void
+mvpp2_bm_pool_init(struct mvpp2_softc *sc)
+{
+ struct mvpp2_bm_pool *bm;
+ struct mvpp2_buf *rxb;
+ uint64_t phys, virt;
+ int i, j;
+
+ for (i = 0; i < MVPP2_BM_POOLS_NUM; i++) {
+ mvpp2_write(sc, MVPP2_BM_INTR_MASK_REG(i), 0);
+ mvpp2_write(sc, MVPP2_BM_INTR_CAUSE_REG(i), 0);
+ }
+
+ for (i = 0; i < MVPP2_MAX_PORT; i++) {
+ bm = &sc->sc_bm_pools[i];
+ bm->bm_mem = mvpp2_dmamem_alloc(sc,
+ MVPP2_BM_SIZE * sizeof(uint64_t) * 2,
+ MVPP2_BM_POOL_PTR_ALIGN);
+ memset(MVPP2_DMA_KVA(bm->bm_mem), 0, MVPP2_DMA_LEN(bm->bm_mem));
+ bus_dmamap_sync(sc->sc_dmat, MVPP2_DMA_MAP(bm->bm_mem), 0,
+ MVPP2_DMA_LEN(bm->bm_mem),
+ BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
+
+ mvpp2_write(sc, MVPP2_BM_POOL_BASE_REG(i),
+ (uint64_t)MVPP2_DMA_KVA(bm->bm_mem) & 0xffffffff);
+ mvpp2_write(sc, MVPP22_BM_POOL_BASE_HIGH_REG,
+ ((uint64_t)MVPP2_DMA_KVA(bm->bm_mem) >> 32)
+ & MVPP22_BM_POOL_BASE_HIGH_MASK);
+ mvpp2_write(sc, MVPP2_BM_POOL_SIZE_REG(i),
+ MVPP2_BM_SIZE);
+
+ mvpp2_write(sc, MVPP2_BM_POOL_CTRL_REG(i),
+ mvpp2_read(sc, MVPP2_BM_POOL_CTRL_REG(i)) |
+ MVPP2_BM_START_MASK);
+
+ mvpp2_write(sc, MVPP2_POOL_BUF_SIZE_REG(i),
+ roundup(MCLBYTES, 1 << MVPP2_POOL_BUF_SIZE_OFFSET));
+
+ bm->rxbuf = mallocarray(MVPP2_BM_SIZE, sizeof(struct mvpp2_buf),
+ M_DEVBUF, M_WAITOK);
+
+ for (j = 0; j < MVPP2_BM_SIZE; j++) {
+ rxb = &bm->rxbuf[j];
+ bus_dmamap_create(sc->sc_dmat, MCLBYTES, 1,
+ MCLBYTES, 0, BUS_DMA_WAITOK, &rxb->mb_map);
+ }
+
+ for (j = 0; j < MVPP2_BM_SIZE; j++) {
+ rxb = &bm->rxbuf[j];
+ rxb->mb_m = mvpp2_alloc_mbuf(sc, rxb->mb_map);
+ if (rxb->mb_m == NULL)
+ break;
+ virt = (i << 16) | (j << 0); /* XXX use cookie? */
+ phys = rxb->mb_map->dm_segs[0].ds_addr;
+ mvpp2_write(sc, MVPP22_BM_PHY_VIRT_HIGH_RLS_REG,
+ (((virt >> 32) & MVPP22_ADDR_HIGH_MASK)
+ << MVPP22_BM_VIRT_HIGH_RLS_OFFST) |
+ (((phys >> 32) & MVPP22_ADDR_HIGH_MASK)
+ << MVPP22_BM_PHY_HIGH_RLS_OFFSET));
+ mvpp2_write(sc, MVPP2_BM_VIRT_RLS_REG,
+ virt & 0xffffffff);
+ mvpp2_write(sc, MVPP2_BM_PHY_RLS_REG(i),
+ phys & 0xffffffff);
+ }
+ }
+}
+
+void
+mvpp2_rx_fifo_init(struct mvpp2_softc *sc)
+{
+ int i;
+
+ mvpp2_write(sc, MVPP2_RX_DATA_FIFO_SIZE_REG(0),
+ MVPP2_RX_FIFO_PORT_DATA_SIZE_32KB);
+ mvpp2_write(sc, MVPP2_RX_ATTR_FIFO_SIZE_REG(0),
+ MVPP2_RX_FIFO_PORT_ATTR_SIZE_32KB);
+
+ mvpp2_write(sc, MVPP2_RX_DATA_FIFO_SIZE_REG(1),
+ MVPP2_RX_FIFO_PORT_DATA_SIZE_8KB);
+ mvpp2_write(sc, MVPP2_RX_ATTR_FIFO_SIZE_REG(1),
+ MVPP2_RX_FIFO_PORT_ATTR_SIZE_8KB);
+
+ for (i = 2; i < MVPP2_MAX_PORTS; i++) {
+ mvpp2_write(sc, MVPP2_RX_DATA_FIFO_SIZE_REG(i),
+ MVPP2_RX_FIFO_PORT_DATA_SIZE_4KB);
+ mvpp2_write(sc, MVPP2_RX_ATTR_FIFO_SIZE_REG(i),
+ MVPP2_RX_FIFO_PORT_ATTR_SIZE_4KB);
+ }
+
+ mvpp2_write(sc, MVPP2_RX_MIN_PKT_SIZE_REG, MVPP2_RX_FIFO_PORT_MIN_PKT);
+ mvpp2_write(sc, MVPP2_RX_FIFO_INIT_REG, 0x1);
+}
+
+void
+mvpp2_tx_fifo_init(struct mvpp2_softc *sc)
+{
+ int i;
+
+ mvpp2_write(sc, MVPP22_TX_FIFO_SIZE_REG(0),
+ MVPP22_TX_FIFO_DATA_SIZE_10KB);
+ mvpp2_write(sc, MVPP22_TX_FIFO_THRESH_REG(0),
+ MVPP2_TX_FIFO_THRESHOLD_10KB);
+
+ for (i = 1; i < MVPP2_MAX_PORTS; i++) {
+ mvpp2_write(sc, MVPP22_TX_FIFO_SIZE_REG(i),
+ MVPP22_TX_FIFO_DATA_SIZE_3KB);
+ mvpp2_write(sc, MVPP22_TX_FIFO_THRESH_REG(i),
+ MVPP2_TX_FIFO_THRESHOLD_3KB);
+ }
+}
+
+int
+mvpp2_prs_default_init(struct mvpp2_softc *sc)
+{
+ int i, j, ret;
+
+ mvpp2_write(sc, MVPP2_PRS_TCAM_CTRL_REG, MVPP2_PRS_TCAM_EN_MASK);
+
+ for (i = 0; i < MVPP2_PRS_TCAM_SRAM_SIZE; i++) {
+ mvpp2_write(sc, MVPP2_PRS_TCAM_IDX_REG, i);
+ for (j = 0; j < MVPP2_PRS_TCAM_WORDS; j++)
+ mvpp2_write(sc, MVPP2_PRS_TCAM_DATA_REG(j), 0);
+
+ mvpp2_write(sc, MVPP2_PRS_SRAM_IDX_REG, i);
+ for (j = 0; j < MVPP2_PRS_SRAM_WORDS; j++)
+ mvpp2_write(sc, MVPP2_PRS_SRAM_DATA_REG(j), 0);
+ }
+
+ for (i = 0; i < MVPP2_PRS_TCAM_SRAM_SIZE; i++)
+ mvpp2_prs_hw_inv(sc, i);
+
+ for (i = 0; i < MVPP2_MAX_PORTS; i++)
+ mvpp2_prs_hw_port_init(sc, i, MVPP2_PRS_LU_MH,
+ MVPP2_PRS_PORT_LU_MAX, 0);
+
+ mvpp2_prs_def_flow_init(sc);
+ mvpp2_prs_mh_init(sc);
+ mvpp2_prs_mac_init(sc);
+ mvpp2_prs_dsa_init(sc);
+ ret = mvpp2_prs_etype_init(sc);
+ if (ret)
+ return ret;
+ ret = mvpp2_prs_vlan_init(sc);
+ if (ret)
+ return ret;
+ ret = mvpp2_prs_pppoe_init(sc);
+ if (ret)
+ return ret;
+ ret = mvpp2_prs_ip6_init(sc);
+ if (ret)
+ return ret;
+ ret = mvpp2_prs_ip4_init(sc);
+ if (ret)
+ return ret;
+
+ return 0;
+}
+
+void
+mvpp2_prs_hw_inv(struct mvpp2_softc *sc, int index)
+{
+ mvpp2_write(sc, MVPP2_PRS_TCAM_IDX_REG, index);
+ mvpp2_write(sc, MVPP2_PRS_TCAM_DATA_REG(MVPP2_PRS_TCAM_INV_WORD),
+ MVPP2_PRS_TCAM_INV_MASK);
+}
+
+void
+mvpp2_prs_hw_port_init(struct mvpp2_softc *sc, int port,
+ int lu_first, int lu_max, int offset)
+{
+ uint32_t reg;
+
+ reg = mvpp2_read(sc, MVPP2_PRS_INIT_LOOKUP_REG);
+ reg &= ~MVPP2_PRS_PORT_LU_MASK(port);
+ reg |= MVPP2_PRS_PORT_LU_VAL(port, lu_first);
+ mvpp2_write(sc, MVPP2_PRS_INIT_LOOKUP_REG, reg);
+
+ reg = mvpp2_read(sc, MVPP2_PRS_MAX_LOOP_REG(port));
+ reg &= ~MVPP2_PRS_MAX_LOOP_MASK(port);
+ reg |= MVPP2_PRS_MAX_LOOP_VAL(port, lu_max);
+ mvpp2_write(sc, MVPP2_PRS_MAX_LOOP_REG(port), reg);
+
+ reg = mvpp2_read(sc, MVPP2_PRS_INIT_OFFS_REG(port));
+ reg &= ~MVPP2_PRS_INIT_OFF_MASK(port);
+ reg |= MVPP2_PRS_INIT_OFF_VAL(port, offset);
+ mvpp2_write(sc, MVPP2_PRS_INIT_OFFS_REG(port), reg);
+}
+
+void
+mvpp2_prs_def_flow_init(struct mvpp2_softc *sc)
+{
+ struct mvpp2_prs_entry pe;
+ int i;
+
+ for (i = 0; i < MVPP2_MAX_PORTS; i++) {
+ memset(&pe, 0, sizeof(pe));
+ mvpp2_prs_tcam_lu_set(&pe, MVPP2_PRS_LU_FLOWS);
+ pe.index = MVPP2_PE_FIRST_DEFAULT_FLOW - i;
+ mvpp2_prs_tcam_port_map_set(&pe, 0);
+ mvpp2_prs_sram_ai_update(&pe, i, MVPP2_PRS_FLOW_ID_MASK);
+ mvpp2_prs_sram_bits_set(&pe, MVPP2_PRS_SRAM_LU_DONE_BIT, 1);
+ mvpp2_prs_shadow_set(sc, pe.index, MVPP2_PRS_LU_FLOWS);
+ mvpp2_prs_hw_write(sc, &pe);
+ }
+}
+
+void
+mvpp2_prs_mh_init(struct mvpp2_softc *sc)
+{
+ struct mvpp2_prs_entry pe;
+
+ memset(&pe, 0, sizeof(pe));
+ pe.index = MVPP2_PE_MH_DEFAULT;
+ mvpp2_prs_tcam_lu_set(&pe, MVPP2_PRS_LU_MH);
+ mvpp2_prs_sram_shift_set(&pe, MVPP2_MH_SIZE,
+ MVPP2_PRS_SRAM_OP_SEL_SHIFT_ADD);
+ mvpp2_prs_sram_next_lu_set(&pe, MVPP2_PRS_LU_MAC);
+ mvpp2_prs_tcam_port_map_set(&pe, MVPP2_PRS_PORT_MASK);
+ mvpp2_prs_shadow_set(sc, pe.index, MVPP2_PRS_LU_MH);
+ mvpp2_prs_hw_write(sc, &pe);
+}
+
+void
+mvpp2_prs_mac_init(struct mvpp2_softc *sc)
+{
+ struct mvpp2_prs_entry pe;
+
+ memset(&pe, 0, sizeof(pe));
+ pe.index = MVPP2_PE_MAC_NON_PROMISCUOUS;
+ mvpp2_prs_tcam_lu_set(&pe, MVPP2_PRS_LU_MAC);
+ mvpp2_prs_sram_ri_update(&pe, MVPP2_PRS_RI_DROP_MASK,
+ MVPP2_PRS_RI_DROP_MASK);
+ mvpp2_prs_sram_bits_set(&pe, MVPP2_PRS_SRAM_LU_GEN_BIT, 1);
+ mvpp2_prs_sram_next_lu_set(&pe, MVPP2_PRS_LU_FLOWS);
+ mvpp2_prs_tcam_port_map_set(&pe, MVPP2_PRS_PORT_MASK);
+ mvpp2_prs_shadow_set(sc, pe.index, MVPP2_PRS_LU_MAC);
+ mvpp2_prs_hw_write(sc, &pe);
+ mvpp2_prs_mac_drop_all_set(sc, 0, 0);
+ mvpp2_prs_mac_promisc_set(sc, 0, 0);
+ mvpp2_prs_mac_multi_set(sc, MVPP2_PE_MAC_MC_ALL, 0, 0);
+ mvpp2_prs_mac_multi_set(sc, MVPP2_PE_MAC_MC_IP6, 0, 0);
+}
+
+void
+mvpp2_prs_dsa_init(struct mvpp2_softc *sc)
+{
+ struct mvpp2_prs_entry pe;
+
+ mvpp2_prs_dsa_tag_set(sc, 0, 0, MVPP2_PRS_UNTAGGED, MVPP2_PRS_EDSA);
+ mvpp2_prs_dsa_tag_set(sc, 0, 0, MVPP2_PRS_TAGGED, MVPP2_PRS_EDSA);
+ mvpp2_prs_dsa_tag_set(sc, 0, 0, MVPP2_PRS_UNTAGGED, MVPP2_PRS_DSA);
+ mvpp2_prs_dsa_tag_set(sc, 0, 0, MVPP2_PRS_TAGGED, MVPP2_PRS_DSA);
+ mvpp2_prs_dsa_tag_ethertype_set(sc, 0, 0, MVPP2_PRS_UNTAGGED, MVPP2_PRS_EDSA);
+ mvpp2_prs_dsa_tag_ethertype_set(sc, 0, 0, MVPP2_PRS_TAGGED, MVPP2_PRS_EDSA);
+ mvpp2_prs_dsa_tag_ethertype_set(sc, 0, 1, MVPP2_PRS_UNTAGGED, MVPP2_PRS_DSA);
+ mvpp2_prs_dsa_tag_ethertype_set(sc, 0, 1, MVPP2_PRS_TAGGED, MVPP2_PRS_DSA);
+ memset(&pe, 0, sizeof(pe));
+ mvpp2_prs_tcam_lu_set(&pe, MVPP2_PRS_LU_DSA);
+ pe.index = MVPP2_PE_DSA_DEFAULT;
+ mvpp2_prs_sram_next_lu_set(&pe, MVPP2_PRS_LU_VLAN);
+ mvpp2_prs_sram_shift_set(&pe, 0, MVPP2_PRS_SRAM_OP_SEL_SHIFT_ADD);
+ mvpp2_prs_shadow_set(sc, pe.index, MVPP2_PRS_LU_MAC);
+ mvpp2_prs_sram_ai_update(&pe, 0, MVPP2_PRS_SRAM_AI_MASK);
+ mvpp2_prs_tcam_port_map_set(&pe, MVPP2_PRS_PORT_MASK);
+ mvpp2_prs_hw_write(sc, &pe);
+}
+
+int
+mvpp2_prs_etype_init(struct mvpp2_softc *sc)
+{
+ struct mvpp2_prs_entry pe;
+ int tid;
+
+ /* Ethertype: PPPoE */
+ tid = mvpp2_prs_tcam_first_free(sc, MVPP2_PE_FIRST_FREE_TID,
+ MVPP2_PE_LAST_FREE_TID);
+ if (tid < 0)
+ return tid;
+ memset(&pe, 0, sizeof(pe));
+ mvpp2_prs_tcam_lu_set(&pe, MVPP2_PRS_LU_L2);
+ pe.index = tid;
+ mvpp2_prs_match_etype(&pe, 0, MV_ETH_P_PPP_SES);
+ mvpp2_prs_sram_shift_set(&pe, MVPP2_PPPOE_HDR_SIZE,
+ MVPP2_PRS_SRAM_OP_SEL_SHIFT_ADD);
+ mvpp2_prs_sram_next_lu_set(&pe, MVPP2_PRS_LU_PPPOE);
+ mvpp2_prs_sram_ri_update(&pe, MVPP2_PRS_RI_PPPOE_MASK,
+ MVPP2_PRS_RI_PPPOE_MASK);
+ mvpp2_prs_shadow_set(sc, pe.index, MVPP2_PRS_LU_L2);
+ sc->sc_prs_shadow[pe.index].udf = MVPP2_PRS_UDF_L2_DEF;
+ sc->sc_prs_shadow[pe.index].finish = 0;
+ mvpp2_prs_shadow_ri_set(sc, pe.index, MVPP2_PRS_RI_PPPOE_MASK,
+ MVPP2_PRS_RI_PPPOE_MASK);
+ mvpp2_prs_hw_write(sc, &pe);
+
+ /* Ethertype: ARP */
+ tid = mvpp2_prs_tcam_first_free(sc, MVPP2_PE_FIRST_FREE_TID,
+ MVPP2_PE_LAST_FREE_TID);
+ if (tid < 0)
+ return tid;
+ memset(&pe, 0, sizeof(pe));
+ mvpp2_prs_tcam_lu_set(&pe, MVPP2_PRS_LU_L2);
+ pe.index = tid;
+ mvpp2_prs_match_etype(&pe, 0, MV_ETH_P_ARP);
+ mvpp2_prs_sram_next_lu_set(&pe, MVPP2_PRS_LU_FLOWS);
+ mvpp2_prs_sram_bits_set(&pe, MVPP2_PRS_SRAM_LU_GEN_BIT, 1);
+ mvpp2_prs_sram_ri_update(&pe, MVPP2_PRS_RI_L3_ARP,
+ MVPP2_PRS_RI_L3_PROTO_MASK);
+ mvpp2_prs_sram_offset_set(&pe, MVPP2_PRS_SRAM_UDF_TYPE_L3,
+ MVPP2_ETH_TYPE_LEN, MVPP2_PRS_SRAM_OP_SEL_UDF_ADD);
+ mvpp2_prs_shadow_set(sc, pe.index, MVPP2_PRS_LU_L2);
+ sc->sc_prs_shadow[pe.index].udf = MVPP2_PRS_UDF_L2_DEF;
+ sc->sc_prs_shadow[pe.index].finish = 1;
+ mvpp2_prs_shadow_ri_set(sc, pe.index, MVPP2_PRS_RI_L3_ARP,
+ MVPP2_PRS_RI_L3_PROTO_MASK);
+ mvpp2_prs_hw_write(sc, &pe);
+
+ /* Ethertype: LBTD */
+ tid = mvpp2_prs_tcam_first_free(sc, MVPP2_PE_FIRST_FREE_TID,
+ MVPP2_PE_LAST_FREE_TID);
+ if (tid < 0)
+ return tid;
+ memset(&pe, 0, sizeof(pe));
+ mvpp2_prs_tcam_lu_set(&pe, MVPP2_PRS_LU_L2);
+ pe.index = tid;
+ mvpp2_prs_match_etype(&pe, 0, MVPP2_IP_LBDT_TYPE);
+ mvpp2_prs_sram_next_lu_set(&pe, MVPP2_PRS_LU_FLOWS);
+ mvpp2_prs_sram_bits_set(&pe, MVPP2_PRS_SRAM_LU_GEN_BIT, 1);
+ mvpp2_prs_sram_ri_update(&pe, MVPP2_PRS_RI_CPU_CODE_RX_SPEC |
+ MVPP2_PRS_RI_UDF3_RX_SPECIAL, MVPP2_PRS_RI_CPU_CODE_MASK |
+ MVPP2_PRS_RI_UDF3_MASK);
+ mvpp2_prs_sram_offset_set(&pe, MVPP2_PRS_SRAM_UDF_TYPE_L3,
+ MVPP2_ETH_TYPE_LEN, MVPP2_PRS_SRAM_OP_SEL_UDF_ADD);
+ mvpp2_prs_shadow_set(sc, pe.index, MVPP2_PRS_LU_L2);
+ sc->sc_prs_shadow[pe.index].udf = MVPP2_PRS_UDF_L2_DEF;
+ sc->sc_prs_shadow[pe.index].finish = 1;
+ mvpp2_prs_shadow_ri_set(sc, pe.index, MVPP2_PRS_RI_CPU_CODE_RX_SPEC |
+ MVPP2_PRS_RI_UDF3_RX_SPECIAL, MVPP2_PRS_RI_CPU_CODE_MASK |
+ MVPP2_PRS_RI_UDF3_MASK);
+ mvpp2_prs_hw_write(sc, &pe);
+
+ /* Ethertype: IPv4 without options */
+ tid = mvpp2_prs_tcam_first_free(sc, MVPP2_PE_FIRST_FREE_TID,
+ MVPP2_PE_LAST_FREE_TID);
+ if (tid < 0)
+ return tid;
+ memset(&pe, 0, sizeof(pe));
+ mvpp2_prs_tcam_lu_set(&pe, MVPP2_PRS_LU_L2);
+ pe.index = tid;
+ mvpp2_prs_match_etype(&pe, 0, MV_ETH_P_IP);
+ mvpp2_prs_tcam_data_byte_set(&pe, MVPP2_ETH_TYPE_LEN,
+ MVPP2_PRS_IPV4_HEAD | MVPP2_PRS_IPV4_IHL,
+ MVPP2_PRS_IPV4_HEAD_MASK | MVPP2_PRS_IPV4_IHL_MASK);
+ mvpp2_prs_sram_next_lu_set(&pe, MVPP2_PRS_LU_IP4);
+ mvpp2_prs_sram_ri_update(&pe, MVPP2_PRS_RI_L3_IP4,
+ MVPP2_PRS_RI_L3_PROTO_MASK);
+ mvpp2_prs_sram_shift_set(&pe, MVPP2_ETH_TYPE_LEN + 4,
+ MVPP2_PRS_SRAM_OP_SEL_SHIFT_ADD);
+ mvpp2_prs_sram_offset_set(&pe, MVPP2_PRS_SRAM_UDF_TYPE_L3,
+ MVPP2_ETH_TYPE_LEN, MVPP2_PRS_SRAM_OP_SEL_UDF_ADD);
+ mvpp2_prs_shadow_set(sc, pe.index, MVPP2_PRS_LU_L2);
+ sc->sc_prs_shadow[pe.index].udf = MVPP2_PRS_UDF_L2_DEF;
+ sc->sc_prs_shadow[pe.index].finish = 0;
+ mvpp2_prs_shadow_ri_set(sc, pe.index, MVPP2_PRS_RI_L3_IP4,
+ MVPP2_PRS_RI_L3_PROTO_MASK);
+ mvpp2_prs_hw_write(sc, &pe);
+
+ /* Ethertype: IPv4 with options */
+ tid = mvpp2_prs_tcam_first_free(sc, MVPP2_PE_FIRST_FREE_TID,
+ MVPP2_PE_LAST_FREE_TID);
+ if (tid < 0)
+ return tid;
+ pe.index = tid;
+
+ pe.tcam.byte[MVPP2_PRS_TCAM_DATA_BYTE(MVPP2_ETH_TYPE_LEN)] = 0x0;
+ pe.tcam.byte[MVPP2_PRS_TCAM_DATA_BYTE_EN(MVPP2_ETH_TYPE_LEN)] = 0x0;
+ mvpp2_prs_tcam_data_byte_set(&pe, MVPP2_ETH_TYPE_LEN,
+ MVPP2_PRS_IPV4_HEAD, MVPP2_PRS_IPV4_HEAD_MASK);
+ pe.sram.word[MVPP2_PRS_SRAM_RI_WORD] = 0x0;
+ pe.sram.word[MVPP2_PRS_SRAM_RI_CTRL_WORD] = 0x0;
+ mvpp2_prs_sram_ri_update(&pe, MVPP2_PRS_RI_L3_IP4_OPT,
+ MVPP2_PRS_RI_L3_PROTO_MASK);
+ mvpp2_prs_shadow_set(sc, pe.index, MVPP2_PRS_LU_L2);
+ sc->sc_prs_shadow[pe.index].udf = MVPP2_PRS_UDF_L2_DEF;
+ sc->sc_prs_shadow[pe.index].finish = 0;
+ mvpp2_prs_shadow_ri_set(sc, pe.index, MVPP2_PRS_RI_L3_IP4_OPT,
+ MVPP2_PRS_RI_L3_PROTO_MASK);
+ mvpp2_prs_hw_write(sc, &pe);
+
+ /* Ethertype: IPv6 without options */
+ tid = mvpp2_prs_tcam_first_free(sc, MVPP2_PE_FIRST_FREE_TID,
+ MVPP2_PE_LAST_FREE_TID);
+ if (tid < 0)
+ return tid;
+ memset(&pe, 0, sizeof(pe));
+ mvpp2_prs_tcam_lu_set(&pe, MVPP2_PRS_LU_L2);
+ pe.index = tid;
+ mvpp2_prs_match_etype(&pe, 0, MV_ETH_P_IPV6);
+ mvpp2_prs_sram_shift_set(&pe, MVPP2_ETH_TYPE_LEN + 8 +
+ MVPP2_MAX_L3_ADDR_SIZE, MVPP2_PRS_SRAM_OP_SEL_SHIFT_ADD);
+ mvpp2_prs_sram_next_lu_set(&pe, MVPP2_PRS_LU_IP6);
+ mvpp2_prs_sram_ri_update(&pe, MVPP2_PRS_RI_L3_IP6,
+ MVPP2_PRS_RI_L3_PROTO_MASK);
+ mvpp2_prs_sram_offset_set(&pe, MVPP2_PRS_SRAM_UDF_TYPE_L3,
+ MVPP2_ETH_TYPE_LEN, MVPP2_PRS_SRAM_OP_SEL_UDF_ADD);
+ mvpp2_prs_shadow_set(sc, pe.index, MVPP2_PRS_LU_L2);
+ sc->sc_prs_shadow[pe.index].udf = MVPP2_PRS_UDF_L2_DEF;
+ sc->sc_prs_shadow[pe.index].finish = 0;
+ mvpp2_prs_shadow_ri_set(sc, pe.index, MVPP2_PRS_RI_L3_IP6,
+ MVPP2_PRS_RI_L3_PROTO_MASK);
+ mvpp2_prs_hw_write(sc, &pe);
+
+ /* Default entry for MVPP2_PRS_LU_L2 - Unknown ethtype */
+ memset(&pe, 0, sizeof(struct mvpp2_prs_entry));
+ mvpp2_prs_tcam_lu_set(&pe, MVPP2_PRS_LU_L2);
+ pe.index = MVPP2_PE_ETH_TYPE_UN;
+ mvpp2_prs_tcam_port_map_set(&pe, MVPP2_PRS_PORT_MASK);
+ mvpp2_prs_sram_bits_set(&pe, MVPP2_PRS_SRAM_LU_GEN_BIT, 1);
+ mvpp2_prs_sram_next_lu_set(&pe, MVPP2_PRS_LU_FLOWS);
+ mvpp2_prs_sram_ri_update(&pe, MVPP2_PRS_RI_L3_UN,
+ MVPP2_PRS_RI_L3_PROTO_MASK);
+ mvpp2_prs_sram_offset_set(&pe, MVPP2_PRS_SRAM_UDF_TYPE_L3,
+ MVPP2_ETH_TYPE_LEN, MVPP2_PRS_SRAM_OP_SEL_UDF_ADD);
+ mvpp2_prs_shadow_set(sc, pe.index, MVPP2_PRS_LU_L2);
+ sc->sc_prs_shadow[pe.index].udf = MVPP2_PRS_UDF_L2_DEF;
+ sc->sc_prs_shadow[pe.index].finish = 1;
+ mvpp2_prs_shadow_ri_set(sc, pe.index, MVPP2_PRS_RI_L3_UN,
+ MVPP2_PRS_RI_L3_PROTO_MASK);
+ mvpp2_prs_hw_write(sc, &pe);
+
+ return 0;
+}
+
+int
+mvpp2_prs_vlan_init(struct mvpp2_softc *sc)
+{
+ struct mvpp2_prs_entry pe;
+ int ret;
+
+ sc->sc_prs_double_vlans = mallocarray(MVPP2_PRS_DBL_VLANS_MAX,
+ sizeof(*sc->sc_prs_double_vlans), M_DEVBUF, M_WAITOK | M_ZERO);
+
+ ret = mvpp2_prs_double_vlan_add(sc, MV_ETH_P_8021Q, MV_ETH_P_8021AD,
+ MVPP2_PRS_PORT_MASK);
+ if (ret)
+ return ret;
+ ret = mvpp2_prs_double_vlan_add(sc, MV_ETH_P_8021Q, MV_ETH_P_8021Q,
+ MVPP2_PRS_PORT_MASK);
+ if (ret)
+ return ret;
+ ret = mvpp2_prs_vlan_add(sc, MV_ETH_P_8021AD, MVPP2_PRS_SINGLE_VLAN_AI,
+ MVPP2_PRS_PORT_MASK);
+ if (ret)
+ return ret;
+ ret = mvpp2_prs_vlan_add(sc, MV_ETH_P_8021Q, MVPP2_PRS_SINGLE_VLAN_AI,
+ MVPP2_PRS_PORT_MASK);
+ if (ret)
+ return ret;
+
+ memset(&pe, 0, sizeof(struct mvpp2_prs_entry));
+ mvpp2_prs_tcam_lu_set(&pe, MVPP2_PRS_LU_VLAN);
+ pe.index = MVPP2_PE_VLAN_DBL;
+ mvpp2_prs_sram_next_lu_set(&pe, MVPP2_PRS_LU_L2);
+ mvpp2_prs_sram_ai_update(&pe, 0, MVPP2_PRS_SRAM_AI_MASK);
+ mvpp2_prs_sram_ri_update(&pe, MVPP2_PRS_RI_VLAN_DOUBLE,
+ MVPP2_PRS_RI_VLAN_MASK);
+ mvpp2_prs_tcam_ai_update(&pe, MVPP2_PRS_DBL_VLAN_AI_BIT,
+ MVPP2_PRS_DBL_VLAN_AI_BIT);
+ mvpp2_prs_tcam_port_map_set(&pe, MVPP2_PRS_PORT_MASK);
+ mvpp2_prs_shadow_set(sc, pe.index, MVPP2_PRS_LU_VLAN);
+ mvpp2_prs_hw_write(sc, &pe);
+
+ memset(&pe, 0, sizeof(struct mvpp2_prs_entry));
+ mvpp2_prs_tcam_lu_set(&pe, MVPP2_PRS_LU_VLAN);
+ pe.index = MVPP2_PE_VLAN_NONE;
+ mvpp2_prs_sram_next_lu_set(&pe, MVPP2_PRS_LU_L2);
+ mvpp2_prs_sram_ri_update(&pe, MVPP2_PRS_RI_VLAN_NONE, MVPP2_PRS_RI_VLAN_MASK);
+ mvpp2_prs_tcam_port_map_set(&pe, MVPP2_PRS_PORT_MASK);
+ mvpp2_prs_shadow_set(sc, pe.index, MVPP2_PRS_LU_VLAN);
+ mvpp2_prs_hw_write(sc, &pe);
+
+ return 0;
+}
+
+int
+mvpp2_prs_pppoe_init(struct mvpp2_softc *sc)
+{
+ struct mvpp2_prs_entry pe;
+ int tid;
+
+ tid = mvpp2_prs_tcam_first_free(sc, MVPP2_PE_FIRST_FREE_TID,
+ MVPP2_PE_LAST_FREE_TID);
+ if (tid < 0)
+ return tid;
+
+ memset(&pe, 0, sizeof(struct mvpp2_prs_entry));
+ mvpp2_prs_tcam_lu_set(&pe, MVPP2_PRS_LU_PPPOE);
+ pe.index = tid;
+ mvpp2_prs_match_etype(&pe, 0, MV_PPP_IP);
+ mvpp2_prs_sram_next_lu_set(&pe, MVPP2_PRS_LU_IP4);
+ mvpp2_prs_sram_ri_update(&pe, MVPP2_PRS_RI_L3_IP4_OPT,
+ MVPP2_PRS_RI_L3_PROTO_MASK);
+ mvpp2_prs_sram_shift_set(&pe, MVPP2_ETH_TYPE_LEN + 4,
+ MVPP2_PRS_SRAM_OP_SEL_SHIFT_ADD);
+ mvpp2_prs_sram_offset_set(&pe, MVPP2_PRS_SRAM_UDF_TYPE_L3,
+ MVPP2_ETH_TYPE_LEN, MVPP2_PRS_SRAM_OP_SEL_UDF_ADD);
+ mvpp2_prs_shadow_set(sc, pe.index, MVPP2_PRS_LU_PPPOE);
+ mvpp2_prs_hw_write(sc, &pe);
+
+ tid = mvpp2_prs_tcam_first_free(sc, MVPP2_PE_FIRST_FREE_TID,
+ MVPP2_PE_LAST_FREE_TID);
+ if (tid < 0)
+ return tid;
+
+ pe.index = tid;
+ mvpp2_prs_tcam_data_byte_set(&pe, MVPP2_ETH_TYPE_LEN,
+ MVPP2_PRS_IPV4_HEAD | MVPP2_PRS_IPV4_IHL,
+ MVPP2_PRS_IPV4_HEAD_MASK | MVPP2_PRS_IPV4_IHL_MASK);
+ pe.sram.word[MVPP2_PRS_SRAM_RI_WORD] = 0x0;
+ pe.sram.word[MVPP2_PRS_SRAM_RI_CTRL_WORD] = 0x0;
+ mvpp2_prs_sram_ri_update(&pe, MVPP2_PRS_RI_L3_IP4, MVPP2_PRS_RI_L3_PROTO_MASK);
+ mvpp2_prs_shadow_set(sc, pe.index, MVPP2_PRS_LU_PPPOE);
+ mvpp2_prs_hw_write(sc, &pe);
+
+ tid = mvpp2_prs_tcam_first_free(sc, MVPP2_PE_FIRST_FREE_TID,
+ MVPP2_PE_LAST_FREE_TID);
+ if (tid < 0)
+ return tid;
+
+ memset(&pe, 0, sizeof(struct mvpp2_prs_entry));
+ mvpp2_prs_tcam_lu_set(&pe, MVPP2_PRS_LU_PPPOE);
+ pe.index = tid;
+ mvpp2_prs_match_etype(&pe, 0, MV_PPP_IPV6);
+ mvpp2_prs_sram_next_lu_set(&pe, MVPP2_PRS_LU_IP6);
+ mvpp2_prs_sram_ri_update(&pe, MVPP2_PRS_RI_L3_IP6,
+ MVPP2_PRS_RI_L3_PROTO_MASK);
+ mvpp2_prs_sram_shift_set(&pe, MVPP2_ETH_TYPE_LEN + 4,
+ MVPP2_PRS_SRAM_OP_SEL_SHIFT_ADD);
+ mvpp2_prs_sram_offset_set(&pe, MVPP2_PRS_SRAM_UDF_TYPE_L3,
+ MVPP2_ETH_TYPE_LEN, MVPP2_PRS_SRAM_OP_SEL_UDF_ADD);
+ mvpp2_prs_shadow_set(sc, pe.index, MVPP2_PRS_LU_PPPOE);
+ mvpp2_prs_hw_write(sc, &pe);
+
+ tid = mvpp2_prs_tcam_first_free(sc, MVPP2_PE_FIRST_FREE_TID,
+ MVPP2_PE_LAST_FREE_TID);
+ if (tid < 0)
+ return tid;
+
+ memset(&pe, 0, sizeof(struct mvpp2_prs_entry));
+ mvpp2_prs_tcam_lu_set(&pe, MVPP2_PRS_LU_PPPOE);
+ pe.index = tid;
+ mvpp2_prs_sram_ri_update(&pe, MVPP2_PRS_RI_L3_UN,
+ MVPP2_PRS_RI_L3_PROTO_MASK);
+ mvpp2_prs_sram_next_lu_set(&pe, MVPP2_PRS_LU_FLOWS);
+ mvpp2_prs_sram_bits_set(&pe, MVPP2_PRS_SRAM_LU_GEN_BIT, 1);
+ mvpp2_prs_sram_offset_set(&pe, MVPP2_PRS_SRAM_UDF_TYPE_L3,
+ MVPP2_ETH_TYPE_LEN, MVPP2_PRS_SRAM_OP_SEL_UDF_ADD);
+ mvpp2_prs_shadow_set(sc, pe.index, MVPP2_PRS_LU_PPPOE);
+ mvpp2_prs_hw_write(sc, &pe);
+
+ return 0;
+}
+
+int
+mvpp2_prs_ip6_init(struct mvpp2_softc *sc)
+{
+ struct mvpp2_prs_entry pe;
+ int tid, ret;
+
+ ret = mvpp2_prs_ip6_proto(sc, MV_IPPR_TCP, MVPP2_PRS_RI_L4_TCP,
+ MVPP2_PRS_RI_L4_PROTO_MASK);
+ if (ret)
+ return ret;
+ ret = mvpp2_prs_ip6_proto(sc, MV_IPPR_UDP, MVPP2_PRS_RI_L4_UDP,
+ MVPP2_PRS_RI_L4_PROTO_MASK);
+ if (ret)
+ return ret;
+ ret = mvpp2_prs_ip6_proto(sc, MV_IPPR_ICMPV6,
+ MVPP2_PRS_RI_CPU_CODE_RX_SPEC | MVPP2_PRS_RI_UDF3_RX_SPECIAL,
+ MVPP2_PRS_RI_CPU_CODE_MASK | MVPP2_PRS_RI_UDF3_MASK);
+ if (ret)
+ return ret;
+ ret = mvpp2_prs_ip6_proto(sc, MV_IPPR_IPIP, MVPP2_PRS_RI_UDF7_IP6_LITE,
+ MVPP2_PRS_RI_UDF7_MASK);
+ if (ret)
+ return ret;
+ ret = mvpp2_prs_ip6_cast(sc, MVPP2_PRS_L3_MULTI_CAST);
+ if (ret)
+ return ret;
+
+ tid = mvpp2_prs_tcam_first_free(sc, MVPP2_PE_FIRST_FREE_TID,
+ MVPP2_PE_LAST_FREE_TID);
+ if (tid < 0)
+ return tid;
+
+ memset(&pe, 0, sizeof(struct mvpp2_prs_entry));
+ mvpp2_prs_tcam_lu_set(&pe, MVPP2_PRS_LU_IP6);
+ pe.index = tid;
+ mvpp2_prs_sram_next_lu_set(&pe, MVPP2_PRS_LU_FLOWS);
+ mvpp2_prs_sram_bits_set(&pe, MVPP2_PRS_SRAM_LU_GEN_BIT, 1);
+ mvpp2_prs_sram_ri_update(&pe,
+ MVPP2_PRS_RI_L3_UN | MVPP2_PRS_RI_DROP_MASK,
+ MVPP2_PRS_RI_L3_PROTO_MASK | MVPP2_PRS_RI_DROP_MASK);
+ mvpp2_prs_tcam_data_byte_set(&pe, 1, 0x00, MVPP2_PRS_IPV6_HOP_MASK);
+ mvpp2_prs_tcam_ai_update(&pe, MVPP2_PRS_IPV6_NO_EXT_AI_BIT,
+ MVPP2_PRS_IPV6_NO_EXT_AI_BIT);
+ mvpp2_prs_shadow_set(sc, pe.index, MVPP2_PRS_LU_IP4);
+ mvpp2_prs_hw_write(sc, &pe);
+
+ memset(&pe, 0, sizeof(struct mvpp2_prs_entry));
+ mvpp2_prs_tcam_lu_set(&pe, MVPP2_PRS_LU_IP6);
+ pe.index = MVPP2_PE_IP6_PROTO_UN;
+ mvpp2_prs_sram_next_lu_set(&pe, MVPP2_PRS_LU_FLOWS);
+ mvpp2_prs_sram_bits_set(&pe, MVPP2_PRS_SRAM_LU_GEN_BIT, 1);
+ mvpp2_prs_sram_ri_update(&pe, MVPP2_PRS_RI_L4_OTHER,
+ MVPP2_PRS_RI_L4_PROTO_MASK);
+ mvpp2_prs_sram_offset_set(&pe, MVPP2_PRS_SRAM_UDF_TYPE_L4,
+ sizeof(struct ip6_hdr) - 6, MVPP2_PRS_SRAM_OP_SEL_UDF_ADD);
+ mvpp2_prs_tcam_ai_update(&pe, MVPP2_PRS_IPV6_NO_EXT_AI_BIT,
+ MVPP2_PRS_IPV6_NO_EXT_AI_BIT);
+ mvpp2_prs_tcam_port_map_set(&pe, MVPP2_PRS_PORT_MASK);
+ mvpp2_prs_shadow_set(sc, pe.index, MVPP2_PRS_LU_IP4);
+ mvpp2_prs_hw_write(sc, &pe);
+
+ memset(&pe, 0, sizeof(struct mvpp2_prs_entry));
+ mvpp2_prs_tcam_lu_set(&pe, MVPP2_PRS_LU_IP6);
+ pe.index = MVPP2_PE_IP6_EXT_PROTO_UN;
+ mvpp2_prs_sram_next_lu_set(&pe, MVPP2_PRS_LU_FLOWS);
+ mvpp2_prs_sram_bits_set(&pe, MVPP2_PRS_SRAM_LU_GEN_BIT, 1);
+ mvpp2_prs_sram_ri_update(&pe, MVPP2_PRS_RI_L4_OTHER,
+ MVPP2_PRS_RI_L4_PROTO_MASK);
+ mvpp2_prs_tcam_ai_update(&pe, MVPP2_PRS_IPV6_EXT_AI_BIT,
+ MVPP2_PRS_IPV6_EXT_AI_BIT);
+ mvpp2_prs_tcam_port_map_set(&pe, MVPP2_PRS_PORT_MASK);
+ mvpp2_prs_shadow_set(sc, pe.index, MVPP2_PRS_LU_IP4);
+ mvpp2_prs_hw_write(sc, &pe);
+
+ memset(&pe, 0, sizeof(struct mvpp2_prs_entry));
+ mvpp2_prs_tcam_lu_set(&pe, MVPP2_PRS_LU_IP6);
+ pe.index = MVPP2_PE_IP6_ADDR_UN;
+ mvpp2_prs_sram_next_lu_set(&pe, MVPP2_PRS_LU_IP6);
+ mvpp2_prs_sram_ri_update(&pe, MVPP2_PRS_RI_L3_UCAST,
+ MVPP2_PRS_RI_L3_ADDR_MASK);
+ mvpp2_prs_sram_ai_update(&pe, MVPP2_PRS_IPV6_NO_EXT_AI_BIT,
+ MVPP2_PRS_IPV6_NO_EXT_AI_BIT);
+ mvpp2_prs_sram_shift_set(&pe, -18, MVPP2_PRS_SRAM_OP_SEL_SHIFT_ADD);
+ mvpp2_prs_tcam_ai_update(&pe, 0, MVPP2_PRS_IPV6_NO_EXT_AI_BIT);
+ mvpp2_prs_tcam_port_map_set(&pe, MVPP2_PRS_PORT_MASK);
+ mvpp2_prs_shadow_set(sc, pe.index, MVPP2_PRS_LU_IP6);
+ mvpp2_prs_hw_write(sc, &pe);
+
+ return 0;
+}
+
+int
+mvpp2_prs_ip4_init(struct mvpp2_softc *sc)
+{
+ struct mvpp2_prs_entry pe;
+ int ret;
+
+ ret = mvpp2_prs_ip4_proto(sc, MV_IPPR_TCP, MVPP2_PRS_RI_L4_TCP,
+ MVPP2_PRS_RI_L4_PROTO_MASK);
+ if (ret)
+ return ret;
+ ret = mvpp2_prs_ip4_proto(sc, MV_IPPR_UDP, MVPP2_PRS_RI_L4_UDP,
+ MVPP2_PRS_RI_L4_PROTO_MASK);
+ if (ret)
+ return ret;
+ ret = mvpp2_prs_ip4_proto(sc, MV_IPPR_IGMP,
+ MVPP2_PRS_RI_CPU_CODE_RX_SPEC | MVPP2_PRS_RI_UDF3_RX_SPECIAL,
+ MVPP2_PRS_RI_CPU_CODE_MASK | MVPP2_PRS_RI_UDF3_MASK);
+ if (ret)
+ return ret;
+ ret = mvpp2_prs_ip4_cast(sc, MVPP2_PRS_L3_BROAD_CAST);
+ if (ret)
+ return ret;
+ ret = mvpp2_prs_ip4_cast(sc, MVPP2_PRS_L3_MULTI_CAST);
+ if (ret)
+ return ret;
+
+ memset(&pe, 0, sizeof(struct mvpp2_prs_entry));
+ mvpp2_prs_tcam_lu_set(&pe, MVPP2_PRS_LU_IP4);
+ pe.index = MVPP2_PE_IP4_PROTO_UN;
+ mvpp2_prs_sram_next_lu_set(&pe, MVPP2_PRS_LU_IP4);
+ mvpp2_prs_sram_shift_set(&pe, 12, MVPP2_PRS_SRAM_OP_SEL_SHIFT_ADD);
+ mvpp2_prs_sram_offset_set( &pe, MVPP2_PRS_SRAM_UDF_TYPE_L4,
+ sizeof(struct ip) - 4, MVPP2_PRS_SRAM_OP_SEL_UDF_ADD);
+ mvpp2_prs_sram_ai_update(&pe, MVPP2_PRS_IPV4_DIP_AI_BIT,
+ MVPP2_PRS_IPV4_DIP_AI_BIT);
+ mvpp2_prs_sram_ri_update(&pe, MVPP2_PRS_RI_L4_OTHER,
+ MVPP2_PRS_RI_L4_PROTO_MASK);
+ mvpp2_prs_tcam_ai_update(&pe, 0, MVPP2_PRS_IPV4_DIP_AI_BIT);
+ mvpp2_prs_tcam_port_map_set(&pe, MVPP2_PRS_PORT_MASK);
+ mvpp2_prs_shadow_set(sc, pe.index, MVPP2_PRS_LU_IP4);
+ mvpp2_prs_hw_write(sc, &pe);
+
+ memset(&pe, 0, sizeof(struct mvpp2_prs_entry));
+ mvpp2_prs_tcam_lu_set(&pe, MVPP2_PRS_LU_IP4);
+ pe.index = MVPP2_PE_IP4_ADDR_UN;
+ mvpp2_prs_sram_next_lu_set(&pe, MVPP2_PRS_LU_FLOWS);
+ mvpp2_prs_sram_bits_set(&pe, MVPP2_PRS_SRAM_LU_GEN_BIT, 1);
+ mvpp2_prs_sram_ri_update(&pe, MVPP2_PRS_RI_L3_UCAST,
+ MVPP2_PRS_RI_L3_ADDR_MASK);
+ mvpp2_prs_tcam_ai_update(&pe, MVPP2_PRS_IPV4_DIP_AI_BIT,
+ MVPP2_PRS_IPV4_DIP_AI_BIT);
+ mvpp2_prs_tcam_port_map_set(&pe, MVPP2_PRS_PORT_MASK);
+ mvpp2_prs_shadow_set(sc, pe.index, MVPP2_PRS_LU_IP4);
+ mvpp2_prs_hw_write(sc, &pe);
+
+ return 0;
+}
+
+int
+mvpp2_port_match(struct device *parent, void *cfdata, void *aux)
+{
+ struct mvpp2_attach_args *maa = aux;
+ char buf[32];
+
+ if (OF_getprop(maa->ma_node, "status", buf, sizeof(buf)) > 0 &&
+ strcmp(buf, "disabled") == 0)
+ return 0;
+
+ return 1;
+}
+
+void
+mvpp2_port_attach(struct device *parent, struct device *self, void *aux)
+{
+ struct mvpp2_port *sc = (void *)self;
+ struct mvpp2_attach_args *maa = aux;
+ struct mvpp2_tx_queue *txq;
+ struct mvpp2_rx_queue *rxq;
+ struct ifnet *ifp;
+ uint32_t phy, reg;
+ int i, idx, len, node;
+ char *phy_mode;
+ char *managed;
+
+ sc->sc = (void *)parent;
+ sc->sc_node = maa->ma_node;
+ sc->sc_dmat = maa->ma_dmat;
+
+ sc->sc_id = OF_getpropint(sc->sc_node, "port-id", 0);
+ sc->sc_gop_id = OF_getpropint(sc->sc_node, "gop-port-id", 0);
+ sc->sc_sfp = OF_getpropint(sc->sc_node, "sfp", 0);
+
+ len = OF_getproplen(sc->sc_node, "phy-mode");
+ if (len <= 0) {
+ printf("%s: cannot extract phy-mode\n", self->dv_xname);
+ return;
+ }
+
+ phy_mode = malloc(len, M_TEMP, M_WAITOK);
+ OF_getprop(sc->sc_node, "phy-mode", phy_mode, len);
+ if (!strncmp(phy_mode, "10gbase-kr", strlen("10gbase-kr")))
+ sc->sc_phy_mode = PHY_MODE_10GBASER;
+ else if (!strncmp(phy_mode, "2500base-x", strlen("2500base-x")))
+ sc->sc_phy_mode = PHY_MODE_2500BASEX;
+ else if (!strncmp(phy_mode, "1000base-x", strlen("1000base-x")))
+ sc->sc_phy_mode = PHY_MODE_1000BASEX;
+ else if (!strncmp(phy_mode, "sgmii", strlen("sgmii")))
+ sc->sc_phy_mode = PHY_MODE_SGMII;
+ else if (!strncmp(phy_mode, "rgmii-rxid", strlen("rgmii-rxid")))
+ sc->sc_phy_mode = PHY_MODE_RGMII_RXID;
+ else if (!strncmp(phy_mode, "rgmii-txid", strlen("rgmii-txid")))
+ sc->sc_phy_mode = PHY_MODE_RGMII_TXID;
+ else if (!strncmp(phy_mode, "rgmii-id", strlen("rgmii-id")))
+ sc->sc_phy_mode = PHY_MODE_RGMII_ID;
+ else if (!strncmp(phy_mode, "rgmii", strlen("rgmii")))
+ sc->sc_phy_mode = PHY_MODE_RGMII;
+ else {
+ printf("%s: cannot use phy-mode %s\n", self->dv_xname,
+ phy_mode);
+ return;
+ }
+ free(phy_mode, M_TEMP, len);
+
+ /* Lookup PHY. */
+ phy = OF_getpropint(sc->sc_node, "phy", 0);
+ if (phy) {
+ node = OF_getnodebyphandle(phy);
+ if (!node) {
+ printf(": no phy\n");
+ return;
+ }
+ sc->sc_mdio = mii_byphandle(phy);
+ sc->sc_phyloc = OF_getpropint(node, "reg", MII_PHY_ANY);
+ sc->sc_sfp = OF_getpropint(node, "sfp", sc->sc_sfp);
+ }
+
+ if ((len = OF_getproplen(sc->sc_node, "managed")) >= 0) {
+ managed = malloc(len, M_TEMP, M_WAITOK);
+ OF_getprop(sc->sc_node, "managed", managed, len);
+ if (!strncmp(managed, "in-band-status",
+ strlen("in-band-status")))
+ sc->sc_inband_status = 1;
+ free(managed, M_TEMP, len);
+ }
+
+ if (OF_getprop(sc->sc_node, "local-mac-address",
+ &sc->sc_lladdr, ETHER_ADDR_LEN) != ETHER_ADDR_LEN)
+ memset(sc->sc_lladdr, 0xff, sizeof(sc->sc_lladdr));
+ printf(": address %s\n", ether_sprintf(sc->sc_lladdr));
+
+ sc->sc_ntxq = sc->sc_nrxq = 1;
+ sc->sc_txqs = mallocarray(sc->sc_ntxq, sizeof(*sc->sc_txqs),
+ M_DEVBUF, M_WAITOK | M_ZERO);
+ sc->sc_rxqs = mallocarray(sc->sc_nrxq, sizeof(*sc->sc_rxqs),
+ M_DEVBUF, M_WAITOK | M_ZERO);
+
+ for (i = 0; i < sc->sc_ntxq; i++) {
+ txq = &sc->sc_txqs[i];
+ txq->id = mvpp2_txq_phys(sc->sc_id, i);
+ txq->log_id = i;
+ txq->done_pkts_coal = MVPP2_TXDONE_COAL_PKTS_THRESH;
+ }
+
+ sc->sc_tx_time_coal = MVPP2_TXDONE_COAL_USEC;
+
+ for (i = 0; i < sc->sc_nrxq; i++) {
+ rxq = &sc->sc_rxqs[i];
+ rxq->id = sc->sc_id * 32 + i;
+ rxq->pkts_coal = MVPP2_RX_COAL_PKTS;
+ rxq->time_coal = MVPP2_RX_COAL_USEC;
+ }
+
+ mvpp2_egress_disable(sc);
+ mvpp2_port_disable(sc);
+
+ mvpp2_write(sc->sc, MVPP2_ISR_RXQ_GROUP_INDEX_REG,
+ sc->sc_id << MVPP2_ISR_RXQ_GROUP_INDEX_GROUP_SHIFT |
+ 0 /* queue vector id */);
+ mvpp2_write(sc->sc, MVPP2_ISR_RXQ_SUB_GROUP_CONFIG_REG,
+ sc->sc_nrxq << MVPP2_ISR_RXQ_SUB_GROUP_CONFIG_SIZE_SHIFT |
+ 0 /* first rxq */);
+
+ mvpp2_ingress_disable(sc);
+ mvpp2_defaults_set(sc);
+
+ mvpp2_cls_oversize_rxq_set(sc);
+ mvpp2_cls_port_config(sc);
+
+ for (i = 0; i < sc->sc_nrxq; i++) {
+ mvpp2_rxq_long_pool_set(sc, i, sc->sc_id);
+ mvpp2_rxq_short_pool_set(sc, i, sc->sc_id);
+ }
+
+ /* Reset Mac */
+ mvpp2_gmac_write(sc, MVPP2_PORT_CTRL2_REG,
+ mvpp2_gmac_read(sc, MVPP2_PORT_CTRL2_REG) |
+ MVPP2_PORT_CTRL2_PORTMACRESET_MASK);
+ if (sc->sc_gop_id == 0) {
+ mvpp2_xlg_write(sc, MV_XLG_PORT_MAC_CTRL0_REG,
+ mvpp2_xlg_read(sc, MV_XLG_PORT_MAC_CTRL0_REG) &
+ ~MV_XLG_MAC_CTRL0_MACRESETN_MASK);
+ if (sc->sc_phy_mode == PHY_MODE_10GBASER) {
+ reg = mvpp2_mpcs_read(sc, MVPP22_MPCS_CLOCK_RESET);
+ reg |= MVPP22_MPCS_CLK_DIV_PHASE_SET_MASK;
+ reg &= ~MVPP22_MPCS_TX_SD_CLK_RESET_MASK;
+ reg &= ~MVPP22_MPCS_RX_SD_CLK_RESET_MASK;
+ reg &= ~MVPP22_MPCS_MAC_CLK_RESET_MASK;
+ mvpp2_mpcs_write(sc, MVPP22_MPCS_CLOCK_RESET, reg);
+ } else if (sc->sc_phy_mode == PHY_MODE_XAUI)
+ mvpp2_xpcs_write(sc, MVPP22_XPCS_GLOBAL_CFG_0_REG,
+ mvpp2_xpcs_read(sc, MVPP22_XPCS_GLOBAL_CFG_0_REG) &
+ ~MVPP22_XPCS_PCSRESET);
+ }
+
+ timeout_set(&sc->sc_tick, mvpp2_tick, sc);
+
+ ifp = &sc->sc_ac.ac_if;
+ ifp->if_softc = sc;
+ ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
+ ifp->if_ioctl = mvpp2_ioctl;
+ ifp->if_start = mvpp2_start;
+ ifp->if_watchdog = mvpp2_watchdog;
+ IFQ_SET_MAXLEN(&ifp->if_snd, MVPP2_NTXDESC - 1);
+ bcopy(sc->sc_dev.dv_xname, ifp->if_xname, IFNAMSIZ);
+
+ ifp->if_capabilities = IFCAP_VLAN_MTU;
+
+ sc->sc_mii.mii_ifp = ifp;
+ sc->sc_mii.mii_readreg = mvpp2_mii_readreg;
+ sc->sc_mii.mii_writereg = mvpp2_mii_writereg;
+ sc->sc_mii.mii_statchg = mvpp2_mii_statchg;
+
+ ifmedia_init(&sc->sc_media, 0, mvpp2_media_change, mvpp2_media_status);
+
+ if (sc->sc_mdio) {
+ mii_attach(self, &sc->sc_mii, 0xffffffff, sc->sc_phyloc,
+ (sc->sc_phyloc == MII_PHY_ANY) ? 0 : MII_OFFSET_ANY, 0);
+ if (LIST_FIRST(&sc->sc_mii.mii_phys) == NULL) {
+ printf("%s: no PHY found!\n", self->dv_xname);
+ ifmedia_add(&sc->sc_mii.mii_media,
+ IFM_ETHER|IFM_MANUAL, 0, NULL);
+ ifmedia_set(&sc->sc_mii.mii_media, IFM_ETHER|IFM_MANUAL);
+ } else
+ ifmedia_set(&sc->sc_mii.mii_media, IFM_ETHER|IFM_AUTO);
+ } else {
+ ifmedia_add(&sc->sc_mii.mii_media, IFM_ETHER|IFM_AUTO, 0, NULL);
+ ifmedia_set(&sc->sc_mii.mii_media, IFM_ETHER|IFM_AUTO);
+
+ if (sc->sc_inband_status) {
+ mvpp2_inband_statchg(sc);
+ } else {
+ sc->sc_mii.mii_media_status = IFM_AVALID|IFM_ACTIVE;
+ sc->sc_mii.mii_media_active = IFM_ETHER|IFM_1000_T|IFM_FDX;
+ mvpp2_mii_statchg(self);
+ }
+
+ ifp->if_baudrate = ifmedia_baudrate(sc->sc_mii.mii_media_active);
+ ifp->if_link_state = LINK_STATE_FULL_DUPLEX;
+ }
+
+ if_attach(ifp);
+ ether_ifattach(ifp);
+
+ if (sc->sc_phy_mode == PHY_MODE_2500BASEX ||
+ sc->sc_phy_mode == PHY_MODE_1000BASEX ||
+ sc->sc_phy_mode == PHY_MODE_SGMII ||
+ sc->sc_phy_mode == PHY_MODE_RGMII ||
+ sc->sc_phy_mode == PHY_MODE_RGMII_ID ||
+ sc->sc_phy_mode == PHY_MODE_RGMII_RXID ||
+ sc->sc_phy_mode == PHY_MODE_RGMII_TXID) {
+ reg = mvpp2_gmac_read(sc, MV_GMAC_INTERRUPT_MASK_REG);
+ reg |= MV_GMAC_INTERRUPT_CAUSE_LINK_CHANGE_MASK;
+ mvpp2_gmac_write(sc, MV_GMAC_INTERRUPT_MASK_REG, reg);
+ reg = mvpp2_gmac_read(sc, MV_GMAC_INTERRUPT_SUM_MASK_REG);
+ reg |= MV_GMAC_INTERRUPT_SUM_CAUSE_LINK_CHANGE_MASK;
+ mvpp2_gmac_write(sc, MV_GMAC_INTERRUPT_SUM_MASK_REG, reg);
+ }
+
+ if (sc->sc_gop_id == 0) {
+ reg = mvpp2_xlg_read(sc, MV_XLG_INTERRUPT_MASK_REG);
+ reg |= MV_XLG_INTERRUPT_LINK_CHANGE_MASK;
+ mvpp2_xlg_write(sc, MV_XLG_INTERRUPT_MASK_REG, reg);
+ reg = mvpp2_xlg_read(sc, MV_XLG_EXTERNAL_INTERRUPT_MASK_REG);
+ reg &= ~MV_XLG_EXTERNAL_INTERRUPT_LINK_CHANGE_XLG_MASK;
+ reg &= ~MV_XLG_EXTERNAL_INTERRUPT_LINK_CHANGE_GIG_MASK;
+ if (sc->sc_phy_mode == PHY_MODE_10GBASER ||
+ sc->sc_phy_mode == PHY_MODE_XAUI)
+ reg |= MV_XLG_EXTERNAL_INTERRUPT_LINK_CHANGE_XLG_MASK;
+ else
+ reg |= MV_XLG_EXTERNAL_INTERRUPT_LINK_CHANGE_GIG_MASK;
+ mvpp2_xlg_write(sc, MV_XLG_EXTERNAL_INTERRUPT_MASK_REG, reg);
+ }
+
+ idx = OF_getindex(sc->sc_node, "link", "interrupt-names");
+ if (idx >= 0)
+ fdt_intr_establish_idx(sc->sc_node, idx, IPL_NET,
+ mvpp2_link_intr, sc, sc->sc_dev.dv_xname);
+ idx = OF_getindex(sc->sc_node, "hif0", "interrupt-names");
+ if (idx < 0)
+ idx = OF_getindex(sc->sc_node, "tx-cpu0", "interrupt-names");
+ if (idx >= 0)
+ fdt_intr_establish_idx(sc->sc_node, idx, IPL_NET,
+ mvpp2_intr, sc, sc->sc_dev.dv_xname);
+}
+
+uint32_t
+mvpp2_read(struct mvpp2_softc *sc, bus_addr_t addr)
+{
+ return bus_space_read_4(sc->sc_iot, sc->sc_ioh_base, addr);
+}
+
+void
+mvpp2_write(struct mvpp2_softc *sc, bus_addr_t addr, uint32_t data)
+{
+ bus_space_write_4(sc->sc_iot, sc->sc_ioh_base, addr, data);
+}
+
+uint32_t
+mvpp2_gmac_read(struct mvpp2_port *sc, bus_addr_t addr)
+{
+ return bus_space_read_4(sc->sc->sc_iot, sc->sc->sc_ioh_iface,
+ MVPP22_GMAC_OFFSET + sc->sc_gop_id * MVPP22_GMAC_REG_SIZE + addr);
+}
+
+void
+mvpp2_gmac_write(struct mvpp2_port *sc, bus_addr_t addr, uint32_t data)
+{
+ bus_space_write_4(sc->sc->sc_iot, sc->sc->sc_ioh_iface,
+ MVPP22_GMAC_OFFSET + sc->sc_gop_id * MVPP22_GMAC_REG_SIZE + addr,
+ data);
+}
+
+uint32_t
+mvpp2_xlg_read(struct mvpp2_port *sc, bus_addr_t addr)
+{
+ return bus_space_read_4(sc->sc->sc_iot, sc->sc->sc_ioh_iface,
+ MVPP22_XLG_OFFSET + sc->sc_gop_id * MVPP22_XLG_REG_SIZE + addr);
+}
+
+void
+mvpp2_xlg_write(struct mvpp2_port *sc, bus_addr_t addr, uint32_t data)
+{
+ bus_space_write_4(sc->sc->sc_iot, sc->sc->sc_ioh_iface,
+ MVPP22_XLG_OFFSET + sc->sc_gop_id * MVPP22_XLG_REG_SIZE + addr,
+ data);
+}
+
+uint32_t
+mvpp2_mpcs_read(struct mvpp2_port *sc, bus_addr_t addr)
+{
+ return bus_space_read_4(sc->sc->sc_iot, sc->sc->sc_ioh_iface,
+ MVPP22_MPCS_OFFSET + sc->sc_gop_id * MVPP22_MPCS_REG_SIZE + addr);
+}
+
+void
+mvpp2_mpcs_write(struct mvpp2_port *sc, bus_addr_t addr, uint32_t data)
+{
+ bus_space_write_4(sc->sc->sc_iot, sc->sc->sc_ioh_iface,
+ MVPP22_MPCS_OFFSET + sc->sc_gop_id * MVPP22_MPCS_REG_SIZE + addr,
+ data);
+}
+
+uint32_t
+mvpp2_xpcs_read(struct mvpp2_port *sc, bus_addr_t addr)
+{
+ return bus_space_read_4(sc->sc->sc_iot, sc->sc->sc_ioh_iface,
+ MVPP22_XPCS_OFFSET + sc->sc_gop_id * MVPP22_XPCS_REG_SIZE + addr);
+}
+
+void
+mvpp2_xpcs_write(struct mvpp2_port *sc, bus_addr_t addr, uint32_t data)
+{
+ bus_space_write_4(sc->sc->sc_iot, sc->sc->sc_ioh_iface,
+ MVPP22_XPCS_OFFSET + sc->sc_gop_id * MVPP22_XPCS_REG_SIZE + addr,
+ data);
+}
+
+void
+mvpp2_start(struct ifnet *ifp)
+{
+ struct mvpp2_port *sc = ifp->if_softc;
+ struct mvpp2_tx_queue *txq = &sc->sc->sc_aggr_txqs[0];
+ struct mbuf *m;
+ int error, idx;
+
+ if (!(ifp->if_flags & IFF_RUNNING))
+ return;
+ if (ifq_is_oactive(&ifp->if_snd))
+ return;
+ if (IFQ_IS_EMPTY(&ifp->if_snd))
+ return;
+ if (!sc->sc_link)
+ return;
+
+ idx = txq->prod;
+ while (txq->cnt < MVPP2_NTXDESC) {
+ m = ifq_dequeue(&ifp->if_snd);
+ if (m == NULL)
+ break;
+
+ error = mvpp2_encap(sc, m, &idx);
+ if (error == ENOBUFS) {
+ m_freem(m); /* give up: drop it */
+ ifq_set_oactive(&ifp->if_snd);
+ break;
+ }
+ if (error == EFBIG) {
+ m_freem(m); /* give up: drop it */
+ ifp->if_oerrors++;
+ continue;
+ }
+
+#if NBPFILTER > 0
+ if (ifp->if_bpf)
+ bpf_mtap(ifp->if_bpf, m, BPF_DIRECTION_OUT);
+#endif
+ }
+
+ if (txq->prod != idx) {
+ txq->prod = idx;
+
+ /* Set a timeout in case the chip goes out to lunch. */
+ ifp->if_timer = 5;
+ }
+}
+
+int
+mvpp2_encap(struct mvpp2_port *sc, struct mbuf *m, int *idx)
+{
+ struct mvpp2_tx_queue *txq = &sc->sc->sc_aggr_txqs[0];
+ struct mvpp2_tx_desc *txd;
+ bus_dmamap_t map;
+ uint32_t command;
+ int i, current, first, last;
+
+ first = last = current = *idx;
+ map = txq->buf[current].mb_map;
+
+ if (bus_dmamap_load_mbuf(sc->sc_dmat, map, m, BUS_DMA_NOWAIT))
+ return ENOBUFS;
+
+ if (map->dm_nsegs > (MVPP2_NTXDESC - txq->cnt - 2)) {
+ bus_dmamap_unload(sc->sc_dmat, map);
+ return ENOBUFS;
+ }
+
+ bus_dmamap_sync(sc->sc_dmat, map, 0, map->dm_mapsize,
+ BUS_DMASYNC_PREWRITE);
+
+ command = MVPP2_TXD_L4_CSUM_NOT |
+ MVPP2_TXD_IP_CSUM_DISABLE;
+ for (i = 0; i < map->dm_nsegs; i++) {
+ txd = &txq->descs[current];
+ memset(txd, 0, sizeof(*txd));
+ txd->buf_phys_addr_hw_cmd2 =
+ map->dm_segs[i].ds_addr & ~0x1f;
+ txd->packet_offset =
+ map->dm_segs[i].ds_addr & 0x1f;
+ txd->data_size = map->dm_segs[i].ds_len;
+ txd->phys_txq = sc->sc_txqs[0].id;
+ txd->command = command |
+ MVPP2_TXD_PADDING_DISABLE;
+ if (i == 0)
+ txd->command |= MVPP2_TXD_F_DESC;
+ if (i == (map->dm_nsegs - 1))
+ txd->command |= MVPP2_TXD_L_DESC;
+
+ bus_dmamap_sync(sc->sc_dmat, MVPP2_DMA_MAP(txq->ring),
+ current * sizeof(*txd), sizeof(*txd),
+ BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
+
+ last = current;
+ current = (current + 1) % MVPP2_NTXDESC;
+ KASSERT(current != txq->cons);
+ }
+
+ KASSERT(txq->buf[last].mb_m == NULL);
+ txq->buf[first].mb_map = txq->buf[last].mb_map;
+ txq->buf[last].mb_map = map;
+ txq->buf[last].mb_m = m;
+
+ txq->cnt += map->dm_nsegs;
+ *idx = current;
+
+ mvpp2_write(sc->sc, MVPP2_AGGR_TXQ_UPDATE_REG, map->dm_nsegs);
+
+ return 0;
+}
+
+int
+mvpp2_ioctl(struct ifnet *ifp, u_long cmd, caddr_t addr)
+{
+ struct mvpp2_port *sc = ifp->if_softc;
+ struct ifreq *ifr = (struct ifreq *)addr;
+ int error = 0, s;
+
+ s = splnet();
+
+ switch (cmd) {
+ case SIOCSIFADDR:
+ ifp->if_flags |= IFF_UP;
+ /* FALLTHROUGH */
+ case SIOCSIFFLAGS:
+ if (ifp->if_flags & IFF_UP) {
+ if (ifp->if_flags & IFF_RUNNING)
+ error = ENETRESET;
+ else
+ mvpp2_up(sc);
+ } else {
+ if (ifp->if_flags & IFF_RUNNING)
+ mvpp2_down(sc);
+ }
+ break;
+
+ case SIOCGIFMEDIA:
+ case SIOCSIFMEDIA:
+ error = ifmedia_ioctl(ifp, ifr, &sc->sc_media, cmd);
+ break;
+
+ case SIOCGIFRXR:
+ error = mvpp2_rxrinfo(sc, (struct if_rxrinfo *)ifr->ifr_data);
+ break;
+
+ case SIOCGIFSFFPAGE:
+ error = rw_enter(&mvpp2_sff_lock, RW_WRITE|RW_INTR);
+ if (error != 0)
+ break;
+
+ error = sfp_get_sffpage(sc->sc_sfp, (struct if_sffpage *)addr);
+ rw_exit(&mvpp2_sff_lock);
+ break;
+
+ default:
+ error = ether_ioctl(ifp, &sc->sc_ac, cmd, addr);
+ break;
+ }
+
+ if (error == ENETRESET) {
+ if (ifp->if_flags & IFF_RUNNING)
+ mvpp2_iff(sc);
+ error = 0;
+ }
+
+ splx(s);
+ return (error);
+}
+
+int
+mvpp2_rxrinfo(struct mvpp2_port *sc, struct if_rxrinfo *ifri)
+{
+ struct mvpp2_rx_queue *rxq;
+ struct if_rxring_info *ifrs, *ifr;
+ unsigned int i;
+ int error;
+
+ ifrs = mallocarray(sc->sc_nrxq, sizeof(*ifrs), M_TEMP,
+ M_WAITOK|M_ZERO|M_CANFAIL);
+ if (ifrs == NULL)
+ return (ENOMEM);
+
+ for (i = 0; i < sc->sc_nrxq; i++) {
+ rxq = &sc->sc_rxqs[i];
+ ifr = &ifrs[i];
+
+ snprintf(ifr->ifr_name, sizeof(ifr->ifr_name), "%u", i);
+ ifr->ifr_size = MCLBYTES;
+ ifr->ifr_info = rxq->rxring;
+ }
+
+ error = if_rxr_info_ioctl(ifri, i, ifrs);
+ free(ifrs, M_TEMP, i * sizeof(*ifrs));
+
+ return (error);
+}
+
+void
+mvpp2_watchdog(struct ifnet *ifp)
+{
+ printf("%s\n", __func__);
+}
+
+int
+mvpp2_media_change(struct ifnet *ifp)
+{
+ struct mvpp2_port *sc = ifp->if_softc;
+
+ if (LIST_FIRST(&sc->sc_mii.mii_phys))
+ mii_mediachg(&sc->sc_mii);
+
+ return (0);
+}
+
+void
+mvpp2_media_status(struct ifnet *ifp, struct ifmediareq *ifmr)
+{
+ struct mvpp2_port *sc = ifp->if_softc;
+
+ if (LIST_FIRST(&sc->sc_mii.mii_phys))
+ mii_pollstat(&sc->sc_mii);
+
+ ifmr->ifm_active = sc->sc_mii.mii_media_active;
+ ifmr->ifm_status = sc->sc_mii.mii_media_status;
+}
+
+int
+mvpp2_mii_readreg(struct device *self, int phy, int reg)
+{
+ struct mvpp2_port *sc = (void *)self;
+ return sc->sc_mdio->md_readreg(sc->sc_mdio->md_cookie, phy, reg);
+}
+
+void
+mvpp2_mii_writereg(struct device *self, int phy, int reg, int val)
+{
+ struct mvpp2_port *sc = (void *)self;
+ return sc->sc_mdio->md_writereg(sc->sc_mdio->md_cookie, phy, reg, val);
+}
+
+void
+mvpp2_mii_statchg(struct device *self)
+{
+ struct mvpp2_port *sc = (void *)self;
+ mvpp2_port_change(sc);
+}
+
+void
+mvpp2_inband_statchg(struct mvpp2_port *sc)
+{
+ uint32_t reg;
+
+ sc->sc_mii.mii_media_status = IFM_AVALID;
+ sc->sc_mii.mii_media_active = IFM_ETHER;
+
+ if (sc->sc_gop_id == 0 && (sc->sc_phy_mode == PHY_MODE_10GBASER ||
+ sc->sc_phy_mode == PHY_MODE_XAUI)) {
+ reg = mvpp2_xlg_read(sc, MV_XLG_MAC_PORT_STATUS_REG);
+ if (reg & MV_XLG_MAC_PORT_STATUS_LINKSTATUS_MASK)
+ sc->sc_mii.mii_media_status |= IFM_ACTIVE;
+ sc->sc_mii.mii_media_active |= IFM_FDX;
+ sc->sc_mii.mii_media_active |= IFM_10G_SR;
+ } else {
+ reg = mvpp2_gmac_read(sc, MVPP2_PORT_STATUS0_REG);
+ if (reg & MVPP2_PORT_STATUS0_LINKUP_MASK)
+ sc->sc_mii.mii_media_status |= IFM_ACTIVE;
+ if (reg & MVPP2_PORT_STATUS0_FULLDX_MASK)
+ sc->sc_mii.mii_media_active |= IFM_FDX;
+ if (sc->sc_phy_mode == PHY_MODE_2500BASEX)
+ sc->sc_mii.mii_media_active |= IFM_2500_SX;
+ else if (sc->sc_phy_mode == PHY_MODE_1000BASEX)
+ sc->sc_mii.mii_media_active |= IFM_1000_SX;
+ else if (reg & MVPP2_PORT_STATUS0_GMIISPEED_MASK)
+ sc->sc_mii.mii_media_active |= IFM_1000_T;
+ else if (reg & MVPP2_PORT_STATUS0_MIISPEED_MASK)
+ sc->sc_mii.mii_media_active |= IFM_100_TX;
+ else
+ sc->sc_mii.mii_media_active |= IFM_10_T;
+ }
+
+ mvpp2_port_change(sc);
+}
+
+void
+mvpp2_port_change(struct mvpp2_port *sc)
+{
+ uint32_t reg;
+
+ if (!!(sc->sc_mii.mii_media_status & IFM_ACTIVE) == sc->sc_link)
+ return;
+
+ sc->sc_link = !sc->sc_link;
+
+ if (sc->sc_inband_status)
+ return;
+
+ if (sc->sc_link) {
+ if (sc->sc_phy_mode == PHY_MODE_10GBASER ||
+ sc->sc_phy_mode == PHY_MODE_XAUI) {
+ reg = mvpp2_xlg_read(sc, MV_XLG_PORT_MAC_CTRL0_REG);
+ reg &= ~MV_XLG_MAC_CTRL0_FORCELINKDOWN_MASK;
+ reg |= MV_XLG_MAC_CTRL0_FORCELINKPASS_MASK;
+ mvpp2_xlg_write(sc, MV_XLG_PORT_MAC_CTRL0_REG, reg);
+ } else {
+ reg = mvpp2_gmac_read(sc, MVPP2_GMAC_AUTONEG_CONFIG);
+ reg &= ~MVPP2_GMAC_FORCE_LINK_DOWN;
+ reg |= MVPP2_GMAC_FORCE_LINK_PASS;
+ reg &= ~MVPP2_GMAC_CONFIG_MII_SPEED;
+ reg &= ~MVPP2_GMAC_CONFIG_GMII_SPEED;
+ reg &= ~MVPP2_GMAC_CONFIG_FULL_DUPLEX;
+ if (IFM_SUBTYPE(sc->sc_mii.mii_media_active) == IFM_2500_SX ||
+ IFM_SUBTYPE(sc->sc_mii.mii_media_active) == IFM_1000_SX ||
+ IFM_SUBTYPE(sc->sc_mii.mii_media_active) == IFM_1000_T)
+ reg |= MVPP2_GMAC_CONFIG_GMII_SPEED;
+ if (IFM_SUBTYPE(sc->sc_mii.mii_media_active) == IFM_100_TX)
+ reg |= MVPP2_GMAC_CONFIG_MII_SPEED;
+ if ((sc->sc_mii.mii_media_active & IFM_GMASK) == IFM_FDX)
+ reg |= MVPP2_GMAC_CONFIG_FULL_DUPLEX;
+ mvpp2_gmac_write(sc, MVPP2_GMAC_AUTONEG_CONFIG, reg);
+ }
+ } else {
+ if (sc->sc_phy_mode == PHY_MODE_10GBASER ||
+ sc->sc_phy_mode == PHY_MODE_XAUI) {
+ reg = mvpp2_xlg_read(sc, MV_XLG_PORT_MAC_CTRL0_REG);
+ reg &= ~MV_XLG_MAC_CTRL0_FORCELINKPASS_MASK;
+ reg |= MV_XLG_MAC_CTRL0_FORCELINKDOWN_MASK;
+ mvpp2_xlg_write(sc, MV_XLG_PORT_MAC_CTRL0_REG, reg);
+ } else {
+ reg = mvpp2_gmac_read(sc, MVPP2_GMAC_AUTONEG_CONFIG);
+ reg &= ~MVPP2_GMAC_FORCE_LINK_PASS;
+ reg |= MVPP2_GMAC_FORCE_LINK_DOWN;
+ mvpp2_gmac_write(sc, MVPP2_GMAC_AUTONEG_CONFIG, reg);
+ }
+ }
+}
+
+void
+mvpp2_tick(void *arg)
+{
+ struct mvpp2_port *sc = arg;
+ int s;
+
+ s = splnet();
+ mii_tick(&sc->sc_mii);
+ splx(s);
+
+ timeout_add_sec(&sc->sc_tick, 1);
+}
+
+int
+mvpp2_link_intr(void *arg)
+{
+ struct mvpp2_port *sc = arg;
+ uint32_t reg;
+ int event = 0;
+
+ if (sc->sc_gop_id == 0 && (sc->sc_phy_mode == PHY_MODE_10GBASER ||
+ sc->sc_phy_mode == PHY_MODE_XAUI)) {
+ reg = mvpp2_xlg_read(sc, MV_XLG_INTERRUPT_CAUSE_REG);
+ if (reg & MV_XLG_INTERRUPT_LINK_CHANGE_MASK)
+ event = 1;
+ } else if (sc->sc_phy_mode == PHY_MODE_2500BASEX ||
+ sc->sc_phy_mode == PHY_MODE_1000BASEX ||
+ sc->sc_phy_mode == PHY_MODE_SGMII ||
+ sc->sc_phy_mode == PHY_MODE_RGMII ||
+ sc->sc_phy_mode == PHY_MODE_RGMII_ID ||
+ sc->sc_phy_mode == PHY_MODE_RGMII_RXID ||
+ sc->sc_phy_mode == PHY_MODE_RGMII_TXID) {
+ reg = mvpp2_gmac_read(sc, MV_GMAC_INTERRUPT_CAUSE_REG);
+ if (reg & MV_GMAC_INTERRUPT_CAUSE_LINK_CHANGE_MASK)
+ event = 1;
+ }
+
+ if (event && sc->sc_inband_status)
+ mvpp2_inband_statchg(sc);
+
+ return (1);
+}
+
+int
+mvpp2_intr(void *arg)
+{
+ struct mvpp2_port *sc = arg;
+ uint32_t reg;
+
+ reg = mvpp2_read(sc->sc, MVPP2_ISR_RX_TX_CAUSE_REG(sc->sc_id));
+ if (reg & MVPP2_CAUSE_MISC_SUM_MASK) {
+ mvpp2_write(sc->sc, MVPP2_ISR_MISC_CAUSE_REG, 0);
+ mvpp2_write(sc->sc, MVPP2_ISR_RX_TX_CAUSE_REG(sc->sc_id),
+ reg & ~MVPP2_CAUSE_MISC_SUM_MASK);
+ }
+ if (reg & MVPP2_CAUSE_TXQ_OCCUP_DESC_ALL_MASK)
+ mvpp2_tx_proc(sc,
+ (reg & MVPP2_CAUSE_TXQ_OCCUP_DESC_ALL_MASK) >>
+ MVPP2_CAUSE_TXQ_OCCUP_DESC_ALL_OFFSET);
+
+ if (reg & MVPP2_CAUSE_RXQ_OCCUP_DESC_ALL_MASK)
+ mvpp2_rx_proc(sc,
+ reg & MVPP2_CAUSE_RXQ_OCCUP_DESC_ALL_MASK);
+
+ return (1);
+}
+
+void
+mvpp2_tx_proc(struct mvpp2_port *sc, uint8_t queues)
+{
+// struct ifnet *ifp = &sc->sc_ac.ac_if;
+ struct mvpp2_tx_queue *txq;
+ uint32_t reg;
+ int i;
+
+ for (i = 0; i < sc->sc_ntxq; i++) {
+ txq = &sc->sc_txqs[i];
+ if ((queues & (1 << i)) == 0)
+ continue;
+ reg = mvpp2_read(sc->sc, MVPP2_TXQ_SENT_REG(txq->id));
+ printf("%s: txq %u sent reg %u\n", sc->sc_dev.dv_xname,
+ i, (reg & MVPP2_TRANSMITTED_COUNT_MASK) >>
+ MVPP2_TRANSMITTED_COUNT_OFFSET);
+ }
+
+ /* FIXME: tx done processing */
+}
+
+void
+mvpp2_rx_proc(struct mvpp2_port *sc, uint8_t queues)
+{
+ struct mvpp2_rx_queue *rxq;
+ int i;
+
+ for (i = 0; i < sc->sc_nrxq; i++) {
+ rxq = &sc->sc_rxqs[i];
+ if ((queues & (1 << i)) == 0)
+ continue;
+ mvpp2_rxq_proc(sc, rxq);
+ }
+}
+
+void
+mvpp2_rxq_proc(struct mvpp2_port *sc, struct mvpp2_rx_queue *rxq)
+{
+ struct ifnet *ifp = &sc->sc_ac.ac_if;
+ struct mbuf_list ml = MBUF_LIST_INITIALIZER();
+ struct mvpp2_rx_desc *rxd;
+ struct mvpp2_bm_pool *bm;
+ struct mvpp2_buf *rxb;
+ struct mbuf *m;
+ uint64_t virt;
+ uint32_t i, nrecv;
+
+ nrecv = mvpp2_rxq_received(sc, rxq->id);
+ if (!nrecv)
+ return;
+
+ printf("%s: rxq %u recv %u\n", sc->sc_dev.dv_xname,
+ rxq->id, nrecv);
+
+ bus_dmamap_sync(sc->sc_dmat, MVPP2_DMA_MAP(rxq->ring), 0,
+ MVPP2_DMA_LEN(rxq->ring),
+ BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE);
+
+ for (i = 0; i < nrecv; i++) {
+ rxd = &rxq->descs[rxq->cons];
+ virt = rxd->buf_cookie_bm_qset_cls_info;
+ bm = &sc->sc->sc_bm_pools[(virt >> 16) & 0xffff];
+ rxb = &bm->rxbuf[virt & 0xffff];
+ KASSERT(rxb);
+ KASSERT(rxb->mb_m);
+
+ bus_dmamap_sync(sc->sc_dmat, rxb->mb_map, 0,
+ rxd->data_size, BUS_DMASYNC_POSTREAD);
+ bus_dmamap_unload(sc->sc_dmat, rxb->mb_map);
+
+ m = rxb->mb_m;
+ rxb->mb_m = NULL;
+
+ m->m_pkthdr.len = m->m_len = rxd->data_size;
+ m_adj(m, MVPP2_MH_SIZE);
+ ml_enqueue(&ml, m);
+
+ rxq->cons = (rxq->cons + 1) % MVPP2_NRXDESC;
+ }
+
+ /*mvpp2_fill_rx_ring(sc);*/
+
+ bus_dmamap_sync(sc->sc_dmat, MVPP2_DMA_MAP(rxq->ring), 0,
+ MVPP2_DMA_LEN(rxq->ring),
+ BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
+
+ mvpp2_rxq_status_update(sc, rxq->id, nrecv, nrecv);
+
+ if_input(ifp, &ml);
+}
+
+void
+mvpp2_up(struct mvpp2_port *sc)
+{
+ struct ifnet *ifp = &sc->sc_ac.ac_if;
+ int i;
+
+ memcpy(sc->sc_cur_lladdr, sc->sc_lladdr, ETHER_ADDR_LEN);
+ mvpp2_prs_mac_da_accept(sc->sc, sc->sc_id, etherbroadcastaddr, 1);
+ mvpp2_prs_mac_da_accept(sc->sc, sc->sc_id, sc->sc_cur_lladdr, 1);
+ /* FIXME: not promisc!!! */
+ mvpp2_prs_mac_promisc_set(sc->sc, sc->sc_id, 1);
+ mvpp2_prs_tag_mode_set(sc->sc, sc->sc_id, MVPP2_TAG_TYPE_MH);
+ mvpp2_prs_def_flow(sc);
+
+ for (i = 0; i < sc->sc_ntxq; i++)
+ mvpp2_txq_hw_init(sc, &sc->sc_txqs[i]);
+
+ mvpp2_tx_time_coal_set(sc, sc->sc_tx_time_coal);
+
+ for (i = 0; i < sc->sc_nrxq; i++)
+ mvpp2_rxq_hw_init(sc, &sc->sc_rxqs[i]);
+
+ /* FIXME: rx buffer fill */
+
+ /* Configure media. */
+ if (LIST_FIRST(&sc->sc_mii.mii_phys))
+ mii_mediachg(&sc->sc_mii);
+
+ /* Program promiscuous mode and multicast filters. */
+ mvpp2_iff(sc);
+
+ ifp->if_flags |= IFF_RUNNING;
+ ifq_clr_oactive(&ifp->if_snd);
+
+ mvpp2_txp_max_tx_size_set(sc);
+
+ /* XXX: single vector */
+ mvpp2_write(sc->sc, MVPP2_ISR_RX_TX_MASK_REG(sc->sc_id),
+ MVPP2_CAUSE_RXQ_OCCUP_DESC_ALL_MASK |
+ MVPP2_CAUSE_TXQ_OCCUP_DESC_ALL_MASK |
+ MVPP2_CAUSE_MISC_SUM_MASK);
+ mvpp2_interrupts_enable(sc, (1 << 0));
+
+ mvpp2_mac_config(sc);
+ mvpp2_egress_enable(sc);
+ mvpp2_ingress_enable(sc);
+
+ timeout_add_sec(&sc->sc_tick, 1);
+}
+
+void
+mvpp2_aggr_txq_hw_init(struct mvpp2_softc *sc, struct mvpp2_tx_queue *txq)
+{
+ struct mvpp2_buf *txb;
+ int i;
+
+ txq->ring = mvpp2_dmamem_alloc(sc,
+ MVPP2_AGGR_TXQ_SIZE * sizeof(struct mvpp2_tx_desc), 32);
+ txq->descs = MVPP2_DMA_KVA(txq->ring);
+
+ txq->buf = mallocarray(MVPP2_AGGR_TXQ_SIZE, sizeof(struct mvpp2_buf),
+ M_DEVBUF, M_WAITOK);
+
+ for (i = 0; i < MVPP2_AGGR_TXQ_SIZE; i++) {
+ txb = &txq->buf[i];
+ bus_dmamap_create(sc->sc_dmat, MCLBYTES, MVPP2_NTXSEGS,
+ MCLBYTES, 0, BUS_DMA_WAITOK, &txb->mb_map);
+ txb->mb_m = NULL;
+ }
+
+ bus_dmamap_sync(sc->sc_dmat, MVPP2_DMA_MAP(txq->ring), 0,
+ MVPP2_DMA_LEN(txq->ring), BUS_DMASYNC_PREWRITE);
+
+ txq->prod = mvpp2_read(sc, MVPP2_AGGR_TXQ_INDEX_REG(txq->id));
+ mvpp2_write(sc, MVPP2_AGGR_TXQ_DESC_ADDR_REG(txq->id),
+ MVPP2_DMA_DVA(txq->ring) >> MVPP22_DESC_ADDR_SHIFT);
+ mvpp2_write(sc, MVPP2_AGGR_TXQ_DESC_SIZE_REG(txq->id),
+ MVPP2_AGGR_TXQ_SIZE);
+}
+
+void
+mvpp2_txq_hw_init(struct mvpp2_port *sc, struct mvpp2_tx_queue *txq)
+{
+ struct mvpp2_buf *txb;
+ int desc, desc_per_txq;
+ uint32_t reg;
+ int i;
+
+ txq->prod = txq->cons = txq->cnt = 0;
+// txq->last_desc = txq->size - 1;
+
+ txq->ring = mvpp2_dmamem_alloc(sc->sc,
+ MVPP2_NTXDESC * sizeof(struct mvpp2_tx_desc), 32);
+ txq->descs = MVPP2_DMA_KVA(txq->ring);
+
+ txq->buf = mallocarray(MVPP2_NTXDESC, sizeof(struct mvpp2_buf),
+ M_DEVBUF, M_WAITOK);
+
+ for (i = 0; i < MVPP2_NTXDESC; i++) {
+ txb = &txq->buf[i];
+ bus_dmamap_create(sc->sc_dmat, MCLBYTES, MVPP2_NTXSEGS,
+ MCLBYTES, 0, BUS_DMA_WAITOK, &txb->mb_map);
+ txb->mb_m = NULL;
+ }
+
+ bus_dmamap_sync(sc->sc_dmat, MVPP2_DMA_MAP(txq->ring), 0,
+ MVPP2_DMA_LEN(txq->ring), BUS_DMASYNC_PREWRITE);
+
+ mvpp2_write(sc->sc, MVPP2_TXQ_NUM_REG, txq->id);
+ mvpp2_write(sc->sc, MVPP2_TXQ_DESC_ADDR_REG,
+ MVPP2_DMA_DVA(txq->ring));
+ mvpp2_write(sc->sc, MVPP2_TXQ_DESC_SIZE_REG,
+ MVPP2_NTXDESC & MVPP2_TXQ_DESC_SIZE_MASK);
+ mvpp2_write(sc->sc, MVPP2_TXQ_INDEX_REG, 0);
+ mvpp2_write(sc->sc, MVPP2_TXQ_RSVD_CLR_REG,
+ txq->id << MVPP2_TXQ_RSVD_CLR_OFFSET);
+ reg = mvpp2_read(sc->sc, MVPP2_TXQ_PENDING_REG);
+ reg &= ~MVPP2_TXQ_PENDING_MASK;
+ mvpp2_write(sc->sc, MVPP2_TXQ_PENDING_REG, reg);
+
+ desc_per_txq = 16;
+ desc = (sc->sc_id * MVPP2_MAX_TXQ * desc_per_txq) +
+ (txq->log_id * desc_per_txq);
+
+ mvpp2_write(sc->sc, MVPP2_TXQ_PREF_BUF_REG,
+ MVPP2_PREF_BUF_PTR(desc) | MVPP2_PREF_BUF_SIZE_16 |
+ MVPP2_PREF_BUF_THRESH(desc_per_txq / 2));
+
+ /* WRR / EJP configuration - indirect access */
+ mvpp2_write(sc->sc, MVPP2_TXP_SCHED_PORT_INDEX_REG,
+ mvpp2_egress_port(sc));
+
+ reg = mvpp2_read(sc->sc, MVPP2_TXQ_SCHED_REFILL_REG(txq->log_id));
+ reg &= ~MVPP2_TXQ_REFILL_PERIOD_ALL_MASK;
+ reg |= MVPP2_TXQ_REFILL_PERIOD_MASK(1);
+ reg |= MVPP2_TXQ_REFILL_TOKENS_ALL_MASK;
+ mvpp2_write(sc->sc, MVPP2_TXQ_SCHED_REFILL_REG(txq->log_id), reg);
+
+ mvpp2_write(sc->sc, MVPP2_TXQ_SCHED_TOKEN_SIZE_REG(txq->log_id),
+ MVPP2_TXQ_TOKEN_SIZE_MAX);
+
+ mvpp2_tx_pkts_coal_set(sc, txq, txq->done_pkts_coal);
+}
+
+void
+mvpp2_rxq_hw_init(struct mvpp2_port *sc, struct mvpp2_rx_queue *rxq)
+{
+ rxq->prod = rxq->cons = 0;
+
+ rxq->ring = mvpp2_dmamem_alloc(sc->sc,
+ MVPP2_NRXDESC * sizeof(struct mvpp2_rx_desc), 32);
+ rxq->descs = MVPP2_DMA_KVA(rxq->ring);
+
+ bus_dmamap_sync(sc->sc_dmat, MVPP2_DMA_MAP(rxq->ring),
+ 0, MVPP2_DMA_LEN(rxq->ring),
+ BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE);
+
+ mvpp2_write(sc->sc, MVPP2_RXQ_STATUS_REG(rxq->id), 0);
+ mvpp2_write(sc->sc, MVPP2_RXQ_NUM_REG, rxq->id);
+ mvpp2_write(sc->sc, MVPP2_RXQ_DESC_ADDR_REG,
+ MVPP2_DMA_DVA(rxq->ring) >> MVPP22_DESC_ADDR_SHIFT);
+ mvpp2_write(sc->sc, MVPP2_RXQ_DESC_SIZE_REG, MVPP2_NRXDESC);
+ mvpp2_write(sc->sc, MVPP2_RXQ_INDEX_REG, 0);
+ mvpp2_rxq_offset_set(sc, rxq->id, 0);
+ mvpp2_rx_pkts_coal_set(sc, rxq, rxq->pkts_coal);
+ mvpp2_rx_time_coal_set(sc, rxq, rxq->time_coal);
+ mvpp2_rxq_status_update(sc, rxq->id, 0, MVPP2_NRXDESC);
+}
+
+void
+mvpp2_mac_config(struct mvpp2_port *sc)
+{
+ uint32_t reg;
+
+ mvpp2_port_disable(sc);
+
+ mvpp2_gmac_write(sc, MVPP2_PORT_CTRL2_REG,
+ mvpp2_gmac_read(sc, MVPP2_PORT_CTRL2_REG) |
+ MVPP2_PORT_CTRL2_PORTMACRESET_MASK);
+ if (sc->sc_gop_id == 0) {
+ mvpp2_xlg_write(sc, MV_XLG_PORT_MAC_CTRL0_REG,
+ mvpp2_xlg_read(sc, MV_XLG_PORT_MAC_CTRL0_REG) &
+ ~MV_XLG_MAC_CTRL0_MACRESETN_MASK);
+ if (sc->sc_phy_mode == PHY_MODE_10GBASER) {
+ reg = mvpp2_mpcs_read(sc, MVPP22_MPCS_CLOCK_RESET);
+ reg |= MVPP22_MPCS_CLK_DIV_PHASE_SET_MASK;
+ reg &= ~MVPP22_MPCS_TX_SD_CLK_RESET_MASK;
+ reg &= ~MVPP22_MPCS_RX_SD_CLK_RESET_MASK;
+ reg &= ~MVPP22_MPCS_MAC_CLK_RESET_MASK;
+ mvpp2_mpcs_write(sc, MVPP22_MPCS_CLOCK_RESET, reg);
+ } else if (sc->sc_phy_mode == PHY_MODE_XAUI)
+ mvpp2_xpcs_write(sc, MVPP22_XPCS_GLOBAL_CFG_0_REG,
+ mvpp2_xpcs_read(sc, MVPP22_XPCS_GLOBAL_CFG_0_REG) &
+ ~MVPP22_XPCS_PCSRESET);
+ }
+
+ if (sc->sc_gop_id == 0) {
+ if (sc->sc_phy_mode == PHY_MODE_10GBASER) {
+ reg = mvpp2_mpcs_read(sc, MVPP22_MPCS_CLOCK_RESET);
+ reg &= ~MVPP22_MPCS_CLK_DIV_PHASE_SET_MASK;
+ reg |= MVPP22_MPCS_TX_SD_CLK_RESET_MASK;
+ reg |= MVPP22_MPCS_RX_SD_CLK_RESET_MASK;
+ reg |= MVPP22_MPCS_MAC_CLK_RESET_MASK;
+ mvpp2_mpcs_write(sc, MVPP22_MPCS_CLOCK_RESET, reg);
+ } else if (sc->sc_phy_mode == PHY_MODE_XAUI)
+ mvpp2_xpcs_write(sc, MVPP22_XPCS_GLOBAL_CFG_0_REG,
+ mvpp2_xpcs_read(sc, MVPP22_XPCS_GLOBAL_CFG_0_REG) |
+ MVPP22_XPCS_PCSRESET);
+
+ reg = mvpp2_xlg_read(sc, MV_XLG_PORT_MAC_CTRL3_REG);
+ reg &= ~MV_XLG_MAC_CTRL3_MACMODESELECT_MASK;
+ if (sc->sc_phy_mode == PHY_MODE_10GBASER ||
+ sc->sc_phy_mode == PHY_MODE_XAUI)
+ reg |= MV_XLG_MAC_CTRL3_MACMODESELECT_10G;
+ else
+ reg |= MV_XLG_MAC_CTRL3_MACMODESELECT_GMAC;
+ mvpp2_xlg_write(sc, MV_XLG_PORT_MAC_CTRL3_REG, reg);
+ }
+
+ if (sc->sc_gop_id == 0 && (sc->sc_phy_mode == PHY_MODE_10GBASER ||
+ sc->sc_phy_mode == PHY_MODE_XAUI)) {
+ reg = mvpp2_xlg_read(sc, MV_XLG_PORT_MAC_CTRL1_REG);
+ reg &= ~MV_XLG_MAC_CTRL1_FRAMESIZELIMIT_MASK;
+ reg |= ((MCLBYTES - MVPP2_MH_SIZE) / 2) <<
+ MV_XLG_MAC_CTRL1_FRAMESIZELIMIT_OFFS;
+ mvpp2_xlg_write(sc, MV_XLG_PORT_MAC_CTRL1_REG, reg);
+ } else {
+ reg = mvpp2_gmac_read(sc, MVPP2_GMAC_CTRL_0_REG);
+ reg &= ~MVPP2_GMAC_MAX_RX_SIZE_MASK;
+ reg |= ((MCLBYTES - MVPP2_MH_SIZE) / 2) <<
+ MVPP2_GMAC_MAX_RX_SIZE_OFFS;
+ mvpp2_gmac_write(sc, MVPP2_GMAC_CTRL_0_REG, reg);
+ }
+
+ if (sc->sc_gop_id == 0 && (sc->sc_phy_mode == PHY_MODE_10GBASER ||
+ sc->sc_phy_mode == PHY_MODE_XAUI))
+ mvpp2_xlg_config(sc);
+ else
+ mvpp2_gmac_config(sc);
+
+ mvpp2_port_enable(sc);
+}
+
+void
+mvpp2_xlg_config(struct mvpp2_port *sc)
+{
+ uint32_t ctl0, ctl4;
+
+ ctl0 = mvpp2_xlg_read(sc, MV_XLG_PORT_MAC_CTRL0_REG);
+ ctl4 = mvpp2_xlg_read(sc, MV_XLG_PORT_MAC_CTRL4_REG);
+
+ ctl0 |= MV_XLG_MAC_CTRL0_MACRESETN_MASK;
+ ctl4 &= ~MV_XLG_MAC_CTRL4_EN_IDLE_CHECK_FOR_LINK;
+ ctl4 |= MV_XLG_MAC_CTRL4_FORWARD_PFC_EN_OFFS;
+ ctl4 |= MV_XLG_MAC_CTRL4_FORWARD_802_3X_FC_EN_MASK;
+
+ mvpp2_xlg_write(sc, MV_XLG_PORT_MAC_CTRL0_REG, ctl0);
+ mvpp2_xlg_write(sc, MV_XLG_PORT_MAC_CTRL4_REG, ctl0);
+
+ /* Port reset */
+ while ((mvpp2_xlg_read(sc, MV_XLG_PORT_MAC_CTRL0_REG) &
+ MV_XLG_MAC_CTRL0_MACRESETN_MASK) == 0)
+ ;
+}
+
+void
+mvpp2_gmac_config(struct mvpp2_port *sc)
+{
+ uint32_t ctl0, ctl2, ctl4, panc;
+
+ /* Setup phy. */
+ ctl0 = mvpp2_gmac_read(sc, MVPP2_PORT_CTRL0_REG);
+ ctl2 = mvpp2_gmac_read(sc, MVPP2_PORT_CTRL2_REG);
+ ctl4 = mvpp2_gmac_read(sc, MVPP2_PORT_CTRL4_REG);
+ panc = mvpp2_gmac_read(sc, MVPP2_GMAC_AUTONEG_CONFIG);
+
+ /* Force link down to change in-band settings. */
+ panc &= ~MVPP2_GMAC_FORCE_LINK_PASS;
+ panc |= MVPP2_GMAC_FORCE_LINK_DOWN;
+ mvpp2_gmac_write(sc, MVPP2_GMAC_AUTONEG_CONFIG, panc);
+
+ ctl0 &= ~MVPP2_GMAC_PORT_TYPE_MASK;
+ ctl2 &= ~(MVPP2_GMAC_PORT_RESET_MASK | MVPP2_GMAC_PCS_ENABLE_MASK |
+ MVPP2_GMAC_INBAND_AN_MASK);
+ panc &= ~(MVPP2_GMAC_AN_DUPLEX_EN | MVPP2_GMAC_FLOW_CTRL_AUTONEG |
+ MVPP2_GMAC_FC_ADV_ASM_EN | MVPP2_GMAC_FC_ADV_EN |
+ MVPP2_GMAC_AN_SPEED_EN | MVPP2_GMAC_IN_BAND_AUTONEG_BYPASS |
+ MVPP2_GMAC_IN_BAND_AUTONEG);
+
+ switch (sc->sc_phy_mode) {
+ case PHY_MODE_XAUI:
+ case PHY_MODE_10GBASER:
+ break;
+ case PHY_MODE_2500BASEX:
+ case PHY_MODE_1000BASEX:
+ ctl2 |= MVPP2_GMAC_PCS_ENABLE_MASK;
+ ctl4 &= ~MVPP2_PORT_CTRL4_EXT_PIN_GMII_SEL_MASK;
+ ctl4 |= MVPP2_PORT_CTRL4_SYNC_BYPASS_MASK;
+ ctl4 |= MVPP2_PORT_CTRL4_DP_CLK_SEL_MASK;
+ ctl4 |= MVPP2_PORT_CTRL4_QSGMII_BYPASS_ACTIVE_MASK;
+ break;
+ case PHY_MODE_SGMII:
+ ctl2 |= MVPP2_GMAC_PCS_ENABLE_MASK;
+ ctl2 |= MVPP2_GMAC_INBAND_AN_MASK;
+ ctl4 &= ~MVPP2_PORT_CTRL4_EXT_PIN_GMII_SEL_MASK;
+ ctl4 |= MVPP2_PORT_CTRL4_SYNC_BYPASS_MASK;
+ ctl4 |= MVPP2_PORT_CTRL4_DP_CLK_SEL_MASK;
+ ctl4 |= MVPP2_PORT_CTRL4_QSGMII_BYPASS_ACTIVE_MASK;
+ break;
+ case PHY_MODE_RGMII:
+ case PHY_MODE_RGMII_ID:
+ case PHY_MODE_RGMII_RXID:
+ case PHY_MODE_RGMII_TXID:
+ ctl4 &= ~MVPP2_PORT_CTRL4_DP_CLK_SEL_MASK;
+ ctl4 |= MVPP2_PORT_CTRL4_EXT_PIN_GMII_SEL_MASK;
+ ctl4 |= MVPP2_PORT_CTRL4_SYNC_BYPASS_MASK;
+ ctl4 |= MVPP2_PORT_CTRL4_QSGMII_BYPASS_ACTIVE_MASK;
+ break;
+ }
+
+ /* Use Auto-Negotiation for Inband Status only */
+ if (sc->sc_inband_status) {
+ panc &= ~MVPP2_GMAC_FORCE_LINK_DOWN;
+ panc &= ~MVPP2_GMAC_FORCE_LINK_PASS;
+ panc &= ~MVPP2_GMAC_CONFIG_MII_SPEED;
+ panc &= ~MVPP2_GMAC_CONFIG_GMII_SPEED;
+ panc &= ~MVPP2_GMAC_CONFIG_FULL_DUPLEX;
+ panc |= MVPP2_GMAC_IN_BAND_AUTONEG;
+ /* TODO: read mode from SFP */
+ if (1) {
+ /* 802.3z */
+ ctl0 |= MVPP2_GMAC_PORT_TYPE_MASK;
+ panc |= MVPP2_GMAC_CONFIG_GMII_SPEED;
+ panc |= MVPP2_GMAC_CONFIG_FULL_DUPLEX;
+ } else {
+ /* SGMII */
+ panc |= MVPP2_GMAC_AN_SPEED_EN;
+ panc |= MVPP2_GMAC_AN_DUPLEX_EN;
+ }
+ }
+
+ mvpp2_gmac_write(sc, MVPP2_PORT_CTRL0_REG, ctl0);
+ mvpp2_gmac_write(sc, MVPP2_PORT_CTRL2_REG, ctl2);
+ mvpp2_gmac_write(sc, MVPP2_PORT_CTRL4_REG, ctl4);
+ mvpp2_gmac_write(sc, MVPP2_GMAC_AUTONEG_CONFIG, panc);
+
+ /* Port reset */
+ while (mvpp2_gmac_read(sc, MVPP2_PORT_CTRL2_REG) &
+ MVPP2_PORT_CTRL2_PORTMACRESET_MASK)
+ ;
+}
+
+void
+mvpp2_down(struct mvpp2_port *sc)
+{
+ struct ifnet *ifp = &sc->sc_ac.ac_if;
+ uint32_t reg;
+ int i;
+
+ timeout_del(&sc->sc_tick);
+
+ ifp->if_flags &= ~IFF_RUNNING;
+ ifq_clr_oactive(&ifp->if_snd);
+ ifp->if_timer = 0;
+
+ mvpp2_egress_disable(sc);
+ mvpp2_ingress_disable(sc);
+ mvpp2_port_disable(sc);
+
+ /* XXX: single vector */
+ mvpp2_interrupts_disable(sc, (1 << 0));
+ mvpp2_write(sc->sc, MVPP2_ISR_RX_TX_MASK_REG(sc->sc_id), 0);
+
+ reg = mvpp2_read(sc->sc, MVPP2_TX_PORT_FLUSH_REG);
+ reg |= MVPP2_TX_PORT_FLUSH_MASK(sc->sc_id);
+ mvpp2_write(sc->sc, MVPP2_TX_PORT_FLUSH_REG, reg);
+
+ for (i = 0; i < sc->sc_ntxq; i++)
+ mvpp2_txq_hw_deinit(sc, &sc->sc_txqs[i]);
+
+ reg &= ~MVPP2_TX_PORT_FLUSH_MASK(sc->sc_id);
+ mvpp2_write(sc->sc, MVPP2_TX_PORT_FLUSH_REG, reg);
+
+ for (i = 0; i < sc->sc_nrxq; i++)
+ mvpp2_rxq_hw_deinit(sc, &sc->sc_rxqs[i]);
+
+ mvpp2_prs_mac_da_accept(sc->sc, sc->sc_id, sc->sc_cur_lladdr, 0);
+}
+
+void
+mvpp2_txq_hw_deinit(struct mvpp2_port *sc, struct mvpp2_tx_queue *txq)
+{
+ struct mvpp2_buf *txb;
+ int i, pending;
+ uint32_t reg;
+
+ mvpp2_write(sc->sc, MVPP2_TXQ_NUM_REG, txq->id);
+ reg = mvpp2_read(sc->sc, MVPP2_TXQ_PREF_BUF_REG);
+ reg |= MVPP2_TXQ_DRAIN_EN_MASK;
+ mvpp2_write(sc->sc, MVPP2_TXQ_PREF_BUF_REG, reg);
+
+ /*
+ * the queue has been stopped so wait for all packets
+ * to be transmitted.
+ */
+ i = 0;
+ do {
+ if (i >= MVPP2_TX_PENDING_TIMEOUT_MSEC) {
+ printf("%s: port %d: cleaning queue %d timed out\n",
+ sc->sc_dev.dv_xname, sc->sc_id, txq->log_id);
+ break;
+ }
+ delay(1000);
+ i++;
+
+ pending = mvpp2_read(sc->sc, MVPP2_TXQ_PENDING_REG) &
+ MVPP2_TXQ_PENDING_MASK;
+ } while (pending);
+
+ reg &= ~MVPP2_TXQ_DRAIN_EN_MASK;
+ mvpp2_write(sc->sc, MVPP2_TXQ_PREF_BUF_REG, reg);
+
+ mvpp2_write(sc->sc, MVPP2_TXQ_SCHED_TOKEN_CNTR_REG(txq->id), 0);
+ mvpp2_write(sc->sc, MVPP2_TXQ_NUM_REG, txq->id);
+ mvpp2_write(sc->sc, MVPP2_TXQ_DESC_ADDR_REG, 0);
+ mvpp2_write(sc->sc, MVPP2_TXQ_DESC_SIZE_REG, 0);
+
+ for (i = 0; i < MVPP2_NTXDESC; i++) {
+ txb = &txq->buf[i];
+ if (txb->mb_m) {
+ bus_dmamap_sync(sc->sc_dmat, txb->mb_map, 0,
+ txb->mb_map->dm_mapsize, BUS_DMASYNC_POSTWRITE);
+ bus_dmamap_unload(sc->sc_dmat, txb->mb_map);
+ m_freem(txb->mb_m);
+ }
+ bus_dmamap_destroy(sc->sc_dmat, txb->mb_map);
+ }
+
+ mvpp2_dmamem_free(sc->sc, txq->ring);
+ free(txq->buf, M_DEVBUF, sizeof(struct mvpp2_buf) *
+ MVPP2_NTXDESC);
+}
+
+void
+mvpp2_rxq_hw_deinit(struct mvpp2_port *sc, struct mvpp2_rx_queue *rxq)
+{
+ uint32_t nrecv;
+
+ nrecv = mvpp2_rxq_received(sc, rxq->id);
+ if (nrecv)
+ mvpp2_rxq_status_update(sc, rxq->id, nrecv, nrecv);
+
+ mvpp2_write(sc->sc, MVPP2_RXQ_STATUS_REG(rxq->id), 0);
+ mvpp2_write(sc->sc, MVPP2_RXQ_NUM_REG, rxq->id);
+ mvpp2_write(sc->sc, MVPP2_RXQ_DESC_ADDR_REG, 0);
+ mvpp2_write(sc->sc, MVPP2_RXQ_DESC_SIZE_REG, 0);
+
+ mvpp2_dmamem_free(sc->sc, rxq->ring);
+}
+
+void
+mvpp2_rxq_long_pool_set(struct mvpp2_port *port, int lrxq, int pool)
+{
+ uint32_t val;
+ int prxq;
+
+ /* get queue physical ID */
+ prxq = port->sc_rxqs[lrxq].id;
+
+ val = mvpp2_read(port->sc, MVPP2_RXQ_CONFIG_REG(prxq));
+ val &= ~MVPP2_RXQ_POOL_LONG_MASK;
+ val |= ((pool << MVPP2_RXQ_POOL_LONG_OFFS) & MVPP2_RXQ_POOL_LONG_MASK);
+
+ mvpp2_write(port->sc, MVPP2_RXQ_CONFIG_REG(prxq), val);
+}
+
+void
+mvpp2_rxq_short_pool_set(struct mvpp2_port *port, int lrxq, int pool)
+{
+ uint32_t val;
+ int prxq;
+
+ /* get queue physical ID */
+ prxq = port->sc_rxqs[lrxq].id;
+
+ val = mvpp2_read(port->sc, MVPP2_RXQ_CONFIG_REG(prxq));
+ val &= ~MVPP2_RXQ_POOL_SHORT_MASK;
+ val |= ((pool << MVPP2_RXQ_POOL_SHORT_OFFS) & MVPP2_RXQ_POOL_SHORT_MASK);
+
+ mvpp2_write(port->sc, MVPP2_RXQ_CONFIG_REG(prxq), val);
+}
+
+void
+mvpp2_iff(struct mvpp2_port *sc)
+{
+ /* FIXME: multicast handling */
+
+ mvpp2_prs_mac_da_accept(sc->sc, sc->sc_id, sc->sc_cur_lladdr, 0);
+ memcpy(sc->sc_cur_lladdr, sc->sc_lladdr, ETHER_ADDR_LEN);
+ mvpp2_prs_mac_da_accept(sc->sc, sc->sc_id, sc->sc_cur_lladdr, 1);
+}
+
+struct mvpp2_dmamem *
+mvpp2_dmamem_alloc(struct mvpp2_softc *sc, bus_size_t size, bus_size_t align)
+{
+ struct mvpp2_dmamem *mdm;
+ int nsegs;
+
+ mdm = malloc(sizeof(*mdm), M_DEVBUF, M_WAITOK | M_ZERO);
+ mdm->mdm_size = size;
+
+ if (bus_dmamap_create(sc->sc_dmat, size, 1, size, 0,
+ BUS_DMA_WAITOK | BUS_DMA_ALLOCNOW, &mdm->mdm_map) != 0)
+ goto mdmfree;
+
+ if (bus_dmamem_alloc(sc->sc_dmat, size, align, 0, &mdm->mdm_seg, 1,
+ &nsegs, BUS_DMA_WAITOK) != 0)
+ goto destroy;
+
+ if (bus_dmamem_map(sc->sc_dmat, &mdm->mdm_seg, nsegs, size,
+ &mdm->mdm_kva, BUS_DMA_WAITOK | BUS_DMA_COHERENT) != 0)
+ goto free;
+
+ if (bus_dmamap_load(sc->sc_dmat, mdm->mdm_map, mdm->mdm_kva, size,
+ NULL, BUS_DMA_WAITOK) != 0)
+ goto unmap;
+
+ bzero(mdm->mdm_kva, size);
+
+ return (mdm);
+
+unmap:
+ bus_dmamem_unmap(sc->sc_dmat, mdm->mdm_kva, size);
+free:
+ bus_dmamem_free(sc->sc_dmat, &mdm->mdm_seg, 1);
+destroy:
+ bus_dmamap_destroy(sc->sc_dmat, mdm->mdm_map);
+mdmfree:
+ free(mdm, M_DEVBUF, 0);
+
+ return (NULL);
+}
+
+void
+mvpp2_dmamem_free(struct mvpp2_softc *sc, struct mvpp2_dmamem *mdm)
+{
+ bus_dmamem_unmap(sc->sc_dmat, mdm->mdm_kva, mdm->mdm_size);
+ bus_dmamem_free(sc->sc_dmat, &mdm->mdm_seg, 1);
+ bus_dmamap_destroy(sc->sc_dmat, mdm->mdm_map);
+ free(mdm, M_DEVBUF, 0);
+}
+
+struct mbuf *
+mvpp2_alloc_mbuf(struct mvpp2_softc *sc, bus_dmamap_t map)
+{
+ struct mbuf *m = NULL;
+
+ m = MCLGETI(NULL, M_DONTWAIT, NULL, MCLBYTES);
+ if (!m)
+ return (NULL);
+ m->m_len = m->m_pkthdr.len = MCLBYTES;
+
+ if (bus_dmamap_load_mbuf(sc->sc_dmat, map, m, BUS_DMA_NOWAIT) != 0) {
+ printf("%s: could not load mbuf DMA map", DEVNAME(sc));
+ m_freem(m);
+ return (NULL);
+ }
+
+ bus_dmamap_sync(sc->sc_dmat, map, 0,
+ m->m_pkthdr.len, BUS_DMASYNC_PREREAD);
+
+ return (m);
+}
+
+void
+mvpp2_interrupts_enable(struct mvpp2_port *port, int cpu_mask)
+{
+ mvpp2_write(port->sc, MVPP2_ISR_ENABLE_REG(port->sc_id),
+ MVPP2_ISR_ENABLE_INTERRUPT(cpu_mask));
+}
+
+void
+mvpp2_interrupts_disable(struct mvpp2_port *port, int cpu_mask)
+{
+ mvpp2_write(port->sc, MVPP2_ISR_ENABLE_REG(port->sc_id),
+ MVPP2_ISR_DISABLE_INTERRUPT(cpu_mask));
+}
+
+int
+mvpp2_egress_port(struct mvpp2_port *port)
+{
+ return MVPP2_MAX_TCONT + port->sc_id;
+}
+
+int
+mvpp2_txq_phys(int port, int txq)
+{
+ return (MVPP2_MAX_TCONT + port) * MVPP2_MAX_TXQ + txq;
+}
+
+void
+mvpp2_defaults_set(struct mvpp2_port *port)
+{
+ int val, queue, p_txq;
+
+ mvpp2_write(port->sc, MVPP2_TXP_SCHED_PORT_INDEX_REG,
+ mvpp2_egress_port(port));
+ mvpp2_write(port->sc, MVPP2_TXP_SCHED_CMD_1_REG, 0);
+
+ for (queue = 0; queue < MVPP2_MAX_TXQ; queue++) {
+ p_txq = mvpp2_txq_phys(port->sc_id, queue);
+ mvpp2_write(port->sc, MVPP2_TXQ_SCHED_TOKEN_CNTR_REG(p_txq), 0);
+ }
+
+ mvpp2_write(port->sc, MVPP2_TXP_SCHED_PERIOD_REG, port->sc->sc_tclk /
+ (1000 * 1000));
+ val = mvpp2_read(port->sc, MVPP2_TXP_SCHED_REFILL_REG);
+ val &= ~MVPP2_TXP_REFILL_PERIOD_ALL_MASK;
+ val |= MVPP2_TXP_REFILL_PERIOD_MASK(1);
+ val |= MVPP2_TXP_REFILL_TOKENS_ALL_MASK;
+ mvpp2_write(port->sc, MVPP2_TXP_SCHED_REFILL_REG, val);
+ val = MVPP2_TXP_TOKEN_SIZE_MAX;
+ mvpp2_write(port->sc, MVPP2_TXP_SCHED_TOKEN_SIZE_REG, val);
+
+ /* set maximum_low_latency_packet_size value to 256 */
+ mvpp2_write(port->sc, MVPP2_RX_CTRL_REG(port->sc_id),
+ MVPP2_RX_USE_PSEUDO_FOR_CSUM_MASK |
+ MVPP2_RX_LOW_LATENCY_PKT_SIZE(256));
+
+ /* mask all interrupts to all present cpus */
+ mvpp2_interrupts_disable(port, (0xf << 0));
+}
+
+void
+mvpp2_ingress_enable(struct mvpp2_port *port)
+{
+ uint32_t val;
+ int lrxq, queue;
+
+ for (lrxq = 0; lrxq < port->sc_nrxq; lrxq++) {
+ queue = port->sc_rxqs[lrxq].id;
+ val = mvpp2_read(port->sc, MVPP2_RXQ_CONFIG_REG(queue));
+ val &= ~MVPP2_RXQ_DISABLE_MASK;
+ mvpp2_write(port->sc, MVPP2_RXQ_CONFIG_REG(queue), val);
+ }
+}
+
+void
+mvpp2_ingress_disable(struct mvpp2_port *port)
+{
+ uint32_t val;
+ int lrxq, queue;
+
+ for (lrxq = 0; lrxq < port->sc_nrxq; lrxq++) {
+ queue = port->sc_rxqs[lrxq].id;
+ val = mvpp2_read(port->sc, MVPP2_RXQ_CONFIG_REG(queue));
+ val |= MVPP2_RXQ_DISABLE_MASK;
+ mvpp2_write(port->sc, MVPP2_RXQ_CONFIG_REG(queue), val);
+ }
+}
+
+void
+mvpp2_egress_enable(struct mvpp2_port *port)
+{
+ struct mvpp2_tx_queue *txq;
+ uint32_t qmap;
+ int queue;
+
+ qmap = 0;
+ for (queue = 0; queue < port->sc_ntxq; queue++) {
+ txq = &port->sc_txqs[queue];
+
+ if (txq->descs != NULL) {
+ qmap |= (1 << queue);
+ }
+ }
+
+ mvpp2_write(port->sc, MVPP2_TXP_SCHED_PORT_INDEX_REG,
+ mvpp2_egress_port(port));
+ mvpp2_write(port->sc, MVPP2_TXP_SCHED_Q_CMD_REG, qmap);
+}
+
+void
+mvpp2_egress_disable(struct mvpp2_port *port)
+{
+ uint32_t reg_data;
+ int i;
+
+ mvpp2_write(port->sc, MVPP2_TXP_SCHED_PORT_INDEX_REG,
+ mvpp2_egress_port(port));
+ reg_data = (mvpp2_read(port->sc, MVPP2_TXP_SCHED_Q_CMD_REG)) &
+ MVPP2_TXP_SCHED_ENQ_MASK;
+ if (reg_data)
+ mvpp2_write(port->sc, MVPP2_TXP_SCHED_Q_CMD_REG,(reg_data <<
+ MVPP2_TXP_SCHED_DISQ_OFFSET));
+
+ i = 0;
+ do {
+ if (i >= MVPP2_TX_DISABLE_TIMEOUT_MSEC) {
+ printf("%s: tx stop timed out, status=0x%08x\n",
+ port->sc_dev.dv_xname, reg_data);
+ break;
+ }
+ delay(1000);
+ i++;
+ reg_data = mvpp2_read(port->sc, MVPP2_TXP_SCHED_Q_CMD_REG);
+ } while (reg_data & MVPP2_TXP_SCHED_ENQ_MASK);
+}
+
+void
+mvpp2_port_enable(struct mvpp2_port *port)
+{
+ uint32_t val;
+
+ if (port->sc_gop_id == 0 && (port->sc_phy_mode == PHY_MODE_10GBASER ||
+ port->sc_phy_mode == PHY_MODE_XAUI)) {
+ val = mvpp2_xlg_read(port, MV_XLG_PORT_MAC_CTRL0_REG);
+ val |= MV_XLG_MAC_CTRL0_PORTEN_MASK;
+ val &= ~MV_XLG_MAC_CTRL0_MIBCNTDIS_MASK;
+ mvpp2_xlg_write(port, MV_XLG_PORT_MAC_CTRL0_REG, val);
+ } else {
+ val = mvpp2_gmac_read(port, MVPP2_GMAC_CTRL_0_REG);
+ val |= MVPP2_GMAC_PORT_EN_MASK;
+ val |= MVPP2_GMAC_MIB_CNTR_EN_MASK;
+ mvpp2_gmac_write(port, MVPP2_GMAC_CTRL_0_REG, val);
+ }
+}
+
+void
+mvpp2_port_disable(struct mvpp2_port *port)
+{
+ uint32_t val;
+
+ if (port->sc_gop_id == 0 && (port->sc_phy_mode == PHY_MODE_10GBASER ||
+ port->sc_phy_mode == PHY_MODE_XAUI)) {
+ val = mvpp2_xlg_read(port, MV_XLG_PORT_MAC_CTRL0_REG);
+ val &= ~MV_XLG_MAC_CTRL0_PORTEN_MASK;
+ mvpp2_xlg_write(port, MV_XLG_PORT_MAC_CTRL0_REG, val);
+ }
+
+ val = mvpp2_gmac_read(port, MVPP2_GMAC_CTRL_0_REG);
+ val &= ~MVPP2_GMAC_PORT_EN_MASK;
+ mvpp2_gmac_write(port, MVPP2_GMAC_CTRL_0_REG, val);
+}
+
+int
+mvpp2_rxq_received(struct mvpp2_port *port, int rxq_id)
+{
+ uint32_t val = mvpp2_read(port->sc, MVPP2_RXQ_STATUS_REG(rxq_id));
+
+ return val & MVPP2_RXQ_OCCUPIED_MASK;
+}
+
+void
+mvpp2_rxq_status_update(struct mvpp2_port *port, int rxq_id,
+ int used_count, int free_count)
+{
+ uint32_t val = used_count | (free_count << MVPP2_RXQ_NUM_NEW_OFFSET);
+ mvpp2_write(port->sc, MVPP2_RXQ_STATUS_UPDATE_REG(rxq_id), val);
+}
+
+void
+mvpp2_rxq_offset_set(struct mvpp2_port *port, int prxq, int offset)
+{
+ uint32_t val;
+
+ offset = offset >> 5;
+ val = mvpp2_read(port->sc, MVPP2_RXQ_CONFIG_REG(prxq));
+ val &= ~MVPP2_RXQ_PACKET_OFFSET_MASK;
+ val |= ((offset << MVPP2_RXQ_PACKET_OFFSET_OFFS) &
+ MVPP2_RXQ_PACKET_OFFSET_MASK);
+ mvpp2_write(port->sc, MVPP2_RXQ_CONFIG_REG(prxq), val);
+}
+
+void
+mvpp2_txp_max_tx_size_set(struct mvpp2_port *port)
+{
+ uint32_t val, size, mtu;
+ int txq;
+
+ mtu = MCLBYTES * 8;
+ if (mtu > MVPP2_TXP_MTU_MAX)
+ mtu = MVPP2_TXP_MTU_MAX;
+
+ /* WA for wrong token bucket update: set MTU value = 3*real MTU value */
+ mtu = 3 * mtu;
+
+ /* indirect access to reg_valisters */
+ mvpp2_write(port->sc, MVPP2_TXP_SCHED_PORT_INDEX_REG,
+ mvpp2_egress_port(port));
+
+ /* set MTU */
+ val = mvpp2_read(port->sc, MVPP2_TXP_SCHED_MTU_REG);
+ val &= ~MVPP2_TXP_MTU_MAX;
+ val |= mtu;
+ mvpp2_write(port->sc, MVPP2_TXP_SCHED_MTU_REG, val);
+
+ /* TXP token size and all TXqs token size must be larger that MTU */
+ val = mvpp2_read(port->sc, MVPP2_TXP_SCHED_TOKEN_SIZE_REG);
+ size = val & MVPP2_TXP_TOKEN_SIZE_MAX;
+ if (size < mtu) {
+ size = mtu;
+ val &= ~MVPP2_TXP_TOKEN_SIZE_MAX;
+ val |= size;
+ mvpp2_write(port->sc, MVPP2_TXP_SCHED_TOKEN_SIZE_REG, val);
+ }
+
+ for (txq = 0; txq < port->sc_ntxq; txq++) {
+ val = mvpp2_read(port->sc, MVPP2_TXQ_SCHED_TOKEN_SIZE_REG(txq));
+ size = val & MVPP2_TXQ_TOKEN_SIZE_MAX;
+
+ if (size < mtu) {
+ size = mtu;
+ val &= ~MVPP2_TXQ_TOKEN_SIZE_MAX;
+ val |= size;
+ mvpp2_write(port->sc, MVPP2_TXQ_SCHED_TOKEN_SIZE_REG(txq), val);
+ }
+ }
+}
+
+void
+mvpp2_rx_pkts_coal_set(struct mvpp2_port *port, struct mvpp2_rx_queue *rxq,
+ uint32_t pkts)
+{
+ rxq->pkts_coal =
+ pkts <= MVPP2_OCCUPIED_THRESH_MASK ?
+ pkts : MVPP2_OCCUPIED_THRESH_MASK;
+
+ mvpp2_write(port->sc, MVPP2_RXQ_NUM_REG, rxq->id);
+ mvpp2_write(port->sc, MVPP2_RXQ_THRESH_REG, rxq->pkts_coal);
+
+}
+
+void
+mvpp2_tx_pkts_coal_set(struct mvpp2_port *port, struct mvpp2_tx_queue *txq,
+ uint32_t pkts)
+{
+ txq->done_pkts_coal =
+ pkts <= MVPP2_TRANSMITTED_THRESH_MASK ?
+ pkts : MVPP2_TRANSMITTED_THRESH_MASK;
+
+ mvpp2_write(port->sc, MVPP2_TXQ_NUM_REG, txq->id);
+ mvpp2_write(port->sc, MVPP2_TXQ_THRESH_REG,
+ txq->done_pkts_coal << MVPP2_TRANSMITTED_THRESH_OFFSET);
+}
+
+void
+mvpp2_rx_time_coal_set(struct mvpp2_port *port, struct mvpp2_rx_queue *rxq,
+ uint32_t usec)
+{
+ uint32_t val;
+
+ val = (port->sc->sc_tclk / (1000 * 1000)) * usec;
+ mvpp2_write(port->sc, MVPP2_ISR_RX_THRESHOLD_REG(rxq->id), val);
+
+ rxq->time_coal = usec;
+}
+
+void
+mvpp2_tx_time_coal_set(struct mvpp2_port *port, uint32_t usec)
+{
+ uint32_t val;
+
+ val = (port->sc->sc_tclk / (1000 * 1000)) * usec;
+ mvpp2_write(port->sc, MVPP2_ISR_TX_THRESHOLD_REG(port->sc_id), val);
+
+ port->sc_tx_time_coal = usec;
+}
+
+void
+mvpp2_prs_shadow_ri_set(struct mvpp2_softc *sc, int index,
+ uint32_t ri, uint32_t ri_mask)
+{
+ sc->sc_prs_shadow[index].ri_mask = ri_mask;
+ sc->sc_prs_shadow[index].ri = ri;
+}
+
+void
+mvpp2_prs_tcam_lu_set(struct mvpp2_prs_entry *pe, uint32_t lu)
+{
+ int enable_off = MVPP2_PRS_TCAM_EN_OFFS(MVPP2_PRS_TCAM_LU_BYTE);
+
+ pe->tcam.byte[MVPP2_PRS_TCAM_LU_BYTE] = lu;
+ pe->tcam.byte[enable_off] = MVPP2_PRS_LU_MASK;
+}
+
+void
+mvpp2_prs_tcam_port_set(struct mvpp2_prs_entry *pe, uint32_t port, int add)
+{
+ int enable_off = MVPP2_PRS_TCAM_EN_OFFS(MVPP2_PRS_TCAM_PORT_BYTE);
+
+ if (add)
+ pe->tcam.byte[enable_off] &= ~(1 << port);
+ else
+ pe->tcam.byte[enable_off] |= (1 << port);
+}
+
+void
+mvpp2_prs_tcam_port_map_set(struct mvpp2_prs_entry *pe, uint32_t port_mask)
+{
+ int enable_off = MVPP2_PRS_TCAM_EN_OFFS(MVPP2_PRS_TCAM_PORT_BYTE);
+ uint8_t mask = MVPP2_PRS_PORT_MASK;
+
+ pe->tcam.byte[MVPP2_PRS_TCAM_PORT_BYTE] = 0;
+ pe->tcam.byte[enable_off] &= ~mask;
+ pe->tcam.byte[enable_off] |= ~port_mask & MVPP2_PRS_PORT_MASK;
+}
+
+uint32_t
+mvpp2_prs_tcam_port_map_get(struct mvpp2_prs_entry *pe)
+{
+ int enable_off = MVPP2_PRS_TCAM_EN_OFFS(MVPP2_PRS_TCAM_PORT_BYTE);
+
+ return ~(pe->tcam.byte[enable_off]) & MVPP2_PRS_PORT_MASK;
+}
+
+void
+mvpp2_prs_tcam_data_byte_set(struct mvpp2_prs_entry *pe, uint32_t offs,
+ uint8_t byte, uint8_t enable)
+{
+ pe->tcam.byte[MVPP2_PRS_TCAM_DATA_BYTE(offs)] = byte;
+ pe->tcam.byte[MVPP2_PRS_TCAM_DATA_BYTE_EN(offs)] = enable;
+}
+
+void
+mvpp2_prs_tcam_data_byte_get(struct mvpp2_prs_entry *pe, uint32_t offs,
+ uint8_t *byte, uint8_t *enable)
+{
+ *byte = pe->tcam.byte[MVPP2_PRS_TCAM_DATA_BYTE(offs)];
+ *enable = pe->tcam.byte[MVPP2_PRS_TCAM_DATA_BYTE_EN(offs)];
+}
+
+int
+mvpp2_prs_tcam_data_cmp(struct mvpp2_prs_entry *pe, int offset, uint16_t data)
+{
+ int byte_offset = MVPP2_PRS_TCAM_DATA_BYTE(offset);
+ uint16_t tcam_data;
+
+ tcam_data = (pe->tcam.byte[byte_offset + 1] << 8) |
+ pe->tcam.byte[byte_offset];
+ if (tcam_data != data)
+ return 0;
+
+ return 1;
+}
+
+void
+mvpp2_prs_tcam_ai_update(struct mvpp2_prs_entry *pe, uint32_t bits, uint32_t enable)
+{
+ int i, ai_idx = MVPP2_PRS_TCAM_AI_BYTE;
+
+ for (i = 0; i < MVPP2_PRS_AI_BITS; i++) {
+ if (!(enable & (i << 1)))
+ continue;
+
+ if (bits & (i << 1))
+ pe->tcam.byte[ai_idx] |= 1 << i;
+ else
+ pe->tcam.byte[ai_idx] &= ~(1 << i);
+ }
+
+ pe->tcam.byte[MVPP2_PRS_TCAM_EN_OFFS(ai_idx)] |= enable;
+}
+
+int
+mvpp2_prs_tcam_ai_get(struct mvpp2_prs_entry *pe)
+{
+ return pe->tcam.byte[MVPP2_PRS_TCAM_AI_BYTE];
+}
+
+void
+mvpp2_prs_tcam_data_word_get(struct mvpp2_prs_entry *pe, uint32_t data_offset,
+ uint32_t *word, uint32_t *enable)
+{
+ int index, position;
+ uint8_t byte, mask;
+
+ for (index = 0; index < 4; index++) {
+ position = (data_offset * sizeof(int)) + index;
+ mvpp2_prs_tcam_data_byte_get(pe, position, &byte, &mask);
+ ((uint8_t *)word)[index] = byte;
+ ((uint8_t *)enable)[index] = mask;
+ }
+}
+
+void
+mvpp2_prs_match_etype(struct mvpp2_prs_entry *pe, uint32_t offs,
+ uint16_t ether_type)
+{
+ mvpp2_prs_tcam_data_byte_set(pe, offs + 0, ether_type >> 8, 0xff);
+ mvpp2_prs_tcam_data_byte_set(pe, offs + 1, ether_type & 0xff, 0xff);
+}
+
+void
+mvpp2_prs_sram_bits_set(struct mvpp2_prs_entry *pe, uint32_t bit, uint32_t val)
+{
+ pe->sram.byte[bit / 8] |= (val << (bit % 8));
+}
+
+void
+mvpp2_prs_sram_bits_clear(struct mvpp2_prs_entry *pe, uint32_t bit, uint32_t val)
+{
+ pe->sram.byte[bit / 8] &= ~(val << (bit % 8));
+}
+
+void
+mvpp2_prs_sram_ri_update(struct mvpp2_prs_entry *pe, uint32_t bits, uint32_t mask)
+{
+ int ri_off = MVPP2_PRS_SRAM_RI_OFFS;
+ int i;
+
+ for (i = 0; i < MVPP2_PRS_SRAM_RI_CTRL_BITS; i++) {
+ if (!(mask & (1 << i)))
+ continue;
+
+ if (bits & (1 << i))
+ mvpp2_prs_sram_bits_set(pe, ri_off + i, 1);
+ else
+ mvpp2_prs_sram_bits_clear(pe, ri_off + i, 1);
+
+ mvpp2_prs_sram_bits_set(pe, MVPP2_PRS_SRAM_RI_CTRL_OFFS + i, 1);
+ }
+}
+
+int
+mvpp2_prs_sram_ri_get(struct mvpp2_prs_entry *pe)
+{
+ return pe->sram.word[MVPP2_PRS_SRAM_RI_WORD];
+}
+
+void
+mvpp2_prs_sram_ai_update(struct mvpp2_prs_entry *pe, uint32_t bits, uint32_t mask)
+{
+ int ai_off = MVPP2_PRS_SRAM_AI_OFFS;
+ int i;
+
+ for (i = 0; i < MVPP2_PRS_SRAM_AI_CTRL_BITS; i++) {
+ if (!(mask & (1 << i)))
+ continue;
+
+ if (bits & (1 << i))
+ mvpp2_prs_sram_bits_set(pe, ai_off + i, 1);
+ else
+ mvpp2_prs_sram_bits_clear(pe, ai_off + i, 1);
+
+ mvpp2_prs_sram_bits_set(pe, MVPP2_PRS_SRAM_AI_CTRL_OFFS + i, 1);
+ }
+}
+
+int
+mvpp2_prs_sram_ai_get(struct mvpp2_prs_entry *pe)
+{
+ uint8_t bits;
+ int ai_off = MVPP2_BIT_TO_BYTE(MVPP2_PRS_SRAM_AI_OFFS);
+ int ai_en_off = ai_off + 1;
+ int ai_shift = MVPP2_PRS_SRAM_AI_OFFS % 8;
+
+ bits = (pe->sram.byte[ai_off] >> ai_shift) |
+ (pe->sram.byte[ai_en_off] << (8 - ai_shift));
+
+ return bits;
+}
+
+void
+mvpp2_prs_sram_shift_set(struct mvpp2_prs_entry *pe, int shift, uint32_t op)
+{
+ if (shift < 0) {
+ mvpp2_prs_sram_bits_set(pe, MVPP2_PRS_SRAM_SHIFT_SIGN_BIT, 1);
+ shift = -shift;
+ } else {
+ mvpp2_prs_sram_bits_clear(pe, MVPP2_PRS_SRAM_SHIFT_SIGN_BIT, 1);
+ }
+
+ pe->sram.byte[MVPP2_BIT_TO_BYTE(MVPP2_PRS_SRAM_SHIFT_OFFS)] |=
+ shift & MVPP2_PRS_SRAM_SHIFT_MASK;
+ mvpp2_prs_sram_bits_clear(pe, MVPP2_PRS_SRAM_OP_SEL_SHIFT_OFFS,
+ MVPP2_PRS_SRAM_OP_SEL_SHIFT_MASK);
+ mvpp2_prs_sram_bits_set(pe, MVPP2_PRS_SRAM_OP_SEL_SHIFT_OFFS, op);
+ mvpp2_prs_sram_bits_clear(pe, MVPP2_PRS_SRAM_OP_SEL_BASE_OFFS, 1);
+}
+
+void
+mvpp2_prs_sram_offset_set(struct mvpp2_prs_entry *pe, uint32_t type, int offset,
+ uint32_t op)
+{
+ uint8_t udf_byte, udf_byte_offset;
+ uint8_t op_sel_udf_byte, op_sel_udf_byte_offset;
+
+ udf_byte = MVPP2_BIT_TO_BYTE(MVPP2_PRS_SRAM_UDF_OFFS +
+ MVPP2_PRS_SRAM_UDF_BITS);
+ udf_byte_offset = (8 - (MVPP2_PRS_SRAM_UDF_OFFS % 8));
+ op_sel_udf_byte = MVPP2_BIT_TO_BYTE(MVPP2_PRS_SRAM_OP_SEL_UDF_OFFS +
+ MVPP2_PRS_SRAM_OP_SEL_UDF_BITS);
+ op_sel_udf_byte_offset = (8 - (MVPP2_PRS_SRAM_OP_SEL_UDF_OFFS % 8));
+
+ if (offset < 0) {
+ mvpp2_prs_sram_bits_set(pe, MVPP2_PRS_SRAM_UDF_SIGN_BIT, 1);
+ offset = -offset;
+ } else {
+ mvpp2_prs_sram_bits_clear(pe, MVPP2_PRS_SRAM_UDF_SIGN_BIT, 1);
+ }
+
+ mvpp2_prs_sram_bits_clear(pe, MVPP2_PRS_SRAM_UDF_OFFS,
+ MVPP2_PRS_SRAM_UDF_MASK);
+ mvpp2_prs_sram_bits_set(pe, MVPP2_PRS_SRAM_UDF_OFFS, offset);
+ pe->sram.byte[udf_byte] &= ~(MVPP2_PRS_SRAM_UDF_MASK >> udf_byte_offset);
+ pe->sram.byte[udf_byte] |= (offset >> udf_byte_offset);
+ mvpp2_prs_sram_bits_clear(pe, MVPP2_PRS_SRAM_UDF_TYPE_OFFS,
+ MVPP2_PRS_SRAM_UDF_TYPE_MASK);
+ mvpp2_prs_sram_bits_set(pe, MVPP2_PRS_SRAM_UDF_TYPE_OFFS, type);
+ mvpp2_prs_sram_bits_clear(pe, MVPP2_PRS_SRAM_OP_SEL_UDF_OFFS,
+ MVPP2_PRS_SRAM_OP_SEL_UDF_MASK);
+ mvpp2_prs_sram_bits_set(pe, MVPP2_PRS_SRAM_OP_SEL_UDF_OFFS, op);
+ pe->sram.byte[op_sel_udf_byte] &= ~(MVPP2_PRS_SRAM_OP_SEL_UDF_MASK >>
+ op_sel_udf_byte_offset);
+ pe->sram.byte[op_sel_udf_byte] |= (op >> op_sel_udf_byte_offset);
+ mvpp2_prs_sram_bits_clear(pe, MVPP2_PRS_SRAM_OP_SEL_BASE_OFFS, 1);
+}
+
+void
+mvpp2_prs_sram_next_lu_set(struct mvpp2_prs_entry *pe, uint32_t lu)
+{
+ int sram_next_off = MVPP2_PRS_SRAM_NEXT_LU_OFFS;
+
+ mvpp2_prs_sram_bits_clear(pe, sram_next_off, MVPP2_PRS_SRAM_NEXT_LU_MASK);
+ mvpp2_prs_sram_bits_set(pe, sram_next_off, lu);
+}
+
+void
+mvpp2_prs_shadow_set(struct mvpp2_softc *sc, int index, uint32_t lu)
+{
+ sc->sc_prs_shadow[index].valid = 1;
+ sc->sc_prs_shadow[index].lu = lu;
+}
+
+int
+mvpp2_prs_hw_write(struct mvpp2_softc *sc, struct mvpp2_prs_entry *pe)
+{
+ int i;
+
+ if (pe->index > MVPP2_PRS_TCAM_SRAM_SIZE - 1)
+ return EINVAL;
+
+ pe->tcam.word[MVPP2_PRS_TCAM_INV_WORD] &= ~MVPP2_PRS_TCAM_INV_MASK;
+ mvpp2_write(sc, MVPP2_PRS_TCAM_IDX_REG, pe->index);
+ for (i = 0; i < MVPP2_PRS_TCAM_WORDS; i++)
+ mvpp2_write(sc, MVPP2_PRS_TCAM_DATA_REG(i), pe->tcam.word[i]);
+ mvpp2_write(sc, MVPP2_PRS_SRAM_IDX_REG, pe->index);
+ for (i = 0; i < MVPP2_PRS_SRAM_WORDS; i++)
+ mvpp2_write(sc, MVPP2_PRS_SRAM_DATA_REG(i), pe->sram.word[i]);
+
+ return 0;
+}
+
+int
+mvpp2_prs_hw_read(struct mvpp2_softc *sc, struct mvpp2_prs_entry *pe)
+{
+ int i;
+
+ if (pe->index > MVPP2_PRS_TCAM_SRAM_SIZE - 1)
+ return EINVAL;
+
+ mvpp2_write(sc, MVPP2_PRS_TCAM_IDX_REG, pe->index);
+ pe->tcam.word[MVPP2_PRS_TCAM_INV_WORD] =
+ mvpp2_read(sc, MVPP2_PRS_TCAM_DATA_REG(MVPP2_PRS_TCAM_INV_WORD));
+ if (pe->tcam.word[MVPP2_PRS_TCAM_INV_WORD] & MVPP2_PRS_TCAM_INV_MASK)
+ return EINVAL;
+ for (i = 0; i < MVPP2_PRS_TCAM_WORDS; i++)
+ pe->tcam.word[i] =
+ mvpp2_read(sc, MVPP2_PRS_TCAM_DATA_REG(i));
+
+ mvpp2_write(sc, MVPP2_PRS_SRAM_IDX_REG, pe->index);
+ for (i = 0; i < MVPP2_PRS_SRAM_WORDS; i++)
+ pe->sram.word[i] =
+ mvpp2_read(sc, MVPP2_PRS_SRAM_DATA_REG(i));
+
+ return 0;
+}
+
+struct mvpp2_prs_entry *
+mvpp2_prs_flow_find(struct mvpp2_softc *sc, int flow)
+{
+ struct mvpp2_prs_entry *pe;
+ uint32_t word, enable;
+ uint8_t bits;
+ int tid;
+
+ pe = malloc(sizeof(*pe), M_TEMP, M_NOWAIT);
+ if (pe == NULL)
+ return NULL;
+
+ mvpp2_prs_tcam_lu_set(pe, MVPP2_PRS_LU_FLOWS);
+ for (tid = MVPP2_PRS_TCAM_SRAM_SIZE - 1; tid >= 0; tid--) {
+ if (!sc->sc_prs_shadow[tid].valid ||
+ sc->sc_prs_shadow[tid].lu != MVPP2_PRS_LU_FLOWS)
+ continue;
+
+ pe->index = tid;
+ mvpp2_prs_hw_read(sc, pe);
+
+ mvpp2_prs_tcam_data_word_get(pe, 0, &word, &enable);
+ if ((word != 0) || (enable != 0))
+ continue;
+
+ bits = mvpp2_prs_sram_ai_get(pe);
+ if ((bits & MVPP2_PRS_FLOW_ID_MASK) == flow)
+ return pe;
+ }
+
+ free(pe, M_TEMP, sizeof(*pe));
+ return NULL;
+}
+
+int
+mvpp2_prs_tcam_first_free(struct mvpp2_softc *sc, uint8_t start, uint8_t end)
+{
+ uint8_t tmp;
+ int tid;
+
+ if (start > end) {
+ tmp = end;
+ end = start;
+ start = tmp;
+ }
+
+ for (tid = start; tid <= end; tid++) {
+ if (!sc->sc_prs_shadow[tid].valid)
+ return tid;
+ }
+
+ return EINVAL;
+}
+
+void
+mvpp2_prs_mac_drop_all_set(struct mvpp2_softc *sc, uint32_t port, int add)
+{
+ struct mvpp2_prs_entry pe;
+
+ if (sc->sc_prs_shadow[MVPP2_PE_DROP_ALL].valid) {
+ pe.index = MVPP2_PE_DROP_ALL;
+ mvpp2_prs_hw_read(sc, &pe);
+ } else {
+ memset(&pe, 0, sizeof(pe));
+ mvpp2_prs_tcam_lu_set(&pe, MVPP2_PRS_LU_MAC);
+ pe.index = MVPP2_PE_DROP_ALL;
+ mvpp2_prs_sram_ri_update(&pe, MVPP2_PRS_RI_DROP_MASK,
+ MVPP2_PRS_RI_DROP_MASK);
+ mvpp2_prs_sram_bits_set(&pe, MVPP2_PRS_SRAM_LU_GEN_BIT, 1);
+ mvpp2_prs_sram_next_lu_set(&pe, MVPP2_PRS_LU_FLOWS);
+ mvpp2_prs_shadow_set(sc, pe.index, MVPP2_PRS_LU_MAC);
+ mvpp2_prs_tcam_port_map_set(&pe, 0);
+ }
+
+ mvpp2_prs_tcam_port_set(&pe, port, add);
+ mvpp2_prs_hw_write(sc, &pe);
+}
+
+void
+mvpp2_prs_mac_promisc_set(struct mvpp2_softc *sc, uint32_t port, int add)
+{
+ struct mvpp2_prs_entry pe;
+
+ if (sc->sc_prs_shadow[MVPP2_PE_MAC_PROMISCUOUS].valid) {
+ pe.index = MVPP2_PE_MAC_PROMISCUOUS;
+ mvpp2_prs_hw_read(sc, &pe);
+ } else {
+ memset(&pe, 0, sizeof(pe));
+ mvpp2_prs_tcam_lu_set(&pe, MVPP2_PRS_LU_MAC);
+ pe.index = MVPP2_PE_MAC_PROMISCUOUS;
+ mvpp2_prs_sram_next_lu_set(&pe, MVPP2_PRS_LU_DSA);
+ mvpp2_prs_sram_ri_update(&pe, MVPP2_PRS_RI_L2_UCAST,
+ MVPP2_PRS_RI_L2_CAST_MASK);
+ mvpp2_prs_sram_shift_set(&pe, 2 * ETHER_ADDR_LEN,
+ MVPP2_PRS_SRAM_OP_SEL_SHIFT_ADD);
+ mvpp2_prs_tcam_port_map_set(&pe, 0);
+ mvpp2_prs_shadow_set(sc, pe.index, MVPP2_PRS_LU_MAC);
+ }
+
+ mvpp2_prs_tcam_port_set(&pe, port, add);
+ mvpp2_prs_hw_write(sc, &pe);
+}
+
+void
+mvpp2_prs_mac_multi_set(struct mvpp2_softc *sc, uint32_t port, uint32_t index, int add)
+{
+ struct mvpp2_prs_entry pe;
+ uint8_t da_mc;
+
+ da_mc = (index == MVPP2_PE_MAC_MC_ALL) ? 0x01 : 0x33;
+
+ if (sc->sc_prs_shadow[index].valid) {
+ pe.index = index;
+ mvpp2_prs_hw_read(sc, &pe);
+ } else {
+ memset(&pe, 0, sizeof(pe));
+ mvpp2_prs_tcam_lu_set(&pe, MVPP2_PRS_LU_MAC);
+ pe.index = index;
+ mvpp2_prs_sram_next_lu_set(&pe, MVPP2_PRS_LU_DSA);
+ mvpp2_prs_sram_ri_update(&pe, MVPP2_PRS_RI_L2_MCAST,
+ MVPP2_PRS_RI_L2_CAST_MASK);
+ mvpp2_prs_tcam_data_byte_set(&pe, 0, da_mc, 0xff);
+ mvpp2_prs_sram_shift_set(&pe, 2 * ETHER_ADDR_LEN,
+ MVPP2_PRS_SRAM_OP_SEL_SHIFT_ADD);
+ mvpp2_prs_tcam_port_map_set(&pe, 0);
+ mvpp2_prs_shadow_set(sc, pe.index, MVPP2_PRS_LU_MAC);
+ }
+
+ mvpp2_prs_tcam_port_set(&pe, port, add);
+ mvpp2_prs_hw_write(sc, &pe);
+}
+
+void
+mvpp2_prs_dsa_tag_set(struct mvpp2_softc *sc, uint32_t port, int add,
+ int tagged, int extend)
+{
+ struct mvpp2_prs_entry pe;
+ int32_t tid, shift;
+
+ if (extend) {
+ tid = tagged ? MVPP2_PE_EDSA_TAGGED : MVPP2_PE_EDSA_UNTAGGED;
+ shift = 8;
+ } else {
+ tid = tagged ? MVPP2_PE_DSA_TAGGED : MVPP2_PE_DSA_UNTAGGED;
+ shift = 4;
+ }
+
+ if (sc->sc_prs_shadow[tid].valid) {
+ pe.index = tid;
+ mvpp2_prs_hw_read(sc, &pe);
+ } else {
+ memset(&pe, 0, sizeof(pe));
+ mvpp2_prs_tcam_lu_set(&pe, MVPP2_PRS_LU_DSA);
+ pe.index = tid;
+ mvpp2_prs_sram_shift_set(&pe, shift,
+ MVPP2_PRS_SRAM_OP_SEL_SHIFT_ADD);
+ mvpp2_prs_shadow_set(sc, pe.index, MVPP2_PRS_LU_DSA);
+ if (tagged) {
+ mvpp2_prs_tcam_data_byte_set(&pe, 0,
+ MVPP2_PRS_TCAM_DSA_TAGGED_BIT,
+ MVPP2_PRS_TCAM_DSA_TAGGED_BIT);
+ mvpp2_prs_sram_ai_update(&pe, 0, MVPP2_PRS_SRAM_AI_MASK);
+ mvpp2_prs_sram_next_lu_set(&pe, MVPP2_PRS_LU_VLAN);
+ } else {
+ mvpp2_prs_sram_ri_update(&pe, MVPP2_PRS_RI_VLAN_NONE,
+ MVPP2_PRS_RI_VLAN_MASK);
+ mvpp2_prs_sram_next_lu_set(&pe, MVPP2_PRS_LU_L2);
+ }
+ mvpp2_prs_tcam_port_map_set(&pe, 0);
+ }
+
+ mvpp2_prs_tcam_port_set(&pe, port, add);
+ mvpp2_prs_hw_write(sc, &pe);
+}
+
+void
+mvpp2_prs_dsa_tag_ethertype_set(struct mvpp2_softc *sc, uint32_t port,
+ int add, int tagged, int extend)
+{
+ struct mvpp2_prs_entry pe;
+ int32_t tid, shift, port_mask;
+
+ if (extend) {
+ tid = tagged ? MVPP2_PE_EDSA_TAGGED : MVPP2_PE_EDSA_UNTAGGED;
+ port_mask = 0;
+ shift = 8;
+ } else {
+ tid = tagged ? MVPP2_PE_DSA_TAGGED : MVPP2_PE_DSA_UNTAGGED;
+ port_mask = MVPP2_PRS_PORT_MASK;
+ shift = 4;
+ }
+
+ if (sc->sc_prs_shadow[tid].valid) {
+ pe.index = tid;
+ mvpp2_prs_hw_read(sc, &pe);
+ } else {
+ memset(&pe, 0, sizeof(pe));
+ mvpp2_prs_tcam_lu_set(&pe, MVPP2_PRS_LU_DSA);
+ pe.index = tid;
+ mvpp2_prs_match_etype(&pe, 0, MV_ETH_P_EDSA);
+ mvpp2_prs_match_etype(&pe, 2, 0);
+ mvpp2_prs_sram_ri_update(&pe, MVPP2_PRS_RI_DSA_MASK,
+ MVPP2_PRS_RI_DSA_MASK);
+ mvpp2_prs_sram_shift_set(&pe, 2 * ETHER_ADDR_LEN + shift,
+ MVPP2_PRS_SRAM_OP_SEL_SHIFT_ADD);
+ mvpp2_prs_shadow_set(sc, pe.index, MVPP2_PRS_LU_DSA);
+ if (tagged) {
+ mvpp2_prs_tcam_data_byte_set(&pe,
+ MVPP2_ETH_TYPE_LEN + 2 + 3,
+ MVPP2_PRS_TCAM_DSA_TAGGED_BIT,
+ MVPP2_PRS_TCAM_DSA_TAGGED_BIT);
+ mvpp2_prs_sram_ai_update(&pe, 0, MVPP2_PRS_SRAM_AI_MASK);
+ mvpp2_prs_sram_next_lu_set(&pe, MVPP2_PRS_LU_VLAN);
+ } else {
+ mvpp2_prs_sram_ri_update(&pe, MVPP2_PRS_RI_VLAN_NONE,
+ MVPP2_PRS_RI_VLAN_MASK);
+ mvpp2_prs_sram_next_lu_set(&pe, MVPP2_PRS_LU_L2);
+ }
+ mvpp2_prs_tcam_port_map_set(&pe, port_mask);
+ }
+
+ mvpp2_prs_tcam_port_set(&pe, port, add);
+ mvpp2_prs_hw_write(sc, &pe);
+}
+
+struct mvpp2_prs_entry *
+mvpp2_prs_vlan_find(struct mvpp2_softc *sc, uint16_t tpid, int ai)
+{
+ struct mvpp2_prs_entry *pe;
+ uint32_t ri_bits, ai_bits;
+ int match, tid;
+
+ pe = malloc(sizeof(*pe), M_TEMP, M_NOWAIT);
+ if (pe == NULL)
+ return NULL;
+
+ mvpp2_prs_tcam_lu_set(pe, MVPP2_PRS_LU_VLAN);
+
+ for (tid = MVPP2_PE_FIRST_FREE_TID; tid <= MVPP2_PE_LAST_FREE_TID; tid++) {
+ if (!sc->sc_prs_shadow[tid].valid ||
+ sc->sc_prs_shadow[tid].lu != MVPP2_PRS_LU_VLAN)
+ continue;
+ pe->index = tid;
+ mvpp2_prs_hw_read(sc, pe);
+ match = mvpp2_prs_tcam_data_cmp(pe, 0, swap16(tpid));
+ if (!match)
+ continue;
+ ri_bits = mvpp2_prs_sram_ri_get(pe);
+ ri_bits &= MVPP2_PRS_RI_VLAN_MASK;
+ ai_bits = mvpp2_prs_tcam_ai_get(pe);
+ ai_bits &= ~MVPP2_PRS_DBL_VLAN_AI_BIT;
+ if (ai != ai_bits)
+ continue;
+ if (ri_bits == MVPP2_PRS_RI_VLAN_SINGLE ||
+ ri_bits == MVPP2_PRS_RI_VLAN_TRIPLE)
+ return pe;
+ }
+
+ free(pe, M_TEMP, sizeof(*pe));
+ return NULL;
+}
+
+int
+mvpp2_prs_vlan_add(struct mvpp2_softc *sc, uint16_t tpid, int ai, uint32_t port_map)
+{
+ struct mvpp2_prs_entry *pe;
+ uint32_t ri_bits;
+ int tid_aux, tid;
+ int ret = 0;
+
+ pe = mvpp2_prs_vlan_find(sc, tpid, ai);
+ if (pe == NULL) {
+ tid = mvpp2_prs_tcam_first_free(sc, MVPP2_PE_LAST_FREE_TID,
+ MVPP2_PE_FIRST_FREE_TID);
+ if (tid < 0)
+ return tid;
+
+ pe = malloc(sizeof(*pe), M_TEMP, M_NOWAIT);
+ if (pe == NULL)
+ return ENOMEM;
+
+ /* get last double vlan tid */
+ for (tid_aux = MVPP2_PE_LAST_FREE_TID;
+ tid_aux >= MVPP2_PE_FIRST_FREE_TID; tid_aux--) {
+ if (!sc->sc_prs_shadow[tid_aux].valid ||
+ sc->sc_prs_shadow[tid_aux].lu != MVPP2_PRS_LU_VLAN)
+ continue;
+ pe->index = tid_aux;
+ mvpp2_prs_hw_read(sc, pe);
+ ri_bits = mvpp2_prs_sram_ri_get(pe);
+ if ((ri_bits & MVPP2_PRS_RI_VLAN_MASK) ==
+ MVPP2_PRS_RI_VLAN_DOUBLE)
+ break;
+ }
+
+ if (tid <= tid_aux) {
+ ret = EINVAL;
+ goto error;
+ }
+
+ memset(pe, 0, sizeof(struct mvpp2_prs_entry));
+ mvpp2_prs_tcam_lu_set(pe, MVPP2_PRS_LU_VLAN);
+ pe->index = tid;
+ mvpp2_prs_match_etype(pe, 0, tpid);
+ mvpp2_prs_sram_next_lu_set(pe, MVPP2_PRS_LU_L2);
+ mvpp2_prs_sram_shift_set(pe, MVPP2_VLAN_TAG_LEN,
+ MVPP2_PRS_SRAM_OP_SEL_SHIFT_ADD);
+ mvpp2_prs_sram_ai_update(pe, 0, MVPP2_PRS_SRAM_AI_MASK);
+ if (ai == MVPP2_PRS_SINGLE_VLAN_AI) {
+ mvpp2_prs_sram_ri_update(pe, MVPP2_PRS_RI_VLAN_SINGLE,
+ MVPP2_PRS_RI_VLAN_MASK);
+ } else {
+ ai |= MVPP2_PRS_DBL_VLAN_AI_BIT;
+ mvpp2_prs_sram_ri_update(pe, MVPP2_PRS_RI_VLAN_TRIPLE,
+ MVPP2_PRS_RI_VLAN_MASK);
+ }
+ mvpp2_prs_tcam_ai_update(pe, ai, MVPP2_PRS_SRAM_AI_MASK);
+ mvpp2_prs_shadow_set(sc, pe->index, MVPP2_PRS_LU_VLAN);
+ }
+
+ mvpp2_prs_tcam_port_map_set(pe, port_map);
+ mvpp2_prs_hw_write(sc, pe);
+
+error:
+ free(pe, M_TEMP, sizeof(*pe));
+ return ret;
+}
+
+int
+mvpp2_prs_double_vlan_ai_free_get(struct mvpp2_softc *sc)
+{
+ int i;
+
+ for (i = 1; i < MVPP2_PRS_DBL_VLANS_MAX; i++)
+ if (!sc->sc_prs_double_vlans[i])
+ return i;
+
+ return EINVAL;
+}
+
+struct mvpp2_prs_entry *
+mvpp2_prs_double_vlan_find(struct mvpp2_softc *sc, uint16_t tpid1, uint16_t tpid2)
+{
+ struct mvpp2_prs_entry *pe;
+ uint32_t ri_mask;
+ int match, tid;
+
+ pe = malloc(sizeof(*pe), M_TEMP, M_NOWAIT);
+ if (pe == NULL)
+ return NULL;
+
+ mvpp2_prs_tcam_lu_set(pe, MVPP2_PRS_LU_VLAN);
+
+ for (tid = MVPP2_PE_FIRST_FREE_TID; tid <= MVPP2_PE_LAST_FREE_TID; tid++) {
+ if (!sc->sc_prs_shadow[tid].valid ||
+ sc->sc_prs_shadow[tid].lu != MVPP2_PRS_LU_VLAN)
+ continue;
+
+ pe->index = tid;
+ mvpp2_prs_hw_read(sc, pe);
+ match = mvpp2_prs_tcam_data_cmp(pe, 0, swap16(tpid1)) &&
+ mvpp2_prs_tcam_data_cmp(pe, 4, swap16(tpid2));
+ if (!match)
+ continue;
+ ri_mask = mvpp2_prs_sram_ri_get(pe) & MVPP2_PRS_RI_VLAN_MASK;
+ if (ri_mask == MVPP2_PRS_RI_VLAN_DOUBLE)
+ return pe;
+ }
+
+ free(pe, M_TEMP, sizeof(*pe));
+ return NULL;
+}
+
+int
+mvpp2_prs_double_vlan_add(struct mvpp2_softc *sc, uint16_t tpid1, uint16_t tpid2,
+ uint32_t port_map)
+{
+ struct mvpp2_prs_entry *pe;
+ int tid_aux, tid, ai, ret = 0;
+ uint32_t ri_bits;
+
+ pe = mvpp2_prs_double_vlan_find(sc, tpid1, tpid2);
+ if (pe == NULL) {
+ tid = mvpp2_prs_tcam_first_free(sc, MVPP2_PE_FIRST_FREE_TID,
+ MVPP2_PE_LAST_FREE_TID);
+ if (tid < 0)
+ return tid;
+
+ pe = malloc(sizeof(*pe), M_TEMP, M_NOWAIT);
+ if (pe == NULL)
+ return ENOMEM;
+
+ ai = mvpp2_prs_double_vlan_ai_free_get(sc);
+ if (ai < 0) {
+ ret = ai;
+ goto error;
+ }
+
+ for (tid_aux = MVPP2_PE_FIRST_FREE_TID;
+ tid_aux <= MVPP2_PE_LAST_FREE_TID; tid_aux++) {
+ if (!sc->sc_prs_shadow[tid_aux].valid ||
+ sc->sc_prs_shadow[tid_aux].lu != MVPP2_PRS_LU_VLAN)
+ continue;
+ pe->index = tid_aux;
+ mvpp2_prs_hw_read(sc, pe);
+ ri_bits = mvpp2_prs_sram_ri_get(pe);
+ ri_bits &= MVPP2_PRS_RI_VLAN_MASK;
+ if (ri_bits == MVPP2_PRS_RI_VLAN_SINGLE ||
+ ri_bits == MVPP2_PRS_RI_VLAN_TRIPLE)
+ break;
+ }
+
+ if (tid >= tid_aux) {
+ ret = ERANGE;
+ goto error;
+ }
+
+ memset(pe, 0, sizeof(struct mvpp2_prs_entry));
+ mvpp2_prs_tcam_lu_set(pe, MVPP2_PRS_LU_VLAN);
+ pe->index = tid;
+ sc->sc_prs_double_vlans[ai] = 1;
+ mvpp2_prs_match_etype(pe, 0, tpid1);
+ mvpp2_prs_match_etype(pe, 4, tpid2);
+ mvpp2_prs_sram_next_lu_set(pe, MVPP2_PRS_LU_VLAN);
+ mvpp2_prs_sram_shift_set(pe, 2 * MVPP2_VLAN_TAG_LEN,
+ MVPP2_PRS_SRAM_OP_SEL_SHIFT_ADD);
+ mvpp2_prs_sram_ri_update(pe, MVPP2_PRS_RI_VLAN_DOUBLE,
+ MVPP2_PRS_RI_VLAN_MASK);
+ mvpp2_prs_sram_ai_update(pe, ai | MVPP2_PRS_DBL_VLAN_AI_BIT,
+ MVPP2_PRS_SRAM_AI_MASK);
+ mvpp2_prs_shadow_set(sc, pe->index, MVPP2_PRS_LU_VLAN);
+ }
+
+ mvpp2_prs_tcam_port_map_set(pe, port_map);
+ mvpp2_prs_hw_write(sc, pe);
+
+error:
+ free(pe, M_TEMP, sizeof(*pe));
+ return ret;
+}
+
+int
+mvpp2_prs_ip4_proto(struct mvpp2_softc *sc, uint16_t proto, uint32_t ri,
+ uint32_t ri_mask)
+{
+ struct mvpp2_prs_entry pe;
+ int tid;
+
+ if ((proto != MV_IPPR_TCP) && (proto != MV_IPPR_UDP) &&
+ (proto != MV_IPPR_IGMP))
+ return EINVAL;
+
+ tid = mvpp2_prs_tcam_first_free(sc, MVPP2_PE_FIRST_FREE_TID,
+ MVPP2_PE_LAST_FREE_TID);
+ if (tid < 0)
+ return tid;
+
+ memset(&pe, 0, sizeof(struct mvpp2_prs_entry));
+ mvpp2_prs_tcam_lu_set(&pe, MVPP2_PRS_LU_IP4);
+ pe.index = tid;
+ mvpp2_prs_sram_next_lu_set(&pe, MVPP2_PRS_LU_IP4);
+ mvpp2_prs_sram_shift_set(&pe, 12, MVPP2_PRS_SRAM_OP_SEL_SHIFT_ADD);
+ mvpp2_prs_sram_offset_set( &pe, MVPP2_PRS_SRAM_UDF_TYPE_L4,
+ sizeof(struct ip) - 4, MVPP2_PRS_SRAM_OP_SEL_UDF_ADD);
+ mvpp2_prs_sram_ai_update(&pe, MVPP2_PRS_IPV4_DIP_AI_BIT,
+ MVPP2_PRS_IPV4_DIP_AI_BIT);
+ mvpp2_prs_sram_ri_update(&pe, ri | MVPP2_PRS_RI_IP_FRAG_MASK, ri_mask |
+ MVPP2_PRS_RI_IP_FRAG_MASK);
+ mvpp2_prs_tcam_data_byte_set(&pe, 5, proto, MVPP2_PRS_TCAM_PROTO_MASK);
+ mvpp2_prs_tcam_ai_update(&pe, 0, MVPP2_PRS_IPV4_DIP_AI_BIT);
+ mvpp2_prs_tcam_port_map_set(&pe, MVPP2_PRS_PORT_MASK);
+ mvpp2_prs_shadow_set(sc, pe.index, MVPP2_PRS_LU_IP4);
+ mvpp2_prs_hw_write(sc, &pe);
+
+ tid = mvpp2_prs_tcam_first_free(sc, MVPP2_PE_FIRST_FREE_TID,
+ MVPP2_PE_LAST_FREE_TID);
+ if (tid < 0)
+ return tid;
+
+ pe.index = tid;
+ pe.sram.word[MVPP2_PRS_SRAM_RI_WORD] = 0x0;
+ pe.sram.word[MVPP2_PRS_SRAM_RI_CTRL_WORD] = 0x0;
+ mvpp2_prs_sram_ri_update(&pe, ri, ri_mask);
+ mvpp2_prs_tcam_data_byte_set(&pe, 2, 0x00, MVPP2_PRS_TCAM_PROTO_MASK_L);
+ mvpp2_prs_tcam_data_byte_set(&pe, 3, 0x00, MVPP2_PRS_TCAM_PROTO_MASK);
+ mvpp2_prs_shadow_set(sc, pe.index, MVPP2_PRS_LU_IP4);
+ mvpp2_prs_hw_write(sc, &pe);
+
+ return 0;
+}
+
+int
+mvpp2_prs_ip4_cast(struct mvpp2_softc *sc, uint16_t l3_cast)
+{
+ struct mvpp2_prs_entry pe;
+ int mask, tid;
+
+ tid = mvpp2_prs_tcam_first_free(sc, MVPP2_PE_FIRST_FREE_TID,
+ MVPP2_PE_LAST_FREE_TID);
+ if (tid < 0)
+ return tid;
+
+ memset(&pe, 0, sizeof(struct mvpp2_prs_entry));
+ mvpp2_prs_tcam_lu_set(&pe, MVPP2_PRS_LU_IP4);
+ pe.index = tid;
+
+ switch (l3_cast) {
+ case MVPP2_PRS_L3_MULTI_CAST:
+ mvpp2_prs_tcam_data_byte_set(&pe, 0, MVPP2_PRS_IPV4_MC,
+ MVPP2_PRS_IPV4_MC_MASK);
+ mvpp2_prs_sram_ri_update(&pe, MVPP2_PRS_RI_L3_MCAST,
+ MVPP2_PRS_RI_L3_ADDR_MASK);
+ break;
+ case MVPP2_PRS_L3_BROAD_CAST:
+ mask = MVPP2_PRS_IPV4_BC_MASK;
+ mvpp2_prs_tcam_data_byte_set(&pe, 0, mask, mask);
+ mvpp2_prs_tcam_data_byte_set(&pe, 1, mask, mask);
+ mvpp2_prs_tcam_data_byte_set(&pe, 2, mask, mask);
+ mvpp2_prs_tcam_data_byte_set(&pe, 3, mask, mask);
+ mvpp2_prs_sram_ri_update(&pe, MVPP2_PRS_RI_L3_BCAST,
+ MVPP2_PRS_RI_L3_ADDR_MASK);
+ break;
+ default:
+ return EINVAL;
+ }
+
+ mvpp2_prs_sram_next_lu_set(&pe, MVPP2_PRS_LU_FLOWS);
+ mvpp2_prs_sram_bits_set(&pe, MVPP2_PRS_SRAM_LU_GEN_BIT, 1);
+ mvpp2_prs_tcam_ai_update(&pe, MVPP2_PRS_IPV4_DIP_AI_BIT,
+ MVPP2_PRS_IPV4_DIP_AI_BIT);
+ mvpp2_prs_tcam_port_map_set(&pe, MVPP2_PRS_PORT_MASK);
+ mvpp2_prs_shadow_set(sc, pe.index, MVPP2_PRS_LU_IP4);
+ mvpp2_prs_hw_write(sc, &pe);
+
+ return 0;
+}
+
+int
+mvpp2_prs_ip6_proto(struct mvpp2_softc *sc, uint16_t proto, uint32_t ri,
+ uint32_t ri_mask)
+{
+ struct mvpp2_prs_entry pe;
+ int tid;
+
+ if ((proto != MV_IPPR_TCP) && (proto != MV_IPPR_UDP) &&
+ (proto != MV_IPPR_ICMPV6) && (proto != MV_IPPR_IPIP))
+ return EINVAL;
+
+ tid = mvpp2_prs_tcam_first_free(sc, MVPP2_PE_FIRST_FREE_TID,
+ MVPP2_PE_LAST_FREE_TID);
+ if (tid < 0)
+ return tid;
+
+ memset(&pe, 0, sizeof(struct mvpp2_prs_entry));
+ mvpp2_prs_tcam_lu_set(&pe, MVPP2_PRS_LU_IP6);
+ pe.index = tid;
+ mvpp2_prs_sram_next_lu_set(&pe, MVPP2_PRS_LU_FLOWS);
+ mvpp2_prs_sram_bits_set(&pe, MVPP2_PRS_SRAM_LU_GEN_BIT, 1);
+ mvpp2_prs_sram_ri_update(&pe, ri, ri_mask);
+ mvpp2_prs_sram_offset_set( &pe, MVPP2_PRS_SRAM_UDF_TYPE_L4,
+ sizeof(struct ip6_hdr) - 6, MVPP2_PRS_SRAM_OP_SEL_UDF_ADD);
+ mvpp2_prs_tcam_data_byte_set(&pe, 0, proto, MVPP2_PRS_TCAM_PROTO_MASK);
+ mvpp2_prs_tcam_ai_update(&pe, MVPP2_PRS_IPV6_NO_EXT_AI_BIT,
+ MVPP2_PRS_IPV6_NO_EXT_AI_BIT);
+ mvpp2_prs_tcam_port_map_set(&pe, MVPP2_PRS_PORT_MASK);
+ mvpp2_prs_shadow_set(sc, pe.index, MVPP2_PRS_LU_IP6);
+ mvpp2_prs_hw_write(sc, &pe);
+
+ return 0;
+}
+
+int
+mvpp2_prs_ip6_cast(struct mvpp2_softc *sc, uint16_t l3_cast)
+{
+ struct mvpp2_prs_entry pe;
+ int tid;
+
+ if (l3_cast != MVPP2_PRS_L3_MULTI_CAST)
+ return EINVAL;
+
+ tid = mvpp2_prs_tcam_first_free(sc, MVPP2_PE_FIRST_FREE_TID, MVPP2_PE_LAST_FREE_TID);
+ if (tid < 0)
+ return tid;
+
+ memset(&pe, 0, sizeof(struct mvpp2_prs_entry));
+ mvpp2_prs_tcam_lu_set(&pe, MVPP2_PRS_LU_IP6);
+ pe.index = tid;
+ mvpp2_prs_sram_next_lu_set(&pe, MVPP2_PRS_LU_IP6);
+ mvpp2_prs_sram_ri_update(&pe, MVPP2_PRS_RI_L3_MCAST,
+ MVPP2_PRS_RI_L3_ADDR_MASK);
+ mvpp2_prs_sram_ai_update(&pe, MVPP2_PRS_IPV6_NO_EXT_AI_BIT,
+ MVPP2_PRS_IPV6_NO_EXT_AI_BIT);
+ mvpp2_prs_sram_shift_set(&pe, -18, MVPP2_PRS_SRAM_OP_SEL_SHIFT_ADD);
+ mvpp2_prs_tcam_data_byte_set(&pe, 0, MVPP2_PRS_IPV6_MC,
+ MVPP2_PRS_IPV6_MC_MASK);
+ mvpp2_prs_tcam_ai_update(&pe, 0, MVPP2_PRS_IPV6_NO_EXT_AI_BIT);
+ mvpp2_prs_tcam_port_map_set(&pe, MVPP2_PRS_PORT_MASK);
+ mvpp2_prs_shadow_set(sc, pe.index, MVPP2_PRS_LU_IP6);
+ mvpp2_prs_hw_write(sc, &pe);
+
+ return 0;
+}
+
+int
+mvpp2_prs_mac_range_equals(struct mvpp2_prs_entry *pe, const uint8_t *da,
+ uint8_t *mask)
+{
+ uint8_t tcam_byte, tcam_mask;
+ int index;
+
+ for (index = 0; index < ETHER_ADDR_LEN; index++) {
+ mvpp2_prs_tcam_data_byte_get(pe, index, &tcam_byte,
+ &tcam_mask);
+ if (tcam_mask != mask[index])
+ return 0;
+ if ((tcam_mask & tcam_byte) != (da[index] & mask[index]))
+ return 0;
+ }
+
+ return 1;
+}
+
+struct mvpp2_prs_entry *
+mvpp2_prs_mac_da_range_find(struct mvpp2_softc *sc, int pmap, const uint8_t *da,
+ uint8_t *mask, int udf_type)
+{
+ struct mvpp2_prs_entry *pe;
+ int tid;
+
+ pe = malloc(sizeof(*pe), M_TEMP, M_NOWAIT);
+ if (pe == NULL)
+ return NULL;
+
+ mvpp2_prs_tcam_lu_set(pe, MVPP2_PRS_LU_MAC);
+ for (tid = MVPP2_PE_FIRST_FREE_TID; tid <= MVPP2_PE_LAST_FREE_TID;
+ tid++) {
+ uint32_t entry_pmap;
+
+ if (!sc->sc_prs_shadow[tid].valid ||
+ (sc->sc_prs_shadow[tid].lu != MVPP2_PRS_LU_MAC) ||
+ (sc->sc_prs_shadow[tid].udf != udf_type))
+ continue;
+
+ pe->index = tid;
+ mvpp2_prs_hw_read(sc, pe);
+ entry_pmap = mvpp2_prs_tcam_port_map_get(pe);
+ if (mvpp2_prs_mac_range_equals(pe, da, mask) &&
+ entry_pmap == pmap)
+ return pe;
+ }
+
+ free(pe, M_TEMP, sizeof(*pe));
+ return NULL;
+}
+
+int
+mvpp2_prs_mac_da_accept(struct mvpp2_softc *sc, int port_id, const uint8_t *da,
+ int add)
+{
+ struct mvpp2_prs_entry *pe;
+ uint32_t pmap, len, ri;
+ uint8_t mask[ETHER_ADDR_LEN] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
+ int tid;
+
+ pe = mvpp2_prs_mac_da_range_find(sc, (1 << port_id), da, mask,
+ MVPP2_PRS_UDF_MAC_DEF);
+ if (pe == NULL) {
+ if (!add)
+ return 0;
+
+ for (tid = MVPP2_PE_FIRST_FREE_TID; tid <=
+ MVPP2_PE_LAST_FREE_TID; tid++) {
+ if (sc->sc_prs_shadow[tid].valid &&
+ (sc->sc_prs_shadow[tid].lu == MVPP2_PRS_LU_MAC) &&
+ (sc->sc_prs_shadow[tid].udf == MVPP2_PRS_UDF_MAC_RANGE))
+ break;
+ }
+
+ tid = mvpp2_prs_tcam_first_free(sc, MVPP2_PE_FIRST_FREE_TID, tid - 1);
+ if (tid < 0)
+ return tid;
+
+ pe = malloc(sizeof(*pe), M_TEMP, M_NOWAIT);
+ if (pe == NULL)
+ return ENOMEM;
+
+ mvpp2_prs_tcam_lu_set(pe, MVPP2_PRS_LU_MAC);
+ pe->index = tid;
+ mvpp2_prs_tcam_port_map_set(pe, 0);
+ }
+
+ mvpp2_prs_tcam_port_set(pe, port_id, add);
+
+ /* invalidate the entry if no ports are left enabled */
+ pmap = mvpp2_prs_tcam_port_map_get(pe);
+ if (pmap == 0) {
+ if (add) {
+ free(pe, M_TEMP, sizeof(*pe));
+ return -1;
+ }
+ mvpp2_prs_hw_inv(sc, pe->index);
+ sc->sc_prs_shadow[pe->index].valid = 0;
+ free(pe, M_TEMP, sizeof(*pe));
+ return 0;
+ }
+
+ mvpp2_prs_sram_next_lu_set(pe, MVPP2_PRS_LU_DSA);
+
+ len = ETHER_ADDR_LEN;
+ while (len--)
+ mvpp2_prs_tcam_data_byte_set(pe, len, da[len], 0xff);
+
+ if (ETHER_IS_BROADCAST(da))
+ ri = MVPP2_PRS_RI_L2_BCAST;
+ else if (ETHER_IS_MULTICAST(da))
+ ri = MVPP2_PRS_RI_L2_MCAST;
+ else
+ ri = MVPP2_PRS_RI_L2_UCAST | MVPP2_PRS_RI_MAC_ME_MASK;
+
+ mvpp2_prs_sram_ri_update(pe, ri, MVPP2_PRS_RI_L2_CAST_MASK |
+ MVPP2_PRS_RI_MAC_ME_MASK);
+ mvpp2_prs_shadow_ri_set(sc, pe->index, ri, MVPP2_PRS_RI_L2_CAST_MASK |
+ MVPP2_PRS_RI_MAC_ME_MASK);
+ mvpp2_prs_sram_shift_set(pe, 2 * ETHER_ADDR_LEN,
+ MVPP2_PRS_SRAM_OP_SEL_SHIFT_ADD);
+ sc->sc_prs_shadow[pe->index].udf = MVPP2_PRS_UDF_MAC_DEF;
+ mvpp2_prs_shadow_set(sc, pe->index, MVPP2_PRS_LU_MAC);
+ mvpp2_prs_hw_write(sc, pe);
+
+ free(pe, M_TEMP, sizeof(*pe));
+ return 0;
+}
+
+int
+mvpp2_prs_tag_mode_set(struct mvpp2_softc *sc, int port_id, int type)
+{
+ switch (type) {
+ case MVPP2_TAG_TYPE_EDSA:
+ mvpp2_prs_dsa_tag_set(sc, port_id, 1, MVPP2_PRS_TAGGED,
+ MVPP2_PRS_EDSA);
+ mvpp2_prs_dsa_tag_set(sc, port_id, 1, MVPP2_PRS_UNTAGGED,
+ MVPP2_PRS_EDSA);
+ mvpp2_prs_dsa_tag_set(sc, port_id, 0, MVPP2_PRS_TAGGED,
+ MVPP2_PRS_DSA);
+ mvpp2_prs_dsa_tag_set(sc, port_id, 0, MVPP2_PRS_UNTAGGED,
+ MVPP2_PRS_DSA);
+ break;
+ case MVPP2_TAG_TYPE_DSA:
+ mvpp2_prs_dsa_tag_set(sc, port_id, 1, MVPP2_PRS_TAGGED,
+ MVPP2_PRS_DSA);
+ mvpp2_prs_dsa_tag_set(sc, port_id, 1, MVPP2_PRS_UNTAGGED,
+ MVPP2_PRS_DSA);
+ mvpp2_prs_dsa_tag_set(sc, port_id, 0, MVPP2_PRS_TAGGED,
+ MVPP2_PRS_EDSA);
+ mvpp2_prs_dsa_tag_set(sc, port_id, 0, MVPP2_PRS_UNTAGGED,
+ MVPP2_PRS_EDSA);
+ break;
+ case MVPP2_TAG_TYPE_MH:
+ case MVPP2_TAG_TYPE_NONE:
+ mvpp2_prs_dsa_tag_set(sc, port_id, 0, MVPP2_PRS_TAGGED,
+ MVPP2_PRS_DSA);
+ mvpp2_prs_dsa_tag_set(sc, port_id, 0, MVPP2_PRS_UNTAGGED,
+ MVPP2_PRS_DSA);
+ mvpp2_prs_dsa_tag_set(sc, port_id, 0, MVPP2_PRS_TAGGED,
+ MVPP2_PRS_EDSA);
+ mvpp2_prs_dsa_tag_set(sc, port_id, 0, MVPP2_PRS_UNTAGGED,
+ MVPP2_PRS_EDSA);
+ break;
+ default:
+ if ((type < 0) || (type > MVPP2_TAG_TYPE_EDSA))
+ return EINVAL;
+ break;
+ }
+
+ return 0;
+}
+
+int
+mvpp2_prs_def_flow(struct mvpp2_port *port)
+{
+ struct mvpp2_prs_entry *pe;
+ int tid;
+
+ pe = mvpp2_prs_flow_find(port->sc, port->sc_id);
+ if (pe == NULL) {
+ tid = mvpp2_prs_tcam_first_free(port->sc,
+ MVPP2_PE_LAST_FREE_TID, MVPP2_PE_FIRST_FREE_TID);
+ if (tid < 0)
+ return tid;
+
+ pe = malloc(sizeof(*pe), M_TEMP, M_NOWAIT);
+ if (pe == NULL)
+ return ENOMEM;
+
+ mvpp2_prs_tcam_lu_set(pe, MVPP2_PRS_LU_FLOWS);
+ pe->index = tid;
+ mvpp2_prs_sram_ai_update(pe, port->sc_id,
+ MVPP2_PRS_FLOW_ID_MASK);
+ mvpp2_prs_sram_bits_set(pe, MVPP2_PRS_SRAM_LU_DONE_BIT, 1);
+ mvpp2_prs_shadow_set(port->sc, pe->index, MVPP2_PRS_LU_FLOWS);
+ }
+
+ mvpp2_prs_tcam_port_map_set (pe,(1 << port->sc_id));
+ mvpp2_prs_hw_write(port->sc, pe);
+ free(pe, M_TEMP, sizeof(*pe));
+ return 0;
+}
+
+void
+mvpp2_cls_flow_write(struct mvpp2_softc *sc, struct mvpp2_cls_flow_entry *fe)
+{
+ mvpp2_write(sc, MVPP2_CLS_FLOW_INDEX_REG, fe->index);
+ mvpp2_write(sc, MVPP2_CLS_FLOW_TBL0_REG, fe->data[0]);
+ mvpp2_write(sc, MVPP2_CLS_FLOW_TBL1_REG, fe->data[1]);
+ mvpp2_write(sc, MVPP2_CLS_FLOW_TBL2_REG, fe->data[2]);
+}
+
+void
+mvpp2_cls_lookup_write(struct mvpp2_softc *sc, struct mvpp2_cls_lookup_entry *le)
+{
+ uint32_t val;
+
+ val = (le->way << MVPP2_CLS_LKP_INDEX_WAY_OFFS) | le->lkpid;
+ mvpp2_write(sc, MVPP2_CLS_LKP_INDEX_REG, val);
+ mvpp2_write(sc, MVPP2_CLS_LKP_TBL_REG, le->data);
+}
+
+void
+mvpp2_cls_init(struct mvpp2_softc *sc)
+{
+ struct mvpp2_cls_lookup_entry le;
+ struct mvpp2_cls_flow_entry fe;
+ int index;
+
+ mvpp2_write(sc, MVPP2_CLS_MODE_REG, MVPP2_CLS_MODE_ACTIVE_MASK);
+ memset(&fe.data, 0, MVPP2_CLS_FLOWS_TBL_DATA_WORDS);
+ for (index = 0; index < MVPP2_CLS_FLOWS_TBL_SIZE; index++) {
+ fe.index = index;
+ mvpp2_cls_flow_write(sc, &fe);
+ }
+ le.data = 0;
+ for (index = 0; index < MVPP2_CLS_LKP_TBL_SIZE; index++) {
+ le.lkpid = index;
+ le.way = 0;
+ mvpp2_cls_lookup_write(sc, &le);
+ le.way = 1;
+ mvpp2_cls_lookup_write(sc, &le);
+ }
+}
+
+void
+mvpp2_cls_port_config(struct mvpp2_port *port)
+{
+ struct mvpp2_cls_lookup_entry le;
+ uint32_t val;
+
+ /* set way for the port */
+ val = mvpp2_read(port->sc, MVPP2_CLS_PORT_WAY_REG);
+ val &= ~MVPP2_CLS_PORT_WAY_MASK(port->sc_id);
+ mvpp2_write(port->sc, MVPP2_CLS_PORT_WAY_REG, val);
+
+ /*
+ * pick the entry to be accessed in lookup ID decoding table
+ * according to the way and lkpid.
+ */
+ le.lkpid = port->sc_id;
+ le.way = 0;
+ le.data = 0;
+
+ /* set initial CPU queue for receiving packets */
+ le.data &= ~MVPP2_CLS_LKP_TBL_RXQ_MASK;
+ le.data |= (port->sc_id * 32);
+
+ /* disable classification engines */
+ le.data &= ~MVPP2_CLS_LKP_TBL_LOOKUP_EN_MASK;
+
+ /* update lookup ID table entry */
+ mvpp2_cls_lookup_write(port->sc, &le);
+}
+
+void
+mvpp2_cls_oversize_rxq_set(struct mvpp2_port *port)
+{
+ mvpp2_write(port->sc, MVPP2_CLS_OVERSIZE_RXQ_LOW_REG(port->sc_id),
+ (port->sc_id * 32) & MVPP2_CLS_OVERSIZE_RXQ_LOW_MASK);
+}
diff --git a/sys/dev/fdt/if_mvppreg.h b/sys/dev/fdt/if_mvppreg.h
new file mode 100644
index 00000000000..4a3e3d5f2c7
--- /dev/null
+++ b/sys/dev/fdt/if_mvppreg.h
@@ -0,0 +1,2077 @@
+/* $OpenBSD: if_mvppreg.h,v 1.1 2020/06/25 12:09:11 patrick Exp $ */
+/*
+ * Copyright (c) 2008, 2019 Mark Kettenis <kettenis@openbsd.org>
+ * Copyright (c) 2017, 2020 Patrick Wildt <patrick@blueri.se>
+ *
+ * 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.
+ */
+/*
+ * Copyright (C) 2016 Marvell International Ltd.
+ *
+ * Marvell BSD License Option
+ *
+ * If you received this File from Marvell, you may opt to use, redistribute
+ * and/or modify this File under the following licensing terms.
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * * Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * * Neither the name of Marvell nor the names of its contributors may be
+ * used to endorse or promote products derived from this software without
+ * specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef __MVPP2_LIB_HW__
+#define __MVPP2_LIB_HW__
+
+#ifndef BIT
+#define BIT(nr) (1 << (nr))
+#endif
+
+/* PP2v2 registers offsets */
+#define MVPP22_SMI_OFFSET 0x1200
+#define MVPP22_MPCS_OFFSET 0x7000
+#define MVPP22_MPCS_REG_SIZE 0x1000
+#define MVPP22_XPCS_OFFSET 0x7400
+#define MVPP22_XPCS_REG_SIZE 0x1000
+#define MVPP22_GMAC_OFFSET 0x7e00
+#define MVPP22_GMAC_REG_SIZE 0x1000
+#define MVPP22_XLG_OFFSET 0x7f00
+#define MVPP22_XLG_REG_SIZE 0x1000
+#define MVPP22_RFU1_OFFSET 0x318000
+#define MVPP22_ADDR_SPACE_SIZE 0x10000
+
+/* RX Fifo Registers */
+#define MVPP2_RX_DATA_FIFO_SIZE_REG(port) (0x00 + 4 * (port))
+#define MVPP2_RX_ATTR_FIFO_SIZE_REG(port) (0x20 + 4 * (port))
+#define MVPP2_RX_MIN_PKT_SIZE_REG 0x60
+#define MVPP2_RX_FIFO_INIT_REG 0x64
+#define MVPP22_TX_FIFO_THRESH_REG(port) (0x8840 + 4 * (port))
+#define MVPP22_TX_FIFO_SIZE_REG(port) (0x8860 + 4 * (port))
+
+/* RX DMA Top Registers */
+#define MVPP2_RX_CTRL_REG(port) (0x140 + 4 * (port))
+#define MVPP2_RX_LOW_LATENCY_PKT_SIZE(s) (((s) & 0xfff) << 16)
+#define MVPP2_RX_USE_PSEUDO_FOR_CSUM_MASK BIT(31)
+#define MVPP2_POOL_BUF_SIZE_REG(pool) (0x180 + 4 * (pool))
+#define MVPP2_POOL_BUF_SIZE_OFFSET 5
+#define MVPP2_RXQ_CONFIG_REG(rxq) (0x800 + 4 * (rxq))
+#define MVPP2_SNOOP_PKT_SIZE_MASK 0x1ff
+#define MVPP2_SNOOP_BUF_HDR_MASK BIT(9)
+#define MVPP2_RXQ_POOL_SHORT_OFFS 20
+#define MVPP2_RXQ_POOL_SHORT_MASK 0xf00000
+#define MVPP2_RXQ_POOL_LONG_OFFS 24
+#define MVPP2_RXQ_POOL_LONG_MASK 0xf000000
+#define MVPP2_RXQ_PACKET_OFFSET_OFFS 28
+#define MVPP2_RXQ_PACKET_OFFSET_MASK 0x70000000
+#define MVPP2_RXQ_DISABLE_MASK BIT(31)
+
+/* Parser Registers */
+#define MVPP2_PRS_INIT_LOOKUP_REG 0x1000
+#define MVPP2_PRS_PORT_LU_MAX 0xf
+#define MVPP2_PRS_PORT_LU_MASK(port) (0xff << ((port) * 4))
+#define MVPP2_PRS_PORT_LU_VAL(port, val) ((val) << ((port) * 4))
+#define MVPP2_PRS_INIT_OFFS_REG(port) (0x1004 + ((port) & 4))
+#define MVPP2_PRS_INIT_OFF_MASK(port) (0x3f << (((port) % 4) * 8))
+#define MVPP2_PRS_INIT_OFF_VAL(port, val) ((val) << (((port) % 4) * 8))
+#define MVPP2_PRS_MAX_LOOP_REG(port) (0x100c + ((port) & 4))
+#define MVPP2_PRS_MAX_LOOP_MASK(port) (0xff << (((port) % 4) * 8))
+#define MVPP2_PRS_MAX_LOOP_VAL(port, val) ((val) << (((port) % 4) * 8))
+#define MVPP2_PRS_TCAM_IDX_REG 0x1100
+#define MVPP2_PRS_TCAM_DATA_REG(idx) (0x1104 + (idx) * 4)
+#define MVPP2_PRS_TCAM_INV_MASK BIT(31)
+#define MVPP2_PRS_SRAM_IDX_REG 0x1200
+#define MVPP2_PRS_SRAM_DATA_REG(idx) (0x1204 + (idx) * 4)
+#define MVPP2_PRS_TCAM_CTRL_REG 0x1230
+#define MVPP2_PRS_TCAM_EN_MASK BIT(0)
+
+/* Classifier Registers */
+#define MVPP2_CLS_MODE_REG 0x1800
+#define MVPP2_CLS_MODE_ACTIVE_MASK BIT(0)
+#define MVPP2_CLS_PORT_WAY_REG 0x1810
+#define MVPP2_CLS_PORT_WAY_MASK(port) (1 << (port))
+#define MVPP2_CLS_LKP_INDEX_REG 0x1814
+#define MVPP2_CLS_LKP_INDEX_WAY_OFFS 6
+#define MVPP2_CLS_LKP_TBL_REG 0x1818
+#define MVPP2_CLS_LKP_TBL_RXQ_MASK 0xff
+#define MVPP2_CLS_LKP_TBL_LOOKUP_EN_MASK BIT(25)
+#define MVPP2_CLS_FLOW_INDEX_REG 0x1820
+#define MVPP2_CLS_FLOW_TBL0_REG 0x1824
+#define MVPP2_CLS_FLOW_TBL1_REG 0x1828
+#define MVPP2_CLS_FLOW_TBL2_REG 0x182c
+#define MVPP2_CLS_OVERSIZE_RXQ_LOW_REG(port) (0x1980 + ((port) * 4))
+#define MVPP2_CLS_OVERSIZE_RXQ_LOW_BITS 3
+#define MVPP2_CLS_OVERSIZE_RXQ_LOW_MASK 0x7
+#define MVPP2_CLS_SWFWD_P2HQ_REG(port) (0x19b0 + ((port) * 4))
+#define MVPP2_CLS_SWFWD_PCTRL_REG 0x19d0
+#define MVPP2_CLS_SWFWD_PCTRL_MASK(port) (1 << (port))
+
+/* Descriptor Manager Top Registers */
+#define MVPP2_RXQ_NUM_REG 0x2040
+#define MVPP2_RXQ_DESC_ADDR_REG 0x2044
+#define MVPP2_RXQ_DESC_SIZE_REG 0x2048
+#define MVPP2_RXQ_DESC_SIZE_MASK 0x3ff0
+#define MVPP2_RXQ_STATUS_UPDATE_REG(rxq) (0x3000 + 4 * (rxq))
+#define MVPP2_RXQ_NUM_PROCESSED_OFFSET 0
+#define MVPP2_RXQ_NUM_NEW_OFFSET 16
+#define MVPP2_RXQ_STATUS_REG(rxq) (0x3400 + 4 * (rxq))
+#define MVPP2_RXQ_OCCUPIED_MASK 0x3fff
+#define MVPP2_RXQ_NON_OCCUPIED_OFFSET 16
+#define MVPP2_RXQ_NON_OCCUPIED_MASK 0x3fff0000
+#define MVPP2_RXQ_THRESH_REG 0x204c
+#define MVPP2_OCCUPIED_THRESH_OFFSET 0
+#define MVPP2_OCCUPIED_THRESH_MASK 0x3fff
+#define MVPP2_RXQ_INDEX_REG 0x2050
+#define MVPP2_TXQ_NUM_REG 0x2080
+#define MVPP2_TXQ_DESC_ADDR_REG 0x2084
+#define MVPP22_TXQ_DESC_ADDR_HIGH_REG 0x20a8
+#define MVPP22_TXQ_DESC_ADDR_HIGH_MASK 0xff
+#define MVPP2_TXQ_DESC_SIZE_REG 0x2088
+#define MVPP2_TXQ_DESC_SIZE_MASK 0x3ff0
+#define MVPP2_AGGR_TXQ_UPDATE_REG 0x2090
+#define MVPP2_TXQ_THRESH_REG 0x2094
+#define MVPP2_TRANSMITTED_THRESH_OFFSET 16
+#define MVPP2_TRANSMITTED_THRESH_MASK 0x3fff
+#define MVPP2_TXQ_INDEX_REG 0x2098
+#define MVPP2_TXQ_PREF_BUF_REG 0x209c
+#define MVPP2_PREF_BUF_PTR(desc) ((desc) & 0xfff)
+#define MVPP2_PREF_BUF_SIZE_4 (BIT(12) | BIT(13))
+#define MVPP2_PREF_BUF_SIZE_16 (BIT(12) | BIT(14))
+#define MVPP2_PREF_BUF_THRESH(val) ((val) << 17)
+#define MVPP2_TXQ_DRAIN_EN_MASK BIT(31)
+#define MVPP2_TXQ_PENDING_REG 0x20a0
+#define MVPP2_TXQ_PENDING_MASK 0x3fff
+#define MVPP2_TXQ_INT_STATUS_REG 0x20a4
+#define MVPP2_TXQ_SENT_REG(txq) (0x3c00 + 4 * (txq))
+#define MVPP22_TXQ_SENT_REG(txq) (0x3e00 + 4 * (txq-128))
+#define MVPP2_TRANSMITTED_COUNT_OFFSET 16
+#define MVPP2_TRANSMITTED_COUNT_MASK 0x3fff0000
+#define MVPP2_TXQ_RSVD_REQ_REG 0x20b0
+#define MVPP2_TXQ_RSVD_REQ_Q_OFFSET 16
+#define MVPP2_TXQ_RSVD_RSLT_REG 0x20b4
+#define MVPP2_TXQ_RSVD_RSLT_MASK 0x3fff
+#define MVPP2_TXQ_RSVD_CLR_REG 0x20b8
+#define MVPP2_TXQ_RSVD_CLR_OFFSET 16
+#define MVPP2_AGGR_TXQ_DESC_ADDR_REG(cpu) (0x2100 + 4 * (cpu))
+#define MVPP2_AGGR_TXQ_DESC_SIZE_REG(cpu) (0x2140 + 4 * (cpu))
+#define MVPP2_AGGR_TXQ_DESC_SIZE_MASK 0x3ff0
+#define MVPP2_AGGR_TXQ_STATUS_REG(cpu) (0x2180 + 4 * (cpu))
+#define MVPP2_AGGR_TXQ_PENDING_MASK 0x3fff
+#define MVPP2_AGGR_TXQ_INDEX_REG(cpu) (0x21c0 + 4 * (cpu))
+
+/* MBUS bridge registers */
+#define MVPP2_WIN_BASE(w) (0x4000 + ((w) << 2))
+#define MVPP2_WIN_SIZE(w) (0x4020 + ((w) << 2))
+#define MVPP2_WIN_REMAP(w) (0x4040 + ((w) << 2))
+#define MVPP2_BASE_ADDR_ENABLE 0x4060
+
+/* Interrupt Cause and Mask registers */
+#define MVPP2_ISR_TX_THRESHOLD_REG(port) (0x5140 + 4 * (port))
+#define MVPP2_ISR_RX_THRESHOLD_REG(rxq) (0x5200 + 4 * (rxq))
+#define MVPP2_ISR_RXQ_GROUP_REG(rxq) (0x5400 + 4 * (rxq))
+#define MVPP2_ISR_RXQ_GROUP_INDEX_REG 0x5400
+#define MVPP2_ISR_RXQ_GROUP_INDEX_GROUP_SHIFT 7
+#define MVPP2_ISR_RXQ_SUB_GROUP_CONFIG_REG 0x5404
+#define MVPP2_ISR_RXQ_SUB_GROUP_CONFIG_SIZE_SHIFT 8
+#define MVPP2_ISR_ENABLE_REG(port) (0x5420 + 4 * (port))
+#define MVPP2_ISR_ENABLE_INTERRUPT(mask) ((mask) & 0xffff)
+#define MVPP2_ISR_DISABLE_INTERRUPT(mask) (((mask) << 16) & 0xffff0000)
+#define MVPP2_ISR_RX_TX_CAUSE_REG(port) (0x5480 + 4 * (port))
+#define MVPP2_CAUSE_RXQ_OCCUP_DESC_ALL_MASK 0xff
+#define MVPP2_CAUSE_TXQ_OCCUP_DESC_ALL_MASK 0xff0000
+#define MVPP2_CAUSE_TXQ_OCCUP_DESC_ALL_OFFSET 16
+#define MVPP2_CAUSE_RX_FIFO_OVERRUN_MASK BIT(24)
+#define MVPP2_CAUSE_FCS_ERR_MASK BIT(25)
+#define MVPP2_CAUSE_TX_FIFO_UNDERRUN_MASK BIT(26)
+#define MVPP2_CAUSE_TX_EXCEPTION_SUM_MASK BIT(29)
+#define MVPP2_CAUSE_RX_EXCEPTION_SUM_MASK BIT(30)
+#define MVPP2_CAUSE_MISC_SUM_MASK BIT(31)
+#define MVPP2_ISR_RX_TX_MASK_REG(port) (0x54a0 + 4 * (port))
+#define MVPP2_ISR_PON_RX_TX_MASK_REG 0x54bc
+#define MVPP2_PON_CAUSE_RXQ_OCCUP_DESC_ALL_MASK 0xffff
+#define MVPP2_PON_CAUSE_TXP_OCCUP_DESC_ALL_MASK 0x3fc00000
+#define MVPP2_PON_CAUSE_MISC_SUM_MASK BIT(31)
+#define MVPP2_ISR_MISC_CAUSE_REG 0x55b0
+
+/* Buffer Manager registers */
+#define MVPP2_BM_POOL_BASE_REG(pool) (0x6000 + ((pool) * 4))
+#define MVPP2_BM_POOL_BASE_ADDR_MASK 0xfffff80
+#define MVPP2_BM_POOL_SIZE_REG(pool) (0x6040 + ((pool) * 4))
+#define MVPP2_BM_POOL_SIZE_MASK 0xfff0
+#define MVPP2_BM_POOL_READ_PTR_REG(pool) (0x6080 + ((pool) * 4))
+#define MVPP2_BM_POOL_GET_READ_PTR_MASK 0xfff0
+#define MVPP2_BM_POOL_PTRS_NUM_REG(pool) (0x60c0 + ((pool) * 4))
+#define MVPP2_BM_POOL_PTRS_NUM_MASK 0xfff8
+#define MVPP2_BM_BPPI_READ_PTR_REG(pool) (0x6100 + ((pool) * 4))
+#define MVPP2_BM_BPPI_PTRS_NUM_REG(pool) (0x6140 + ((pool) * 4))
+#define MVPP2_BM_BPPI_PTR_NUM_MASK 0x7ff
+#define MVPP2_BM_BPPI_PREFETCH_FULL_MASK BIT(16)
+#define MVPP2_BM_POOL_CTRL_REG(pool) (0x6200 + ((pool) * 4))
+#define MVPP2_BM_START_MASK BIT(0)
+#define MVPP2_BM_STOP_MASK BIT(1)
+#define MVPP2_BM_STATE_MASK BIT(4)
+#define MVPP2_BM_LOW_THRESH_OFFS 8
+#define MVPP2_BM_LOW_THRESH_MASK 0x7f00
+#define MVPP2_BM_LOW_THRESH_VALUE(val) ((val) << MVPP2_BM_LOW_THRESH_OFFS)
+#define MVPP2_BM_HIGH_THRESH_OFFS 16
+#define MVPP2_BM_HIGH_THRESH_MASK 0x7f0000
+#define MVPP2_BM_HIGH_THRESH_VALUE(val) ((val) << MVPP2_BM_HIGH_THRESH_OFFS)
+#define MVPP2_BM_INTR_CAUSE_REG(pool) (0x6240 + ((pool) * 4))
+#define MVPP2_BM_RELEASED_DELAY_MASK BIT(0)
+#define MVPP2_BM_ALLOC_FAILED_MASK BIT(1)
+#define MVPP2_BM_BPPE_EMPTY_MASK BIT(2)
+#define MVPP2_BM_BPPE_FULL_MASK BIT(3)
+#define MVPP2_BM_AVAILABLE_BP_LOW_MASK BIT(4)
+#define MVPP2_BM_INTR_MASK_REG(pool) (0x6280 + ((pool) * 4))
+#define MVPP2_BM_PHY_ALLOC_REG(pool) (0x6400 + ((pool) * 4))
+#define MVPP2_BM_PHY_ALLOC_GRNTD_MASK BIT(0)
+#define MVPP2_BM_VIRT_ALLOC_REG 0x6440
+#define MVPP2_BM_PHY_RLS_REG(pool) (0x6480 + ((pool) * 4))
+#define MVPP2_BM_PHY_RLS_MC_BUFF_MASK BIT(0)
+#define MVPP2_BM_PHY_RLS_PRIO_EN_MASK BIT(1)
+#define MVPP2_BM_PHY_RLS_GRNTD_MASK BIT(2)
+#define MVPP2_BM_VIRT_RLS_REG 0x64c0
+#define MVPP2_BM_MC_RLS_REG 0x64c4
+#define MVPP2_BM_MC_ID_MASK 0xfff
+#define MVPP2_BM_FORCE_RELEASE_MASK BIT(12)
+
+#define MVPP22_BM_PHY_VIRT_HIGH_ALLOC_REG 0x6444
+#define MVPP22_BM_PHY_HIGH_ALLOC_OFFSET 0
+#define MVPP22_BM_VIRT_HIGH_ALLOC_OFFSET 8
+#define MVPP22_BM_VIRT_HIGH_ALLOC_MASK 0xff00
+
+#define MVPP22_BM_PHY_VIRT_HIGH_RLS_REG 0x64c4
+
+#define MVPP22_BM_PHY_HIGH_RLS_OFFSET 0
+#define MVPP22_BM_VIRT_HIGH_RLS_OFFST 8
+
+#define MVPP22_BM_POOL_BASE_HIGH_REG 0x6310
+#define MVPP22_BM_POOL_BASE_HIGH_MASK 0xff
+#define MVPP2_BM_PRIO_CTRL_REG 0x6800
+
+/* TX Scheduler registers */
+#define MVPP2_TXP_SCHED_PORT_INDEX_REG 0x8000
+#define MVPP2_TXP_SCHED_Q_CMD_REG 0x8004
+#define MVPP2_TXP_SCHED_ENQ_MASK 0xff
+#define MVPP2_TXP_SCHED_DISQ_OFFSET 8
+#define MVPP2_TXP_SCHED_CMD_1_REG 0x8010
+#define MVPP2_TXP_SCHED_PERIOD_REG 0x8018
+#define MVPP2_TXP_SCHED_MTU_REG 0x801c
+#define MVPP2_TXP_MTU_MAX 0x7FFFF
+#define MVPP2_TXP_SCHED_REFILL_REG 0x8020
+#define MVPP2_TXP_REFILL_TOKENS_ALL_MASK 0x7ffff
+#define MVPP2_TXP_REFILL_PERIOD_ALL_MASK 0x3ff00000
+#define MVPP2_TXP_REFILL_PERIOD_MASK(v) ((v) << 20)
+#define MVPP2_TXP_SCHED_TOKEN_SIZE_REG 0x8024
+#define MVPP2_TXP_TOKEN_SIZE_MAX 0xffffffff
+#define MVPP2_TXQ_SCHED_REFILL_REG(q) (0x8040 + ((q) << 2))
+#define MVPP2_TXQ_REFILL_TOKENS_ALL_MASK 0x7ffff
+#define MVPP2_TXQ_REFILL_PERIOD_ALL_MASK 0x3ff00000
+#define MVPP2_TXQ_REFILL_PERIOD_MASK(v) ((v) << 20)
+#define MVPP2_TXQ_SCHED_TOKEN_SIZE_REG(q) (0x8060 + ((q) << 2))
+#define MVPP2_TXQ_TOKEN_SIZE_MAX 0x7fffffff
+#define MVPP2_TXQ_SCHED_TOKEN_CNTR_REG(q) (0x8080 + ((q) << 2))
+#define MVPP2_TXQ_TOKEN_CNTR_MAX 0xffffffff
+
+/* TX general registers */
+#define MVPP2_TX_SNOOP_REG 0x8800
+#define MVPP2_TX_PORT_FLUSH_REG 0x8810
+#define MVPP2_TX_PORT_FLUSH_MASK(port) (1 << (port))
+
+/* LMS registers */
+#define MVPP2_SRC_ADDR_MIDDLE 0x24
+#define MVPP2_SRC_ADDR_HIGH 0x28
+#define MVPP2_PHY_AN_CFG0_REG 0x34
+#define MVPP2_PHY_AN_STOP_SMI0_MASK BIT(7)
+#define MVPP2_MIB_COUNTERS_BASE(port) (0x1000 + ((port) >> 1) * 0x400 + (port) * 0x400)
+#define MVPP2_MIB_LATE_COLLISION 0x7c
+#define MVPP2_ISR_SUM_MASK_REG 0x220c
+#define MVPP2_MNG_EXTENDED_GLOBAL_CTRL_REG 0x305c
+#define MVPP2_EXT_GLOBAL_CTRL_DEFAULT 0x27
+
+/* Per-port registers */
+#define MVPP2_GMAC_CTRL_0_REG 0x0
+#define MVPP2_GMAC_PORT_EN_MASK BIT(0)
+#define MVPP2_GMAC_PORT_TYPE_MASK BIT(1)
+#define MVPP2_GMAC_MAX_RX_SIZE_OFFS 2
+#define MVPP2_GMAC_MAX_RX_SIZE_MASK 0x7ffc
+#define MVPP2_GMAC_MIB_CNTR_EN_MASK BIT(15)
+#define MVPP2_GMAC_CTRL_1_REG 0x4
+#define MVPP2_GMAC_PERIODIC_XON_EN_MASK BIT(1)
+#define MVPP2_GMAC_GMII_LB_EN_MASK BIT(5)
+#define MVPP2_GMAC_PCS_LB_EN_BIT 6
+#define MVPP2_GMAC_PCS_LB_EN_MASK BIT(6)
+#define MVPP2_GMAC_SA_LOW_OFFS 7
+#define MVPP2_GMAC_CTRL_2_REG 0x8
+#define MVPP2_GMAC_INBAND_AN_MASK BIT(0)
+#define MVPP2_GMAC_PCS_ENABLE_MASK BIT(3)
+#define MVPP2_GMAC_PORT_RGMII_MASK BIT(4)
+#define MVPP2_GMAC_PORT_RESET_MASK BIT(6)
+#define MVPP2_GMAC_AUTONEG_CONFIG 0xc
+#define MVPP2_GMAC_FORCE_LINK_DOWN BIT(0)
+#define MVPP2_GMAC_FORCE_LINK_PASS BIT(1)
+#define MVPP2_GMAC_IN_BAND_AUTONEG BIT(2)
+#define MVPP2_GMAC_IN_BAND_AUTONEG_BYPASS BIT(3)
+#define MVPP2_GMAC_IN_BAND_RESTART_AN BIT(4)
+#define MVPP2_GMAC_CONFIG_MII_SPEED BIT(5)
+#define MVPP2_GMAC_CONFIG_GMII_SPEED BIT(6)
+#define MVPP2_GMAC_AN_SPEED_EN BIT(7)
+#define MVPP2_GMAC_FC_ADV_EN BIT(9)
+#define MVPP2_GMAC_FC_ADV_ASM_EN BIT(10)
+#define MVPP2_GMAC_FLOW_CTRL_AUTONEG BIT(11)
+#define MVPP2_GMAC_CONFIG_FULL_DUPLEX BIT(12)
+#define MVPP2_GMAC_AN_DUPLEX_EN BIT(13)
+#define MVPP2_GMAC_PORT_FIFO_CFG_1_REG 0x1c
+#define MVPP2_GMAC_TX_FIFO_MIN_TH_OFFS 6
+#define MVPP2_GMAC_TX_FIFO_MIN_TH_ALL_MASK 0x1fc0
+#define MVPP2_GMAC_TX_FIFO_MIN_TH_MASK(v) (((v) << 6) & MVPP2_GMAC_TX_FIFO_MIN_TH_ALL_MASK)
+
+/* Port Interrupts */
+#define MV_GMAC_INTERRUPT_CAUSE_REG (0x0020)
+#define MV_GMAC_INTERRUPT_MASK_REG (0x0024)
+#define MV_GMAC_INTERRUPT_CAUSE_LINK_CHANGE_OFFS 1
+#define MV_GMAC_INTERRUPT_CAUSE_LINK_CHANGE_MASK (0x1 << MV_GMAC_INTERRUPT_CAUSE_LINK_CHANGE_OFFS)
+
+/* Port Interrupt Summary */
+#define MV_GMAC_INTERRUPT_SUM_CAUSE_REG (0x00A0)
+#define MV_GMAC_INTERRUPT_SUM_MASK_REG (0x00A4)
+#define MV_GMAC_INTERRUPT_SUM_CAUSE_LINK_CHANGE_OFFS 1
+#define MV_GMAC_INTERRUPT_SUM_CAUSE_LINK_CHANGE_MASK (0x1 << MV_GMAC_INTERRUPT_SUM_CAUSE_LINK_CHANGE_OFFS)
+
+/* Port Mac Control0 */
+#define MVPP2_PORT_CTRL0_REG (0x0000)
+#define MVPP2_PORT_CTRL0_PORTEN_OFFS 0
+#define MVPP2_PORT_CTRL0_PORTEN_MASK \
+ (0x00000001 << MVPP2_PORT_CTRL0_PORTEN_OFFS)
+
+#define MVPP2_PORT_CTRL0_PORTTYPE_OFFS 1
+#define MVPP2_PORT_CTRL0_PORTTYPE_MASK \
+ (0x00000001 << MVPP2_PORT_CTRL0_PORTTYPE_OFFS)
+
+#define MVPP2_PORT_CTRL0_FRAMESIZELIMIT_OFFS 2
+#define MVPP2_PORT_CTRL0_FRAMESIZELIMIT_MASK \
+ (0x00001fff << MVPP2_PORT_CTRL0_FRAMESIZELIMIT_OFFS)
+
+#define MVPP2_PORT_CTRL0_COUNT_EN_OFFS 15
+#define MVPP2_PORT_CTRL0_COUNT_EN_MASK \
+ (0x00000001 << MVPP2_PORT_CTRL0_COUNT_EN_OFFS)
+
+/* Port Mac Control1 */
+#define MVPP2_PORT_CTRL1_REG (0x0004)
+#define MVPP2_PORT_CTRL1_EN_RX_CRC_CHECK_OFFS 0
+#define MVPP2_PORT_CTRL1_EN_RX_CRC_CHECK_MASK \
+ (0x00000001 << MVPP2_PORT_CTRL1_EN_RX_CRC_CHECK_OFFS)
+
+#define MVPP2_PORT_CTRL1_EN_PERIODIC_FC_XON_OFFS 1
+#define MVPP2_PORT_CTRL1_EN_PERIODIC_FC_XON_MASK \
+ (0x00000001 << MVPP2_PORT_CTRL1_EN_PERIODIC_FC_XON_OFFS)
+
+#define MVPP2_PORT_CTRL1_MGMII_MODE_OFFS 2
+#define MVPP2_PORT_CTRL1_MGMII_MODE_MASK \
+ (0x00000001 << MVPP2_PORT_CTRL1_MGMII_MODE_OFFS)
+
+#define MVPP2_PORT_CTRL1_PFC_CASCADE_PORT_ENABLE_OFFS 3
+#define MVPP2_PORT_CTRL1_PFC_CASCADE_PORT_ENABLE_MASK \
+ (0x00000001 << MVPP2_PORT_CTRL1_PFC_CASCADE_PORT_ENABLE_OFFS)
+
+#define MVPP2_PORT_CTRL1_DIS_EXCESSIVE_COL_OFFS 4
+#define MVPP2_PORT_CTRL1_DIS_EXCESSIVE_COL_MASK \
+ (0x00000001 << MVPP2_PORT_CTRL1_DIS_EXCESSIVE_COL_OFFS)
+
+#define MVPP2_PORT_CTRL1_GMII_LOOPBACK_OFFS 5
+#define MVPP2_PORT_CTRL1_GMII_LOOPBACK_MASK \
+ (0x00000001 << MVPP2_PORT_CTRL1_GMII_LOOPBACK_OFFS)
+
+#define MVPP2_PORT_CTRL1_PCS_LOOPBACK_OFFS 6
+#define MVPP2_PORT_CTRL1_PCS_LOOPBACK_MASK \
+ (0x00000001 << MVPP2_PORT_CTRL1_PCS_LOOPBACK_OFFS)
+
+#define MVPP2_PORT_CTRL1_FC_SA_ADDR_LO_OFFS 7
+#define MVPP2_PORT_CTRL1_FC_SA_ADDR_LO_MASK \
+ (0x000000ff << MVPP2_PORT_CTRL1_FC_SA_ADDR_LO_OFFS)
+
+#define MVPP2_PORT_CTRL1_EN_SHORT_PREAMBLE_OFFS 15
+#define MVPP2_PORT_CTRL1_EN_SHORT_PREAMBLE_MASK \
+ (0x00000001 << MVPP2_PORT_CTRL1_EN_SHORT_PREAMBLE_OFFS)
+
+/* Port Mac Control2 */
+#define MVPP2_PORT_CTRL2_REG (0x0008)
+#define MVPP2_PORT_CTRL2_SGMII_MODE_OFFS 0
+#define MVPP2_PORT_CTRL2_SGMII_MODE_MASK \
+ (0x00000001 << MVPP2_PORT_CTRL2_SGMII_MODE_OFFS)
+
+#define MVPP2_PORT_CTRL2_FC_MODE_OFFS 1
+#define MVPP2_PORT_CTRL2_FC_MODE_MASK \
+ (0x00000003 << MVPP2_PORT_CTRL2_FC_MODE_OFFS)
+
+#define MVPP2_PORT_CTRL2_PCS_EN_OFFS 3
+#define MVPP2_PORT_CTRL2_PCS_EN_MASK \
+ (0x00000001 << MVPP2_PORT_CTRL2_PCS_EN_OFFS)
+
+#define MVPP2_PORT_CTRL2_RGMII_MODE_OFFS 4
+#define MVPP2_PORT_CTRL2_RGMII_MODE_MASK \
+ (0x00000001 << MVPP2_PORT_CTRL2_RGMII_MODE_OFFS)
+
+#define MVPP2_PORT_CTRL2_DIS_PADING_OFFS 5
+#define MVPP2_PORT_CTRL2_DIS_PADING_MASK \
+ (0x00000001 << MVPP2_PORT_CTRL2_DIS_PADING_OFFS)
+
+#define MVPP2_PORT_CTRL2_PORTMACRESET_OFFS 6
+#define MVPP2_PORT_CTRL2_PORTMACRESET_MASK \
+ (0x00000001 << MVPP2_PORT_CTRL2_PORTMACRESET_OFFS)
+
+#define MVPP2_PORT_CTRL2_TX_DRAIN_OFFS 7
+#define MVPP2_PORT_CTRL2_TX_DRAIN_MASK \
+ (0x00000001 << MVPP2_PORT_CTRL2_TX_DRAIN_OFFS)
+
+#define MVPP2_PORT_CTRL2_EN_MII_ODD_PRE_OFFS 8
+#define MVPP2_PORT_CTRL2_EN_MII_ODD_PRE_MASK \
+ (0x00000001 << MVPP2_PORT_CTRL2_EN_MII_ODD_PRE_OFFS)
+
+#define MVPP2_PORT_CTRL2_CLK_125_BYPS_EN_OFFS 9
+#define MVPP2_PORT_CTRL2_CLK_125_BYPS_EN_MASK \
+ (0x00000001 << MVPP2_PORT_CTRL2_CLK_125_BYPS_EN_OFFS)
+
+#define MVPP2_PORT_CTRL2_PRBS_CHECK_EN_OFFS 10
+#define MVPP2_PORT_CTRL2_PRBS_CHECK_EN_MASK \
+ (0x00000001 << MVPP2_PORT_CTRL2_PRBS_CHECK_EN_OFFS)
+
+#define MVPP2_PORT_CTRL2_PRBS_GEN_EN_OFFS 11
+#define MVPP2_PORT_CTRL2_PRBS_GEN_EN_MASK \
+ (0x00000001 << MVPP2_PORT_CTRL2_PRBS_GEN_EN_OFFS)
+
+#define MVPP2_PORT_CTRL2_SELECT_DATA_TO_TX_OFFS 12
+#define MVPP2_PORT_CTRL2_SELECT_DATA_TO_TX_MASK \
+ (0x00000003 << MVPP2_PORT_CTRL2_SELECT_DATA_TO_TX_OFFS)
+
+#define MVPP2_PORT_CTRL2_EN_COL_ON_BP_OFFS 14
+#define MVPP2_PORT_CTRL2_EN_COL_ON_BP_MASK \
+ (0x00000001 << MVPP2_PORT_CTRL2_EN_COL_ON_BP_OFFS)
+
+#define MVPP2_PORT_CTRL2_EARLY_REJECT_MODE_OFFS 15
+#define MVPP2_PORT_CTRL2_EARLY_REJECT_MODE_MASK \
+ (0x00000001 << MVPP2_PORT_CTRL2_EARLY_REJECT_MODE_OFFS)
+
+/* Port Auto-negotiation Configuration */
+#define MVPP2_PORT_AUTO_NEG_CFG_REG (0x000c)
+#define MVPP2_PORT_AUTO_NEG_CFG_FORCE_LINK_DOWN_OFFS 0
+#define MVPP2_PORT_AUTO_NEG_CFG_FORCE_LINK_DOWN_MASK \
+ (0x00000001 << MVPP2_PORT_AUTO_NEG_CFG_FORCE_LINK_DOWN_OFFS)
+
+#define MVPP2_PORT_AUTO_NEG_CFG_FORCE_LINK_UP_OFFS 1
+#define MVPP2_PORT_AUTO_NEG_CFG_FORCE_LINK_UP_MASK \
+ (0x00000001 << MVPP2_PORT_AUTO_NEG_CFG_FORCE_LINK_UP_OFFS)
+
+#define MVPP2_PORT_AUTO_NEG_CFG_EN_PCS_AN_OFFS 2
+#define MVPP2_PORT_AUTO_NEG_CFG_EN_PCS_AN_MASK \
+ (0x00000001 << MVPP2_PORT_AUTO_NEG_CFG_EN_PCS_AN_OFFS)
+
+#define MVPP2_PORT_AUTO_NEG_CFG_AN_BYPASS_EN_OFFS 3
+#define MVPP2_PORT_AUTO_NEG_CFG_AN_BYPASS_EN_MASK \
+ (0x00000001 << MVPP2_PORT_AUTO_NEG_CFG_AN_BYPASS_EN_OFFS)
+
+#define MVPP2_PORT_AUTO_NEG_CFG_INBAND_RESTARTAN_OFFS 4
+#define MVPP2_PORT_AUTO_NEG_CFG_INBAND_RESTARTAN_MASK \
+ (0x00000001 << MVPP2_PORT_AUTO_NEG_CFG_INBAND_RESTARTAN_OFFS)
+
+#define MVPP2_PORT_AUTO_NEG_CFG_SET_MII_SPEED_OFFS 5
+#define MVPP2_PORT_AUTO_NEG_CFG_SET_MII_SPEED_MASK \
+ (0x00000001 << MVPP2_PORT_AUTO_NEG_CFG_SET_MII_SPEED_OFFS)
+
+#define MVPP2_PORT_AUTO_NEG_CFG_SET_GMII_SPEED_OFFS 6
+#define MVPP2_PORT_AUTO_NEG_CFG_SET_GMII_SPEED_MASK \
+ (0x00000001 << MVPP2_PORT_AUTO_NEG_CFG_SET_GMII_SPEED_OFFS)
+
+#define MVPP2_PORT_AUTO_NEG_CFG_EN_AN_SPEED_OFFS 7
+#define MVPP2_PORT_AUTO_NEG_CFG_EN_AN_SPEED_MASK \
+ (0x00000001 << MVPP2_PORT_AUTO_NEG_CFG_EN_AN_SPEED_OFFS)
+
+#define MVPP2_PORT_AUTO_NEG_CFG_ADV_PAUSE_OFFS 9
+#define MVPP2_PORT_AUTO_NEG_CFG_ADV_PAUSE_MASK \
+ (0x00000001 << MVPP2_PORT_AUTO_NEG_CFG_ADV_PAUSE_OFFS)
+
+#define MVPP2_PORT_AUTO_NEG_CFG_ADV_ASM_PAUSE_OFFS 10
+#define MVPP2_PORT_AUTO_NEG_CFG_ADV_ASM_PAUSE_MASK \
+ (0x00000001 << MVPP2_PORT_AUTO_NEG_CFG_ADV_ASM_PAUSE_OFFS)
+
+#define MVPP2_PORT_AUTO_NEG_CFG_EN_FC_AN_OFFS 11
+#define MVPP2_PORT_AUTO_NEG_CFG_EN_FC_AN_MASK \
+ (0x00000001 << MVPP2_PORT_AUTO_NEG_CFG_EN_FC_AN_OFFS)
+
+#define MVPP2_PORT_AUTO_NEG_CFG_SET_FULL_DX_OFFS 12
+#define MVPP2_PORT_AUTO_NEG_CFG_SET_FULL_DX_MASK \
+ (0x00000001 << MVPP2_PORT_AUTO_NEG_CFG_SET_FULL_DX_OFFS)
+
+#define MVPP2_PORT_AUTO_NEG_CFG_EN_FDX_AN_OFFS 13
+#define MVPP2_PORT_AUTO_NEG_CFG_EN_FDX_AN_MASK \
+ (0x00000001 << MVPP2_PORT_AUTO_NEG_CFG_EN_FDX_AN_OFFS)
+
+#define MVPP2_PORT_AUTO_NEG_CFG_PHY_MODE_OFFS 14
+#define MVPP2_PORT_AUTO_NEG_CFG_PHY_MODE_MASK \
+ (0x00000001 << MVPP2_PORT_AUTO_NEG_CFG_PHY_MODE_OFFS)
+
+#define MVPP2_PORT_AUTO_NEG_CFG_CHOOSE_SAMPLE_TX_CONFIG_OFFS 15
+#define MVPP2_PORT_AUTO_NEG_CFG_CHOOSE_SAMPLE_TX_CONFIG_MASK \
+ (0x00000001 << MVPP2_PORT_AUTO_NEG_CFG_CHOOSE_SAMPLE_TX_CONFIG_OFFS)
+
+/* Port Status0 */
+#define MVPP2_PORT_STATUS0_REG (0x0010)
+#define MVPP2_PORT_STATUS0_LINKUP_OFFS 0
+#define MVPP2_PORT_STATUS0_LINKUP_MASK \
+ (0x00000001 << MVPP2_PORT_STATUS0_LINKUP_OFFS)
+
+#define MVPP2_PORT_STATUS0_GMIISPEED_OFFS 1
+#define MVPP2_PORT_STATUS0_GMIISPEED_MASK \
+ (0x00000001 << MVPP2_PORT_STATUS0_GMIISPEED_OFFS)
+
+#define MVPP2_PORT_STATUS0_MIISPEED_OFFS 2
+#define MVPP2_PORT_STATUS0_MIISPEED_MASK \
+ (0x00000001 << MVPP2_PORT_STATUS0_MIISPEED_OFFS)
+
+#define MVPP2_PORT_STATUS0_FULLDX_OFFS 3
+#define MVPP2_PORT_STATUS0_FULLDX_MASK \
+ (0x00000001 << MVPP2_PORT_STATUS0_FULLDX_OFFS)
+
+#define MVPP2_PORT_STATUS0_RXFCEN_OFFS 4
+#define MVPP2_PORT_STATUS0_RXFCEN_MASK \
+ (0x00000001 << MVPP2_PORT_STATUS0_RXFCEN_OFFS)
+
+#define MVPP2_PORT_STATUS0_TXFCEN_OFFS 5
+#define MVPP2_PORT_STATUS0_TXFCEN_MASK \
+ (0x00000001 << MVPP2_PORT_STATUS0_TXFCEN_OFFS)
+
+#define MVPP2_PORT_STATUS0_PORTRXPAUSE_OFFS 6
+#define MVPP2_PORT_STATUS0_PORTRXPAUSE_MASK \
+ (0x00000001 << MVPP2_PORT_STATUS0_PORTRXPAUSE_OFFS)
+
+#define MVPP2_PORT_STATUS0_PORTTXPAUSE_OFFS 7
+#define MVPP2_PORT_STATUS0_PORTTXPAUSE_MASK \
+ (0x00000001 << MVPP2_PORT_STATUS0_PORTTXPAUSE_OFFS)
+
+#define MVPP2_PORT_STATUS0_PORTIS_DOINGPRESSURE_OFFS 8
+#define MVPP2_PORT_STATUS0_PORTIS_DOINGPRESSURE_MASK \
+ (0x00000001 << MVPP2_PORT_STATUS0_PORTIS_DOINGPRESSURE_OFFS)
+
+#define MVPP2_PORT_STATUS0_PORTBUFFULL_OFFS 9
+#define MVPP2_PORT_STATUS0_PORTBUFFULL_MASK \
+ (0x00000001 << MVPP2_PORT_STATUS0_PORTBUFFULL_OFFS)
+
+#define MVPP2_PORT_STATUS0_SYNCFAIL10MS_OFFS 10
+#define MVPP2_PORT_STATUS0_SYNCFAIL10MS_MASK \
+ (0x00000001 << MVPP2_PORT_STATUS0_SYNCFAIL10MS_OFFS)
+
+#define MVPP2_PORT_STATUS0_ANDONE_OFFS 11
+#define MVPP2_PORT_STATUS0_ANDONE_MASK \
+ (0x00000001 << MVPP2_PORT_STATUS0_ANDONE_OFFS)
+
+#define MVPP2_PORT_STATUS0_INBAND_AUTONEG_BYPASSACT_OFFS 12
+#define MVPP2_PORT_STATUS0_INBAND_AUTONEG_BYPASSACT_MASK \
+ (0x00000001 << MVPP2_PORT_STATUS0_INBAND_AUTONEG_BYPASSACT_OFFS)
+
+#define MVPP2_PORT_STATUS0_SERDESPLL_LOCKED_OFFS 13
+#define MVPP2_PORT_STATUS0_SERDESPLL_LOCKED_MASK \
+ (0x00000001 << MVPP2_PORT_STATUS0_SERDESPLL_LOCKED_OFFS)
+
+#define MVPP2_PORT_STATUS0_SYNCOK_OFFS 14
+#define MVPP2_PORT_STATUS0_SYNCOK_MASK \
+ (0x00000001 << MVPP2_PORT_STATUS0_SYNCOK_OFFS)
+
+#define MVPP2_PORT_STATUS0_SQUELCHNOT_DETECTED_OFFS 15
+#define MVPP2_PORT_STATUS0_SQUELCHNOT_DETECTED_MASK \
+ (0x00000001 << MVPP2_PORT_STATUS0_SQUELCHNOT_DETECTED_OFFS)
+
+/* Port Serial Parameters Configuration */
+#define MVPP2_PORT_SERIAL_PARAM_CFG_REG (0x0014)
+#define MVPP2_PORT_SERIAL_PARAM_CFG_UNIDIRECTIONAL_ENABLE_OFFS 0
+#define MVPP2_PORT_SERIAL_PARAM_CFG_UNIDIRECTIONAL_ENABLE_MASK \
+ (0x00000001 << MVPP2_PORT_SERIAL_PARAM_CFG_UNIDIRECTIONAL_ENABLE_OFFS)
+
+#define MVPP2_PORT_SERIAL_PARAM_CFG_RETRANSMIT_COLLISION_DOMAIN_OFFS 1
+#define MVPP2_PORT_SERIAL_PARAM_CFG_RETRANSMIT_COLLISION_DOMAIN_MASK \
+ (0x00000001 << MVPP2_PORT_SERIAL_PARAM_CFG_RETRANSMIT_COLLISION_DOMAIN_OFFS)
+
+#define MVPP2_PORT_SERIAL_PARAM_CFG_PUMA2_BTS1444_EN_OFFS 2
+#define MVPP2_PORT_SERIAL_PARAM_CFG_PUMA2_BTS1444_EN_MASK \
+ (0x00000001 << MVPP2_PORT_SERIAL_PARAM_CFG_PUMA2_BTS1444_EN_OFFS)
+
+#define MVPP2_PORT_SERIAL_PARAM_CFG_FORWARD_802_3X_FC_EN_OFFS 3
+#define MVPP2_PORT_SERIAL_PARAM_CFG_FORWARD_802_3X_FC_EN_MASK \
+ (0x00000001 << MVPP2_PORT_SERIAL_PARAM_CFG_FORWARD_802_3X_FC_EN_OFFS)
+
+#define MVPP2_PORT_SERIAL_PARAM_CFG_BP_EN_OFFS 4
+#define MVPP2_PORT_SERIAL_PARAM_CFG_BP_EN_MASK \
+ (0x00000001 << MVPP2_PORT_SERIAL_PARAM_CFG_BP_EN_OFFS)
+
+#define MVPP2_PORT_SERIAL_PARAM_CFG_RX_NEGEDGE_SAMPLE_EN_OFFS 5
+#define MVPP2_PORT_SERIAL_PARAM_CFG_RX_NEGEDGE_SAMPLE_EN_MASK \
+ (0x00000001 << MVPP2_PORT_SERIAL_PARAM_CFG_RX_NEGEDGE_SAMPLE_EN_OFFS)
+
+#define MVPP2_PORT_SERIAL_PARAM_CFG_COL_DOMAIN_LIMIT_OFFS 6
+#define MVPP2_PORT_SERIAL_PARAM_CFG_COL_DOMAIN_LIMIT_MASK \
+ (0x0000003f << MVPP2_PORT_SERIAL_PARAM_CFG_COL_DOMAIN_LIMIT_OFFS)
+
+#define MVPP2_PORT_SERIAL_PARAM_CFG_PERIODIC_TYPE_SELECT_OFFS 12
+#define MVPP2_PORT_SERIAL_PARAM_CFG_PERIODIC_TYPE_SELECT_MASK \
+ (0x00000001 << MVPP2_PORT_SERIAL_PARAM_CFG_PERIODIC_TYPE_SELECT_OFFS)
+
+#define MVPP2_PORT_SERIAL_PARAM_CFG_PER_PRIORITY_FC_EN_OFFS 13
+#define MVPP2_PORT_SERIAL_PARAM_CFG_PER_PRIORITY_FC_EN_MASK \
+ (0x00000001 << MVPP2_PORT_SERIAL_PARAM_CFG_PER_PRIORITY_FC_EN_OFFS)
+
+#define MVPP2_PORT_SERIAL_PARAM_CFG_TX_STANDARD_PRBS7_OFFS 14
+#define MVPP2_PORT_SERIAL_PARAM_CFG_TX_STANDARD_PRBS7_MASK \
+ (0x00000001 << MVPP2_PORT_SERIAL_PARAM_CFG_TX_STANDARD_PRBS7_OFFS)
+
+#define MVPP2_PORT_SERIAL_PARAM_CFG_REVERSE_PRBS_RX_OFFS 15
+#define MVPP2_PORT_SERIAL_PARAM_CFG_REVERSE_PRBS_RX_MASK \
+ (0x00000001 << MVPP2_PORT_SERIAL_PARAM_CFG_REVERSE_PRBS_RX_OFFS)
+
+/* Port Fifo Configuration 0 */
+#define MVPP2_PORT_FIFO_CFG_0_REG (0x0018)
+#define MVPP2_PORT_FIFO_CFG_0_TX_FIFO_HIGH_WM_OFFS 0
+#define MVPP2_PORT_FIFO_CFG_0_TX_FIFO_HIGH_WM_MASK \
+ (0x000000ff << MVPP2_PORT_FIFO_CFG_0_TX_FIFO_HIGH_WM_OFFS)
+
+#define MVPP2_PORT_FIFO_CFG_0_TX_FIFO_LOW_WM_OFFS 8
+#define MVPP2_PORT_FIFO_CFG_0_TX_FIFO_LOW_WM_MASK \
+ (0x000000ff << MVPP2_PORT_FIFO_CFG_0_TX_FIFO_LOW_WM_OFFS)
+
+/* Port Fifo Configuration 1 */
+#define MVPP2_PORT_FIFO_CFG_1_REG (0x001c)
+#define MVPP2_PORT_FIFO_CFG_1_RX_FIFO_MAX_TH_OFFS 0
+#define MVPP2_PORT_FIFO_CFG_1_RX_FIFO_MAX_TH_MASK \
+ (0x0000003f << MVPP2_PORT_FIFO_CFG_1_RX_FIFO_MAX_TH_OFFS)
+
+#define MVPP2_PORT_FIFO_CFG_1_TX_FIFO_MIN_TH_OFFS 6
+#define MVPP2_PORT_FIFO_CFG_1_TX_FIFO_MIN_TH_MASK \
+ (0x000000ff << MVPP2_PORT_FIFO_CFG_1_TX_FIFO_MIN_TH_OFFS)
+
+#define MVPP2_PORT_FIFO_CFG_1_PORT_EN_FIX_EN_OFFS 15
+#define MVPP2_PORT_FIFO_CFG_1_PORT_EN_FIX_EN_MASK \
+ (0x00000001 << MVPP2_PORT_FIFO_CFG_1_PORT_EN_FIX_EN_OFFS)
+
+/* Port Serdes Configuration0 */
+#define MVPP2_PORT_SERDES_CFG0_REG (0x0028)
+#define MVPP2_PORT_SERDES_CFG0_SERDESRESET_OFFS 0
+#define MVPP2_PORT_SERDES_CFG0_SERDESRESET_MASK \
+ (0x00000001 << MVPP2_PORT_SERDES_CFG0_SERDESRESET_OFFS)
+
+#define MVPP2_PORT_SERDES_CFG0_PU_TX_OFFS 1
+#define MVPP2_PORT_SERDES_CFG0_PU_TX_MASK \
+ (0x00000001 << MVPP2_PORT_SERDES_CFG0_PU_TX_OFFS)
+
+#define MVPP2_PORT_SERDES_CFG0_PU_RX_OFFS 2
+#define MVPP2_PORT_SERDES_CFG0_PU_RX_MASK \
+ (0x00000001 << MVPP2_PORT_SERDES_CFG0_PU_RX_OFFS)
+
+#define MVPP2_PORT_SERDES_CFG0_PU_PLL_OFFS 3
+#define MVPP2_PORT_SERDES_CFG0_PU_PLL_MASK \
+ (0x00000001 << MVPP2_PORT_SERDES_CFG0_PU_PLL_OFFS)
+
+#define MVPP2_PORT_SERDES_CFG0_PU_IVREF_OFFS 4
+#define MVPP2_PORT_SERDES_CFG0_PU_IVREF_MASK \
+ (0x00000001 << MVPP2_PORT_SERDES_CFG0_PU_IVREF_OFFS)
+
+#define MVPP2_PORT_SERDES_CFG0_TESTEN_OFFS 5
+#define MVPP2_PORT_SERDES_CFG0_TESTEN_MASK \
+ (0x00000001 << MVPP2_PORT_SERDES_CFG0_TESTEN_OFFS)
+
+#define MVPP2_PORT_SERDES_CFG0_DPHER_EN_OFFS 6
+#define MVPP2_PORT_SERDES_CFG0_DPHER_EN_MASK \
+ (0x00000001 << MVPP2_PORT_SERDES_CFG0_DPHER_EN_OFFS)
+
+#define MVPP2_PORT_SERDES_CFG0_RUDI_INVALID_ENABLE_OFFS 7
+#define MVPP2_PORT_SERDES_CFG0_RUDI_INVALID_ENABLE_MASK \
+ (0x00000001 << MVPP2_PORT_SERDES_CFG0_RUDI_INVALID_ENABLE_OFFS)
+
+#define MVPP2_PORT_SERDES_CFG0_ACK_OVERRIDE_ENABLE_OFFS 8
+#define MVPP2_PORT_SERDES_CFG0_ACK_OVERRIDE_ENABLE_MASK \
+ (0x00000001 << MVPP2_PORT_SERDES_CFG0_ACK_OVERRIDE_ENABLE_OFFS)
+
+#define MVPP2_PORT_SERDES_CFG0_CONFIG_WORD_ENABLE_OFFS 9
+#define MVPP2_PORT_SERDES_CFG0_CONFIG_WORD_ENABLE_MASK \
+ (0x00000001 << MVPP2_PORT_SERDES_CFG0_CONFIG_WORD_ENABLE_OFFS)
+
+#define MVPP2_PORT_SERDES_CFG0_SYNC_FAIL_INT_ENABLE_OFFS 10
+#define MVPP2_PORT_SERDES_CFG0_SYNC_FAIL_INT_ENABLE_MASK \
+ (0x00000001 << MVPP2_PORT_SERDES_CFG0_SYNC_FAIL_INT_ENABLE_OFFS)
+
+#define MVPP2_PORT_SERDES_CFG0_MASTER_MODE_ENABLE_OFFS 11
+#define MVPP2_PORT_SERDES_CFG0_MASTER_MODE_ENABLE_MASK \
+ (0x00000001 << MVPP2_PORT_SERDES_CFG0_MASTER_MODE_ENABLE_OFFS)
+
+#define MVPP2_PORT_SERDES_CFG0_TERM75_TX_OFFS 12
+#define MVPP2_PORT_SERDES_CFG0_TERM75_TX_MASK \
+ (0x00000001 << MVPP2_PORT_SERDES_CFG0_TERM75_TX_OFFS)
+
+#define MVPP2_PORT_SERDES_CFG0_OUTAMP_OFFS 13
+#define MVPP2_PORT_SERDES_CFG0_OUTAMP_MASK \
+ (0x00000001 << MVPP2_PORT_SERDES_CFG0_OUTAMP_OFFS)
+
+#define MVPP2_PORT_SERDES_CFG0_BTS712_FIX_EN_OFFS 14
+#define MVPP2_PORT_SERDES_CFG0_BTS712_FIX_EN_MASK \
+ (0x00000001 << MVPP2_PORT_SERDES_CFG0_BTS712_FIX_EN_OFFS)
+
+#define MVPP2_PORT_SERDES_CFG0_BTS156_FIX_EN_OFFS 15
+#define MVPP2_PORT_SERDES_CFG0_BTS156_FIX_EN_MASK \
+ (0x00000001 << MVPP2_PORT_SERDES_CFG0_BTS156_FIX_EN_OFFS)
+
+/* Port Serdes Configuration1 */
+#define MVPP2_PORT_SERDES_CFG1_REG (0x002c)
+#define MVPP2_PORT_SERDES_CFG1_SMII_RX_10MB_CLK_EDGE_SEL_OFFS 0
+#define MVPP2_PORT_SERDES_CFG1_SMII_RX_10MB_CLK_EDGE_SEL_MASK \
+ (0x00000001 << MVPP2_GMAC_PORT_SERDES_CFG1_SMII_RX_10MB_CLK_EDGE_SEL_OFFS)
+
+#define MVPP2_GMAC_PORT_SERDES_CFG1_SMII_TX_10MB_CLK_EDGE_SEL_OFFS 1
+#define MVPP2_GMAC_PORT_SERDES_CFG1_SMII_TX_10MB_CLK_EDGE_SEL_MASK \
+ (0x00000001 << MVPP2_GMAC_PORT_SERDES_CFG1_SMII_TX_10MB_CLK_EDGE_SEL_OFFS)
+
+#define MVPP2_GMAC_PORT_SERDES_CFG1_MEN_OFFS 2
+#define MVPP2_GMAC_PORT_SERDES_CFG1_MEN_MASK \
+ (0x00000003 << MVPP2_GMAC_PORT_SERDES_CFG1_MEN_OFFS)
+
+#define MVPP2_GMAC_PORT_SERDES_CFG1_VCMS_OFFS 4
+#define MVPP2_GMAC_PORT_SERDES_CFG1_VCMS_MASK \
+ (0x00000001 << MVPP2_GMAC_PORT_SERDES_CFG1_VCMS_OFFS)
+
+#define MVPP2_GMAC_PORT_SERDES_CFG1_100FX_PCS_USE_SIGDET_OFFS 5
+#define MVPP2_GMAC_PORT_SERDES_CFG1_100FX_PCS_USE_SIGDET_MASK \
+ (0x00000001 << MVPP2_GMAC_PORT_SERDES_CFG1_100FX_PCS_USE_SIGDET_OFFS)
+
+#define MVPP2_GMAC_PORT_SERDES_CFG1_EN_CRS_MASK_TX_OFFS 6
+#define MVPP2_GMAC_PORT_SERDES_CFG1_EN_CRS_MASK_TX_MASK \
+ (0x00000001 << MVPP2_GMAC_PORT_SERDES_CFG1_EN_CRS_MASK_TX_OFFS)
+
+#define MVPP2_GMAC_PORT_SERDES_CFG1_100FX_ENABLE_OFFS 7
+#define MVPP2_GMAC_PORT_SERDES_CFG1_100FX_ENABLE_MASK \
+ (0x00000001 << MVPP2_GMAC_PORT_SERDES_CFG1_100FX_ENABLE_OFFS)
+
+#define MVPP2_GMAC_PORT_SERDES_CFG1_100FX_PCS_PHY_ADDRESS_OFFS 8
+#define MVPP2_GMAC_PORT_SERDES_CFG1_100FX_PCS_PHY_ADDRESS_MASK \
+ (0x0000001f << MVPP2_GMAC_PORT_SERDES_CFG1_100FX_PCS_PHY_ADDRESS_OFFS)
+
+#define MVPP2_GMAC_PORT_SERDES_CFG1_100FX_PCS_SIGDET_POLARITY_OFFS 13
+#define MVPP2_GMAC_PORT_SERDES_CFG1_100FX_PCS_SIGDET_POLARITY_MASK \
+ (0x00000001 << MVPP2_GMAC_PORT_SERDES_CFG1_100FX_PCS_SIGDET_POLARITY_OFFS)
+
+#define MVPP2_GMAC_PORT_SERDES_CFG1_100FX_PCS_INTERRUPT_POLARITY_OFFS 14
+#define MVPP2_GMAC_PORT_SERDES_CFG1_100FX_PCS_INTERRUPT_POLARITY_MASK \
+ (0x00000001 << MVPP2_GMAC_PORT_SERDES_CFG1_100FX_PCS_INTERRUPT_POLARITY_OFFS)
+
+#define MVPP2_GMAC_PORT_SERDES_CFG1_100FX_PCS_SERDES_POLARITY_OFFS 15
+#define MVPP2_GMAC_PORT_SERDES_CFG1_100FX_PCS_SERDES_POLARITY_MASK \
+ (0x00000001 << MVPP2_GMAC_PORT_SERDES_CFG1_100FX_PCS_SERDES_POLARITY_OFFS)
+
+/* Port Serdes Configuration2 */
+#define MVPP2_PORT_SERDES_CFG2_REG (0x0030)
+#define MVPP2_PORT_SERDES_CFG2_AN_ADV_CONFIGURATION_OFFS 0
+#define MVPP2_PORT_SERDES_CFG2_AN_ADV_CONFIGURATION_MASK \
+ (0x0000ffff << MVPP2_PORT_SERDES_CFG2_AN_ADV_CONFIGURATION_OFFS)
+
+/* Port Serdes Configuration3 */
+#define MVPP2_PORT_SERDES_CFG3_REG (0x0034)
+#define MVPP2_PORT_SERDES_CFG3_ABILITY_MATCH_STATUS_OFFS 0
+#define MVPP2_PORT_SERDES_CFG3_ABILITY_MATCH_STATUS_MASK \
+ (0x0000ffff << MVPP2_PORT_SERDES_CFG3_ABILITY_MATCH_STATUS_OFFS)
+
+/* Port Prbs Status */
+#define MVPP2_PORT_PRBS_STATUS_REG (0x0038)
+#define MVPP2_PORT_PRBS_STATUS_PRBSCHECK_LOCKED_OFFS 0
+#define MVPP2_PORT_PRBS_STATUS_PRBSCHECK_LOCKED_MASK \
+ (0x00000001 << MVPP2_PORT_PRBS_STATUS_PRBSCHECK_LOCKED_OFFS)
+
+#define MVPP2_PORT_PRBS_STATUS_PRBSCHECKRDY_OFFS 1
+#define MVPP2_PORT_PRBS_STATUS_PRBSCHECKRDY_MASK \
+ (0x00000001 << MVPP2_PORT_PRBS_STATUS_PRBSCHECKRDY_OFFS)
+
+/* Port Prbs Error Counter */
+#define MVPP2_PORT_PRBS_ERR_CNTR_REG (0x003c)
+#define MVPP2_PORT_PRBS_ERR_CNTR_PRBSBITERRCNT_OFFS 0
+#define MVPP2_PORT_PRBS_ERR_CNTR_PRBSBITERRCNT_MASK \
+ (0x0000ffff << MVPP2_PORT_PRBS_ERR_CNTR_PRBSBITERRCNT_OFFS)
+
+/* Port Status1 */
+#define MVPP2_PORT_STATUS1_REG (0x0040)
+#define MVPP2_PORT_STATUS1_MEDIAACTIVE_OFFS 0
+#define MVPP2_PORT_STATUS1_MEDIAACTIVE_MASK \
+ (0x00000001 << MVPP2_PORT_STATUS1_MEDIAACTIVE_OFFS)
+
+/* Port Mib Counters Control */
+#define MVPP2_PORT_MIB_CNTRS_CTRL_REG (0x0044)
+#define MVPP2_PORT_MIB_CNTRS_CTRL_MIB_COPY_TRIGGER_OFFS 0
+#define MVPP2_PORT_MIB_CNTRS_CTRL_MIB_COPY_TRIGGER_MASK \
+ (0x00000001 << MVPP2_PORT_MIB_CNTRS_CTRL_MIB_COPY_TRIGGER_OFFS)
+
+#define MVPP2_PORT_MIB_CNTRS_CTRL_MIB_CLEAR_ON_READ__OFFS 1
+#define MVPP2_PORT_MIB_CNTRS_CTRL_MIB_CLEAR_ON_READ__MASK \
+ (0x00000001 << MVPP2_PORT_MIB_CNTRS_CTRL_MIB_CLEAR_ON_READ__OFFS)
+
+#define MVPP2_PORT_MIB_CNTRS_CTRL_RX_HISTOGRAM_EN_OFFS 2
+#define MVPP2_PORT_MIB_CNTRS_CTRL_RX_HISTOGRAM_EN_MASK \
+ (0x00000001 << MVPP2_PORT_MIB_CNTRS_CTRL_RX_HISTOGRAM_EN_OFFS)
+
+#define MVPP2_PORT_MIB_CNTRS_CTRL_TX_HISTOGRAM_EN_OFFS 3
+#define MVPP2_PORT_MIB_CNTRS_CTRL_TX_HISTOGRAM_EN_MASK \
+ (0x00000001 << MVPP2_PORT_MIB_CNTRS_CTRL_TX_HISTOGRAM_EN_OFFS)
+
+#define MVPP2_PORT_MIB_CNTRS_CTRL_MFA1_BTT940_FIX_ENABLE__OFFS 4
+#define MVPP2_PORT_MIB_CNTRS_CTRL_MFA1_BTT940_FIX_ENABLE__MASK \
+ (0x00000001 << MVPP2_PORT_MIB_CNTRS_CTRL_MFA1_BTT940_FIX_ENABLE__OFFS)
+
+#define MVPP2_PORT_MIB_CNTRS_CTRL_XCAT_BTS_340_EN__OFFS 5
+#define MVPP2_PORT_MIB_CNTRS_CTRL_XCAT_BTS_340_EN__MASK \
+ (0x00000001 << MVPP2_PORT_MIB_CNTRS_CTRL_XCAT_BTS_340_EN__OFFS)
+
+#define MVPP2_PORT_MIB_CNTRS_CTRL_MIB_4_COUNT_HIST_OFFS 6
+#define MVPP2_PORT_MIB_CNTRS_CTRL_MIB_4_COUNT_HIST_MASK \
+ (0x00000001 << MVPP2_PORT_MIB_CNTRS_CTRL_MIB_4_COUNT_HIST_OFFS)
+
+#define MVPP2_PORT_MIB_CNTRS_CTRL_MIB_4_LIMIT_1518_1522_OFFS 7
+#define MVPP2_PORT_MIB_CNTRS_CTRL_MIB_4_LIMIT_1518_1522_MASK \
+ (0x00000001 << MVPP2_PORT_MIB_CNTRS_CTRL_MIB_4_LIMIT_1518_1522_OFFS)
+
+/* Port Mac Control3 */
+#define MVPP2_PORT_CTRL3_REG (0x0048)
+#define MVPP2_PORT_CTRL3_BUF_SIZE_OFFS 0
+#define MVPP2_PORT_CTRL3_BUF_SIZE_MASK \
+ (0x0000003f << MVPP2_PORT_CTRL3_BUF_SIZE_OFFS)
+
+#define MVPP2_PORT_CTRL3_IPG_DATA_OFFS 6
+#define MVPP2_PORT_CTRL3_IPG_DATA_MASK \
+ (0x000001ff << MVPP2_PORT_CTRL3_IPG_DATA_OFFS)
+
+#define MVPP2_PORT_CTRL3_LLFC_GLOBAL_FC_ENABLE_OFFS 15
+#define MVPP2_PORT_CTRL3_LLFC_GLOBAL_FC_ENABLE_MASK \
+ (0x00000001 << MVPP2_PORT_CTRL3_LLFC_GLOBAL_FC_ENABLE_OFFS)
+#define MVPP2_CAUSE_TXQ_SENT_DESC_ALL_MASK 0xff
+
+/* Port Mac Control4 */
+#define MVPP2_PORT_CTRL4_REG (0x0090)
+#define MVPP2_PORT_CTRL4_EXT_PIN_GMII_SEL_OFFS 0
+#define MVPP2_PORT_CTRL4_EXT_PIN_GMII_SEL_MASK \
+ (0x00000001 << MVPP2_PORT_CTRL4_EXT_PIN_GMII_SEL_OFFS)
+
+#define MVPP2_PORT_CTRL4_PREAMBLE_FIX_OFFS 1
+#define MVPP2_PORT_CTRL4_PREAMBLE_FIX_MASK \
+ (0x00000001 << MVPP2_PORT_CTRL4_PREAMBLE_FIX_OFFS)
+
+#define MVPP2_PORT_CTRL4_SQ_DETECT_FIX_EN_OFFS 2
+#define MVPP2_PORT_CTRL4_SQ_DETECT_FIX_EN_MASK \
+ (0x00000001 << MVPP2_PORT_CTRL4_SQ_DETECT_FIX_EN_OFFS)
+
+#define MVPP2_PORT_CTRL4_FC_EN_RX_OFFS 3
+#define MVPP2_PORT_CTRL4_FC_EN_RX_MASK \
+ (0x00000001 << MVPP2_PORT_CTRL4_FC_EN_RX_OFFS)
+
+#define MVPP2_PORT_CTRL4_FC_EN_TX_OFFS 4
+#define MVPP2_PORT_CTRL4_FC_EN_TX_MASK \
+ (0x00000001 << MVPP2_PORT_CTRL4_FC_EN_TX_OFFS)
+
+#define MVPP2_PORT_CTRL4_DP_CLK_SEL_OFFS 5
+#define MVPP2_PORT_CTRL4_DP_CLK_SEL_MASK \
+ (0x00000001 << MVPP2_PORT_CTRL4_DP_CLK_SEL_OFFS)
+
+#define MVPP2_PORT_CTRL4_SYNC_BYPASS_OFFS 6
+#define MVPP2_PORT_CTRL4_SYNC_BYPASS_MASK \
+ (0x00000001 << MVPP2_PORT_CTRL4_SYNC_BYPASS_OFFS)
+
+#define MVPP2_PORT_CTRL4_QSGMII_BYPASS_ACTIVE_OFFS 7
+#define MVPP2_PORT_CTRL4_QSGMII_BYPASS_ACTIVE_MASK \
+ (0x00000001 << MVPP2_PORT_CTRL4_QSGMII_BYPASS_ACTIVE_OFFS)
+
+#define MVPP2_PORT_CTRL4_COUNT_EXTERNAL_FC_EN_OFFS 8
+#define MVPP2_PORT_CTRL4_COUNT_EXTERNAL_FC_EN_MASK \
+ (0x00000001 << MVPP2_PORT_CTRL4_COUNT_EXTERNAL_FC_EN_OFFS)
+
+#define MVPP2_PORT_CTRL4_MARVELL_HEADER_EN_OFFS 9
+#define MVPP2_PORT_CTRL4_MARVELL_HEADER_EN_MASK \
+ (0x00000001 << MVPP2_PORT_CTRL4_MARVELL_HEADER_EN_OFFS)
+
+#define MVPP2_PORT_CTRL4_LEDS_NUMBER_OFFS 10
+#define MVPP2_PORT_CTRL4_LEDS_NUMBER_MASK \
+ (0x0000003f << MVPP2_PORT_CTRL4_LEDS_NUMBER_OFFS)
+
+/* XPCS registers */
+
+/* Global Configuration 0 */
+#define MVPP22_XPCS_GLOBAL_CFG_0_REG 0x0
+#define MVPP22_XPCS_PCSRESET BIT(0)
+#define MVPP22_XPCS_PCSMODE_OFFS 3
+#define MVPP22_XPCS_PCSMODE_MASK (0x3 << MVPP22_XPCS_PCSMODE_OFFS)
+#define MVPP22_XPCS_LANEACTIVE_OFFS 5
+#define MVPP22_XPCS_LANEACTIVE_MASK (0x3 << MVPP22_XPCS_LANEACTIVE_OFFS)
+
+/* MPCS registers */
+
+#define MVPP22_MPCS40G_COMMON_CONTROL 0x14
+#define MVPP22_MPCS_FORWARD_ERROR_CORRECTION_MASK BIT(10)
+
+#define MVPP22_MPCS_CLOCK_RESET 0x14c
+#define MVPP22_MPCS_TX_SD_CLK_RESET_MASK BIT(0)
+#define MVPP22_MPCS_RX_SD_CLK_RESET_MASK BIT(1)
+#define MVPP22_MPCS_MAC_CLK_RESET_MASK BIT(2)
+#define MVPP22_MPCS_CLK_DIVISION_RATIO_OFFS 4
+#define MVPP22_MPCS_CLK_DIVISION_RATIO_MASK (0x7 << MVPP22_MPCS_CLK_DIVISION_RATIO_OFFS)
+#define MVPP22_MPCS_CLK_DIVISION_RATIO_DEFAULT (0x1 << MVPP22_MPCS_CLK_DIVISION_RATIO_OFFS)
+#define MVPP22_MPCS_CLK_DIV_PHASE_SET_MASK BIT(11)
+
+/* Descriptor ring Macros */
+#define MVPP2_QUEUE_NEXT_DESC(q, index) (((index) < (q)->LastDesc) ? ((index) + 1) : 0)
+
+/* Various constants */
+
+/* Coalescing */
+#define MVPP2_TXDONE_COAL_PKTS_THRESH 64
+#define MVPP2_TXDONE_HRTIMER_PERIOD_NS 1000000UL
+#define MVPP2_TXDONE_COAL_USEC 1000
+#define MVPP2_RX_COAL_PKTS 32
+#define MVPP2_RX_COAL_USEC 64
+
+/*
+ * The two bytes Marvell header. Either contains a special value used
+ * by Marvell switches when a specific hardware mode is enabled (not
+ * supported by this driver) or is filled automatically by zeroes on
+ * the RX side. Those two bytes being at the front of the Ethernet
+ * header, they allow to have the IP header aligned on a 4 bytes
+ * boundary automatically: the hardware skips those two bytes on its
+ * own.
+ */
+#define MVPP2_MH_SIZE 2
+#define MVPP2_ETH_TYPE_LEN 2
+#define MVPP2_PPPOE_HDR_SIZE 8
+#define MVPP2_VLAN_TAG_LEN 4
+
+/* Lbtd 802.3 type */
+#define MVPP2_IP_LBDT_TYPE 0xfffa
+
+#define MVPP2_CPU_D_CACHE_LINE_SIZE 32
+#define MVPP2_TX_CSUM_MAX_SIZE 9800
+
+/* Timeout constants */
+#define MVPP2_TX_DISABLE_TIMEOUT_MSEC 1000
+#define MVPP2_TX_PENDING_TIMEOUT_MSEC 1000
+
+#define MVPP2_TX_MTU_MAX 0x7ffff
+
+/* Maximum number of T-CONTs of PON port */
+#define MVPP2_MAX_TCONT 16
+
+/* Maximum number of supported ports */
+#define MVPP2_MAX_PORTS 4
+
+/* Maximum number of TXQs used by single port */
+#define MVPP2_MAX_TXQ 8
+
+/* Maximum number of RXQs used by single port */
+#define MVPP2_MAX_RXQ 8
+
+/* Dfault number of RXQs in use */
+#define MVPP2_DEFAULT_RXQ 4
+
+/* Total number of RXQs available to all ports */
+#define MVPP2_RXQ_TOTAL_NUM (MVPP2_MAX_PORTS * MVPP2_MAX_RXQ)
+
+/* Max number of Rx descriptors */
+#define MVPP2_MAX_RXD 64
+
+/* Max number of Tx descriptors */
+#define MVPP2_MAX_TXD 32
+
+/* Amount of Tx descriptors that can be reserved at once by CPU */
+#define MVPP2_CPU_DESC_CHUNK 64
+
+/* Max number of Tx descriptors in each aggregated queue */
+#define MVPP2_AGGR_TXQ_SIZE 256
+
+/* Descriptor aligned size */
+#define MVPP2_DESC_ALIGNED_SIZE 32
+
+/* Descriptor alignment mask */
+#define MVPP2_TX_DESC_ALIGN (MVPP2_DESC_ALIGNED_SIZE - 1)
+
+/* RX FIFO constants */
+#define MVPP2_RX_FIFO_PORT_DATA_SIZE_32KB 0x8000
+#define MVPP2_RX_FIFO_PORT_DATA_SIZE_8KB 0x2000
+#define MVPP2_RX_FIFO_PORT_DATA_SIZE_4KB 0x1000
+#define MVPP2_RX_FIFO_PORT_ATTR_SIZE_32KB 0x200
+#define MVPP2_RX_FIFO_PORT_ATTR_SIZE_8KB 0x80
+#define MVPP2_RX_FIFO_PORT_ATTR_SIZE_4KB 0x40
+#define MVPP2_RX_FIFO_PORT_MIN_PKT 0x80
+
+/* TX FIFO constants */
+#define MVPP22_TX_FIFO_DATA_SIZE_10KB 0xa
+#define MVPP22_TX_FIFO_DATA_SIZE_3KB 0x3
+#define MVPP2_TX_FIFO_THRESHOLD_MIN 256
+#define MVPP2_TX_FIFO_THRESHOLD_10KB \
+ (MVPP22_TX_FIFO_DATA_SIZE_10KB * 1024 - MVPP2_TX_FIFO_THRESHOLD_MIN)
+#define MVPP2_TX_FIFO_THRESHOLD_3KB \
+ (MVPP22_TX_FIFO_DATA_SIZE_3KB * 1024 - MVPP2_TX_FIFO_THRESHOLD_MIN)
+
+#define MVPP2_BIT_TO_BYTE(bit) ((bit) / 8)
+
+/* IPv6 max L3 address size */
+#define MVPP2_MAX_L3_ADDR_SIZE 16
+
+/* Port flags */
+#define MVPP2_F_LOOPBACK BIT(0)
+
+/* SD1 Control1 */
+#define SD1_CONTROL_1_REG (0x148)
+
+#define SD1_CONTROL_XAUI_EN_OFFSET 28
+#define SD1_CONTROL_XAUI_EN_MASK (0x1 << SD1_CONTROL_XAUI_EN_OFFSET)
+
+#define SD1_CONTROL_RXAUI0_L23_EN_OFFSET 27
+#define SD1_CONTROL_RXAUI0_L23_EN_MASK (0x1 << SD1_CONTROL_RXAUI0_L23_EN_OFFSET)
+
+#define SD1_CONTROL_RXAUI1_L45_EN_OFFSET 26
+#define SD1_CONTROL_RXAUI1_L45_EN_MASK (0x1 << SD1_CONTROL_RXAUI1_L45_EN_OFFSET)
+
+/* System Soft Reset 1 */
+#define MV_GOP_SOFT_RESET_1_REG (0x108)
+
+#define NETC_GOP_SOFT_RESET_OFFSET 6
+#define NETC_GOP_SOFT_RESET_MASK (0x1 << NETC_GOP_SOFT_RESET_OFFSET)
+
+/* Ports Control 0 */
+#define MV_NETCOMP_PORTS_CONTROL_0 (0x110)
+
+#define NETC_CLK_DIV_PHASE_OFFSET 31
+#define NETC_CLK_DIV_PHASE_MASK (0x1 << NETC_CLK_DIV_PHASE_OFFSET)
+
+#define NETC_GIG_RX_DATA_SAMPLE_OFFSET 29
+#define NETC_GIG_RX_DATA_SAMPLE_MASK (0x1 << NETC_GIG_RX_DATA_SAMPLE_OFFSET)
+
+#define NETC_BUS_WIDTH_SELECT_OFFSET 1
+#define NETC_BUS_WIDTH_SELECT_MASK (0x1 << NETC_BUS_WIDTH_SELECT_OFFSET)
+
+#define NETC_GOP_ENABLE_OFFSET 0
+#define NETC_GOP_ENABLE_MASK (0x1 << NETC_GOP_ENABLE_OFFSET)
+
+/* Ports Control 1 */
+#define MV_NETCOMP_PORTS_CONTROL_1 (0x114)
+
+#define NETC_PORT_GIG_RF_RESET_OFFSET(port) (28 + port)
+#define NETC_PORT_GIG_RF_RESET_MASK(port) (0x1 << NETC_PORT_GIG_RF_RESET_OFFSET(port))
+
+#define NETC_PORTS_ACTIVE_OFFSET(port) (0 + port)
+#define NETC_PORTS_ACTIVE_MASK(port) (0x1 << NETC_PORTS_ACTIVE_OFFSET(port))
+
+/* Ports Status */
+#define MV_NETCOMP_PORTS_STATUS (0x11C)
+#define NETC_PORTS_STATUS_OFFSET(port) (0 + port)
+#define NETC_PORTS_STATUS_MASK(port) (0x1 << NETC_PORTS_STATUS_OFFSET(port))
+
+/* Networking Complex Control 0 */
+#define MV_NETCOMP_CONTROL_0 (0x120)
+
+#define NETC_GBE_PORT1_MII_MODE_OFFSET 2
+#define NETC_GBE_PORT1_MII_MODE_MASK (0x1 << NETC_GBE_PORT1_MII_MODE_OFFSET)
+
+#define NETC_GBE_PORT1_SGMII_MODE_OFFSET 1
+#define NETC_GBE_PORT1_SGMII_MODE_MASK (0x1 << NETC_GBE_PORT1_SGMII_MODE_OFFSET)
+
+#define NETC_GBE_PORT0_SGMII_MODE_OFFSET 0
+#define NETC_GBE_PORT0_SGMII_MODE_MASK (0x1 << NETC_GBE_PORT0_SGMII_MODE_OFFSET)
+
+/* Port Mac Control0 */
+#define MV_XLG_PORT_MAC_CTRL0_REG ( 0x0000)
+#define MV_XLG_MAC_CTRL0_PORTEN_OFFS 0
+#define MV_XLG_MAC_CTRL0_PORTEN_MASK \
+ (0x00000001 << MV_XLG_MAC_CTRL0_PORTEN_OFFS)
+
+#define MV_XLG_MAC_CTRL0_MACRESETN_OFFS 1
+#define MV_XLG_MAC_CTRL0_MACRESETN_MASK \
+ (0x00000001 << MV_XLG_MAC_CTRL0_MACRESETN_OFFS)
+
+#define MV_XLG_MAC_CTRL0_FORCELINKDOWN_OFFS 2
+#define MV_XLG_MAC_CTRL0_FORCELINKDOWN_MASK \
+ (0x00000001 << MV_XLG_MAC_CTRL0_FORCELINKDOWN_OFFS)
+
+#define MV_XLG_MAC_CTRL0_FORCELINKPASS_OFFS 3
+#define MV_XLG_MAC_CTRL0_FORCELINKPASS_MASK \
+ (0x00000001 << MV_XLG_MAC_CTRL0_FORCELINKPASS_OFFS)
+
+#define MV_XLG_MAC_CTRL0_TXIPGMODE_OFFS 5
+#define MV_XLG_MAC_CTRL0_TXIPGMODE_MASK \
+ (0x00000003 << MV_XLG_MAC_CTRL0_TXIPGMODE_OFFS)
+
+#define MV_XLG_MAC_CTRL0_RXFCEN_OFFS 7
+#define MV_XLG_MAC_CTRL0_RXFCEN_MASK \
+ (0x00000001 << MV_XLG_MAC_CTRL0_RXFCEN_OFFS)
+
+#define MV_XLG_MAC_CTRL0_TXFCEN_OFFS 8
+#define MV_XLG_MAC_CTRL0_TXFCEN_MASK \
+ (0x00000001 << MV_XLG_MAC_CTRL0_TXFCEN_OFFS)
+
+#define MV_XLG_MAC_CTRL0_RXCRCCHECKEN_OFFS 9
+#define MV_XLG_MAC_CTRL0_RXCRCCHECKEN_MASK \
+ (0x00000001 << MV_XLG_MAC_CTRL0_RXCRCCHECKEN_OFFS)
+
+#define MV_XLG_MAC_CTRL0_PERIODICXONEN_OFFS 10
+#define MV_XLG_MAC_CTRL0_PERIODICXONEN_MASK \
+ (0x00000001 << MV_XLG_MAC_CTRL0_PERIODICXONEN_OFFS)
+
+#define MV_XLG_MAC_CTRL0_RXCRCSTRIPEN_OFFS 11
+#define MV_XLG_MAC_CTRL0_RXCRCSTRIPEN_MASK \
+ (0x00000001 << MV_XLG_MAC_CTRL0_RXCRCSTRIPEN_OFFS)
+
+#define MV_XLG_MAC_CTRL0_PADDINGDIS_OFFS 13
+#define MV_XLG_MAC_CTRL0_PADDINGDIS_MASK \
+ (0x00000001 << MV_XLG_MAC_CTRL0_PADDINGDIS_OFFS)
+
+#define MV_XLG_MAC_CTRL0_MIBCNTDIS_OFFS 14
+#define MV_XLG_MAC_CTRL0_MIBCNTDIS_MASK \
+ (0x00000001 << MV_XLG_MAC_CTRL0_MIBCNTDIS_OFFS)
+
+#define MV_XLG_MAC_CTRL0_PFC_CASCADE_PORT_ENABLE_OFFS 15
+#define MV_XLG_MAC_CTRL0_PFC_CASCADE_PORT_ENABLE_MASK \
+ (0x00000001 << MV_XLG_MAC_CTRL0_PFC_CASCADE_PORT_ENABLE_OFFS)
+
+/* Port Mac Control1 */
+#define MV_XLG_PORT_MAC_CTRL1_REG (0x0004)
+#define MV_XLG_MAC_CTRL1_FRAMESIZELIMIT_OFFS 0
+#define MV_XLG_MAC_CTRL1_FRAMESIZELIMIT_MASK \
+ (0x00001fff << MV_XLG_MAC_CTRL1_FRAMESIZELIMIT_OFFS)
+#define MV_XLG_MAC_CTRL1_FRAMESIZELIMIT_DEFAULT 0x1400
+
+#define MV_XLG_MAC_CTRL1_MACLOOPBACKEN_OFFS 13
+#define MV_XLG_MAC_CTRL1_MACLOOPBACKEN_MASK \
+ (0x00000001 << MV_XLG_MAC_CTRL1_MACLOOPBACKEN_OFFS)
+
+#define MV_XLG_MAC_CTRL1_XGMIILOOPBACKEN_OFFS 14
+#define MV_XLG_MAC_CTRL1_XGMIILOOPBACKEN_MASK \
+ (0x00000001 << MV_XLG_MAC_CTRL1_XGMIILOOPBACKEN_OFFS)
+
+#define MV_XLG_MAC_CTRL1_LOOPBACKCLOCKSELECT_OFFS 15
+#define MV_XLG_MAC_CTRL1_LOOPBACKCLOCKSELECT_MASK \
+ (0x00000001 << MV_XLG_MAC_CTRL1_LOOPBACKCLOCKSELECT_OFFS)
+
+/* Port Mac Control2 */
+#define MV_XLG_PORT_MAC_CTRL2_REG (0x0008)
+#define MV_XLG_MAC_CTRL2_SALOW_7_0_OFFS 0
+#define MV_XLG_MAC_CTRL2_SALOW_7_0_MASK \
+ (0x000000ff << MV_XLG_MAC_CTRL2_SALOW_7_0_OFFS)
+
+#define MV_XLG_MAC_CTRL2_UNIDIRECTIONALEN_OFFS 8
+#define MV_XLG_MAC_CTRL2_UNIDIRECTIONALEN_MASK \
+ (0x00000001 << MV_XLG_MAC_CTRL2_UNIDIRECTIONALEN_OFFS)
+
+#define MV_XLG_MAC_CTRL2_FIXEDIPGBASE_OFFS 9
+#define MV_XLG_MAC_CTRL2_FIXEDIPGBASE_MASK \
+ (0x00000001 << MV_XLG_MAC_CTRL2_FIXEDIPGBASE_OFFS)
+
+#define MV_XLG_MAC_CTRL2_PERIODICXOFFEN_OFFS 10
+#define MV_XLG_MAC_CTRL2_PERIODICXOFFEN_MASK \
+ (0x00000001 << MV_XLG_MAC_CTRL2_PERIODICXOFFEN_OFFS)
+
+#define MV_XLG_MAC_CTRL2_SIMPLEXMODEEN_OFFS 13
+#define MV_XLG_MAC_CTRL2_SIMPLEXMODEEN_MASK \
+ (0x00000001 << MV_XLG_MAC_CTRL2_SIMPLEXMODEEN_OFFS)
+
+#define MV_XLG_MAC_CTRL2_FC_MODE_OFFS 14
+#define MV_XLG_MAC_CTRL2_FC_MODE_MASK \
+ (0x00000003 << MV_XLG_MAC_CTRL2_FC_MODE_OFFS)
+
+/* Port Status */
+#define MV_XLG_MAC_PORT_STATUS_REG (0x000c)
+#define MV_XLG_MAC_PORT_STATUS_LINKSTATUS_OFFS 0
+#define MV_XLG_MAC_PORT_STATUS_LINKSTATUS_MASK \
+ (0x00000001 << MV_XLG_MAC_PORT_STATUS_LINKSTATUS_OFFS)
+
+#define MV_XLG_MAC_PORT_STATUS_REMOTEFAULT_OFFS 1
+#define MV_XLG_MAC_PORT_STATUS_REMOTEFAULT_MASK \
+ (0x00000001 << MV_XLG_MAC_PORT_STATUS_REMOTEFAULT_OFFS)
+
+#define MV_XLG_MAC_PORT_STATUS_LOCALFAULT_OFFS 2
+#define MV_XLG_MAC_PORT_STATUS_LOCALFAULT_MASK \
+ (0x00000001 << MV_XLG_MAC_PORT_STATUS_LOCALFAULT_OFFS)
+
+#define MV_XLG_MAC_PORT_STATUS_LINKSTATUSCLEAN_OFFS 3
+#define MV_XLG_MAC_PORT_STATUS_LINKSTATUSCLEAN_MASK \
+ (0x00000001 << MV_XLG_MAC_PORT_STATUS_LINKSTATUSCLEAN_OFFS)
+
+#define MV_XLG_MAC_PORT_STATUS_LOCALFAULTCLEAN_OFFS 4
+#define MV_XLG_MAC_PORT_STATUS_LOCALFAULTCLEAN_MASK \
+ (0x00000001 << MV_XLG_MAC_PORT_STATUS_LOCALFAULTCLEAN_OFFS)
+
+#define MV_XLG_MAC_PORT_STATUS_REMOTEFAULTCLEAN_OFFS 5
+#define MV_XLG_MAC_PORT_STATUS_REMOTEFAULTCLEAN_MASK \
+ (0x00000001 << MV_XLG_MAC_PORT_STATUS_REMOTEFAULTCLEAN_OFFS)
+
+#define MV_XLG_MAC_PORT_STATUS_PORTRXPAUSE_OFFS 6
+#define MV_XLG_MAC_PORT_STATUS_PORTRXPAUSE_MASK \
+ (0x00000001 << MV_XLG_MAC_PORT_STATUS_PORTRXPAUSE_OFFS)
+
+#define MV_XLG_MAC_PORT_STATUS_PORTTXPAUSE_OFFS 7
+#define MV_XLG_MAC_PORT_STATUS_PORTTXPAUSE_MASK \
+ (0x00000001 << MV_XLG_MAC_PORT_STATUS_PORTTXPAUSE_OFFS)
+
+#define MV_XLG_MAC_PORT_STATUS_PFC_SYNC_FIFO_FULL_OFFS 8
+#define MV_XLG_MAC_PORT_STATUS_PFC_SYNC_FIFO_FULL_MASK \
+ (0x00000001 << MV_XLG_MAC_PORT_STATUS_PFC_SYNC_FIFO_FULL_OFFS)
+
+/* Port Fifos Thresholds Configuration */
+#define MV_XLG_PORT_FIFOS_THRS_CFG_REG (0x0010)
+#define MV_XLG_MAC_PORT_FIFOS_THRS_CFG_RXFULLTHR_OFFS 0
+#define MV_XLG_MAC_PORT_FIFOS_THRS_CFG_RXFULLTHR_MASK \
+ (0x0000001f << MV_XLG_MAC_PORT_FIFOS_THRS_CFG_RXFULLTHR_OFFS)
+
+#define MV_XLG_MAC_PORT_FIFOS_THRS_CFG_TXFIFOSIZE_OFFS 5
+#define MV_XLG_MAC_PORT_FIFOS_THRS_CFG_TXFIFOSIZE_MASK \
+ (0x0000003f << MV_XLG_MAC_PORT_FIFOS_THRS_CFG_TXFIFOSIZE_OFFS)
+
+#define MV_XLG_MAC_PORT_FIFOS_THRS_CFG_TXRDTHR_OFFS 11
+#define MV_XLG_MAC_PORT_FIFOS_THRS_CFG_TXRDTHR_MASK \
+ (0x0000001f << MV_XLG_MAC_PORT_FIFOS_THRS_CFG_TXRDTHR_OFFS)
+
+/* Port Mac Control3 */
+#define MV_XLG_PORT_MAC_CTRL3_REG (0x001c)
+#define MV_XLG_MAC_CTRL3_BUFSIZE_OFFS 0
+#define MV_XLG_MAC_CTRL3_BUFSIZE_MASK \
+ (0x0000003f << MV_XLG_MAC_CTRL3_BUFSIZE_OFFS)
+
+#define MV_XLG_MAC_CTRL3_XTRAIPG_OFFS 6
+#define MV_XLG_MAC_CTRL3_XTRAIPG_MASK \
+ (0x0000007f << MV_XLG_MAC_CTRL3_XTRAIPG_OFFS)
+
+#define MV_XLG_MAC_CTRL3_MACMODESELECT_OFFS 13
+#define MV_XLG_MAC_CTRL3_MACMODESELECT_MASK \
+ (0x00000007 << MV_XLG_MAC_CTRL3_MACMODESELECT_OFFS)
+#define MV_XLG_MAC_CTRL3_MACMODESELECT_GMAC \
+ (0x00000000 << MV_XLG_MAC_CTRL3_MACMODESELECT_OFFS)
+#define MV_XLG_MAC_CTRL3_MACMODESELECT_10G \
+ (0x00000001 << MV_XLG_MAC_CTRL3_MACMODESELECT_OFFS)
+
+/* Port Per Prio Flow Control Status */
+#define MV_XLG_PORT_PER_PRIO_FLOW_CTRL_STATUS_REG (0x0020)
+#define MV_XLG_MAC_PORT_PER_PRIO_FLOW_CTRL_STATUS_PRIONSTATUS_OFFS 0
+#define MV_XLG_MAC_PORT_PER_PRIO_FLOW_CTRL_STATUS_PRIONSTATUS_MASK \
+ (0x00000001 << MV_XLG_MAC_PORT_PER_PRIO_FLOW_CTRL_STATUS_PRIONSTATUS_OFFS)
+
+/* Debug Bus Status */
+#define MV_XLG_DEBUG_BUS_STATUS_REG (0x0024)
+#define MV_XLG_MAC_DEBUG_BUS_STATUS_DEBUG_BUS_OFFS 0
+#define MV_XLG_MAC_DEBUG_BUS_STATUS_DEBUG_BUS_MASK \
+ (0x0000ffff << MV_XLG_MAC_DEBUG_BUS_STATUS_DEBUG_BUS_OFFS)
+
+/* Port Metal Fix */
+#define MV_XLG_PORT_METAL_FIX_REG (0x002c)
+#define MV_XLG_MAC_PORT_METAL_FIX_EN_EOP_IN_FIFO__OFFS 0
+#define MV_XLG_MAC_PORT_METAL_FIX_EN_EOP_IN_FIFO__MASK \
+ (0x00000001 << MV_XLG_MAC_PORT_METAL_FIX_EN_EOP_IN_FIFO__OFFS)
+
+#define MV_XLG_MAC_PORT_METAL_FIX_EN_LTF_FIX__OFFS 1
+#define MV_XLG_MAC_PORT_METAL_FIX_EN_LTF_FIX__MASK \
+ (0x00000001 << MV_XLG_MAC_PORT_METAL_FIX_EN_LTF_FIX__OFFS)
+
+#define MV_XLG_MAC_PORT_METAL_FIX_EN_HOLD_FIX__OFFS 2
+#define MV_XLG_MAC_PORT_METAL_FIX_EN_HOLD_FIX__MASK \
+ (0x00000001 << MV_XLG_MAC_PORT_METAL_FIX_EN_HOLD_FIX__OFFS)
+
+#define MV_XLG_MAC_PORT_METAL_FIX_EN_LED_FIX__OFFS 3
+#define MV_XLG_MAC_PORT_METAL_FIX_EN_LED_FIX__MASK \
+ (0x00000001 << MV_XLG_MAC_PORT_METAL_FIX_EN_LED_FIX__OFFS)
+
+#define MV_XLG_MAC_PORT_METAL_FIX_EN_PAD_PROTECT__OFFS 4
+#define MV_XLG_MAC_PORT_METAL_FIX_EN_PAD_PROTECT__MASK \
+ (0x00000001 << MV_XLG_MAC_PORT_METAL_FIX_EN_PAD_PROTECT__OFFS)
+
+#define MV_XLG_MAC_PORT_METAL_FIX_EN_NX_BTS44__OFFS 5
+#define MV_XLG_MAC_PORT_METAL_FIX_EN_NX_BTS44__MASK \
+ (0x00000001 << MV_XLG_MAC_PORT_METAL_FIX_EN_NX_BTS44__OFFS)
+
+#define MV_XLG_MAC_PORT_METAL_FIX_EN_NX_BTS42__OFFS 6
+#define MV_XLG_MAC_PORT_METAL_FIX_EN_NX_BTS42__MASK \
+ (0x00000001 << MV_XLG_MAC_PORT_METAL_FIX_EN_NX_BTS42__OFFS)
+
+#define MV_XLG_MAC_PORT_METAL_FIX_EN_FLUSH_FIX_OFFS 7
+#define MV_XLG_MAC_PORT_METAL_FIX_EN_FLUSH_FIX_MASK \
+ (0x00000001 << MV_XLG_MAC_PORT_METAL_FIX_EN_FLUSH_FIX_OFFS)
+
+#define MV_XLG_MAC_PORT_METAL_FIX_EN_PORT_EN_FIX_OFFS 8
+#define MV_XLG_MAC_PORT_METAL_FIX_EN_PORT_EN_FIX_MASK \
+ (0x00000001 << MV_XLG_MAC_PORT_METAL_FIX_EN_PORT_EN_FIX_OFFS)
+
+#define MV_XLG_MAC_PORT_METAL_FIX_SPARE_DEF0_BITS_OFFS 9
+#define MV_XLG_MAC_PORT_METAL_FIX_SPARE_DEF0_BITS_MASK \
+ (0x0000000f << MV_XLG_MAC_PORT_METAL_FIX_SPARE_DEF0_BITS_OFFS)
+
+#define MV_XLG_MAC_PORT_METAL_FIX_SPARE_DEF1_BITS_OFFS 13
+#define MV_XLG_MAC_PORT_METAL_FIX_SPARE_DEF1_BITS_MASK \
+ (0x00000007 << MV_XLG_MAC_PORT_METAL_FIX_SPARE_DEF1_BITS_OFFS)
+
+/* Xg Mib Counters Control */
+#define MV_XLG_MIB_CNTRS_CTRL_REG (0x0030)
+#define MV_XLG_MAC_XG_MIB_CNTRS_CTRL_XGCAPTURETRIGGER_OFFS 0
+#define MV_XLG_MAC_XG_MIB_CNTRS_CTRL_XGCAPTURETRIGGER_MASK \
+ (0x00000001 << MV_XLG_MAC_XG_MIB_CNTRS_CTRL_XGCAPTURETRIGGER_OFFS)
+
+#define MV_XLG_MAC_XG_MIB_CNTRS_CTRL_XGDONTCLEARAFTERREAD_OFFS 1
+#define MV_XLG_MAC_XG_MIB_CNTRS_CTRL_XGDONTCLEARAFTERREAD_MASK \
+ (0x00000001 << MV_XLG_MAC_XG_MIB_CNTRS_CTRL_XGDONTCLEARAFTERREAD_OFFS)
+
+#define MV_XLG_MAC_XG_MIB_CNTRS_CTRL_XGRXHISTOGRAMEN_OFFS 2
+#define MV_XLG_MAC_XG_MIB_CNTRS_CTRL_XGRXHISTOGRAMEN_MASK \
+ (0x00000001 << MV_XLG_MAC_XG_MIB_CNTRS_CTRL_XGRXHISTOGRAMEN_OFFS)
+
+#define MV_XLG_MAC_XG_MIB_CNTRS_CTRL_XGTXHISTOGRAMEN_OFFS 3
+#define MV_XLG_MAC_XG_MIB_CNTRS_CTRL_XGTXHISTOGRAMEN_MASK \
+ (0x00000001 << MV_XLG_MAC_XG_MIB_CNTRS_CTRL_XGTXHISTOGRAMEN_OFFS)
+
+#define MV_XLG_MAC_XG_MIB_CNTRS_CTRL_MFA1_BTT940_FIX_ENABLE__OFFS 4
+#define MV_XLG_MAC_XG_MIB_CNTRS_CTRL_MFA1_BTT940_FIX_ENABLE__MASK \
+ (0x00000001 << MV_XLG_MAC_XG_MIB_CNTRS_CTRL_MFA1_BTT940_FIX_ENABLE__OFFS)
+
+#define MV_XLG_MAC_XG_MIB_CNTRS_CTRL_LEDS_NUMBER_OFFS 5
+#define MV_XLG_MAC_XG_MIB_CNTRS_CTRL_LEDS_NUMBER_MASK \
+ (0x0000003f << MV_XLG_MAC_XG_MIB_CNTRS_CTRL_LEDS_NUMBER_OFFS)
+
+#define MV_XLG_MAC_XG_MIB_CNTRS_CTRL_MIB_4_COUNT_HIST_OFFS 11
+#define MV_XLG_MAC_XG_MIB_CNTRS_CTRL_MIB_4_COUNT_HIST_MASK \
+ (0x00000001 << MV_XLG_MAC_XG_MIB_CNTRS_CTRL_MIB_4_COUNT_HIST_OFFS)
+
+#define MV_XLG_MAC_XG_MIB_CNTRS_CTRL_MIB_4_LIMIT_1518_1522_OFFS 12
+#define MV_XLG_MAC_XG_MIB_CNTRS_CTRL_MIB_4_LIMIT_1518_1522_MASK \
+ (0x00000001 << MV_XLG_MAC_XG_MIB_CNTRS_CTRL_MIB_4_LIMIT_1518_1522_OFFS)
+
+/* Cn/ccfc Timer%i */
+#define MV_XLG_CNCCFC_TIMERI_REG(t) ((0x0038 + (t) * 4))
+#define MV_XLG_MAC_CNCCFC_TIMERI_PORTSPEEDTIMER_OFFS 0
+#define MV_XLG_MAC_CNCCFC_TIMERI_PORTSPEEDTIMER_MASK \
+ (0x0000ffff << MV_XLG_MAC_CNCCFC_TIMERI_PORTSPEEDTIMER_OFFS)
+
+/* Ppfc Control */
+#define MV_XLG_MAC_PPFC_CTRL_REG (0x0060)
+#define MV_XLG_MAC_PPFC_CTRL_GLOBAL_PAUSE_ENI_OFFS 0
+#define MV_XLG_MAC_PPFC_CTRL_GLOBAL_PAUSE_ENI_MASK \
+ (0x00000001 << MV_XLG_MAC_PPFC_CTRL_GLOBAL_PAUSE_ENI_OFFS)
+
+#define MV_XLG_MAC_PPFC_CTRL_DIP_BTS_677_EN_OFFS 9
+#define MV_XLG_MAC_PPFC_CTRL_DIP_BTS_677_EN_MASK \
+ (0x00000001 << MV_XLG_MAC_PPFC_CTRL_DIP_BTS_677_EN_OFFS)
+
+/* Fc Dsa Tag 0 */
+#define MV_XLG_MAC_FC_DSA_TAG_0_REG (0x0068)
+#define MV_XLG_MAC_FC_DSA_TAG_0_DSATAGREG0_OFFS 0
+#define MV_XLG_MAC_FC_DSA_TAG_0_DSATAGREG0_MASK \
+ (0x0000ffff << MV_XLG_MAC_FC_DSA_TAG_0_DSATAGREG0_OFFS)
+
+/* Fc Dsa Tag 1 */
+#define MV_XLG_MAC_FC_DSA_TAG_1_REG (0x006c)
+#define MV_XLG_MAC_FC_DSA_TAG_1_DSATAGREG1_OFFS 0
+#define MV_XLG_MAC_FC_DSA_TAG_1_DSATAGREG1_MASK \
+ (0x0000ffff << MV_XLG_MAC_FC_DSA_TAG_1_DSATAGREG1_OFFS)
+
+/* Fc Dsa Tag 2 */
+#define MV_XLG_MAC_FC_DSA_TAG_2_REG (0x0070)
+#define MV_XLG_MAC_FC_DSA_TAG_2_DSATAGREG2_OFFS 0
+#define MV_XLG_MAC_FC_DSA_TAG_2_DSATAGREG2_MASK \
+ (0x0000ffff << MV_XLG_MAC_FC_DSA_TAG_2_DSATAGREG2_OFFS)
+
+/* Fc Dsa Tag 3 */
+#define MV_XLG_MAC_FC_DSA_TAG_3_REG (0x0074)
+#define MV_XLG_MAC_FC_DSA_TAG_3_DSATAGREG3_OFFS 0
+#define MV_XLG_MAC_FC_DSA_TAG_3_DSATAGREG3_MASK \
+ (0x0000ffff << MV_XLG_MAC_FC_DSA_TAG_3_DSATAGREG3_OFFS)
+
+/* Dic Budget Compensation */
+#define MV_XLG_MAC_DIC_BUDGET_COMPENSATION_REG (0x0080)
+#define MV_XLG_MAC_DIC_BUDGET_COMPENSATION_DIC_COUNTER_TO_ADD_8BYTES_OFFS 0
+#define MV_XLG_MAC_DIC_BUDGET_COMPENSATION_DIC_COUNTER_TO_ADD_8BYTES_MASK \
+ (0x0000ffff << MV_XLG_MAC_DIC_BUDGET_COMPENSATION_DIC_COUNTER_TO_ADD_8BYTES_OFFS)
+
+/* Port Mac Control4 */
+#define MV_XLG_PORT_MAC_CTRL4_REG (0x0084)
+#define MV_XLG_MAC_CTRL4_LLFC_GLOBAL_FC_ENABLE_OFFS 0
+#define MV_XLG_MAC_CTRL4_LLFC_GLOBAL_FC_ENABLE_MASK \
+ (0x00000001 << MV_XLG_MAC_CTRL4_LLFC_GLOBAL_FC_ENABLE_OFFS)
+
+#define MV_XLG_MAC_CTRL4_LED_STREAM_SELECT_OFFS 1
+#define MV_XLG_MAC_CTRL4_LED_STREAM_SELECT_MASK \
+ (0x00000001 << MV_XLG_MAC_CTRL4_LED_STREAM_SELECT_OFFS)
+
+#define MV_XLG_MAC_CTRL4_DEBUG_BUS_SELECT_OFFS 2
+#define MV_XLG_MAC_CTRL4_DEBUG_BUS_SELECT_MASK \
+ (0x00000001 << MV_XLG_MAC_CTRL4_DEBUG_BUS_SELECT_OFFS)
+
+#define MV_XLG_MAC_CTRL4_MASK_PCS_RESET_OFFS 3
+#define MV_XLG_MAC_CTRL4_MASK_PCS_RESET_MASK \
+ (0x00000001 << MV_XLG_MAC_CTRL4_MASK_PCS_RESET_OFFS)
+
+#define MV_XLG_MAC_CTRL4_ENABLE_SHORT_PREAMBLE_FOR_XLG_OFFS 4
+#define MV_XLG_MAC_CTRL4_ENABLE_SHORT_PREAMBLE_FOR_XLG_MASK \
+ (0x00000001 << MV_XLG_MAC_CTRL4_ENABLE_SHORT_PREAMBLE_FOR_XLG_OFFS)
+
+#define MV_XLG_MAC_CTRL4_FORWARD_802_3X_FC_EN_OFFS 5
+#define MV_XLG_MAC_CTRL4_FORWARD_802_3X_FC_EN_MASK \
+ (0x00000001 << MV_XLG_MAC_CTRL4_FORWARD_802_3X_FC_EN_OFFS)
+
+#define MV_XLG_MAC_CTRL4_FORWARD_PFC_EN_OFFS 6
+#define MV_XLG_MAC_CTRL4_FORWARD_PFC_EN_MASK \
+ (0x00000001 << MV_XLG_MAC_CTRL4_FORWARD_PFC_EN_OFFS)
+
+#define MV_XLG_MAC_CTRL4_FORWARD_UNKNOWN_FC_EN_OFFS 7
+#define MV_XLG_MAC_CTRL4_FORWARD_UNKNOWN_FC_EN_MASK \
+ (0x00000001 << MV_XLG_MAC_CTRL4_FORWARD_UNKNOWN_FC_EN_OFFS)
+
+#define MV_XLG_MAC_CTRL4_USE_XPCS_OFFS 8
+#define MV_XLG_MAC_CTRL4_USE_XPCS_MASK \
+ (0x00000001 << MV_XLG_MAC_CTRL4_USE_XPCS_OFFS)
+
+#define MV_XLG_MAC_CTRL4_DMA_INTERFACE_IS_64_BIT_OFFS 9
+#define MV_XLG_MAC_CTRL4_DMA_INTERFACE_IS_64_BIT_MASK \
+ (0x00000001 << MV_XLG_MAC_CTRL4_DMA_INTERFACE_IS_64_BIT_OFFS)
+
+#define MV_XLG_MAC_CTRL4_TX_DMA_INTERFACE_BITS_OFFS 10
+#define MV_XLG_MAC_CTRL4_TX_DMA_INTERFACE_BITS_MASK \
+ (0x00000003 << MV_XLG_MAC_CTRL4_TX_DMA_INTERFACE_BITS_OFFS)
+
+#define MV_XLG_MAC_CTRL4_MAC_MODE_DMA_1G_OFFS 12
+#define MV_XLG_MAC_CTRL4_MAC_MODE_DMA_1G_MASK \
+ (0x00000001 << MV_XLG_MAC_CTRL4_MAC_MODE_DMA_1G_OFFS)
+
+#define MV_XLG_MAC_CTRL4_EN_IDLE_CHECK_FOR_LINK 14
+#define MV_XLG_MAC_CTRL4_EN_IDLE_CHECK_FOR_LINK_MASK \
+ (0x00000001 << MV_XLG_MAC_CTRL4_EN_IDLE_CHECK_FOR_LINK)
+
+/* Port Mac Control5 */
+#define MV_XLG_PORT_MAC_CTRL5_REG (0x0088)
+#define MV_XLG_MAC_CTRL5_TXIPGLENGTH_OFFS 0
+#define MV_XLG_MAC_CTRL5_TXIPGLENGTH_MASK \
+ (0x0000000f << MV_XLG_MAC_CTRL5_TXIPGLENGTH_OFFS)
+
+#define MV_XLG_MAC_CTRL5_PREAMBLELENGTHTX_OFFS 4
+#define MV_XLG_MAC_CTRL5_PREAMBLELENGTHTX_MASK \
+ (0x00000007 << MV_XLG_MAC_CTRL5_PREAMBLELENGTHTX_OFFS)
+
+#define MV_XLG_MAC_CTRL5_PREAMBLELENGTHRX_OFFS 7
+#define MV_XLG_MAC_CTRL5_PREAMBLELENGTHRX_MASK \
+ (0x00000007 << MV_XLG_MAC_CTRL5_PREAMBLELENGTHRX_OFFS)
+
+#define MV_XLG_MAC_CTRL5_TXNUMCRCBYTES_OFFS 10
+#define MV_XLG_MAC_CTRL5_TXNUMCRCBYTES_MASK \
+ (0x00000007 << MV_XLG_MAC_CTRL5_TXNUMCRCBYTES_OFFS)
+
+#define MV_XLG_MAC_CTRL5_RXNUMCRCBYTES_OFFS 13
+#define MV_XLG_MAC_CTRL5_RXNUMCRCBYTES_MASK \
+ (0x00000007 << MV_XLG_MAC_CTRL5_RXNUMCRCBYTES_OFFS)
+
+/* External Control */
+#define MV_XLG_MAC_EXT_CTRL_REG (0x0090)
+#define MV_XLG_MAC_EXT_CTRL_EXTERNAL_CTRL0_OFFS 0
+#define MV_XLG_MAC_EXT_CTRL_EXTERNAL_CTRL0_MASK \
+ (0x00000001 << MV_XLG_MAC_EXT_CTRL_EXTERNAL_CTRL0_OFFS)
+
+#define MV_XLG_MAC_EXT_CTRL_EXTERNAL_CTRL1_OFFS 1
+#define MV_XLG_MAC_EXT_CTRL_EXTERNAL_CTRL1_MASK \
+ (0x00000001 << MV_XLG_MAC_EXT_CTRL_EXTERNAL_CTRL1_OFFS)
+
+#define MV_XLG_MAC_EXT_CTRL_EXTERNAL_CTRL2_OFFS 2
+#define MV_XLG_MAC_EXT_CTRL_EXTERNAL_CTRL2_MASK \
+ (0x00000001 << MV_XLG_MAC_EXT_CTRL_EXTERNAL_CTRL2_OFFS)
+
+#define MV_XLG_MAC_EXT_CTRL_EXTERNAL_CTRL3_OFFS 3
+#define MV_XLG_MAC_EXT_CTRL_EXTERNAL_CTRL3_MASK \
+ (0x00000001 << MV_XLG_MAC_EXT_CTRL_EXTERNAL_CTRL3_OFFS)
+
+#define MV_XLG_MAC_EXT_CTRL_EXTERNAL_CTRL4_OFFS 4
+#define MV_XLG_MAC_EXT_CTRL_EXTERNAL_CTRL4_MASK \
+ (0x00000001 << MV_XLG_MAC_EXT_CTRL_EXTERNAL_CTRL4_OFFS)
+
+#define MV_XLG_MAC_EXT_CTRL_EXTERNAL_CTRL5_OFFS 5
+#define MV_XLG_MAC_EXT_CTRL_EXTERNAL_CTRL5_MASK \
+ (0x00000001 << MV_XLG_MAC_EXT_CTRL_EXTERNAL_CTRL5_OFFS)
+
+#define MV_XLG_MAC_EXT_CTRL_EXTERNAL_CTRL6_OFFS 6
+#define MV_XLG_MAC_EXT_CTRL_EXTERNAL_CTRL6_MASK \
+ (0x00000001 << MV_XLG_MAC_EXT_CTRL_EXTERNAL_CTRL6_OFFS)
+
+#define MV_XLG_MAC_EXT_CTRL_EXTERNAL_CTRL7_OFFS 7
+#define MV_XLG_MAC_EXT_CTRL_EXTERNAL_CTRL7_MASK \
+ (0x00000001 << MV_XLG_MAC_EXT_CTRL_EXTERNAL_CTRL7_OFFS)
+
+#define MV_XLG_MAC_EXT_CTRL_EXTERNAL_CTRL8_OFFS 8
+#define MV_XLG_MAC_EXT_CTRL_EXTERNAL_CTRL8_MASK \
+ (0x00000001 << MV_XLG_MAC_EXT_CTRL_EXTERNAL_CTRL8_OFFS)
+
+#define MV_XLG_MAC_EXT_CTRL_EXTERNAL_CTRL9_OFFS 9
+#define MV_XLG_MAC_EXT_CTRL_EXTERNAL_CTRL9_MASK \
+ (0x00000001 << MV_XLG_MAC_EXT_CTRL_EXTERNAL_CTRL9_OFFS)
+
+#define MV_XLG_MAC_EXT_CTRL_EXT_CTRL_10_OFFS 10
+#define MV_XLG_MAC_EXT_CTRL_EXT_CTRL_10_MASK \
+ (0x00000001 << MV_XLG_MAC_EXT_CTRL_EXT_CTRL_10_OFFS)
+
+#define MV_XLG_MAC_EXT_CTRL_EXT_CTRL_11_OFFS 11
+#define MV_XLG_MAC_EXT_CTRL_EXT_CTRL_11_MASK \
+ (0x00000001 << MV_XLG_MAC_EXT_CTRL_EXT_CTRL_11_OFFS)
+
+#define MV_XLG_MAC_EXT_CTRL_EXT_CTRL_12_OFFS 12
+#define MV_XLG_MAC_EXT_CTRL_EXT_CTRL_12_MASK \
+ (0x00000001 << MV_XLG_MAC_EXT_CTRL_EXT_CTRL_12_OFFS)
+
+#define MV_XLG_MAC_EXT_CTRL_EXT_CTRL_13_OFFS 13
+#define MV_XLG_MAC_EXT_CTRL_EXT_CTRL_13_MASK \
+ (0x00000001 << MV_XLG_MAC_EXT_CTRL_EXT_CTRL_13_OFFS)
+
+#define MV_XLG_MAC_EXT_CTRL_EXT_CTRL_14_OFFS 14
+#define MV_XLG_MAC_EXT_CTRL_EXT_CTRL_14_MASK \
+ (0x00000001 << MV_XLG_MAC_EXT_CTRL_EXT_CTRL_14_OFFS)
+
+#define MV_XLG_MAC_EXT_CTRL_EXT_CTRL_15_OFFS 15
+#define MV_XLG_MAC_EXT_CTRL_EXT_CTRL_15_MASK \
+ (0x00000001 << MV_XLG_MAC_EXT_CTRL_EXT_CTRL_15_OFFS)
+
+/* Macro Control */
+#define MV_XLG_MAC_MACRO_CTRL_REG (0x0094)
+#define MV_XLG_MAC_MACRO_CTRL_MACRO_CTRL_0_OFFS 0
+#define MV_XLG_MAC_MACRO_CTRL_MACRO_CTRL_0_MASK \
+ (0x00000001 << MV_XLG_MAC_MACRO_CTRL_MACRO_CTRL_0_OFFS)
+
+#define MV_XLG_MAC_MACRO_CTRL_MACRO_CTRL_1_OFFS 1
+#define MV_XLG_MAC_MACRO_CTRL_MACRO_CTRL_1_MASK \
+ (0x00000001 << MV_XLG_MAC_MACRO_CTRL_MACRO_CTRL_1_OFFS)
+
+#define MV_XLG_MAC_MACRO_CTRL_MACRO_CTRL_2_OFFS 2
+#define MV_XLG_MAC_MACRO_CTRL_MACRO_CTRL_2_MASK \
+ (0x00000001 << MV_XLG_MAC_MACRO_CTRL_MACRO_CTRL_2_OFFS)
+
+#define MV_XLG_MAC_MACRO_CTRL_MACRO_CTRL_3_OFFS 3
+#define MV_XLG_MAC_MACRO_CTRL_MACRO_CTRL_3_MASK \
+ (0x00000001 << MV_XLG_MAC_MACRO_CTRL_MACRO_CTRL_3_OFFS)
+
+#define MV_XLG_MAC_MACRO_CTRL_MACRO_CTRL_4_OFFS 4
+#define MV_XLG_MAC_MACRO_CTRL_MACRO_CTRL_4_MASK \
+ (0x00000001 << MV_XLG_MAC_MACRO_CTRL_MACRO_CTRL_4_OFFS)
+
+#define MV_XLG_MAC_MACRO_CTRL_MACRO_CTRL_5_OFFS 5
+#define MV_XLG_MAC_MACRO_CTRL_MACRO_CTRL_5_MASK \
+ (0x00000001 << MV_XLG_MAC_MACRO_CTRL_MACRO_CTRL_5_OFFS)
+
+#define MV_XLG_MAC_MACRO_CTRL_MACRO_CTRL_6_OFFS 6
+#define MV_XLG_MAC_MACRO_CTRL_MACRO_CTRL_6_MASK \
+ (0x00000001 << MV_XLG_MAC_MACRO_CTRL_MACRO_CTRL_6_OFFS)
+
+#define MV_XLG_MAC_MACRO_CTRL_MACRO_CTRL_7_OFFS 7
+#define MV_XLG_MAC_MACRO_CTRL_MACRO_CTRL_7_MASK \
+ (0x00000001 << MV_XLG_MAC_MACRO_CTRL_MACRO_CTRL_7_OFFS)
+
+#define MV_XLG_MAC_MACRO_CTRL_MACRO_CTRL_8_OFFS 8
+#define MV_XLG_MAC_MACRO_CTRL_MACRO_CTRL_8_MASK \
+ (0x00000001 << MV_XLG_MAC_MACRO_CTRL_MACRO_CTRL_8_OFFS)
+
+#define MV_XLG_MAC_MACRO_CTRL_MACRO_CTRL_9_OFFS 9
+#define MV_XLG_MAC_MACRO_CTRL_MACRO_CTRL_9_MASK \
+ (0x00000001 << MV_XLG_MAC_MACRO_CTRL_MACRO_CTRL_9_OFFS)
+
+#define MV_XLG_MAC_MACRO_CTRL_MACRO_CTRL_10_OFFS 10
+#define MV_XLG_MAC_MACRO_CTRL_MACRO_CTRL_10_MASK \
+ (0x00000001 << MV_XLG_MAC_MACRO_CTRL_MACRO_CTRL_10_OFFS)
+
+#define MV_XLG_MAC_MACRO_CTRL_MACRO_CTRL_11_OFFS 11
+#define MV_XLG_MAC_MACRO_CTRL_MACRO_CTRL_11_MASK \
+ (0x00000001 << MV_XLG_MAC_MACRO_CTRL_MACRO_CTRL_11_OFFS)
+
+#define MV_XLG_MAC_MACRO_CTRL_MACRO_CTRL_12_OFFS 12
+#define MV_XLG_MAC_MACRO_CTRL_MACRO_CTRL_12_MASK \
+ (0x00000001 << MV_XLG_MAC_MACRO_CTRL_MACRO_CTRL_12_OFFS)
+
+#define MV_XLG_MAC_MACRO_CTRL_MACRO_CTRL_13_OFFS 13
+#define MV_XLG_MAC_MACRO_CTRL_MACRO_CTRL_13_MASK \
+ (0x00000001 << MV_XLG_MAC_MACRO_CTRL_MACRO_CTRL_13_OFFS)
+
+#define MV_XLG_MAC_MACRO_CTRL_MACRO_CTRL_14_OFFS 14
+#define MV_XLG_MAC_MACRO_CTRL_MACRO_CTRL_14_MASK \
+ (0x00000001 << MV_XLG_MAC_MACRO_CTRL_MACRO_CTRL_14_OFFS)
+
+#define MV_XLG_MAC_MACRO_CTRL_MACRO_CTRL_15_OFFS 15
+#define MV_XLG_MAC_MACRO_CTRL_MACRO_CTRL_15_MASK \
+ (0x00000001 << MV_XLG_MAC_MACRO_CTRL_MACRO_CTRL_15_OFFS)
+
+#define MV_XLG_MAC_DIC_PPM_IPG_REDUCE_REG (0x0094)
+
+/* Port Interrupt Cause */
+#define MV_XLG_INTERRUPT_CAUSE_REG (0x0014)
+/* Port Interrupt Mask */
+#define MV_XLG_INTERRUPT_MASK_REG (0x0018)
+#define MV_XLG_SUMMARY_INTERRUPT_OFFSET 0
+#define MV_XLG_SUMMARY_INTERRUPT_MASK \
+ (0x1 << MV_XLG_SUMMARY_INTERRUPT_OFFSET)
+#define MV_XLG_INTERRUPT_LINK_CHANGE_OFFS 1
+#define MV_XLG_INTERRUPT_LINK_CHANGE_MASK \
+ (0x1 << MV_XLG_INTERRUPT_LINK_CHANGE_OFFS)
+
+/* Port Interrupt Summary Cause */
+#define MV_XLG_EXTERNAL_INTERRUPT_CAUSE_REG (0x0058)
+/* Port Interrupt Summary Mask */
+#define MV_XLG_EXTERNAL_INTERRUPT_MASK_REG (0x005C)
+#define MV_XLG_EXTERNAL_INTERRUPT_LINK_CHANGE_XLG_OFFS 1
+#define MV_XLG_EXTERNAL_INTERRUPT_LINK_CHANGE_XLG_MASK \
+ (0x1 << MV_XLG_EXTERNAL_INTERRUPT_LINK_CHANGE_XLG_OFFS)
+#define MV_XLG_EXTERNAL_INTERRUPT_LINK_CHANGE_GIG_OFFS 2
+#define MV_XLG_EXTERNAL_INTERRUPT_LINK_CHANGE_GIG_MASK \
+ (0x1 << MV_XLG_EXTERNAL_INTERRUPT_LINK_CHANGE_GIG_OFFS)
+
+/*All PPV22 Addresses are 40-bit */
+#define MVPP22_ADDR_HIGH_SIZE 8
+#define MVPP22_ADDR_HIGH_MASK ((1<<MVPP22_ADDR_HIGH_SIZE) - 1)
+#define MVPP22_ADDR_MASK (0xFFFFFFFFFF)
+
+/* Desc addr shift */
+#define MVPP21_DESC_ADDR_SHIFT 0 /*Applies to RXQ, AGGR_TXQ*/
+#define MVPP22_DESC_ADDR_SHIFT 8 /*Applies to RXQ, AGGR_TXQ*/
+
+/* AXI Bridge Registers */
+#define MVPP22_AXI_BM_WR_ATTR_REG 0x4100
+#define MVPP22_AXI_BM_RD_ATTR_REG 0x4104
+#define MVPP22_AXI_AGGRQ_DESCR_RD_ATTR_REG 0x4110
+#define MVPP22_AXI_TXQ_DESCR_WR_ATTR_REG 0x4114
+#define MVPP22_AXI_TXQ_DESCR_RD_ATTR_REG 0x4118
+#define MVPP22_AXI_RXQ_DESCR_WR_ATTR_REG 0x411c
+#define MVPP22_AXI_RX_DATA_WR_ATTR_REG 0x4120
+#define MVPP22_AXI_TX_DATA_RD_ATTR_REG 0x4130
+#define MVPP22_AXI_RD_NORMAL_CODE_REG 0x4150
+#define MVPP22_AXI_RD_SNOOP_CODE_REG 0x4154
+#define MVPP22_AXI_WR_NORMAL_CODE_REG 0x4160
+#define MVPP22_AXI_WR_SNOOP_CODE_REG 0x4164
+
+#define MVPP22_AXI_ATTR_CACHE_OFFS 0
+#define MVPP22_AXI_ATTR_DOMAIN_OFFS 12
+
+#define MVPP22_AXI_CODE_CACHE_OFFS 0
+#define MVPP22_AXI_CODE_DOMAIN_OFFS 4
+
+#define MVPP22_AXI_CODE_CACHE_NON_CACHE 0x3
+#define MVPP22_AXI_CODE_CACHE_WR_CACHE 0x7
+#define MVPP22_AXI_CODE_CACHE_RD_CACHE 0xb
+
+#define MVPP22_AXI_CODE_DOMAIN_OUTER_DOM 2
+#define MVPP22_AXI_CODE_DOMAIN_SYSTEM 3
+
+/* PHY address register */
+#define MV_SMI_PHY_ADDRESS_REG(n) (0xC + 0x4 * (n))
+#define MV_SMI_PHY_ADDRESS_PHYAD_OFFS 0
+#define MV_SMI_PHY_ADDRESS_PHYAD_MASK \
+ (0x1F << MV_SMI_PHY_ADDRESS_PHYAD_OFFS)
+
+/* Marvell tag types */
+enum Mvpp2TagType {
+ MVPP2_TAG_TYPE_NONE = 0,
+ MVPP2_TAG_TYPE_MH = 1,
+ MVPP2_TAG_TYPE_DSA = 2,
+ MVPP2_TAG_TYPE_EDSA = 3,
+ MVPP2_TAG_TYPE_VLAN = 4,
+ MVPP2_TAG_TYPE_LAST = 5
+};
+
+/* Parser constants */
+#define MVPP2_PRS_TCAM_SRAM_SIZE 256
+#define MVPP2_PRS_TCAM_WORDS 6
+#define MVPP2_PRS_SRAM_WORDS 4
+#define MVPP2_PRS_FLOW_ID_SIZE 64
+#define MVPP2_PRS_FLOW_ID_MASK 0x3f
+#define MVPP2_PRS_TCAM_ENTRY_INVALID 1
+#define MVPP2_PRS_TCAM_DSA_TAGGED_BIT BIT(5)
+#define MVPP2_PRS_IPV4_HEAD 0x40
+#define MVPP2_PRS_IPV4_HEAD_MASK 0xf0
+#define MVPP2_PRS_IPV4_MC 0xe0
+#define MVPP2_PRS_IPV4_MC_MASK 0xf0
+#define MVPP2_PRS_IPV4_BC_MASK 0xff
+#define MVPP2_PRS_IPV4_IHL 0x5
+#define MVPP2_PRS_IPV4_IHL_MASK 0xf
+#define MVPP2_PRS_IPV6_MC 0xff
+#define MVPP2_PRS_IPV6_MC_MASK 0xff
+#define MVPP2_PRS_IPV6_HOP_MASK 0xff
+#define MVPP2_PRS_TCAM_PROTO_MASK 0xff
+#define MVPP2_PRS_TCAM_PROTO_MASK_L 0x3f
+#define MVPP2_PRS_DBL_VLANS_MAX 100
+
+/*
+ * Tcam structure:
+ * - lookup ID - 4 bits
+ * - port ID - 1 byte
+ * - additional information - 1 byte
+ * - header data - 8 bytes
+ * The fields are represented by MVPP2_PRS_TCAM_DATA_REG(5)->(0).
+ */
+#define MVPP2_PRS_AI_BITS 8
+#define MVPP2_PRS_PORT_MASK 0xff
+#define MVPP2_PRS_LU_MASK 0xf
+#define MVPP2_PRS_TCAM_DATA_BYTE(offs) (((offs) - ((offs) % 2)) * 2 + ((offs) % 2))
+#define MVPP2_PRS_TCAM_DATA_BYTE_EN(offs) (((offs) * 2) - ((offs) % 2) + 2)
+#define MVPP2_PRS_TCAM_AI_BYTE 16
+#define MVPP2_PRS_TCAM_PORT_BYTE 17
+#define MVPP2_PRS_TCAM_LU_BYTE 20
+#define MVPP2_PRS_TCAM_EN_OFFS(offs) ((offs) + 2)
+#define MVPP2_PRS_TCAM_INV_WORD 5
+/* Tcam entries ID */
+#define MVPP2_PE_DROP_ALL 0
+#define MVPP2_PE_FIRST_FREE_TID 1
+#define MVPP2_PE_LAST_FREE_TID (MVPP2_PRS_TCAM_SRAM_SIZE - 31)
+#define MVPP2_PE_IP6_EXT_PROTO_UN (MVPP2_PRS_TCAM_SRAM_SIZE - 30)
+#define MVPP2_PE_MAC_MC_IP6 (MVPP2_PRS_TCAM_SRAM_SIZE - 29)
+#define MVPP2_PE_IP6_ADDR_UN (MVPP2_PRS_TCAM_SRAM_SIZE - 28)
+#define MVPP2_PE_IP4_ADDR_UN (MVPP2_PRS_TCAM_SRAM_SIZE - 27)
+#define MVPP2_PE_LAST_DEFAULT_FLOW (MVPP2_PRS_TCAM_SRAM_SIZE - 26)
+#define MVPP2_PE_FIRST_DEFAULT_FLOW (MVPP2_PRS_TCAM_SRAM_SIZE - 19)
+#define MVPP2_PE_EDSA_TAGGED (MVPP2_PRS_TCAM_SRAM_SIZE - 18)
+#define MVPP2_PE_EDSA_UNTAGGED (MVPP2_PRS_TCAM_SRAM_SIZE - 17)
+#define MVPP2_PE_DSA_TAGGED (MVPP2_PRS_TCAM_SRAM_SIZE - 16)
+#define MVPP2_PE_DSA_UNTAGGED (MVPP2_PRS_TCAM_SRAM_SIZE - 15)
+#define MVPP2_PE_ETYPE_EDSA_TAGGED (MVPP2_PRS_TCAM_SRAM_SIZE - 14)
+#define MVPP2_PE_ETYPE_EDSA_UNTAGGED (MVPP2_PRS_TCAM_SRAM_SIZE - 13)
+#define MVPP2_PE_ETYPE_DSA_TAGGED (MVPP2_PRS_TCAM_SRAM_SIZE - 12)
+#define MVPP2_PE_ETYPE_DSA_UNTAGGED (MVPP2_PRS_TCAM_SRAM_SIZE - 11)
+#define MVPP2_PE_MH_DEFAULT (MVPP2_PRS_TCAM_SRAM_SIZE - 10)
+#define MVPP2_PE_DSA_DEFAULT (MVPP2_PRS_TCAM_SRAM_SIZE - 9)
+#define MVPP2_PE_IP6_PROTO_UN (MVPP2_PRS_TCAM_SRAM_SIZE - 8)
+#define MVPP2_PE_IP4_PROTO_UN (MVPP2_PRS_TCAM_SRAM_SIZE - 7)
+#define MVPP2_PE_ETH_TYPE_UN (MVPP2_PRS_TCAM_SRAM_SIZE - 6)
+#define MVPP2_PE_VLAN_DBL (MVPP2_PRS_TCAM_SRAM_SIZE - 5)
+#define MVPP2_PE_VLAN_NONE (MVPP2_PRS_TCAM_SRAM_SIZE - 4)
+#define MVPP2_PE_MAC_MC_ALL (MVPP2_PRS_TCAM_SRAM_SIZE - 3)
+#define MVPP2_PE_MAC_PROMISCUOUS (MVPP2_PRS_TCAM_SRAM_SIZE - 2)
+#define MVPP2_PE_MAC_NON_PROMISCUOUS (MVPP2_PRS_TCAM_SRAM_SIZE - 1)
+
+/*
+ * Sram structure
+ * The fields are represented by MVPP2_PRS_TCAM_DATA_REG(3)->(0).
+ */
+#define MVPP2_PRS_SRAM_RI_OFFS 0
+#define MVPP2_PRS_SRAM_RI_WORD 0
+#define MVPP2_PRS_SRAM_RI_CTRL_OFFS 32
+#define MVPP2_PRS_SRAM_RI_CTRL_WORD 1
+#define MVPP2_PRS_SRAM_RI_CTRL_BITS 32
+#define MVPP2_PRS_SRAM_SHIFT_OFFS 64
+#define MVPP2_PRS_SRAM_SHIFT_SIGN_BIT 72
+#define MVPP2_PRS_SRAM_SHIFT_MASK 0xff
+#define MVPP2_PRS_SRAM_UDF_OFFS 73
+#define MVPP2_PRS_SRAM_UDF_BITS 8
+#define MVPP2_PRS_SRAM_UDF_MASK 0xff
+#define MVPP2_PRS_SRAM_UDF_SIGN_BIT 81
+#define MVPP2_PRS_SRAM_UDF_TYPE_OFFS 82
+#define MVPP2_PRS_SRAM_UDF_TYPE_MASK 0x7
+#define MVPP2_PRS_SRAM_UDF_TYPE_L3 1
+#define MVPP2_PRS_SRAM_UDF_TYPE_L4 4
+#define MVPP2_PRS_SRAM_OP_SEL_SHIFT_OFFS 85
+#define MVPP2_PRS_SRAM_OP_SEL_SHIFT_MASK 0x3
+#define MVPP2_PRS_SRAM_OP_SEL_SHIFT_ADD 1
+#define MVPP2_PRS_SRAM_OP_SEL_SHIFT_IP4_ADD 2
+#define MVPP2_PRS_SRAM_OP_SEL_SHIFT_IP6_ADD 3
+#define MVPP2_PRS_SRAM_OP_SEL_UDF_OFFS 87
+#define MVPP2_PRS_SRAM_OP_SEL_UDF_BITS 2
+#define MVPP2_PRS_SRAM_OP_SEL_UDF_MASK 0x3
+#define MVPP2_PRS_SRAM_OP_SEL_UDF_ADD 0
+#define MVPP2_PRS_SRAM_OP_SEL_UDF_IP4_ADD 2
+#define MVPP2_PRS_SRAM_OP_SEL_UDF_IP6_ADD 3
+#define MVPP2_PRS_SRAM_OP_SEL_BASE_OFFS 89
+#define MVPP2_PRS_SRAM_AI_OFFS 90
+#define MVPP2_PRS_SRAM_AI_CTRL_OFFS 98
+#define MVPP2_PRS_SRAM_AI_CTRL_BITS 8
+#define MVPP2_PRS_SRAM_AI_MASK 0xff
+#define MVPP2_PRS_SRAM_NEXT_LU_OFFS 106
+#define MVPP2_PRS_SRAM_NEXT_LU_MASK 0xf
+#define MVPP2_PRS_SRAM_LU_DONE_BIT 110
+#define MVPP2_PRS_SRAM_LU_GEN_BIT 111
+
+/* Sram result info bits assignment */
+#define MVPP2_PRS_RI_MAC_ME_MASK 0x1
+#define MVPP2_PRS_RI_DSA_MASK 0x2
+#define MVPP2_PRS_RI_VLAN_MASK 0xc
+#define MVPP2_PRS_RI_VLAN_NONE ~(BIT(2) | BIT(3))
+#define MVPP2_PRS_RI_VLAN_SINGLE BIT(2)
+#define MVPP2_PRS_RI_VLAN_DOUBLE BIT(3)
+#define MVPP2_PRS_RI_VLAN_TRIPLE (BIT(2) | BIT(3))
+#define MVPP2_PRS_RI_CPU_CODE_MASK 0x70
+#define MVPP2_PRS_RI_CPU_CODE_RX_SPEC BIT(4)
+#define MVPP2_PRS_RI_L2_CAST_MASK 0x600
+#define MVPP2_PRS_RI_L2_UCAST ~(BIT(9) | BIT(10))
+#define MVPP2_PRS_RI_L2_MCAST BIT(9)
+#define MVPP2_PRS_RI_L2_BCAST BIT(10)
+#define MVPP2_PRS_RI_PPPOE_MASK 0x800
+#define MVPP2_PRS_RI_L3_PROTO_MASK 0x7000
+#define MVPP2_PRS_RI_L3_UN ~(BIT(12) | BIT(13) | BIT(14))
+#define MVPP2_PRS_RI_L3_IP4 BIT(12)
+#define MVPP2_PRS_RI_L3_IP4_OPT BIT(13)
+#define MVPP2_PRS_RI_L3_IP4_OTHER (BIT(12) | BIT(13))
+#define MVPP2_PRS_RI_L3_IP6 BIT(14)
+#define MVPP2_PRS_RI_L3_IP6_EXT (BIT(12) | BIT(14))
+#define MVPP2_PRS_RI_L3_ARP (BIT(13) | BIT(14))
+#define MVPP2_PRS_RI_L3_ADDR_MASK 0x18000
+#define MVPP2_PRS_RI_L3_UCAST ~(BIT(15) | BIT(16))
+#define MVPP2_PRS_RI_L3_MCAST BIT(15)
+#define MVPP2_PRS_RI_L3_BCAST (BIT(15) | BIT(16))
+#define MVPP2_PRS_RI_IP_FRAG_MASK 0x20000
+#define MVPP2_PRS_RI_UDF3_MASK 0x300000
+#define MVPP2_PRS_RI_UDF3_RX_SPECIAL BIT(21)
+#define MVPP2_PRS_RI_L4_PROTO_MASK 0x1c00000
+#define MVPP2_PRS_RI_L4_TCP BIT(22)
+#define MVPP2_PRS_RI_L4_UDP BIT(23)
+#define MVPP2_PRS_RI_L4_OTHER (BIT(22) | BIT(23))
+#define MVPP2_PRS_RI_UDF7_MASK 0x60000000
+#define MVPP2_PRS_RI_UDF7_IP6_LITE BIT(29)
+#define MVPP2_PRS_RI_DROP_MASK 0x80000000
+
+/* Sram additional info bits assignment */
+#define MVPP2_PRS_IPV4_DIP_AI_BIT BIT(0)
+#define MVPP2_PRS_IPV6_NO_EXT_AI_BIT BIT(0)
+#define MVPP2_PRS_IPV6_EXT_AI_BIT BIT(1)
+#define MVPP2_PRS_IPV6_EXT_AH_AI_BIT BIT(2)
+#define MVPP2_PRS_IPV6_EXT_AH_LEN_AI_BIT BIT(3)
+#define MVPP2_PRS_IPV6_EXT_AH_L4_AI_BIT BIT(4)
+#define MVPP2_PRS_SINGLE_VLAN_AI 0
+#define MVPP2_PRS_DBL_VLAN_AI_BIT BIT(7)
+
+/* DSA/EDSA type */
+#define MVPP2_PRS_TAGGED 1
+#define MVPP2_PRS_UNTAGGED 0
+#define MVPP2_PRS_EDSA 1
+#define MVPP2_PRS_DSA 0
+
+/* MAC entries, shadow udf */
+enum Mvpp2PrsUdf {
+ MVPP2_PRS_UDF_MAC_DEF,
+ MVPP2_PRS_UDF_MAC_RANGE,
+ MVPP2_PRS_UDF_L2_DEF,
+ MVPP2_PRS_UDF_L2_DEF_COPY,
+ MVPP2_PRS_UDF_L2_USER,
+};
+
+/* Lookup ID */
+enum Mvpp2PrsLookup {
+ MVPP2_PRS_LU_MH,
+ MVPP2_PRS_LU_MAC,
+ MVPP2_PRS_LU_DSA,
+ MVPP2_PRS_LU_VLAN,
+ MVPP2_PRS_LU_L2,
+ MVPP2_PRS_LU_PPPOE,
+ MVPP2_PRS_LU_IP4,
+ MVPP2_PRS_LU_IP6,
+ MVPP2_PRS_LU_FLOWS,
+ MVPP2_PRS_LU_LAST,
+};
+
+/* L3 cast enum */
+enum Mvpp2PrsL3Cast {
+ MVPP2_PRS_L3_UNI_CAST,
+ MVPP2_PRS_L3_MULTI_CAST,
+ MVPP2_PRS_L3_BROAD_CAST
+};
+
+/* Classifier constants */
+#define MVPP2_CLS_FLOWS_TBL_SIZE 512
+#define MVPP2_CLS_FLOWS_TBL_DATA_WORDS 3
+#define MVPP2_CLS_LKP_TBL_SIZE 64
+
+/* BM cookie (32 bits) definition */
+#define MVPP2_BM_COOKIE_POOL_OFFS 8
+#define MVPP2_BM_COOKIE_CPU_OFFS 24
+
+/*
+ * The MVPP2_TX_DESC and MVPP2_RX_DESC structures describe the
+ * layout of the transmit and reception DMA descriptors, and their
+ * layout is therefore defined by the hardware design
+ */
+#define MVPP2_TXD_L3_OFF_SHIFT 0
+#define MVPP2_TXD_IP_HLEN_SHIFT 8
+#define MVPP2_TXD_L4_CSUM_FRAG BIT(13)
+#define MVPP2_TXD_L4_CSUM_NOT BIT(14)
+#define MVPP2_TXD_IP_CSUM_DISABLE BIT(15)
+#define MVPP2_TXD_PADDING_DISABLE BIT(23)
+#define MVPP2_TXD_L4_UDP BIT(24)
+#define MVPP2_TXD_L3_IP6 BIT(26)
+#define MVPP2_TXD_L_DESC BIT(28)
+#define MVPP2_TXD_F_DESC BIT(29)
+
+#define MVPP2_RXD_ERR_SUMMARY BIT(15)
+#define MVPP2_RXD_ERR_CODE_MASK (BIT(13) | BIT(14))
+#define MVPP2_RXD_ERR_CRC 0x0
+#define MVPP2_RXD_ERR_OVERRUN BIT(13)
+#define MVPP2_RXD_ERR_RESOURCE (BIT(13) | BIT(14))
+#define MVPP2_RXD_BM_POOL_ID_OFFS 16
+#define MVPP2_RXD_BM_POOL_ID_MASK (BIT(16) | BIT(17) | BIT(18))
+#define MVPP2_RXD_HWF_SYNC BIT(21)
+#define MVPP2_RXD_L4_CSUM_OK BIT(22)
+#define MVPP2_RXD_IP4_HEADER_ERR BIT(24)
+#define MVPP2_RXD_L4_TCP BIT(25)
+#define MVPP2_RXD_L4_UDP BIT(26)
+#define MVPP2_RXD_L3_IP4 BIT(28)
+#define MVPP2_RXD_L3_IP6 BIT(30)
+#define MVPP2_RXD_BUF_HDR BIT(31)
+
+struct mvpp2_tx_desc {
+ uint32_t command; /* Options used by HW for packet transmitting.*/
+ uint8_t packet_offset; /* the offset from the buffer beginning */
+ uint8_t phys_txq; /* destination queue ID */
+ uint16_t data_size; /* data size of transmitted packet in bytes */
+ uint64_t rsrvd_hw_cmd1; /* HwCmd (BM, PON, PNC) */
+ uint64_t buf_phys_addr_hw_cmd2;
+ uint64_t buf_cookie_bm_qset_hw_cmd3;
+};
+
+struct mvpp2_rx_desc {
+ uint32_t status; /* info about received packet */
+ uint16_t reserved1; /* ParserInfo (for future use, PnC) */
+ uint16_t data_size; /* size of received packet in bytes */
+ uint16_t rsrvd_gem; /* GemPortId (for future use, PON) */
+ uint16_t rsrvd_l4_csum; /* CsumL4 (for future use, PnC) */
+ uint32_t rsrvd_timestamp;
+ uint64_t buf_phys_addr_key_hash;
+ uint64_t buf_cookie_bm_qset_cls_info;
+};
+
+union mvpp2_prs_tcam_entry {
+ uint32_t word[MVPP2_PRS_TCAM_WORDS];
+ uint8_t byte[MVPP2_PRS_TCAM_WORDS * 4];
+};
+
+union mvpp2_prs_sram_entry {
+ uint32_t word[MVPP2_PRS_SRAM_WORDS];
+ uint8_t byte[MVPP2_PRS_SRAM_WORDS * 4];
+};
+
+struct mvpp2_prs_entry {
+ uint32_t index;
+ union mvpp2_prs_tcam_entry tcam;
+ union mvpp2_prs_sram_entry sram;
+};
+
+struct mvpp2_prs_shadow {
+ int valid;
+ int finish;
+
+ /* Lookup ID */
+ int32_t lu;
+
+ /* User defined offset */
+ int32_t udf;
+
+ /* Result info */
+ uint32_t ri;
+ uint32_t ri_mask;
+};
+
+struct mvpp2_cls_flow_entry {
+ uint32_t index;
+ uint32_t data[MVPP2_CLS_FLOWS_TBL_DATA_WORDS];
+};
+
+struct mvpp2_cls_lookup_entry {
+ uint32_t lkpid;
+ uint32_t way;
+ uint32_t data;
+};
+
+typedef struct {
+ uint32_t NextBuffPhysAddr;
+ uint32_t NextBuffVirtAddr;
+ uint16_t ByteCount;
+ uint16_t info;
+ uint8_t reserved1; /* BmQset (for future use, BM) */
+} MVPP2_BUFF_HDR;
+
+/* Buffer header info bits */
+#define MVPP2_B_HDR_INFO_MC_ID_MASK 0xfff
+#define MVPP2_B_HDR_INFO_MC_ID(info) ((info) & MVPP2_B_HDR_INFO_MC_ID_MASK)
+#define MVPP2_B_HDR_INFO_LAST_OFFS 12
+#define MVPP2_B_HDR_INFO_LAST_MASK BIT(12)
+#define MVPP2_B_HDR_INFO_IS_LAST(info) ((info & MVPP2_B_HDR_INFO_LAST_MASK) >> MVPP2_B_HDR_INFO_LAST_OFFS)
+
+/* SerDes */
+#define MVPP2_SFI_LANE_COUNT 1
+
+/* Net Complex */
+enum MvNetcTopology {
+ MV_NETC_GE_MAC0_RXAUI_L23 = BIT(0),
+ MV_NETC_GE_MAC0_RXAUI_L45 = BIT(1),
+ MV_NETC_GE_MAC0_XAUI = BIT(2),
+ MV_NETC_GE_MAC2_SGMII = BIT(3),
+ MV_NETC_GE_MAC3_SGMII = BIT(4),
+ MV_NETC_GE_MAC3_RGMII = BIT(5),
+};
+
+enum MvNetcPhase {
+ MV_NETC_FIRST_PHASE,
+ MV_NETC_SECOND_PHASE,
+};
+
+enum MvNetcSgmiiXmiMode {
+ MV_NETC_GBE_SGMII,
+ MV_NETC_GBE_XMII,
+};
+
+enum MvNetcMiiMode {
+ MV_NETC_GBE_RGMII,
+ MV_NETC_GBE_MII,
+};
+
+enum MvNetcLanes {
+ MV_NETC_LANE_23,
+ MV_NETC_LANE_45,
+};
+
+/* Port related */
+enum MvReset {
+ RESET,
+ UNRESET
+};
+
+enum Mvpp2Command {
+ MVPP2_START, /* Start */
+ MVPP2_STOP, /* Stop */
+ MVPP2_PAUSE, /* Pause */
+ MVPP2_RESTART /* Restart */
+};
+
+enum MvPortDuplex {
+ MV_PORT_DUPLEX_AN,
+ MV_PORT_DUPLEX_HALF,
+ MV_PORT_DUPLEX_FULL
+};
+
+/* L2 and L3 protocol macros */
+#define MV_IPPR_TCP 0
+#define MV_IPPR_UDP 1
+#define MV_IPPR_IPIP 2
+#define MV_IPPR_ICMPV6 3
+#define MV_IPPR_IGMP 4
+#define MV_ETH_P_IP 5
+#define MV_ETH_P_IPV6 6
+#define MV_ETH_P_PPP_SES 7
+#define MV_ETH_P_ARP 8
+#define MV_ETH_P_8021Q 9
+#define MV_ETH_P_8021AD 10
+#define MV_ETH_P_EDSA 11
+#define MV_PPP_IP 12
+#define MV_PPP_IPV6 13
+
+#endif /* __MVPP2_LIB_HW__ */