diff --git a/share/man/man4/man4.aarch64/Makefile b/share/man/man4/man4.aarch64/Makefile index ef5fcd84ccd4..6d0e427e6b28 100644 --- a/share/man/man4/man4.aarch64/Makefile +++ b/share/man/man4/man4.aarch64/Makefile @@ -1,27 +1,28 @@ # $FreeBSD$ .PATH: ${.CURDIR}/../man4.arm # Some manpages are common to arm and aarch64 MAN= \ armv8crypto.4 \ aw_gpio.4 \ aw_mmc.4 \ aw_rtc.4 \ aw_sid.4 \ aw_spi.4 \ aw_syscon.4 \ bcm283x_pwm.4 \ enetc.4 \ + felix.4 \ rk_gpio.4 \ rk_grf.4 \ rk_i2c.4 \ rk_pinctrl.4 \ # Link files to the parent directory .for _manpage in ${MAN} MLINKS+=${_manpage} ../${_manpage} .endfor MANSUBDIR=/aarch64 .include diff --git a/share/man/man4/man4.aarch64/felix.4 b/share/man/man4/man4.aarch64/felix.4 new file mode 100644 index 000000000000..738309a4cc84 --- /dev/null +++ b/share/man/man4/man4.aarch64/felix.4 @@ -0,0 +1,83 @@ +.\" - +.\" SPDX-License-Identifier: BSD-2-Clause-FreeBSD +.\" +.\" Copyright (c) 2021 Alstom Group. +.\" Copyright (c) 2021 Semihalf. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. 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. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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. +.\" +.Dd June 21, 2021 +.Dt FELIX 4 +.Os +.Sh NAME +.Nm felix +.Nd "driver for Microchip Ocelot Felix switch" +.Sh SYNOPSIS +To compile this driver into the kernel the following lines must be present +in the kernel configuration file: +.sp +.Cd "options SOC_NXP_LS" +.Cd "device pci" +.Cd "device fdt" +.Cd "device mdio" +.Cd "device enetc" +.Cd "device etherswitch" +.Cd "device felix" +.Sh DESCRIPTION +The +.Nm +driver provides a management interface to Microchip Ocelot Felix switch (VSC9959) +found in NXP LS1028A SoC. It is a PCI device, part of the larger ENETC +root complex. The driver is using +.Xr etherswitch 4 +framework. +.Pp +This driver supports only dot1q vlan. dot1q support port base addtag, striptag, +dropuntagged, dropuntagged. +.Sh EXAMPLES +Configure dot1q vlan by etherswitchcfg command. +.Pp +.Dl # etherswitchcfg config vlan_mode dot1q +.Pp +Configure port 5 is tagging port. +.Pp +.Dl # etherswitchcfg port5 addtag +.Pp +Disable port 5 is tagging port. +.Pp +.Dl # etherswitchcfg port5 -addtag +.Sh SEE ALSO +.Xr etherswitch 4 , +.Xr etherswitchcfg 8 +.Sh HISTORY +The +.Nm +device driver first appeared in +.Fx 14.0 . +.Sh AUTHORS +The +.Nm +driver was written by +.An Kornel Duleba (mindal@semihalf.com) +and +.An Lukasz Hajec (lha@semihalf.com) + diff --git a/sys/conf/files.arm64 b/sys/conf/files.arm64 index 3bc534073634..bfa03dade1db 100644 --- a/sys/conf/files.arm64 +++ b/sys/conf/files.arm64 @@ -1,586 +1,588 @@ # $FreeBSD$ ## ## Kernel ## kern/msi_if.m optional intrng kern/pic_if.m optional intrng kern/subr_devmap.c standard kern/subr_intr.c optional intrng kern/subr_physmem.c standard libkern/bcmp.c standard libkern/memcmp.c standard \ compile-with "${NORMAL_C:N-fsanitize*}" libkern/memset.c standard \ compile-with "${NORMAL_C:N-fsanitize*}" libkern/strlen.c standard libkern/arm64/crc32c_armv8.S standard arm/arm/generic_timer.c standard arm/arm/gic.c standard arm/arm/gic_acpi.c optional acpi arm/arm/gic_fdt.c optional fdt arm/arm/pmu.c standard arm/arm/pmu_fdt.c optional fdt arm64/acpica/acpi_iort.c optional acpi arm64/acpica/acpi_machdep.c optional acpi arm64/acpica/OsdEnvironment.c optional acpi arm64/acpica/acpi_wakeup.c optional acpi arm64/acpica/pci_cfgreg.c optional acpi pci arm64/arm64/autoconf.c standard arm64/arm64/bus_machdep.c standard arm64/arm64/bus_space_asm.S standard arm64/arm64/busdma_bounce.c standard arm64/arm64/busdma_machdep.c standard arm64/arm64/bzero.S standard arm64/arm64/clock.c standard arm64/arm64/copyinout.S standard arm64/arm64/cpu_errata.c standard arm64/arm64/cpufunc_asm.S standard arm64/arm64/db_disasm.c optional ddb arm64/arm64/db_interface.c optional ddb arm64/arm64/db_trace.c optional ddb arm64/arm64/debug_monitor.c standard arm64/arm64/disassem.c optional ddb arm64/arm64/dump_machdep.c standard arm64/arm64/efirt_machdep.c optional efirt arm64/arm64/elf32_machdep.c optional compat_freebsd32 arm64/arm64/elf_machdep.c standard arm64/arm64/exception.S standard arm64/arm64/freebsd32_machdep.c optional compat_freebsd32 arm64/arm64/gdb_machdep.c optional gdb arm64/arm64/gicv3_its.c optional intrng fdt arm64/arm64/gic_v3.c standard arm64/arm64/gic_v3_acpi.c optional acpi arm64/arm64/gic_v3_fdt.c optional fdt arm64/arm64/identcpu.c standard arm64/arm64/in_cksum.c optional inet | inet6 arm64/arm64/locore.S standard no-obj arm64/arm64/machdep.c standard arm64/arm64/machdep_boot.c standard arm64/arm64/mem.c standard arm64/arm64/memcpy.S standard arm64/arm64/memmove.S standard arm64/arm64/minidump_machdep.c standard arm64/arm64/mp_machdep.c optional smp arm64/arm64/nexus.c standard arm64/arm64/ofw_machdep.c optional fdt arm64/arm64/pmap.c standard arm64/arm64/stack_machdep.c optional ddb | stack arm64/arm64/support.S standard arm64/arm64/swtch.S standard arm64/arm64/sys_machdep.c standard arm64/arm64/trap.c standard arm64/arm64/uio_machdep.c standard arm64/arm64/uma_machdep.c standard arm64/arm64/undefined.c standard arm64/arm64/unwind.c optional ddb | kdtrace_hooks | stack arm64/arm64/vfp.c standard arm64/arm64/vm_machdep.c standard arm64/coresight/coresight.c standard arm64/coresight/coresight_acpi.c optional acpi arm64/coresight/coresight_fdt.c optional fdt arm64/coresight/coresight_if.m standard arm64/coresight/coresight_cmd.c standard arm64/coresight/coresight_cpu_debug.c standard arm64/coresight/coresight_etm4x.c standard arm64/coresight/coresight_etm4x_acpi.c optional acpi arm64/coresight/coresight_etm4x_fdt.c optional fdt arm64/coresight/coresight_funnel.c standard arm64/coresight/coresight_funnel_acpi.c optional acpi arm64/coresight/coresight_funnel_fdt.c optional fdt arm64/coresight/coresight_replicator.c standard arm64/coresight/coresight_replicator_acpi.c optional acpi arm64/coresight/coresight_replicator_fdt.c optional fdt arm64/coresight/coresight_tmc.c standard arm64/coresight/coresight_tmc_acpi.c optional acpi arm64/coresight/coresight_tmc_fdt.c optional fdt arm64/iommu/iommu.c optional iommu arm64/iommu/iommu_if.m optional iommu arm64/iommu/iommu_pmap.c optional iommu arm64/iommu/smmu.c optional iommu arm64/iommu/smmu_acpi.c optional acpi iommu arm64/iommu/smmu_quirks.c optional iommu dev/iommu/busdma_iommu.c optional iommu dev/iommu/iommu_gas.c optional iommu crypto/armv8/armv8_crypto.c optional armv8crypto armv8_crypto_wrap.o optional armv8crypto \ dependency "$S/crypto/armv8/armv8_crypto_wrap.c" \ compile-with "${CC} -c ${CFLAGS:C/^-O2$/-O3/:N-nostdinc:N-mgeneral-regs-only} -I$S/crypto/armv8/ ${WERROR} ${NO_WCAST_QUAL} -march=armv8-a+crypto ${.IMPSRC}" \ no-implicit-rule \ clean "armv8_crypto_wrap.o" aesv8-armx.o optional armv8crypto \ dependency "$S/crypto/openssl/aarch64/aesv8-armx.S" \ compile-with "${CC} -c ${CFLAGS:C/^-O2$/-O3/:N-nostdinc:N-mgeneral-regs-only} -I$S/crypto/armv8/ -I$S/crypto/openssl/crypto ${WERROR} ${NO_WCAST_QUAL} -march=armv8-a+crypto ${.IMPSRC}" \ no-implicit-rule \ clean "aesv8-armx.o" ghashv8-armx.o optional armv8crypto \ dependency "$S/crypto/openssl/aarch64/ghashv8-armx.S" \ compile-with "${CC} -c ${CFLAGS:C/^-O2$/-O3/:N-nostdinc:N-mgeneral-regs-only} -I$S/crypto/armv8/ -I$S/crypto/openssl/crypto ${WERROR} ${NO_WCAST_QUAL} -march=armv8-a+crypto ${.IMPSRC}" \ no-implicit-rule \ clean "ghashv8-armx.o" crypto/des/des_enc.c optional netsmb crypto/openssl/ossl_aarch64.c optional ossl crypto/openssl/aarch64/chacha-armv8.S optional ossl \ compile-with "${CC} -c ${CFLAGS:N-mgeneral-regs-only} ${WERROR} ${.IMPSRC}" crypto/openssl/aarch64/poly1305-armv8.S optional ossl \ compile-with "${CC} -c ${CFLAGS:N-mgeneral-regs-only} ${WERROR} ${.IMPSRC}" crypto/openssl/aarch64/sha1-armv8.S optional ossl \ compile-with "${CC} -c ${CFLAGS:N-mgeneral-regs-only} ${WERROR} ${.IMPSRC}" crypto/openssl/aarch64/sha256-armv8.S optional ossl \ compile-with "${CC} -c ${CFLAGS:N-mgeneral-regs-only} ${WERROR} ${.IMPSRC}" crypto/openssl/aarch64/sha512-armv8.S optional ossl \ compile-with "${CC} -c ${CFLAGS:N-mgeneral-regs-only} ${WERROR} ${.IMPSRC}" dev/acpica/acpi_bus_if.m optional acpi dev/acpica/acpi_if.m optional acpi dev/acpica/acpi_pci_link.c optional acpi pci dev/acpica/acpi_pcib.c optional acpi pci dev/acpica/acpi_pxm.c optional acpi dev/ahci/ahci_generic.c optional ahci cddl/dev/dtrace/aarch64/dtrace_asm.S optional dtrace compile-with "${DTRACE_S}" cddl/dev/dtrace/aarch64/dtrace_subr.c optional dtrace compile-with "${DTRACE_C}" cddl/dev/fbt/aarch64/fbt_isa.c optional dtrace_fbt | dtraceall compile-with "${FBT_C}" ## ## ASoC support ## dev/sound/fdt/audio_dai_if.m optional sound fdt dev/sound/fdt/audio_soc.c optional sound fdt dev/sound/fdt/dummy_codec.c optional sound fdt dev/sound/fdt/simple_amplifier.c optional sound fdt ## ## Device drivers ## dev/axgbe/if_axgbe.c optional axa dev/axgbe/xgbe-desc.c optional axa dev/axgbe/xgbe-dev.c optional axa dev/axgbe/xgbe-drv.c optional axa dev/axgbe/xgbe-mdio.c optional axa dev/axgbe/xgbe-sysctl.c optional axa dev/axgbe/xgbe-txrx.c optional axa dev/axgbe/xgbe_osdep.c optional axa dev/axgbe/xgbe-phy-v1.c optional axa dev/cpufreq/cpufreq_dt.c optional cpufreq fdt dev/dwc/if_dwc.c optional fdt dwc_rk soc_rockchip_rk3328 | fdt dwc_rk soc_rockchip_rk3399 | fdt dwc_socfpga soc_intel_stratix10 dev/dwc/if_dwc_if.m optional fdt dwc_rk soc_rockchip_rk3328 | fdt dwc_rk soc_rockchip_rk3399 | fdt dwc_socfpga soc_intel_stratix10 dev/enetc/enetc_mdio.c optional enetc soc_nxp_ls dev/enetc/enetc_mdio_pci.c optional enetc pci soc_nxp_ls dev/enetc/if_enetc.c optional enetc iflib pci fdt soc_nxp_ls +dev/etherswitch/felix/felix.c optional enetc etherswitch fdt felix pci soc_nxp_ls + dev/gpio/pl061.c optional pl061 gpio dev/gpio/pl061_acpi.c optional pl061 gpio acpi dev/gpio/pl061_fdt.c optional pl061 gpio fdt dev/gpio/qoriq_gpio.c optional SOC_NXP_LS gpio fdt dev/hwpmc/hwpmc_arm64.c optional hwpmc dev/hwpmc/hwpmc_arm64_md.c optional hwpmc dev/ice/if_ice_iflib.c optional ice pci \ compile-with "${NORMAL_C} -I$S/dev/ice" dev/ice/ice_lib.c optional ice pci \ compile-with "${NORMAL_C} -I$S/dev/ice" dev/ice/ice_osdep.c optional ice pci \ compile-with "${NORMAL_C} -I$S/dev/ice" dev/ice/ice_resmgr.c optional ice pci \ compile-with "${NORMAL_C} -I$S/dev/ice" dev/ice/ice_strings.c optional ice pci \ compile-with "${NORMAL_C} -I$S/dev/ice" dev/ice/ice_iflib_recovery_txrx.c optional ice pci \ compile-with "${NORMAL_C} -I$S/dev/ice" dev/ice/ice_iflib_txrx.c optional ice pci \ compile-with "${NORMAL_C} -I$S/dev/ice" dev/ice/ice_common.c optional ice pci \ compile-with "${NORMAL_C} -I$S/dev/ice" dev/ice/ice_controlq.c optional ice pci \ compile-with "${NORMAL_C} -I$S/dev/ice" dev/ice/ice_dcb.c optional ice pci \ compile-with "${NORMAL_C} -I$S/dev/ice" dev/ice/ice_flex_pipe.c optional ice pci \ compile-with "${NORMAL_C} -I$S/dev/ice" dev/ice/ice_flow.c optional ice pci \ compile-with "${NORMAL_C} -I$S/dev/ice" dev/ice/ice_nvm.c optional ice pci \ compile-with "${NORMAL_C} -I$S/dev/ice" dev/ice/ice_sched.c optional ice pci \ compile-with "${NORMAL_C} -I$S/dev/ice" dev/ice/ice_sriov.c optional ice pci \ compile-with "${NORMAL_C} -I$S/dev/ice" dev/ice/ice_switch.c optional ice pci \ compile-with "${NORMAL_C} -I$S/dev/ice" dev/ice/ice_vlan_mode.c optional ice pci \ compile-with "${NORMAL_C} -I$S/dev/ice" ice_ddp.c optional ice_ddp \ compile-with "${AWK} -f $S/tools/fw_stub.awk ice_ddp.fw:ice_ddp:0x01031800 -mice_ddp -c${.TARGET}" \ no-ctfconvert no-implicit-rule before-depend local \ clean "ice_ddp.c" ice_ddp.fwo optional ice_ddp \ dependency "ice_ddp.fw" \ compile-with "${NORMAL_FWO}" \ no-implicit-rule \ clean "ice_ddp.fwo" ice_ddp.fw optional ice_ddp \ dependency "$S/contrib/dev/ice/ice-1.3.24.0.pkg" \ compile-with "${CP} $S/contrib/dev/ice/ice-1.3.24.0.pkg ice_ddp.fw" \ no-obj no-implicit-rule \ clean "ice_ddp.fw" dev/iicbus/sy8106a.c optional sy8106a fdt dev/iicbus/twsi/mv_twsi.c optional twsi fdt dev/iicbus/twsi/a10_twsi.c optional twsi fdt dev/iicbus/twsi/twsi.c optional twsi fdt dev/ipmi/ipmi.c optional ipmi dev/ipmi/ipmi_acpi.c optional ipmi acpi dev/ipmi/ipmi_kcs.c optional ipmi dev/ipmi/ipmi_smic.c optional ipmi dev/mbox/mbox_if.m optional soc_brcm_bcm2837 dev/mmc/host/dwmmc.c optional dwmmc fdt dev/mmc/host/dwmmc_altera.c optional dwmmc dwmmc_altera fdt dev/mmc/host/dwmmc_hisi.c optional dwmmc dwmmc_hisi fdt dev/mmc/host/dwmmc_rockchip.c optional dwmmc rk_dwmmc fdt dev/neta/if_mvneta_fdt.c optional neta fdt dev/neta/if_mvneta.c optional neta mdio mii dev/ofw/ofw_cpu.c optional fdt dev/ofw/ofw_pci.c optional fdt pci dev/ofw/ofw_pcib.c optional fdt pci dev/pci/controller/pci_n1sdp.c optional pci_n1sdp acpi dev/pci/pci_host_generic.c optional pci dev/pci/pci_host_generic_acpi.c optional pci acpi dev/pci/pci_host_generic_fdt.c optional pci fdt dev/pci/pci_dw_mv.c optional pci fdt dev/pci/pci_dw.c optional pci fdt dev/pci/pci_dw_if.m optional pci fdt dev/psci/psci.c standard dev/psci/smccc_arm64.S standard dev/psci/smccc.c standard dev/safexcel/safexcel.c optional safexcel fdt dev/sdhci/sdhci_xenon.c optional sdhci_xenon sdhci fdt dev/uart/uart_cpu_arm64.c optional uart dev/uart/uart_dev_mu.c optional uart uart_mu dev/uart/uart_dev_pl011.c optional uart pl011 dev/usb/controller/dwc_otg_hisi.c optional dwcotg fdt soc_hisi_hi6220 dev/usb/controller/dwc3.c optional fdt dwc3 dev/usb/controller/ehci_mv.c optional ehci_mv fdt dev/usb/controller/generic_ehci.c optional ehci dev/usb/controller/generic_ehci_acpi.c optional ehci acpi dev/usb/controller/generic_ehci_fdt.c optional ehci fdt dev/usb/controller/generic_ohci.c optional ohci fdt dev/usb/controller/generic_usb_if.m optional ohci fdt dev/usb/controller/musb_otg_allwinner.c optional musb fdt soc_allwinner_a64 dev/usb/controller/usb_nop_xceiv.c optional fdt ext_resources dev/usb/controller/generic_xhci.c optional xhci dev/usb/controller/generic_xhci_acpi.c optional xhci acpi dev/usb/controller/generic_xhci_fdt.c optional xhci fdt dev/vnic/mrml_bridge.c optional vnic fdt dev/vnic/nic_main.c optional vnic pci dev/vnic/nicvf_main.c optional vnic pci pci_iov dev/vnic/nicvf_queues.c optional vnic pci pci_iov dev/vnic/thunder_bgx_fdt.c optional soc_cavm_thunderx pci vnic fdt dev/vnic/thunder_bgx.c optional soc_cavm_thunderx pci vnic pci dev/vnic/thunder_mdio_fdt.c optional soc_cavm_thunderx pci vnic fdt dev/vnic/thunder_mdio.c optional soc_cavm_thunderx pci vnic dev/vnic/lmac_if.m optional inet | inet6 | vnic ## ## SoC Support ## # Allwinner common files arm/allwinner/a10_timer.c optional a10_timer fdt arm/allwinner/a10_codec.c optional sound a10_codec arm/allwinner/a31_dmac.c optional a31_dmac arm/allwinner/a33_codec.c optional fdt sound a33_codec arm/allwinner/a64/sun50i_a64_acodec.c optional fdt sound a64_codec arm/allwinner/sunxi_dma_if.m optional a31_dmac arm/allwinner/aw_cir.c optional evdev aw_cir fdt arm/allwinner/aw_dwc3.c optional aw_dwc3 fdt arm/allwinner/aw_i2s.c optional fdt sound aw_i2s arm/allwinner/aw_gpio.c optional gpio aw_gpio fdt arm/allwinner/aw_mmc.c optional mmc aw_mmc fdt | mmccam aw_mmc fdt arm/allwinner/aw_nmi.c optional aw_nmi fdt \ compile-with "${NORMAL_C} -I$S/contrib/device-tree/include" arm/allwinner/aw_pwm.c optional aw_pwm fdt arm/allwinner/aw_r_intc.c optional aw_r_intc fdt arm/allwinner/aw_rsb.c optional aw_rsb fdt arm/allwinner/aw_rtc.c optional aw_rtc fdt arm/allwinner/aw_sid.c optional aw_sid nvmem fdt arm/allwinner/aw_spi.c optional aw_spi fdt arm/allwinner/aw_syscon.c optional aw_syscon ext_resources syscon fdt arm/allwinner/aw_thermal.c optional aw_thermal nvmem fdt arm/allwinner/aw_usbphy.c optional ehci aw_usbphy fdt arm/allwinner/aw_usb3phy.c optional xhci aw_usbphy fdt arm/allwinner/aw_wdog.c optional aw_wdog fdt arm/allwinner/axp81x.c optional axp81x fdt arm/allwinner/if_awg.c optional awg ext_resources syscon aw_sid nvmem fdt # Allwinner clock driver arm/allwinner/clkng/aw_ccung.c optional aw_ccu fdt arm/allwinner/clkng/aw_clk_frac.c optional aw_ccu fdt arm/allwinner/clkng/aw_clk_m.c optional aw_ccu fdt arm/allwinner/clkng/aw_clk_mipi.c optional aw_ccu fdt arm/allwinner/clkng/aw_clk_nkmp.c optional aw_ccu fdt arm/allwinner/clkng/aw_clk_nm.c optional aw_ccu fdt arm/allwinner/clkng/aw_clk_nmm.c optional aw_ccu fdt arm/allwinner/clkng/aw_clk_np.c optional aw_ccu fdt arm/allwinner/clkng/aw_clk_prediv_mux.c optional aw_ccu fdt arm/allwinner/clkng/ccu_a64.c optional soc_allwinner_a64 aw_ccu fdt arm/allwinner/clkng/ccu_h3.c optional soc_allwinner_h5 aw_ccu fdt arm/allwinner/clkng/ccu_h6.c optional soc_allwinner_h6 aw_ccu fdt arm/allwinner/clkng/ccu_h6_r.c optional soc_allwinner_h6 aw_ccu fdt arm/allwinner/clkng/ccu_sun8i_r.c optional aw_ccu fdt arm/allwinner/clkng/ccu_de2.c optional aw_ccu fdt # Allwinner padconf files arm/allwinner/a64/a64_padconf.c optional soc_allwinner_a64 fdt arm/allwinner/a64/a64_r_padconf.c optional soc_allwinner_a64 fdt arm/allwinner/h3/h3_padconf.c optional soc_allwinner_h5 fdt arm/allwinner/h3/h3_r_padconf.c optional soc_allwinner_h5 fdt arm/allwinner/h6/h6_padconf.c optional soc_allwinner_h6 fdt arm/allwinner/h6/h6_r_padconf.c optional soc_allwinner_h6 fdt # Altera/Intel dev/altera/dwc/if_dwc_socfpga.c optional fdt dwc_socfpga arm64/intel/firmware.c optional soc_intel_stratix10 arm64/intel/stratix10-soc-fpga-mgr.c optional soc_intel_stratix10 arm64/intel/stratix10-svc.c optional soc_intel_stratix10 # Annapurna arm/annapurna/alpine/alpine_ccu.c optional al_ccu fdt arm/annapurna/alpine/alpine_nb_service.c optional al_nb_service fdt arm/annapurna/alpine/alpine_pci.c optional al_pci fdt arm/annapurna/alpine/alpine_pci_msix.c optional al_pci fdt arm/annapurna/alpine/alpine_serdes.c optional al_serdes fdt \ no-depend \ compile-with "${CC} -c -o ${.TARGET} ${CFLAGS} -I$S/contrib/alpine-hal -I$S/contrib/alpine-hal/eth ${.IMPSRC}" # Broadcom arm64/broadcom/brcmmdio/mdio_mux_iproc.c optional soc_brcm_ns2 fdt arm64/broadcom/brcmmdio/mdio_nexus_iproc.c optional soc_brcm_ns2 fdt arm64/broadcom/brcmmdio/mdio_ns2_pcie_phy.c optional soc_brcm_ns2 fdt pci arm64/broadcom/genet/if_genet.c optional SOC_BRCM_BCM2838 fdt genet arm/broadcom/bcm2835/bcm2835_audio.c optional sound vchiq fdt \ compile-with "${NORMAL_C} -DUSE_VCHIQ_ARM -D__VCCOREVER__=0x04000000 -I$S/contrib/vchiq" arm/broadcom/bcm2835/bcm2835_bsc.c optional bcm2835_bsc fdt arm/broadcom/bcm2835/bcm2835_clkman.c optional soc_brcm_bcm2837 fdt | soc_brcm_bcm2838 fdt arm/broadcom/bcm2835/bcm2835_cpufreq.c optional soc_brcm_bcm2837 fdt | soc_brcm_bcm2838 fdt arm/broadcom/bcm2835/bcm2835_dma.c optional soc_brcm_bcm2837 fdt | soc_brcm_bcm2838 fdt arm/broadcom/bcm2835/bcm2835_fbd.c optional vt soc_brcm_bcm2837 fdt | vt soc_brcm_bcm2838 fdt arm/broadcom/bcm2835/bcm2835_firmware.c optional soc_brcm_bcm2837 fdt | soc_brcm_bcm2838 fdt arm/broadcom/bcm2835/bcm2835_ft5406.c optional evdev bcm2835_ft5406 fdt arm/broadcom/bcm2835/bcm2835_gpio.c optional gpio soc_brcm_bcm2837 fdt | gpio soc_brcm_bcm2838 fdt arm/broadcom/bcm2835/bcm2835_intr.c optional soc_brcm_bcm2837 fdt | soc_brcm_bcm2838 fdt arm/broadcom/bcm2835/bcm2835_mbox.c optional soc_brcm_bcm2837 fdt | soc_brcm_bcm2838 fdt arm/broadcom/bcm2835/bcm2835_rng.c optional !random_loadable soc_brcm_bcm2837 fdt | !random_loadable soc_brcm_bcm2838 fdt arm/broadcom/bcm2835/bcm2835_sdhci.c optional sdhci soc_brcm_bcm2837 fdt | sdhci soc_brcm_bcm2838 fdt arm/broadcom/bcm2835/bcm2835_sdhost.c optional sdhci soc_brcm_bcm2837 fdt | sdhci soc_brcm_bcm2838 fdt arm/broadcom/bcm2835/bcm2835_spi.c optional bcm2835_spi fdt arm/broadcom/bcm2835/bcm2835_vcbus.c optional soc_brcm_bcm2837 fdt | soc_brcm_bcm2838 fdt arm/broadcom/bcm2835/bcm2835_vcio.c optional soc_brcm_bcm2837 fdt | soc_brcm_bcm2838 fdt arm/broadcom/bcm2835/bcm2835_wdog.c optional soc_brcm_bcm2837 fdt | soc_brcm_bcm2838 fdt arm/broadcom/bcm2835/bcm2836.c optional soc_brcm_bcm2837 fdt | soc_brcm_bcm2838 fdt arm/broadcom/bcm2835/bcm283x_dwc_fdt.c optional dwcotg fdt soc_brcm_bcm2837 | dwcotg fdt soc_brcm_bcm2838 arm/broadcom/bcm2835/bcm2838_pci.c optional soc_brcm_bcm2838 fdt pci arm/broadcom/bcm2835/bcm2838_xhci.c optional soc_brcm_bcm2838 fdt pci xhci arm/broadcom/bcm2835/raspberrypi_gpio.c optional soc_brcm_bcm2837 gpio | soc_brcm_bcm2838 gpio contrib/vchiq/interface/compat/vchi_bsd.c optional vchiq soc_brcm_bcm2837 \ compile-with "${NORMAL_C} -DUSE_VCHIQ_ARM -D__VCCOREVER__=0x04000000 -I$S/contrib/vchiq" contrib/vchiq/interface/vchiq_arm/vchiq_2835_arm.c optional vchiq soc_brcm_bcm2837 \ compile-with "${NORMAL_C} -Wno-unused -DUSE_VCHIQ_ARM -D__VCCOREVER__=0x04000000 -I$S/contrib/vchiq" contrib/vchiq/interface/vchiq_arm/vchiq_arm.c optional vchiq soc_brcm_bcm2837 \ compile-with "${NORMAL_C} -Wno-unused -DUSE_VCHIQ_ARM -D__VCCOREVER__=0x04000000 -I$S/contrib/vchiq" contrib/vchiq/interface/vchiq_arm/vchiq_connected.c optional vchiq soc_brcm_bcm2837 \ compile-with "${NORMAL_C} -DUSE_VCHIQ_ARM -D__VCCOREVER__=0x04000000 -I$S/contrib/vchiq" contrib/vchiq/interface/vchiq_arm/vchiq_core.c optional vchiq soc_brcm_bcm2837 \ compile-with "${NORMAL_C} -DUSE_VCHIQ_ARM -D__VCCOREVER__=0x04000000 -I$S/contrib/vchiq" contrib/vchiq/interface/vchiq_arm/vchiq_kern_lib.c optional vchiq soc_brcm_bcm2837 \ compile-with "${NORMAL_C} -DUSE_VCHIQ_ARM -D__VCCOREVER__=0x04000000 -I$S/contrib/vchiq" contrib/vchiq/interface/vchiq_arm/vchiq_kmod.c optional vchiq soc_brcm_bcm2837 \ compile-with "${NORMAL_C} -DUSE_VCHIQ_ARM -D__VCCOREVER__=0x04000000 -I$S/contrib/vchiq" contrib/vchiq/interface/vchiq_arm/vchiq_shim.c optional vchiq soc_brcm_bcm2837 \ compile-with "${NORMAL_C} -DUSE_VCHIQ_ARM -D__VCCOREVER__=0x04000000 -I$S/contrib/vchiq" contrib/vchiq/interface/vchiq_arm/vchiq_util.c optional vchiq soc_brcm_bcm2837 \ compile-with "${NORMAL_C} -DUSE_VCHIQ_ARM -D__VCCOREVER__=0x04000000 -I$S/contrib/vchiq" # Cavium arm64/cavium/thunder_pcie_fdt.c optional soc_cavm_thunderx pci fdt arm64/cavium/thunder_pcie_pem.c optional soc_cavm_thunderx pci arm64/cavium/thunder_pcie_pem_fdt.c optional soc_cavm_thunderx pci fdt arm64/cavium/thunder_pcie_common.c optional soc_cavm_thunderx pci # i.MX8 Clock support arm64/freescale/imx/imx8mq_ccm.c optional fdt soc_freescale_imx8 arm64/freescale/imx/clk/imx_clk_gate.c optional fdt soc_freescale_imx8 arm64/freescale/imx/clk/imx_clk_mux.c optional fdt soc_freescale_imx8 arm64/freescale/imx/clk/imx_clk_composite.c optional fdt soc_freescale_imx8 arm64/freescale/imx/clk/imx_clk_sscg_pll.c optional fdt soc_freescale_imx8 arm64/freescale/imx/clk/imx_clk_frac_pll.c optional fdt soc_freescale_imx8 # iMX drivers arm/freescale/imx/imx_gpio.c optional gpio soc_freescale_imx8 arm/freescale/imx/imx_i2c.c optional fsliic arm/freescale/imx/imx_machdep.c optional fdt soc_freescale_imx8 arm64/freescale/imx/imx7gpc.c optional fdt soc_freescale_imx8 dev/ffec/if_ffec.c optional ffec # Marvell arm/mv/a37x0_gpio.c optional a37x0_gpio gpio fdt arm/mv/a37x0_iic.c optional a37x0_iic iicbus fdt arm/mv/a37x0_spi.c optional a37x0_spi spibus fdt arm/mv/armada38x/armada38x_rtc.c optional mv_rtc fdt arm/mv/gpio.c optional mv_gpio fdt arm/mv/mvebu_gpio.c optional mv_gpio fdt arm/mv/mvebu_pinctrl.c optional mvebu_pinctrl fdt arm/mv/mv_ap806_clock.c optional SOC_MARVELL_8K fdt arm/mv/mv_ap806_gicp.c optional mv_ap806_gicp fdt arm/mv/mv_ap806_sei.c optional mv_ap806_sei fdt arm/mv/mv_cp110_clock.c optional SOC_MARVELL_8K fdt arm/mv/mv_cp110_icu.c optional mv_cp110_icu fdt arm/mv/mv_cp110_icu_bus.c optional mv_cp110_icu fdt arm/mv/mv_thermal.c optional SOC_MARVELL_8K mv_thermal fdt arm/mv/armada38x/armada38x_rtc.c optional mv_rtc fdt # NVidia arm/nvidia/tegra_abpmisc.c optional fdt soc_nvidia_tegra210 arm/nvidia/tegra_ahci.c optional fdt soc_nvidia_tegra210 arm/nvidia/tegra_efuse.c optional fdt soc_nvidia_tegra210 arm/nvidia/tegra_ehci.c optional fdt soc_nvidia_tegra210 arm/nvidia/tegra_gpio.c optional fdt soc_nvidia_tegra210 arm/nvidia/tegra_i2c.c optional fdt soc_nvidia_tegra210 arm/nvidia/tegra_lic.c optional fdt soc_nvidia_tegra210 arm/nvidia/tegra_mc.c optional fdt soc_nvidia_tegra210 arm/nvidia/tegra_pcie.c optional fdt soc_nvidia_tegra210 arm/nvidia/tegra_sdhci.c optional fdt soc_nvidia_tegra210 arm/nvidia/tegra_soctherm_if.m optional fdt soc_nvidia_tegra210 arm/nvidia/tegra_soctherm.c optional fdt soc_nvidia_tegra210 arm/nvidia/tegra_uart.c optional fdt soc_nvidia_tegra210 arm/nvidia/tegra_usbphy.c optional fdt soc_nvidia_tegra210 arm/nvidia/tegra_xhci.c optional fdt soc_nvidia_tegra210 arm64/nvidia/tegra210/max77620.c optional fdt soc_nvidia_tegra210 arm64/nvidia/tegra210/max77620_gpio.c optional fdt soc_nvidia_tegra210 arm64/nvidia/tegra210/max77620_regulators.c optional fdt soc_nvidia_tegra210 arm64/nvidia/tegra210/max77620_rtc.c optional fdt soc_nvidia_tegra210 arm64/nvidia/tegra210/tegra210_car.c optional fdt soc_nvidia_tegra210 arm64/nvidia/tegra210/tegra210_clk_per.c optional fdt soc_nvidia_tegra210 arm64/nvidia/tegra210/tegra210_clk_pll.c optional fdt soc_nvidia_tegra210 arm64/nvidia/tegra210/tegra210_clk_super.c optional fdt soc_nvidia_tegra210 arm64/nvidia/tegra210/tegra210_coretemp.c optional fdt soc_nvidia_tegra210 arm64/nvidia/tegra210/tegra210_cpufreq.c optional fdt soc_nvidia_tegra210 arm64/nvidia/tegra210/tegra210_pinmux.c optional fdt soc_nvidia_tegra210 arm64/nvidia/tegra210/tegra210_pmc.c optional fdt soc_nvidia_tegra210 arm64/nvidia/tegra210/tegra210_xusbpadctl.c optional fdt soc_nvidia_tegra210 # Nvidia firmware for Tegra tegra210_xusb_fw.c optional tegra210_xusb_fw \ dependency "$S/conf/files.arm64" \ compile-with "${AWK} -f $S/tools/fw_stub.awk tegra210_xusb.fw:tegra210_xusb_fw -mtegra210_xusb_fw -c${.TARGET}" \ no-ctfconvert no-implicit-rule before-depend local \ clean "tegra210_xusb_fw.c" tegra210_xusb.fwo optional tegra210_xusb_fw \ dependency "tegra210_xusb.fw" \ compile-with "${NORMAL_FWO}" \ no-implicit-rule \ clean "tegra210_xusb.fwo" tegra210_xusb.fw optional tegra210_xusb_fw \ dependency "$S/contrib/dev/nvidia/tegra210_xusb.bin.uu" \ compile-with "${NORMAL_FW}" \ no-obj no-implicit-rule \ clean "tegra210_xusb.fw" # NXP arm/freescale/vybrid/vf_i2c.c optional vf_i2c iicbus SOC_NXP_LS arm64/qoriq/qoriq_dw_pci.c optional pci fdt SOC_NXP_LS arm64/qoriq/qoriq_therm.c optional pci fdt SOC_NXP_LS arm64/qoriq/qoriq_therm_if.m optional pci fdt SOC_NXP_LS arm64/qoriq/clk/ls1028a_clkgen.c optional clk SOC_NXP_LS arm64/qoriq/clk/ls1046a_clkgen.c optional clk SOC_NXP_LS arm64/qoriq/clk/lx2160a_clkgen.c optional clk SOC_NXP_LS arm64/qoriq/clk/qoriq_clk_pll.c optional clk SOC_NXP_LS arm64/qoriq/clk/qoriq_clkgen.c optional clk SOC_NXP_LS dev/ahci/ahci_fsl_fdt.c optional SOC_NXP_LS ahci fdt # Qualcomm arm64/qualcomm/qcom_gcc.c optional qcom_gcc fdt # RockChip Drivers arm64/rockchip/rk3399_emmcphy.c optional fdt rk_emmcphy soc_rockchip_rk3399 arm64/rockchip/rk_dwc3.c optional fdt rk_dwc3 soc_rockchip_rk3399 arm64/rockchip/rk_i2c.c optional fdt rk_i2c soc_rockchip_rk3328 | fdt rk_i2c soc_rockchip_rk3399 arm64/rockchip/rk805.c optional fdt rk805 soc_rockchip_rk3328 | fdt rk805 soc_rockchip_rk3399 arm64/rockchip/rk_grf.c optional fdt soc_rockchip_rk3328 | fdt soc_rockchip_rk3399 arm64/rockchip/rk_pinctrl.c optional fdt rk_pinctrl soc_rockchip_rk3328 | fdt rk_pinctrl soc_rockchip_rk3399 arm64/rockchip/rk_gpio.c optional fdt rk_gpio soc_rockchip_rk3328 | fdt rk_gpio soc_rockchip_rk3399 arm64/rockchip/rk_iodomain.c optional fdt rk_iodomain arm64/rockchip/rk_spi.c optional fdt rk_spi arm64/rockchip/rk_usb2phy.c optional fdt rk_usb2phy soc_rockchip_rk3328 | soc_rockchip_rk3399 arm64/rockchip/rk_typec_phy.c optional fdt rk_typec_phy soc_rockchip_rk3399 arm64/rockchip/if_dwc_rk.c optional fdt dwc_rk soc_rockchip_rk3328 | fdt dwc_rk soc_rockchip_rk3399 arm64/rockchip/rk_tsadc_if.m optional fdt soc_rockchip_rk3399 arm64/rockchip/rk_tsadc.c optional fdt soc_rockchip_rk3399 arm64/rockchip/rk_pwm.c optional fdt rk_pwm arm64/rockchip/rk_pcie.c optional fdt pci soc_rockchip_rk3399 arm64/rockchip/rk_pcie_phy.c optional fdt pci soc_rockchip_rk3399 # RockChip Clock support arm64/rockchip/clk/rk_cru.c optional fdt soc_rockchip_rk3328 | fdt soc_rockchip_rk3399 arm64/rockchip/clk/rk_clk_armclk.c optional fdt soc_rockchip_rk3328 | fdt soc_rockchip_rk3399 arm64/rockchip/clk/rk_clk_composite.c optional fdt soc_rockchip_rk3328 | fdt soc_rockchip_rk3399 arm64/rockchip/clk/rk_clk_fract.c optional fdt soc_rockchip_rk3328 | fdt soc_rockchip_rk3399 arm64/rockchip/clk/rk_clk_gate.c optional fdt soc_rockchip_rk3328 | fdt soc_rockchip_rk3399 arm64/rockchip/clk/rk_clk_mux.c optional fdt soc_rockchip_rk3328 | fdt soc_rockchip_rk3399 arm64/rockchip/clk/rk_clk_pll.c optional fdt soc_rockchip_rk3328 | fdt soc_rockchip_rk3399 arm64/rockchip/clk/rk3328_cru.c optional fdt soc_rockchip_rk3328 arm64/rockchip/clk/rk3399_cru.c optional fdt soc_rockchip_rk3399 arm64/rockchip/clk/rk3399_pmucru.c optional fdt soc_rockchip_rk3399 # Xilinx arm/xilinx/uart_dev_cdnc.c optional uart soc_xilinx_zynq # Cloudabi arm64/cloudabi32/cloudabi32_sysvec.c optional compat_cloudabi32 arm64/cloudabi64/cloudabi64_sysvec.c optional compat_cloudabi64 cloudabi32_vdso.o optional compat_cloudabi32 \ dependency "$S/contrib/cloudabi/cloudabi_vdso_armv6_on_64bit.S" \ compile-with "${CC} -x assembler-with-cpp -m32 -shared -nostdinc -nostdlib -Wl,-T$S/compat/cloudabi/cloudabi_vdso.lds $S/contrib/cloudabi/cloudabi_vdso_armv6_on_64bit.S -o ${.TARGET}" \ no-obj no-implicit-rule \ clean "cloudabi32_vdso.o" cloudabi32_vdso_blob.o optional compat_cloudabi32 \ dependency "cloudabi32_vdso.o" \ compile-with "${OBJCOPY} --input-target binary --output-target elf64-littleaarch64 --binary-architecture aarch64 cloudabi32_vdso.o ${.TARGET}" \ no-implicit-rule \ clean "cloudabi32_vdso_blob.o" cloudabi64_vdso.o optional compat_cloudabi64 \ dependency "$S/contrib/cloudabi/cloudabi_vdso_aarch64.S" \ compile-with "${CC} -x assembler-with-cpp -shared -nostdinc -nostdlib -Wl,-T$S/compat/cloudabi/cloudabi_vdso.lds $S/contrib/cloudabi/cloudabi_vdso_aarch64.S -o ${.TARGET}" \ no-obj no-implicit-rule \ clean "cloudabi64_vdso.o" cloudabi64_vdso_blob.o optional compat_cloudabi64 \ dependency "cloudabi64_vdso.o" \ compile-with "${OBJCOPY} --input-target binary --output-target elf64-littleaarch64 --binary-architecture aarch64 cloudabi64_vdso.o ${.TARGET}" \ no-implicit-rule \ clean "cloudabi64_vdso_blob.o" diff --git a/sys/dev/etherswitch/felix/felix.c b/sys/dev/etherswitch/felix/felix.c new file mode 100644 index 000000000000..140811807586 --- /dev/null +++ b/sys/dev/etherswitch/felix/felix.c @@ -0,0 +1,996 @@ +/*- + * SPDX-License-Identifier: BSD-2-Clause-FreeBSD + * + * Copyright (c) 2021 Alstom Group. + * Copyright (c) 2021 Semihalf. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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 +__FBSDID("$FreeBSD$"); + +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include +#include +#include + +#include +#include +#include +#include +#include + +#include +#include + +#include +#include + +#include "etherswitch_if.h" +#include "miibus_if.h" + +MALLOC_DECLARE(M_FELIX); +MALLOC_DEFINE(M_FELIX, "felix", "felix switch"); + +static device_probe_t felix_probe; +static device_attach_t felix_attach; +static device_detach_t felix_detach; + +static etherswitch_info_t* felix_getinfo(device_t); +static int felix_getconf(device_t, etherswitch_conf_t *); +static int felix_setconf(device_t, etherswitch_conf_t *); +static void felix_lock(device_t); +static void felix_unlock(device_t); +static int felix_getport(device_t, etherswitch_port_t *); +static int felix_setport(device_t, etherswitch_port_t *); +static int felix_readreg_wrapper(device_t, int); +static int felix_writereg_wrapper(device_t, int, int); +static int felix_readphy(device_t, int, int); +static int felix_writephy(device_t, int, int, int); +static int felix_setvgroup(device_t, etherswitch_vlangroup_t *); +static int felix_getvgroup(device_t, etherswitch_vlangroup_t *); + +static int felix_parse_port_fdt(felix_softc_t, phandle_t, int *); +static int felix_setup(felix_softc_t); +static void felix_setup_port(felix_softc_t, int); + +static void felix_tick(void *); +static int felix_ifmedia_upd(struct ifnet *); +static void felix_ifmedia_sts(struct ifnet *, struct ifmediareq *); + +static void felix_get_port_cfg(felix_softc_t, etherswitch_port_t *); +static void felix_set_port_cfg(felix_softc_t, etherswitch_port_t *); + +static bool felix_is_phyport(felix_softc_t, int); +static struct mii_data *felix_miiforport(felix_softc_t, unsigned int); +static int felix_phyforport(felix_softc_t, int); + +static struct felix_pci_id felix_pci_ids[] = { + {PCI_VENDOR_FREESCALE, FELIX_DEV_ID, FELIX_DEV_NAME}, + {0, 0, NULL} +}; + +static device_method_t felix_methods[] = { + /* device interface */ + DEVMETHOD(device_probe, felix_probe), + DEVMETHOD(device_attach, felix_attach), + DEVMETHOD(device_detach, felix_detach), + + /* bus interface */ + DEVMETHOD(bus_add_child, device_add_child_ordered), + + /* etherswitch interface */ + DEVMETHOD(etherswitch_getinfo, felix_getinfo), + DEVMETHOD(etherswitch_getconf, felix_getconf), + DEVMETHOD(etherswitch_setconf, felix_setconf), + DEVMETHOD(etherswitch_lock, felix_lock), + DEVMETHOD(etherswitch_unlock, felix_unlock), + DEVMETHOD(etherswitch_getport, felix_getport), + DEVMETHOD(etherswitch_setport, felix_setport), + DEVMETHOD(etherswitch_readreg, felix_readreg_wrapper), + DEVMETHOD(etherswitch_writereg, felix_writereg_wrapper), + DEVMETHOD(etherswitch_readphyreg, felix_readphy), + DEVMETHOD(etherswitch_writephyreg, felix_writephy), + DEVMETHOD(etherswitch_setvgroup, felix_setvgroup), + DEVMETHOD(etherswitch_getvgroup, felix_getvgroup), + + DEVMETHOD_END +}; + +static devclass_t felix_devclass; +DEFINE_CLASS_0(felix, felix_driver, felix_methods, + sizeof(struct felix_softc)); + +DRIVER_MODULE(felix, pci, felix_driver, felix_devclass, NULL, NULL); +DRIVER_MODULE(etherswitch, felix, etherswitch_driver, etherswitch_devclass, + NULL, NULL); +MODULE_VERSION(felix, 1); +MODULE_PNP_INFO("U16:vendor;U16:device;D:#", pci, felix, + felix_pci_ids, nitems(felix_pci_ids) - 1); + +static int +felix_probe(device_t dev) +{ + struct felix_pci_id *id; + felix_softc_t sc; + + sc = device_get_softc(dev); + sc->dev = dev; + + for (id = felix_pci_ids; id->vendor != 0; ++id) { + if (pci_get_device(dev) != id->device || + pci_get_vendor(dev) != id->vendor) + continue; + + device_set_desc(dev, id->desc); + + return (BUS_PROBE_DEFAULT); + } + + return (ENXIO); +} + +static int +felix_parse_port_fdt(felix_softc_t sc, phandle_t child, int *pport) +{ + uint32_t port, status; + phandle_t node; + + if (OF_getencprop(child, "reg", (void *)&port, sizeof(port)) < 0) { + device_printf(sc->dev, "Port node doesn't have reg property\n"); + return (ENXIO); + } + + *pport = port; + + node = OF_getproplen(child, "ethernet"); + if (node <= 0) + sc->ports[port].cpu_port = false; + else + sc->ports[port].cpu_port = true; + + node = ofw_bus_find_child(child, "fixed-link"); + if (node <= 0) { + sc->ports[port].fixed_port = false; + return (0); + } + + sc->ports[port].fixed_port = true;; + + if (OF_getencprop(node, "speed", &status, sizeof(status)) <= 0) { + device_printf(sc->dev, + "Port has fixed-link node without link speed specified\n"); + return (ENXIO); + } + + switch (status) { + case 2500: + status = IFM_2500_T; + break; + case 1000: + status = IFM_1000_T; + break; + case 100: + status = IFM_100_T; + break; + case 10: + status = IFM_10_T; + break; + default: + device_printf(sc->dev, + "Unsupported link speed value of %d\n", + status); + return (ENXIO); + } + + if (OF_hasprop(node, "full-duplex")) + status |= IFM_FDX; + else + status |= IFM_HDX; + + status |= IFM_ETHER; + sc->ports[port].fixed_link_status = status; + return (0); +} + +static int +felix_init_interface(felix_softc_t sc, int port) +{ + char name[IFNAMSIZ]; + + snprintf(name, IFNAMSIZ, "%sport", device_get_nameunit(sc->dev)); + + sc->ports[port].ifp = if_alloc(IFT_ETHER); + if (sc->ports[port].ifp == NULL) + return (ENOMEM); + + sc->ports[port].ifp->if_softc = sc; + sc->ports[port].ifp->if_flags = IFF_UP | IFF_BROADCAST | IFF_MULTICAST | + IFF_DRV_RUNNING | IFF_SIMPLEX; + sc->ports[port].ifname = malloc(strlen(name) + 1, M_FELIX, M_NOWAIT); + if (sc->ports[port].ifname == NULL) { + if_free(sc->ports[port].ifp); + return (ENOMEM); + } + + memcpy(sc->ports[port].ifname, name, strlen(name) + 1); + if_initname(sc->ports[port].ifp, sc->ports[port].ifname, port); + return (0); +} + +static void +felix_setup_port(felix_softc_t sc, int port) +{ + + /* Link speed has to be always set to 1000 in the clock register. */ + FELIX_DEVGMII_PORT_WR4(sc, port, FELIX_DEVGMII_CLK_CFG, + FELIX_DEVGMII_CLK_CFG_SPEED_1000); + FELIX_DEVGMII_PORT_WR4(sc, port, FELIX_DEVGMII_MAC_CFG, + FELIX_DEVGMII_MAC_CFG_TX_ENA | FELIX_DEVGMII_MAC_CFG_RX_ENA); + FELIX_WR4(sc, FELIX_QSYS_PORT_MODE(port), + FELIX_QSYS_PORT_MODE_PORT_ENA); + + /* + * Enable "VLANMTU". Each port has a configurable MTU. + * Accept frames that are 8 and 4 bytes longer than it + * for double and single tagged frames respectively. + * Since etherswitch API doesn't provide an option to change + * MTU don't touch it for now. + */ + FELIX_DEVGMII_PORT_WR4(sc, port, FELIX_DEVGMII_VLAN_CFG, + FELIX_DEVGMII_VLAN_CFG_ENA | + FELIX_DEVGMII_VLAN_CFG_LEN_ENA | + FELIX_DEVGMII_VLAN_CFG_DOUBLE_ENA); +} + +static int +felix_setup(felix_softc_t sc) +{ + int timeout, i; + uint32_t reg; + + /* Trigger soft reset, bit is self-clearing, with 5s timeout. */ + FELIX_WR4(sc, FELIX_DEVCPU_GCB_RST, FELIX_DEVCPU_GCB_RST_EN); + timeout = FELIX_INIT_TIMEOUT; + do { + DELAY(1000); + reg = FELIX_RD4(sc, FELIX_DEVCPU_GCB_RST); + if ((reg & FELIX_DEVCPU_GCB_RST_EN) == 0) + break; + } while (timeout-- > 0); + if (timeout == 0) { + device_printf(sc->dev, + "Timeout while waiting for switch to reset\n"); + return (ETIMEDOUT); + } + + FELIX_WR4(sc, FELIX_SYS_RAM_CTRL, FELIX_SYS_RAM_CTRL_INIT); + timeout = FELIX_INIT_TIMEOUT; + do { + DELAY(1000); + reg = FELIX_RD4(sc, FELIX_SYS_RAM_CTRL); + if ((reg & FELIX_SYS_RAM_CTRL_INIT) == 0) + break; + } while (timeout-- > 0); + if (timeout == 0) { + device_printf(sc->dev, + "Timeout while waiting for switch RAM init.\n"); + return (ETIMEDOUT); + } + + FELIX_WR4(sc, FELIX_SYS_CFG, FELIX_SYS_CFG_CORE_EN); + + for (i = 0; i < sc->info.es_nports; i++) + felix_setup_port(sc, i); + + return (0); +} + +static int +felix_attach(device_t dev) +{ + phandle_t child, ports, node; + int error, port, rid; + felix_softc_t sc; + device_t mdio_dev; + uint32_t phy_addr; + ssize_t size; + + sc = device_get_softc(dev); + sc->info.es_nports = 0; + sc->info.es_vlan_caps = ETHERSWITCH_VLAN_DOT1Q; + strlcpy(sc->info.es_name, "Felix TSN Switch", sizeof(sc->info.es_name)); + + rid = PCIR_BAR(FELIX_BAR_REGS); + sc->regs = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid, + RF_ACTIVE); + if (sc->regs == NULL) { + device_printf(dev, "Failed to allocate registers BAR.\n"); + return (ENXIO); + } + + mtx_init(&sc->mtx, "felix lock", NULL, MTX_DEF); + callout_init_mtx(&sc->tick_callout, &sc->mtx, 0); + + node = ofw_bus_get_node(dev); + if (node <= 0) { + error = ENXIO; + goto out_fail; + } + + ports = ofw_bus_find_child(node, "ports"); + if (ports == 0) { + device_printf(dev, + "Failed to find \"ports\" property in DTS.\n"); + error = ENXIO; + goto out_fail; + } + + for (child = OF_child(ports); child != 0; child = OF_peer(child)) { + /* Do not parse disabled ports. */ + if (ofw_bus_node_status_okay(child) == 0) + continue; + + error = felix_parse_port_fdt(sc, child, &port); + if (error != 0) + goto out_fail; + + error = felix_init_interface(sc, port); + if (error != 0) { + device_printf(sc->dev, + "Failed to initialize interface.\n"); + goto out_fail; + } + + if (sc->ports[port].fixed_port) { + sc->info.es_nports++; + continue; + } + + size = OF_getencprop(child, "phy-handle", &node, sizeof(node)); + if (size <= 0) { + device_printf(sc->dev, + "Failed to acquire PHY handle from FDT.\n"); + error = ENXIO; + goto out_fail; + } + + node = OF_node_from_xref(node); + size = OF_getencprop(node, "reg", &phy_addr, sizeof(phy_addr)); + if (size <= 0) { + device_printf(sc->dev, + "Failed to obtain PHY address.\n"); + error = ENXIO; + goto out_fail; + } + + node = OF_parent(node); + if (node <= 0) { + device_printf(sc->dev, + "Failed to obtain MDIO node.\n"); + error = ENXIO; + goto out_fail; + } + + mdio_dev = OF_device_from_xref(node); + if (mdio_dev == NULL) { + device_printf(sc->dev, + "Failed to obtain MDIO driver handle.\n"); + error = ENXIO; + goto out_fail; + } + + sc->ports[port].phyaddr = phy_addr; + sc->ports[port].miibus = NULL; + error = mii_attach(mdio_dev, &sc->ports[port].miibus, sc->ports[port].ifp, + felix_ifmedia_upd, felix_ifmedia_sts, BMSR_DEFCAPMASK, + phy_addr, MII_OFFSET_ANY, 0); + if (error != 0) + goto out_fail; + + sc->info.es_nports++; + } + + error = felix_setup(sc); + if (error != 0) + goto out_fail; + + /* The tick routine has to be called with the lock held. */ + FELIX_LOCK(sc); + felix_tick(sc); + FELIX_UNLOCK(sc); + + /* Allow etherswitch to attach as our child. */ + bus_generic_probe(dev); + bus_generic_attach(dev); + + return (0); + +out_fail: + felix_detach(dev); + return (error); +} + +static int +felix_detach(device_t dev) +{ + felix_softc_t sc; + device_t mdio_dev; + int error; + int i; + + error = 0; + sc = device_get_softc(dev); + bus_generic_detach(dev); + + mtx_lock(&sc->mtx); + callout_stop(&sc->tick_callout); + mtx_unlock(&sc->mtx); + mtx_destroy(&sc->mtx); + + /* + * If we have been fully attached do a soft reset. + * This way after when driver is unloaded switch is left in unmanaged mode. + */ + if (device_is_attached(dev)) + felix_setup(sc); + + for (i = 0; i < sc->info.es_nports; i++) { + if (sc->ports[i].miibus != NULL) { + mdio_dev = device_get_parent(sc->ports[i].miibus); + device_delete_child(mdio_dev, sc->ports[i].miibus); + } + if (sc->ports[i].ifp != NULL) + if_free(sc->ports[i].ifp); + if (sc->ports[i].ifname != NULL) + free(sc->ports[i].ifname, M_FELIX); + } + + if (sc->regs != NULL) + error = bus_release_resource(sc->dev, SYS_RES_MEMORY, + rman_get_rid(sc->regs), sc->regs); + + return (error); +} + +static etherswitch_info_t* +felix_getinfo(device_t dev) +{ + felix_softc_t sc; + + sc = device_get_softc(dev); + return (&sc->info); +} + +static int +felix_getconf(device_t dev, etherswitch_conf_t *conf) +{ + felix_softc_t sc; + + sc = device_get_softc(dev); + + /* Return the VLAN mode. */ + conf->cmd = ETHERSWITCH_CONF_VLAN_MODE; + conf->vlan_mode = sc->vlan_mode; + return (0); +} + +static int +felix_init_vlan(felix_softc_t sc) +{ + int timeout = FELIX_INIT_TIMEOUT; + uint32_t reg; + int i; + + /* Flush VLAN table in hardware. */ + FELIX_WR4(sc, FELIX_ANA_VT, FELIX_ANA_VT_RESET); + do { + DELAY(1000); + reg = FELIX_RD4(sc, FELIX_ANA_VT); + if ((reg & FELIX_ANA_VT_STS) == FELIX_ANA_VT_IDLE) + break; + } while (timeout-- > 0); + if (timeout == 0) { + device_printf(sc->dev, + "Timeout during VLAN table reset.\n"); + return (ETIMEDOUT); + } + + /* Flush VLAN table in sc. */ + for (i = 0; i < sc->info.es_nvlangroups; i++) + sc->vlans[i] = 0; + + /* + * Make all ports VLAN aware. + * Read VID from incoming frames and use it for port grouping + * purposes. + * Don't set this if pvid is set. + */ + for (i = 0; i < sc->info.es_nports; i++) { + reg = FELIX_ANA_PORT_RD4(sc, i, FELIX_ANA_PORT_VLAN_CFG); + if ((reg & FELIX_ANA_PORT_VLAN_CFG_VID_MASK) != 0) + continue; + + reg |= FELIX_ANA_PORT_VLAN_CFG_VID_AWARE; + FELIX_ANA_PORT_WR4(sc, i, FELIX_ANA_PORT_VLAN_CFG, reg); + } + return (0); +} + +static int +felix_setconf(device_t dev, etherswitch_conf_t *conf) +{ + felix_softc_t sc; + int error; + + error = 0; + /* Set the VLAN mode. */ + sc = device_get_softc(dev); + FELIX_LOCK(sc); + if (conf->cmd & ETHERSWITCH_CONF_VLAN_MODE) { + switch (conf->vlan_mode) { + case ETHERSWITCH_VLAN_DOT1Q: + sc->vlan_mode = ETHERSWITCH_VLAN_DOT1Q; + sc->info.es_nvlangroups = FELIX_NUM_VLANS; + error = felix_init_vlan(sc); + break; + default: + error = EINVAL; + } + } + FELIX_UNLOCK(sc); + return (error); +} + +static void +felix_lock(device_t dev) +{ + felix_softc_t sc; + + sc = device_get_softc(dev); + FELIX_LOCK_ASSERT(sc, MA_NOTOWNED); + FELIX_LOCK(sc); +} + +static void +felix_unlock(device_t dev) +{ + felix_softc_t sc; + + sc = device_get_softc(dev); + FELIX_LOCK_ASSERT(sc, MA_OWNED); + FELIX_UNLOCK(sc); +} + +static void +felix_get_port_cfg(felix_softc_t sc, etherswitch_port_t *p) +{ + uint32_t reg; + + p->es_flags = 0; + + reg = FELIX_ANA_PORT_RD4(sc, p->es_port, FELIX_ANA_PORT_DROP_CFG); + if (reg & FELIX_ANA_PORT_DROP_CFG_TAGGED) + p->es_flags |= ETHERSWITCH_PORT_DROPTAGGED; + + if (reg & FELIX_ANA_PORT_DROP_CFG_UNTAGGED) + p->es_flags |= ETHERSWITCH_PORT_DROPUNTAGGED; + + reg = FELIX_DEVGMII_PORT_RD4(sc, p->es_port, FELIX_DEVGMII_VLAN_CFG); + if (reg & FELIX_DEVGMII_VLAN_CFG_DOUBLE_ENA) + p->es_flags |= ETHERSWITCH_PORT_DOUBLE_TAG; + + reg = FELIX_REW_PORT_RD4(sc, p->es_port, FELIX_REW_PORT_TAG_CFG); + if (reg & FELIX_REW_PORT_TAG_CFG_ALL) + p->es_flags |= ETHERSWITCH_PORT_ADDTAG; + + reg = FELIX_ANA_PORT_RD4(sc, p->es_port, FELIX_ANA_PORT_VLAN_CFG); + if (reg & FELIX_ANA_PORT_VLAN_CFG_POP) + p->es_flags |= ETHERSWITCH_PORT_STRIPTAGINGRESS; + + p->es_pvid = reg & FELIX_ANA_PORT_VLAN_CFG_VID_MASK; +} + +static int +felix_getport(device_t dev, etherswitch_port_t *p) +{ + struct ifmediareq *ifmr; + struct mii_data *mii; + felix_softc_t sc; + int error; + + error = 0; + sc = device_get_softc(dev); + FELIX_LOCK_ASSERT(sc, MA_NOTOWNED); + + if (p->es_port >= sc->info.es_nports || p->es_port < 0) + return (EINVAL); + + FELIX_LOCK(sc); + felix_get_port_cfg(sc, p); + if (sc->ports[p->es_port].fixed_port) { + ifmr = &p->es_ifmr; + ifmr->ifm_status = IFM_ACTIVE | IFM_AVALID; + ifmr->ifm_count = 0; + ifmr->ifm_active = sc->ports[p->es_port].fixed_link_status; + ifmr->ifm_current = ifmr->ifm_active; + ifmr->ifm_mask = 0; + } else { + mii = felix_miiforport(sc, p->es_port); + error = ifmedia_ioctl(mii->mii_ifp, &p->es_ifr, + &mii->mii_media, SIOCGIFMEDIA); + } + FELIX_UNLOCK(sc); + return (error); +} + +static void +felix_set_port_cfg(felix_softc_t sc, etherswitch_port_t *p) +{ + uint32_t reg; + + reg = FELIX_ANA_PORT_RD4(sc, p->es_port, FELIX_ANA_PORT_DROP_CFG); + if (p->es_flags & ETHERSWITCH_PORT_DROPTAGGED) + reg |= FELIX_ANA_PORT_DROP_CFG_TAGGED; + else + reg &= ~FELIX_ANA_PORT_DROP_CFG_TAGGED; + + if (p->es_flags & ETHERSWITCH_PORT_DROPUNTAGGED) + reg |= FELIX_ANA_PORT_DROP_CFG_UNTAGGED; + else + reg &= ~FELIX_ANA_PORT_DROP_CFG_UNTAGGED; + + FELIX_ANA_PORT_WR4(sc, p->es_port, FELIX_ANA_PORT_DROP_CFG, reg); + + reg = FELIX_REW_PORT_RD4(sc, p->es_port, FELIX_REW_PORT_TAG_CFG); + if (p->es_flags & ETHERSWITCH_PORT_ADDTAG) + reg |= FELIX_REW_PORT_TAG_CFG_ALL; + else + reg &= ~FELIX_REW_PORT_TAG_CFG_ALL; + + FELIX_REW_PORT_WR4(sc, p->es_port, FELIX_REW_PORT_TAG_CFG, reg); + + reg = FELIX_ANA_PORT_RD4(sc, p->es_port, FELIX_ANA_PORT_VLAN_CFG); + if (p->es_flags & ETHERSWITCH_PORT_STRIPTAGINGRESS) + reg |= FELIX_ANA_PORT_VLAN_CFG_POP; + else + reg &= ~FELIX_ANA_PORT_VLAN_CFG_POP; + + reg &= ~FELIX_ANA_PORT_VLAN_CFG_VID_MASK; + reg |= p->es_pvid & FELIX_ANA_PORT_VLAN_CFG_VID_MASK; + /* + * If port VID is set use it for VLAN classification, + * instead of frame VID. + * By default the frame tag takes precedence. + * Force the switch to ignore it. + */ + if (p->es_pvid != 0) + reg &= ~FELIX_ANA_PORT_VLAN_CFG_VID_AWARE; + else + reg |= FELIX_ANA_PORT_VLAN_CFG_VID_AWARE; + + FELIX_ANA_PORT_WR4(sc, p->es_port, FELIX_ANA_PORT_VLAN_CFG, reg); +} + +static int +felix_setport(device_t dev, etherswitch_port_t *p) +{ + felix_softc_t sc; + struct mii_data *mii; + int error; + + error = 0; + sc = device_get_softc(dev); + FELIX_LOCK_ASSERT(sc, MA_NOTOWNED); + + if (p->es_port >= sc->info.es_nports || p->es_port < 0) + return (EINVAL); + + FELIX_LOCK(sc); + felix_set_port_cfg(sc, p); + if (felix_is_phyport(sc, p->es_port)) { + mii = felix_miiforport(sc, p->es_port); + error = ifmedia_ioctl(mii->mii_ifp, &p->es_ifr, &mii->mii_media, + SIOCSIFMEDIA); + } + FELIX_UNLOCK(sc); + + return (error); +} + +static int +felix_readreg_wrapper(device_t dev, int addr_reg) +{ + felix_softc_t sc; + + sc = device_get_softc(dev); + if (addr_reg > rman_get_size(sc->regs)) + return (UINT32_MAX); /* Can't return errors here. */ + + return (FELIX_RD4(sc, addr_reg)); +} + +static int +felix_writereg_wrapper(device_t dev, int addr_reg, int val) +{ + felix_softc_t sc; + + sc = device_get_softc(dev); + if (addr_reg > rman_get_size(sc->regs)) + return (EINVAL); + + FELIX_WR4(sc, addr_reg, val); + return (0); +} + +static int +felix_readphy(device_t dev, int phy, int reg) +{ + felix_softc_t sc; + device_t mdio_dev; + int port; + + sc = device_get_softc(dev); + port = felix_phyforport(sc, phy); + if (port < 0) + return (UINT32_MAX); /* Can't return errors here. */ + + mdio_dev = device_get_parent(sc->ports[port].miibus); + return (MIIBUS_READREG(mdio_dev, phy, reg)); +} + +static int +felix_writephy(device_t dev, int phy, int reg, int data) +{ + felix_softc_t sc; + device_t mdio_dev; + int port; + + sc = device_get_softc(dev); + port = felix_phyforport(sc, phy); + if (port < 0) + return (ENXIO); + + mdio_dev = device_get_parent(sc->ports[port].miibus); + return (MIIBUS_WRITEREG(mdio_dev, phy, reg, data)); +} + +static int +felix_set_dot1q_vlan(felix_softc_t sc, etherswitch_vlangroup_t *vg) +{ + uint32_t reg; + int i, vid; + + vid = vg->es_vid & ETHERSWITCH_VID_MASK; + + /* Tagged mode is not supported. */ + if (vg->es_member_ports != vg->es_untagged_ports) + return (EINVAL); + + /* + * Hardware support 4096 groups, but we can't do group_id == vid. + * Note that hw_group_id == vid. + */ + if (vid == 0) { + /* Clear VLAN table entry using old VID. */ + FELIX_WR4(sc, FELIX_ANA_VTIDX, sc->vlans[vg->es_vlangroup]); + FELIX_WR4(sc, FELIX_ANA_VT, FELIX_ANA_VT_WRITE); + sc->vlans[vg->es_vlangroup] = 0; + return (0); + } + + /* The VID is already used in a different group. */ + for (i = 0; i < sc->info.es_nvlangroups; i++) + if (i != vg->es_vlangroup && vid == sc->vlans[i]) + return (EINVAL); + + /* This group already uses a different VID. */ + if (sc->vlans[vg->es_vlangroup] != 0 && + sc->vlans[vg->es_vlangroup] != vid) + return (EINVAL); + + sc->vlans[vg->es_vlangroup] = vid; + + /* Assign members to the given group. */ + reg = vg->es_member_ports & FELIX_ANA_VT_PORTMASK_MASK; + reg <<= FELIX_ANA_VT_PORTMASK_SHIFT; + reg |= FELIX_ANA_VT_WRITE; + + FELIX_WR4(sc, FELIX_ANA_VTIDX, vid); + FELIX_WR4(sc, FELIX_ANA_VT, reg); + + /* + * According to documentation read and write commands + * are instant. + * Add a small delay just to be safe. + */ + mb(); + DELAY(100); + reg = FELIX_RD4(sc, FELIX_ANA_VT); + if ((reg & FELIX_ANA_VT_STS) != FELIX_ANA_VT_IDLE) + return (ENXIO); + + return (0); +} + +static int +felix_setvgroup(device_t dev, etherswitch_vlangroup_t *vg) +{ + felix_softc_t sc; + int error; + + sc = device_get_softc(dev); + + FELIX_LOCK(sc); + if (sc->vlan_mode == ETHERSWITCH_VLAN_DOT1Q) + error = felix_set_dot1q_vlan(sc, vg); + else + error = EINVAL; + + FELIX_UNLOCK(sc); + return (error); +} + +static int +felix_get_dot1q_vlan(felix_softc_t sc, etherswitch_vlangroup_t *vg) +{ + uint32_t reg; + int vid; + + vid = sc->vlans[vg->es_vlangroup]; + + if (vid == 0) + return (0); + + FELIX_WR4(sc, FELIX_ANA_VTIDX, vid); + FELIX_WR4(sc, FELIX_ANA_VT, FELIX_ANA_VT_READ); + + /* + * According to documentation read and write commands + * are instant. + * Add a small delay just to be safe. + */ + mb(); + DELAY(100); + reg = FELIX_RD4(sc, FELIX_ANA_VT); + if ((reg & FELIX_ANA_VT_STS) != FELIX_ANA_VT_IDLE) + return (ENXIO); + + reg >>= FELIX_ANA_VT_PORTMASK_SHIFT; + reg &= FELIX_ANA_VT_PORTMASK_MASK; + + vg->es_untagged_ports = vg->es_member_ports = reg; + vg->es_fid = 0; + vg->es_vid = vid | ETHERSWITCH_VID_VALID; + return (0); +} + +static int +felix_getvgroup(device_t dev, etherswitch_vlangroup_t *vg) +{ + felix_softc_t sc; + int error; + + sc = device_get_softc(dev); + + FELIX_LOCK(sc); + if (sc->vlan_mode == ETHERSWITCH_VLAN_DOT1Q) + error = felix_get_dot1q_vlan(sc, vg); + else + error = EINVAL; + + FELIX_UNLOCK(sc); + return (error); +} + +static void +felix_tick(void *arg) +{ + struct mii_data *mii; + felix_softc_t sc; + int port; + + sc = arg; + + FELIX_LOCK_ASSERT(sc, MA_OWNED); + + for (port = 0; port < sc->info.es_nports; port++) { + if (!felix_is_phyport(sc, port)) + continue; + + mii = felix_miiforport(sc, port); + MPASS(mii != NULL); + mii_tick(mii); + } + callout_reset(&sc->tick_callout, hz, felix_tick, sc); +} + +static int +felix_ifmedia_upd(struct ifnet *ifp) +{ + struct mii_data *mii; + felix_softc_t sc; + + sc = ifp->if_softc; + mii = felix_miiforport(sc, ifp->if_dunit); + if (mii == NULL) + return (ENXIO); + + mii_mediachg(mii); + return (0); +} + +static void +felix_ifmedia_sts(struct ifnet *ifp, struct ifmediareq *ifmr) +{ + felix_softc_t sc; + struct mii_data *mii; + + sc = ifp->if_softc; + mii = felix_miiforport(sc, ifp->if_dunit); + if (mii == NULL) + return; + + mii_pollstat(mii); + ifmr->ifm_active = mii->mii_media_active; + ifmr->ifm_status = mii->mii_media_status; +} + +static bool +felix_is_phyport(felix_softc_t sc, int port) +{ + + return (!sc->ports[port].fixed_port); +} + +static int +felix_phyforport(felix_softc_t sc, int phy) +{ + int port; + + for (port = 0; port < sc->info.es_nports; port++) { + if (sc->ports[port].phyaddr == phy) + return (port); + } + return (-1); +} + +static struct mii_data* +felix_miiforport(felix_softc_t sc, unsigned int port) +{ + + if (!felix_is_phyport(sc, port)) + return (NULL); + + return (device_get_softc(sc->ports[port].miibus)); +} diff --git a/sys/dev/etherswitch/felix/felix_reg.h b/sys/dev/etherswitch/felix/felix_reg.h new file mode 100644 index 000000000000..3474da72a456 --- /dev/null +++ b/sys/dev/etherswitch/felix/felix_reg.h @@ -0,0 +1,100 @@ +/*- + * SPDX-License-Identifier: BSD-2-Clause-FreeBSD + * + * Copyright (c) 2021 Alstom Group. + * Copyright (c) 2021 Semihalf. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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 _FELIX_REG_H_ +#define _FELIX_REG_H_ + +#define BIT(x) (1UL << (x)) + +#define FELIX_DEVCPU_GCB_RST 0x70004 +#define FELIX_DEVCPU_GCB_RST_EN BIT(0) + +#define FELIX_ANA_VT 0x287F34 +#define FELIX_ANA_VT_PORTMASK_SHIFT 2 +#define FELIX_ANA_VT_PORTMASK_MASK 0x7F +#define FELIX_ANA_VT_STS (BIT(0) | BIT(1)) +#define FELIX_ANA_VT_RESET (BIT(0) | BIT(1)) +#define FELIX_ANA_VT_WRITE BIT(1) +#define FELIX_ANA_VT_READ BIT(0) +#define FELIX_ANA_VT_IDLE 0 +#define FELIX_ANA_VTIDX 0x287F38 + +#define FELIX_ANA_PORT_BASE 0x287800 +#define FELIX_ANA_PORT_OFFSET 0x100 +#define FELIX_ANA_PORT_VLAN_CFG 0x0 +#define FELIX_ANA_PORT_VLAN_CFG_VID_MASK 0xFFF +#define FELIX_ANA_PORT_VLAN_CFG_POP BIT(18) +#define FELIX_ANA_PORT_VLAN_CFG_VID_AWARE BIT(20) +#define FELIX_ANA_PORT_DROP_CFG 0x4 +#define FELIX_ANA_PORT_DROP_CFG_MULTI BIT(0) +#define FELIX_ANA_PORT_DROP_CFG_NULL BIT(1) /* SRC, or DST MAC == 0 */ +#define FELIX_ANA_PORT_DROP_CFG_CTAGGED_PRIO BIT(2) /* 0x8100, VID == 0 */ +#define FELIX_ANA_PORT_DROP_CFG_STAGGED_PRIO BIT(3) /* 0x88A8, VID == 0 */ +#define FELIX_ANA_PORT_DROP_CFG_CTAGGED BIT(4) /* 0x8100 */ +#define FELIX_ANA_PORT_DROP_CFG_STAGGED BIT(5) /* 0x88A8 */ +#define FELIX_ANA_PORT_DROP_CFG_UNTAGGED BIT(6) +#define FELIX_ANA_PORT_DROP_CFG_TAGGED \ + (FELIX_ANA_PORT_DROP_CFG_CTAGGED_PRIO | \ + FELIX_ANA_PORT_DROP_CFG_STAGGED_PRIO | \ + FELIX_ANA_PORT_DROP_CFG_CTAGGED | \ + FELIX_ANA_PORT_DROP_CFG_STAGGED) + +#define FELIX_DEVGMII_BASE 0x100000 +#define FELIX_DEVGMII_PORT_OFFSET 0x010000 + +#define FELIX_DEVGMII_CLK_CFG 0x0 +#define FELIX_DEVGMII_CLK_CFG_SPEED_1000 1 +#define FELIX_DEVGMII_CLK_CFG_SPEED_100 2 +#define FELIX_DEVGMII_CLK_CFG_SPEED_10 3 + +#define FELIX_DEVGMII_MAC_CFG 0x1c +#define FELIX_DEVGMII_MAC_CFG_TX_ENA BIT(0) +#define FELIX_DEVGMII_MAC_CFG_RX_ENA BIT(4) + +#define FELIX_DEVGMII_VLAN_CFG 0x28 +#define FELIX_DEVGMII_VLAN_CFG_ENA BIT(0) /* Accept 0x8100 only. */ +#define FELIX_DEVGMII_VLAN_CFG_DOUBLE_ENA BIT(1) /* Inner tag can only be 0x8100. */ +#define FELIX_DEVGMII_VLAN_CFG_LEN_ENA BIT(2) /* Enable VLANMTU. */ + +#define FELIX_REW_PORT_BASE 0x030000 +#define FELIX_REW_PORT_OFFSET 0x80 +#define FELIX_REW_PORT_TAG_CFG 0x4 +#define FELIX_REW_PORT_TAG_CFG_MASK (BIT(7) | BIT(8)) +#define FELIX_REW_PORT_TAG_CFG_DIS (0 << 7) /* Port tagging disabled */ +#define FELIX_REW_PORT_TAG_CFG_ALL (2 << 7) /* Tag frames if pvid != 0 */ + +#define FELIX_SYS_RAM_CTRL 0x10F24 +#define FELIX_SYS_RAM_CTRL_INIT BIT(1) + +#define FELIX_SYS_CFG 0x10E00 +#define FELIX_SYS_CFG_CORE_EN BIT(0) + +#define FELIX_QSYS_PORT_MODE(port) (0x20F480 + 4*(port)) +#define FELIX_QSYS_PORT_MODE_PORT_ENA BIT(14) + +#endif diff --git a/sys/dev/etherswitch/felix/felix_var.h b/sys/dev/etherswitch/felix/felix_var.h new file mode 100644 index 000000000000..1bdbc35e6116 --- /dev/null +++ b/sys/dev/etherswitch/felix/felix_var.h @@ -0,0 +1,105 @@ +/*- + * SPDX-License-Identifier: BSD-2-Clause-FreeBSD + * + * Copyright (c) 2021 Alstom Group. + * Copyright (c) 2021 Semihalf. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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 _FELIX_VAR_H_ +#define _FELIX_VAR_H_ + +#define FELIX_INIT_TIMEOUT 5000 /* msec */ + +#define FELIX_DEV_NAME "Felix TSN Switch driver" +#define FELIX_MAX_PORTS 6 +#define FELIX_NUM_VLANS 4096 + +#define PCI_VENDOR_FREESCALE 0x1957 +#define FELIX_DEV_ID 0xEEF0 + +#define FELIX_BAR_REGS 4 + +#define FELIX_LOCK(_sc) mtx_lock(&(_sc)->mtx) +#define FELIX_UNLOCK(_sc) mtx_unlock(&(_sc)->mtx) +#define FELIX_LOCK_ASSERT(_sc, _what) mtx_assert(&(_sc)->mtx, (_what)) + +#define FELIX_RD4(sc, reg) bus_read_4((sc)->regs, reg) +#define FELIX_WR4(sc, reg, value) bus_write_4((sc)->regs, reg, value) + +#define FELIX_DEVGMII_PORT_RD4(sc, port, reg) \ + FELIX_RD4(sc, \ + FELIX_DEVGMII_BASE + (FELIX_DEVGMII_PORT_OFFSET * (port)) + reg) +#define FELIX_DEVGMII_PORT_WR4(sc, port, reg, value) \ + FELIX_WR4(sc, \ + FELIX_DEVGMII_BASE + (FELIX_DEVGMII_PORT_OFFSET * (port)) + reg, \ + value) + +#define FELIX_ANA_PORT_RD4(sc, port, reg) \ + FELIX_RD4(sc, \ + FELIX_ANA_PORT_BASE + (FELIX_ANA_PORT_OFFSET * (port)) + reg) +#define FELIX_ANA_PORT_WR4(sc, port, reg, value) \ + FELIX_WR4(sc, \ + FELIX_ANA_PORT_BASE + (FELIX_ANA_PORT_OFFSET * (port)) + reg, \ + value) + +#define FELIX_REW_PORT_RD4(sc, port, reg) \ + FELIX_RD4(sc, \ + FELIX_REW_PORT_BASE + (FELIX_REW_PORT_OFFSET * (port)) + reg) +#define FELIX_REW_PORT_WR4(sc, port, reg, value) \ + FELIX_WR4(sc, \ + FELIX_REW_PORT_BASE + (FELIX_REW_PORT_OFFSET * (port)) + reg, \ + value) + +struct felix_pci_id { + uint16_t vendor; + uint16_t device; + const char *desc; +}; + +struct felix_port { + struct ifnet *ifp; + device_t miibus; + char *ifname; + + uint32_t phyaddr; + + int fixed_link_status; + bool fixed_port; + bool cpu_port; +}; + +typedef struct felix_softc { + device_t dev; + struct resource *regs; + + etherswitch_info_t info; + struct callout tick_callout; + struct mtx mtx; + struct felix_port ports[FELIX_MAX_PORTS]; + + int vlan_mode; + int vlans[FELIX_NUM_VLANS]; +} *felix_softc_t; + +#endif diff --git a/sys/modules/Makefile b/sys/modules/Makefile index 16f5ba061db6..e6e683ecd65e 100644 --- a/sys/modules/Makefile +++ b/sys/modules/Makefile @@ -1,844 +1,846 @@ # $FreeBSD$ SYSDIR?=${SRCTOP}/sys .include "${SYSDIR}/conf/kern.opts.mk" SUBDIR_PARALLEL= # Modules that include binary-only blobs of microcode should be selectable by # MK_SOURCELESS_UCODE option (see below). .include "${SYSDIR}/conf/config.mk" .if defined(MODULES_OVERRIDE) && !defined(ALL_MODULES) SUBDIR=${MODULES_OVERRIDE} .else SUBDIR= \ ${_3dfx} \ ${_3dfx_linux} \ ${_aac} \ ${_aacraid} \ accf_data \ accf_dns \ accf_http \ acl_nfs4 \ acl_posix1e \ ${_acpi} \ ae \ ${_aesni} \ age \ ${_agp} \ ahci \ aic7xxx \ alc \ ale \ alq \ ${_amd_ecc_inject} \ ${_amdgpio} \ ${_amdsbwd} \ ${_amdsmn} \ ${_amdtemp} \ amr \ ${_aout} \ ${_arcmsr} \ ${_allwinner} \ ${_armv8crypto} \ ${_asmc} \ ata \ ath \ ath_dfs \ ath_hal \ ath_hal_ar5210 \ ath_hal_ar5211 \ ath_hal_ar5212 \ ath_hal_ar5416 \ ath_hal_ar9300 \ ath_main \ ath_rate \ ath_pci \ ${_autofs} \ axgbe \ backlight \ ${_bce} \ ${_bcm283x_clkman} \ ${_bcm283x_pwm} \ bfe \ bge \ bhnd \ ${_bxe} \ ${_bios} \ ${_blake2} \ bnxt \ bridgestp \ bwi \ bwn \ ${_bytgpio} \ ${_chvgpio} \ cam \ ${_cardbus} \ ${_carp} \ cas \ ${_cbb} \ cc \ ${_ccp} \ cd9660 \ cd9660_iconv \ ${_ce} \ ${_cfi} \ ${_chromebook_platform} \ ${_ciss} \ cloudabi \ ${_cloudabi32} \ ${_cloudabi64} \ ${_coretemp} \ ${_cp} \ ${_cpsw} \ ${_cpuctl} \ ${_cpufreq} \ ${_crypto} \ ${_cryptodev} \ ctl \ ${_cxgb} \ ${_cxgbe} \ dc \ dcons \ dcons_crom \ ${_dpdk_lpm4} \ ${_dpdk_lpm6} \ ${_dpms} \ dummynet \ ${_dwwdt} \ ${_efirt} \ ${_em} \ ${_ena} \ esp \ ${_et} \ evdev \ ${_exca} \ ext2fs \ fdc \ fdescfs \ + ${_felix} \ ${_ffec} \ ${_fib_dxr} \ filemon \ firewire \ firmware \ ${_ftwd} \ fusefs \ ${_fxp} \ gem \ geom \ ${_glxiic} \ ${_glxsb} \ gpio \ hid \ hifn \ ${_hpt27xx} \ ${_hptiop} \ ${_hptmv} \ ${_hptnr} \ ${_hptrr} \ hwpmc \ ${_hwpmc_mips24k} \ ${_hwpmc_mips74k} \ ${_hyperv} \ i2c \ ${_iavf} \ ${_ibcore} \ ${_ichwd} \ ${_ice} \ ${_ice_ddp} \ ${_ida} \ if_bridge \ if_disc \ if_edsc \ ${_if_enc} \ if_epair \ ${_if_gif} \ ${_if_gre} \ ${_if_me} \ if_infiniband \ if_lagg \ ${_if_stf} \ if_tuntap \ if_vlan \ if_vxlan \ iflib \ ${_igc} \ ${_iir} \ imgact_binmisc \ ${_intelspi} \ ${_io} \ ${_ioat} \ ${_ipoib} \ ${_ipdivert} \ ${_ipfilter} \ ${_ipfw} \ ipfw_nat \ ${_ipfw_nat64} \ ${_ipfw_nptv6} \ ${_ipfw_pmod} \ ${_ipmi} \ ip6_mroute_mod \ ip_mroute_mod \ ${_ips} \ ${_ipsec} \ ${_ipw} \ ${_ipwfw} \ ${_isci} \ ${_iser} \ isp \ ${_ispfw} \ ${_itwd} \ ${_iwi} \ ${_iwifw} \ ${_iwm} \ ${_iwmfw} \ ${_iwn} \ ${_iwnfw} \ ${_ix} \ ${_ixv} \ ${_ixl} \ jme \ kbdmux \ kgssapi \ kgssapi_krb5 \ khelp \ krpc \ ksyms \ le \ lge \ libalias \ libiconv \ libmchain \ lindebugfs \ linuxkpi \ ${_lio} \ lpt \ mac_biba \ mac_bsdextended \ mac_ifoff \ mac_lomac \ mac_mls \ mac_none \ mac_ntpd \ mac_partition \ mac_portacl \ mac_seeotheruids \ mac_stub \ mac_test \ ${_malo} \ md \ mdio \ mem \ mfi \ mii \ mlx \ mlxfw \ ${_mlx4} \ ${_mlx4ib} \ ${_mlx4en} \ ${_mlx5} \ ${_mlx5en} \ ${_mlx5ib} \ ${_mly} \ mmc \ mmcsd \ ${_mpr} \ ${_mps} \ mpt \ mqueue \ mrsas \ msdosfs \ msdosfs_iconv \ msk \ ${_mthca} \ mvs \ mwl \ ${_mwlfw} \ mxge \ my \ ${_nctgpio} \ ${_netgraph} \ ${_nfe} \ nfscl \ nfscommon \ nfsd \ nfslockd \ nfssvc \ nge \ nmdm \ nullfs \ ${_ntb} \ ${_nvd} \ ${_nvdimm} \ ${_nvme} \ ${_nvram} \ oce \ ${_ocs_fc} \ ${_ossl} \ otus \ ${_otusfw} \ ow \ ${_padlock} \ ${_padlock_rng} \ ${_pchtherm} \ ${_pcfclock} \ ${_pf} \ ${_pflog} \ ${_pfsync} \ plip \ ${_pms} \ ppbus \ ppc \ ppi \ pps \ procfs \ proto \ pseudofs \ ${_pst} \ pty \ puc \ pwm \ ${_qat} \ ${_qatfw} \ ${_qlxge} \ ${_qlxgb} \ ${_qlxgbe} \ ${_qlnx} \ ral \ ${_ralfw} \ ${_random_fortuna} \ ${_random_other} \ rc4 \ ${_rdma} \ ${_rdrand_rng} \ re \ rl \ ${_rockchip} \ rtsx \ rtwn \ rtwn_pci \ rtwn_usb \ ${_rtwnfw} \ ${_s3} \ ${_safe} \ safexcel \ ${_sbni} \ scc \ ${_sctp} \ sdhci \ ${_sdhci_acpi} \ ${_sdhci_fdt} \ sdhci_pci \ sdio \ sem \ send \ ${_sfxge} \ sge \ ${_sgx} \ ${_sgx_linux} \ siftr \ siis \ sis \ sk \ ${_smartpqi} \ smbfs \ snp \ sound \ ${_speaker} \ spi \ ${_splash} \ ${_sppp} \ ste \ stge \ ${_sume} \ ${_superio} \ ${_sym} \ ${_syscons} \ sysvipc \ tcp \ ${_ti} \ tmpfs \ ${_toecore} \ ${_tpm} \ ${_twa} \ twe \ tws \ uart \ udf \ udf_iconv \ ufs \ uinput \ unionfs \ usb \ ${_vesa} \ virtio \ vge \ ${_viawd} \ videomode \ vkbd \ ${_vmd} \ ${_vmm} \ ${_vmware} \ vr \ vte \ ${_wbwd} \ wlan \ wlan_acl \ wlan_amrr \ wlan_ccmp \ wlan_rssadapt \ wlan_tkip \ wlan_wep \ wlan_xauth \ ${_wpi} \ ${_wpifw} \ ${_x86bios} \ xdr \ xl \ xz \ zlib .if ${MK_AUTOFS} != "no" || defined(ALL_MODULES) _autofs= autofs .endif .if ${MK_CDDL} != "no" || defined(ALL_MODULES) .if (${MACHINE_CPUARCH} != "arm" || ${MACHINE_ARCH:Marmv[67]*} != "") && \ ${MACHINE_CPUARCH} != "mips" .if ${KERN_OPTS:MKDTRACE_HOOKS} SUBDIR+= dtrace .endif .endif SUBDIR+= opensolaris .endif .if ${MK_CRYPT} != "no" || defined(ALL_MODULES) .if exists(${SRCTOP}/sys/opencrypto) _crypto= crypto _cryptodev= cryptodev _random_fortuna=random_fortuna _random_other= random_other .endif .endif .if ${MK_CUSE} != "no" || defined(ALL_MODULES) SUBDIR+= cuse .endif .if ${MK_EFI} != "no" .if ${MACHINE_CPUARCH} == "aarch64" || ${MACHINE_CPUARCH} == "amd64" _efirt= efirt .endif .endif .if (${MK_INET_SUPPORT} != "no" || ${MK_INET6_SUPPORT} != "no") || \ defined(ALL_MODULES) _carp= carp _toecore= toecore _if_enc= if_enc _if_gif= if_gif _if_gre= if_gre _ipfw_pmod= ipfw_pmod .if ${KERN_OPTS:MIPSEC_SUPPORT} && !${KERN_OPTS:MIPSEC} _ipsec= ipsec .endif .if ${KERN_OPTS:MSCTP_SUPPORT} || ${KERN_OPTS:MSCTP} _sctp= sctp .endif .endif .if (${MK_INET_SUPPORT} != "no" && ${MK_INET6_SUPPORT} != "no") || \ defined(ALL_MODULES) _if_stf= if_stf .endif .if ${MK_INET_SUPPORT} != "no" || defined(ALL_MODULES) _if_me= if_me _ipdivert= ipdivert _ipfw= ipfw .if ${MK_INET6_SUPPORT} != "no" || defined(ALL_MODULES) _ipfw_nat64= ipfw_nat64 .endif .endif .if ${MK_INET6_SUPPORT} != "no" || defined(ALL_MODULES) _ipfw_nptv6= ipfw_nptv6 .endif .if ${MK_IPFILTER} != "no" || defined(ALL_MODULES) _ipfilter= ipfilter .endif .if ${MK_INET_SUPPORT} != "no" && ${KERN_OPTS:MFIB_ALGO} _dpdk_lpm4= dpdk_lpm4 _fib_dxr= fib_dxr .endif .if ${MK_INET6_SUPPORT} != "no" && ${KERN_OPTS:MFIB_ALGO} _dpdk_lpm6= dpdk_lpm6 .endif .if ${MK_ISCSI} != "no" || defined(ALL_MODULES) SUBDIR+= cfiscsi SUBDIR+= iscsi SUBDIR+= iscsi_initiator .endif .if !empty(OPT_FDT) SUBDIR+= fdt .endif # Linuxulator .if ${MACHINE_CPUARCH} == "aarch64" || ${MACHINE_CPUARCH} == "amd64" || \ ${MACHINE_CPUARCH} == "i386" SUBDIR+= linprocfs SUBDIR+= linsysfs .endif .if ${MACHINE_CPUARCH} == "amd64" || ${MACHINE_CPUARCH} == "i386" SUBDIR+= linux .endif .if ${MACHINE_CPUARCH} == "aarch64" || ${MACHINE_CPUARCH} == "amd64" SUBDIR+= linux64 SUBDIR+= linux_common .endif .if ${MACHINE_CPUARCH} == "aarch64" || ${MACHINE_CPUARCH} == "amd64" || \ ${MACHINE_CPUARCH} == "i386" _ena= ena .if ${MK_OFED} != "no" || defined(ALL_MODULES) _ibcore= ibcore _ipoib= ipoib _iser= iser .endif _ipmi= ipmi _mlx4= mlx4 _mlx5= mlx5 .if (${MK_INET_SUPPORT} != "no" && ${MK_INET6_SUPPORT} != "no") || \ defined(ALL_MODULES) _mlx4en= mlx4en _mlx5en= mlx5en .endif .if ${MK_OFED} != "no" || defined(ALL_MODULES) _mthca= mthca _mlx4ib= mlx4ib _mlx5ib= mlx5ib .endif _ossl= ossl _vmware= vmware .endif .if ${MK_NETGRAPH} != "no" || defined(ALL_MODULES) _netgraph= netgraph .endif .if (${MK_PF} != "no" && (${MK_INET_SUPPORT} != "no" || \ ${MK_INET6_SUPPORT} != "no")) || defined(ALL_MODULES) _pf= pf _pflog= pflog .if ${MK_INET_SUPPORT} != "no" _pfsync= pfsync .endif .endif .if ${MK_SOURCELESS_UCODE} != "no" _bce= bce _fxp= fxp _ispfw= ispfw _ti= ti .if ${MACHINE_CPUARCH} != "mips" _mwlfw= mwlfw _otusfw= otusfw _ralfw= ralfw _rtwnfw= rtwnfw .endif .endif .if ${MK_SOURCELESS_UCODE} != "no" && ${MACHINE_CPUARCH} != "arm" && \ ${MACHINE_CPUARCH} != "mips" && \ ${MACHINE_ARCH} != "powerpc" && ${MACHINE_ARCH} != "powerpcspe" && \ ${MACHINE_CPUARCH} != "riscv" _cxgbe= cxgbe .endif .if ${MACHINE_ARCH} == "amd64" || ${MACHINE_ARCH} == "arm64" _ice= ice .if ${MK_SOURCELESS_UCODE} != "no" _ice_ddp= ice_ddp .endif .endif # These rely on 64bit atomics .if ${MACHINE_ARCH} != "powerpc" && ${MACHINE_ARCH} != "powerpcspe" && \ ${MACHINE_CPUARCH} != "mips" _mps= mps _mpr= mpr .endif .if ${MK_TESTS} != "no" || defined(ALL_MODULES) SUBDIR+= tests .endif .if ${MK_ZFS} != "no" || (defined(ALL_MODULES) && ${MACHINE_CPUARCH} != "powerpc") SUBDIR+= zfs .endif .if (${MACHINE_CPUARCH} == "mips" && ${MACHINE_ARCH:Mmips64} == "") _hwpmc_mips24k= hwpmc_mips24k _hwpmc_mips74k= hwpmc_mips74k .endif .if ${MACHINE_CPUARCH} != "aarch64" && ${MACHINE_CPUARCH} != "arm" && \ ${MACHINE_CPUARCH} != "mips" && ${MACHINE_CPUARCH} != "powerpc" && \ ${MACHINE_CPUARCH} != "riscv" _syscons= syscons .endif .if ${MACHINE_CPUARCH} != "mips" # no BUS_SPACE_UNSPECIFIED # No barrier instruction support (specific to this driver) _sym= sym # intr_disable() is a macro, causes problems .if ${MK_SOURCELESS_UCODE} != "no" _cxgb= cxgb .endif .endif .if ${MACHINE_CPUARCH} == "aarch64" _allwinner= allwinner _armv8crypto= armv8crypto _dwwdt= dwwdt _em= em +_felix= felix _rockchip= rockchip .endif .if ${MACHINE_CPUARCH} == "aarch64" || ${MACHINE_CPUARCH} == "arm" _sdhci_fdt= sdhci_fdt .endif .if ${MACHINE_CPUARCH} == "i386" || ${MACHINE_CPUARCH} == "amd64" _agp= agp _aout= aout _bios= bios .if ${MK_SOURCELESS_UCODE} != "no" _bxe= bxe .endif _cardbus= cardbus _cbb= cbb _cpuctl= cpuctl _cpufreq= cpufreq _dpms= dpms _em= em _et= et _ftwd= ftwd _exca= exca _igc= igc _io= io _itwd= itwd _ix= ix _ixv= ixv .if ${MK_SOURCELESS_UCODE} != "no" _lio= lio .endif _nctgpio= nctgpio _ntb= ntb _ocs_fc= ocs_fc _qat= qat _qatfw= qatfw .if ${MK_OFED} != "no" || defined(ALL_MODULES) _rdma= rdma .endif _safe= safe _speaker= speaker _splash= splash _sppp= sppp _wbwd= wbwd _aac= aac _aacraid= aacraid _acpi= acpi .if ${MK_CRYPT} != "no" || defined(ALL_MODULES) _aesni= aesni .endif _amd_ecc_inject=amd_ecc_inject _amdsbwd= amdsbwd _amdsmn= amdsmn _amdtemp= amdtemp _arcmsr= arcmsr _asmc= asmc .if ${MK_CRYPT} != "no" || defined(ALL_MODULES) _blake2= blake2 .endif _bytgpio= bytgpio _chvgpio= chvgpio _ciss= ciss _chromebook_platform= chromebook_platform _coretemp= coretemp .if ${MK_SOURCELESS_HOST} != "no" && empty(KCSAN_ENABLED) _hpt27xx= hpt27xx .endif _hptiop= hptiop .if ${MK_SOURCELESS_HOST} != "no" && empty(KCSAN_ENABLED) _hptmv= hptmv _hptnr= hptnr _hptrr= hptrr .endif _hyperv= hyperv _ichwd= ichwd _ida= ida _iir= iir _intelspi= intelspi _ips= ips _isci= isci _ipw= ipw _iwi= iwi _iwm= iwm _iwn= iwn .if ${MK_SOURCELESS_UCODE} != "no" _ipwfw= ipwfw _iwifw= iwifw _iwmfw= iwmfw _iwnfw= iwnfw .endif _mly= mly _nfe= nfe _nvd= nvd _nvme= nvme _nvram= nvram .if ${MK_CRYPT} != "no" || defined(ALL_MODULES) _padlock= padlock _padlock_rng= padlock_rng _rdrand_rng= rdrand_rng .endif _pchtherm = pchtherm _s3= s3 _sdhci_acpi= sdhci_acpi _superio= superio _tpm= tpm _twa= twa _vesa= vesa _viawd= viawd _wpi= wpi .if ${MK_SOURCELESS_UCODE} != "no" _wpifw= wpifw .endif _x86bios= x86bios .endif .if ${MACHINE_CPUARCH} == "amd64" _amdgpio= amdgpio _ccp= ccp _iavf= iavf _ioat= ioat _ixl= ixl _nvdimm= nvdimm _pms= pms _qlxge= qlxge _qlxgb= qlxgb _sume= sume _vmd= vmd .if ${MK_SOURCELESS_UCODE} != "no" _qlxgbe= qlxgbe _qlnx= qlnx .endif _sfxge= sfxge _sgx= sgx _sgx_linux= sgx_linux _smartpqi= smartpqi .if ${MK_BHYVE} != "no" || defined(ALL_MODULES) .if ${KERN_OPTS:MSMP} _vmm= vmm .endif .endif .endif .if ${MACHINE_CPUARCH} == "i386" # XXX some of these can move to the general case when de-i386'ed # XXX some of these can move now, but are untested on other architectures. _3dfx= 3dfx _3dfx_linux= 3dfx_linux .if ${MK_SOURCELESS_HOST} != "no" _ce= ce .endif .if ${MK_SOURCELESS_HOST} != "no" _cp= cp .endif _glxiic= glxiic _glxsb= glxsb _pcfclock= pcfclock _pst= pst _sbni= sbni .endif .if ${MACHINE_ARCH} == "armv7" _cfi= cfi _cpsw= cpsw .endif .if ${MACHINE_CPUARCH} == "powerpc" _aacraid= aacraid _agp= agp _an= an _cardbus= cardbus _cbb= cbb _cfi= cfi _cpufreq= cpufreq _exca= exca _ffec= ffec _nvd= nvd _nvme= nvme .endif .if ${MACHINE_ARCH:Mpowerpc64*} != "" _ipmi= ipmi _ixl= ixl _nvram= opal_nvram .endif .if ${MACHINE_CPUARCH} == "powerpc" && ${MACHINE_ARCH} != "powerpcspe" # Don't build powermac_nvram for powerpcspe, it's never supported. _nvram+= powermac_nvram .endif .if (${MACHINE_CPUARCH} == "aarch64" || ${MACHINE_CPUARCH} == "amd64" || \ ${MACHINE_ARCH:Marmv[67]*} != "" || ${MACHINE_CPUARCH} == "i386") _cloudabi32= cloudabi32 .endif .if ${MACHINE_CPUARCH} == "aarch64" || ${MACHINE_CPUARCH} == "amd64" _cloudabi64= cloudabi64 .endif .endif .if ${MACHINE_ARCH:Marmv[67]*} != "" || ${MACHINE_CPUARCH} == "aarch64" _bcm283x_clkman= bcm283x_clkman _bcm283x_pwm= bcm283x_pwm .endif .if !(${COMPILER_TYPE} == "clang" && ${COMPILER_VERSION} < 110000) # LLVM 10 crashes when building if_malo_pci.c, fixed in LLVM11: # https://bugs.llvm.org/show_bug.cgi?id=44351 _malo= malo .endif SUBDIR+=${MODULES_EXTRA} .for reject in ${WITHOUT_MODULES} SUBDIR:= ${SUBDIR:N${reject}} .endfor # Calling kldxref(8) for each module is expensive. .if !defined(NO_XREF) .MAKEFLAGS+= -DNO_XREF afterinstall: .PHONY @if type kldxref >/dev/null 2>&1; then \ ${ECHO} ${KLDXREF_CMD} ${DESTDIR}${KMODDIR}; \ ${KLDXREF_CMD} ${DESTDIR}${KMODDIR}; \ fi .endif SUBDIR:= ${SUBDIR:u:O} .include diff --git a/sys/modules/felix/Makefile b/sys/modules/felix/Makefile new file mode 100644 index 000000000000..cfe36a58c3dc --- /dev/null +++ b/sys/modules/felix/Makefile @@ -0,0 +1,34 @@ +#- +# SPDX-License-Identifier: BSD-2-Clause-FreeBSD +# +# Copyright (c) 2021 Alstom Group. +# Copyright (c) 2021 Semihalf. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. 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. +# +# THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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. +# + +.PATH: ${SRCTOP}/sys/dev/etherswitch/felix + +KMOD = felix +SRCS = felix.c + +.include