The branch main has been updated by jhibbits:

URL: 
https://cgit.FreeBSD.org/src/commit/?id=5d884fc07662760a2090928e98e51dc8162389a3

commit 5d884fc07662760a2090928e98e51dc8162389a3
Author:     Justin Hibbits <[email protected]>
AuthorDate: 2026-08-13 15:40:49 +0000
Commit:     Justin Hibbits <[email protected]>
CommitDate: 2026-08-25 03:03:08 +0000

    dpaa: Split FMan port driver into distinct TX/RX
    
    There are several port functions that are only for one type or the
    other, so they don't make sense to be together.  Splitting these up also
    simplifies adding support for the Offline/Host Command ports.
---
 sys/conf/files.powerpc       |   2 +
 sys/dev/dpaa/fman_port.c     | 648 ++-----------------------------------------
 sys/dev/dpaa/fman_port_rx.c  | 398 ++++++++++++++++++++++++++
 sys/dev/dpaa/fman_port_tx.c  | 347 +++++++++++++++++++++++
 sys/dev/dpaa/fman_port_var.h |  85 ++++++
 5 files changed, 850 insertions(+), 630 deletions(-)

diff --git a/sys/conf/files.powerpc b/sys/conf/files.powerpc
index 3623a8f15424..06b189b95edb 100644
--- a/sys/conf/files.powerpc
+++ b/sys/conf/files.powerpc
@@ -100,6 +100,8 @@ dev/dpaa/fman_keygen.c              optional        dpaa
 dev/dpaa/fman_mdio.c           optional        dpaa fdt
 dev/dpaa/fman_port_if.m                optional        dpaa
 dev/dpaa/fman_port.c           optional        dpaa
+dev/dpaa/fman_port_rx.c                optional        dpaa
+dev/dpaa/fman_port_tx.c                optional        dpaa
 dev/dpaa/fman_xmdio.c          optional        dpaa fdt mdio miibus
 dev/dpaa/dpaa_common.c         optional        dpaa
 dev/dpaa/if_dtsec.c            optional        dpaa
diff --git a/sys/dev/dpaa/fman_port.c b/sys/dev/dpaa/fman_port.c
index 833be542055e..24ed4ed3ba79 100644
--- a/sys/dev/dpaa/fman_port.c
+++ b/sys/dev/dpaa/fman_port.c
@@ -2,270 +2,61 @@
  * Copyright (c) 2026 Justin Hibbits
  *
  * SPDX-License-Identifier: BSD-2-Clause
+ *
+ * Shared bits of the FMan port drivers.
  */
 
 #include <sys/param.h>
 #include <sys/bus.h>
 #include <sys/kernel.h>
 #include <sys/module.h>
+
 #include <dev/ofw/ofw_bus_subr.h>
 #include <machine/bus.h>
+
 #include "fman.h"
-#include "fman_parser.h"
 #include "fman_port.h"
+#include "fman_port_var.h"
 #include "fman_if.h"
-#include "fman_port_if.h"
-
-struct fman_port_rsrc {
-       uint32_t        num;
-       uint32_t        extra;
-};
-
-#define        MAX_BM_POOLS    64
-struct fman_port_softc {
-       device_t sc_dev;
-       struct resource *sc_mem;
-       int sc_port_id;
-       int sc_port_speed;
-       int sc_port_type;
-
-       int sc_revision_major;
-       int sc_revision_minor;
-
-       int sc_max_frame_length;
-       int sc_bm_max_pools;
-       int sc_max_port_fifo_size;
-       int sc_qman_channel_id;
-
-       int sc_deq_byte_count;
-       int sc_deq_high_priority;
-       int sc_tx_deq_pipeline_depth;
-
-       int sc_default_fqid;
-       int sc_err_fqid;
-       int pcd_base_fqid;
-       int pcd_fqs_count;
-
-       int sc_max_ext_portals;
-       int sc_max_sub_portals;
-
-       struct fman_port_rsrc sc_open_dmas;
-       struct fman_port_rsrc sc_tasks;
-       struct fman_port_rsrc sc_fifo_bufs;
-
-       struct fman_port_buffer_pool sc_bpools[FMAN_PORT_MAX_POOLS];
-};
-
-#define        TX_10G_PORT_BASE        0x30
-#define        RX_10G_PORT_BASE        0x10
-
-#define        FMAN_PORT_TYPE_TX       0
-#define        FMAN_PORT_TYPE_RX       1
-
-#define        PORT_RX         0x01
-#define        PORT_TX         0x02
-#define        PORT_V3         0x04
-
-#define        FMBM_RCFG               0x000
-#define          BMI_PORT_CFG_EN         0x80000000
-#define        FMBM_RST                0x004
-#define        FMBM_RDA                0x008
-#define          RDA_WOPT                0x00100000
-#define        FMBM_RFP                0x00c
-#define        FMBM_RFED               0x010
-#define          BMI_RX_FRAME_END_CUT_SHIFT    16
-#define        FMBM_RICP               0x014   /* Counts are units of 16 bytes 
*/
-#define          RICP_ICEOF_M            0x001f0000
-#define          RICP_ICEOF_S            16
-#define          RICP_ICIOF_M            0x00000f00
-#define          RICP_ICIOF_S            8
-#define          RICP_ICSZ_S             0x0000001f
-#define        FMBM_RIM                0x018
-#define        FMBM_REBM               0x01c
-#define          REBM_BSM_M              0x01ff0000
-#define          REBM_BSM_S              16
-#define          REBM_BEM_M              0x000001ff
-#define        FMBM_RFNE               0x020
-#define        FMBM_RFCA               0x024
-#define          RFCA_OR                 0x80000000
-#define          RFCA_COLOR              0x0c000000
-#define          RFCA_SYNC               0x03000000
-#define          RFCA_SYNC_REQ           0x02000000
-#define          RFCA_MR                 0x003f0000
-#define          RFCA_MR_DEF             0x003c0000
-#define        FMBM_RFPNE              0x028
-#define        FMBM_RETH               0x038
-#define          RETH_ETHE               0x80000000 /* Excessive Threshold 
Enable */
-#define        FMBM_RFQID              0x060
-#define        FMBM_REFQID             0x064
-#define        FMBM_RFSDM              0x068
-#define        FMBM_RFSEM              0x06c
-#define        FMBM_RFENE              0x070
-#define        FMBM_REBMPI(i)          (0x100 + (4 * (i)))
-#define          REBMPI_VAL              0x80000000
-#define          REBMPI_ACE              0x40000000
-#define          REBMPI_BPID_S           16
-#define        FMBM_RSTC               0x0200
-#define          RSTC_EN                 0x80000000
-
-#define        FMBM_TCFG       0x000
-#define        FMBM_TST                0x004
-#define        FMBM_TDA                0x008
-#define        FMBM_TFP                0x00c
-#define          BMI_FIFO_PIPELINE_DEPTH_SHIFT 12
-#define        FMBM_TFED       0x010
-#define        FMBM_TICP       0x014
-#define          TICP_ICEOF_M            0x001f0000
-#define          TICP_ICEOF_S            16
-#define          TICP_ICIOF_M            0x00000f00
-#define          TICP_ICIOF_S            8
-#define          TICP_ICSZ_S             0x0000001f
-#define        FMBM_TFDNE      0x018
-#define        FMBM_TFCA       0x01c
-#define          TFCA_MR_DEF     0
-#define          TFCA_ATTR_ORDER         0x80000000
-#define        FMBM_TCFQID     0x020
-#define        FMBM_TEFQID     0x024
-#define        FMBM_TFENE      0x028
-#define        FMBM_TFNE       0x070
-#define          TFNE_EBD                0x80000000
-
-#define        FMQM_PNC                        0x400
-#define          PNC_EN                          0x80000000
-#define          PNC_STEN                        0x80000000
-#define        FMQM_PNS                        0x404
-#define          PNS_DEQ_FD_BSY                  0x20000000
-#define        FMQM_PNEN                       0x41c
-#define        FMQM_PNDN                       0x42c
-#define        FMQM_PNDC                       0x430
-#define          QMI_DEQ_CFG_PRI                 0x80000000
-#define          QMI_DEQ_CFG_TYPE1               0x10000000
-#define          QMI_DEQ_CFG_TYPE2               0x20000000
-#define          QMI_DEQ_CFG_TYPE3               0x30000000
-#define          QMI_DEQ_CFG_PREFETCH_PARTIAL    0x01000000
-#define          QMI_DEQ_CFG_PREFETCH_FULL       0x03000000
-#define          QMI_DEQ_CFG_SP_MASK             0xf
-#define          QMI_DEQ_CFG_SP_SHIFT            20
-
-#define        HWP_PCAC                0xbf8
-#define          HWP_PCAC_PSTOP          0x00000001
-#define          HWP_HXS_PCAC_PSTAT      0x00000100
-#define        HWP_HXS_SSA(x)          (0x800 + x * 2 * sizeof(uint32_t))
-#define        HWP_HXS_LCV(x)          (0x800 + (x * 2 + 1) * sizeof(uint32_t))
-#define        HWP_HXS_TCP               0xA
-#define        HWP_HXS_UDP               0xB
-#define        HXS_SH_PAD_REM            0x80000000
-#define        HWP_HXS_COUNT           16
-
-#define        PORT_MAX_FRAME_LENGTH   9600
 
-#define        BMI_RX_ERR              (FM_FD_ERR_DMA | FM_FD_ERR_FPE | \
-                                FM_FD_ERR_FSE | FM_FD_ERR_DIS | \
-                                FM_FD_ERR_EOF | FM_FD_ERR_NSS | \
-                                FM_FD_ERR_KSO | FM_FD_ERR_IPP | \
-                                FM_FD_ERR_PTE | FM_FD_ERR_PHE | \
-                                FM_FD_ERR_BLE)
-
-/* Default configurations */
-#define        DEFAULT_RX_CUT_END_BYTES        4
-
-static struct ofw_compat_data compats[] = {
-       { "fsl,fman-v2-port-rx", PORT_RX },
-       { "fsl,fman-v2-port-tx", PORT_TX },
-       { "fsl,fman-v3-port-rx", PORT_V3 | PORT_RX },
-       { "fsl,fman-v3-port-tx", PORT_V3 | PORT_TX },
-       { NULL, 0 }
-};
-
-static int
-fman_port_probe(device_t dev)
-{
-       if (ofw_bus_search_compatible(dev, compats)->ocd_str == NULL)
-               return (ENXIO);
-
-       device_set_desc(dev, "FMan port");
-
-       return (BUS_PROBE_DEFAULT);
-}
-
-static int
-fman_port_attach(device_t dev)
+int
+fman_port_attach_common(device_t dev, struct fman_port_softc *sc,
+    int port_speed)
 {
-       struct fman_port_softc *sc;
        phandle_t node;
        pcell_t cell;
-       uintptr_t compat_data =
-           ofw_bus_search_compatible(dev, compats)->ocd_data;
-       int port_speed = 1000;
-       int port_type;
 
-       sc = device_get_softc(dev);
        sc->sc_dev = dev;
 
        node = ofw_bus_get_node(dev);
        if (OF_getencprop(node, "cell-index", &cell, sizeof(cell)) < 0) {
-               device_printf(dev, "No cell-index property");
+               device_printf(dev, "No cell-index property\n");
                return (ENXIO);
        }
-
        sc->sc_port_id = cell;
 
        sc->sc_mem = bus_alloc_resource_any(dev, SYS_RES_MEMORY, 0,
            RF_ACTIVE | RF_SHAREABLE);
-
        if (sc->sc_mem == NULL) {
-               device_printf(dev, "failed to allocate MMIO");
+               device_printf(dev, "failed to allocate MMIO\n");
                return (ENXIO);
        }
 
        FMAN_GET_REVISION(device_get_parent(dev),
            &sc->sc_revision_major, &sc->sc_revision_minor);
 
-       if ((compat_data & PORT_TX) == PORT_TX)
-               port_type = FMAN_PORT_TYPE_TX;
-       else
-               port_type = FMAN_PORT_TYPE_RX;
-
-       if ((compat_data & PORT_V3) == PORT_V3) {
-               if (OF_hasprop(node, "fsl,fman-10g-port"))
-                       port_speed = 10000;
-       } else {
-               if ((compat_data & PORT_TX) &&
-                   sc->sc_port_id > TX_10G_PORT_BASE)
-                       port_speed = 10000;
-               else if ((compat_data & PORT_RX) &&
-                   sc->sc_port_id > RX_10G_PORT_BASE)
-                       port_speed = 10000;
-       }
-
-       if (sc->sc_port_speed == 10000) {
-               sc->sc_deq_high_priority = true;
-               sc->sc_deq_byte_count = 0x1400;
-       } else {
-               sc->sc_deq_high_priority = false;
-               sc->sc_deq_byte_count = 0x0400;
-       }
-
-       sc->sc_port_type = port_type;
        sc->sc_port_speed = port_speed;
-
        sc->sc_bm_max_pools = MAX_BM_POOLS;
        sc->sc_max_frame_length = PORT_MAX_FRAME_LENGTH;
 
-       if (port_type == FMAN_PORT_TYPE_TX)
-               sc->sc_qman_channel_id =
-                   FMAN_GET_QMAN_CHANNEL_ID(device_get_parent(dev),
-                   sc->sc_port_id);
-
-       OF_device_register_xref(OF_xref_from_node(ofw_bus_get_node(dev)), dev);
+       OF_device_register_xref(OF_xref_from_node(node), dev);
 
        return (0);
 }
 
-static int
-fman_port_detach(device_t dev)
+int
+fman_port_detach_common(device_t dev, struct fman_port_softc *sc)
 {
-       struct fman_port_softc *sc = device_get_softc(dev);
 
        if (sc->sc_mem != NULL)
                bus_release_resource(dev, sc->sc_mem);
@@ -273,16 +64,17 @@ fman_port_detach(device_t dev)
        return (0);
 }
 
-static int
-fman_port_config(device_t dev, struct fman_port_params *params)
+void
+fman_port_config_common(struct fman_port_softc *sc,
+    struct fman_port_params *params)
 {
-       struct fman_port_softc *sc = device_get_softc(dev);
 
        sc->sc_default_fqid = params->dflt_fqid;
        sc->sc_err_fqid = params->err_fqid;
 
        sc->sc_max_port_fifo_size =
-           FMAN_GET_BMI_MAX_FIFO_SIZE(device_get_parent(dev));
+           FMAN_GET_BMI_MAX_FIFO_SIZE(device_get_parent(sc->sc_dev));
+
        switch (sc->sc_revision_major) {
        case 2:
        case 3:
@@ -294,377 +86,6 @@ fman_port_config(device_t dev, struct fman_port_params 
*params)
                sc->sc_max_sub_portals = 16;
                break;
        }
-       if (sc->sc_revision_major >= 6 &&
-           sc->sc_port_type == FMAN_PORT_TYPE_TX && sc->sc_port_speed == 1000)
-               /* Errata A005127 workaround */
-               bus_write_4(sc->sc_mem, FMBM_TFP, 0x00001013);
-
-       sc->sc_tasks.extra = 0;
-
-       switch (sc->sc_port_speed) {
-       case 10000:
-               if (sc->sc_revision_major < 6) {
-                       sc->sc_tasks.num = 16;
-                       if (sc->sc_port_type == FMAN_PORT_TYPE_RX)
-                               sc->sc_tasks.extra = 8;
-               } else
-                       sc->sc_tasks.num = 14;
-               break;
-       case 1000:
-               if (sc->sc_revision_major >= 6)
-                       sc->sc_tasks.num = 4;
-               else {
-                       sc->sc_tasks.num = 3;
-                       if (sc->sc_port_type == FMAN_PORT_TYPE_RX)
-                               sc->sc_tasks.extra = 2;
-               }
-               break;
-       default:
-               sc->sc_tasks.num = 0;
-               break;
-       }
-
-       /* Open DMAs */
-       if (sc->sc_revision_major >= 6) {
-               sc->sc_open_dmas.extra = 0;
-               if (sc->sc_port_speed == 10000) {
-                       if (sc->sc_port_type == FMAN_PORT_TYPE_TX)
-                               sc->sc_open_dmas.num = 12;
-                       else
-                               sc->sc_open_dmas.num = 8;
-               } else {
-                       if (sc->sc_port_type == FMAN_PORT_TYPE_TX)
-                               sc->sc_open_dmas.num = 3;
-                       else
-                               sc->sc_open_dmas.num = 2;
-               }
-       } else {
-               if (sc->sc_port_speed == 10000) {
-                       sc->sc_open_dmas.num = 8;
-                       sc->sc_open_dmas.num = 8;
-               } else {
-                       sc->sc_open_dmas.num = 1;
-                       sc->sc_open_dmas.extra = 1;
-               }
-       }
-
-       /* FIFO bufs */
-       if (sc->sc_revision_major >= 6) {
-               if (sc->sc_port_type == FMAN_PORT_TYPE_TX)
-                       if (sc->sc_port_speed == 10000)
-                               sc->sc_fifo_bufs.num = 64;
-                       else
-                               sc->sc_fifo_bufs.num = 50;
-               else
-                       if (sc->sc_port_speed == 10000)
-                               sc->sc_fifo_bufs.num = 96;
-                       else
-                               sc->sc_fifo_bufs.num = 50;
-       } else {
-               if (sc->sc_port_type == FMAN_PORT_TYPE_TX)
-                       if (sc->sc_port_speed == 10000)
-                               sc->sc_fifo_bufs.num = 48;
-                       else
-                               sc->sc_fifo_bufs.num = 44;
-               else
-                       if (sc->sc_port_speed == 10000)
-                               sc->sc_fifo_bufs.num = 48;
-                       else
-                               sc->sc_fifo_bufs.num = 45;
-       }
-
-       sc->sc_fifo_bufs.extra = 0;
-       sc->sc_fifo_bufs.num *= FMAN_BMI_FIFO_UNITS;
-
-       if (sc->sc_port_type == FMAN_PORT_TYPE_RX)
-               for (int i = 0; i < params->rx_params.num_pools; i++)
-                       sc->sc_bpools[i] = params->rx_params.bpools[i];
-
-       /* TODO: buf_margins?  See fman_sp_build_buffer_struct */
-
-       return (0);
-}
-
-static int
-fman_port_init_bmi_rx(struct fman_port_softc *sc)
-{
-       uint32_t reg;
-
-       /* TODO: Sort the buffer pool list.  */
-       /* TODO: Backup pools */
-       /* TODO: Depletion mode */
-       for (int i = 0; i < FMAN_PORT_MAX_POOLS; i++) {
-               /* Initialize the external pool info */
-               if (sc->sc_bpools[i].size != 0) {
-                       bus_write_4(sc->sc_mem, FMBM_REBMPI(i),
-                           REBMPI_VAL | REBMPI_ACE |
-                           (sc->sc_bpools[i].bpid << REBMPI_BPID_S) |
-                           sc->sc_bpools[i].size);
-               } else
-                       /* Mark invalid if zero */
-                       bus_write_4(sc->sc_mem, FMBM_REBMPI(i), 0);
-       }
-
-       bus_write_4(sc->sc_mem, FMBM_RDA, RDA_WOPT);
-
-       bus_write_4(sc->sc_mem, FMBM_RFCA,
-           RFCA_OR | RFCA_SYNC_REQ | RFCA_MR_DEF);
-
-       bus_write_4(sc->sc_mem, FMBM_RFPNE,
-           NIA_ENG_BMI | NIA_BMI_AC_ENQ_FRAME);
-       bus_write_4(sc->sc_mem, FMBM_RFENE,
-           NIA_ENG_QMI_ENQ | NIA_ORDER_RESTORE);
-
-       bus_write_4(sc->sc_mem, FMBM_RFQID, sc->sc_default_fqid);
-       bus_write_4(sc->sc_mem, FMBM_REFQID, sc->sc_err_fqid);
-
-       if (sc->sc_revision_major < 6)
-               bus_write_4(sc->sc_mem, FMBM_RETH, RETH_ETHE);
-
-       /* Errata A006320 makes CFED field bad */
-       if (sc->sc_revision_major == 6 && (sc->sc_revision_minor == 0))
-               /* These are under errata A006320 */;
-       else
-               bus_write_4(sc->sc_mem, FMBM_RFED,
-                   DEFAULT_RX_CUT_END_BYTES << BMI_RX_FRAME_END_CUT_SHIFT);
-
-       /* Insert internal context ahead of the frame */
-       reg = sizeof(struct fman_internal_context) << REBM_BSM_S;
-       bus_write_4(sc->sc_mem, FMBM_REBM, reg);
-       reg = howmany(FMAN_PARSE_RESULT_OFF, 0x10) << RICP_ICIOF_S;
-       reg |= howmany(sizeof(struct fman_internal_context), 0x10);
-       bus_write_4(sc->sc_mem, FMBM_RICP, reg);
-
-       bus_write_4(sc->sc_mem, FMBM_RFNE, NIA_ENG_HWP);
-       bus_write_4(sc->sc_mem, FMBM_RFSDM, FM_FD_ERR_DIS);
-       bus_write_4(sc->sc_mem, FMBM_RFSEM, BMI_RX_ERR & ~FM_FD_ERR_DIS);
-
-       return (0);
-}
-
-static int
-fman_port_init_bmi_tx(struct fman_port_softc *sc)
-{
-       uint32_t reg;
-       int depth;
-
-       bus_write_4(sc->sc_mem, FMBM_TCFG, 0);
-       bus_write_4(sc->sc_mem, FMBM_TDA, 0);
-       bus_write_4(sc->sc_mem, FMBM_TFED, 0);
-       if (sc->sc_port_speed == 10000)
-               depth = 4;
-       else if (sc->sc_revision_major >= 6)
-               depth = 2;
-       else
-               depth = 1;
-       sc->sc_tx_deq_pipeline_depth = depth;
-       reg = ((depth - 1) << BMI_FIFO_PIPELINE_DEPTH_SHIFT) | 0x13;
-       bus_write_4(sc->sc_mem, FMBM_TFP, reg);
-
-       /* Default color: green */
-       bus_write_4(sc->sc_mem, FMBM_TFCA,
-           TFCA_MR_DEF | TFCA_ATTR_ORDER);
-
-       bus_write_4(sc->sc_mem, FMBM_TFDNE, NIA_ENG_QMI_DEQ);
-       bus_write_4(sc->sc_mem, FMBM_TFENE,
-           NIA_ENG_QMI_ENQ | NIA_ORDER_RESTORE);
-
-       /* Insert internal context ahead of the frame */
-       reg = howmany(FMAN_PARSE_RESULT_OFF, 0x10) << TICP_ICIOF_S;
-       reg |= howmany(sizeof(struct fman_internal_context), 0x10);
-       bus_write_4(sc->sc_mem, FMBM_TICP, reg);
-
-       if (sc->sc_revision_major >= 6)
-               bus_write_4(sc->sc_mem, FMBM_TFNE,
-                   (sc->sc_default_fqid == 0 ? TFNE_EBD : 0) |
-                   NIA_BMI_AC_FETCH_ALLFRAME);
-       bus_write_4(sc->sc_mem, FMBM_TCFQID, sc->sc_default_fqid);
-       bus_write_4(sc->sc_mem, FMBM_TEFQID, sc->sc_err_fqid);
-
-       return (0);
-}
-
-static int
-fman_port_init_hwp(struct fman_port_softc *sc)
-{
-       int i;
-
-       /* Stop the parser so we can initialize it for our uses */
-       bus_write_4(sc->sc_mem, HWP_PCAC, HWP_PCAC_PSTOP);
-
-       for (i = 0; i < 100 &&
-           (bus_read_4(sc->sc_mem, HWP_PCAC) & HWP_HXS_PCAC_PSTAT) != 0; i++) {
-               DELAY(10);
-       }
-       if (i == 100) {
-               device_printf(sc->sc_dev, "Timeout stopping HW parser\n");
-               return (ENXIO);
-       }
-
-       /* set the parser examination config */
-       for (i = 0; i < HWP_HXS_COUNT; i++) {
-               bus_write_4(sc->sc_mem, HWP_HXS_SSA(i), 0);
-               bus_write_4(sc->sc_mem, HWP_HXS_LCV(i), 0xffffffff);
-       }
-       bus_write_4(sc->sc_mem, HWP_HXS_SSA(HWP_HXS_TCP), HXS_SH_PAD_REM);
-       bus_write_4(sc->sc_mem, HWP_HXS_SSA(HWP_HXS_UDP), HXS_SH_PAD_REM);
-
-       /* Re-enable the parser */
-       bus_write_4(sc->sc_mem, HWP_PCAC, 0);
-
-       return (0);
-}
-
-static int
-fman_port_init_qmi(struct fman_port_softc *sc)
-{
-       uint32_t reg;
-
-       if (sc->sc_port_type == FMAN_PORT_TYPE_RX) {
-               bus_write_4(sc->sc_mem, FMQM_PNEN,
-                   NIA_ENG_BMI | NIA_BMI_AC_RELEASE);
-               return (0);
-       }
-
-       /* TX port */
-       bus_write_4(sc->sc_mem, FMQM_PNDN,
-           NIA_ENG_BMI | NIA_BMI_AC_TX);
-       /* TX port */
-       bus_write_4(sc->sc_mem, FMQM_PNEN,
-           NIA_ENG_BMI | NIA_BMI_AC_TX_RELEASE);
-
-       reg = 0;
-
-       if (sc->sc_deq_high_priority)
-               reg |= QMI_DEQ_CFG_PRI;
-
-       reg |= QMI_DEQ_CFG_TYPE1;
-       reg |= QMI_DEQ_CFG_PREFETCH_FULL;
-       reg |= (sc->sc_qman_channel_id & QMI_DEQ_CFG_SP_MASK) << 
QMI_DEQ_CFG_SP_SHIFT;
-       reg |= sc->sc_deq_byte_count;
-       bus_write_4(sc->sc_mem, FMQM_PNDC, reg);
-
-       return (0);
-}
-
-static int
-fman_port_init(device_t dev)
-{
-       struct fman_port_init_params params;
-       struct fman_port_softc *sc = device_get_softc(dev);
-       int err;
-
-       if (sc->sc_port_type == FMAN_PORT_TYPE_RX) {
-               /* Set up RX buffers and fifo */
-       }
-       params.port_id = sc->sc_port_id;
-       params.is_rx_port = (sc->sc_port_type == FMAN_PORT_TYPE_RX);
-       params.num_tasks = sc->sc_tasks.num;
-       params.extra_tasks = sc->sc_tasks.extra;
-       params.open_dmas = sc->sc_open_dmas.num;
-       params.extra_dmas = sc->sc_open_dmas.extra;
-       params.fifo_size = sc->sc_fifo_bufs.num;
-       params.extra_fifo_size = sc->sc_fifo_bufs.extra;
-       params.max_frame_length = sc->sc_max_frame_length;
-       params.deq_pipeline_size = sc->sc_tx_deq_pipeline_depth;
-
-       /* TODO: verify_size_of_fifo() from Linux driver */
-       err = FMAN_SET_PORT_PARAMS(device_get_parent(dev), &params);
-
-       if (err != 0)
-               return (err);
-
-       if (sc->sc_port_type == FMAN_PORT_TYPE_TX)
-               err = fman_port_init_bmi_tx(sc);
-       else {
-               err = fman_port_init_bmi_rx(sc);
-               if (err == 0)
-                       fman_port_init_hwp(sc);
-       }
-
-       if (err != 0)
-               return (err);
-
-       err = fman_port_init_qmi(sc);
-
-       /* TODO: keygen here */
-
-       return (err);
-}
-
-static int
-fman_port_disable(device_t dev)
-{
-       struct fman_port_softc *sc;
-       uint32_t        reg;
-       int             count;
-
-       sc = device_get_softc(dev);
-
-       switch (sc->sc_port_type) {
-       case FMAN_PORT_TYPE_TX:
-               reg = bus_read_4(sc->sc_mem, FMQM_PNC);
-               bus_write_4(sc->sc_mem, FMQM_PNC, reg & ~PNC_EN);
-               for (count = 0; count < 100; count++) {
-                       DELAY(10);
-                       reg = bus_read_4(sc->sc_mem, FMQM_PNS);
-                       if (!(reg & PNS_DEQ_FD_BSY))
-                               break;
-               }
-               if (count == 100)
-                       device_printf(sc->sc_dev, "Timeout stopping QMI\n");
-               reg = bus_read_4(sc->sc_mem, FMBM_TCFG);
-               bus_write_4(sc->sc_mem, FMBM_TCFG, reg & ~BMI_PORT_CFG_EN);
-               for (count = 0; count < 100; count++) {
-                       DELAY(10);
-                       reg = bus_read_4(sc->sc_mem, FMBM_TST);
-                       if (!(reg & PNS_DEQ_FD_BSY))
-                               break;
-               }
-               if (count == 100)
-                       device_printf(sc->sc_dev, "Timeout stopping BMI");
-               break;
-       case FMAN_PORT_TYPE_RX:
-               reg = bus_read_4(sc->sc_mem, FMBM_RCFG);
-               bus_write_4(sc->sc_mem, FMBM_RCFG, reg & ~BMI_PORT_CFG_EN);
-               for (count = 0; count < 100; count++) {
-                       DELAY(10);
-                       reg = bus_read_4(sc->sc_mem, FMBM_RST);
-                       if (!(reg & PNS_DEQ_FD_BSY))
-                               break;
-               }
-               if (count == 100)
-                       device_printf(sc->sc_dev, "Timeout stopping BMI");
-               break;
-       }
-
-       return (0);
-}
-
-static int
-fman_port_enable(device_t dev)
-{
-       struct fman_port_softc *sc;
-       uint32_t        reg;
-
-       sc = device_get_softc(dev);
-       switch (sc->sc_port_type) {
-       case FMAN_PORT_TYPE_TX:
-               reg = bus_read_4(sc->sc_mem, FMQM_PNC);
-               bus_write_4(sc->sc_mem, FMQM_PNC, reg | PNC_EN | PNC_STEN);
-               reg = bus_read_4(sc->sc_mem, FMBM_TCFG);
-               bus_write_4(sc->sc_mem, FMBM_TCFG, reg | BMI_PORT_CFG_EN);
-               break;
-       case FMAN_PORT_TYPE_RX:
-               reg = bus_read_4(sc->sc_mem, FMQM_PNC);
-               bus_write_4(sc->sc_mem, FMQM_PNC, reg | PNC_EN | PNC_STEN);
-               reg = bus_read_4(sc->sc_mem, FMBM_RCFG);
-               bus_write_4(sc->sc_mem, FMBM_RCFG, reg | BMI_PORT_CFG_EN);
-               bus_write_4(sc->sc_mem, FMBM_RSTC, RSTC_EN);
-               break;
-       }
-
-       return (0);
 }
 
 int
@@ -674,36 +95,3 @@ fman_port_get_id(device_t dev)
 
        return (sc->sc_port_id);
 }
-
-/*
- * Runtime toggle for whether the praser sends frames to KeyGen (HWK)
- * or straight to BMI-enqueue.  Called by dpaa_eth after successfully
- * binding a KG scheme to this port -- flipping this without a bound scheme
- * drops all Rx traffic on the port.
- */
-void
-fman_port_rx_use_kg(device_t dev, bool enable)
-{
-       struct fman_port_softc *sc = device_get_softc(dev);
-
-       bus_write_4(sc->sc_mem, FMBM_RFPNE,
-           enable ? NIA_ENG_HWK : (NIA_ENG_BMI | NIA_BMI_AC_ENQ_FRAME));
-}
-
-static device_method_t fman_port_methods[] = {
-       DEVMETHOD(device_probe,         fman_port_probe),
-       DEVMETHOD(device_attach,        fman_port_attach),
-       DEVMETHOD(device_detach,        fman_port_detach),
-
-       DEVMETHOD(fman_port_config,     fman_port_config),
-       DEVMETHOD(fman_port_init,       fman_port_init),
-       DEVMETHOD(fman_port_enable,     fman_port_enable),
-       DEVMETHOD(fman_port_disable,    fman_port_disable),
-
-       DEVMETHOD_END
-};
-
-DEFINE_CLASS_0(fman_port, fman_port_driver, fman_port_methods,
-    sizeof(struct fman_port_softc));
-EARLY_DRIVER_MODULE(fman_port, fman, fman_port_driver, 0, 0,
-    BUS_PASS_SUPPORTDEV + BUS_PASS_ORDER_MIDDLE);
diff --git a/sys/dev/dpaa/fman_port_rx.c b/sys/dev/dpaa/fman_port_rx.c
new file mode 100644
index 000000000000..5499e5e1599d
--- /dev/null
+++ b/sys/dev/dpaa/fman_port_rx.c
@@ -0,0 +1,398 @@
+/*
+ * Copyright (c) 2026 Justin Hibbits
+ *
+ * SPDX-License-Identifier: BSD-2-Clause
+ *
+ * FMan RX port driver.
+ */
+
+#include <sys/param.h>
+#include <sys/bus.h>
+#include <sys/kernel.h>
+#include <sys/module.h>
+
+#include <dev/ofw/ofw_bus.h>
+#include <dev/ofw/ofw_bus_subr.h>
+#include <machine/bus.h>
+
+#include "fman.h"
+#include "fman_parser.h"
+#include "fman_port.h"
+#include "fman_port_var.h"
+#include "fman_if.h"
+#include "fman_port_if.h"
+
+#define        RX_10G_PORT_BASE        0x10
+
+/* BMI Rx registers. */
+#define        FMBM_RCFG               0x000
+#define        FMBM_RST                0x004
+#define        FMBM_RDA                0x008
+#define          RDA_WOPT                0x00100000
+#define        FMBM_RFP                0x00c
+#define        FMBM_RFED               0x010
+#define          BMI_RX_FRAME_END_CUT_SHIFT    16
+#define        FMBM_RICP               0x014   /* Counts are units of 16 bytes 
*/
+#define          RICP_ICEOF_M            0x001f0000
+#define          RICP_ICEOF_S            16
+#define          RICP_ICIOF_M            0x00000f00
+#define          RICP_ICIOF_S            8
+#define          RICP_ICSZ_S             0x0000001f
+#define        FMBM_RIM                0x018
+#define        FMBM_REBM               0x01c
+#define          REBM_BSM_M              0x01ff0000
+#define          REBM_BSM_S              16
+#define          REBM_BEM_M              0x000001ff
+#define        FMBM_RFNE               0x020
+#define        FMBM_RFCA               0x024
+#define          RFCA_OR                 0x80000000
+#define          RFCA_COLOR              0x0c000000
+#define          RFCA_SYNC               0x03000000
+#define          RFCA_SYNC_REQ           0x02000000
+#define          RFCA_MR                 0x003f0000
+#define          RFCA_MR_DEF             0x003c0000
+#define        FMBM_RFPNE              0x028
+#define        FMBM_RETH               0x038
+#define          RETH_ETHE               0x80000000 /* Excessive Threshold 
Enable */
+#define        FMBM_RFQID              0x060
+#define        FMBM_REFQID             0x064
+#define        FMBM_RFSDM              0x068
+#define        FMBM_RFSEM              0x06c
+#define        FMBM_RFENE              0x070
+#define        FMBM_REBMPI(i)          (0x100 + (4 * (i)))
+#define          REBMPI_VAL              0x80000000
+#define          REBMPI_ACE              0x40000000
+#define          REBMPI_BPID_S           16
+#define        FMBM_RSTC               0x0200
+#define          RSTC_EN                 0x80000000
+
+/* Hardware Parser (HWP). */
+#define        HWP_PCAC                0xbf8
+#define          HWP_PCAC_PSTOP          0x00000001
+#define          HWP_HXS_PCAC_PSTAT      0x00000100
+#define        HWP_HXS_SSA(x)          (0x800 + x * 2 * sizeof(uint32_t))
+#define        HWP_HXS_LCV(x)          (0x800 + (x * 2 + 1) * sizeof(uint32_t))
+#define        HWP_HXS_TCP               0xA
+#define        HWP_HXS_UDP               0xB
+#define        HXS_SH_PAD_REM            0x80000000
+#define        HWP_HXS_COUNT           16
+
+#define        BMI_RX_ERR              (FM_FD_ERR_DMA | FM_FD_ERR_FPE |        
\
+                                FM_FD_ERR_FSE | FM_FD_ERR_DIS |        \
+                                FM_FD_ERR_EOF | FM_FD_ERR_NSS |        \
+                                FM_FD_ERR_KSO | FM_FD_ERR_IPP |        \
+                                FM_FD_ERR_PTE | FM_FD_ERR_PHE |        \
+                                FM_FD_ERR_BLE)
+
+#define        DEFAULT_RX_CUT_END_BYTES        4
+
+struct fman_port_rx_softc {
+       struct fman_port_softc sc_base;
+       struct fman_port_buffer_pool sc_bpools[FMAN_PORT_MAX_POOLS];
+};
+
+static struct ofw_compat_data rx_compats[] = {
+       { "fsl,fman-v2-port-rx", 0 },
+       { "fsl,fman-v3-port-rx", PORT_V3 },
+       { NULL, 0 }
+};
+
+static int
+fman_port_rx_probe(device_t dev)
+{
+
+       if (ofw_bus_search_compatible(dev, rx_compats)->ocd_str == NULL)
+               return (ENXIO);
+
+       device_set_desc(dev, "FMan RX port");
+       return (BUS_PROBE_DEFAULT);
+}
+
+static int
+fman_port_rx_attach(device_t dev)
+{
+       struct fman_port_rx_softc *sc;
+       uintptr_t compat_data;
+       int port_speed;
+
+       sc = device_get_softc(dev);
+       compat_data = ofw_bus_search_compatible(dev, rx_compats)->ocd_data;
+
+       port_speed = 1000;
+       if ((compat_data & PORT_V3) == PORT_V3) {
+               if (OF_hasprop(ofw_bus_get_node(dev), "fsl,fman-10g-port"))
+                       port_speed = 10000;
+       } else {
+               int cell = 0;
+               OF_getencprop(ofw_bus_get_node(dev), "cell-index", &cell,
+                   sizeof(cell));
+               if (cell > RX_10G_PORT_BASE)
+                       port_speed = 10000;
+       }
+
+       return (fman_port_attach_common(dev, &sc->sc_base, port_speed));
+}
+
+static int
+fman_port_rx_detach(device_t dev)
+{
+       struct fman_port_rx_softc *sc = device_get_softc(dev);
+
+       return (fman_port_detach_common(dev, &sc->sc_base));
+}
+
+static int
+fman_port_rx_config(device_t dev, struct fman_port_params *params)
+{
+       struct fman_port_rx_softc *sc = device_get_softc(dev);
+       struct fman_port_softc *base = &sc->sc_base;
+
+       fman_port_config_common(base, params);
+
+       base->sc_tasks.extra = 0;
+       switch (base->sc_port_speed) {
+       case 10000:
+               if (base->sc_revision_major < 6) {
+                       base->sc_tasks.num = 16;
+                       base->sc_tasks.extra = 8;
+               } else
+                       base->sc_tasks.num = 14;
+               break;
+       case 1000:
+               if (base->sc_revision_major >= 6)
+                       base->sc_tasks.num = 4;
+               else {
+                       base->sc_tasks.num = 3;
+                       base->sc_tasks.extra = 2;
+               }
+               break;
+       default:
+               base->sc_tasks.num = 0;
+               break;
+       }
+
+       if (base->sc_revision_major >= 6) {
+               base->sc_open_dmas.extra = 0;
+               base->sc_open_dmas.num =
+                   (base->sc_port_speed == 10000) ? 8 : 2;
+       } else if (base->sc_port_speed == 10000) {
+               base->sc_open_dmas.num = 8;
+               base->sc_open_dmas.extra = 8;
+       } else {
+               base->sc_open_dmas.num = 1;
+               base->sc_open_dmas.extra = 1;
+       }
+
+       if (base->sc_revision_major >= 6)
+               base->sc_fifo_bufs.num =
+                   (base->sc_port_speed == 10000) ? 96 : 50;
+       else
+               base->sc_fifo_bufs.num =
+                   (base->sc_port_speed == 10000) ? 48 : 45;
+       base->sc_fifo_bufs.extra = 0;
+       base->sc_fifo_bufs.num *= FMAN_BMI_FIFO_UNITS;
+
+       for (int i = 0; i < params->rx_params.num_pools; i++)
+               sc->sc_bpools[i] = params->rx_params.bpools[i];
+
+       /* TODO: buf_margins?  See fman_sp_build_buffer_struct */
+       return (0);
+}
+
+static int
+fman_port_rx_init_bmi(struct fman_port_rx_softc *sc)
+{
+       struct fman_port_softc *base = &sc->sc_base;
+       uint32_t reg;
+
+       /* TODO: Sort the buffer pool list.  */
+       /* TODO: Backup pools */
+       /* TODO: Depletion mode */
+       for (int i = 0; i < FMAN_PORT_MAX_POOLS; i++) {
+               if (sc->sc_bpools[i].size != 0) {
+                       bus_write_4(base->sc_mem, FMBM_REBMPI(i),
+                           REBMPI_VAL | REBMPI_ACE |
+                           (sc->sc_bpools[i].bpid << REBMPI_BPID_S) |
+                           sc->sc_bpools[i].size);
+               } else
+                       bus_write_4(base->sc_mem, FMBM_REBMPI(i), 0);
+       }
+
*** 622 LINES SKIPPED ***

Reply via email to