mirror of
git://git.openwrt.org/openwrt/openwrt.git
synced 2025-12-06 04:34:00 -05:00
microchipsw: add support for Microchip LAN969x switches
Add a new microchipsw target aimed add supporting Microchip switch SoC-s. Start by supporting LAN969x SoC-s as the first subtarget. Signed-off-by: Robert Marko <robert.marko@sartura.hr>
This commit is contained in:
parent
5e3a602def
commit
88a404a2d1
6
.github/labeler.yml
vendored
6
.github/labeler.yml
vendored
@ -126,6 +126,12 @@
|
||||
- "target/linux/mediatek/**"
|
||||
- "package/boot/arm-trusted-firmware-mediatek/**"
|
||||
- "package/boot/uboot-mediatek/**"
|
||||
"target/microchipsw":
|
||||
- changed-files:
|
||||
- any-glob-to-any-file:
|
||||
- "target/linux/microchipsw/**"
|
||||
- "package/boot/arm-trusted-firmware-microchipsw/**"
|
||||
- "package/boot/uboot-microchipsw/**"
|
||||
"target/mpc85xx":
|
||||
- changed-files:
|
||||
- any-glob-to-any-file:
|
||||
|
||||
@ -18,6 +18,7 @@ menu "Target Images"
|
||||
default TARGET_INITRAMFS_COMPRESSION_LZMA if TARGET_mpc85xx
|
||||
default TARGET_INITRAMFS_COMPRESSION_LZMA if TARGET_ramips
|
||||
default TARGET_INITRAMFS_COMPRESSION_ZSTD if TARGET_qualcommax
|
||||
default TARGET_INITRAMFS_COMPRESSION_ZSTD if TARGET_microchipsw
|
||||
default TARGET_INITRAMFS_COMPRESSION_XZ if USES_SEPARATE_INITRAMFS
|
||||
default TARGET_INITRAMFS_COMPRESSION_NONE
|
||||
depends on TARGET_ROOTFS_INITRAMFS
|
||||
|
||||
20
target/linux/microchipsw/Makefile
Normal file
20
target/linux/microchipsw/Makefile
Normal file
@ -0,0 +1,20 @@
|
||||
include $(TOPDIR)/rules.mk
|
||||
|
||||
ARCH:=aarch64
|
||||
BOARD:=microchipsw
|
||||
BOARDNAME:=Microchip switches
|
||||
FEATURES:=squashfs ramdisk fpu rtc emmc source-only
|
||||
KERNELNAME:=Image
|
||||
CPU_TYPE:=cortex-a53
|
||||
SUBTARGETS:=lan969x
|
||||
|
||||
KERNEL_PATCHVER:=6.12
|
||||
|
||||
include $(INCLUDE_DIR)/target.mk
|
||||
DEFAULT_PACKAGES += \
|
||||
kmod-gpio-button-hotplug \
|
||||
kmod-leds-gpio \
|
||||
uboot-envtools \
|
||||
ethtool-full
|
||||
|
||||
$(eval $(call BuildTarget))
|
||||
538
target/linux/microchipsw/dts/lan969x.dtsi
Normal file
538
target/linux/microchipsw/dts/lan969x.dtsi
Normal file
@ -0,0 +1,538 @@
|
||||
// SPDX-License-Identifier: (GPL-2.0-or-later OR MIT)
|
||||
/*
|
||||
* Copyright (c) 2025 Microchip Technology Inc. and its subsidiaries.
|
||||
*/
|
||||
|
||||
#include <dt-bindings/clock/microchip,lan969x.h>
|
||||
#include <dt-bindings/dma/at91.h>
|
||||
#include <dt-bindings/interrupt-controller/arm-gic.h>
|
||||
#include <dt-bindings/mfd/at91-usart.h>
|
||||
#include <dt-bindings/mfd/atmel-flexcom.h>
|
||||
|
||||
/ {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <1>;
|
||||
|
||||
model = "Microchip LAN969x";
|
||||
compatible = "microchip,lan969x";
|
||||
interrupt-parent = <&gic>;
|
||||
|
||||
psci {
|
||||
compatible = "arm,psci-1.0";
|
||||
method = "smc";
|
||||
};
|
||||
|
||||
clocks {
|
||||
fx100_clk: fx100-clk {
|
||||
compatible = "fixed-clock";
|
||||
#clock-cells = <0>;
|
||||
clock-frequency = <320000000>;
|
||||
};
|
||||
|
||||
cpu_clk: cpu-clk {
|
||||
compatible = "fixed-clock";
|
||||
#clock-cells = <0>;
|
||||
clock-frequency = <1000000000>;
|
||||
};
|
||||
|
||||
ddr_clk: ddr-clk {
|
||||
compatible = "fixed-clock";
|
||||
#clock-cells = <0>;
|
||||
clock-frequency = <600000000>;
|
||||
};
|
||||
|
||||
fabric_clk: fabric-clk {
|
||||
compatible = "fixed-clock";
|
||||
#clock-cells = <0>;
|
||||
clock-frequency = <250000000>;
|
||||
};
|
||||
};
|
||||
|
||||
cpus {
|
||||
#address-cells = <2>;
|
||||
#size-cells = <0>;
|
||||
|
||||
cpu0: cpu@0 {
|
||||
compatible = "arm,cortex-a53";
|
||||
device_type = "cpu";
|
||||
reg = <0x0 0x0>;
|
||||
next-level-cache = <&l2_0>;
|
||||
};
|
||||
|
||||
l2_0: l2-cache {
|
||||
compatible = "cache";
|
||||
cache-level = <2>;
|
||||
cache-unified;
|
||||
};
|
||||
};
|
||||
|
||||
pmu {
|
||||
compatible = "arm,cortex-a53-pmu";
|
||||
interrupts = <GIC_SPI 77 IRQ_TYPE_LEVEL_HIGH>;
|
||||
};
|
||||
|
||||
timer {
|
||||
compatible = "arm,armv8-timer";
|
||||
interrupts = <GIC_PPI 13 IRQ_TYPE_LEVEL_LOW>, /* Secure Phys IRQ */
|
||||
<GIC_PPI 14 IRQ_TYPE_LEVEL_LOW>, /* Non-secure Phys IRQ */
|
||||
<GIC_PPI 11 IRQ_TYPE_LEVEL_LOW>, /* Virt IRQ */
|
||||
<GIC_PPI 10 IRQ_TYPE_LEVEL_LOW>; /* Hyp IRQ */
|
||||
};
|
||||
|
||||
axi: axi {
|
||||
compatible = "simple-bus";
|
||||
#address-cells = <1>;
|
||||
#size-cells = <1>;
|
||||
ranges;
|
||||
|
||||
usb: usb@300000 {
|
||||
compatible = "microchip,lan9691-dwc3", "snps,dwc3";
|
||||
reg = <0x300000 0x80000>;
|
||||
interrupts = <GIC_SPI 80 IRQ_TYPE_LEVEL_HIGH>;
|
||||
clocks = <&clks GCK_GATE_USB_DRD>,
|
||||
<&clks GCK_ID_USB_REFCLK>;
|
||||
clock-names = "bus_early", "ref";
|
||||
assigned-clocks = <&clks GCK_ID_USB_REFCLK>;
|
||||
assigned-clock-rates = <60000000>;
|
||||
maximum-speed = "high-speed";
|
||||
dr_mode = "host";
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
otp: otp@e0021000 {
|
||||
compatible = "microchip,lan9691-otpc";
|
||||
reg = <0xe0021000 0x1000>;
|
||||
};
|
||||
|
||||
flx0: flexcom@e0040000 {
|
||||
compatible = "atmel,sama5d2-flexcom";
|
||||
reg = <0xe0040000 0x100>;
|
||||
clocks = <&clks GCK_ID_FLEXCOM0>;
|
||||
#address-cells = <1>;
|
||||
#size-cells = <1>;
|
||||
ranges = <0x0 0xe0040000 0x800>;
|
||||
status = "disabled";
|
||||
|
||||
usart0: serial@200 {
|
||||
compatible = "atmel,at91sam9260-usart";
|
||||
reg = <0x200 0x200>;
|
||||
atmel,usart-mode = <AT91_USART_MODE_SERIAL>;
|
||||
interrupts = <GIC_SPI 46 IRQ_TYPE_LEVEL_HIGH>;
|
||||
dmas = <&dma AT91_XDMAC_DT_PERID(3)>,
|
||||
<&dma AT91_XDMAC_DT_PERID(2)>;
|
||||
dma-names = "tx", "rx";
|
||||
clocks = <&fabric_clk>;
|
||||
clock-names = "usart";
|
||||
atmel,fifo-size = <32>;
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
spi0: spi@400 {
|
||||
compatible = "atmel,at91rm9200-spi";
|
||||
reg = <0x400 0x200>;
|
||||
interrupts = <GIC_SPI 46 IRQ_TYPE_LEVEL_HIGH>;
|
||||
dmas = <&dma AT91_XDMAC_DT_PERID(3)>,
|
||||
<&dma AT91_XDMAC_DT_PERID(2)>;
|
||||
dma-names = "tx", "rx";
|
||||
clocks = <&fabric_clk>;
|
||||
clock-names = "spi_clk";
|
||||
atmel,fifo-size = <32>;
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
i2c0: i2c@600 {
|
||||
compatible = "microchip,sam9x60-i2c";
|
||||
reg = <0x600 0x200>;
|
||||
interrupts = <GIC_SPI 46 IRQ_TYPE_LEVEL_HIGH>;
|
||||
dmas = <&dma AT91_XDMAC_DT_PERID(3)>,
|
||||
<&dma AT91_XDMAC_DT_PERID(2)>;
|
||||
dma-names = "tx", "rx";
|
||||
clocks = <&fabric_clk>;
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
status = "disabled";
|
||||
};
|
||||
};
|
||||
|
||||
flx1: flexcom@e0044000 {
|
||||
compatible = "atmel,sama5d2-flexcom";
|
||||
reg = <0xe0044000 0x100>;
|
||||
clocks = <&clks GCK_ID_FLEXCOM1>;
|
||||
#address-cells = <1>;
|
||||
#size-cells = <1>;
|
||||
ranges = <0x0 0xe0044000 0x800>;
|
||||
status = "disabled";
|
||||
|
||||
usart1: serial@200 {
|
||||
compatible = "atmel,at91sam9260-usart";
|
||||
reg = <0x200 0x200>;
|
||||
atmel,usart-mode = <AT91_USART_MODE_SERIAL>;
|
||||
interrupts = <GIC_SPI 47 IRQ_TYPE_LEVEL_HIGH>;
|
||||
dmas = <&dma AT91_XDMAC_DT_PERID(3)>,
|
||||
<&dma AT91_XDMAC_DT_PERID(2)>;
|
||||
dma-names = "tx", "rx";
|
||||
clocks = <&fabric_clk>;
|
||||
clock-names = "usart";
|
||||
atmel,fifo-size = <32>;
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
spi1: spi@400 {
|
||||
compatible = "atmel,at91rm9200-spi";
|
||||
reg = <0x400 0x200>;
|
||||
interrupts = <GIC_SPI 47 IRQ_TYPE_LEVEL_HIGH>;
|
||||
dmas = <&dma AT91_XDMAC_DT_PERID(3)>,
|
||||
<&dma AT91_XDMAC_DT_PERID(2)>;
|
||||
dma-names = "tx", "rx";
|
||||
clocks = <&fabric_clk>;
|
||||
clock-names = "spi_clk";
|
||||
atmel,fifo-size = <32>;
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
i2c1: i2c@600 {
|
||||
compatible = "microchip,sam9x60-i2c";
|
||||
reg = <0x600 0x200>;
|
||||
interrupts = <GIC_SPI 47 IRQ_TYPE_LEVEL_HIGH>;
|
||||
dmas = <&dma AT91_XDMAC_DT_PERID(3)>,
|
||||
<&dma AT91_XDMAC_DT_PERID(2)>;
|
||||
dma-names = "tx", "rx";
|
||||
clocks = <&fabric_clk>;
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
status = "disabled";
|
||||
};
|
||||
};
|
||||
|
||||
trng: rng@e0048000 {
|
||||
compatible = "atmel,at91sam9g45-trng";
|
||||
reg = <0xe0048000 0x100>;
|
||||
clocks = <&fabric_clk>;
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
aes: crypto@e004c000 {
|
||||
compatible = "atmel,at91sam9g46-aes";
|
||||
reg = <0xe004c000 0x100>;
|
||||
interrupts = <GIC_SPI 51 IRQ_TYPE_LEVEL_HIGH>;
|
||||
dmas = <&dma AT91_XDMAC_DT_PERID(12)>,
|
||||
<&dma AT91_XDMAC_DT_PERID(13)>;
|
||||
dma-names = "tx", "rx";
|
||||
clocks = <&fabric_clk>;
|
||||
clock-names = "aes_clk";
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
flx2: flexcom@e0060000 {
|
||||
compatible = "atmel,sama5d2-flexcom";
|
||||
reg = <0xe0060000 0x100>;
|
||||
clocks = <&clks GCK_ID_FLEXCOM2>;
|
||||
#address-cells = <1>;
|
||||
#size-cells = <1>;
|
||||
ranges = <0x0 0xe0060000 0x800>;
|
||||
status = "disabled";
|
||||
|
||||
usart2: serial@200 {
|
||||
compatible = "atmel,at91sam9260-usart";
|
||||
reg = <0x200 0x200>;
|
||||
atmel,usart-mode = <AT91_USART_MODE_SERIAL>;
|
||||
interrupts = <GIC_SPI 48 IRQ_TYPE_LEVEL_HIGH>;
|
||||
dmas = <&dma AT91_XDMAC_DT_PERID(7)>,
|
||||
<&dma AT91_XDMAC_DT_PERID(6)>;
|
||||
dma-names = "tx", "rx";
|
||||
clocks = <&fabric_clk>;
|
||||
clock-names = "usart";
|
||||
atmel,fifo-size = <32>;
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
spi2: spi@400 {
|
||||
compatible = "atmel,at91rm9200-spi";
|
||||
reg = <0x400 0x200>;
|
||||
interrupts = <GIC_SPI 48 IRQ_TYPE_LEVEL_HIGH>;
|
||||
dmas = <&dma AT91_XDMAC_DT_PERID(7)>,
|
||||
<&dma AT91_XDMAC_DT_PERID(6)>;
|
||||
dma-names = "tx", "rx";
|
||||
clocks = <&fabric_clk>;
|
||||
clock-names = "spi_clk";
|
||||
atmel,fifo-size = <32>;
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
i2c2: i2c@600 {
|
||||
compatible = "microchip,sam9x60-i2c";
|
||||
reg = <0x600 0x200>;
|
||||
interrupts = <GIC_SPI 48 IRQ_TYPE_LEVEL_HIGH>;
|
||||
clocks = <&fabric_clk>;
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
status = "disabled";
|
||||
};
|
||||
};
|
||||
|
||||
flx3: flexcom@e0064000 {
|
||||
compatible = "atmel,sama5d2-flexcom";
|
||||
reg = <0xe0064000 0x100>;
|
||||
clocks = <&clks GCK_ID_FLEXCOM3>;
|
||||
#address-cells = <1>;
|
||||
#size-cells = <1>;
|
||||
ranges = <0x0 0xe0064000 0x800>;
|
||||
status = "disabled";
|
||||
|
||||
usart3: serial@200 {
|
||||
compatible = "atmel,at91sam9260-usart";
|
||||
reg = <0x200 0x200>;
|
||||
atmel,usart-mode = <AT91_USART_MODE_SERIAL>;
|
||||
interrupts = <GIC_SPI 49 IRQ_TYPE_LEVEL_HIGH>;
|
||||
dmas = <&dma AT91_XDMAC_DT_PERID(9)>,
|
||||
<&dma AT91_XDMAC_DT_PERID(8)>;
|
||||
dma-names = "tx", "rx";
|
||||
clocks = <&fabric_clk>;
|
||||
clock-names = "usart";
|
||||
atmel,fifo-size = <32>;
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
spi3: spi@400 {
|
||||
compatible = "atmel,at91rm9200-spi";
|
||||
reg = <0x400 0x200>;
|
||||
interrupts = <GIC_SPI 49 IRQ_TYPE_LEVEL_HIGH>;
|
||||
dmas = <&dma AT91_XDMAC_DT_PERID(9)>,
|
||||
<&dma AT91_XDMAC_DT_PERID(8)>;
|
||||
dma-names = "tx", "rx";
|
||||
clocks = <&fabric_clk>;
|
||||
clock-names = "spi_clk";
|
||||
atmel,fifo-size = <32>;
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
i2c3: i2c@600 {
|
||||
compatible = "microchip,sam9x60-i2c";
|
||||
reg = <0x600 0x200>;
|
||||
interrupts = <GIC_SPI 49 IRQ_TYPE_LEVEL_HIGH>;
|
||||
dmas = <&dma AT91_XDMAC_DT_PERID(9)>,
|
||||
<&dma AT91_XDMAC_DT_PERID(8)>;
|
||||
dma-names = "tx", "rx";
|
||||
clocks = <&fabric_clk>;
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
status = "disabled";
|
||||
};
|
||||
};
|
||||
|
||||
dma: dma-controller@e0068000 {
|
||||
compatible = "microchip,sama7g5-dma";
|
||||
reg = <0xe0068000 0x1000>;
|
||||
interrupts = <GIC_SPI 44 IRQ_TYPE_LEVEL_HIGH>;
|
||||
dma-channels = <16>;
|
||||
#dma-cells = <1>;
|
||||
clocks = <&fabric_clk>;
|
||||
clock-names = "dma_clk";
|
||||
};
|
||||
|
||||
sha: crypto@e006c000 {
|
||||
compatible = "atmel,at91sam9g46-sha";
|
||||
reg = <0xe006c000 0xec>;
|
||||
interrupts = <GIC_SPI 55 IRQ_TYPE_LEVEL_HIGH>;
|
||||
dmas = <&dma AT91_XDMAC_DT_PERID(14)>;
|
||||
dma-names = "tx";
|
||||
clocks = <&fabric_clk>;
|
||||
clock-names = "sha_clk";
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
timer: timer@e008c000 {
|
||||
compatible = "snps,dw-apb-timer";
|
||||
reg = <0xe008c000 0x400>;
|
||||
clocks = <&fabric_clk>;
|
||||
clock-names = "timer";
|
||||
interrupts = <GIC_SPI 37 IRQ_TYPE_LEVEL_HIGH>;
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
watchdog: watchdog@e0090000 {
|
||||
compatible = "snps,dw-wdt";
|
||||
reg = <0xe0090000 0x1000>;
|
||||
interrupts = <GIC_SPI 36 IRQ_TYPE_LEVEL_HIGH>;
|
||||
clocks = <&fabric_clk>;
|
||||
};
|
||||
|
||||
cpu_ctrl: syscon@e00c0000 {
|
||||
compatible = "microchip,lan966x-cpu-syscon", "syscon";
|
||||
reg = <0xe00c0000 0x350>;
|
||||
};
|
||||
|
||||
switch: switch@e00c0000 {
|
||||
compatible = "microchip,lan9691-switch";
|
||||
reg = <0xe00c0000 0x0010000>,
|
||||
<0xe2010000 0x1410000>;
|
||||
reg-names = "cpu", "devices";
|
||||
interrupt-names = "xtr", "fdma", "ptp";
|
||||
interrupts = <GIC_SPI 10 IRQ_TYPE_LEVEL_HIGH>,
|
||||
<GIC_SPI 88 IRQ_TYPE_LEVEL_HIGH>,
|
||||
<GIC_SPI 9 IRQ_TYPE_LEVEL_HIGH>;
|
||||
resets = <&reset 0>;
|
||||
reset-names = "switch";
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
clks: clock-controller@e00c00b4 {
|
||||
compatible = "microchip,lan9691-gck";
|
||||
#clock-cells = <1>;
|
||||
clocks = <&cpu_clk>, <&ddr_clk>, <&fx100_clk>;
|
||||
clock-names = "cpu", "ddr", "sys";
|
||||
reg = <0xe00c00b4 0x30>, <0xe00c0308 0x4>;
|
||||
};
|
||||
|
||||
qspi0: spi@e0804000 {
|
||||
compatible = "microchip,lan9691-qspi";
|
||||
reg = <0xe0804000 0x00000100>,
|
||||
<0x20000000 0x08000000>;
|
||||
reg-names = "qspi_base", "qspi_mmap";
|
||||
interrupts = <GIC_SPI 43 IRQ_TYPE_LEVEL_HIGH>;
|
||||
clocks = <&fabric_clk>, <&clks GCK_ID_QSPI0>;
|
||||
clock-names = "pclk", "gclk";
|
||||
assigned-clocks = <&clks GCK_ID_QSPI0>;
|
||||
assigned-clock-rates = <100000000>;
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
sdmmc0: mmc@e0830000 {
|
||||
compatible = "microchip,lan9691-sdhci";
|
||||
reg = <0xe0830000 0x00000300>;
|
||||
interrupts = <GIC_SPI 64 IRQ_TYPE_LEVEL_HIGH>;
|
||||
clocks = <&clks GCK_ID_SDMMC0>, <&clks GCK_ID_SDMMC0>;
|
||||
clock-names = "hclock", "multclk";
|
||||
assigned-clocks = <&clks GCK_ID_SDMMC0>;
|
||||
assigned-clock-rates = <100000000>;
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
sdmmc1: mmc@e0838000 {
|
||||
compatible = "microchip,lan9691-sdhci";
|
||||
reg = <0xe0838000 0x00000300>;
|
||||
interrupts = <GIC_SPI 50 IRQ_TYPE_LEVEL_HIGH>;
|
||||
clocks = <&clks GCK_ID_SDMMC1>, <&clks GCK_ID_SDMMC1>;
|
||||
clock-names = "hclock", "multclk";
|
||||
assigned-clocks = <&clks GCK_ID_SDMMC1>;
|
||||
assigned-clock-rates = <45000000>;
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
qspi2: spi@e0834000 {
|
||||
compatible = "microchip,lan9691-qspi";
|
||||
reg = <0xe0834000 0x00000100>,
|
||||
<0x30000000 0x04000000>;
|
||||
reg-names = "qspi_base", "qspi_mmap";
|
||||
interrupts = <GIC_SPI 66 IRQ_TYPE_LEVEL_HIGH>;
|
||||
clocks = <&fabric_clk>, <&clks GCK_ID_QSPI2>;
|
||||
clock-names = "pclk", "gclk";
|
||||
assigned-clocks = <&clks GCK_ID_QSPI2>;
|
||||
assigned-clock-rates = <100000000>;
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
reset: reset-controller@e201000c {
|
||||
compatible = "microchip,lan9691-switch-reset", "microchip,lan966x-switch-reset";
|
||||
reg = <0xe201000c 0x4>;
|
||||
reg-names = "gcb";
|
||||
#reset-cells = <1>;
|
||||
cpu-syscon = <&cpu_ctrl>;
|
||||
};
|
||||
|
||||
gpio: pinctrl@e20100d4 {
|
||||
compatible = "microchip,lan9691-pinctrl";
|
||||
reg = <0xe20100d4 0xd4>,
|
||||
<0xe2010370 0xa8>;
|
||||
gpio-controller;
|
||||
#gpio-cells = <2>;
|
||||
gpio-ranges = <&gpio 0 0 66>;
|
||||
interrupt-controller;
|
||||
interrupts = <GIC_SPI 15 IRQ_TYPE_LEVEL_HIGH>;
|
||||
#interrupt-cells = <2>;
|
||||
};
|
||||
|
||||
mdio0: mdio@e20101a8 {
|
||||
compatible = "mscc,ocelot-miim";
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
reg = <0xe20101a8 0x24>;
|
||||
clocks = <&fx100_clk>;
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
mdio1: mdio@e20101cc {
|
||||
compatible = "mscc,ocelot-miim";
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
reg = <0xe20101cc 0x24>;
|
||||
clocks = <&fx100_clk>;
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
sgpio: gpio@e2010230 {
|
||||
compatible = "microchip,sparx5-sgpio";
|
||||
reg = <0xe2010230 0x118>;
|
||||
clocks = <&fx100_clk>;
|
||||
resets = <&reset 0>;
|
||||
reset-names = "switch";
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
status = "disabled";
|
||||
|
||||
sgpio_in: gpio@0 {
|
||||
compatible = "microchip,sparx5-sgpio-bank";
|
||||
reg = <0>;
|
||||
gpio-controller;
|
||||
#gpio-cells = <3>;
|
||||
interrupts = <GIC_SPI 16 IRQ_TYPE_LEVEL_HIGH>;
|
||||
interrupt-controller;
|
||||
#interrupt-cells = <3>;
|
||||
};
|
||||
|
||||
sgpio_out: gpio@1 {
|
||||
compatible = "microchip,sparx5-sgpio-bank";
|
||||
reg = <1>;
|
||||
gpio-controller;
|
||||
#gpio-cells = <3>;
|
||||
};
|
||||
};
|
||||
|
||||
tmon: hwmon@e2020100 {
|
||||
compatible = "microchip,sparx5-temp";
|
||||
reg = <0xe2020100 0xc>;
|
||||
clocks = <&fx100_clk>;
|
||||
#thermal-sensor-cells = <0>;
|
||||
};
|
||||
|
||||
serdes: serdes@e3410000 {
|
||||
compatible = "microchip,lan9691-serdes";
|
||||
#phy-cells = <1>;
|
||||
clocks = <&fabric_clk>;
|
||||
reg = <0xe3410000 0x150000>;
|
||||
};
|
||||
|
||||
gic: interrupt-controller@e8c11000 {
|
||||
compatible = "arm,gic-400";
|
||||
#interrupt-cells = <3>;
|
||||
interrupt-controller;
|
||||
reg = <0xe8c11000 0x1000>, /* Distributor GICD_ */
|
||||
<0xe8c12000 0x2000>, /* CPU interface GICC_ */
|
||||
<0xe8c14000 0x2000>, /* Virt interface control */
|
||||
<0xe8c16000 0x2000>; /* Virt CPU interface */
|
||||
interrupts = <GIC_PPI 9 IRQ_TYPE_LEVEL_HIGH>;
|
||||
};
|
||||
};
|
||||
};
|
||||
21
target/linux/microchipsw/image/Makefile
Normal file
21
target/linux/microchipsw/image/Makefile
Normal file
@ -0,0 +1,21 @@
|
||||
include $(TOPDIR)/rules.mk
|
||||
include $(INCLUDE_DIR)/image.mk
|
||||
|
||||
define Device/Default
|
||||
PROFILES := Default
|
||||
KERNEL_LOADADDR := 0x60000000
|
||||
DEVICE_DTS = $$(SOC)-$(lastword $(subst _, ,$(1)))
|
||||
DEVICE_DTS_CONFIG := config-1
|
||||
DEVICE_DTS_DIR := ../dts
|
||||
IMAGES := sysupgrade.bin
|
||||
IMAGE/sysupgrade.bin = sysupgrade-tar | append-metadata
|
||||
IMAGE/sysupgrade.bin/squashfs :=
|
||||
endef
|
||||
|
||||
define Device/FitImage
|
||||
KERNEL_SUFFIX := -uImage.itb
|
||||
KERNEL = kernel-bin | libdeflate-gzip | fit gzip $$(KDIR)/image-$$(DEVICE_DTS).dtb
|
||||
KERNEL_NAME := Image
|
||||
endef
|
||||
|
||||
$(eval $(call BuildImage))
|
||||
272
target/linux/microchipsw/lan969x/config-default
Normal file
272
target/linux/microchipsw/lan969x/config-default
Normal file
@ -0,0 +1,272 @@
|
||||
CONFIG_64BIT=y
|
||||
CONFIG_ARCH_BINFMT_ELF_EXTRA_PHDRS=y
|
||||
CONFIG_ARCH_CORRECT_STACKTRACE_ON_KRETPROBE=y
|
||||
CONFIG_ARCH_DEFAULT_KEXEC_IMAGE_VERIFY_SIG=y
|
||||
CONFIG_ARCH_DMA_ADDR_T_64BIT=y
|
||||
CONFIG_ARCH_FORCE_MAX_ORDER=10
|
||||
CONFIG_ARCH_KEEP_MEMBLOCK=y
|
||||
CONFIG_ARCH_LAN969X=y
|
||||
CONFIG_ARCH_MHP_MEMMAP_ON_MEMORY_ENABLE=y
|
||||
CONFIG_ARCH_MICROCHIP=y
|
||||
CONFIG_ARCH_MMAP_RND_BITS=18
|
||||
CONFIG_ARCH_MMAP_RND_BITS_MAX=24
|
||||
CONFIG_ARCH_MMAP_RND_BITS_MIN=18
|
||||
CONFIG_ARCH_MMAP_RND_COMPAT_BITS_MIN=11
|
||||
CONFIG_ARCH_PKEY_BITS=3
|
||||
CONFIG_ARCH_PROC_KCORE_TEXT=y
|
||||
CONFIG_ARCH_SPARSEMEM_ENABLE=y
|
||||
CONFIG_ARCH_STACKWALK=y
|
||||
CONFIG_ARCH_SUSPEND_POSSIBLE=y
|
||||
CONFIG_ARCH_WANTS_EXECMEM_LATE=y
|
||||
CONFIG_ARCH_WANTS_NO_INSTR=y
|
||||
CONFIG_ARCH_WANTS_THP_SWAP=y
|
||||
CONFIG_ARM64=y
|
||||
CONFIG_ARM64_4K_PAGES=y
|
||||
CONFIG_ARM64_ERRATUM_819472=y
|
||||
CONFIG_ARM64_ERRATUM_824069=y
|
||||
CONFIG_ARM64_ERRATUM_826319=y
|
||||
CONFIG_ARM64_ERRATUM_827319=y
|
||||
CONFIG_ARM64_ERRATUM_843419=y
|
||||
CONFIG_ARM64_LD_HAS_FIX_ERRATUM_843419=y
|
||||
CONFIG_ARM64_PA_BITS=48
|
||||
CONFIG_ARM64_PA_BITS_48=y
|
||||
CONFIG_ARM64_PLATFORM_DEVICES=y
|
||||
CONFIG_ARM64_TAGGED_ADDR_ABI=y
|
||||
CONFIG_ARM64_VA_BITS=39
|
||||
CONFIG_ARM64_VA_BITS_39=y
|
||||
CONFIG_ARM64_WORKAROUND_CLEAN_CACHE=y
|
||||
CONFIG_ARM_AMBA=y
|
||||
CONFIG_ARM_ARCH_TIMER=y
|
||||
CONFIG_ARM_ARCH_TIMER_EVTSTREAM=y
|
||||
CONFIG_ARM_GIC=y
|
||||
CONFIG_ARM_GIC_V3=y
|
||||
CONFIG_ARM_GIC_V3_ITS=y
|
||||
CONFIG_ARM_PSCI_FW=y
|
||||
CONFIG_AT_XDMAC=y
|
||||
CONFIG_AUDIT_ARCH_COMPAT_GENERIC=y
|
||||
CONFIG_BUILTIN_RETURN_ADDRESS_STRIPS_PAC=y
|
||||
CONFIG_CC_HAVE_SHADOW_CALL_STACK=y
|
||||
CONFIG_CC_HAVE_STACKPROTECTOR_SYSREG=y
|
||||
CONFIG_CLONE_BACKWARDS=y
|
||||
CONFIG_COMMON_CLK=y
|
||||
CONFIG_COMMON_CLK_LAN966X=y
|
||||
CONFIG_COMPACT_UNEVICTABLE_DEFAULT=1
|
||||
# CONFIG_COMPAT_32BIT_TIME is not set
|
||||
CONFIG_CONTEXT_TRACKING=y
|
||||
CONFIG_CONTEXT_TRACKING_IDLE=y
|
||||
CONFIG_CPUMASK_OFFSTACK=y
|
||||
CONFIG_CPU_LITTLE_ENDIAN=y
|
||||
CONFIG_CPU_MITIGATIONS=y
|
||||
CONFIG_CPU_RMAP=y
|
||||
CONFIG_CRYPTO_DEV_ATMEL_AES=y
|
||||
CONFIG_CRYPTO_ECB=y
|
||||
CONFIG_CRYPTO_HW=y
|
||||
CONFIG_CRYPTO_LIB_BLAKE2S_GENERIC=y
|
||||
CONFIG_CRYPTO_LIB_GF128MUL=y
|
||||
CONFIG_CRYPTO_LIB_SHA1=y
|
||||
CONFIG_CRYPTO_LIB_UTILS=y
|
||||
CONFIG_DCACHE_WORD_ACCESS=y
|
||||
CONFIG_DEBUG_INFO=y
|
||||
CONFIG_DMADEVICES=y
|
||||
CONFIG_DMA_BOUNCE_UNALIGNED_KMALLOC=y
|
||||
CONFIG_DMA_DIRECT_REMAP=y
|
||||
CONFIG_DMA_ENGINE=y
|
||||
CONFIG_DMA_NEED_SYNC=y
|
||||
CONFIG_DMA_OF=y
|
||||
CONFIG_DTC=y
|
||||
CONFIG_DW_APB_TIMER=y
|
||||
CONFIG_DW_APB_TIMER_OF=y
|
||||
CONFIG_DW_WATCHDOG=y
|
||||
CONFIG_EDAC_SUPPORT=y
|
||||
CONFIG_EXCLUSIVE_SYSTEM_RAM=y
|
||||
CONFIG_FDMA=y
|
||||
CONFIG_FIXED_PHY=y
|
||||
CONFIG_FIX_EARLYCON_MEM=y
|
||||
CONFIG_FRAME_POINTER=y
|
||||
CONFIG_FS_IOMAP=y
|
||||
CONFIG_FUNCTION_ALIGNMENT=4
|
||||
CONFIG_FUNCTION_ALIGNMENT_4B=y
|
||||
CONFIG_FWNODE_MDIO=y
|
||||
CONFIG_FW_LOADER_PAGED_BUF=y
|
||||
CONFIG_FW_LOADER_SYSFS=y
|
||||
CONFIG_GCC_SUPPORTS_DYNAMIC_FTRACE_WITH_ARGS=y
|
||||
CONFIG_GENERIC_ALLOCATOR=y
|
||||
CONFIG_GENERIC_ARCH_TOPOLOGY=y
|
||||
CONFIG_GENERIC_BUG=y
|
||||
CONFIG_GENERIC_BUG_RELATIVE_POINTERS=y
|
||||
CONFIG_GENERIC_CLOCKEVENTS=y
|
||||
CONFIG_GENERIC_CLOCKEVENTS_BROADCAST=y
|
||||
CONFIG_GENERIC_CPU_AUTOPROBE=y
|
||||
CONFIG_GENERIC_CPU_DEVICES=y
|
||||
CONFIG_GENERIC_CPU_VULNERABILITIES=y
|
||||
CONFIG_GENERIC_CSUM=y
|
||||
CONFIG_GENERIC_EARLY_IOREMAP=y
|
||||
CONFIG_GENERIC_GETTIMEOFDAY=y
|
||||
CONFIG_GENERIC_IDLE_POLL_SETUP=y
|
||||
CONFIG_GENERIC_IOREMAP=y
|
||||
CONFIG_GENERIC_IRQ_EFFECTIVE_AFF_MASK=y
|
||||
CONFIG_GENERIC_IRQ_SHOW=y
|
||||
CONFIG_GENERIC_IRQ_SHOW_LEVEL=y
|
||||
CONFIG_GENERIC_LIB_DEVMEM_IS_ALLOWED=y
|
||||
CONFIG_GENERIC_MSI_IRQ=y
|
||||
CONFIG_GENERIC_PCI_IOMAP=y
|
||||
CONFIG_GENERIC_PHY=y
|
||||
CONFIG_GENERIC_PINCONF=y
|
||||
CONFIG_GENERIC_PINCTRL_GROUPS=y
|
||||
CONFIG_GENERIC_PINMUX_FUNCTIONS=y
|
||||
CONFIG_GENERIC_SCHED_CLOCK=y
|
||||
CONFIG_GENERIC_SMP_IDLE_THREAD=y
|
||||
CONFIG_GENERIC_STRNCPY_FROM_USER=y
|
||||
CONFIG_GENERIC_STRNLEN_USER=y
|
||||
CONFIG_GENERIC_TIME_VSYSCALL=y
|
||||
CONFIG_GPIOLIB_IRQCHIP=y
|
||||
CONFIG_GPIO_CDEV=y
|
||||
CONFIG_HARDIRQS_SW_RESEND=y
|
||||
CONFIG_HAS_DMA=y
|
||||
CONFIG_HAS_IOMEM=y
|
||||
CONFIG_HAS_IOPORT=y
|
||||
CONFIG_HWMON=y
|
||||
CONFIG_HW_RANDOM=y
|
||||
CONFIG_HW_RANDOM_ATMEL=y
|
||||
CONFIG_HZ_PERIODIC=y
|
||||
CONFIG_I2C=y
|
||||
CONFIG_I2C_AT91=y
|
||||
# CONFIG_I2C_AT91_SLAVE_EXPERIMENTAL is not set
|
||||
CONFIG_I2C_BOARDINFO=y
|
||||
CONFIG_I2C_CHARDEV=y
|
||||
CONFIG_I2C_HELPER_AUTO=y
|
||||
CONFIG_ILLEGAL_POINTER_VALUE=0xdead000000000000
|
||||
CONFIG_INITRAMFS_SOURCE=""
|
||||
CONFIG_IRQCHIP=y
|
||||
CONFIG_IRQ_DOMAIN=y
|
||||
CONFIG_IRQ_DOMAIN_HIERARCHY=y
|
||||
CONFIG_IRQ_FORCED_THREADING=y
|
||||
CONFIG_IRQ_MSI_LIB=y
|
||||
CONFIG_IRQ_WORK=y
|
||||
CONFIG_LAN969X_SWITCH=y
|
||||
CONFIG_LIBFDT=y
|
||||
CONFIG_LOCK_DEBUGGING_SUPPORT=y
|
||||
CONFIG_LOCK_SPIN_ON_OWNER=y
|
||||
CONFIG_LRU_GEN_WALKS_MMU=y
|
||||
CONFIG_MDIO_BUS=y
|
||||
CONFIG_MDIO_DEVICE=y
|
||||
CONFIG_MDIO_DEVRES=y
|
||||
CONFIG_MDIO_I2C=y
|
||||
CONFIG_MDIO_MSCC_MIIM=y
|
||||
CONFIG_MFD_AT91_USART=y
|
||||
CONFIG_MFD_ATMEL_FLEXCOM=y
|
||||
CONFIG_MFD_CORE=y
|
||||
CONFIG_MFD_SYSCON=y
|
||||
CONFIG_MICREL_PHY=y
|
||||
CONFIG_MIGRATION=y
|
||||
CONFIG_MMC=y
|
||||
CONFIG_MMC_BLOCK=y
|
||||
CONFIG_MMC_SDHCI=y
|
||||
CONFIG_MMC_SDHCI_OF_AT91=y
|
||||
CONFIG_MMC_SDHCI_PLTFM=y
|
||||
CONFIG_MMU_LAZY_TLB_REFCOUNT=y
|
||||
CONFIG_MODULES_USE_ELF_RELA=y
|
||||
CONFIG_MTD_SPI_NOR=y
|
||||
CONFIG_MUTEX_SPIN_ON_OWNER=y
|
||||
CONFIG_NEED_DMA_MAP_STATE=y
|
||||
CONFIG_NEED_SG_DMA_LENGTH=y
|
||||
CONFIG_NET_EGRESS=y
|
||||
CONFIG_NET_FLOW_LIMIT=y
|
||||
CONFIG_NET_INGRESS=y
|
||||
CONFIG_NET_SELFTESTS=y
|
||||
CONFIG_NET_XGRESS=y
|
||||
CONFIG_NLS=y
|
||||
CONFIG_NO_IOPORT_MAP=y
|
||||
CONFIG_NR_CPUS=512
|
||||
CONFIG_NVMEM=y
|
||||
CONFIG_NVMEM_LAN9662_OTPC=y
|
||||
CONFIG_NVMEM_LAYOUTS=y
|
||||
CONFIG_NVMEM_SYSFS=y
|
||||
CONFIG_OF=y
|
||||
CONFIG_OF_ADDRESS=y
|
||||
CONFIG_OF_EARLY_FLATTREE=y
|
||||
CONFIG_OF_FLATTREE=y
|
||||
CONFIG_OF_GPIO=y
|
||||
CONFIG_OF_IRQ=y
|
||||
CONFIG_OF_KOBJ=y
|
||||
CONFIG_OF_MDIO=y
|
||||
CONFIG_PADATA=y
|
||||
CONFIG_PAGE_POOL=y
|
||||
CONFIG_PAGE_SIZE_LESS_THAN_256KB=y
|
||||
CONFIG_PAGE_SIZE_LESS_THAN_64KB=y
|
||||
CONFIG_PARTITION_PERCPU=y
|
||||
CONFIG_PER_VMA_LOCK=y
|
||||
CONFIG_PGTABLE_LEVELS=3
|
||||
CONFIG_PHYLIB=y
|
||||
CONFIG_PHYLIB_LEDS=y
|
||||
CONFIG_PHYLINK=y
|
||||
CONFIG_PHYS_ADDR_T_64BIT=y
|
||||
CONFIG_PHY_SPARX5_SERDES=y
|
||||
CONFIG_PINCTRL=y
|
||||
CONFIG_PINCTRL_MICROCHIP_SGPIO=y
|
||||
CONFIG_PINCTRL_OCELOT=y
|
||||
CONFIG_POSIX_CPU_TIMERS_TASK_WORK=y
|
||||
CONFIG_POWER_RESET=y
|
||||
CONFIG_POWER_RESET_GPIO_RESTART=y
|
||||
CONFIG_POWER_SUPPLY=y
|
||||
CONFIG_PTP_1588_CLOCK_OPTIONAL=y
|
||||
CONFIG_PWM=y
|
||||
CONFIG_QUEUED_RWLOCKS=y
|
||||
CONFIG_QUEUED_SPINLOCKS=y
|
||||
CONFIG_RANDSTRUCT_NONE=y
|
||||
CONFIG_RATIONAL=y
|
||||
CONFIG_REGMAP=y
|
||||
CONFIG_REGMAP_MMIO=y
|
||||
CONFIG_RELOCATABLE=y
|
||||
CONFIG_RESET_CONTROLLER=y
|
||||
CONFIG_RESET_MCHP_SPARX5=y
|
||||
CONFIG_RFS_ACCEL=y
|
||||
CONFIG_RODATA_FULL_DEFAULT_ENABLED=y
|
||||
CONFIG_RPS=y
|
||||
CONFIG_RWSEM_SPIN_ON_OWNER=y
|
||||
CONFIG_SENSORS_SPARX5=y
|
||||
# CONFIG_SERIAL_8250 is not set
|
||||
CONFIG_SERIAL_ATMEL=y
|
||||
CONFIG_SERIAL_ATMEL_CONSOLE=y
|
||||
CONFIG_SERIAL_ATMEL_PDC=y
|
||||
CONFIG_SERIAL_ATMEL_TTYAT=y
|
||||
CONFIG_SERIAL_MCTRL_GPIO=y
|
||||
CONFIG_SFP=y
|
||||
CONFIG_SMP=y
|
||||
CONFIG_SOCK_RX_QUEUE_MAPPING=y
|
||||
CONFIG_SOFTIRQ_ON_OWN_STACK=y
|
||||
CONFIG_SPARSEMEM=y
|
||||
CONFIG_SPARSEMEM_EXTREME=y
|
||||
CONFIG_SPARSEMEM_VMEMMAP=y
|
||||
CONFIG_SPARSEMEM_VMEMMAP_ENABLE=y
|
||||
CONFIG_SPARSE_IRQ=y
|
||||
CONFIG_SPARX5_SWITCH=y
|
||||
CONFIG_SPI=y
|
||||
CONFIG_SPI_ATMEL=y
|
||||
CONFIG_SPI_ATMEL_QUADSPI=y
|
||||
CONFIG_SPI_MASTER=y
|
||||
CONFIG_SPI_MEM=y
|
||||
CONFIG_SPLIT_PMD_PTLOCKS=y
|
||||
CONFIG_SPLIT_PTE_PTLOCKS=y
|
||||
CONFIG_SWIOTLB=y
|
||||
CONFIG_SWPHY=y
|
||||
CONFIG_SYSCTL_EXCEPTION_TRACE=y
|
||||
CONFIG_THREAD_INFO_IN_TASK=y
|
||||
CONFIG_TICK_CPU_ACCOUNTING=y
|
||||
CONFIG_TIMER_OF=y
|
||||
CONFIG_TIMER_PROBE=y
|
||||
CONFIG_TOOLS_SUPPORT_RELR=y
|
||||
CONFIG_TRACE_IRQFLAGS_NMI_SUPPORT=y
|
||||
CONFIG_TREE_RCU=y
|
||||
CONFIG_TREE_SRCU=y
|
||||
CONFIG_UNMAP_KERNEL_AT_EL0=y
|
||||
CONFIG_USB=y
|
||||
CONFIG_USB_COMMON=y
|
||||
CONFIG_USB_SUPPORT=y
|
||||
CONFIG_USER_STACKTRACE_SUPPORT=y
|
||||
CONFIG_VCAP=y
|
||||
CONFIG_VDSO_GETRANDOM=y
|
||||
CONFIG_WATCHDOG_CORE=y
|
||||
CONFIG_WATCHDOG_SYSFS=y
|
||||
CONFIG_XPS=y
|
||||
CONFIG_ZONE_DMA32=y
|
||||
8
target/linux/microchipsw/lan969x/target.mk
Normal file
8
target/linux/microchipsw/lan969x/target.mk
Normal file
@ -0,0 +1,8 @@
|
||||
SUBTARGET:=lan969x
|
||||
BOARDNAME:=Microchip LAN969x switches
|
||||
|
||||
DEFAULT_PACKAGES += kmod-usb3 kmod-usb-dwc3
|
||||
|
||||
define Target/Description
|
||||
Build firmware images for Microchip LAN969x switch based boards.
|
||||
endef
|
||||
@ -0,0 +1,74 @@
|
||||
From 83647d5b9b5b1f7315c908c8c35632cd46a47801 Mon Sep 17 00:00:00 2001
|
||||
From: Robert Marko <robert.marko@sartura.hr>
|
||||
Date: Wed, 13 Aug 2025 19:44:37 +0200
|
||||
Subject: [PATCH 01/25] arm64: Add config for Microchip SoC platforms
|
||||
|
||||
Currently, Microchip SparX-5 SoC is supported and it has its own symbol.
|
||||
|
||||
However, this means that new Microchip platforms that share drivers need
|
||||
to constantly keep updating depends on various drivers.
|
||||
|
||||
So, to try and reduce this lets add ARCH_MICROCHIP symbol that drivers
|
||||
could instead depend on.
|
||||
|
||||
LAN969x is being worked on and it will be added under ARCH_MICROCHIP.
|
||||
|
||||
Signed-off-by: Robert Marko <robert.marko@sartura.hr>
|
||||
Acked-by: Daniel Machon <daniel.machon@microchip.com>
|
||||
Signed-off-by: Nicolas Ferre <nicolas.ferre@microchip.com>
|
||||
---
|
||||
arch/arm64/Kconfig.platforms | 36 ++++++++++++++++++++++--------------
|
||||
1 file changed, 22 insertions(+), 14 deletions(-)
|
||||
|
||||
--- a/arch/arm64/Kconfig.platforms
|
||||
+++ b/arch/arm64/Kconfig.platforms
|
||||
@@ -114,20 +114,6 @@ config ARCH_EXYNOS
|
||||
help
|
||||
This enables support for ARMv8 based Samsung Exynos SoC family.
|
||||
|
||||
-config ARCH_SPARX5
|
||||
- bool "Microchip Sparx5 SoC family"
|
||||
- select PINCTRL
|
||||
- select DW_APB_TIMER_OF
|
||||
- help
|
||||
- This enables support for the Microchip Sparx5 ARMv8-based
|
||||
- SoC family of TSN-capable gigabit switches.
|
||||
-
|
||||
- The SparX-5 Ethernet switch family provides a rich set of
|
||||
- switching features such as advanced TCAM-based VLAN and QoS
|
||||
- processing enabling delivery of differentiated services, and
|
||||
- security through TCAM-based frame processing using versatile
|
||||
- content aware processor (VCAP).
|
||||
-
|
||||
config ARCH_K3
|
||||
bool "Texas Instruments Inc. K3 multicore SoC architecture"
|
||||
select PM_GENERIC_DOMAINS if PM
|
||||
@@ -175,6 +161,28 @@ config ARCH_MESON
|
||||
This enables support for the arm64 based Amlogic SoCs
|
||||
such as the s905, S905X/D, S912, A113X/D or S905X/D2
|
||||
|
||||
+menu "Microchip SoC support"
|
||||
+
|
||||
+config ARCH_MICROCHIP
|
||||
+ bool
|
||||
+
|
||||
+config ARCH_SPARX5
|
||||
+ bool "Microchip Sparx5 SoC family"
|
||||
+ select PINCTRL
|
||||
+ select DW_APB_TIMER_OF
|
||||
+ select ARCH_MICROCHIP
|
||||
+ help
|
||||
+ This enables support for the Microchip Sparx5 ARMv8-based
|
||||
+ SoC family of TSN-capable gigabit switches.
|
||||
+
|
||||
+ The SparX-5 Ethernet switch family provides a rich set of
|
||||
+ switching features such as advanced TCAM-based VLAN and QoS
|
||||
+ processing enabling delivery of differentiated services, and
|
||||
+ security through TCAM-based frame processing using versatile
|
||||
+ content aware processor (VCAP).
|
||||
+
|
||||
+endmenu
|
||||
+
|
||||
config ARCH_MVEBU
|
||||
bool "Marvell EBU SoC Family"
|
||||
select ARMADA_AP806_SYSCON
|
||||
@ -0,0 +1,38 @@
|
||||
From 64016a564b81491c092ef03c7e11305650d8641a Mon Sep 17 00:00:00 2001
|
||||
From: Robert Marko <robert.marko@sartura.hr>
|
||||
Date: Wed, 13 Aug 2025 19:44:39 +0200
|
||||
Subject: [PATCH 02/25] arm64: lan969x: Add support for Microchip LAN969x SoC
|
||||
|
||||
This adds support for the Microchip LAN969x ARMv8-based SoC switch family.
|
||||
|
||||
Signed-off-by: Robert Marko <robert.marko@sartura.hr>
|
||||
Acked-by: Daniel Machon <daniel.machon@microchip.com>
|
||||
Signed-off-by: Nicolas Ferre <nicolas.ferre@microchip.com>
|
||||
---
|
||||
arch/arm64/Kconfig.platforms | 15 +++++++++++++++
|
||||
1 file changed, 15 insertions(+)
|
||||
|
||||
--- a/arch/arm64/Kconfig.platforms
|
||||
+++ b/arch/arm64/Kconfig.platforms
|
||||
@@ -166,6 +166,21 @@ menu "Microchip SoC support"
|
||||
config ARCH_MICROCHIP
|
||||
bool
|
||||
|
||||
+config ARCH_LAN969X
|
||||
+ bool "Microchip LAN969X SoC family"
|
||||
+ select PINCTRL
|
||||
+ select DW_APB_TIMER_OF
|
||||
+ select ARCH_MICROCHIP
|
||||
+ help
|
||||
+ This enables support for the Microchip LAN969X ARMv8-based
|
||||
+ SoC family of TSN-capable gigabit switches.
|
||||
+
|
||||
+ The LAN969X Ethernet switch family provides a rich set of
|
||||
+ switching features such as advanced TCAM-based VLAN and QoS
|
||||
+ processing enabling delivery of differentiated services, and
|
||||
+ security through TCAM-based frame processing using versatile
|
||||
+ content aware processor (VCAP).
|
||||
+
|
||||
config ARCH_SPARX5
|
||||
bool "Microchip Sparx5 SoC family"
|
||||
select PINCTRL
|
||||
@ -0,0 +1,348 @@
|
||||
From bcf540500e1feb072cf7659f71a437a63f1735f9 Mon Sep 17 00:00:00 2001
|
||||
From: Daniel Machon <daniel.machon@microchip.com>
|
||||
Date: Tue, 17 Sep 2024 14:45:41 +0200
|
||||
Subject: [PATCH 03/25] pinctrl: ocelot: add support for lan969x SoC pinctrl
|
||||
|
||||
This adds support for lan969x SoC pinctrl, reusing the existing ocelot
|
||||
driver. There are 66 General Purpose I/O pins that are individually
|
||||
configurable to multiple interfaces.
|
||||
|
||||
Signed-off-by: Daniel Machon <daniel.machon@microchip.com>
|
||||
Link: https://lore.kernel.org/20240917-lan969x-pinctrl-v2-2-ea02cbc56831@microchip.com
|
||||
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
|
||||
---
|
||||
drivers/pinctrl/pinctrl-ocelot.c | 203 +++++++++++++++++++++++++++++++
|
||||
1 file changed, 203 insertions(+)
|
||||
|
||||
--- a/drivers/pinctrl/pinctrl-ocelot.c
|
||||
+++ b/drivers/pinctrl/pinctrl-ocelot.c
|
||||
@@ -57,6 +57,8 @@ enum {
|
||||
FUNC_CAN1,
|
||||
FUNC_CLKMON,
|
||||
FUNC_NONE,
|
||||
+ FUNC_FAN,
|
||||
+ FUNC_FC,
|
||||
FUNC_FC0_a,
|
||||
FUNC_FC0_b,
|
||||
FUNC_FC0_c,
|
||||
@@ -71,6 +73,7 @@ enum {
|
||||
FUNC_FC4_a,
|
||||
FUNC_FC4_b,
|
||||
FUNC_FC4_c,
|
||||
+ FUNC_FC_SHRD,
|
||||
FUNC_FC_SHRD0,
|
||||
FUNC_FC_SHRD1,
|
||||
FUNC_FC_SHRD2,
|
||||
@@ -92,6 +95,7 @@ enum {
|
||||
FUNC_FC_SHRD18,
|
||||
FUNC_FC_SHRD19,
|
||||
FUNC_FC_SHRD20,
|
||||
+ FUNC_FUSA,
|
||||
FUNC_GPIO,
|
||||
FUNC_IB_TRG_a,
|
||||
FUNC_IB_TRG_b,
|
||||
@@ -108,6 +112,8 @@ enum {
|
||||
FUNC_IRQ1,
|
||||
FUNC_IRQ1_IN,
|
||||
FUNC_IRQ1_OUT,
|
||||
+ FUNC_IRQ3,
|
||||
+ FUNC_IRQ4,
|
||||
FUNC_EXT_IRQ,
|
||||
FUNC_MIIM,
|
||||
FUNC_MIIM_a,
|
||||
@@ -115,12 +121,14 @@ enum {
|
||||
FUNC_MIIM_c,
|
||||
FUNC_MIIM_Sa,
|
||||
FUNC_MIIM_Sb,
|
||||
+ FUNC_MIIM_IRQ,
|
||||
FUNC_OB_TRG,
|
||||
FUNC_OB_TRG_a,
|
||||
FUNC_OB_TRG_b,
|
||||
FUNC_PHY_LED,
|
||||
FUNC_PCI_WAKE,
|
||||
FUNC_MD,
|
||||
+ FUNC_PCIE_PERST,
|
||||
FUNC_PTP0,
|
||||
FUNC_PTP1,
|
||||
FUNC_PTP2,
|
||||
@@ -152,6 +160,7 @@ enum {
|
||||
FUNC_SGPIO_b,
|
||||
FUNC_SI,
|
||||
FUNC_SI2,
|
||||
+ FUNC_SYNCE,
|
||||
FUNC_TACHO,
|
||||
FUNC_TACHO_a,
|
||||
FUNC_TACHO_b,
|
||||
@@ -170,6 +179,10 @@ enum {
|
||||
FUNC_USB_S_a,
|
||||
FUNC_USB_S_b,
|
||||
FUNC_USB_S_c,
|
||||
+ FUNC_USB_POWER,
|
||||
+ FUNC_USB2PHY_RST,
|
||||
+ FUNC_USB_OVER_DETECT,
|
||||
+ FUNC_USB_ULPI,
|
||||
FUNC_PLL_STAT,
|
||||
FUNC_EMMC,
|
||||
FUNC_EMMC_SD,
|
||||
@@ -184,6 +197,8 @@ static const char *const ocelot_function
|
||||
[FUNC_CAN1] = "can1",
|
||||
[FUNC_CLKMON] = "clkmon",
|
||||
[FUNC_NONE] = "none",
|
||||
+ [FUNC_FAN] = "fan",
|
||||
+ [FUNC_FC] = "fc",
|
||||
[FUNC_FC0_a] = "fc0_a",
|
||||
[FUNC_FC0_b] = "fc0_b",
|
||||
[FUNC_FC0_c] = "fc0_c",
|
||||
@@ -198,6 +213,7 @@ static const char *const ocelot_function
|
||||
[FUNC_FC4_a] = "fc4_a",
|
||||
[FUNC_FC4_b] = "fc4_b",
|
||||
[FUNC_FC4_c] = "fc4_c",
|
||||
+ [FUNC_FC_SHRD] = "fc_shrd",
|
||||
[FUNC_FC_SHRD0] = "fc_shrd0",
|
||||
[FUNC_FC_SHRD1] = "fc_shrd1",
|
||||
[FUNC_FC_SHRD2] = "fc_shrd2",
|
||||
@@ -219,6 +235,7 @@ static const char *const ocelot_function
|
||||
[FUNC_FC_SHRD18] = "fc_shrd18",
|
||||
[FUNC_FC_SHRD19] = "fc_shrd19",
|
||||
[FUNC_FC_SHRD20] = "fc_shrd20",
|
||||
+ [FUNC_FUSA] = "fusa",
|
||||
[FUNC_GPIO] = "gpio",
|
||||
[FUNC_IB_TRG_a] = "ib_trig_a",
|
||||
[FUNC_IB_TRG_b] = "ib_trig_b",
|
||||
@@ -235,6 +252,8 @@ static const char *const ocelot_function
|
||||
[FUNC_IRQ1] = "irq1",
|
||||
[FUNC_IRQ1_IN] = "irq1_in",
|
||||
[FUNC_IRQ1_OUT] = "irq1_out",
|
||||
+ [FUNC_IRQ3] = "irq3",
|
||||
+ [FUNC_IRQ4] = "irq4",
|
||||
[FUNC_EXT_IRQ] = "ext_irq",
|
||||
[FUNC_MIIM] = "miim",
|
||||
[FUNC_MIIM_a] = "miim_a",
|
||||
@@ -242,8 +261,10 @@ static const char *const ocelot_function
|
||||
[FUNC_MIIM_c] = "miim_c",
|
||||
[FUNC_MIIM_Sa] = "miim_slave_a",
|
||||
[FUNC_MIIM_Sb] = "miim_slave_b",
|
||||
+ [FUNC_MIIM_IRQ] = "miim_irq",
|
||||
[FUNC_PHY_LED] = "phy_led",
|
||||
[FUNC_PCI_WAKE] = "pci_wake",
|
||||
+ [FUNC_PCIE_PERST] = "pcie_perst",
|
||||
[FUNC_MD] = "md",
|
||||
[FUNC_OB_TRG] = "ob_trig",
|
||||
[FUNC_OB_TRG_a] = "ob_trig_a",
|
||||
@@ -279,6 +300,7 @@ static const char *const ocelot_function
|
||||
[FUNC_SGPIO_b] = "sgpio_b",
|
||||
[FUNC_SI] = "si",
|
||||
[FUNC_SI2] = "si2",
|
||||
+ [FUNC_SYNCE] = "synce",
|
||||
[FUNC_TACHO] = "tacho",
|
||||
[FUNC_TACHO_a] = "tacho_a",
|
||||
[FUNC_TACHO_b] = "tacho_b",
|
||||
@@ -294,6 +316,10 @@ static const char *const ocelot_function
|
||||
[FUNC_USB_S_a] = "usb_slave_a",
|
||||
[FUNC_USB_S_b] = "usb_slave_b",
|
||||
[FUNC_USB_S_c] = "usb_slave_c",
|
||||
+ [FUNC_USB_POWER] = "usb_power",
|
||||
+ [FUNC_USB2PHY_RST] = "usb2phy_rst",
|
||||
+ [FUNC_USB_OVER_DETECT] = "usb_over_detect",
|
||||
+ [FUNC_USB_ULPI] = "usb_ulpi",
|
||||
[FUNC_UART] = "uart",
|
||||
[FUNC_UART2] = "uart2",
|
||||
[FUNC_UART3] = "uart3",
|
||||
@@ -1136,6 +1162,165 @@ static const struct pinctrl_pin_desc lan
|
||||
LAN966X_PIN(77),
|
||||
};
|
||||
|
||||
+#define LAN969X_P(p, f0, f1, f2, f3, f4, f5, f6, f7) \
|
||||
+static struct ocelot_pin_caps lan969x_pin_##p = { \
|
||||
+ .pin = p, \
|
||||
+ .functions = { \
|
||||
+ FUNC_##f0, FUNC_##f1, FUNC_##f2, \
|
||||
+ FUNC_##f3 \
|
||||
+ }, \
|
||||
+ .a_functions = { \
|
||||
+ FUNC_##f4, FUNC_##f5, FUNC_##f6, \
|
||||
+ FUNC_##f7 \
|
||||
+ }, \
|
||||
+}
|
||||
+
|
||||
+/* Pinmuxing table taken from data sheet */
|
||||
+/* Pin FUNC0 FUNC1 FUNC2 FUNC3 FUNC4 FUNC5 FUNC6 FUNC7 */
|
||||
+LAN969X_P(0, GPIO, IRQ0, FC_SHRD, PCIE_PERST, NONE, NONE, NONE, R);
|
||||
+LAN969X_P(1, GPIO, IRQ1, FC_SHRD, USB_POWER, NONE, NONE, NONE, R);
|
||||
+LAN969X_P(2, GPIO, FC, NONE, NONE, NONE, NONE, NONE, R);
|
||||
+LAN969X_P(3, GPIO, FC, NONE, NONE, NONE, NONE, NONE, R);
|
||||
+LAN969X_P(4, GPIO, FC, NONE, NONE, NONE, NONE, NONE, R);
|
||||
+LAN969X_P(5, GPIO, SGPIO_a, NONE, CLKMON, NONE, NONE, NONE, R);
|
||||
+LAN969X_P(6, GPIO, SGPIO_a, NONE, CLKMON, NONE, NONE, NONE, R);
|
||||
+LAN969X_P(7, GPIO, SGPIO_a, NONE, CLKMON, NONE, NONE, NONE, R);
|
||||
+LAN969X_P(8, GPIO, SGPIO_a, NONE, CLKMON, NONE, NONE, NONE, R);
|
||||
+LAN969X_P(9, GPIO, MIIM, MIIM_Sa, CLKMON, NONE, NONE, NONE, R);
|
||||
+LAN969X_P(10, GPIO, MIIM, MIIM_Sa, CLKMON, NONE, NONE, NONE, R);
|
||||
+LAN969X_P(11, GPIO, MIIM_IRQ, MIIM_Sa, CLKMON, NONE, NONE, NONE, R);
|
||||
+LAN969X_P(12, GPIO, IRQ3, FC_SHRD, USB2PHY_RST, NONE, NONE, NONE, R);
|
||||
+LAN969X_P(13, GPIO, IRQ4, FC_SHRD, USB_OVER_DETECT, NONE, NONE, NONE, R);
|
||||
+LAN969X_P(14, GPIO, EMMC_SD, QSPI1, FC, NONE, NONE, NONE, R);
|
||||
+LAN969X_P(15, GPIO, EMMC_SD, QSPI1, FC, NONE, NONE, NONE, R);
|
||||
+LAN969X_P(16, GPIO, EMMC_SD, QSPI1, FC, NONE, NONE, NONE, R);
|
||||
+LAN969X_P(17, GPIO, EMMC_SD, QSPI1, PTPSYNC_0, USB_POWER, NONE, NONE, R);
|
||||
+LAN969X_P(18, GPIO, EMMC_SD, QSPI1, PTPSYNC_1, USB2PHY_RST, NONE, NONE, R);
|
||||
+LAN969X_P(19, GPIO, EMMC_SD, QSPI1, PTPSYNC_2, USB_OVER_DETECT, NONE, NONE, R);
|
||||
+LAN969X_P(20, GPIO, EMMC_SD, NONE, FC_SHRD, NONE, NONE, NONE, R);
|
||||
+LAN969X_P(21, GPIO, EMMC_SD, NONE, FC_SHRD, NONE, NONE, NONE, R);
|
||||
+LAN969X_P(22, GPIO, EMMC_SD, NONE, FC_SHRD, NONE, NONE, NONE, R);
|
||||
+LAN969X_P(23, GPIO, EMMC_SD, NONE, FC_SHRD, NONE, NONE, NONE, R);
|
||||
+LAN969X_P(24, GPIO, EMMC_SD, NONE, NONE, NONE, NONE, NONE, R);
|
||||
+LAN969X_P(25, GPIO, FAN, FUSA, CAN0_a, QSPI1, NONE, NONE, R);
|
||||
+LAN969X_P(26, GPIO, FAN, FUSA, CAN0_a, QSPI1, NONE, NONE, R);
|
||||
+LAN969X_P(27, GPIO, SYNCE, FC, MIIM, QSPI1, NONE, NONE, R);
|
||||
+LAN969X_P(28, GPIO, SYNCE, FC, MIIM, QSPI1, NONE, NONE, R);
|
||||
+LAN969X_P(29, GPIO, SYNCE, FC, MIIM_IRQ, QSPI1, NONE, NONE, R);
|
||||
+LAN969X_P(30, GPIO, PTPSYNC_0, USB_ULPI, FC_SHRD, QSPI1, NONE, NONE, R);
|
||||
+LAN969X_P(31, GPIO, PTPSYNC_1, USB_ULPI, FC_SHRD, NONE, NONE, NONE, R);
|
||||
+LAN969X_P(32, GPIO, PTPSYNC_2, USB_ULPI, FC_SHRD, NONE, NONE, NONE, R);
|
||||
+LAN969X_P(33, GPIO, SD, USB_ULPI, FC_SHRD, NONE, NONE, NONE, R);
|
||||
+LAN969X_P(34, GPIO, SD, USB_ULPI, CAN1, FC_SHRD, NONE, NONE, R);
|
||||
+LAN969X_P(35, GPIO, SD, USB_ULPI, CAN1, FC_SHRD, NONE, NONE, R);
|
||||
+LAN969X_P(36, GPIO, SD, USB_ULPI, PCIE_PERST, FC_SHRD, NONE, NONE, R);
|
||||
+LAN969X_P(37, GPIO, SD, USB_ULPI, CAN0_b, NONE, NONE, NONE, R);
|
||||
+LAN969X_P(38, GPIO, SD, USB_ULPI, CAN0_b, NONE, NONE, NONE, R);
|
||||
+LAN969X_P(39, GPIO, SD, USB_ULPI, MIIM, NONE, NONE, NONE, R);
|
||||
+LAN969X_P(40, GPIO, SD, USB_ULPI, MIIM, NONE, NONE, NONE, R);
|
||||
+LAN969X_P(41, GPIO, SD, USB_ULPI, MIIM_IRQ, NONE, NONE, NONE, R);
|
||||
+LAN969X_P(42, GPIO, PTPSYNC_3, CAN1, NONE, NONE, NONE, NONE, R);
|
||||
+LAN969X_P(43, GPIO, PTPSYNC_4, CAN1, NONE, NONE, NONE, NONE, R);
|
||||
+LAN969X_P(44, GPIO, PTPSYNC_5, SFP_SD, NONE, NONE, NONE, NONE, R);
|
||||
+LAN969X_P(45, GPIO, PTPSYNC_6, SFP_SD, NONE, NONE, NONE, NONE, R);
|
||||
+LAN969X_P(46, GPIO, PTPSYNC_7, SFP_SD, NONE, NONE, NONE, NONE, R);
|
||||
+LAN969X_P(47, GPIO, NONE, SFP_SD, NONE, NONE, NONE, NONE, R);
|
||||
+LAN969X_P(48, GPIO, NONE, SFP_SD, NONE, NONE, NONE, NONE, R);
|
||||
+LAN969X_P(49, GPIO, NONE, SFP_SD, NONE, NONE, NONE, NONE, R);
|
||||
+LAN969X_P(50, GPIO, NONE, SFP_SD, NONE, NONE, NONE, NONE, R);
|
||||
+LAN969X_P(51, GPIO, NONE, SFP_SD, NONE, NONE, NONE, NONE, R);
|
||||
+LAN969X_P(52, GPIO, FAN, SFP_SD, NONE, NONE, NONE, NONE, R);
|
||||
+LAN969X_P(53, GPIO, FAN, SFP_SD, NONE, NONE, NONE, NONE, R);
|
||||
+LAN969X_P(54, GPIO, SYNCE, FC, NONE, NONE, NONE, NONE, R);
|
||||
+LAN969X_P(55, GPIO, SYNCE, FC, NONE, NONE, NONE, NONE, R);
|
||||
+LAN969X_P(56, GPIO, SYNCE, FC, NONE, NONE, NONE, NONE, R);
|
||||
+LAN969X_P(57, GPIO, SFP_SD, FC_SHRD, TWI, PTPSYNC_3, NONE, NONE, R);
|
||||
+LAN969X_P(58, GPIO, SFP_SD, FC_SHRD, TWI, PTPSYNC_4, NONE, NONE, R);
|
||||
+LAN969X_P(59, GPIO, SFP_SD, FC_SHRD, TWI, PTPSYNC_5, NONE, NONE, R);
|
||||
+LAN969X_P(60, GPIO, SFP_SD, FC_SHRD, TWI, PTPSYNC_6, NONE, NONE, R);
|
||||
+LAN969X_P(61, GPIO, MIIM, FC_SHRD, TWI, NONE, NONE, NONE, R);
|
||||
+LAN969X_P(62, GPIO, MIIM, FC_SHRD, TWI, NONE, NONE, NONE, R);
|
||||
+LAN969X_P(63, GPIO, MIIM_IRQ, FC_SHRD, TWI, NONE, NONE, NONE, R);
|
||||
+LAN969X_P(64, GPIO, FC, FC_SHRD, TWI, NONE, NONE, NONE, R);
|
||||
+LAN969X_P(65, GPIO, FC, FC_SHRD, TWI, NONE, NONE, NONE, R);
|
||||
+LAN969X_P(66, GPIO, FC, FC_SHRD, TWI, NONE, NONE, NONE, R);
|
||||
+
|
||||
+#define LAN969X_PIN(n) { \
|
||||
+ .number = n, \
|
||||
+ .name = "GPIO_"#n, \
|
||||
+ .drv_data = &lan969x_pin_##n \
|
||||
+}
|
||||
+
|
||||
+static const struct pinctrl_pin_desc lan969x_pins[] = {
|
||||
+ LAN969X_PIN(0),
|
||||
+ LAN969X_PIN(1),
|
||||
+ LAN969X_PIN(2),
|
||||
+ LAN969X_PIN(3),
|
||||
+ LAN969X_PIN(4),
|
||||
+ LAN969X_PIN(5),
|
||||
+ LAN969X_PIN(6),
|
||||
+ LAN969X_PIN(7),
|
||||
+ LAN969X_PIN(8),
|
||||
+ LAN969X_PIN(9),
|
||||
+ LAN969X_PIN(10),
|
||||
+ LAN969X_PIN(11),
|
||||
+ LAN969X_PIN(12),
|
||||
+ LAN969X_PIN(13),
|
||||
+ LAN969X_PIN(14),
|
||||
+ LAN969X_PIN(15),
|
||||
+ LAN969X_PIN(16),
|
||||
+ LAN969X_PIN(17),
|
||||
+ LAN969X_PIN(18),
|
||||
+ LAN969X_PIN(19),
|
||||
+ LAN969X_PIN(20),
|
||||
+ LAN969X_PIN(21),
|
||||
+ LAN969X_PIN(22),
|
||||
+ LAN969X_PIN(23),
|
||||
+ LAN969X_PIN(24),
|
||||
+ LAN969X_PIN(25),
|
||||
+ LAN969X_PIN(26),
|
||||
+ LAN969X_PIN(27),
|
||||
+ LAN969X_PIN(28),
|
||||
+ LAN969X_PIN(29),
|
||||
+ LAN969X_PIN(30),
|
||||
+ LAN969X_PIN(31),
|
||||
+ LAN969X_PIN(32),
|
||||
+ LAN969X_PIN(33),
|
||||
+ LAN969X_PIN(34),
|
||||
+ LAN969X_PIN(35),
|
||||
+ LAN969X_PIN(36),
|
||||
+ LAN969X_PIN(37),
|
||||
+ LAN969X_PIN(38),
|
||||
+ LAN969X_PIN(39),
|
||||
+ LAN969X_PIN(40),
|
||||
+ LAN969X_PIN(41),
|
||||
+ LAN969X_PIN(42),
|
||||
+ LAN969X_PIN(43),
|
||||
+ LAN969X_PIN(44),
|
||||
+ LAN969X_PIN(45),
|
||||
+ LAN969X_PIN(46),
|
||||
+ LAN969X_PIN(47),
|
||||
+ LAN969X_PIN(48),
|
||||
+ LAN969X_PIN(49),
|
||||
+ LAN969X_PIN(50),
|
||||
+ LAN969X_PIN(51),
|
||||
+ LAN969X_PIN(52),
|
||||
+ LAN969X_PIN(53),
|
||||
+ LAN969X_PIN(54),
|
||||
+ LAN969X_PIN(55),
|
||||
+ LAN969X_PIN(56),
|
||||
+ LAN969X_PIN(57),
|
||||
+ LAN969X_PIN(58),
|
||||
+ LAN969X_PIN(59),
|
||||
+ LAN969X_PIN(60),
|
||||
+ LAN969X_PIN(61),
|
||||
+ LAN969X_PIN(62),
|
||||
+ LAN969X_PIN(63),
|
||||
+ LAN969X_PIN(64),
|
||||
+ LAN969X_PIN(65),
|
||||
+ LAN969X_PIN(66),
|
||||
+};
|
||||
+
|
||||
static int ocelot_get_functions_count(struct pinctrl_dev *pctldev)
|
||||
{
|
||||
return ARRAY_SIZE(ocelot_function_names);
|
||||
@@ -1682,6 +1867,23 @@ static struct ocelot_match_data lan966x_
|
||||
},
|
||||
};
|
||||
|
||||
+static struct ocelot_match_data lan969x_desc = {
|
||||
+ .desc = {
|
||||
+ .name = "lan969x-pinctrl",
|
||||
+ .pins = lan969x_pins,
|
||||
+ .npins = ARRAY_SIZE(lan969x_pins),
|
||||
+ .pctlops = &ocelot_pctl_ops,
|
||||
+ .pmxops = &lan966x_pmx_ops,
|
||||
+ .confops = &ocelot_confops,
|
||||
+ .owner = THIS_MODULE,
|
||||
+ },
|
||||
+ .pincfg_data = {
|
||||
+ .pd_bit = BIT(3),
|
||||
+ .pu_bit = BIT(2),
|
||||
+ .drive_bits = GENMASK(1, 0),
|
||||
+ },
|
||||
+};
|
||||
+
|
||||
static int ocelot_create_group_func_map(struct device *dev,
|
||||
struct ocelot_pinctrl *info)
|
||||
{
|
||||
@@ -2014,6 +2216,7 @@ static const struct of_device_id ocelot_
|
||||
{ .compatible = "mscc,servalt-pinctrl", .data = &servalt_desc },
|
||||
{ .compatible = "microchip,sparx5-pinctrl", .data = &sparx5_desc },
|
||||
{ .compatible = "microchip,lan966x-pinctrl", .data = &lan966x_desc },
|
||||
+ { .compatible = "microchip,lan9691-pinctrl", .data = &lan969x_desc },
|
||||
{},
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, ocelot_pinctrl_of_match);
|
||||
@ -0,0 +1,26 @@
|
||||
From 60b15ad144394ef5da427160fd947af93affef72 Mon Sep 17 00:00:00 2001
|
||||
From: Daniel Machon <daniel.machon@microchip.com>
|
||||
Date: Mon, 16 Sep 2024 11:49:20 +0200
|
||||
Subject: [PATCH 04/25] clk: lan966x: make clk_names const char * const
|
||||
|
||||
Change clk_names to const char * const to silence checkpatch in
|
||||
subsequent patches.
|
||||
|
||||
Signed-off-by: Daniel Machon <daniel.machon@microchip.com>
|
||||
Link: https://lore.kernel.org/r/20240916-lan969x-clock-v1-2-0e150336074d@microchip.com
|
||||
Signed-off-by: Claudiu Beznea <claudiu.beznea@tuxon.dev>
|
||||
---
|
||||
drivers/clk/clk-lan966x.c | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
--- a/drivers/clk/clk-lan966x.c
|
||||
+++ b/drivers/clk/clk-lan966x.c
|
||||
@@ -24,7 +24,7 @@
|
||||
|
||||
#define DIV_MAX 255
|
||||
|
||||
-static const char *clk_names[N_CLOCKS] = {
|
||||
+static const char * const clk_names[N_CLOCKS] = {
|
||||
"qspi0", "qspi1", "qspi2", "sdmmc0",
|
||||
"pi", "mcan0", "mcan1", "flexcom0",
|
||||
"flexcom1", "flexcom2", "flexcom3",
|
||||
@ -0,0 +1,151 @@
|
||||
From 471d54facf2a1ee5740839e7870873a3f5965911 Mon Sep 17 00:00:00 2001
|
||||
From: Daniel Machon <daniel.machon@microchip.com>
|
||||
Date: Mon, 16 Sep 2024 11:49:21 +0200
|
||||
Subject: [PATCH 05/25] clk: lan966x: prepare driver for lan969x support
|
||||
|
||||
In preparation for lan969x support, add private match data for lan966x
|
||||
and add variables for: peripheral clock names, clock gate names, number
|
||||
of total clocks and number of generic clocks. Use the variables
|
||||
throughout.
|
||||
|
||||
Signed-off-by: Daniel Machon <daniel.machon@microchip.com>
|
||||
Link: https://lore.kernel.org/r/20240916-lan969x-clock-v1-3-0e150336074d@microchip.com
|
||||
[claudiu.beznea: in lan966x_clk_probe(): keep struct_size() arguments on
|
||||
a single line]
|
||||
Signed-off-by: Claudiu Beznea <claudiu.beznea@tuxon.dev>
|
||||
---
|
||||
drivers/clk/clk-lan966x.c | 55 +++++++++++++++++++++++++++------------
|
||||
1 file changed, 39 insertions(+), 16 deletions(-)
|
||||
|
||||
--- a/drivers/clk/clk-lan966x.c
|
||||
+++ b/drivers/clk/clk-lan966x.c
|
||||
@@ -24,7 +24,7 @@
|
||||
|
||||
#define DIV_MAX 255
|
||||
|
||||
-static const char * const clk_names[N_CLOCKS] = {
|
||||
+static const char * const lan966x_clk_names[] = {
|
||||
"qspi0", "qspi1", "qspi2", "sdmmc0",
|
||||
"pi", "mcan0", "mcan1", "flexcom0",
|
||||
"flexcom1", "flexcom2", "flexcom3",
|
||||
@@ -53,7 +53,7 @@ struct clk_gate_soc_desc {
|
||||
int bit_idx;
|
||||
};
|
||||
|
||||
-static const struct clk_gate_soc_desc clk_gate_desc[] = {
|
||||
+static const struct clk_gate_soc_desc lan966x_clk_gate_desc[] = {
|
||||
{ "uhphs", 11 },
|
||||
{ "udphs", 10 },
|
||||
{ "mcramc", 9 },
|
||||
@@ -61,6 +61,22 @@ static const struct clk_gate_soc_desc cl
|
||||
{ }
|
||||
};
|
||||
|
||||
+struct lan966x_match_data {
|
||||
+ char *name;
|
||||
+ const char * const *clk_name;
|
||||
+ const struct clk_gate_soc_desc *clk_gate_desc;
|
||||
+ u8 num_generic_clks;
|
||||
+ u8 num_total_clks;
|
||||
+};
|
||||
+
|
||||
+static struct lan966x_match_data lan966x_desc = {
|
||||
+ .name = "lan966x",
|
||||
+ .clk_name = lan966x_clk_names,
|
||||
+ .clk_gate_desc = lan966x_clk_gate_desc,
|
||||
+ .num_total_clks = 18,
|
||||
+ .num_generic_clks = 14,
|
||||
+};
|
||||
+
|
||||
static DEFINE_SPINLOCK(clk_gate_lock);
|
||||
static void __iomem *base;
|
||||
|
||||
@@ -186,24 +202,26 @@ static struct clk_hw *lan966x_gck_clk_re
|
||||
};
|
||||
|
||||
static int lan966x_gate_clk_register(struct device *dev,
|
||||
+ const struct lan966x_match_data *data,
|
||||
struct clk_hw_onecell_data *hw_data,
|
||||
void __iomem *gate_base)
|
||||
{
|
||||
- int i;
|
||||
+ for (int i = data->num_generic_clks; i < data->num_total_clks; ++i) {
|
||||
+ int idx = i - data->num_generic_clks;
|
||||
+ const struct clk_gate_soc_desc *desc;
|
||||
|
||||
- for (i = GCK_GATE_UHPHS; i < N_CLOCKS; ++i) {
|
||||
- int idx = i - GCK_GATE_UHPHS;
|
||||
+ desc = &data->clk_gate_desc[idx];
|
||||
|
||||
hw_data->hws[i] =
|
||||
- devm_clk_hw_register_gate(dev, clk_gate_desc[idx].name,
|
||||
- "lan966x", 0, gate_base,
|
||||
- clk_gate_desc[idx].bit_idx,
|
||||
+ devm_clk_hw_register_gate(dev, desc->name,
|
||||
+ data->name, 0, gate_base,
|
||||
+ desc->bit_idx,
|
||||
0, &clk_gate_lock);
|
||||
|
||||
if (IS_ERR(hw_data->hws[i]))
|
||||
return dev_err_probe(dev, PTR_ERR(hw_data->hws[i]),
|
||||
"failed to register %s clock\n",
|
||||
- clk_gate_desc[idx].name);
|
||||
+ desc->name);
|
||||
}
|
||||
|
||||
return 0;
|
||||
@@ -211,13 +229,18 @@ static int lan966x_gate_clk_register(str
|
||||
|
||||
static int lan966x_clk_probe(struct platform_device *pdev)
|
||||
{
|
||||
+ const struct lan966x_match_data *data;
|
||||
struct clk_hw_onecell_data *hw_data;
|
||||
struct device *dev = &pdev->dev;
|
||||
void __iomem *gate_base;
|
||||
struct resource *res;
|
||||
int i, ret;
|
||||
|
||||
- hw_data = devm_kzalloc(dev, struct_size(hw_data, hws, N_CLOCKS),
|
||||
+ data = device_get_match_data(dev);
|
||||
+ if (!data)
|
||||
+ return -EINVAL;
|
||||
+
|
||||
+ hw_data = devm_kzalloc(dev, struct_size(hw_data, hws, data->num_total_clks),
|
||||
GFP_KERNEL);
|
||||
if (!hw_data)
|
||||
return -ENOMEM;
|
||||
@@ -228,10 +251,10 @@ static int lan966x_clk_probe(struct plat
|
||||
|
||||
init.ops = &lan966x_gck_ops;
|
||||
|
||||
- hw_data->num = GCK_GATE_UHPHS;
|
||||
+ hw_data->num = data->num_generic_clks;
|
||||
|
||||
- for (i = 0; i < GCK_GATE_UHPHS; i++) {
|
||||
- init.name = clk_names[i];
|
||||
+ for (i = 0; i < data->num_generic_clks; i++) {
|
||||
+ init.name = data->clk_name[i];
|
||||
hw_data->hws[i] = lan966x_gck_clk_register(dev, i);
|
||||
if (IS_ERR(hw_data->hws[i])) {
|
||||
dev_err(dev, "failed to register %s clock\n",
|
||||
@@ -246,9 +269,9 @@ static int lan966x_clk_probe(struct plat
|
||||
if (IS_ERR(gate_base))
|
||||
return PTR_ERR(gate_base);
|
||||
|
||||
- hw_data->num = N_CLOCKS;
|
||||
+ hw_data->num = data->num_total_clks;
|
||||
|
||||
- ret = lan966x_gate_clk_register(dev, hw_data, gate_base);
|
||||
+ ret = lan966x_gate_clk_register(dev, data, hw_data, gate_base);
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
@@ -257,7 +280,7 @@ static int lan966x_clk_probe(struct plat
|
||||
}
|
||||
|
||||
static const struct of_device_id lan966x_clk_dt_ids[] = {
|
||||
- { .compatible = "microchip,lan966x-gck", },
|
||||
+ { .compatible = "microchip,lan966x-gck", .data = &lan966x_desc },
|
||||
{ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, lan966x_clk_dt_ids);
|
||||
@ -0,0 +1,70 @@
|
||||
From 5b89e2d7ec7afd2e2d92f90f90f232e17d70cfc0 Mon Sep 17 00:00:00 2001
|
||||
From: Daniel Machon <daniel.machon@microchip.com>
|
||||
Date: Mon, 16 Sep 2024 11:49:22 +0200
|
||||
Subject: [PATCH 06/25] clk: lan966x: add support for lan969x SoC clock driver
|
||||
|
||||
Add support for the lan969x SoC clock driver in the existing lan966x
|
||||
driver. The lan969x clock controller contains 3 PLLs - cpu_clk, ddr_clk
|
||||
and sys_clk (same as lan966x) which generates and supplies the clock to
|
||||
various peripherals within the SoC.
|
||||
|
||||
Signed-off-by: Daniel Machon <daniel.machon@microchip.com>
|
||||
Link: https://lore.kernel.org/r/20240916-lan969x-clock-v1-4-0e150336074d@microchip.com
|
||||
Signed-off-by: Claudiu Beznea <claudiu.beznea@tuxon.dev>
|
||||
---
|
||||
drivers/clk/clk-lan966x.c | 23 +++++++++++++++++++++++
|
||||
1 file changed, 23 insertions(+)
|
||||
|
||||
--- a/drivers/clk/clk-lan966x.c
|
||||
+++ b/drivers/clk/clk-lan966x.c
|
||||
@@ -31,6 +31,13 @@ static const char * const lan966x_clk_na
|
||||
"flexcom4", "timer1", "usb_refclk",
|
||||
};
|
||||
|
||||
+static const char * const lan969x_clk_names[] = {
|
||||
+ "qspi0", "qspi2", "sdmmc0", "sdmmc1",
|
||||
+ "mcan0", "mcan1", "flexcom0",
|
||||
+ "flexcom1", "flexcom2", "flexcom3",
|
||||
+ "timer1", "usb_refclk",
|
||||
+};
|
||||
+
|
||||
struct lan966x_gck {
|
||||
struct clk_hw hw;
|
||||
void __iomem *reg;
|
||||
@@ -61,6 +68,13 @@ static const struct clk_gate_soc_desc la
|
||||
{ }
|
||||
};
|
||||
|
||||
+static const struct clk_gate_soc_desc lan969x_clk_gate_desc[] = {
|
||||
+ { "usb_drd", 10 },
|
||||
+ { "mcramc", 9 },
|
||||
+ { "hmatrix", 8 },
|
||||
+ { }
|
||||
+};
|
||||
+
|
||||
struct lan966x_match_data {
|
||||
char *name;
|
||||
const char * const *clk_name;
|
||||
@@ -77,6 +91,14 @@ static struct lan966x_match_data lan966x
|
||||
.num_generic_clks = 14,
|
||||
};
|
||||
|
||||
+static struct lan966x_match_data lan969x_desc = {
|
||||
+ .name = "lan969x",
|
||||
+ .clk_name = lan969x_clk_names,
|
||||
+ .clk_gate_desc = lan969x_clk_gate_desc,
|
||||
+ .num_total_clks = 15,
|
||||
+ .num_generic_clks = 12,
|
||||
+};
|
||||
+
|
||||
static DEFINE_SPINLOCK(clk_gate_lock);
|
||||
static void __iomem *base;
|
||||
|
||||
@@ -281,6 +303,7 @@ static int lan966x_clk_probe(struct plat
|
||||
|
||||
static const struct of_device_id lan966x_clk_dt_ids[] = {
|
||||
{ .compatible = "microchip,lan966x-gck", .data = &lan966x_desc },
|
||||
+ { .compatible = "microchip,lan9691-gck", .data = &lan969x_desc },
|
||||
{ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, lan966x_clk_dt_ids);
|
||||
@ -0,0 +1,84 @@
|
||||
From 6c18e8aba5313a930a72c5b2143e73e2cc437a14 Mon Sep 17 00:00:00 2001
|
||||
From: Daniel Machon <daniel.machon@microchip.com>
|
||||
Date: Mon, 9 Sep 2024 17:14:41 +0200
|
||||
Subject: [PATCH 08/25] phy: sparx5-serdes: add support for private match data
|
||||
|
||||
In order to reuse the existing Sparx5 SERDES driver for lan969x, we add
|
||||
support for private match data, with initial fields for the iomap and
|
||||
imap_size.
|
||||
|
||||
Signed-off-by: Daniel Machon <daniel.machon@microchip.com>
|
||||
Reviewed-by: Steen Hegelund <Steen.Hegelund@microchip.com>
|
||||
Link: https://lore.kernel.org/r/20240909-sparx5-lan969x-serdes-driver-v2-1-d695bcb57b84@microchip.com
|
||||
Signed-off-by: Vinod Koul <vkoul@kernel.org>
|
||||
---
|
||||
drivers/phy/microchip/sparx5_serdes.c | 16 +++++++++++++---
|
||||
drivers/phy/microchip/sparx5_serdes.h | 6 ++++++
|
||||
2 files changed, 19 insertions(+), 3 deletions(-)
|
||||
|
||||
--- a/drivers/phy/microchip/sparx5_serdes.c
|
||||
+++ b/drivers/phy/microchip/sparx5_serdes.c
|
||||
@@ -2507,6 +2507,11 @@ static struct sparx5_serdes_io_resource
|
||||
{ TARGET_SD_LANE_25G + 7, 0x5c8000 }, /* 0x610dd0000: sd_lane_25g_32 */
|
||||
};
|
||||
|
||||
+static const struct sparx5_serdes_match_data sparx5_desc = {
|
||||
+ .iomap = sparx5_serdes_iomap,
|
||||
+ .iomap_size = ARRAY_SIZE(sparx5_serdes_iomap),
|
||||
+};
|
||||
+
|
||||
/* Client lookup function, uses serdes index */
|
||||
static struct phy *sparx5_serdes_xlate(struct device *dev,
|
||||
const struct of_phandle_args *args)
|
||||
@@ -2555,6 +2560,10 @@ static int sparx5_serdes_probe(struct pl
|
||||
platform_set_drvdata(pdev, priv);
|
||||
priv->dev = &pdev->dev;
|
||||
|
||||
+ priv->data = device_get_match_data(priv->dev);
|
||||
+ if (!priv->data)
|
||||
+ return -EINVAL;
|
||||
+
|
||||
/* Get coreclock */
|
||||
clk = devm_clk_get(priv->dev, NULL);
|
||||
if (IS_ERR(clk)) {
|
||||
@@ -2579,8 +2588,9 @@ static int sparx5_serdes_probe(struct pl
|
||||
iores->name);
|
||||
return -ENOMEM;
|
||||
}
|
||||
- for (idx = 0; idx < ARRAY_SIZE(sparx5_serdes_iomap); idx++) {
|
||||
- struct sparx5_serdes_io_resource *iomap = &sparx5_serdes_iomap[idx];
|
||||
+ for (idx = 0; idx < priv->data->iomap_size; idx++) {
|
||||
+ const struct sparx5_serdes_io_resource *iomap =
|
||||
+ &priv->data->iomap[idx];
|
||||
|
||||
priv->regs[iomap->id] = iomem + iomap->offset;
|
||||
}
|
||||
@@ -2599,7 +2609,7 @@ static int sparx5_serdes_probe(struct pl
|
||||
}
|
||||
|
||||
static const struct of_device_id sparx5_serdes_match[] = {
|
||||
- { .compatible = "microchip,sparx5-serdes" },
|
||||
+ { .compatible = "microchip,sparx5-serdes", .data = &sparx5_desc },
|
||||
{ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, sparx5_serdes_match);
|
||||
--- a/drivers/phy/microchip/sparx5_serdes.h
|
||||
+++ b/drivers/phy/microchip/sparx5_serdes.h
|
||||
@@ -26,11 +26,17 @@ enum sparx5_serdes_mode {
|
||||
SPX5_SD_MODE_SFI,
|
||||
};
|
||||
|
||||
+struct sparx5_serdes_match_data {
|
||||
+ const struct sparx5_serdes_io_resource *iomap;
|
||||
+ int iomap_size;
|
||||
+};
|
||||
+
|
||||
struct sparx5_serdes_private {
|
||||
struct device *dev;
|
||||
void __iomem *regs[NUM_TARGETS];
|
||||
struct phy *phys[SPX5_SERDES_MAX];
|
||||
unsigned long coreclock;
|
||||
+ const struct sparx5_serdes_match_data *data;
|
||||
};
|
||||
|
||||
struct sparx5_serdes_macro {
|
||||
@ -0,0 +1,63 @@
|
||||
From 484f940614857bfb2766c6a0dadd6f77485ba992 Mon Sep 17 00:00:00 2001
|
||||
From: Daniel Machon <daniel.machon@microchip.com>
|
||||
Date: Mon, 9 Sep 2024 17:14:42 +0200
|
||||
Subject: [PATCH 09/25] phy: sparx5-serdes: add constants to match data
|
||||
|
||||
We need to handle a few different constants that differ for Sparx5 and
|
||||
lan969x. Add a new struct: sparx5_serdes_consts for this purpose. We
|
||||
populate it with an initial field for the number of SERDES'es: sd_max.
|
||||
|
||||
Signed-off-by: Daniel Machon <daniel.machon@microchip.com>
|
||||
Reviewed-by: Steen Hegelund <Steen.Hegelund@microchip.com>
|
||||
Link: https://lore.kernel.org/r/20240909-sparx5-lan969x-serdes-driver-v2-2-d695bcb57b84@microchip.com
|
||||
Signed-off-by: Vinod Koul <vkoul@kernel.org>
|
||||
---
|
||||
drivers/phy/microchip/sparx5_serdes.c | 7 +++++--
|
||||
drivers/phy/microchip/sparx5_serdes.h | 5 +++++
|
||||
2 files changed, 10 insertions(+), 2 deletions(-)
|
||||
|
||||
--- a/drivers/phy/microchip/sparx5_serdes.c
|
||||
+++ b/drivers/phy/microchip/sparx5_serdes.c
|
||||
@@ -2510,6 +2510,9 @@ static struct sparx5_serdes_io_resource
|
||||
static const struct sparx5_serdes_match_data sparx5_desc = {
|
||||
.iomap = sparx5_serdes_iomap,
|
||||
.iomap_size = ARRAY_SIZE(sparx5_serdes_iomap),
|
||||
+ .consts = {
|
||||
+ .sd_max = 33,
|
||||
+ },
|
||||
};
|
||||
|
||||
/* Client lookup function, uses serdes index */
|
||||
@@ -2526,7 +2529,7 @@ static struct phy *sparx5_serdes_xlate(s
|
||||
sidx = args->args[0];
|
||||
|
||||
/* Check validity: ERR_PTR(-ENODEV) if not valid */
|
||||
- for (idx = 0; idx < SPX5_SERDES_MAX; idx++) {
|
||||
+ for (idx = 0; idx < priv->data->consts.sd_max; idx++) {
|
||||
struct sparx5_serdes_macro *macro =
|
||||
phy_get_drvdata(priv->phys[idx]);
|
||||
|
||||
@@ -2594,7 +2597,7 @@ static int sparx5_serdes_probe(struct pl
|
||||
|
||||
priv->regs[iomap->id] = iomem + iomap->offset;
|
||||
}
|
||||
- for (idx = 0; idx < SPX5_SERDES_MAX; idx++) {
|
||||
+ for (idx = 0; idx < priv->data->consts.sd_max; idx++) {
|
||||
err = sparx5_phy_create(priv, idx, &priv->phys[idx]);
|
||||
if (err)
|
||||
return err;
|
||||
--- a/drivers/phy/microchip/sparx5_serdes.h
|
||||
+++ b/drivers/phy/microchip/sparx5_serdes.h
|
||||
@@ -26,7 +26,12 @@ enum sparx5_serdes_mode {
|
||||
SPX5_SD_MODE_SFI,
|
||||
};
|
||||
|
||||
+struct sparx5_serdes_consts {
|
||||
+ int sd_max;
|
||||
+};
|
||||
+
|
||||
struct sparx5_serdes_match_data {
|
||||
+ const struct sparx5_serdes_consts consts;
|
||||
const struct sparx5_serdes_io_resource *iomap;
|
||||
int iomap_size;
|
||||
};
|
||||
@ -0,0 +1,56 @@
|
||||
From 25fec35ac0e5bf3f9da0920055c278bb170983d2 Mon Sep 17 00:00:00 2001
|
||||
From: Daniel Machon <daniel.machon@microchip.com>
|
||||
Date: Mon, 9 Sep 2024 17:14:43 +0200
|
||||
Subject: [PATCH 10/25] phy: sparx5-serdes: add constant for the number of
|
||||
CMU's
|
||||
|
||||
The number of CMU's differ for Sparx5 and lan969x, so add a new field:
|
||||
cmu_max and use it throughout.
|
||||
|
||||
Signed-off-by: Daniel Machon <daniel.machon@microchip.com>
|
||||
Reviewed-by: Steen Hegelund <Steen.Hegelund@microchip.com>
|
||||
Link: https://lore.kernel.org/r/20240909-sparx5-lan969x-serdes-driver-v2-3-d695bcb57b84@microchip.com
|
||||
Signed-off-by: Vinod Koul <vkoul@kernel.org>
|
||||
---
|
||||
drivers/phy/microchip/sparx5_serdes.c | 5 ++---
|
||||
drivers/phy/microchip/sparx5_serdes.h | 1 +
|
||||
2 files changed, 3 insertions(+), 3 deletions(-)
|
||||
|
||||
--- a/drivers/phy/microchip/sparx5_serdes.c
|
||||
+++ b/drivers/phy/microchip/sparx5_serdes.c
|
||||
@@ -21,8 +21,6 @@
|
||||
|
||||
#include "sparx5_serdes.h"
|
||||
|
||||
-#define SPX5_CMU_MAX 14
|
||||
-
|
||||
#define SPX5_SERDES_10G_START 13
|
||||
#define SPX5_SERDES_25G_START 25
|
||||
#define SPX5_SERDES_6G10G_CNT SPX5_SERDES_25G_START
|
||||
@@ -1101,7 +1099,7 @@ static void sparx5_serdes_cmu_power_off(
|
||||
int i;
|
||||
|
||||
/* Power down each CMU */
|
||||
- for (i = 0; i < SPX5_CMU_MAX; i++) {
|
||||
+ for (i = 0; i < priv->data->consts.cmu_max; i++) {
|
||||
cmu_inst = sdx5_inst_get(priv, TARGET_SD_CMU, i);
|
||||
cmu_cfg_inst = sdx5_inst_get(priv, TARGET_SD_CMU_CFG, i);
|
||||
|
||||
@@ -2512,6 +2510,7 @@ static const struct sparx5_serdes_match_
|
||||
.iomap_size = ARRAY_SIZE(sparx5_serdes_iomap),
|
||||
.consts = {
|
||||
.sd_max = 33,
|
||||
+ .cmu_max = 14,
|
||||
},
|
||||
};
|
||||
|
||||
--- a/drivers/phy/microchip/sparx5_serdes.h
|
||||
+++ b/drivers/phy/microchip/sparx5_serdes.h
|
||||
@@ -28,6 +28,7 @@ enum sparx5_serdes_mode {
|
||||
|
||||
struct sparx5_serdes_consts {
|
||||
int sd_max;
|
||||
+ int cmu_max;
|
||||
};
|
||||
|
||||
struct sparx5_serdes_match_data {
|
||||
@ -0,0 +1,120 @@
|
||||
From 06d4a10a636ef4c97680007abb4625b9eebbf169 Mon Sep 17 00:00:00 2001
|
||||
From: Daniel Machon <daniel.machon@microchip.com>
|
||||
Date: Mon, 9 Sep 2024 17:14:44 +0200
|
||||
Subject: [PATCH 11/25] phy: sparx5-serdes: add ops to match data
|
||||
|
||||
We need to handle code differently in a few places. Add a struct:
|
||||
sparx5_serdes_ops for this purpose, and populate it a with function to
|
||||
set the SERDES type.
|
||||
|
||||
Signed-off-by: Daniel Machon <daniel.machon@microchip.com>
|
||||
Reviewed-by: Steen Hegelund <Steen.Hegelund@microchip.com>
|
||||
Link: https://lore.kernel.org/r/20240909-sparx5-lan969x-serdes-driver-v2-4-d695bcb57b84@microchip.com
|
||||
Signed-off-by: Vinod Koul <vkoul@kernel.org>
|
||||
---
|
||||
drivers/phy/microchip/sparx5_serdes.c | 29 ++++++++++++++++++---------
|
||||
drivers/phy/microchip/sparx5_serdes.h | 27 +++++++++++++++----------
|
||||
2 files changed, 35 insertions(+), 21 deletions(-)
|
||||
|
||||
--- a/drivers/phy/microchip/sparx5_serdes.c
|
||||
+++ b/drivers/phy/microchip/sparx5_serdes.c
|
||||
@@ -2373,6 +2373,20 @@ static const struct phy_ops sparx5_serde
|
||||
.owner = THIS_MODULE,
|
||||
};
|
||||
|
||||
+static void sparx5_serdes_type_set(struct sparx5_serdes_macro *macro, int sidx)
|
||||
+{
|
||||
+ if (sidx < SPX5_SERDES_10G_START) {
|
||||
+ macro->serdestype = SPX5_SDT_6G;
|
||||
+ macro->stpidx = macro->sidx;
|
||||
+ } else if (sidx < SPX5_SERDES_25G_START) {
|
||||
+ macro->serdestype = SPX5_SDT_10G;
|
||||
+ macro->stpidx = macro->sidx - SPX5_SERDES_10G_START;
|
||||
+ } else {
|
||||
+ macro->serdestype = SPX5_SDT_25G;
|
||||
+ macro->stpidx = macro->sidx - SPX5_SERDES_25G_START;
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
static int sparx5_phy_create(struct sparx5_serdes_private *priv,
|
||||
int idx, struct phy **phy)
|
||||
{
|
||||
@@ -2389,16 +2403,8 @@ static int sparx5_phy_create(struct spar
|
||||
macro->sidx = idx;
|
||||
macro->priv = priv;
|
||||
macro->speed = SPEED_UNKNOWN;
|
||||
- if (idx < SPX5_SERDES_10G_START) {
|
||||
- macro->serdestype = SPX5_SDT_6G;
|
||||
- macro->stpidx = macro->sidx;
|
||||
- } else if (idx < SPX5_SERDES_25G_START) {
|
||||
- macro->serdestype = SPX5_SDT_10G;
|
||||
- macro->stpidx = macro->sidx - SPX5_SERDES_10G_START;
|
||||
- } else {
|
||||
- macro->serdestype = SPX5_SDT_25G;
|
||||
- macro->stpidx = macro->sidx - SPX5_SERDES_25G_START;
|
||||
- }
|
||||
+
|
||||
+ priv->data->ops.serdes_type_set(macro, idx);
|
||||
|
||||
phy_set_drvdata(*phy, macro);
|
||||
|
||||
@@ -2512,6 +2518,9 @@ static const struct sparx5_serdes_match_
|
||||
.sd_max = 33,
|
||||
.cmu_max = 14,
|
||||
},
|
||||
+ .ops = {
|
||||
+ .serdes_type_set = &sparx5_serdes_type_set,
|
||||
+ },
|
||||
};
|
||||
|
||||
/* Client lookup function, uses serdes index */
|
||||
--- a/drivers/phy/microchip/sparx5_serdes.h
|
||||
+++ b/drivers/phy/microchip/sparx5_serdes.h
|
||||
@@ -26,13 +26,29 @@ enum sparx5_serdes_mode {
|
||||
SPX5_SD_MODE_SFI,
|
||||
};
|
||||
|
||||
+struct sparx5_serdes_macro {
|
||||
+ struct sparx5_serdes_private *priv;
|
||||
+ u32 sidx;
|
||||
+ u32 stpidx;
|
||||
+ enum sparx5_serdes_type serdestype;
|
||||
+ enum sparx5_serdes_mode serdesmode;
|
||||
+ phy_interface_t portmode;
|
||||
+ int speed;
|
||||
+ enum phy_media media;
|
||||
+};
|
||||
+
|
||||
struct sparx5_serdes_consts {
|
||||
int sd_max;
|
||||
int cmu_max;
|
||||
};
|
||||
|
||||
+struct sparx5_serdes_ops {
|
||||
+ void (*serdes_type_set)(struct sparx5_serdes_macro *macro, int sidx);
|
||||
+};
|
||||
+
|
||||
struct sparx5_serdes_match_data {
|
||||
const struct sparx5_serdes_consts consts;
|
||||
+ const struct sparx5_serdes_ops ops;
|
||||
const struct sparx5_serdes_io_resource *iomap;
|
||||
int iomap_size;
|
||||
};
|
||||
@@ -45,17 +61,6 @@ struct sparx5_serdes_private {
|
||||
const struct sparx5_serdes_match_data *data;
|
||||
};
|
||||
|
||||
-struct sparx5_serdes_macro {
|
||||
- struct sparx5_serdes_private *priv;
|
||||
- u32 sidx;
|
||||
- u32 stpidx;
|
||||
- enum sparx5_serdes_type serdestype;
|
||||
- enum sparx5_serdes_mode serdesmode;
|
||||
- phy_interface_t portmode;
|
||||
- int speed;
|
||||
- enum phy_media media;
|
||||
-};
|
||||
-
|
||||
/* Read, Write and modify registers content.
|
||||
* The register definition macros start at the id
|
||||
*/
|
||||
@ -0,0 +1,77 @@
|
||||
From e072ab8d032cd89a6c5333652c2ea909a8942b8a Mon Sep 17 00:00:00 2001
|
||||
From: Daniel Machon <daniel.machon@microchip.com>
|
||||
Date: Mon, 9 Sep 2024 17:14:45 +0200
|
||||
Subject: [PATCH 12/25] phy: sparx5-serdes: add function for getting the CMU
|
||||
index
|
||||
|
||||
The SERDES to CMU mapping is different on Sparx5 and lan969x. Therefore
|
||||
create a function for getting the CMU index on Sparx5.
|
||||
|
||||
Signed-off-by: Daniel Machon <daniel.machon@microchip.com>
|
||||
Reviewed-by: Steen Hegelund <Steen.Hegelund@microchip.com>
|
||||
Link: https://lore.kernel.org/r/20240909-sparx5-lan969x-serdes-driver-v2-5-d695bcb57b84@microchip.com
|
||||
Signed-off-by: Vinod Koul <vkoul@kernel.org>
|
||||
---
|
||||
drivers/phy/microchip/sparx5_serdes.c | 11 ++---------
|
||||
drivers/phy/microchip/sparx5_serdes.h | 9 +++++++++
|
||||
2 files changed, 11 insertions(+), 9 deletions(-)
|
||||
|
||||
--- a/drivers/phy/microchip/sparx5_serdes.c
|
||||
+++ b/drivers/phy/microchip/sparx5_serdes.c
|
||||
@@ -28,14 +28,6 @@
|
||||
/* Optimal power settings from GUC */
|
||||
#define SPX5_SERDES_QUIET_MODE_VAL 0x01ef4e0c
|
||||
|
||||
-enum sparx5_10g28cmu_mode {
|
||||
- SPX5_SD10G28_CMU_MAIN = 0,
|
||||
- SPX5_SD10G28_CMU_AUX1 = 1,
|
||||
- SPX5_SD10G28_CMU_AUX2 = 3,
|
||||
- SPX5_SD10G28_CMU_NONE = 4,
|
||||
- SPX5_SD10G28_CMU_MAX,
|
||||
-};
|
||||
-
|
||||
enum sparx5_sd25g28_mode_preset_type {
|
||||
SPX5_SD25G28_MODE_PRESET_25000,
|
||||
SPX5_SD25G28_MODE_PRESET_10000,
|
||||
@@ -1648,7 +1640,7 @@ static int sparx5_sd10g28_apply_params(s
|
||||
if (params->skip_cmu_cfg)
|
||||
return 0;
|
||||
|
||||
- cmu_idx = sparx5_serdes_cmu_get(params->cmu_sel, lane_index);
|
||||
+ cmu_idx = priv->data->ops.serdes_cmu_get(params->cmu_sel, macro->sidx);
|
||||
err = sparx5_cmu_cfg(priv, cmu_idx);
|
||||
if (err)
|
||||
return err;
|
||||
@@ -2520,6 +2512,7 @@ static const struct sparx5_serdes_match_
|
||||
},
|
||||
.ops = {
|
||||
.serdes_type_set = &sparx5_serdes_type_set,
|
||||
+ .serdes_cmu_get = &sparx5_serdes_cmu_get,
|
||||
},
|
||||
};
|
||||
|
||||
--- a/drivers/phy/microchip/sparx5_serdes.h
|
||||
+++ b/drivers/phy/microchip/sparx5_serdes.h
|
||||
@@ -26,6 +26,14 @@ enum sparx5_serdes_mode {
|
||||
SPX5_SD_MODE_SFI,
|
||||
};
|
||||
|
||||
+enum sparx5_10g28cmu_mode {
|
||||
+ SPX5_SD10G28_CMU_MAIN = 0,
|
||||
+ SPX5_SD10G28_CMU_AUX1 = 1,
|
||||
+ SPX5_SD10G28_CMU_AUX2 = 3,
|
||||
+ SPX5_SD10G28_CMU_NONE = 4,
|
||||
+ SPX5_SD10G28_CMU_MAX,
|
||||
+};
|
||||
+
|
||||
struct sparx5_serdes_macro {
|
||||
struct sparx5_serdes_private *priv;
|
||||
u32 sidx;
|
||||
@@ -44,6 +52,7 @@ struct sparx5_serdes_consts {
|
||||
|
||||
struct sparx5_serdes_ops {
|
||||
void (*serdes_type_set)(struct sparx5_serdes_macro *macro, int sidx);
|
||||
+ int (*serdes_cmu_get)(enum sparx5_10g28cmu_mode mode, int sd_index);
|
||||
};
|
||||
|
||||
struct sparx5_serdes_match_data {
|
||||
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,101 @@
|
||||
From db156d900072423be739b1aaaa68a712d3fcb8e4 Mon Sep 17 00:00:00 2001
|
||||
From: Daniel Machon <daniel.machon@microchip.com>
|
||||
Date: Mon, 9 Sep 2024 17:14:47 +0200
|
||||
Subject: [PATCH 14/25] phy: sparx5-serdes: add support for branching on chip
|
||||
type
|
||||
|
||||
In preparation for lan969x, add a way to branch out on code that is to
|
||||
be executed on either Sparx5 or lan969x. Initially, this is required to
|
||||
branch out when checking the SERDES types and SERDES speeds, since the
|
||||
handling of these differ on the two platforms. This will also be used by
|
||||
the lan969x driver introduced in a subsequent patch.
|
||||
|
||||
Signed-off-by: Daniel Machon <daniel.machon@microchip.com>
|
||||
Reviewed-by: Steen Hegelund <Steen.Hegelund@microchip.com>
|
||||
Link: https://lore.kernel.org/r/20240909-sparx5-lan969x-serdes-driver-v2-7-d695bcb57b84@microchip.com
|
||||
Signed-off-by: Vinod Koul <vkoul@kernel.org>
|
||||
---
|
||||
drivers/phy/microchip/sparx5_serdes.c | 29 +++++++++++++++++----------
|
||||
drivers/phy/microchip/sparx5_serdes.h | 5 +++++
|
||||
2 files changed, 23 insertions(+), 11 deletions(-)
|
||||
|
||||
--- a/drivers/phy/microchip/sparx5_serdes.c
|
||||
+++ b/drivers/phy/microchip/sparx5_serdes.c
|
||||
@@ -2298,10 +2298,12 @@ static int sparx5_serdes_set_speed(struc
|
||||
{
|
||||
struct sparx5_serdes_macro *macro = phy_get_drvdata(phy);
|
||||
|
||||
- if (macro->sidx < SPX5_SERDES_10G_START && speed > SPEED_5000)
|
||||
- return -EINVAL;
|
||||
- if (macro->sidx < SPX5_SERDES_25G_START && speed > SPEED_10000)
|
||||
- return -EINVAL;
|
||||
+ if (macro->priv->data->type == SPX5_TARGET_SPARX5) {
|
||||
+ if (macro->sidx < SPX5_SERDES_10G_START && speed > SPEED_5000)
|
||||
+ return -EINVAL;
|
||||
+ if (macro->sidx < SPX5_SERDES_25G_START && speed > SPEED_10000)
|
||||
+ return -EINVAL;
|
||||
+ }
|
||||
if (speed != macro->speed) {
|
||||
macro->speed = speed;
|
||||
if (macro->serdesmode != SPX5_SD_MODE_NONE)
|
||||
@@ -2338,11 +2340,14 @@ static int sparx5_serdes_validate(struct
|
||||
if (macro->speed == 0)
|
||||
return -EINVAL;
|
||||
|
||||
- if (macro->sidx < SPX5_SERDES_10G_START && macro->speed > SPEED_5000)
|
||||
- return -EINVAL;
|
||||
- if (macro->sidx < SPX5_SERDES_25G_START && macro->speed > SPEED_10000)
|
||||
- return -EINVAL;
|
||||
-
|
||||
+ if (macro->priv->data->type == SPX5_TARGET_SPARX5) {
|
||||
+ if (macro->sidx < SPX5_SERDES_10G_START &&
|
||||
+ macro->speed > SPEED_5000)
|
||||
+ return -EINVAL;
|
||||
+ if (macro->sidx < SPX5_SERDES_25G_START &&
|
||||
+ macro->speed > SPEED_10000)
|
||||
+ return -EINVAL;
|
||||
+ }
|
||||
switch (submode) {
|
||||
case PHY_INTERFACE_MODE_1000BASEX:
|
||||
if (macro->speed != SPEED_100 && /* This is for 100BASE-FX */
|
||||
@@ -2515,6 +2520,7 @@ static struct sparx5_serdes_io_resource
|
||||
};
|
||||
|
||||
static const struct sparx5_serdes_match_data sparx5_desc = {
|
||||
+ .type = SPX5_TARGET_SPARX5,
|
||||
.iomap = sparx5_serdes_iomap,
|
||||
.iomap_size = ARRAY_SIZE(sparx5_serdes_iomap),
|
||||
.tsize = sparx5_serdes_tsize,
|
||||
@@ -2618,8 +2624,9 @@ static int sparx5_serdes_probe(struct pl
|
||||
return err;
|
||||
}
|
||||
|
||||
- /* Power down all CMUs by default */
|
||||
- sparx5_serdes_cmu_power_off(priv);
|
||||
+ /* Power down all CMU's by default */
|
||||
+ if (priv->data->type == SPX5_TARGET_SPARX5)
|
||||
+ sparx5_serdes_cmu_power_off(priv);
|
||||
|
||||
provider = devm_of_phy_provider_register(priv->dev, sparx5_serdes_xlate);
|
||||
|
||||
--- a/drivers/phy/microchip/sparx5_serdes.h
|
||||
+++ b/drivers/phy/microchip/sparx5_serdes.h
|
||||
@@ -34,6 +34,10 @@ enum sparx5_10g28cmu_mode {
|
||||
SPX5_SD10G28_CMU_MAX,
|
||||
};
|
||||
|
||||
+enum sparx5_target {
|
||||
+ SPX5_TARGET_SPARX5,
|
||||
+};
|
||||
+
|
||||
struct sparx5_serdes_macro {
|
||||
struct sparx5_serdes_private *priv;
|
||||
u32 sidx;
|
||||
@@ -56,6 +60,7 @@ struct sparx5_serdes_ops {
|
||||
};
|
||||
|
||||
struct sparx5_serdes_match_data {
|
||||
+ enum sparx5_target type;
|
||||
const struct sparx5_serdes_consts consts;
|
||||
const struct sparx5_serdes_ops ops;
|
||||
const struct sparx5_serdes_io_resource *iomap;
|
||||
@ -0,0 +1,175 @@
|
||||
From ec933122868bb205d8cdecc2049c49f811d32397 Mon Sep 17 00:00:00 2001
|
||||
From: Daniel Machon <daniel.machon@microchip.com>
|
||||
Date: Mon, 9 Sep 2024 17:14:49 +0200
|
||||
Subject: [PATCH 15/25] phy: lan969x-serdes: add support for lan969x serdes
|
||||
driver
|
||||
|
||||
Add support for lan969x SERDES driver. Lan969x has ten 10G SERDES'es
|
||||
which share the same features and data rates as the Sparx5 SERDES'es.
|
||||
|
||||
Signed-off-by: Daniel Machon <daniel.machon@microchip.com>
|
||||
Reviewed-by: Steen Hegelund <Steen.Hegelund@microchip.com>
|
||||
Link: https://lore.kernel.org/r/20240909-sparx5-lan969x-serdes-driver-v2-9-d695bcb57b84@microchip.com
|
||||
Signed-off-by: Vinod Koul <vkoul@kernel.org>
|
||||
---
|
||||
drivers/phy/microchip/sparx5_serdes.c | 88 +++++++++++++++++++++++++++
|
||||
drivers/phy/microchip/sparx5_serdes.h | 2 +
|
||||
2 files changed, 90 insertions(+)
|
||||
|
||||
--- a/drivers/phy/microchip/sparx5_serdes.c
|
||||
+++ b/drivers/phy/microchip/sparx5_serdes.c
|
||||
@@ -25,6 +25,8 @@
|
||||
#define SPX5_SERDES_25G_START 25
|
||||
#define SPX5_SERDES_6G10G_CNT SPX5_SERDES_25G_START
|
||||
|
||||
+#define LAN969X_SERDES_10G_CNT 10
|
||||
+
|
||||
/* Optimal power settings from GUC */
|
||||
#define SPX5_SERDES_QUIET_MODE_VAL 0x01ef4e0c
|
||||
|
||||
@@ -36,6 +38,13 @@ const unsigned int sparx5_serdes_tsize[T
|
||||
[TC_SD_LANE] = 25,
|
||||
};
|
||||
|
||||
+const unsigned int lan969x_serdes_tsize[TSIZE_LAST] = {
|
||||
+ [TC_SD10G_LANE] = 10,
|
||||
+ [TC_SD_CMU] = 6,
|
||||
+ [TC_SD_CMU_CFG] = 6,
|
||||
+ [TC_SD_LANE] = 10,
|
||||
+};
|
||||
+
|
||||
/* Pointer to the register target size table */
|
||||
const unsigned int *tsize;
|
||||
|
||||
@@ -1096,6 +1105,24 @@ static int sparx5_serdes_cmu_get(enum sp
|
||||
return sparx5_serdes_cmu_map[mode][sd_index];
|
||||
}
|
||||
|
||||
+/* Map of 6G/10G serdes mode and index to CMU index. */
|
||||
+static const int
|
||||
+lan969x_serdes_cmu_map[SPX5_SD10G28_CMU_MAX][LAN969X_SERDES_10G_CNT] = {
|
||||
+ [SPX5_SD10G28_CMU_MAIN] = { 2, 2, 2, 2, 2,
|
||||
+ 2, 2, 2, 5, 5 },
|
||||
+ [SPX5_SD10G28_CMU_AUX1] = { 0, 0, 3, 3, 3,
|
||||
+ 3, 3, 3, 3, 3 },
|
||||
+ [SPX5_SD10G28_CMU_AUX2] = { 1, 1, 1, 1, 4,
|
||||
+ 4, 4, 4, 4, 4 },
|
||||
+ [SPX5_SD10G28_CMU_NONE] = { 1, 1, 1, 1, 4,
|
||||
+ 4, 4, 4, 4, 4 },
|
||||
+};
|
||||
+
|
||||
+static int lan969x_serdes_cmu_get(enum sparx5_10g28cmu_mode mode, int sd_index)
|
||||
+{
|
||||
+ return lan969x_serdes_cmu_map[mode][sd_index];
|
||||
+}
|
||||
+
|
||||
static void sparx5_serdes_cmu_power_off(struct sparx5_serdes_private *priv)
|
||||
{
|
||||
void __iomem *cmu_inst, *cmu_cfg_inst;
|
||||
@@ -2184,6 +2211,10 @@ static int sparx5_serdes_clock_config(st
|
||||
{
|
||||
struct sparx5_serdes_private *priv = macro->priv;
|
||||
|
||||
+ /* Clock is auto-detected in 100Base-FX mode on lan969x */
|
||||
+ if (priv->data->type == SPX5_TARGET_LAN969X)
|
||||
+ return 0;
|
||||
+
|
||||
if (macro->serdesmode == SPX5_SD_MODE_100FX) {
|
||||
u32 freq = priv->coreclock == 250000000 ? 2 :
|
||||
priv->coreclock == 500000000 ? 1 : 0;
|
||||
@@ -2395,6 +2426,12 @@ static void sparx5_serdes_type_set(struc
|
||||
}
|
||||
}
|
||||
|
||||
+static void lan969x_serdes_type_set(struct sparx5_serdes_macro *macro, int sidx)
|
||||
+{
|
||||
+ macro->serdestype = SPX5_SDT_10G;
|
||||
+ macro->stpidx = macro->sidx;
|
||||
+}
|
||||
+
|
||||
static int sparx5_phy_create(struct sparx5_serdes_private *priv,
|
||||
int idx, struct phy **phy)
|
||||
{
|
||||
@@ -2519,6 +2556,41 @@ static struct sparx5_serdes_io_resource
|
||||
{ TARGET_SD_LANE_25G + 7, 0x5c8000 }, /* 0x610dd0000: sd_lane_25g_32 */
|
||||
};
|
||||
|
||||
+static const struct sparx5_serdes_io_resource lan969x_serdes_iomap[] = {
|
||||
+ { TARGET_SD_CMU, 0x0 }, /* 0xe3410000 */
|
||||
+ { TARGET_SD_CMU + 1, 0x8000 }, /* 0xe3418000 */
|
||||
+ { TARGET_SD_CMU + 2, 0x10000 }, /* 0xe3420000 */
|
||||
+ { TARGET_SD_CMU + 3, 0x18000 }, /* 0xe3428000 */
|
||||
+ { TARGET_SD_CMU + 4, 0x20000 }, /* 0xe3430000 */
|
||||
+ { TARGET_SD_CMU + 5, 0x28000 }, /* 0xe3438000 */
|
||||
+ { TARGET_SD_CMU_CFG, 0x30000 }, /* 0xe3440000 */
|
||||
+ { TARGET_SD_CMU_CFG + 1, 0x38000 }, /* 0xe3448000 */
|
||||
+ { TARGET_SD_CMU_CFG + 2, 0x40000 }, /* 0xe3450000 */
|
||||
+ { TARGET_SD_CMU_CFG + 3, 0x48000 }, /* 0xe3458000 */
|
||||
+ { TARGET_SD_CMU_CFG + 4, 0x50000 }, /* 0xe3460000 */
|
||||
+ { TARGET_SD_CMU_CFG + 5, 0x58000 }, /* 0xe3468000 */
|
||||
+ { TARGET_SD10G_LANE, 0x60000 }, /* 0xe3470000 */
|
||||
+ { TARGET_SD10G_LANE + 1, 0x68000 }, /* 0xe3478000 */
|
||||
+ { TARGET_SD10G_LANE + 2, 0x70000 }, /* 0xe3480000 */
|
||||
+ { TARGET_SD10G_LANE + 3, 0x78000 }, /* 0xe3488000 */
|
||||
+ { TARGET_SD10G_LANE + 4, 0x80000 }, /* 0xe3490000 */
|
||||
+ { TARGET_SD10G_LANE + 5, 0x88000 }, /* 0xe3498000 */
|
||||
+ { TARGET_SD10G_LANE + 6, 0x90000 }, /* 0xe34a0000 */
|
||||
+ { TARGET_SD10G_LANE + 7, 0x98000 }, /* 0xe34a8000 */
|
||||
+ { TARGET_SD10G_LANE + 8, 0xa0000 }, /* 0xe34b0000 */
|
||||
+ { TARGET_SD10G_LANE + 9, 0xa8000 }, /* 0xe34b8000 */
|
||||
+ { TARGET_SD_LANE, 0x100000 }, /* 0xe3510000 */
|
||||
+ { TARGET_SD_LANE + 1, 0x108000 }, /* 0xe3518000 */
|
||||
+ { TARGET_SD_LANE + 2, 0x110000 }, /* 0xe3520000 */
|
||||
+ { TARGET_SD_LANE + 3, 0x118000 }, /* 0xe3528000 */
|
||||
+ { TARGET_SD_LANE + 4, 0x120000 }, /* 0xe3530000 */
|
||||
+ { TARGET_SD_LANE + 5, 0x128000 }, /* 0xe3538000 */
|
||||
+ { TARGET_SD_LANE + 6, 0x130000 }, /* 0xe3540000 */
|
||||
+ { TARGET_SD_LANE + 7, 0x138000 }, /* 0xe3548000 */
|
||||
+ { TARGET_SD_LANE + 8, 0x140000 }, /* 0xe3550000 */
|
||||
+ { TARGET_SD_LANE + 9, 0x148000 }, /* 0xe3558000 */
|
||||
+};
|
||||
+
|
||||
static const struct sparx5_serdes_match_data sparx5_desc = {
|
||||
.type = SPX5_TARGET_SPARX5,
|
||||
.iomap = sparx5_serdes_iomap,
|
||||
@@ -2534,6 +2606,21 @@ static const struct sparx5_serdes_match_
|
||||
},
|
||||
};
|
||||
|
||||
+static const struct sparx5_serdes_match_data lan969x_desc = {
|
||||
+ .type = SPX5_TARGET_LAN969X,
|
||||
+ .iomap = lan969x_serdes_iomap,
|
||||
+ .iomap_size = ARRAY_SIZE(lan969x_serdes_iomap),
|
||||
+ .tsize = lan969x_serdes_tsize,
|
||||
+ .consts = {
|
||||
+ .sd_max = 10,
|
||||
+ .cmu_max = 6,
|
||||
+ },
|
||||
+ .ops = {
|
||||
+ .serdes_type_set = &lan969x_serdes_type_set,
|
||||
+ .serdes_cmu_get = &lan969x_serdes_cmu_get,
|
||||
+ }
|
||||
+};
|
||||
+
|
||||
/* Client lookup function, uses serdes index */
|
||||
static struct phy *sparx5_serdes_xlate(struct device *dev,
|
||||
const struct of_phandle_args *args)
|
||||
@@ -2635,6 +2722,7 @@ static int sparx5_serdes_probe(struct pl
|
||||
|
||||
static const struct of_device_id sparx5_serdes_match[] = {
|
||||
{ .compatible = "microchip,sparx5-serdes", .data = &sparx5_desc },
|
||||
+ { .compatible = "microchip,lan9691-serdes", .data = &lan969x_desc },
|
||||
{ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, sparx5_serdes_match);
|
||||
--- a/drivers/phy/microchip/sparx5_serdes.h
|
||||
+++ b/drivers/phy/microchip/sparx5_serdes.h
|
||||
@@ -36,6 +36,8 @@ enum sparx5_10g28cmu_mode {
|
||||
|
||||
enum sparx5_target {
|
||||
SPX5_TARGET_SPARX5,
|
||||
+ SPX5_TARGET_LAN969X,
|
||||
+
|
||||
};
|
||||
|
||||
struct sparx5_serdes_macro {
|
||||
@ -0,0 +1,26 @@
|
||||
From 48a8c9defc691a038c1fa515b2b6c8edb6e55aa4 Mon Sep 17 00:00:00 2001
|
||||
From: Robert Marko <robert.marko@sartura.hr>
|
||||
Date: Wed, 8 Jan 2025 14:09:28 +0100
|
||||
Subject: [PATCH 17/25] tty: serial: atmel: make it selectable for ARCH_LAN969X
|
||||
|
||||
LAN969x uses the Atmel serial, so make it selectable for ARCH_LAN969X.
|
||||
|
||||
Signed-off-by: Robert Marko <robert.marko@sartura.hr>
|
||||
Acked-by: Nicolas Ferre <nicolas.ferre@microchip.com>
|
||||
Link: https://lore.kernel.org/r/20250108131045.40642-3-robert.marko@sartura.hr
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||
---
|
||||
drivers/tty/serial/Kconfig | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
--- a/drivers/tty/serial/Kconfig
|
||||
+++ b/drivers/tty/serial/Kconfig
|
||||
@@ -128,7 +128,7 @@ config SERIAL_SB1250_DUART_CONSOLE
|
||||
config SERIAL_ATMEL
|
||||
bool "AT91 on-chip serial port support"
|
||||
depends on COMMON_CLK
|
||||
- depends on ARCH_AT91 || COMPILE_TEST
|
||||
+ depends on ARCH_AT91 || ARCH_LAN969X || COMPILE_TEST
|
||||
select SERIAL_CORE
|
||||
select SERIAL_MCTRL_GPIO if GPIOLIB
|
||||
select MFD_AT91_USART
|
||||
@ -0,0 +1,26 @@
|
||||
From 04d0fbaff226d574e698ba1f6220be173b3b554d Mon Sep 17 00:00:00 2001
|
||||
From: Robert Marko <robert.marko@sartura.hr>
|
||||
Date: Fri, 31 Jan 2025 18:14:10 +0100
|
||||
Subject: [PATCH 18/25] mfd: at91-usart: Make it selectable for ARCH_LAN969X
|
||||
|
||||
LAN969x uses the AT91 USART IP so make it selectable for ARCH_LAN969X.
|
||||
|
||||
Signed-off-by: Robert Marko <robert.marko@sartura.hr>
|
||||
Acked-by: Nicolas Ferre <nicolas.ferre@microchip.com>
|
||||
Link: https://lore.kernel.org/r/20250131171739.1044701-2-robert.marko@sartura.hr
|
||||
Signed-off-by: Lee Jones <lee@kernel.org>
|
||||
---
|
||||
drivers/mfd/Kconfig | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
--- a/drivers/mfd/Kconfig
|
||||
+++ b/drivers/mfd/Kconfig
|
||||
@@ -138,7 +138,7 @@ config MFD_AAT2870_CORE
|
||||
config MFD_AT91_USART
|
||||
tristate "AT91 USART Driver"
|
||||
select MFD_CORE
|
||||
- depends on ARCH_AT91 || COMPILE_TEST
|
||||
+ depends on ARCH_AT91 || ARCH_LAN969X || COMPILE_TEST
|
||||
help
|
||||
Select this to get support for AT91 USART IP. This is a wrapper
|
||||
over at91-usart-serial driver and usart-spi-driver. Only one function
|
||||
@ -0,0 +1,27 @@
|
||||
From 823122980e18bf20eac1689ebccad488e828b33b Mon Sep 17 00:00:00 2001
|
||||
From: Robert Marko <robert.marko@sartura.hr>
|
||||
Date: Wed, 2 Jul 2025 20:36:06 +0200
|
||||
Subject: [PATCH 19/25] dmaengine: xdmac: make it selectable for ARCH_MICROCHIP
|
||||
|
||||
LAN969x uses the Atmel XDMAC, so make it selectable for ARCH_MICROCHIP to
|
||||
avoid needing to update depends in future if other Microchip SoC-s use it
|
||||
as well.
|
||||
|
||||
Signed-off-by: Robert Marko <robert.marko@sartura.hr>
|
||||
Link: https://lore.kernel.org/r/20250702183856.1727275-9-robert.marko@sartura.hr
|
||||
Signed-off-by: Vinod Koul <vkoul@kernel.org>
|
||||
---
|
||||
drivers/dma/Kconfig | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
--- a/drivers/dma/Kconfig
|
||||
+++ b/drivers/dma/Kconfig
|
||||
@@ -103,7 +103,7 @@ config AT_HDMAC
|
||||
|
||||
config AT_XDMAC
|
||||
tristate "Atmel XDMA support"
|
||||
- depends on ARCH_AT91
|
||||
+ depends on ARCH_MICROCHIP
|
||||
select DMA_ENGINE
|
||||
help
|
||||
Support the Atmel XDMA controller.
|
||||
@ -0,0 +1,28 @@
|
||||
From a1166284ce7eecc7ff3b0611ba58cbbee2e3953a Mon Sep 17 00:00:00 2001
|
||||
From: Robert Marko <robert.marko@sartura.hr>
|
||||
Date: Wed, 13 Aug 2025 19:44:40 +0200
|
||||
Subject: [PATCH 20/25] mfd: at91-usart: Make it selectable for ARCH_MICROCHIP
|
||||
|
||||
LAN969x uses the Atmel USART, so make it selectable for ARCH_MICROCHIP to
|
||||
avoid needing to update depends in future if other Microchip SoC-s use it
|
||||
as well.
|
||||
|
||||
Signed-off-by: Robert Marko <robert.marko@sartura.hr>
|
||||
Acked-by: Daniel Machon <daniel.machon@microchip.com>
|
||||
Acked-by: Lee Jones <lee@kernel.org>
|
||||
Signed-off-by: Nicolas Ferre <nicolas.ferre@microchip.com>
|
||||
---
|
||||
drivers/mfd/Kconfig | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
--- a/drivers/mfd/Kconfig
|
||||
+++ b/drivers/mfd/Kconfig
|
||||
@@ -138,7 +138,7 @@ config MFD_AAT2870_CORE
|
||||
config MFD_AT91_USART
|
||||
tristate "AT91 USART Driver"
|
||||
select MFD_CORE
|
||||
- depends on ARCH_AT91 || ARCH_LAN969X || COMPILE_TEST
|
||||
+ depends on ARCH_MICROCHIP || COMPILE_TEST
|
||||
help
|
||||
Select this to get support for AT91 USART IP. This is a wrapper
|
||||
over at91-usart-serial driver and usart-spi-driver. Only one function
|
||||
@ -0,0 +1,29 @@
|
||||
From 67a4c049056d6de07460d576e785c2fdbf64bc7c Mon Sep 17 00:00:00 2001
|
||||
From: Robert Marko <robert.marko@sartura.hr>
|
||||
Date: Wed, 13 Aug 2025 19:44:41 +0200
|
||||
Subject: [PATCH 21/25] tty: serial: atmel: make it selectable for
|
||||
ARCH_MICROCHIP
|
||||
|
||||
LAN969x uses the Atmel USART serial, so make it selectable for
|
||||
ARCH_MICROCHIP to avoid needing to update depends in future if other
|
||||
Microchip SoC-s use it as well.
|
||||
|
||||
Signed-off-by: Robert Marko <robert.marko@sartura.hr>
|
||||
Acked-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||
Acked-by: Daniel Machon <daniel.machon@microchip.com>
|
||||
Signed-off-by: Nicolas Ferre <nicolas.ferre@microchip.com>
|
||||
---
|
||||
drivers/tty/serial/Kconfig | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
--- a/drivers/tty/serial/Kconfig
|
||||
+++ b/drivers/tty/serial/Kconfig
|
||||
@@ -128,7 +128,7 @@ config SERIAL_SB1250_DUART_CONSOLE
|
||||
config SERIAL_ATMEL
|
||||
bool "AT91 on-chip serial port support"
|
||||
depends on COMMON_CLK
|
||||
- depends on ARCH_AT91 || ARCH_LAN969X || COMPILE_TEST
|
||||
+ depends on ARCH_MICROCHIP || COMPILE_TEST
|
||||
select SERIAL_CORE
|
||||
select SERIAL_MCTRL_GPIO if GPIOLIB
|
||||
select MFD_AT91_USART
|
||||
@ -0,0 +1,28 @@
|
||||
From e761a7b6753f3d4db9fde26dacab5ecff3b5d0e8 Mon Sep 17 00:00:00 2001
|
||||
From: Robert Marko <robert.marko@sartura.hr>
|
||||
Date: Wed, 13 Aug 2025 19:44:42 +0200
|
||||
Subject: [PATCH 22/25] spi: atmel: make it selectable for ARCH_MICROCHIP
|
||||
|
||||
LAN969x uses the Atmel SPI, so make it selectable for ARCH_MICROCHIP to
|
||||
avoid needing to update depends in future if other Microchip SoC-s use it
|
||||
as well.
|
||||
|
||||
Signed-off-by: Robert Marko <robert.marko@sartura.hr>
|
||||
Acked-by: Mark Brown <broonie@kernel.org>
|
||||
Acked-by: Daniel Machon <daniel.machon@microchip.com>
|
||||
Signed-off-by: Nicolas Ferre <nicolas.ferre@microchip.com>
|
||||
---
|
||||
drivers/spi/Kconfig | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
--- a/drivers/spi/Kconfig
|
||||
+++ b/drivers/spi/Kconfig
|
||||
@@ -131,7 +131,7 @@ config SPI_ASPEED_SMC
|
||||
|
||||
config SPI_ATMEL
|
||||
tristate "Atmel SPI Controller"
|
||||
- depends on ARCH_AT91 || COMPILE_TEST
|
||||
+ depends on ARCH_MICROCHIP || COMPILE_TEST
|
||||
depends on OF
|
||||
help
|
||||
This selects a driver for the Atmel SPI Controller, present on
|
||||
@ -0,0 +1,28 @@
|
||||
From 0ee61e26871b1c039b905569cf74382c800c1e8b Mon Sep 17 00:00:00 2001
|
||||
From: Robert Marko <robert.marko@sartura.hr>
|
||||
Date: Wed, 13 Aug 2025 19:44:43 +0200
|
||||
Subject: [PATCH 23/25] i2c: at91: make it selectable for ARCH_MICROCHIP
|
||||
|
||||
LAN969x uses the Atmel TWI I2C, so make it selectable for ARCH_MICROCHIP to
|
||||
avoid needing to update depends in future if other Microchip SoC-s use it
|
||||
as well.
|
||||
|
||||
Signed-off-by: Robert Marko <robert.marko@sartura.hr>
|
||||
Acked-by: Wolfram Sang <wsa+renesas@sang-engineering.com>
|
||||
Acked-by: Daniel Machon <daniel.machon@microchip.com>
|
||||
Signed-off-by: Nicolas Ferre <nicolas.ferre@microchip.com>
|
||||
---
|
||||
drivers/i2c/busses/Kconfig | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
--- a/drivers/i2c/busses/Kconfig
|
||||
+++ b/drivers/i2c/busses/Kconfig
|
||||
@@ -423,7 +423,7 @@ config I2C_ASPEED
|
||||
|
||||
config I2C_AT91
|
||||
tristate "Atmel AT91 I2C Two-Wire interface (TWI)"
|
||||
- depends on ARCH_AT91 || COMPILE_TEST
|
||||
+ depends on ARCH_MICROCHIP || COMPILE_TEST
|
||||
help
|
||||
This supports the use of the I2C interface on Atmel AT91
|
||||
processors.
|
||||
@ -0,0 +1,28 @@
|
||||
From 25e23abbc37484862c411b7317878d448b47fad5 Mon Sep 17 00:00:00 2001
|
||||
From: Robert Marko <robert.marko@sartura.hr>
|
||||
Date: Wed, 13 Aug 2025 19:44:44 +0200
|
||||
Subject: [PATCH 24/25] char: hw_random: atmel: make it selectable for
|
||||
ARCH_MICROCHIP
|
||||
|
||||
LAN969x uses the Atmel HWRNG, so make it selectable for ARCH_MICROCHIP to
|
||||
avoid needing to update depends in future if other Microchip SoC-s use it
|
||||
as well.
|
||||
|
||||
Signed-off-by: Robert Marko <robert.marko@sartura.hr>
|
||||
Acked-by: Daniel Machon <daniel.machon@microchip.com>
|
||||
Signed-off-by: Nicolas Ferre <nicolas.ferre@microchip.com>
|
||||
---
|
||||
drivers/char/hw_random/Kconfig | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
--- a/drivers/char/hw_random/Kconfig
|
||||
+++ b/drivers/char/hw_random/Kconfig
|
||||
@@ -64,7 +64,7 @@ config HW_RANDOM_AMD
|
||||
|
||||
config HW_RANDOM_ATMEL
|
||||
tristate "Atmel Random Number Generator support"
|
||||
- depends on (ARCH_AT91 || COMPILE_TEST)
|
||||
+ depends on (ARCH_MICROCHIP || COMPILE_TEST)
|
||||
default HW_RANDOM
|
||||
help
|
||||
This driver provides kernel-side support for the Random Number
|
||||
@ -0,0 +1,29 @@
|
||||
From 405fad723d71997ca9ad894ba7ac755a75fa5443 Mon Sep 17 00:00:00 2001
|
||||
From: Robert Marko <robert.marko@sartura.hr>
|
||||
Date: Wed, 13 Aug 2025 19:44:45 +0200
|
||||
Subject: [PATCH 25/25] crypto: atmel-aes: make it selectable for
|
||||
ARCH_MICROCHIP
|
||||
|
||||
LAN969x uses the Atmel crypto, so make it selectable for ARCH_MICROCHIP to
|
||||
avoid needing to update depends in future if other Microchip SoC-s use it
|
||||
as well.
|
||||
|
||||
Signed-off-by: Robert Marko <robert.marko@sartura.hr>
|
||||
Acked-by: Herbert Xu <herbert@gondor.apana.org.au>
|
||||
Acked-by: Daniel Machon <daniel.machon@microchip.com>
|
||||
Signed-off-by: Nicolas Ferre <nicolas.ferre@microchip.com>
|
||||
---
|
||||
drivers/crypto/Kconfig | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
--- a/drivers/crypto/Kconfig
|
||||
+++ b/drivers/crypto/Kconfig
|
||||
@@ -421,7 +421,7 @@ config CRYPTO_DEV_ATMEL_AUTHENC
|
||||
|
||||
config CRYPTO_DEV_ATMEL_AES
|
||||
tristate "Support for Atmel AES hw accelerator"
|
||||
- depends on ARCH_AT91 || COMPILE_TEST
|
||||
+ depends on ARCH_MICROCHIP || COMPILE_TEST
|
||||
select CRYPTO_AES
|
||||
select CRYPTO_AEAD
|
||||
select CRYPTO_SKCIPHER
|
||||
@ -0,0 +1,135 @@
|
||||
From 7b27e8e600e75b493c97a3fd5b764064fa61dd91 Mon Sep 17 00:00:00 2001
|
||||
From: Daniel Machon <daniel.machon@microchip.com>
|
||||
Date: Fri, 4 Oct 2024 15:19:27 +0200
|
||||
Subject: [PATCH 29/82] net: sparx5: add support for private match data
|
||||
|
||||
In preparation for lan969x, add support for private match data. This
|
||||
will be needed for abstracting away differences between the Sparx5 and
|
||||
lan969x platforms. We initially add values for: iomap, iomap size and
|
||||
ioranges. Update the use of these throughout.
|
||||
|
||||
Reviewed-by: Steen Hegelund <Steen.Hegelund@microchip.com>
|
||||
Reviewed-by: Jacob Keller <jacob.e.keller@intel.com>
|
||||
Signed-off-by: Daniel Machon <daniel.machon@microchip.com>
|
||||
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
|
||||
---
|
||||
.../ethernet/microchip/sparx5/sparx5_main.c | 36 +++++++++++--------
|
||||
.../ethernet/microchip/sparx5/sparx5_main.h | 13 +++++++
|
||||
2 files changed, 34 insertions(+), 15 deletions(-)
|
||||
|
||||
--- a/drivers/net/ethernet/microchip/sparx5/sparx5_main.c
|
||||
+++ b/drivers/net/ethernet/microchip/sparx5/sparx5_main.c
|
||||
@@ -45,12 +45,6 @@ struct sparx5_ram_config {
|
||||
u32 init_val;
|
||||
};
|
||||
|
||||
-struct sparx5_main_io_resource {
|
||||
- enum sparx5_target id;
|
||||
- phys_addr_t offset;
|
||||
- int range;
|
||||
-};
|
||||
-
|
||||
static const struct sparx5_main_io_resource sparx5_main_iomap[] = {
|
||||
{ TARGET_CPU, 0, 0 }, /* 0x600000000 */
|
||||
{ TARGET_FDMA, 0x80000, 0 }, /* 0x600080000 */
|
||||
@@ -216,21 +210,24 @@ static const struct sparx5_main_io_resou
|
||||
|
||||
static int sparx5_create_targets(struct sparx5 *sparx5)
|
||||
{
|
||||
+ const struct sparx5_main_io_resource *iomap = sparx5->data->iomap;
|
||||
+ int iomap_size = sparx5->data->iomap_size;
|
||||
+ int ioranges = sparx5->data->ioranges;
|
||||
struct resource *iores[IO_RANGES];
|
||||
void __iomem *iomem[IO_RANGES];
|
||||
void __iomem *begin[IO_RANGES];
|
||||
int range_id[IO_RANGES];
|
||||
int idx, jdx;
|
||||
|
||||
- for (idx = 0, jdx = 0; jdx < ARRAY_SIZE(sparx5_main_iomap); jdx++) {
|
||||
- const struct sparx5_main_io_resource *iomap = &sparx5_main_iomap[jdx];
|
||||
+ for (idx = 0, jdx = 0; jdx < iomap_size; jdx++) {
|
||||
+ const struct sparx5_main_io_resource *io = &iomap[jdx];
|
||||
|
||||
- if (idx == iomap->range) {
|
||||
+ if (idx == io->range) {
|
||||
range_id[idx] = jdx;
|
||||
idx++;
|
||||
}
|
||||
}
|
||||
- for (idx = 0; idx < IO_RANGES; idx++) {
|
||||
+ for (idx = 0; idx < ioranges; idx++) {
|
||||
iores[idx] = platform_get_resource(sparx5->pdev, IORESOURCE_MEM,
|
||||
idx);
|
||||
if (!iores[idx]) {
|
||||
@@ -245,12 +242,12 @@ static int sparx5_create_targets(struct
|
||||
iores[idx]->name);
|
||||
return -ENOMEM;
|
||||
}
|
||||
- begin[idx] = iomem[idx] - sparx5_main_iomap[range_id[idx]].offset;
|
||||
+ begin[idx] = iomem[idx] - iomap[range_id[idx]].offset;
|
||||
}
|
||||
- for (jdx = 0; jdx < ARRAY_SIZE(sparx5_main_iomap); jdx++) {
|
||||
- const struct sparx5_main_io_resource *iomap = &sparx5_main_iomap[jdx];
|
||||
+ for (jdx = 0; jdx < iomap_size; jdx++) {
|
||||
+ const struct sparx5_main_io_resource *io = &iomap[jdx];
|
||||
|
||||
- sparx5->regs[iomap->id] = begin[iomap->range] + iomap->offset;
|
||||
+ sparx5->regs[io->id] = begin[io->range] + io->offset;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@@ -758,6 +755,9 @@ static int mchp_sparx5_probe(struct plat
|
||||
sparx5->dev = &pdev->dev;
|
||||
spin_lock_init(&sparx5->tx_lock);
|
||||
|
||||
+ sparx5->data = device_get_match_data(sparx5->dev);
|
||||
+ if (!sparx5->data)
|
||||
+ return -EINVAL;
|
||||
/* Do switch core reset if available */
|
||||
reset = devm_reset_control_get_optional_shared(&pdev->dev, "switch");
|
||||
if (IS_ERR(reset))
|
||||
@@ -936,8 +936,14 @@ static void mchp_sparx5_remove(struct pl
|
||||
destroy_workqueue(sparx5->mact_queue);
|
||||
}
|
||||
|
||||
+static const struct sparx5_match_data sparx5_desc = {
|
||||
+ .iomap = sparx5_main_iomap,
|
||||
+ .iomap_size = ARRAY_SIZE(sparx5_main_iomap),
|
||||
+ .ioranges = 3,
|
||||
+};
|
||||
+
|
||||
static const struct of_device_id mchp_sparx5_match[] = {
|
||||
- { .compatible = "microchip,sparx5-switch" },
|
||||
+ { .compatible = "microchip,sparx5-switch", .data = &sparx5_desc },
|
||||
{ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, mchp_sparx5_match);
|
||||
--- a/drivers/net/ethernet/microchip/sparx5/sparx5_main.h
|
||||
+++ b/drivers/net/ethernet/microchip/sparx5/sparx5_main.h
|
||||
@@ -226,6 +226,18 @@ struct sparx5_mall_entry {
|
||||
#define SPARX5_SKB_CB(skb) \
|
||||
((struct sparx5_skb_cb *)((skb)->cb))
|
||||
|
||||
+struct sparx5_main_io_resource {
|
||||
+ enum sparx5_target id;
|
||||
+ phys_addr_t offset;
|
||||
+ int range;
|
||||
+};
|
||||
+
|
||||
+struct sparx5_match_data {
|
||||
+ const struct sparx5_main_io_resource *iomap;
|
||||
+ int ioranges;
|
||||
+ int iomap_size;
|
||||
+};
|
||||
+
|
||||
struct sparx5 {
|
||||
struct platform_device *pdev;
|
||||
struct device *dev;
|
||||
@@ -293,6 +305,7 @@ struct sparx5 {
|
||||
struct list_head mall_entries;
|
||||
/* Common root for debugfs */
|
||||
struct dentry *debugfs_root;
|
||||
+ const struct sparx5_match_data *data;
|
||||
};
|
||||
|
||||
/* sparx5_switchdev.c */
|
||||
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,36 @@
|
||||
From 9f4b9996e892cd721bf1f6664c3ba95a7592924c Mon Sep 17 00:00:00 2001
|
||||
From: Daniel Machon <daniel.machon@microchip.com>
|
||||
Date: Fri, 4 Oct 2024 15:19:29 +0200
|
||||
Subject: [PATCH 31/82] net: sparx5: modify SPX5_PORTS_ALL macro
|
||||
|
||||
In preparation for lan969x, we need to define the SPX5_PORTS_ALL macro
|
||||
as 70 (65 front ports + 5 internal ports). This is required as the
|
||||
SPX5_PORT_CPU will be redefined as an offset to the number of front
|
||||
ports, in a subsequent patch.
|
||||
|
||||
Reviewed-by: Steen Hegelund <Steen.Hegelund@microchip.com>
|
||||
Reviewed-by: Jacob Keller <jacob.e.keller@intel.com>
|
||||
Signed-off-by: Daniel Machon <daniel.machon@microchip.com>
|
||||
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
|
||||
---
|
||||
drivers/net/ethernet/microchip/sparx5/sparx5_main.h | 3 ++-
|
||||
1 file changed, 2 insertions(+), 1 deletion(-)
|
||||
|
||||
--- a/drivers/net/ethernet/microchip/sparx5/sparx5_main.h
|
||||
+++ b/drivers/net/ethernet/microchip/sparx5/sparx5_main.h
|
||||
@@ -52,13 +52,14 @@ enum sparx5_vlan_port_type {
|
||||
};
|
||||
|
||||
#define SPX5_PORTS 65
|
||||
+#define SPX5_PORTS_ALL 70 /* Total number of ports */
|
||||
+
|
||||
#define SPX5_PORT_CPU (SPX5_PORTS) /* Next port is CPU port */
|
||||
#define SPX5_PORT_CPU_0 (SPX5_PORT_CPU + 0) /* CPU Port 65 */
|
||||
#define SPX5_PORT_CPU_1 (SPX5_PORT_CPU + 1) /* CPU Port 66 */
|
||||
#define SPX5_PORT_VD0 (SPX5_PORT_CPU + 2) /* VD0/Port 67 used for IPMC */
|
||||
#define SPX5_PORT_VD1 (SPX5_PORT_CPU + 3) /* VD1/Port 68 used for AFI/OAM */
|
||||
#define SPX5_PORT_VD2 (SPX5_PORT_CPU + 4) /* VD2/Port 69 used for IPinIP*/
|
||||
-#define SPX5_PORTS_ALL (SPX5_PORT_CPU + 5) /* Total number of ports */
|
||||
|
||||
#define PGID_BASE SPX5_PORTS /* Starts after port PGIDs */
|
||||
#define PGID_UC_FLOOD (PGID_BASE + 0)
|
||||
@ -0,0 +1,355 @@
|
||||
From fc875dc858249c8c2c2eac758c3f89b3a7719f74 Mon Sep 17 00:00:00 2001
|
||||
From: Daniel Machon <daniel.machon@microchip.com>
|
||||
Date: Fri, 4 Oct 2024 15:19:30 +0200
|
||||
Subject: [PATCH 32/82] net: sparx5: add *sparx5 argument to a few functions
|
||||
|
||||
The *sparx5 context pointer is required in functions that need to access
|
||||
platform constants (which will be added in a subsequent patch). Prepare
|
||||
for this by updating the prototype and use of such functions.
|
||||
|
||||
Reviewed-by: Steen Hegelund <Steen.Hegelund@microchip.com>
|
||||
Reviewed-by: Jacob Keller <jacob.e.keller@intel.com>
|
||||
Signed-off-by: Daniel Machon <daniel.machon@microchip.com>
|
||||
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
|
||||
---
|
||||
.../microchip/sparx5/sparx5_ethtool.c | 24 ++++++++--------
|
||||
.../ethernet/microchip/sparx5/sparx5_main.h | 2 +-
|
||||
.../ethernet/microchip/sparx5/sparx5_netdev.c | 2 +-
|
||||
.../ethernet/microchip/sparx5/sparx5_packet.c | 2 +-
|
||||
.../ethernet/microchip/sparx5/sparx5_port.c | 28 +++++++++----------
|
||||
.../ethernet/microchip/sparx5/sparx5_port.h | 6 ++--
|
||||
.../ethernet/microchip/sparx5/sparx5_psfp.c | 24 ++++++++--------
|
||||
.../net/ethernet/microchip/sparx5/sparx5_tc.c | 8 +++---
|
||||
8 files changed, 48 insertions(+), 48 deletions(-)
|
||||
|
||||
--- a/drivers/net/ethernet/microchip/sparx5/sparx5_ethtool.c
|
||||
+++ b/drivers/net/ethernet/microchip/sparx5/sparx5_ethtool.c
|
||||
@@ -505,8 +505,8 @@ static void sparx5_get_dev_misc_stats(u6
|
||||
static void sparx5_get_device_stats(struct sparx5 *sparx5, int portno)
|
||||
{
|
||||
u64 *portstats = &sparx5->stats[portno * sparx5->num_stats];
|
||||
- u32 tinst = sparx5_port_dev_index(portno);
|
||||
- u32 dev = sparx5_to_high_dev(portno);
|
||||
+ u32 tinst = sparx5_port_dev_index(sparx5, portno);
|
||||
+ u32 dev = sparx5_to_high_dev(sparx5, portno);
|
||||
void __iomem *inst;
|
||||
|
||||
inst = spx5_inst_get(sparx5, dev, tinst);
|
||||
@@ -819,8 +819,8 @@ static void sparx5_get_eth_phy_stats(str
|
||||
|
||||
portstats = &sparx5->stats[portno * sparx5->num_stats];
|
||||
if (sparx5_is_baser(port->conf.portmode)) {
|
||||
- u32 tinst = sparx5_port_dev_index(portno);
|
||||
- u32 dev = sparx5_to_high_dev(portno);
|
||||
+ u32 tinst = sparx5_port_dev_index(sparx5, portno);
|
||||
+ u32 dev = sparx5_to_high_dev(sparx5, portno);
|
||||
|
||||
inst = spx5_inst_get(sparx5, dev, tinst);
|
||||
sparx5_get_dev_phy_stats(portstats, inst, tinst);
|
||||
@@ -844,8 +844,8 @@ static void sparx5_get_eth_mac_stats(str
|
||||
|
||||
portstats = &sparx5->stats[portno * sparx5->num_stats];
|
||||
if (sparx5_is_baser(port->conf.portmode)) {
|
||||
- u32 tinst = sparx5_port_dev_index(portno);
|
||||
- u32 dev = sparx5_to_high_dev(portno);
|
||||
+ u32 tinst = sparx5_port_dev_index(sparx5, portno);
|
||||
+ u32 dev = sparx5_to_high_dev(sparx5, portno);
|
||||
|
||||
inst = spx5_inst_get(sparx5, dev, tinst);
|
||||
sparx5_get_dev_mac_stats(portstats, inst, tinst);
|
||||
@@ -912,8 +912,8 @@ static void sparx5_get_eth_mac_ctrl_stat
|
||||
|
||||
portstats = &sparx5->stats[portno * sparx5->num_stats];
|
||||
if (sparx5_is_baser(port->conf.portmode)) {
|
||||
- u32 tinst = sparx5_port_dev_index(portno);
|
||||
- u32 dev = sparx5_to_high_dev(portno);
|
||||
+ u32 tinst = sparx5_port_dev_index(sparx5, portno);
|
||||
+ u32 dev = sparx5_to_high_dev(sparx5, portno);
|
||||
|
||||
inst = spx5_inst_get(sparx5, dev, tinst);
|
||||
sparx5_get_dev_mac_ctrl_stats(portstats, inst, tinst);
|
||||
@@ -944,8 +944,8 @@ static void sparx5_get_eth_rmon_stats(st
|
||||
|
||||
portstats = &sparx5->stats[portno * sparx5->num_stats];
|
||||
if (sparx5_is_baser(port->conf.portmode)) {
|
||||
- u32 tinst = sparx5_port_dev_index(portno);
|
||||
- u32 dev = sparx5_to_high_dev(portno);
|
||||
+ u32 tinst = sparx5_port_dev_index(sparx5, portno);
|
||||
+ u32 dev = sparx5_to_high_dev(sparx5, portno);
|
||||
|
||||
inst = spx5_inst_get(sparx5, dev, tinst);
|
||||
sparx5_get_dev_rmon_stats(portstats, inst, tinst);
|
||||
@@ -1027,8 +1027,8 @@ static void sparx5_get_sset_data(struct
|
||||
|
||||
portstats = &sparx5->stats[portno * sparx5->num_stats];
|
||||
if (sparx5_is_baser(port->conf.portmode)) {
|
||||
- u32 tinst = sparx5_port_dev_index(portno);
|
||||
- u32 dev = sparx5_to_high_dev(portno);
|
||||
+ u32 tinst = sparx5_port_dev_index(sparx5, portno);
|
||||
+ u32 dev = sparx5_to_high_dev(sparx5, portno);
|
||||
|
||||
inst = spx5_inst_get(sparx5, dev, tinst);
|
||||
sparx5_get_dev_misc_stats(portstats, inst, tinst);
|
||||
--- a/drivers/net/ethernet/microchip/sparx5/sparx5_main.h
|
||||
+++ b/drivers/net/ethernet/microchip/sparx5/sparx5_main.h
|
||||
@@ -401,7 +401,7 @@ void sparx5_set_port_ifh_timestamp(void
|
||||
void sparx5_set_port_ifh_rew_op(void *ifh_hdr, u32 rew_op);
|
||||
void sparx5_set_port_ifh_pdu_type(void *ifh_hdr, u32 pdu_type);
|
||||
void sparx5_set_port_ifh_pdu_w16_offset(void *ifh_hdr, u32 pdu_w16_offset);
|
||||
-void sparx5_set_port_ifh(void *ifh_hdr, u16 portno);
|
||||
+void sparx5_set_port_ifh(struct sparx5 *sparx5, void *ifh_hdr, u16 portno);
|
||||
bool sparx5_netdevice_check(const struct net_device *dev);
|
||||
struct net_device *sparx5_create_netdev(struct sparx5 *sparx5, u32 portno);
|
||||
int sparx5_register_netdevs(struct sparx5 *sparx5);
|
||||
--- a/drivers/net/ethernet/microchip/sparx5/sparx5_netdev.c
|
||||
+++ b/drivers/net/ethernet/microchip/sparx5/sparx5_netdev.c
|
||||
@@ -55,7 +55,7 @@ static void __ifh_encode_bitfield(void *
|
||||
ifh_hdr[byte - 5] |= (u8)((encode & 0xFF0000000000) >> 40);
|
||||
}
|
||||
|
||||
-void sparx5_set_port_ifh(void *ifh_hdr, u16 portno)
|
||||
+void sparx5_set_port_ifh(struct sparx5 *sparx5, void *ifh_hdr, u16 portno)
|
||||
{
|
||||
/* VSTAX.RSV = 1. MSBit must be 1 */
|
||||
ifh_encode_bitfield(ifh_hdr, 1, VSTAX + 79, 1);
|
||||
--- a/drivers/net/ethernet/microchip/sparx5/sparx5_packet.c
|
||||
+++ b/drivers/net/ethernet/microchip/sparx5/sparx5_packet.c
|
||||
@@ -235,7 +235,7 @@ netdev_tx_t sparx5_port_xmit_impl(struct
|
||||
netdev_tx_t ret;
|
||||
|
||||
memset(ifh, 0, IFH_LEN * 4);
|
||||
- sparx5_set_port_ifh(ifh, port->portno);
|
||||
+ sparx5_set_port_ifh(sparx5, ifh, port->portno);
|
||||
|
||||
if (sparx5->ptp && skb_shinfo(skb)->tx_flags & SKBTX_HW_TSTAMP) {
|
||||
if (sparx5_ptp_txtstamp_request(port, skb) < 0)
|
||||
--- a/drivers/net/ethernet/microchip/sparx5/sparx5_port.c
|
||||
+++ b/drivers/net/ethernet/microchip/sparx5/sparx5_port.c
|
||||
@@ -132,8 +132,8 @@ static int sparx5_get_sfi_status(struct
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
- dev = sparx5_to_high_dev(portno);
|
||||
- tinst = sparx5_port_dev_index(portno);
|
||||
+ dev = sparx5_to_high_dev(sparx5, portno);
|
||||
+ tinst = sparx5_port_dev_index(sparx5, portno);
|
||||
inst = spx5_inst_get(sparx5, dev, tinst);
|
||||
|
||||
value = spx5_inst_rd(inst, DEV10G_MAC_TX_MONITOR_STICKY(0));
|
||||
@@ -316,9 +316,9 @@ static int sparx5_port_flush_poll(struct
|
||||
static int sparx5_port_disable(struct sparx5 *sparx5, struct sparx5_port *port, bool high_spd_dev)
|
||||
{
|
||||
u32 tinst = high_spd_dev ?
|
||||
- sparx5_port_dev_index(port->portno) : port->portno;
|
||||
+ sparx5_port_dev_index(sparx5, port->portno) : port->portno;
|
||||
u32 dev = high_spd_dev ?
|
||||
- sparx5_to_high_dev(port->portno) : TARGET_DEV2G5;
|
||||
+ sparx5_to_high_dev(sparx5, port->portno) : TARGET_DEV2G5;
|
||||
void __iomem *devinst = spx5_inst_get(sparx5, dev, tinst);
|
||||
u32 spd = port->conf.speed;
|
||||
u32 spd_prm;
|
||||
@@ -427,7 +427,7 @@ static int sparx5_port_disable(struct sp
|
||||
HSCH_FLUSH_CTRL);
|
||||
|
||||
if (high_spd_dev) {
|
||||
- u32 pcs = sparx5_to_pcs_dev(port->portno);
|
||||
+ u32 pcs = sparx5_to_pcs_dev(sparx5, port->portno);
|
||||
void __iomem *pcsinst = spx5_inst_get(sparx5, pcs, tinst);
|
||||
|
||||
/* 12: Disable 5G/10G/25 BaseR PCS */
|
||||
@@ -558,8 +558,8 @@ static int sparx5_port_max_tags_set(stru
|
||||
bool dtag = max_tags == SPX5_PORT_MAX_TAGS_TWO;
|
||||
enum sparx5_vlan_port_type vlan_type = port->vlan_type;
|
||||
bool dotag = max_tags != SPX5_PORT_MAX_TAGS_NONE;
|
||||
- u32 dev = sparx5_to_high_dev(port->portno);
|
||||
- u32 tinst = sparx5_port_dev_index(port->portno);
|
||||
+ u32 dev = sparx5_to_high_dev(sparx5, port->portno);
|
||||
+ u32 tinst = sparx5_port_dev_index(sparx5, port->portno);
|
||||
void __iomem *inst = spx5_inst_get(sparx5, dev, tinst);
|
||||
u32 etype;
|
||||
|
||||
@@ -789,9 +789,9 @@ static int sparx5_port_pcs_high_set(stru
|
||||
struct sparx5_port_config *conf)
|
||||
{
|
||||
u32 clk_spd = conf->portmode == PHY_INTERFACE_MODE_5GBASER ? 1 : 0;
|
||||
- u32 pix = sparx5_port_dev_index(port->portno);
|
||||
- u32 dev = sparx5_to_high_dev(port->portno);
|
||||
- u32 pcs = sparx5_to_pcs_dev(port->portno);
|
||||
+ u32 pix = sparx5_port_dev_index(sparx5, port->portno);
|
||||
+ u32 dev = sparx5_to_high_dev(sparx5, port->portno);
|
||||
+ u32 pcs = sparx5_to_pcs_dev(sparx5, port->portno);
|
||||
void __iomem *devinst;
|
||||
void __iomem *pcsinst;
|
||||
int err;
|
||||
@@ -843,7 +843,7 @@ static int sparx5_port_pcs_high_set(stru
|
||||
/* Switch between 1G/2500 and 5G/10G/25G devices */
|
||||
static void sparx5_dev_switch(struct sparx5 *sparx5, int port, bool hsd)
|
||||
{
|
||||
- int bt_indx = BIT(sparx5_port_dev_index(port));
|
||||
+ int bt_indx = BIT(sparx5_port_dev_index(sparx5, port));
|
||||
|
||||
if (sparx5_port_is_5g(port)) {
|
||||
spx5_rmw(hsd ? 0 : bt_indx,
|
||||
@@ -1016,9 +1016,9 @@ int sparx5_port_init(struct sparx5 *spar
|
||||
{
|
||||
u32 pause_start = sparx5_wm_enc(6 * (ETH_MAXLEN / SPX5_BUFFER_CELL_SZ));
|
||||
u32 atop = sparx5_wm_enc(20 * (ETH_MAXLEN / SPX5_BUFFER_CELL_SZ));
|
||||
- u32 devhigh = sparx5_to_high_dev(port->portno);
|
||||
- u32 pix = sparx5_port_dev_index(port->portno);
|
||||
- u32 pcs = sparx5_to_pcs_dev(port->portno);
|
||||
+ u32 devhigh = sparx5_to_high_dev(sparx5, port->portno);
|
||||
+ u32 pix = sparx5_port_dev_index(sparx5, port->portno);
|
||||
+ u32 pcs = sparx5_to_pcs_dev(sparx5, port->portno);
|
||||
bool sd_pol = port->signd_active_high;
|
||||
bool sd_sel = !port->signd_internal;
|
||||
bool sd_ena = port->signd_enable;
|
||||
--- a/drivers/net/ethernet/microchip/sparx5/sparx5_port.h
|
||||
+++ b/drivers/net/ethernet/microchip/sparx5/sparx5_port.h
|
||||
@@ -40,7 +40,7 @@ static inline bool sparx5_port_is_25g(in
|
||||
return portno >= 56 && portno <= 63;
|
||||
}
|
||||
|
||||
-static inline u32 sparx5_to_high_dev(int port)
|
||||
+static inline u32 sparx5_to_high_dev(struct sparx5 *sparx5, int port)
|
||||
{
|
||||
if (sparx5_port_is_5g(port))
|
||||
return TARGET_DEV5G;
|
||||
@@ -49,7 +49,7 @@ static inline u32 sparx5_to_high_dev(int
|
||||
return TARGET_DEV25G;
|
||||
}
|
||||
|
||||
-static inline u32 sparx5_to_pcs_dev(int port)
|
||||
+static inline u32 sparx5_to_pcs_dev(struct sparx5 *sparx5, int port)
|
||||
{
|
||||
if (sparx5_port_is_5g(port))
|
||||
return TARGET_PCS5G_BR;
|
||||
@@ -58,7 +58,7 @@ static inline u32 sparx5_to_pcs_dev(int
|
||||
return TARGET_PCS25G_BR;
|
||||
}
|
||||
|
||||
-static inline int sparx5_port_dev_index(int port)
|
||||
+static inline int sparx5_port_dev_index(struct sparx5 *sparx5, int port)
|
||||
{
|
||||
if (sparx5_port_is_2g5(port))
|
||||
return port;
|
||||
--- a/drivers/net/ethernet/microchip/sparx5/sparx5_psfp.c
|
||||
+++ b/drivers/net/ethernet/microchip/sparx5/sparx5_psfp.c
|
||||
@@ -20,34 +20,34 @@ static struct sparx5_pool_entry sparx5_p
|
||||
/* Pool of available stream filters */
|
||||
static struct sparx5_pool_entry sparx5_psfp_sf_pool[SPX5_PSFP_SF_CNT];
|
||||
|
||||
-static int sparx5_psfp_sf_get(u32 *id)
|
||||
+static int sparx5_psfp_sf_get(struct sparx5 *sparx5, u32 *id)
|
||||
{
|
||||
return sparx5_pool_get(sparx5_psfp_sf_pool, SPX5_PSFP_SF_CNT, id);
|
||||
}
|
||||
|
||||
-static int sparx5_psfp_sf_put(u32 id)
|
||||
+static int sparx5_psfp_sf_put(struct sparx5 *sparx5, u32 id)
|
||||
{
|
||||
return sparx5_pool_put(sparx5_psfp_sf_pool, SPX5_PSFP_SF_CNT, id);
|
||||
}
|
||||
|
||||
-static int sparx5_psfp_sg_get(u32 idx, u32 *id)
|
||||
+static int sparx5_psfp_sg_get(struct sparx5 *sparx5, u32 idx, u32 *id)
|
||||
{
|
||||
return sparx5_pool_get_with_idx(sparx5_psfp_sg_pool, SPX5_PSFP_SG_CNT,
|
||||
idx, id);
|
||||
}
|
||||
|
||||
-static int sparx5_psfp_sg_put(u32 id)
|
||||
+static int sparx5_psfp_sg_put(struct sparx5 *sparx5, u32 id)
|
||||
{
|
||||
return sparx5_pool_put(sparx5_psfp_sg_pool, SPX5_PSFP_SG_CNT, id);
|
||||
}
|
||||
|
||||
-static int sparx5_psfp_fm_get(u32 idx, u32 *id)
|
||||
+static int sparx5_psfp_fm_get(struct sparx5 *sparx5, u32 idx, u32 *id)
|
||||
{
|
||||
return sparx5_pool_get_with_idx(sparx5_psfp_fm_pool, SPX5_SDLB_CNT, idx,
|
||||
id);
|
||||
}
|
||||
|
||||
-static int sparx5_psfp_fm_put(u32 id)
|
||||
+static int sparx5_psfp_fm_put(struct sparx5 *sparx5, u32 id)
|
||||
{
|
||||
return sparx5_pool_put(sparx5_psfp_fm_pool, SPX5_SDLB_CNT, id);
|
||||
}
|
||||
@@ -205,7 +205,7 @@ int sparx5_psfp_sf_add(struct sparx5 *sp
|
||||
{
|
||||
int ret;
|
||||
|
||||
- ret = sparx5_psfp_sf_get(id);
|
||||
+ ret = sparx5_psfp_sf_get(sparx5, id);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
@@ -220,7 +220,7 @@ int sparx5_psfp_sf_del(struct sparx5 *sp
|
||||
|
||||
sparx5_psfp_sf_set(sparx5, id, &sf);
|
||||
|
||||
- return sparx5_psfp_sf_put(id);
|
||||
+ return sparx5_psfp_sf_put(sparx5, id);
|
||||
}
|
||||
|
||||
int sparx5_psfp_sg_add(struct sparx5 *sparx5, u32 uidx,
|
||||
@@ -229,7 +229,7 @@ int sparx5_psfp_sg_add(struct sparx5 *sp
|
||||
ktime_t basetime;
|
||||
int ret;
|
||||
|
||||
- ret = sparx5_psfp_sg_get(uidx, id);
|
||||
+ ret = sparx5_psfp_sg_get(sparx5, uidx, id);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
/* Was already in use, no need to reconfigure */
|
||||
@@ -253,7 +253,7 @@ int sparx5_psfp_sg_del(struct sparx5 *sp
|
||||
const struct sparx5_psfp_sg sg = { 0 };
|
||||
int ret;
|
||||
|
||||
- ret = sparx5_psfp_sg_put(id);
|
||||
+ ret = sparx5_psfp_sg_put(sparx5, id);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
/* Stream gate still in use ? */
|
||||
@@ -270,7 +270,7 @@ int sparx5_psfp_fm_add(struct sparx5 *sp
|
||||
int ret;
|
||||
|
||||
/* Get flow meter */
|
||||
- ret = sparx5_psfp_fm_get(uidx, &fm->pol.idx);
|
||||
+ ret = sparx5_psfp_fm_get(sparx5, uidx, &fm->pol.idx);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
/* Was already in use, no need to reconfigure */
|
||||
@@ -303,7 +303,7 @@ int sparx5_psfp_fm_del(struct sparx5 *sp
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
- ret = sparx5_psfp_fm_put(id);
|
||||
+ ret = sparx5_psfp_fm_put(sparx5, id);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
/* Do not reset flow-meter if still in use. */
|
||||
--- a/drivers/net/ethernet/microchip/sparx5/sparx5_tc.c
|
||||
+++ b/drivers/net/ethernet/microchip/sparx5/sparx5_tc.c
|
||||
@@ -60,8 +60,8 @@ static int sparx5_tc_setup_block(struct
|
||||
cb, ndev, ndev, false);
|
||||
}
|
||||
|
||||
-static void sparx5_tc_get_layer_and_idx(u32 parent, u32 portno, u32 *layer,
|
||||
- u32 *idx)
|
||||
+static void sparx5_tc_get_layer_and_idx(struct sparx5 *sparx5, u32 parent,
|
||||
+ u32 portno, u32 *layer, u32 *idx)
|
||||
{
|
||||
if (parent == TC_H_ROOT) {
|
||||
*layer = 2;
|
||||
@@ -90,8 +90,8 @@ static int sparx5_tc_setup_qdisc_tbf(str
|
||||
struct sparx5_port *port = netdev_priv(ndev);
|
||||
u32 layer, se_idx;
|
||||
|
||||
- sparx5_tc_get_layer_and_idx(qopt->parent, port->portno, &layer,
|
||||
- &se_idx);
|
||||
+ sparx5_tc_get_layer_and_idx(port->sparx5, qopt->parent, port->portno,
|
||||
+ &layer, &se_idx);
|
||||
|
||||
switch (qopt->command) {
|
||||
case TC_TBF_REPLACE:
|
||||
@ -0,0 +1,88 @@
|
||||
From e263a2c741eef417e769075e11d32318b8b2b8ab Mon Sep 17 00:00:00 2001
|
||||
From: Daniel Machon <daniel.machon@microchip.com>
|
||||
Date: Fri, 4 Oct 2024 15:19:31 +0200
|
||||
Subject: [PATCH 33/82] net: sparx5: add constants to match data
|
||||
|
||||
Add new struct sparx5_consts, containing all the chip constants that are
|
||||
known to be different for Sparx5 and lan969x.
|
||||
|
||||
Reviewed-by: Steen Hegelund <Steen.Hegelund@microchip.com>
|
||||
Signed-off-by: Daniel Machon <daniel.machon@microchip.com>
|
||||
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
|
||||
---
|
||||
.../ethernet/microchip/sparx5/sparx5_main.c | 21 +++++++++++++++++++
|
||||
.../ethernet/microchip/sparx5/sparx5_main.h | 21 +++++++++++++++++++
|
||||
2 files changed, 42 insertions(+)
|
||||
|
||||
--- a/drivers/net/ethernet/microchip/sparx5/sparx5_main.c
|
||||
+++ b/drivers/net/ethernet/microchip/sparx5/sparx5_main.c
|
||||
@@ -952,11 +952,32 @@ static const struct sparx5_regs sparx5_r
|
||||
.fsize = sparx5_fsize,
|
||||
};
|
||||
|
||||
+static const struct sparx5_consts sparx5_consts = {
|
||||
+ .n_ports = 65,
|
||||
+ .n_ports_all = 70,
|
||||
+ .n_hsch_l1_elems = 64,
|
||||
+ .n_hsch_queues = 8,
|
||||
+ .n_lb_groups = 10,
|
||||
+ .n_pgids = 2113, /* (2048 + n_ports) */
|
||||
+ .n_sio_clks = 3,
|
||||
+ .n_own_upsids = 3,
|
||||
+ .n_auto_cals = 7,
|
||||
+ .n_filters = 1024,
|
||||
+ .n_gates = 1024,
|
||||
+ .n_sdlbs = 4096,
|
||||
+ .n_dsm_cal_taxis = 8,
|
||||
+ .buf_size = 4194280,
|
||||
+ .qres_max_prio_idx = 630,
|
||||
+ .qres_max_colour_idx = 638,
|
||||
+ .tod_pin = 4,
|
||||
+};
|
||||
+
|
||||
static const struct sparx5_match_data sparx5_desc = {
|
||||
.iomap = sparx5_main_iomap,
|
||||
.iomap_size = ARRAY_SIZE(sparx5_main_iomap),
|
||||
.ioranges = 3,
|
||||
.regs = &sparx5_regs,
|
||||
+ .consts = &sparx5_consts,
|
||||
};
|
||||
|
||||
static const struct of_device_id mchp_sparx5_match[] = {
|
||||
--- a/drivers/net/ethernet/microchip/sparx5/sparx5_main.h
|
||||
+++ b/drivers/net/ethernet/microchip/sparx5/sparx5_main.h
|
||||
@@ -238,6 +238,26 @@ struct sparx5_regs {
|
||||
const unsigned int *fsize;
|
||||
};
|
||||
|
||||
+struct sparx5_consts {
|
||||
+ u32 n_ports; /* Number of front ports */
|
||||
+ u32 n_ports_all; /* Number of front ports + internal ports */
|
||||
+ u32 n_hsch_l1_elems; /* Number of HSCH layer 1 elements */
|
||||
+ u32 n_hsch_queues; /* Number of HSCH queues */
|
||||
+ u32 n_lb_groups; /* Number of leacky bucket groupd */
|
||||
+ u32 n_pgids; /* Number of PGID's */
|
||||
+ u32 n_sio_clks; /* Number of serial IO clocks */
|
||||
+ u32 n_own_upsids; /* Number of own UPSID's */
|
||||
+ u32 n_auto_cals; /* Number of auto calendars */
|
||||
+ u32 n_filters; /* Number of PSFP filters */
|
||||
+ u32 n_gates; /* Number of PSFP gates */
|
||||
+ u32 n_sdlbs; /* Number of service dual leaky buckets */
|
||||
+ u32 n_dsm_cal_taxis; /* Number of DSM calendar taxis */
|
||||
+ u32 buf_size; /* Amount of QLIM watermark memory */
|
||||
+ u32 qres_max_prio_idx; /* Maximum QRES prio index */
|
||||
+ u32 qres_max_colour_idx; /* Maximum QRES colour index */
|
||||
+ u32 tod_pin; /* PTP TOD pin */
|
||||
+};
|
||||
+
|
||||
struct sparx5_main_io_resource {
|
||||
enum sparx5_target id;
|
||||
phys_addr_t offset;
|
||||
@@ -246,6 +266,7 @@ struct sparx5_main_io_resource {
|
||||
|
||||
struct sparx5_match_data {
|
||||
const struct sparx5_regs *regs;
|
||||
+ const struct sparx5_consts *consts;
|
||||
const struct sparx5_main_io_resource *iomap;
|
||||
int ioranges;
|
||||
int iomap_size;
|
||||
@ -0,0 +1,600 @@
|
||||
From 27584455298c4d27246bfcb7ac6c570128648847 Mon Sep 17 00:00:00 2001
|
||||
From: Daniel Machon <daniel.machon@microchip.com>
|
||||
Date: Fri, 4 Oct 2024 15:19:32 +0200
|
||||
Subject: [PATCH 34/82] net: sparx5: use SPX5_CONST for constants which already
|
||||
have a symbol
|
||||
|
||||
Now that we have indentified all the chip constants, update the use of
|
||||
them where a symbol is already defined for the constant.
|
||||
|
||||
Reviewed-by: Steen Hegelund <Steen.Hegelund@microchip.com>
|
||||
Signed-off-by: Daniel Machon <daniel.machon@microchip.com>
|
||||
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
|
||||
---
|
||||
.../microchip/sparx5/sparx5_calendar.c | 13 +++---
|
||||
.../ethernet/microchip/sparx5/sparx5_dcb.c | 5 ++-
|
||||
.../microchip/sparx5/sparx5_ethtool.c | 8 ++--
|
||||
.../ethernet/microchip/sparx5/sparx5_fdma.c | 6 ++-
|
||||
.../microchip/sparx5/sparx5_mactable.c | 7 +--
|
||||
.../ethernet/microchip/sparx5/sparx5_main.c | 21 +++++----
|
||||
.../ethernet/microchip/sparx5/sparx5_netdev.c | 7 ++-
|
||||
.../ethernet/microchip/sparx5/sparx5_packet.c | 2 +-
|
||||
.../ethernet/microchip/sparx5/sparx5_pgid.c | 6 +--
|
||||
.../ethernet/microchip/sparx5/sparx5_psfp.c | 22 ++++++----
|
||||
.../ethernet/microchip/sparx5/sparx5_ptp.c | 44 ++++++++++++-------
|
||||
.../ethernet/microchip/sparx5/sparx5_sdlb.c | 4 +-
|
||||
.../microchip/sparx5/sparx5_switchdev.c | 2 +-
|
||||
.../microchip/sparx5/sparx5_tc_flower.c | 4 +-
|
||||
.../ethernet/microchip/sparx5/sparx5_vlan.c | 2 +-
|
||||
15 files changed, 90 insertions(+), 63 deletions(-)
|
||||
|
||||
--- a/drivers/net/ethernet/microchip/sparx5/sparx5_calendar.c
|
||||
+++ b/drivers/net/ethernet/microchip/sparx5/sparx5_calendar.c
|
||||
@@ -131,7 +131,7 @@ static enum sparx5_cal_bw sparx5_get_por
|
||||
{
|
||||
struct sparx5_port *port;
|
||||
|
||||
- if (portno >= SPX5_PORTS) {
|
||||
+ if (portno >= sparx5->data->consts->n_ports) {
|
||||
/* Internal ports */
|
||||
if (portno == SPX5_PORT_CPU_0 || portno == SPX5_PORT_CPU_1) {
|
||||
/* Equals 1.25G */
|
||||
@@ -159,6 +159,7 @@ static enum sparx5_cal_bw sparx5_get_por
|
||||
/* Auto configure the QSYS calendar based on port configuration */
|
||||
int sparx5_config_auto_calendar(struct sparx5 *sparx5)
|
||||
{
|
||||
+ const struct sparx5_consts *consts = sparx5->data->consts;
|
||||
u32 cal[7], value, idx, portno;
|
||||
u32 max_core_bw;
|
||||
u32 total_bw = 0, used_port_bw = 0;
|
||||
@@ -174,7 +175,7 @@ int sparx5_config_auto_calendar(struct s
|
||||
}
|
||||
|
||||
/* Setup the calendar with the bandwidth to each port */
|
||||
- for (portno = 0; portno < SPX5_PORTS_ALL; portno++) {
|
||||
+ for (portno = 0; portno < consts->n_ports_all; portno++) {
|
||||
u64 reg, offset, this_bw;
|
||||
|
||||
spd = sparx5_get_port_cal_speed(sparx5, portno);
|
||||
@@ -182,7 +183,7 @@ int sparx5_config_auto_calendar(struct s
|
||||
continue;
|
||||
|
||||
this_bw = sparx5_cal_speed_to_value(spd);
|
||||
- if (portno < SPX5_PORTS)
|
||||
+ if (portno < consts->n_ports)
|
||||
used_port_bw += this_bw;
|
||||
else
|
||||
/* Internal ports are granted half the value */
|
||||
@@ -213,7 +214,7 @@ int sparx5_config_auto_calendar(struct s
|
||||
sparx5, QSYS_CAL_CTRL);
|
||||
|
||||
/* Assign port bandwidth to auto calendar */
|
||||
- for (idx = 0; idx < ARRAY_SIZE(cal); idx++)
|
||||
+ for (idx = 0; idx < consts->n_auto_cals; idx++)
|
||||
spx5_wr(cal[idx], sparx5, QSYS_CAL_AUTO(idx));
|
||||
|
||||
/* Increase grant rate of all ports to account for
|
||||
@@ -304,7 +305,7 @@ static int sparx5_dsm_calendar_calc(stru
|
||||
for (idx = 0; idx < SPX5_DSM_CAL_MAX_DEVS_PER_TAXI; idx++) {
|
||||
u32 portno = data->taxi_ports[idx];
|
||||
|
||||
- if (portno < SPX5_TAXI_PORT_MAX) {
|
||||
+ if (portno < sparx5->data->consts->n_ports_all) {
|
||||
data->taxi_speeds[idx] = sparx5_cal_speed_to_value
|
||||
(sparx5_get_port_cal_speed(sparx5, portno));
|
||||
} else {
|
||||
@@ -573,7 +574,7 @@ int sparx5_config_dsm_calendar(struct sp
|
||||
if (!data)
|
||||
return -ENOMEM;
|
||||
|
||||
- for (taxi = 0; taxi < SPX5_DSM_CAL_TAXIS; ++taxi) {
|
||||
+ for (taxi = 0; taxi < sparx5->data->consts->n_dsm_cal_taxis; ++taxi) {
|
||||
err = sparx5_dsm_calendar_calc(sparx5, taxi, data);
|
||||
if (err) {
|
||||
dev_err(sparx5->dev, "DSM calendar calculation failed\n");
|
||||
--- a/drivers/net/ethernet/microchip/sparx5/sparx5_dcb.c
|
||||
+++ b/drivers/net/ethernet/microchip/sparx5/sparx5_dcb.c
|
||||
@@ -234,10 +234,11 @@ static int sparx5_dcb_ieee_dscp_setdel(s
|
||||
struct dcb_app *))
|
||||
{
|
||||
struct sparx5_port *port = netdev_priv(dev);
|
||||
+ struct sparx5 *sparx5 = port->sparx5;
|
||||
struct sparx5_port *port_itr;
|
||||
int err, i;
|
||||
|
||||
- for (i = 0; i < SPX5_PORTS; i++) {
|
||||
+ for (i = 0; i < sparx5->data->consts->n_ports; i++) {
|
||||
port_itr = port->sparx5->ports[i];
|
||||
if (!port_itr)
|
||||
continue;
|
||||
@@ -386,7 +387,7 @@ int sparx5_dcb_init(struct sparx5 *sparx
|
||||
struct sparx5_port *port;
|
||||
int i;
|
||||
|
||||
- for (i = 0; i < SPX5_PORTS; i++) {
|
||||
+ for (i = 0; i < sparx5->data->consts->n_ports; i++) {
|
||||
port = sparx5->ports[i];
|
||||
if (!port)
|
||||
continue;
|
||||
--- a/drivers/net/ethernet/microchip/sparx5/sparx5_ethtool.c
|
||||
+++ b/drivers/net/ethernet/microchip/sparx5/sparx5_ethtool.c
|
||||
@@ -1122,7 +1122,7 @@ static void sparx5_update_stats(struct s
|
||||
{
|
||||
int idx;
|
||||
|
||||
- for (idx = 0; idx < SPX5_PORTS; idx++)
|
||||
+ for (idx = 0; idx < sparx5->data->consts->n_ports; idx++)
|
||||
if (sparx5->ports[idx])
|
||||
sparx5_update_port_stats(sparx5, idx);
|
||||
}
|
||||
@@ -1228,6 +1228,7 @@ const struct ethtool_ops sparx5_ethtool_
|
||||
|
||||
int sparx_stats_init(struct sparx5 *sparx5)
|
||||
{
|
||||
+ const struct sparx5_consts *consts = sparx5->data->consts;
|
||||
char queue_name[32];
|
||||
int portno;
|
||||
|
||||
@@ -1235,14 +1236,15 @@ int sparx_stats_init(struct sparx5 *spar
|
||||
sparx5->num_stats = spx5_stats_count;
|
||||
sparx5->num_ethtool_stats = ARRAY_SIZE(sparx5_stats_layout);
|
||||
sparx5->stats = devm_kcalloc(sparx5->dev,
|
||||
- SPX5_PORTS_ALL * sparx5->num_stats,
|
||||
+ consts->n_ports_all *
|
||||
+ sparx5->num_stats,
|
||||
sizeof(u64), GFP_KERNEL);
|
||||
if (!sparx5->stats)
|
||||
return -ENOMEM;
|
||||
|
||||
mutex_init(&sparx5->queue_stats_lock);
|
||||
sparx5_config_stats(sparx5);
|
||||
- for (portno = 0; portno < SPX5_PORTS; portno++)
|
||||
+ for (portno = 0; portno < consts->n_ports; portno++)
|
||||
if (sparx5->ports[portno])
|
||||
sparx5_config_port_stats(sparx5, portno);
|
||||
|
||||
--- a/drivers/net/ethernet/microchip/sparx5/sparx5_fdma.c
|
||||
+++ b/drivers/net/ethernet/microchip/sparx5/sparx5_fdma.c
|
||||
@@ -156,7 +156,9 @@ static bool sparx5_fdma_rx_get_frame(str
|
||||
/* Now do the normal processing of the skb */
|
||||
sparx5_ifh_parse((u32 *)skb->data, &fi);
|
||||
/* Map to port netdev */
|
||||
- port = fi.src_port < SPX5_PORTS ? sparx5->ports[fi.src_port] : NULL;
|
||||
+ port = fi.src_port < sparx5->data->consts->n_ports ?
|
||||
+ sparx5->ports[fi.src_port] :
|
||||
+ NULL;
|
||||
if (!port || !port->ndev) {
|
||||
dev_err(sparx5->dev, "Data on inactive port %d\n", fi.src_port);
|
||||
sparx5_xtr_flush(sparx5, XTR_QUEUE);
|
||||
@@ -296,7 +298,7 @@ static void sparx5_fdma_rx_init(struct s
|
||||
fdma->ops.dataptr_cb = &sparx5_fdma_rx_dataptr_cb;
|
||||
fdma->ops.nextptr_cb = &fdma_nextptr_cb;
|
||||
/* Fetch a netdev for SKB and NAPI use, any will do */
|
||||
- for (idx = 0; idx < SPX5_PORTS; ++idx) {
|
||||
+ for (idx = 0; idx < sparx5->data->consts->n_ports; ++idx) {
|
||||
struct sparx5_port *port = sparx5->ports[idx];
|
||||
|
||||
if (port && port->ndev) {
|
||||
--- a/drivers/net/ethernet/microchip/sparx5/sparx5_mactable.c
|
||||
+++ b/drivers/net/ethernet/microchip/sparx5/sparx5_mactable.c
|
||||
@@ -80,15 +80,16 @@ static void sparx5_mact_select(struct sp
|
||||
int sparx5_mact_learn(struct sparx5 *sparx5, int pgid,
|
||||
const unsigned char mac[ETH_ALEN], u16 vid)
|
||||
{
|
||||
+ const struct sparx5_consts *consts = sparx5->data->consts;
|
||||
int addr, type, ret;
|
||||
|
||||
- if (pgid < SPX5_PORTS) {
|
||||
+ if (pgid < consts->n_ports) {
|
||||
type = MAC_ENTRY_ADDR_TYPE_UPSID_PN;
|
||||
addr = pgid % 32;
|
||||
addr += (pgid / 32) << 5; /* Add upsid */
|
||||
} else {
|
||||
type = MAC_ENTRY_ADDR_TYPE_MC_IDX;
|
||||
- addr = pgid - SPX5_PORTS;
|
||||
+ addr = pgid - consts->n_ports;
|
||||
}
|
||||
|
||||
mutex_lock(&sparx5->lock);
|
||||
@@ -371,7 +372,7 @@ static void sparx5_mact_handle_entry(str
|
||||
return;
|
||||
|
||||
port = LRN_MAC_ACCESS_CFG_2_MAC_ENTRY_ADDR_GET(cfg2);
|
||||
- if (port >= SPX5_PORTS)
|
||||
+ if (port >= sparx5->data->consts->n_ports)
|
||||
return;
|
||||
|
||||
if (!test_bit(port, sparx5->bridge_mask))
|
||||
--- a/drivers/net/ethernet/microchip/sparx5/sparx5_main.c
|
||||
+++ b/drivers/net/ethernet/microchip/sparx5/sparx5_main.c
|
||||
@@ -31,8 +31,6 @@
|
||||
|
||||
const struct sparx5_regs *regs;
|
||||
|
||||
-#define QLIM_WM(fraction) \
|
||||
- ((SPX5_BUFFER_MEMORY / SPX5_BUFFER_CELL_SZ - 100) * (fraction) / 100)
|
||||
#define IO_RANGES 3
|
||||
|
||||
struct initial_port_config {
|
||||
@@ -544,6 +542,12 @@ static int sparx5_init_coreclock(struct
|
||||
return 0;
|
||||
}
|
||||
|
||||
+static u32 qlim_wm(struct sparx5 *sparx5, int fraction)
|
||||
+{
|
||||
+ return (sparx5->data->consts->buf_size / SPX5_BUFFER_CELL_SZ - 100) *
|
||||
+ fraction / 100;
|
||||
+}
|
||||
+
|
||||
static int sparx5_qlim_set(struct sparx5 *sparx5)
|
||||
{
|
||||
u32 res, dp, prio;
|
||||
@@ -559,10 +563,10 @@ static int sparx5_qlim_set(struct sparx5
|
||||
}
|
||||
|
||||
/* Set 80,90,95,100% of memory size for top watermarks */
|
||||
- spx5_wr(QLIM_WM(80), sparx5, XQS_QLIMIT_SHR_QLIM_CFG(0));
|
||||
- spx5_wr(QLIM_WM(90), sparx5, XQS_QLIMIT_SHR_CTOP_CFG(0));
|
||||
- spx5_wr(QLIM_WM(95), sparx5, XQS_QLIMIT_SHR_ATOP_CFG(0));
|
||||
- spx5_wr(QLIM_WM(100), sparx5, XQS_QLIMIT_SHR_TOP_CFG(0));
|
||||
+ spx5_wr(qlim_wm(sparx5, 80), sparx5, XQS_QLIMIT_SHR_QLIM_CFG(0));
|
||||
+ spx5_wr(qlim_wm(sparx5, 90), sparx5, XQS_QLIMIT_SHR_CTOP_CFG(0));
|
||||
+ spx5_wr(qlim_wm(sparx5, 95), sparx5, XQS_QLIMIT_SHR_ATOP_CFG(0));
|
||||
+ spx5_wr(qlim_wm(sparx5, 100), sparx5, XQS_QLIMIT_SHR_TOP_CFG(0));
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -584,7 +588,7 @@ static void sparx5_board_init(struct spa
|
||||
GCB_HW_SGPIO_SD_CFG);
|
||||
|
||||
/* Refer to LOS SGPIO */
|
||||
- for (idx = 0; idx < SPX5_PORTS; idx++)
|
||||
+ for (idx = 0; idx < sparx5->data->consts->n_ports; idx++)
|
||||
if (sparx5->ports[idx])
|
||||
if (sparx5->ports[idx]->conf.sd_sgpio != ~0)
|
||||
spx5_wr(sparx5->ports[idx]->conf.sd_sgpio,
|
||||
@@ -595,6 +599,7 @@ static void sparx5_board_init(struct spa
|
||||
static int sparx5_start(struct sparx5 *sparx5)
|
||||
{
|
||||
u8 broadcast[ETH_ALEN] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
|
||||
+ const struct sparx5_consts *consts = sparx5->data->consts;
|
||||
char queue_name[32];
|
||||
u32 idx;
|
||||
int err;
|
||||
@@ -608,7 +613,7 @@ static int sparx5_start(struct sparx5 *s
|
||||
}
|
||||
|
||||
/* Enable CPU ports */
|
||||
- for (idx = SPX5_PORTS; idx < SPX5_PORTS_ALL; idx++)
|
||||
+ for (idx = consts->n_ports; idx < consts->n_ports_all; idx++)
|
||||
spx5_rmw(QFWD_SWITCH_PORT_MODE_PORT_ENA_SET(1),
|
||||
QFWD_SWITCH_PORT_MODE_PORT_ENA,
|
||||
sparx5,
|
||||
--- a/drivers/net/ethernet/microchip/sparx5/sparx5_netdev.c
|
||||
+++ b/drivers/net/ethernet/microchip/sparx5/sparx5_netdev.c
|
||||
@@ -290,7 +290,7 @@ int sparx5_register_netdevs(struct sparx
|
||||
int portno;
|
||||
int err;
|
||||
|
||||
- for (portno = 0; portno < SPX5_PORTS; portno++)
|
||||
+ for (portno = 0; portno < sparx5->data->consts->n_ports; portno++)
|
||||
if (sparx5->ports[portno]) {
|
||||
err = register_netdev(sparx5->ports[portno]->ndev);
|
||||
if (err) {
|
||||
@@ -309,7 +309,7 @@ void sparx5_destroy_netdevs(struct sparx
|
||||
struct sparx5_port *port;
|
||||
int portno;
|
||||
|
||||
- for (portno = 0; portno < SPX5_PORTS; portno++) {
|
||||
+ for (portno = 0; portno < sparx5->data->consts->n_ports; portno++) {
|
||||
port = sparx5->ports[portno];
|
||||
if (port && port->phylink) {
|
||||
/* Disconnect the phy */
|
||||
@@ -327,8 +327,7 @@ void sparx5_unregister_netdevs(struct sp
|
||||
{
|
||||
int portno;
|
||||
|
||||
- for (portno = 0; portno < SPX5_PORTS; portno++)
|
||||
+ for (portno = 0; portno < sparx5->data->consts->n_ports; portno++)
|
||||
if (sparx5->ports[portno])
|
||||
unregister_netdev(sparx5->ports[portno]->ndev);
|
||||
}
|
||||
-
|
||||
--- a/drivers/net/ethernet/microchip/sparx5/sparx5_packet.c
|
||||
+++ b/drivers/net/ethernet/microchip/sparx5/sparx5_packet.c
|
||||
@@ -75,7 +75,7 @@ static void sparx5_xtr_grp(struct sparx5
|
||||
sparx5_ifh_parse(ifh, &fi);
|
||||
|
||||
/* Map to port netdev */
|
||||
- port = fi.src_port < SPX5_PORTS ?
|
||||
+ port = fi.src_port < sparx5->data->consts->n_ports ?
|
||||
sparx5->ports[fi.src_port] : NULL;
|
||||
if (!port || !port->ndev) {
|
||||
dev_err(sparx5->dev, "Data on inactive port %d\n", fi.src_port);
|
||||
--- a/drivers/net/ethernet/microchip/sparx5/sparx5_pgid.c
|
||||
+++ b/drivers/net/ethernet/microchip/sparx5/sparx5_pgid.c
|
||||
@@ -5,7 +5,7 @@ void sparx5_pgid_init(struct sparx5 *spx
|
||||
{
|
||||
int i;
|
||||
|
||||
- for (i = 0; i < PGID_TABLE_SIZE; i++)
|
||||
+ for (i = 0; i < spx5->data->consts->n_pgids; i++)
|
||||
spx5->pgid_map[i] = SPX5_PGID_FREE;
|
||||
|
||||
/* Reserved for unicast, flood control, broadcast, and CPU.
|
||||
@@ -22,7 +22,7 @@ int sparx5_pgid_alloc_mcast(struct sparx
|
||||
/* The multicast area starts at index 65, but the first 7
|
||||
* are reserved for flood masks and CPU. Start alloc after that.
|
||||
*/
|
||||
- for (i = PGID_MCAST_START; i < PGID_TABLE_SIZE; i++) {
|
||||
+ for (i = PGID_MCAST_START; i < spx5->data->consts->n_pgids; i++) {
|
||||
if (spx5->pgid_map[i] == SPX5_PGID_FREE) {
|
||||
spx5->pgid_map[i] = SPX5_PGID_MULTICAST;
|
||||
*idx = i;
|
||||
@@ -35,7 +35,7 @@ int sparx5_pgid_alloc_mcast(struct sparx
|
||||
|
||||
int sparx5_pgid_free(struct sparx5 *spx5, u16 idx)
|
||||
{
|
||||
- if (idx <= PGID_CPU || idx >= PGID_TABLE_SIZE)
|
||||
+ if (idx <= PGID_CPU || idx >= spx5->data->consts->n_pgids)
|
||||
return -EINVAL;
|
||||
|
||||
if (spx5->pgid_map[idx] == SPX5_PGID_FREE)
|
||||
--- a/drivers/net/ethernet/microchip/sparx5/sparx5_psfp.c
|
||||
+++ b/drivers/net/ethernet/microchip/sparx5/sparx5_psfp.c
|
||||
@@ -22,34 +22,38 @@ static struct sparx5_pool_entry sparx5_p
|
||||
|
||||
static int sparx5_psfp_sf_get(struct sparx5 *sparx5, u32 *id)
|
||||
{
|
||||
- return sparx5_pool_get(sparx5_psfp_sf_pool, SPX5_PSFP_SF_CNT, id);
|
||||
+ return sparx5_pool_get(sparx5_psfp_sf_pool,
|
||||
+ sparx5->data->consts->n_filters, id);
|
||||
}
|
||||
|
||||
static int sparx5_psfp_sf_put(struct sparx5 *sparx5, u32 id)
|
||||
{
|
||||
- return sparx5_pool_put(sparx5_psfp_sf_pool, SPX5_PSFP_SF_CNT, id);
|
||||
+ return sparx5_pool_put(sparx5_psfp_sf_pool,
|
||||
+ sparx5->data->consts->n_filters, id);
|
||||
}
|
||||
|
||||
static int sparx5_psfp_sg_get(struct sparx5 *sparx5, u32 idx, u32 *id)
|
||||
{
|
||||
- return sparx5_pool_get_with_idx(sparx5_psfp_sg_pool, SPX5_PSFP_SG_CNT,
|
||||
- idx, id);
|
||||
+ return sparx5_pool_get_with_idx(sparx5_psfp_sg_pool,
|
||||
+ sparx5->data->consts->n_gates, idx, id);
|
||||
}
|
||||
|
||||
static int sparx5_psfp_sg_put(struct sparx5 *sparx5, u32 id)
|
||||
{
|
||||
- return sparx5_pool_put(sparx5_psfp_sg_pool, SPX5_PSFP_SG_CNT, id);
|
||||
+ return sparx5_pool_put(sparx5_psfp_sg_pool,
|
||||
+ sparx5->data->consts->n_gates, id);
|
||||
}
|
||||
|
||||
static int sparx5_psfp_fm_get(struct sparx5 *sparx5, u32 idx, u32 *id)
|
||||
{
|
||||
- return sparx5_pool_get_with_idx(sparx5_psfp_fm_pool, SPX5_SDLB_CNT, idx,
|
||||
- id);
|
||||
+ return sparx5_pool_get_with_idx(sparx5_psfp_fm_pool,
|
||||
+ sparx5->data->consts->n_sdlbs, idx, id);
|
||||
}
|
||||
|
||||
static int sparx5_psfp_fm_put(struct sparx5 *sparx5, u32 id)
|
||||
{
|
||||
- return sparx5_pool_put(sparx5_psfp_fm_pool, SPX5_SDLB_CNT, id);
|
||||
+ return sparx5_pool_put(sparx5_psfp_fm_pool,
|
||||
+ sparx5->data->consts->n_sdlbs, id);
|
||||
}
|
||||
|
||||
u32 sparx5_psfp_isdx_get_sf(struct sparx5 *sparx5, u32 isdx)
|
||||
@@ -318,7 +322,7 @@ void sparx5_psfp_init(struct sparx5 *spa
|
||||
const struct sparx5_sdlb_group *group;
|
||||
int i;
|
||||
|
||||
- for (i = 0; i < SPX5_SDLB_GROUP_CNT; i++) {
|
||||
+ for (i = 0; i < sparx5->data->consts->n_lb_groups; i++) {
|
||||
group = &sdlb_groups[i];
|
||||
sparx5_sdlb_group_init(sparx5, group->max_rate,
|
||||
group->min_burst, group->frame_size, i);
|
||||
--- a/drivers/net/ethernet/microchip/sparx5/sparx5_ptp.c
|
||||
+++ b/drivers/net/ethernet/microchip/sparx5/sparx5_ptp.c
|
||||
@@ -274,6 +274,7 @@ static void sparx5_get_hwtimestamp(struc
|
||||
u32 nsec)
|
||||
{
|
||||
/* Read current PTP time to get seconds */
|
||||
+ const struct sparx5_consts *consts = sparx5->data->consts;
|
||||
unsigned long flags;
|
||||
u32 curr_nsec;
|
||||
|
||||
@@ -285,10 +286,10 @@ static void sparx5_get_hwtimestamp(struc
|
||||
PTP_PTP_PIN_CFG_PTP_PIN_ACTION |
|
||||
PTP_PTP_PIN_CFG_PTP_PIN_DOM |
|
||||
PTP_PTP_PIN_CFG_PTP_PIN_SYNC,
|
||||
- sparx5, PTP_PTP_PIN_CFG(TOD_ACC_PIN));
|
||||
+ sparx5, PTP_PTP_PIN_CFG(consts->tod_pin));
|
||||
|
||||
- ts->tv_sec = spx5_rd(sparx5, PTP_PTP_TOD_SEC_LSB(TOD_ACC_PIN));
|
||||
- curr_nsec = spx5_rd(sparx5, PTP_PTP_TOD_NSEC(TOD_ACC_PIN));
|
||||
+ ts->tv_sec = spx5_rd(sparx5, PTP_PTP_TOD_SEC_LSB(consts->tod_pin));
|
||||
+ curr_nsec = spx5_rd(sparx5, PTP_PTP_TOD_NSEC(consts->tod_pin));
|
||||
|
||||
ts->tv_nsec = nsec;
|
||||
|
||||
@@ -440,8 +441,11 @@ static int sparx5_ptp_settime64(struct p
|
||||
{
|
||||
struct sparx5_phc *phc = container_of(ptp, struct sparx5_phc, info);
|
||||
struct sparx5 *sparx5 = phc->sparx5;
|
||||
+ const struct sparx5_consts *consts;
|
||||
unsigned long flags;
|
||||
|
||||
+ consts = sparx5->data->consts;
|
||||
+
|
||||
spin_lock_irqsave(&sparx5->ptp_clock_lock, flags);
|
||||
|
||||
/* Must be in IDLE mode before the time can be loaded */
|
||||
@@ -451,14 +455,14 @@ static int sparx5_ptp_settime64(struct p
|
||||
PTP_PTP_PIN_CFG_PTP_PIN_ACTION |
|
||||
PTP_PTP_PIN_CFG_PTP_PIN_DOM |
|
||||
PTP_PTP_PIN_CFG_PTP_PIN_SYNC,
|
||||
- sparx5, PTP_PTP_PIN_CFG(TOD_ACC_PIN));
|
||||
+ sparx5, PTP_PTP_PIN_CFG(consts->tod_pin));
|
||||
|
||||
/* Set new value */
|
||||
spx5_wr(PTP_PTP_TOD_SEC_MSB_PTP_TOD_SEC_MSB_SET(upper_32_bits(ts->tv_sec)),
|
||||
- sparx5, PTP_PTP_TOD_SEC_MSB(TOD_ACC_PIN));
|
||||
+ sparx5, PTP_PTP_TOD_SEC_MSB(consts->tod_pin));
|
||||
spx5_wr(lower_32_bits(ts->tv_sec),
|
||||
- sparx5, PTP_PTP_TOD_SEC_LSB(TOD_ACC_PIN));
|
||||
- spx5_wr(ts->tv_nsec, sparx5, PTP_PTP_TOD_NSEC(TOD_ACC_PIN));
|
||||
+ sparx5, PTP_PTP_TOD_SEC_LSB(consts->tod_pin));
|
||||
+ spx5_wr(ts->tv_nsec, sparx5, PTP_PTP_TOD_NSEC(consts->tod_pin));
|
||||
|
||||
/* Apply new values */
|
||||
spx5_rmw(PTP_PTP_PIN_CFG_PTP_PIN_ACTION_SET(PTP_PIN_ACTION_LOAD) |
|
||||
@@ -467,7 +471,7 @@ static int sparx5_ptp_settime64(struct p
|
||||
PTP_PTP_PIN_CFG_PTP_PIN_ACTION |
|
||||
PTP_PTP_PIN_CFG_PTP_PIN_DOM |
|
||||
PTP_PTP_PIN_CFG_PTP_PIN_SYNC,
|
||||
- sparx5, PTP_PTP_PIN_CFG(TOD_ACC_PIN));
|
||||
+ sparx5, PTP_PTP_PIN_CFG(consts->tod_pin));
|
||||
|
||||
spin_unlock_irqrestore(&sparx5->ptp_clock_lock, flags);
|
||||
|
||||
@@ -478,10 +482,13 @@ int sparx5_ptp_gettime64(struct ptp_cloc
|
||||
{
|
||||
struct sparx5_phc *phc = container_of(ptp, struct sparx5_phc, info);
|
||||
struct sparx5 *sparx5 = phc->sparx5;
|
||||
+ const struct sparx5_consts *consts;
|
||||
unsigned long flags;
|
||||
time64_t s;
|
||||
s64 ns;
|
||||
|
||||
+ consts = sparx5->data->consts;
|
||||
+
|
||||
spin_lock_irqsave(&sparx5->ptp_clock_lock, flags);
|
||||
|
||||
spx5_rmw(PTP_PTP_PIN_CFG_PTP_PIN_ACTION_SET(PTP_PIN_ACTION_SAVE) |
|
||||
@@ -490,12 +497,12 @@ int sparx5_ptp_gettime64(struct ptp_cloc
|
||||
PTP_PTP_PIN_CFG_PTP_PIN_ACTION |
|
||||
PTP_PTP_PIN_CFG_PTP_PIN_DOM |
|
||||
PTP_PTP_PIN_CFG_PTP_PIN_SYNC,
|
||||
- sparx5, PTP_PTP_PIN_CFG(TOD_ACC_PIN));
|
||||
+ sparx5, PTP_PTP_PIN_CFG(consts->tod_pin));
|
||||
|
||||
- s = spx5_rd(sparx5, PTP_PTP_TOD_SEC_MSB(TOD_ACC_PIN));
|
||||
+ s = spx5_rd(sparx5, PTP_PTP_TOD_SEC_MSB(consts->tod_pin));
|
||||
s <<= 32;
|
||||
- s |= spx5_rd(sparx5, PTP_PTP_TOD_SEC_LSB(TOD_ACC_PIN));
|
||||
- ns = spx5_rd(sparx5, PTP_PTP_TOD_NSEC(TOD_ACC_PIN));
|
||||
+ s |= spx5_rd(sparx5, PTP_PTP_TOD_SEC_LSB(consts->tod_pin));
|
||||
+ ns = spx5_rd(sparx5, PTP_PTP_TOD_NSEC(consts->tod_pin));
|
||||
ns &= PTP_PTP_TOD_NSEC_PTP_TOD_NSEC;
|
||||
|
||||
spin_unlock_irqrestore(&sparx5->ptp_clock_lock, flags);
|
||||
@@ -515,6 +522,9 @@ static int sparx5_ptp_adjtime(struct ptp
|
||||
{
|
||||
struct sparx5_phc *phc = container_of(ptp, struct sparx5_phc, info);
|
||||
struct sparx5 *sparx5 = phc->sparx5;
|
||||
+ const struct sparx5_consts *consts;
|
||||
+
|
||||
+ consts = sparx5->data->consts;
|
||||
|
||||
if (delta > -(NSEC_PER_SEC / 2) && delta < (NSEC_PER_SEC / 2)) {
|
||||
unsigned long flags;
|
||||
@@ -528,10 +538,10 @@ static int sparx5_ptp_adjtime(struct ptp
|
||||
PTP_PTP_PIN_CFG_PTP_PIN_ACTION |
|
||||
PTP_PTP_PIN_CFG_PTP_PIN_DOM |
|
||||
PTP_PTP_PIN_CFG_PTP_PIN_SYNC,
|
||||
- sparx5, PTP_PTP_PIN_CFG(TOD_ACC_PIN));
|
||||
+ sparx5, PTP_PTP_PIN_CFG(consts->tod_pin));
|
||||
|
||||
spx5_wr(PTP_PTP_TOD_NSEC_PTP_TOD_NSEC_SET(delta),
|
||||
- sparx5, PTP_PTP_TOD_NSEC(TOD_ACC_PIN));
|
||||
+ sparx5, PTP_PTP_TOD_NSEC(consts->tod_pin));
|
||||
|
||||
/* Adjust time with the value of PTP_TOD_NSEC */
|
||||
spx5_rmw(PTP_PTP_PIN_CFG_PTP_PIN_ACTION_SET(PTP_PIN_ACTION_DELTA) |
|
||||
@@ -540,7 +550,7 @@ static int sparx5_ptp_adjtime(struct ptp
|
||||
PTP_PTP_PIN_CFG_PTP_PIN_ACTION |
|
||||
PTP_PTP_PIN_CFG_PTP_PIN_DOM |
|
||||
PTP_PTP_PIN_CFG_PTP_PIN_SYNC,
|
||||
- sparx5, PTP_PTP_PIN_CFG(TOD_ACC_PIN));
|
||||
+ sparx5, PTP_PTP_PIN_CFG(consts->tod_pin));
|
||||
|
||||
spin_unlock_irqrestore(&sparx5->ptp_clock_lock, flags);
|
||||
} else {
|
||||
@@ -630,7 +640,7 @@ int sparx5_ptp_init(struct sparx5 *sparx
|
||||
/* Enable master counters */
|
||||
spx5_wr(PTP_PTP_DOM_CFG_PTP_ENA_SET(0x7), sparx5, PTP_PTP_DOM_CFG);
|
||||
|
||||
- for (i = 0; i < SPX5_PORTS; i++) {
|
||||
+ for (i = 0; i < sparx5->data->consts->n_ports; i++) {
|
||||
port = sparx5->ports[i];
|
||||
if (!port)
|
||||
continue;
|
||||
@@ -646,7 +656,7 @@ void sparx5_ptp_deinit(struct sparx5 *sp
|
||||
struct sparx5_port *port;
|
||||
int i;
|
||||
|
||||
- for (i = 0; i < SPX5_PORTS; i++) {
|
||||
+ for (i = 0; i < sparx5->data->consts->n_ports; i++) {
|
||||
port = sparx5->ports[i];
|
||||
if (!port)
|
||||
continue;
|
||||
--- a/drivers/net/ethernet/microchip/sparx5/sparx5_sdlb.c
|
||||
+++ b/drivers/net/ethernet/microchip/sparx5/sparx5_sdlb.c
|
||||
@@ -184,7 +184,7 @@ int sparx5_sdlb_group_get_by_rate(struct
|
||||
|
||||
rate_bps = rate * 1000;
|
||||
|
||||
- for (i = SPX5_SDLB_GROUP_CNT - 1; i >= 0; i--) {
|
||||
+ for (i = sparx5->data->consts->n_lb_groups - 1; i >= 0; i--) {
|
||||
group = &sdlb_groups[i];
|
||||
|
||||
count = sparx5_sdlb_group_get_count(sparx5, i);
|
||||
@@ -208,7 +208,7 @@ int sparx5_sdlb_group_get_by_index(struc
|
||||
u32 itr, next;
|
||||
int i;
|
||||
|
||||
- for (i = 0; i < SPX5_SDLB_GROUP_CNT; i++) {
|
||||
+ for (i = 0; i < sparx5->data->consts->n_lb_groups; i++) {
|
||||
if (sparx5_sdlb_group_is_empty(sparx5, i))
|
||||
continue;
|
||||
|
||||
--- a/drivers/net/ethernet/microchip/sparx5/sparx5_switchdev.c
|
||||
+++ b/drivers/net/ethernet/microchip/sparx5/sparx5_switchdev.c
|
||||
@@ -547,7 +547,7 @@ static int sparx5_handle_port_mdb_add(st
|
||||
|
||||
/* Add any mrouter ports to the new entry */
|
||||
if (is_new && ether_addr_is_ip_mcast(v->addr))
|
||||
- for (i = 0; i < SPX5_PORTS; i++)
|
||||
+ for (i = 0; i < spx5->data->consts->n_ports; i++)
|
||||
if (spx5->ports[i] && spx5->ports[i]->is_mrouter)
|
||||
sparx5_pgid_update_mask(spx5->ports[i],
|
||||
entry->pgid_idx,
|
||||
--- a/drivers/net/ethernet/microchip/sparx5/sparx5_tc_flower.c
|
||||
+++ b/drivers/net/ethernet/microchip/sparx5/sparx5_tc_flower.c
|
||||
@@ -785,7 +785,9 @@ static int sparx5_tc_flower_psfp_setup(s
|
||||
* allocate a stream gate that is always open.
|
||||
*/
|
||||
if (sg_idx < 0) {
|
||||
- sg_idx = sparx5_pool_idx_to_id(SPX5_PSFP_SG_OPEN);
|
||||
+ /* Always-open stream gate is always the last */
|
||||
+ sg_idx = sparx5_pool_idx_to_id(sparx5->data->consts->n_gates -
|
||||
+ 1);
|
||||
sg->ipv = 0; /* Disabled */
|
||||
sg->cycletime = SPX5_PSFP_SG_CYCLE_TIME_DEFAULT;
|
||||
sg->num_entries = 1;
|
||||
--- a/drivers/net/ethernet/microchip/sparx5/sparx5_vlan.c
|
||||
+++ b/drivers/net/ethernet/microchip/sparx5/sparx5_vlan.c
|
||||
@@ -169,7 +169,7 @@ void sparx5_update_fwd(struct sparx5 *sp
|
||||
}
|
||||
|
||||
/* Update SRC masks */
|
||||
- for (port = 0; port < SPX5_PORTS; port++) {
|
||||
+ for (port = 0; port < sparx5->data->consts->n_ports; port++) {
|
||||
if (test_bit(port, sparx5->bridge_fwd_mask)) {
|
||||
/* Allow to send to all bridged but self */
|
||||
bitmap_copy(workmask, sparx5->bridge_fwd_mask, SPX5_PORTS);
|
||||
@ -0,0 +1,60 @@
|
||||
From efdc2c3094cc2e8aca09c3a16f7a0f3a10d9a097 Mon Sep 17 00:00:00 2001
|
||||
From: Daniel Machon <daniel.machon@microchip.com>
|
||||
Date: Fri, 4 Oct 2024 15:19:33 +0200
|
||||
Subject: [PATCH 35/82] net: sparx5: use SPX5_CONST for constants which do not
|
||||
have a symbol
|
||||
|
||||
Now that we have indentified all the chip constants, update the use of
|
||||
them where a symbol is not defined for the constant.
|
||||
|
||||
Reviewed-by: Steen Hegelund <Steen.Hegelund@microchip.com>
|
||||
Signed-off-by: Daniel Machon <daniel.machon@microchip.com>
|
||||
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
|
||||
---
|
||||
drivers/net/ethernet/microchip/sparx5/sparx5_main.c | 13 +++++++++----
|
||||
1 file changed, 9 insertions(+), 4 deletions(-)
|
||||
|
||||
--- a/drivers/net/ethernet/microchip/sparx5/sparx5_main.c
|
||||
+++ b/drivers/net/ethernet/microchip/sparx5/sparx5_main.c
|
||||
@@ -522,7 +522,7 @@ static int sparx5_init_coreclock(struct
|
||||
sparx5,
|
||||
LRN_AUTOAGE_CFG_1);
|
||||
|
||||
- for (idx = 0; idx < 3; idx++)
|
||||
+ for (idx = 0; idx < sparx5->data->consts->n_sio_clks; idx++)
|
||||
spx5_rmw(GCB_SIO_CLOCK_SYS_CLK_PERIOD_SET(clk_period / 100),
|
||||
GCB_SIO_CLOCK_SYS_CLK_PERIOD,
|
||||
sparx5,
|
||||
@@ -550,16 +550,21 @@ static u32 qlim_wm(struct sparx5 *sparx5
|
||||
|
||||
static int sparx5_qlim_set(struct sparx5 *sparx5)
|
||||
{
|
||||
+ const struct sparx5_consts *consts = sparx5->data->consts;
|
||||
u32 res, dp, prio;
|
||||
|
||||
for (res = 0; res < 2; res++) {
|
||||
for (prio = 0; prio < 8; prio++)
|
||||
spx5_wr(0xFFF, sparx5,
|
||||
- QRES_RES_CFG(prio + 630 + res * 1024));
|
||||
+ QRES_RES_CFG(prio +
|
||||
+ consts->qres_max_prio_idx +
|
||||
+ res * 1024));
|
||||
|
||||
for (dp = 0; dp < 4; dp++)
|
||||
spx5_wr(0xFFF, sparx5,
|
||||
- QRES_RES_CFG(dp + 638 + res * 1024));
|
||||
+ QRES_RES_CFG(dp +
|
||||
+ consts->qres_max_colour_idx +
|
||||
+ res * 1024));
|
||||
}
|
||||
|
||||
/* Set 80,90,95,100% of memory size for top watermarks */
|
||||
@@ -605,7 +610,7 @@ static int sparx5_start(struct sparx5 *s
|
||||
int err;
|
||||
|
||||
/* Setup own UPSIDs */
|
||||
- for (idx = 0; idx < 3; idx++) {
|
||||
+ for (idx = 0; idx < consts->n_own_upsids; idx++) {
|
||||
spx5_wr(idx, sparx5, ANA_AC_OWN_UPSID(idx));
|
||||
spx5_wr(idx, sparx5, ANA_CL_OWN_UPSID(idx));
|
||||
spx5_wr(idx, sparx5, ANA_L2_OWN_UPSID(idx));
|
||||
@ -0,0 +1,227 @@
|
||||
From 9a6d927f8d9386fcabe4b93aa1bf16a0796e69fb Mon Sep 17 00:00:00 2001
|
||||
From: Daniel Machon <daniel.machon@microchip.com>
|
||||
Date: Fri, 4 Oct 2024 15:19:34 +0200
|
||||
Subject: [PATCH 36/82] net: sparx5: add ops to match data
|
||||
|
||||
Add new struct sparx5_ops, containing functions that needs to be
|
||||
different as the implementation differs on Sparx5 and lan969x. Initially
|
||||
we add functions for checking the port type (2g5, 5g, 10g or 25g) based
|
||||
on the port number. Update the code to use the ops instead of the
|
||||
platform specific functions.
|
||||
|
||||
Reviewed-by: Steen Hegelund <Steen.Hegelund@microchip.com>
|
||||
Reviewed-by: Jacob Keller <jacob.e.keller@intel.com>
|
||||
Signed-off-by: Daniel Machon <daniel.machon@microchip.com>
|
||||
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
|
||||
---
|
||||
.../ethernet/microchip/sparx5/sparx5_main.c | 8 +++++
|
||||
.../ethernet/microchip/sparx5/sparx5_main.h | 8 +++++
|
||||
.../ethernet/microchip/sparx5/sparx5_port.c | 34 +++++++++++--------
|
||||
.../ethernet/microchip/sparx5/sparx5_port.h | 12 ++++---
|
||||
4 files changed, 44 insertions(+), 18 deletions(-)
|
||||
|
||||
--- a/drivers/net/ethernet/microchip/sparx5/sparx5_main.c
|
||||
+++ b/drivers/net/ethernet/microchip/sparx5/sparx5_main.c
|
||||
@@ -982,12 +982,20 @@ static const struct sparx5_consts sparx5
|
||||
.tod_pin = 4,
|
||||
};
|
||||
|
||||
+static const struct sparx5_ops sparx5_ops = {
|
||||
+ .is_port_2g5 = &sparx5_port_is_2g5,
|
||||
+ .is_port_5g = &sparx5_port_is_5g,
|
||||
+ .is_port_10g = &sparx5_port_is_10g,
|
||||
+ .is_port_25g = &sparx5_port_is_25g,
|
||||
+};
|
||||
+
|
||||
static const struct sparx5_match_data sparx5_desc = {
|
||||
.iomap = sparx5_main_iomap,
|
||||
.iomap_size = ARRAY_SIZE(sparx5_main_iomap),
|
||||
.ioranges = 3,
|
||||
.regs = &sparx5_regs,
|
||||
.consts = &sparx5_consts,
|
||||
+ .ops = &sparx5_ops,
|
||||
};
|
||||
|
||||
static const struct of_device_id mchp_sparx5_match[] = {
|
||||
--- a/drivers/net/ethernet/microchip/sparx5/sparx5_main.h
|
||||
+++ b/drivers/net/ethernet/microchip/sparx5/sparx5_main.h
|
||||
@@ -258,6 +258,13 @@ struct sparx5_consts {
|
||||
u32 tod_pin; /* PTP TOD pin */
|
||||
};
|
||||
|
||||
+struct sparx5_ops {
|
||||
+ bool (*is_port_2g5)(int portno);
|
||||
+ bool (*is_port_5g)(int portno);
|
||||
+ bool (*is_port_10g)(int portno);
|
||||
+ bool (*is_port_25g)(int portno);
|
||||
+};
|
||||
+
|
||||
struct sparx5_main_io_resource {
|
||||
enum sparx5_target id;
|
||||
phys_addr_t offset;
|
||||
@@ -267,6 +274,7 @@ struct sparx5_main_io_resource {
|
||||
struct sparx5_match_data {
|
||||
const struct sparx5_regs *regs;
|
||||
const struct sparx5_consts *consts;
|
||||
+ const struct sparx5_ops *ops;
|
||||
const struct sparx5_main_io_resource *iomap;
|
||||
int ioranges;
|
||||
int iomap_size;
|
||||
--- a/drivers/net/ethernet/microchip/sparx5/sparx5_port.c
|
||||
+++ b/drivers/net/ethernet/microchip/sparx5/sparx5_port.c
|
||||
@@ -213,11 +213,13 @@ static int sparx5_port_verify_speed(stru
|
||||
struct sparx5_port *port,
|
||||
struct sparx5_port_config *conf)
|
||||
{
|
||||
- if ((sparx5_port_is_2g5(port->portno) &&
|
||||
+ const struct sparx5_ops *ops = sparx5->data->ops;
|
||||
+
|
||||
+ if ((ops->is_port_2g5(port->portno) &&
|
||||
conf->speed > SPEED_2500) ||
|
||||
- (sparx5_port_is_5g(port->portno) &&
|
||||
+ (ops->is_port_5g(port->portno) &&
|
||||
conf->speed > SPEED_5000) ||
|
||||
- (sparx5_port_is_10g(port->portno) &&
|
||||
+ (ops->is_port_10g(port->portno) &&
|
||||
conf->speed > SPEED_10000))
|
||||
return sparx5_port_error(port, conf, SPX5_PERR_SPEED);
|
||||
|
||||
@@ -226,14 +228,14 @@ static int sparx5_port_verify_speed(stru
|
||||
return -EINVAL;
|
||||
case PHY_INTERFACE_MODE_1000BASEX:
|
||||
if (conf->speed != SPEED_1000 ||
|
||||
- sparx5_port_is_2g5(port->portno))
|
||||
+ ops->is_port_2g5(port->portno))
|
||||
return sparx5_port_error(port, conf, SPX5_PERR_SPEED);
|
||||
- if (sparx5_port_is_2g5(port->portno))
|
||||
+ if (ops->is_port_2g5(port->portno))
|
||||
return sparx5_port_error(port, conf, SPX5_PERR_IFTYPE);
|
||||
break;
|
||||
case PHY_INTERFACE_MODE_2500BASEX:
|
||||
if (conf->speed != SPEED_2500 ||
|
||||
- sparx5_port_is_2g5(port->portno))
|
||||
+ ops->is_port_2g5(port->portno))
|
||||
return sparx5_port_error(port, conf, SPX5_PERR_SPEED);
|
||||
break;
|
||||
case PHY_INTERFACE_MODE_QSGMII:
|
||||
@@ -320,6 +322,7 @@ static int sparx5_port_disable(struct sp
|
||||
u32 dev = high_spd_dev ?
|
||||
sparx5_to_high_dev(sparx5, port->portno) : TARGET_DEV2G5;
|
||||
void __iomem *devinst = spx5_inst_get(sparx5, dev, tinst);
|
||||
+ const struct sparx5_ops *ops = sparx5->data->ops;
|
||||
u32 spd = port->conf.speed;
|
||||
u32 spd_prm;
|
||||
int err;
|
||||
@@ -436,7 +439,7 @@ static int sparx5_port_disable(struct sp
|
||||
pcsinst,
|
||||
PCS10G_BR_PCS_CFG(0));
|
||||
|
||||
- if (sparx5_port_is_25g(port->portno))
|
||||
+ if (ops->is_port_25g(port->portno))
|
||||
/* Disable 25G PCS */
|
||||
spx5_rmw(DEV25G_PCS25G_CFG_PCS25G_ENA_SET(0),
|
||||
DEV25G_PCS25G_CFG_PCS25G_ENA,
|
||||
@@ -561,6 +564,7 @@ static int sparx5_port_max_tags_set(stru
|
||||
u32 dev = sparx5_to_high_dev(sparx5, port->portno);
|
||||
u32 tinst = sparx5_port_dev_index(sparx5, port->portno);
|
||||
void __iomem *inst = spx5_inst_get(sparx5, dev, tinst);
|
||||
+ const struct sparx5_ops *ops = sparx5->data->ops;
|
||||
u32 etype;
|
||||
|
||||
etype = (vlan_type == SPX5_VLAN_PORT_TYPE_S_CUSTOM ?
|
||||
@@ -575,7 +579,7 @@ static int sparx5_port_max_tags_set(stru
|
||||
sparx5,
|
||||
DEV2G5_MAC_TAGS_CFG(port->portno));
|
||||
|
||||
- if (sparx5_port_is_2g5(port->portno))
|
||||
+ if (ops->is_port_2g5(port->portno))
|
||||
return 0;
|
||||
|
||||
spx5_inst_rmw(DEV10G_MAC_TAGS_CFG_TAG_ID_SET(etype) |
|
||||
@@ -844,18 +848,19 @@ static int sparx5_port_pcs_high_set(stru
|
||||
static void sparx5_dev_switch(struct sparx5 *sparx5, int port, bool hsd)
|
||||
{
|
||||
int bt_indx = BIT(sparx5_port_dev_index(sparx5, port));
|
||||
+ const struct sparx5_ops *ops = sparx5->data->ops;
|
||||
|
||||
- if (sparx5_port_is_5g(port)) {
|
||||
+ if (ops->is_port_5g(port)) {
|
||||
spx5_rmw(hsd ? 0 : bt_indx,
|
||||
bt_indx,
|
||||
sparx5,
|
||||
PORT_CONF_DEV5G_MODES);
|
||||
- } else if (sparx5_port_is_10g(port)) {
|
||||
+ } else if (ops->is_port_10g(port)) {
|
||||
spx5_rmw(hsd ? 0 : bt_indx,
|
||||
bt_indx,
|
||||
sparx5,
|
||||
PORT_CONF_DEV10G_MODES);
|
||||
- } else if (sparx5_port_is_25g(port)) {
|
||||
+ } else if (ops->is_port_25g(port)) {
|
||||
spx5_rmw(hsd ? 0 : bt_indx,
|
||||
bt_indx,
|
||||
sparx5,
|
||||
@@ -1016,6 +1021,7 @@ int sparx5_port_init(struct sparx5 *spar
|
||||
{
|
||||
u32 pause_start = sparx5_wm_enc(6 * (ETH_MAXLEN / SPX5_BUFFER_CELL_SZ));
|
||||
u32 atop = sparx5_wm_enc(20 * (ETH_MAXLEN / SPX5_BUFFER_CELL_SZ));
|
||||
+ const struct sparx5_ops *ops = sparx5->data->ops;
|
||||
u32 devhigh = sparx5_to_high_dev(sparx5, port->portno);
|
||||
u32 pix = sparx5_port_dev_index(sparx5, port->portno);
|
||||
u32 pcs = sparx5_to_pcs_dev(sparx5, port->portno);
|
||||
@@ -1082,7 +1088,7 @@ int sparx5_port_init(struct sparx5 *spar
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
- if (!sparx5_port_is_2g5(port->portno))
|
||||
+ if (!ops->is_port_2g5(port->portno))
|
||||
/* Enable shadow device */
|
||||
spx5_rmw(DSM_DEV_TX_STOP_WM_CFG_DEV10G_SHADOW_ENA_SET(1),
|
||||
DSM_DEV_TX_STOP_WM_CFG_DEV10G_SHADOW_ENA,
|
||||
@@ -1105,7 +1111,7 @@ int sparx5_port_init(struct sparx5 *spar
|
||||
sparx5,
|
||||
DEV2G5_MAC_IFG_CFG(port->portno));
|
||||
|
||||
- if (sparx5_port_is_2g5(port->portno))
|
||||
+ if (ops->is_port_2g5(port->portno))
|
||||
return 0; /* Low speed device only - return */
|
||||
|
||||
/* Now setup the high speed device */
|
||||
@@ -1128,7 +1134,7 @@ int sparx5_port_init(struct sparx5 *spar
|
||||
pcsinst,
|
||||
PCS10G_BR_PCS_SD_CFG(0));
|
||||
|
||||
- if (sparx5_port_is_25g(port->portno)) {
|
||||
+ if (ops->is_port_25g(port->portno)) {
|
||||
/* Handle Signal Detect in 25G PCS */
|
||||
spx5_wr(DEV25G_PCS25G_SD_CFG_SD_POL_SET(sd_pol) |
|
||||
DEV25G_PCS25G_SD_CFG_SD_SEL_SET(sd_sel) |
|
||||
--- a/drivers/net/ethernet/microchip/sparx5/sparx5_port.h
|
||||
+++ b/drivers/net/ethernet/microchip/sparx5/sparx5_port.h
|
||||
@@ -42,18 +42,22 @@ static inline bool sparx5_port_is_25g(in
|
||||
|
||||
static inline u32 sparx5_to_high_dev(struct sparx5 *sparx5, int port)
|
||||
{
|
||||
- if (sparx5_port_is_5g(port))
|
||||
+ const struct sparx5_ops *ops = sparx5->data->ops;
|
||||
+
|
||||
+ if (ops->is_port_5g(port))
|
||||
return TARGET_DEV5G;
|
||||
- if (sparx5_port_is_10g(port))
|
||||
+ if (ops->is_port_10g(port))
|
||||
return TARGET_DEV10G;
|
||||
return TARGET_DEV25G;
|
||||
}
|
||||
|
||||
static inline u32 sparx5_to_pcs_dev(struct sparx5 *sparx5, int port)
|
||||
{
|
||||
- if (sparx5_port_is_5g(port))
|
||||
+ const struct sparx5_ops *ops = sparx5->data->ops;
|
||||
+
|
||||
+ if (ops->is_port_5g(port))
|
||||
return TARGET_PCS5G_BR;
|
||||
- if (sparx5_port_is_10g(port))
|
||||
+ if (ops->is_port_10g(port))
|
||||
return TARGET_PCS10G_BR;
|
||||
return TARGET_PCS25G_BR;
|
||||
}
|
||||
@ -0,0 +1,80 @@
|
||||
From cc1814ae3a2cd34a345c7d638f5da991d8d22d33 Mon Sep 17 00:00:00 2001
|
||||
From: Daniel Machon <daniel.machon@microchip.com>
|
||||
Date: Fri, 4 Oct 2024 15:19:35 +0200
|
||||
Subject: [PATCH 37/82] net: sparx5: ops out chip port to device index/bit
|
||||
functions
|
||||
|
||||
The chip port device index and mode bit can be obtained using the port
|
||||
number. However the mapping of port number to chip device index and
|
||||
mode bit differs on Sparx5 and lan969x. Therefore ops out the function.
|
||||
|
||||
Reviewed-by: Steen Hegelund <Steen.Hegelund@microchip.com>
|
||||
Reviewed-by: Jacob Keller <jacob.e.keller@intel.com>
|
||||
Signed-off-by: Daniel Machon <daniel.machon@microchip.com>
|
||||
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
|
||||
---
|
||||
drivers/net/ethernet/microchip/sparx5/sparx5_main.c | 2 ++
|
||||
drivers/net/ethernet/microchip/sparx5/sparx5_main.h | 2 ++
|
||||
drivers/net/ethernet/microchip/sparx5/sparx5_port.c | 4 +++-
|
||||
drivers/net/ethernet/microchip/sparx5/sparx5_port.h | 7 ++++++-
|
||||
4 files changed, 13 insertions(+), 2 deletions(-)
|
||||
|
||||
--- a/drivers/net/ethernet/microchip/sparx5/sparx5_main.c
|
||||
+++ b/drivers/net/ethernet/microchip/sparx5/sparx5_main.c
|
||||
@@ -987,6 +987,8 @@ static const struct sparx5_ops sparx5_op
|
||||
.is_port_5g = &sparx5_port_is_5g,
|
||||
.is_port_10g = &sparx5_port_is_10g,
|
||||
.is_port_25g = &sparx5_port_is_25g,
|
||||
+ .get_port_dev_index = &sparx5_port_dev_mapping,
|
||||
+ .get_port_dev_bit = &sparx5_port_dev_mapping,
|
||||
};
|
||||
|
||||
static const struct sparx5_match_data sparx5_desc = {
|
||||
--- a/drivers/net/ethernet/microchip/sparx5/sparx5_main.h
|
||||
+++ b/drivers/net/ethernet/microchip/sparx5/sparx5_main.h
|
||||
@@ -263,6 +263,8 @@ struct sparx5_ops {
|
||||
bool (*is_port_5g)(int portno);
|
||||
bool (*is_port_10g)(int portno);
|
||||
bool (*is_port_25g)(int portno);
|
||||
+ u32 (*get_port_dev_index)(struct sparx5 *sparx5, int port);
|
||||
+ u32 (*get_port_dev_bit)(struct sparx5 *sparx5, int port);
|
||||
};
|
||||
|
||||
struct sparx5_main_io_resource {
|
||||
--- a/drivers/net/ethernet/microchip/sparx5/sparx5_port.c
|
||||
+++ b/drivers/net/ethernet/microchip/sparx5/sparx5_port.c
|
||||
@@ -847,8 +847,10 @@ static int sparx5_port_pcs_high_set(stru
|
||||
/* Switch between 1G/2500 and 5G/10G/25G devices */
|
||||
static void sparx5_dev_switch(struct sparx5 *sparx5, int port, bool hsd)
|
||||
{
|
||||
- int bt_indx = BIT(sparx5_port_dev_index(sparx5, port));
|
||||
const struct sparx5_ops *ops = sparx5->data->ops;
|
||||
+ int bt_indx;
|
||||
+
|
||||
+ bt_indx = BIT(ops->get_port_dev_bit(sparx5, port));
|
||||
|
||||
if (ops->is_port_5g(port)) {
|
||||
spx5_rmw(hsd ? 0 : bt_indx,
|
||||
--- a/drivers/net/ethernet/microchip/sparx5/sparx5_port.h
|
||||
+++ b/drivers/net/ethernet/microchip/sparx5/sparx5_port.h
|
||||
@@ -62,7 +62,7 @@ static inline u32 sparx5_to_pcs_dev(stru
|
||||
return TARGET_PCS25G_BR;
|
||||
}
|
||||
|
||||
-static inline int sparx5_port_dev_index(struct sparx5 *sparx5, int port)
|
||||
+static inline u32 sparx5_port_dev_mapping(struct sparx5 *sparx5, int port)
|
||||
{
|
||||
if (sparx5_port_is_2g5(port))
|
||||
return port;
|
||||
@@ -74,6 +74,11 @@ static inline int sparx5_port_dev_index(
|
||||
return (port - 56);
|
||||
}
|
||||
|
||||
+static inline u32 sparx5_port_dev_index(struct sparx5 *sparx5, int port)
|
||||
+{
|
||||
+ return sparx5->data->ops->get_port_dev_index(sparx5, port);
|
||||
+}
|
||||
+
|
||||
int sparx5_port_init(struct sparx5 *sparx5,
|
||||
struct sparx5_port *spx5_port,
|
||||
struct sparx5_port_config *conf);
|
||||
@ -0,0 +1,170 @@
|
||||
From 54a152e60ab7b7fb64211ee6a3defec095fb796e Mon Sep 17 00:00:00 2001
|
||||
From: Daniel Machon <daniel.machon@microchip.com>
|
||||
Date: Fri, 4 Oct 2024 15:19:36 +0200
|
||||
Subject: [PATCH 38/82] net: sparx5: ops out functions for getting certain
|
||||
array values
|
||||
|
||||
Add getters for getting values in arrays: sdlb_groups and
|
||||
sparx5_hsch_max_group_rate and ops out the getters, as these arrays will
|
||||
differ on lan969x.
|
||||
|
||||
Reviewed-by: Steen Hegelund <Steen.Hegelund@microchip.com>
|
||||
Reviewed-by: Jacob Keller <jacob.e.keller@intel.com>
|
||||
Signed-off-by: Daniel Machon <daniel.machon@microchip.com>
|
||||
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
|
||||
---
|
||||
drivers/net/ethernet/microchip/sparx5/sparx5_main.c | 2 ++
|
||||
drivers/net/ethernet/microchip/sparx5/sparx5_main.h | 3 +++
|
||||
drivers/net/ethernet/microchip/sparx5/sparx5_police.c | 3 ++-
|
||||
drivers/net/ethernet/microchip/sparx5/sparx5_psfp.c | 3 ++-
|
||||
drivers/net/ethernet/microchip/sparx5/sparx5_qos.c | 8 +++++++-
|
||||
drivers/net/ethernet/microchip/sparx5/sparx5_qos.h | 2 ++
|
||||
drivers/net/ethernet/microchip/sparx5/sparx5_sdlb.c | 11 +++++++++--
|
||||
7 files changed, 27 insertions(+), 5 deletions(-)
|
||||
|
||||
--- a/drivers/net/ethernet/microchip/sparx5/sparx5_main.c
|
||||
+++ b/drivers/net/ethernet/microchip/sparx5/sparx5_main.c
|
||||
@@ -989,6 +989,8 @@ static const struct sparx5_ops sparx5_op
|
||||
.is_port_25g = &sparx5_port_is_25g,
|
||||
.get_port_dev_index = &sparx5_port_dev_mapping,
|
||||
.get_port_dev_bit = &sparx5_port_dev_mapping,
|
||||
+ .get_hsch_max_group_rate = &sparx5_get_hsch_max_group_rate,
|
||||
+ .get_sdlb_group = &sparx5_get_sdlb_group,
|
||||
};
|
||||
|
||||
static const struct sparx5_match_data sparx5_desc = {
|
||||
--- a/drivers/net/ethernet/microchip/sparx5/sparx5_main.h
|
||||
+++ b/drivers/net/ethernet/microchip/sparx5/sparx5_main.h
|
||||
@@ -265,6 +265,8 @@ struct sparx5_ops {
|
||||
bool (*is_port_25g)(int portno);
|
||||
u32 (*get_port_dev_index)(struct sparx5 *sparx5, int port);
|
||||
u32 (*get_port_dev_bit)(struct sparx5 *sparx5, int port);
|
||||
+ u32 (*get_hsch_max_group_rate)(int grp);
|
||||
+ struct sparx5_sdlb_group *(*get_sdlb_group)(int idx);
|
||||
};
|
||||
|
||||
struct sparx5_main_io_resource {
|
||||
@@ -501,6 +503,7 @@ struct sparx5_sdlb_group {
|
||||
};
|
||||
|
||||
extern struct sparx5_sdlb_group sdlb_groups[SPX5_SDLB_GROUP_CNT];
|
||||
+struct sparx5_sdlb_group *sparx5_get_sdlb_group(int idx);
|
||||
int sparx5_sdlb_pup_token_get(struct sparx5 *sparx5, u32 pup_interval,
|
||||
u64 rate);
|
||||
|
||||
--- a/drivers/net/ethernet/microchip/sparx5/sparx5_police.c
|
||||
+++ b/drivers/net/ethernet/microchip/sparx5/sparx5_police.c
|
||||
@@ -11,10 +11,11 @@ static int sparx5_policer_service_conf_s
|
||||
struct sparx5_policer *pol)
|
||||
{
|
||||
u32 idx, pup_tokens, max_pup_tokens, burst, thres;
|
||||
+ const struct sparx5_ops *ops = sparx5->data->ops;
|
||||
struct sparx5_sdlb_group *g;
|
||||
u64 rate;
|
||||
|
||||
- g = &sdlb_groups[pol->group];
|
||||
+ g = ops->get_sdlb_group(pol->group);
|
||||
idx = pol->idx;
|
||||
|
||||
rate = pol->rate * 1000;
|
||||
--- a/drivers/net/ethernet/microchip/sparx5/sparx5_psfp.c
|
||||
+++ b/drivers/net/ethernet/microchip/sparx5/sparx5_psfp.c
|
||||
@@ -319,11 +319,12 @@ int sparx5_psfp_fm_del(struct sparx5 *sp
|
||||
|
||||
void sparx5_psfp_init(struct sparx5 *sparx5)
|
||||
{
|
||||
+ const struct sparx5_ops *ops = sparx5->data->ops;
|
||||
const struct sparx5_sdlb_group *group;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < sparx5->data->consts->n_lb_groups; i++) {
|
||||
- group = &sdlb_groups[i];
|
||||
+ group = ops->get_sdlb_group(i);
|
||||
sparx5_sdlb_group_init(sparx5, group->max_rate,
|
||||
group->min_burst, group->frame_size, i);
|
||||
}
|
||||
--- a/drivers/net/ethernet/microchip/sparx5/sparx5_qos.c
|
||||
+++ b/drivers/net/ethernet/microchip/sparx5/sparx5_qos.c
|
||||
@@ -74,6 +74,11 @@ static const u32 spx5_hsch_max_group_rat
|
||||
26214200 /* 26.214 Gbps */
|
||||
};
|
||||
|
||||
+u32 sparx5_get_hsch_max_group_rate(int grp)
|
||||
+{
|
||||
+ return spx5_hsch_max_group_rate[grp];
|
||||
+}
|
||||
+
|
||||
static struct sparx5_layer layers[SPX5_HSCH_LAYER_CNT];
|
||||
|
||||
static u32 sparx5_lg_get_leak_time(struct sparx5 *sparx5, u32 layer, u32 group)
|
||||
@@ -385,6 +390,7 @@ static int sparx5_dwrr_conf_set(struct s
|
||||
|
||||
static int sparx5_leak_groups_init(struct sparx5 *sparx5)
|
||||
{
|
||||
+ const struct sparx5_ops *ops = sparx5->data->ops;
|
||||
struct sparx5_layer *layer;
|
||||
u32 sys_clk_per_100ps;
|
||||
struct sparx5_lg *lg;
|
||||
@@ -397,7 +403,7 @@ static int sparx5_leak_groups_init(struc
|
||||
layer = &layers[i];
|
||||
for (ii = 0; ii < SPX5_HSCH_LEAK_GRP_CNT; ii++) {
|
||||
lg = &layer->leak_groups[ii];
|
||||
- lg->max_rate = spx5_hsch_max_group_rate[ii];
|
||||
+ lg->max_rate = ops->get_hsch_max_group_rate(i);
|
||||
|
||||
/* Calculate the leak time in us, to serve a maximum
|
||||
* rate of 'max_rate' for this group
|
||||
--- a/drivers/net/ethernet/microchip/sparx5/sparx5_qos.h
|
||||
+++ b/drivers/net/ethernet/microchip/sparx5/sparx5_qos.h
|
||||
@@ -79,4 +79,6 @@ int sparx5_tc_ets_add(struct sparx5_port
|
||||
|
||||
int sparx5_tc_ets_del(struct sparx5_port *port);
|
||||
|
||||
+u32 sparx5_get_hsch_max_group_rate(int grp);
|
||||
+
|
||||
#endif /* __SPARX5_QOS_H__ */
|
||||
--- a/drivers/net/ethernet/microchip/sparx5/sparx5_sdlb.c
|
||||
+++ b/drivers/net/ethernet/microchip/sparx5/sparx5_sdlb.c
|
||||
@@ -20,6 +20,11 @@ struct sparx5_sdlb_group sdlb_groups[SPX
|
||||
{ 5000000ULL, 8192 / 8, 64 } /* 5 M */
|
||||
};
|
||||
|
||||
+struct sparx5_sdlb_group *sparx5_get_sdlb_group(int idx)
|
||||
+{
|
||||
+ return &sdlb_groups[idx];
|
||||
+}
|
||||
+
|
||||
int sparx5_sdlb_clk_hz_get(struct sparx5 *sparx5)
|
||||
{
|
||||
u32 clk_per_100ps;
|
||||
@@ -178,6 +183,7 @@ static int sparx5_sdlb_group_get_count(s
|
||||
|
||||
int sparx5_sdlb_group_get_by_rate(struct sparx5 *sparx5, u32 rate, u32 burst)
|
||||
{
|
||||
+ const struct sparx5_ops *ops = sparx5->data->ops;
|
||||
const struct sparx5_sdlb_group *group;
|
||||
u64 rate_bps;
|
||||
int i, count;
|
||||
@@ -185,7 +191,7 @@ int sparx5_sdlb_group_get_by_rate(struct
|
||||
rate_bps = rate * 1000;
|
||||
|
||||
for (i = sparx5->data->consts->n_lb_groups - 1; i >= 0; i--) {
|
||||
- group = &sdlb_groups[i];
|
||||
+ group = ops->get_sdlb_group(i);
|
||||
|
||||
count = sparx5_sdlb_group_get_count(sparx5, i);
|
||||
|
||||
@@ -303,11 +309,12 @@ int sparx5_sdlb_group_del(struct sparx5
|
||||
void sparx5_sdlb_group_init(struct sparx5 *sparx5, u64 max_rate, u32 min_burst,
|
||||
u32 frame_size, u32 idx)
|
||||
{
|
||||
+ const struct sparx5_ops *ops = sparx5->data->ops;
|
||||
u32 thres_shift, mask = 0x01, power = 0;
|
||||
struct sparx5_sdlb_group *group;
|
||||
u64 max_token;
|
||||
|
||||
- group = &sdlb_groups[idx];
|
||||
+ group = ops->get_sdlb_group(idx);
|
||||
|
||||
/* Number of positions to right-shift LB's threshold value. */
|
||||
while ((min_burst & mask) == 0) {
|
||||
@ -0,0 +1,74 @@
|
||||
From def4582837fa546a00860649a253c47107123060 Mon Sep 17 00:00:00 2001
|
||||
From: Daniel Machon <daniel.machon@microchip.com>
|
||||
Date: Fri, 4 Oct 2024 15:19:37 +0200
|
||||
Subject: [PATCH 39/82] net: sparx5: ops out function for setting the port mux
|
||||
|
||||
Port muxing is configured based on the supported port modes. As these
|
||||
modes can differ on Sparx5 and lan969x we ops out the port muxing
|
||||
function.
|
||||
|
||||
Reviewed-by: Steen Hegelund <Steen.Hegelund@microchip.com>
|
||||
Reviewed-by: Jacob Keller <jacob.e.keller@intel.com>
|
||||
Signed-off-by: Daniel Machon <daniel.machon@microchip.com>
|
||||
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
|
||||
---
|
||||
drivers/net/ethernet/microchip/sparx5/sparx5_main.c | 1 +
|
||||
drivers/net/ethernet/microchip/sparx5/sparx5_main.h | 6 ++++++
|
||||
drivers/net/ethernet/microchip/sparx5/sparx5_port.c | 7 +++----
|
||||
3 files changed, 10 insertions(+), 4 deletions(-)
|
||||
|
||||
--- a/drivers/net/ethernet/microchip/sparx5/sparx5_main.c
|
||||
+++ b/drivers/net/ethernet/microchip/sparx5/sparx5_main.c
|
||||
@@ -991,6 +991,7 @@ static const struct sparx5_ops sparx5_op
|
||||
.get_port_dev_bit = &sparx5_port_dev_mapping,
|
||||
.get_hsch_max_group_rate = &sparx5_get_hsch_max_group_rate,
|
||||
.get_sdlb_group = &sparx5_get_sdlb_group,
|
||||
+ .set_port_mux = &sparx5_port_mux_set,
|
||||
};
|
||||
|
||||
static const struct sparx5_match_data sparx5_desc = {
|
||||
--- a/drivers/net/ethernet/microchip/sparx5/sparx5_main.h
|
||||
+++ b/drivers/net/ethernet/microchip/sparx5/sparx5_main.h
|
||||
@@ -267,6 +267,8 @@ struct sparx5_ops {
|
||||
u32 (*get_port_dev_bit)(struct sparx5 *sparx5, int port);
|
||||
u32 (*get_hsch_max_group_rate)(int grp);
|
||||
struct sparx5_sdlb_group *(*get_sdlb_group)(int idx);
|
||||
+ int (*set_port_mux)(struct sparx5 *sparx5, struct sparx5_port *port,
|
||||
+ struct sparx5_port_config *conf);
|
||||
};
|
||||
|
||||
struct sparx5_main_io_resource {
|
||||
@@ -485,6 +487,10 @@ int sparx5_pool_get(struct sparx5_pool_e
|
||||
int sparx5_pool_get_with_idx(struct sparx5_pool_entry *pool, int size, u32 idx,
|
||||
u32 *id);
|
||||
|
||||
+/* sparx5_port.c */
|
||||
+int sparx5_port_mux_set(struct sparx5 *sparx5, struct sparx5_port *port,
|
||||
+ struct sparx5_port_config *conf);
|
||||
+
|
||||
/* sparx5_sdlb.c */
|
||||
#define SPX5_SDLB_PUP_TOKEN_DISABLE 0x1FFF
|
||||
#define SPX5_SDLB_PUP_TOKEN_MAX (SPX5_SDLB_PUP_TOKEN_DISABLE - 1)
|
||||
--- a/drivers/net/ethernet/microchip/sparx5/sparx5_port.c
|
||||
+++ b/drivers/net/ethernet/microchip/sparx5/sparx5_port.c
|
||||
@@ -516,9 +516,8 @@ static int sparx5_port_fifo_sz(struct sp
|
||||
/* Configure port muxing:
|
||||
* QSGMII: 4x2G5 devices
|
||||
*/
|
||||
-static int sparx5_port_mux_set(struct sparx5 *sparx5,
|
||||
- struct sparx5_port *port,
|
||||
- struct sparx5_port_config *conf)
|
||||
+int sparx5_port_mux_set(struct sparx5 *sparx5, struct sparx5_port *port,
|
||||
+ struct sparx5_port_config *conf)
|
||||
{
|
||||
u32 portno = port->portno;
|
||||
u32 inst;
|
||||
@@ -1039,7 +1038,7 @@ int sparx5_port_init(struct sparx5 *spar
|
||||
pcsinst = spx5_inst_get(sparx5, pcs, pix);
|
||||
|
||||
/* Set the mux port mode */
|
||||
- err = sparx5_port_mux_set(sparx5, port, conf);
|
||||
+ err = ops->set_port_mux(sparx5, port, conf);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
@ -0,0 +1,56 @@
|
||||
From 6802dd4ba13b3487fb4e57dce38c53edf2ba63a2 Mon Sep 17 00:00:00 2001
|
||||
From: Daniel Machon <daniel.machon@microchip.com>
|
||||
Date: Fri, 4 Oct 2024 15:19:38 +0200
|
||||
Subject: [PATCH 40/82] net: sparx5: ops out PTP IRQ handler
|
||||
|
||||
The PTP registers are located in two different register targets on
|
||||
Sparx5 and lan969x. We can't handle this with the register macros, so
|
||||
ops out the handler.
|
||||
|
||||
Reviewed-by: Steen Hegelund <Steen.Hegelund@microchip.com>
|
||||
Reviewed-by: Jacob Keller <jacob.e.keller@intel.com>
|
||||
Signed-off-by: Daniel Machon <daniel.machon@microchip.com>
|
||||
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
|
||||
---
|
||||
drivers/net/ethernet/microchip/sparx5/sparx5_main.c | 4 +++-
|
||||
drivers/net/ethernet/microchip/sparx5/sparx5_main.h | 2 ++
|
||||
2 files changed, 5 insertions(+), 1 deletion(-)
|
||||
|
||||
--- a/drivers/net/ethernet/microchip/sparx5/sparx5_main.c
|
||||
+++ b/drivers/net/ethernet/microchip/sparx5/sparx5_main.c
|
||||
@@ -605,6 +605,7 @@ static int sparx5_start(struct sparx5 *s
|
||||
{
|
||||
u8 broadcast[ETH_ALEN] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
|
||||
const struct sparx5_consts *consts = sparx5->data->consts;
|
||||
+ const struct sparx5_ops *ops = sparx5->data->ops;
|
||||
char queue_name[32];
|
||||
u32 idx;
|
||||
int err;
|
||||
@@ -728,7 +729,7 @@ static int sparx5_start(struct sparx5 *s
|
||||
|
||||
if (sparx5->ptp_irq >= 0) {
|
||||
err = devm_request_threaded_irq(sparx5->dev, sparx5->ptp_irq,
|
||||
- NULL, sparx5_ptp_irq_handler,
|
||||
+ NULL, ops->ptp_irq_handler,
|
||||
IRQF_ONESHOT, "sparx5-ptp",
|
||||
sparx5);
|
||||
if (err)
|
||||
@@ -992,6 +993,7 @@ static const struct sparx5_ops sparx5_op
|
||||
.get_hsch_max_group_rate = &sparx5_get_hsch_max_group_rate,
|
||||
.get_sdlb_group = &sparx5_get_sdlb_group,
|
||||
.set_port_mux = &sparx5_port_mux_set,
|
||||
+ .ptp_irq_handler = &sparx5_ptp_irq_handler,
|
||||
};
|
||||
|
||||
static const struct sparx5_match_data sparx5_desc = {
|
||||
--- a/drivers/net/ethernet/microchip/sparx5/sparx5_main.h
|
||||
+++ b/drivers/net/ethernet/microchip/sparx5/sparx5_main.h
|
||||
@@ -269,6 +269,8 @@ struct sparx5_ops {
|
||||
struct sparx5_sdlb_group *(*get_sdlb_group)(int idx);
|
||||
int (*set_port_mux)(struct sparx5 *sparx5, struct sparx5_port *port,
|
||||
struct sparx5_port_config *conf);
|
||||
+
|
||||
+ irqreturn_t (*ptp_irq_handler)(int irq, void *args);
|
||||
};
|
||||
|
||||
struct sparx5_main_io_resource {
|
||||
@ -0,0 +1,137 @@
|
||||
From e8df6924d6e793aca572b8fa766779354d20adae Mon Sep 17 00:00:00 2001
|
||||
From: Daniel Machon <daniel.machon@microchip.com>
|
||||
Date: Fri, 4 Oct 2024 15:19:39 +0200
|
||||
Subject: [PATCH 41/82] net: sparx5: ops out function for DSM calendar
|
||||
calculation
|
||||
|
||||
The DSM (Disassembler) calendar grants each port access to internal
|
||||
busses. The configuration of the calendar is done differently on Sparx5
|
||||
and lan969x. Therefore ops out the function that calculates the
|
||||
calendar.
|
||||
|
||||
Reviewed-by: Steen Hegelund <Steen.Hegelund@microchip.com>
|
||||
Reviewed-by: Jacob Keller <jacob.e.keller@intel.com>
|
||||
Signed-off-by: Daniel Machon <daniel.machon@microchip.com>
|
||||
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
|
||||
---
|
||||
.../microchip/sparx5/sparx5_calendar.c | 22 ++++---------------
|
||||
.../ethernet/microchip/sparx5/sparx5_main.c | 1 +
|
||||
.../ethernet/microchip/sparx5/sparx5_main.h | 21 ++++++++++++++++++
|
||||
3 files changed, 26 insertions(+), 18 deletions(-)
|
||||
|
||||
--- a/drivers/net/ethernet/microchip/sparx5/sparx5_calendar.c
|
||||
+++ b/drivers/net/ethernet/microchip/sparx5/sparx5_calendar.c
|
||||
@@ -15,9 +15,7 @@
|
||||
#define SPX5_CALBITS_PER_PORT 3 /* Bit per port in calendar register */
|
||||
|
||||
/* DSM calendar information */
|
||||
-#define SPX5_DSM_CAL_LEN 64
|
||||
#define SPX5_DSM_CAL_EMPTY 0xFFFF
|
||||
-#define SPX5_DSM_CAL_MAX_DEVS_PER_TAXI 13
|
||||
#define SPX5_DSM_CAL_TAXIS 8
|
||||
#define SPX5_DSM_CAL_BW_LOSS 553
|
||||
|
||||
@@ -37,19 +35,6 @@ static u32 sparx5_taxi_ports[SPX5_DSM_CA
|
||||
{64, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99},
|
||||
};
|
||||
|
||||
-struct sparx5_calendar_data {
|
||||
- u32 schedule[SPX5_DSM_CAL_LEN];
|
||||
- u32 avg_dist[SPX5_DSM_CAL_MAX_DEVS_PER_TAXI];
|
||||
- u32 taxi_ports[SPX5_DSM_CAL_MAX_DEVS_PER_TAXI];
|
||||
- u32 taxi_speeds[SPX5_DSM_CAL_MAX_DEVS_PER_TAXI];
|
||||
- u32 dev_slots[SPX5_DSM_CAL_MAX_DEVS_PER_TAXI];
|
||||
- u32 new_slots[SPX5_DSM_CAL_LEN];
|
||||
- u32 temp_sched[SPX5_DSM_CAL_LEN];
|
||||
- u32 indices[SPX5_DSM_CAL_LEN];
|
||||
- u32 short_list[SPX5_DSM_CAL_LEN];
|
||||
- u32 long_list[SPX5_DSM_CAL_LEN];
|
||||
-};
|
||||
-
|
||||
static u32 sparx5_target_bandwidth(struct sparx5 *sparx5)
|
||||
{
|
||||
switch (sparx5->target_ct) {
|
||||
@@ -279,8 +264,8 @@ static u32 sparx5_dsm_cp_cal(u32 *sched)
|
||||
return SPX5_DSM_CAL_EMPTY;
|
||||
}
|
||||
|
||||
-static int sparx5_dsm_calendar_calc(struct sparx5 *sparx5, u32 taxi,
|
||||
- struct sparx5_calendar_data *data)
|
||||
+int sparx5_dsm_calendar_calc(struct sparx5 *sparx5, u32 taxi,
|
||||
+ struct sparx5_calendar_data *data)
|
||||
{
|
||||
bool slow_mode;
|
||||
u32 gcd, idx, sum, min, factor;
|
||||
@@ -566,6 +551,7 @@ update_err:
|
||||
/* Configure the DSM calendar based on port configuration */
|
||||
int sparx5_config_dsm_calendar(struct sparx5 *sparx5)
|
||||
{
|
||||
+ const struct sparx5_ops *ops = sparx5->data->ops;
|
||||
int taxi;
|
||||
struct sparx5_calendar_data *data;
|
||||
int err = 0;
|
||||
@@ -575,7 +561,7 @@ int sparx5_config_dsm_calendar(struct sp
|
||||
return -ENOMEM;
|
||||
|
||||
for (taxi = 0; taxi < sparx5->data->consts->n_dsm_cal_taxis; ++taxi) {
|
||||
- err = sparx5_dsm_calendar_calc(sparx5, taxi, data);
|
||||
+ err = ops->dsm_calendar_calc(sparx5, taxi, data);
|
||||
if (err) {
|
||||
dev_err(sparx5->dev, "DSM calendar calculation failed\n");
|
||||
goto cal_out;
|
||||
--- a/drivers/net/ethernet/microchip/sparx5/sparx5_main.c
|
||||
+++ b/drivers/net/ethernet/microchip/sparx5/sparx5_main.c
|
||||
@@ -994,6 +994,7 @@ static const struct sparx5_ops sparx5_op
|
||||
.get_sdlb_group = &sparx5_get_sdlb_group,
|
||||
.set_port_mux = &sparx5_port_mux_set,
|
||||
.ptp_irq_handler = &sparx5_ptp_irq_handler,
|
||||
+ .dsm_calendar_calc = &sparx5_dsm_calendar_calc,
|
||||
};
|
||||
|
||||
static const struct sparx5_match_data sparx5_desc = {
|
||||
--- a/drivers/net/ethernet/microchip/sparx5/sparx5_main.h
|
||||
+++ b/drivers/net/ethernet/microchip/sparx5/sparx5_main.h
|
||||
@@ -101,8 +101,24 @@ enum sparx5_vlan_port_type {
|
||||
#define IFH_PDU_TYPE_IPV4_UDP_PTP 0x6
|
||||
#define IFH_PDU_TYPE_IPV6_UDP_PTP 0x7
|
||||
|
||||
+#define SPX5_DSM_CAL_LEN 64
|
||||
+#define SPX5_DSM_CAL_MAX_DEVS_PER_TAXI 13
|
||||
+
|
||||
struct sparx5;
|
||||
|
||||
+struct sparx5_calendar_data {
|
||||
+ u32 schedule[SPX5_DSM_CAL_LEN];
|
||||
+ u32 avg_dist[SPX5_DSM_CAL_MAX_DEVS_PER_TAXI];
|
||||
+ u32 taxi_ports[SPX5_DSM_CAL_MAX_DEVS_PER_TAXI];
|
||||
+ u32 taxi_speeds[SPX5_DSM_CAL_MAX_DEVS_PER_TAXI];
|
||||
+ u32 dev_slots[SPX5_DSM_CAL_MAX_DEVS_PER_TAXI];
|
||||
+ u32 new_slots[SPX5_DSM_CAL_LEN];
|
||||
+ u32 temp_sched[SPX5_DSM_CAL_LEN];
|
||||
+ u32 indices[SPX5_DSM_CAL_LEN];
|
||||
+ u32 short_list[SPX5_DSM_CAL_LEN];
|
||||
+ u32 long_list[SPX5_DSM_CAL_LEN];
|
||||
+};
|
||||
+
|
||||
/* Frame DMA receive state:
|
||||
* For each DB, there is a SKB, and the skb data pointer is mapped in
|
||||
* the DB. Once a frame is received the skb is given to the upper layers
|
||||
@@ -271,6 +287,8 @@ struct sparx5_ops {
|
||||
struct sparx5_port_config *conf);
|
||||
|
||||
irqreturn_t (*ptp_irq_handler)(int irq, void *args);
|
||||
+ int (*dsm_calendar_calc)(struct sparx5 *sparx5, u32 taxi,
|
||||
+ struct sparx5_calendar_data *data);
|
||||
};
|
||||
|
||||
struct sparx5_main_io_resource {
|
||||
@@ -418,6 +436,9 @@ void sparx5_vlan_port_apply(struct sparx
|
||||
/* sparx5_calendar.c */
|
||||
int sparx5_config_auto_calendar(struct sparx5 *sparx5);
|
||||
int sparx5_config_dsm_calendar(struct sparx5 *sparx5);
|
||||
+int sparx5_dsm_calendar_calc(struct sparx5 *sparx5, u32 taxi,
|
||||
+ struct sparx5_calendar_data *data);
|
||||
+
|
||||
|
||||
/* sparx5_ethtool.c */
|
||||
void sparx5_get_stats64(struct net_device *ndev, struct rtnl_link_stats64 *stats);
|
||||
@ -0,0 +1,267 @@
|
||||
From 234d82beadb5fdf26dd9f469764e048f1ca4dd60 Mon Sep 17 00:00:00 2001
|
||||
From: Daniel Machon <daniel.machon@microchip.com>
|
||||
Date: Fri, 4 Oct 2024 15:19:40 +0200
|
||||
Subject: [PATCH 42/82] net: sparx5: add is_sparx5 macro and use it throughout
|
||||
|
||||
We dont want to ops out each time a function needs to do some platform
|
||||
specifics. In particular we have a few places, where it would be
|
||||
convenient to just branch out on the platform type. Add the function
|
||||
is_sparx5() and, initially, use it for:
|
||||
|
||||
- register writes that should only be done on Sparx5 (QSYS_CAL_CTRL,
|
||||
CLKGEN_LCPLL1_CORE_CLK).
|
||||
|
||||
- function calls that should only be done on Sparx5
|
||||
(ethtool_op_get_ts_info())
|
||||
|
||||
- register writes that are chip-exclusive (MASK_CFG1/2, PGID_CFG1/2,
|
||||
these are replicated for n_ports >32 on Sparx5).
|
||||
|
||||
The is_sparx5() function simply checks the target chip type, to
|
||||
determine if this is a Sparx5 SKU or not.
|
||||
|
||||
Reviewed-by: Steen Hegelund <Steen.Hegelund@microchip.com>
|
||||
Reviewed-by: Jacob Keller <jacob.e.keller@intel.com>
|
||||
Signed-off-by: Daniel Machon <daniel.machon@microchip.com>
|
||||
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
|
||||
---
|
||||
.../microchip/sparx5/sparx5_calendar.c | 7 +-
|
||||
.../microchip/sparx5/sparx5_ethtool.c | 2 +-
|
||||
.../ethernet/microchip/sparx5/sparx5_main.c | 88 ++++++++++++-------
|
||||
.../ethernet/microchip/sparx5/sparx5_main.h | 3 +
|
||||
.../ethernet/microchip/sparx5/sparx5_vlan.c | 42 ++++++---
|
||||
5 files changed, 90 insertions(+), 52 deletions(-)
|
||||
|
||||
--- a/drivers/net/ethernet/microchip/sparx5/sparx5_calendar.c
|
||||
+++ b/drivers/net/ethernet/microchip/sparx5/sparx5_calendar.c
|
||||
@@ -194,9 +194,10 @@ int sparx5_config_auto_calendar(struct s
|
||||
}
|
||||
|
||||
/* Halt the calendar while changing it */
|
||||
- spx5_rmw(QSYS_CAL_CTRL_CAL_MODE_SET(10),
|
||||
- QSYS_CAL_CTRL_CAL_MODE,
|
||||
- sparx5, QSYS_CAL_CTRL);
|
||||
+ if (is_sparx5(sparx5))
|
||||
+ spx5_rmw(QSYS_CAL_CTRL_CAL_MODE_SET(10),
|
||||
+ QSYS_CAL_CTRL_CAL_MODE,
|
||||
+ sparx5, QSYS_CAL_CTRL);
|
||||
|
||||
/* Assign port bandwidth to auto calendar */
|
||||
for (idx = 0; idx < consts->n_auto_cals; idx++)
|
||||
--- a/drivers/net/ethernet/microchip/sparx5/sparx5_ethtool.c
|
||||
+++ b/drivers/net/ethernet/microchip/sparx5/sparx5_ethtool.c
|
||||
@@ -1189,7 +1189,7 @@ static int sparx5_get_ts_info(struct net
|
||||
struct sparx5 *sparx5 = port->sparx5;
|
||||
struct sparx5_phc *phc;
|
||||
|
||||
- if (!sparx5->ptp)
|
||||
+ if (!sparx5->ptp && is_sparx5(sparx5))
|
||||
return ethtool_op_get_ts_info(dev, info);
|
||||
|
||||
phc = &sparx5->phc[SPARX5_PHC_PORT];
|
||||
--- a/drivers/net/ethernet/microchip/sparx5/sparx5_main.c
|
||||
+++ b/drivers/net/ethernet/microchip/sparx5/sparx5_main.c
|
||||
@@ -208,6 +208,25 @@ static const struct sparx5_main_io_resou
|
||||
{ TARGET_VOP, 0x11a00000, 2 }, /* 0x611a00000 */
|
||||
};
|
||||
|
||||
+bool is_sparx5(struct sparx5 *sparx5)
|
||||
+{
|
||||
+ switch (sparx5->target_ct) {
|
||||
+ case SPX5_TARGET_CT_7546:
|
||||
+ case SPX5_TARGET_CT_7549:
|
||||
+ case SPX5_TARGET_CT_7552:
|
||||
+ case SPX5_TARGET_CT_7556:
|
||||
+ case SPX5_TARGET_CT_7558:
|
||||
+ case SPX5_TARGET_CT_7546TSN:
|
||||
+ case SPX5_TARGET_CT_7549TSN:
|
||||
+ case SPX5_TARGET_CT_7552TSN:
|
||||
+ case SPX5_TARGET_CT_7556TSN:
|
||||
+ case SPX5_TARGET_CT_7558TSN:
|
||||
+ return true;
|
||||
+ default:
|
||||
+ return false;
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
static int sparx5_create_targets(struct sparx5 *sparx5)
|
||||
{
|
||||
const struct sparx5_main_io_resource *iomap = sparx5->data->iomap;
|
||||
@@ -462,44 +481,45 @@ static int sparx5_init_coreclock(struct
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
- switch (freq) {
|
||||
- case SPX5_CORE_CLOCK_250MHZ:
|
||||
- clk_div = 10;
|
||||
- pol_upd_int = 312;
|
||||
- break;
|
||||
- case SPX5_CORE_CLOCK_500MHZ:
|
||||
- clk_div = 5;
|
||||
- pol_upd_int = 624;
|
||||
- break;
|
||||
- case SPX5_CORE_CLOCK_625MHZ:
|
||||
- clk_div = 4;
|
||||
- pol_upd_int = 780;
|
||||
- break;
|
||||
- default:
|
||||
- dev_err(sparx5->dev, "%d coreclock not supported on (%#04x)\n",
|
||||
- sparx5->coreclock, sparx5->target_ct);
|
||||
- return -EINVAL;
|
||||
+ if (is_sparx5(sparx5)) {
|
||||
+ switch (freq) {
|
||||
+ case SPX5_CORE_CLOCK_250MHZ:
|
||||
+ clk_div = 10;
|
||||
+ pol_upd_int = 312;
|
||||
+ break;
|
||||
+ case SPX5_CORE_CLOCK_500MHZ:
|
||||
+ clk_div = 5;
|
||||
+ pol_upd_int = 624;
|
||||
+ break;
|
||||
+ case SPX5_CORE_CLOCK_625MHZ:
|
||||
+ clk_div = 4;
|
||||
+ pol_upd_int = 780;
|
||||
+ break;
|
||||
+ default:
|
||||
+ dev_err(sparx5->dev,
|
||||
+ "%d coreclock not supported on (%#04x)\n",
|
||||
+ sparx5->coreclock, sparx5->target_ct);
|
||||
+ return -EINVAL;
|
||||
+ }
|
||||
+
|
||||
+ /* Configure the LCPLL */
|
||||
+ spx5_rmw(CLKGEN_LCPLL1_CORE_CLK_CFG_CORE_CLK_DIV_SET(clk_div) |
|
||||
+ CLKGEN_LCPLL1_CORE_CLK_CFG_CORE_PRE_DIV_SET(0) |
|
||||
+ CLKGEN_LCPLL1_CORE_CLK_CFG_CORE_ROT_DIR_SET(0) |
|
||||
+ CLKGEN_LCPLL1_CORE_CLK_CFG_CORE_ROT_SEL_SET(0) |
|
||||
+ CLKGEN_LCPLL1_CORE_CLK_CFG_CORE_ROT_ENA_SET(0) |
|
||||
+ CLKGEN_LCPLL1_CORE_CLK_CFG_CORE_CLK_ENA_SET(1),
|
||||
+ CLKGEN_LCPLL1_CORE_CLK_CFG_CORE_CLK_DIV |
|
||||
+ CLKGEN_LCPLL1_CORE_CLK_CFG_CORE_PRE_DIV |
|
||||
+ CLKGEN_LCPLL1_CORE_CLK_CFG_CORE_ROT_DIR |
|
||||
+ CLKGEN_LCPLL1_CORE_CLK_CFG_CORE_ROT_SEL |
|
||||
+ CLKGEN_LCPLL1_CORE_CLK_CFG_CORE_ROT_ENA |
|
||||
+ CLKGEN_LCPLL1_CORE_CLK_CFG_CORE_CLK_ENA,
|
||||
+ sparx5, CLKGEN_LCPLL1_CORE_CLK_CFG);
|
||||
}
|
||||
|
||||
/* Update state with chosen frequency */
|
||||
sparx5->coreclock = freq;
|
||||
-
|
||||
- /* Configure the LCPLL */
|
||||
- spx5_rmw(CLKGEN_LCPLL1_CORE_CLK_CFG_CORE_CLK_DIV_SET(clk_div) |
|
||||
- CLKGEN_LCPLL1_CORE_CLK_CFG_CORE_PRE_DIV_SET(0) |
|
||||
- CLKGEN_LCPLL1_CORE_CLK_CFG_CORE_ROT_DIR_SET(0) |
|
||||
- CLKGEN_LCPLL1_CORE_CLK_CFG_CORE_ROT_SEL_SET(0) |
|
||||
- CLKGEN_LCPLL1_CORE_CLK_CFG_CORE_ROT_ENA_SET(0) |
|
||||
- CLKGEN_LCPLL1_CORE_CLK_CFG_CORE_CLK_ENA_SET(1),
|
||||
- CLKGEN_LCPLL1_CORE_CLK_CFG_CORE_CLK_DIV |
|
||||
- CLKGEN_LCPLL1_CORE_CLK_CFG_CORE_PRE_DIV |
|
||||
- CLKGEN_LCPLL1_CORE_CLK_CFG_CORE_ROT_DIR |
|
||||
- CLKGEN_LCPLL1_CORE_CLK_CFG_CORE_ROT_SEL |
|
||||
- CLKGEN_LCPLL1_CORE_CLK_CFG_CORE_ROT_ENA |
|
||||
- CLKGEN_LCPLL1_CORE_CLK_CFG_CORE_CLK_ENA,
|
||||
- sparx5,
|
||||
- CLKGEN_LCPLL1_CORE_CLK_CFG);
|
||||
-
|
||||
clk_period = sparx5_clk_period(freq);
|
||||
|
||||
spx5_rmw(HSCH_SYS_CLK_PER_100PS_SET(clk_period / 100),
|
||||
--- a/drivers/net/ethernet/microchip/sparx5/sparx5_main.h
|
||||
+++ b/drivers/net/ethernet/microchip/sparx5/sparx5_main.h
|
||||
@@ -376,6 +376,9 @@ struct sparx5 {
|
||||
const struct sparx5_match_data *data;
|
||||
};
|
||||
|
||||
+/* sparx5_main.c */
|
||||
+bool is_sparx5(struct sparx5 *sparx5);
|
||||
+
|
||||
/* sparx5_switchdev.c */
|
||||
int sparx5_register_notifier_blocks(struct sparx5 *sparx5);
|
||||
void sparx5_unregister_notifier_blocks(struct sparx5 *sparx5);
|
||||
--- a/drivers/net/ethernet/microchip/sparx5/sparx5_vlan.c
|
||||
+++ b/drivers/net/ethernet/microchip/sparx5/sparx5_vlan.c
|
||||
@@ -16,8 +16,10 @@ static int sparx5_vlant_set_mask(struct
|
||||
|
||||
/* Output mask to respective registers */
|
||||
spx5_wr(mask[0], sparx5, ANA_L3_VLAN_MASK_CFG(vid));
|
||||
- spx5_wr(mask[1], sparx5, ANA_L3_VLAN_MASK_CFG1(vid));
|
||||
- spx5_wr(mask[2], sparx5, ANA_L3_VLAN_MASK_CFG2(vid));
|
||||
+ if (is_sparx5(sparx5)) {
|
||||
+ spx5_wr(mask[1], sparx5, ANA_L3_VLAN_MASK_CFG1(vid));
|
||||
+ spx5_wr(mask[2], sparx5, ANA_L3_VLAN_MASK_CFG2(vid));
|
||||
+ }
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -141,15 +143,19 @@ void sparx5_pgid_update_mask(struct spar
|
||||
void sparx5_pgid_clear(struct sparx5 *spx5, int pgid)
|
||||
{
|
||||
spx5_wr(0, spx5, ANA_AC_PGID_CFG(pgid));
|
||||
- spx5_wr(0, spx5, ANA_AC_PGID_CFG1(pgid));
|
||||
- spx5_wr(0, spx5, ANA_AC_PGID_CFG2(pgid));
|
||||
+ if (is_sparx5(spx5)) {
|
||||
+ spx5_wr(0, spx5, ANA_AC_PGID_CFG1(pgid));
|
||||
+ spx5_wr(0, spx5, ANA_AC_PGID_CFG2(pgid));
|
||||
+ }
|
||||
}
|
||||
|
||||
void sparx5_pgid_read_mask(struct sparx5 *spx5, int pgid, u32 portmask[3])
|
||||
{
|
||||
portmask[0] = spx5_rd(spx5, ANA_AC_PGID_CFG(pgid));
|
||||
- portmask[1] = spx5_rd(spx5, ANA_AC_PGID_CFG1(pgid));
|
||||
- portmask[2] = spx5_rd(spx5, ANA_AC_PGID_CFG2(pgid));
|
||||
+ if (is_sparx5(spx5)) {
|
||||
+ portmask[1] = spx5_rd(spx5, ANA_AC_PGID_CFG1(pgid));
|
||||
+ portmask[2] = spx5_rd(spx5, ANA_AC_PGID_CFG2(pgid));
|
||||
+ }
|
||||
}
|
||||
|
||||
void sparx5_update_fwd(struct sparx5 *sparx5)
|
||||
@@ -164,8 +170,10 @@ void sparx5_update_fwd(struct sparx5 *sp
|
||||
/* Update flood masks */
|
||||
for (port = PGID_UC_FLOOD; port <= PGID_BCAST; port++) {
|
||||
spx5_wr(mask[0], sparx5, ANA_AC_PGID_CFG(port));
|
||||
- spx5_wr(mask[1], sparx5, ANA_AC_PGID_CFG1(port));
|
||||
- spx5_wr(mask[2], sparx5, ANA_AC_PGID_CFG2(port));
|
||||
+ if (is_sparx5(sparx5)) {
|
||||
+ spx5_wr(mask[1], sparx5, ANA_AC_PGID_CFG1(port));
|
||||
+ spx5_wr(mask[2], sparx5, ANA_AC_PGID_CFG2(port));
|
||||
+ }
|
||||
}
|
||||
|
||||
/* Update SRC masks */
|
||||
@@ -176,12 +184,16 @@ void sparx5_update_fwd(struct sparx5 *sp
|
||||
clear_bit(port, workmask);
|
||||
bitmap_to_arr32(mask, workmask, SPX5_PORTS);
|
||||
spx5_wr(mask[0], sparx5, ANA_AC_SRC_CFG(port));
|
||||
- spx5_wr(mask[1], sparx5, ANA_AC_SRC_CFG1(port));
|
||||
- spx5_wr(mask[2], sparx5, ANA_AC_SRC_CFG2(port));
|
||||
+ if (is_sparx5(sparx5)) {
|
||||
+ spx5_wr(mask[1], sparx5, ANA_AC_SRC_CFG1(port));
|
||||
+ spx5_wr(mask[2], sparx5, ANA_AC_SRC_CFG2(port));
|
||||
+ }
|
||||
} else {
|
||||
spx5_wr(0, sparx5, ANA_AC_SRC_CFG(port));
|
||||
- spx5_wr(0, sparx5, ANA_AC_SRC_CFG1(port));
|
||||
- spx5_wr(0, sparx5, ANA_AC_SRC_CFG2(port));
|
||||
+ if (is_sparx5(sparx5)) {
|
||||
+ spx5_wr(0, sparx5, ANA_AC_SRC_CFG1(port));
|
||||
+ spx5_wr(0, sparx5, ANA_AC_SRC_CFG2(port));
|
||||
+ }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -192,8 +204,10 @@ void sparx5_update_fwd(struct sparx5 *sp
|
||||
|
||||
/* Apply learning mask */
|
||||
spx5_wr(mask[0], sparx5, ANA_L2_AUTO_LRN_CFG);
|
||||
- spx5_wr(mask[1], sparx5, ANA_L2_AUTO_LRN_CFG1);
|
||||
- spx5_wr(mask[2], sparx5, ANA_L2_AUTO_LRN_CFG2);
|
||||
+ if (is_sparx5(sparx5)) {
|
||||
+ spx5_wr(mask[1], sparx5, ANA_L2_AUTO_LRN_CFG1);
|
||||
+ spx5_wr(mask[2], sparx5, ANA_L2_AUTO_LRN_CFG2);
|
||||
+ }
|
||||
}
|
||||
|
||||
void sparx5_vlan_port_apply(struct sparx5 *sparx5,
|
||||
@ -0,0 +1,351 @@
|
||||
From 976b85797451b92683f78af10334ceda13d5f1e0 Mon Sep 17 00:00:00 2001
|
||||
From: Daniel Machon <daniel.machon@microchip.com>
|
||||
Date: Fri, 4 Oct 2024 15:19:41 +0200
|
||||
Subject: [PATCH 43/82] net: sparx5: redefine internal ports and PGID's as
|
||||
offsets
|
||||
|
||||
Internal ports and PGID's are both defined relative to the number of
|
||||
front ports on Sparx5. This will not work on lan969x. Instead make them
|
||||
offsets to the number of front ports and add two helpers to retrieve
|
||||
them. Use the helpers throughout.
|
||||
|
||||
Reviewed-by: Steen Hegelund <Steen.Hegelund@microchip.com>
|
||||
Signed-off-by: Daniel Machon <daniel.machon@microchip.com>
|
||||
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
|
||||
---
|
||||
.../microchip/sparx5/sparx5_calendar.c | 14 +++++---
|
||||
.../ethernet/microchip/sparx5/sparx5_fdma.c | 4 ++-
|
||||
.../microchip/sparx5/sparx5_mactable.c | 3 +-
|
||||
.../ethernet/microchip/sparx5/sparx5_main.c | 14 ++++----
|
||||
.../ethernet/microchip/sparx5/sparx5_main.h | 34 +++++++++----------
|
||||
.../ethernet/microchip/sparx5/sparx5_netdev.c | 6 ++--
|
||||
.../ethernet/microchip/sparx5/sparx5_packet.c | 4 ++-
|
||||
.../ethernet/microchip/sparx5/sparx5_pgid.c | 13 +++++--
|
||||
.../ethernet/microchip/sparx5/sparx5_port.c | 5 +++
|
||||
.../microchip/sparx5/sparx5_switchdev.c | 31 ++++++++++++-----
|
||||
.../ethernet/microchip/sparx5/sparx5_vlan.c | 3 +-
|
||||
11 files changed, 86 insertions(+), 45 deletions(-)
|
||||
|
||||
--- a/drivers/net/ethernet/microchip/sparx5/sparx5_calendar.c
|
||||
+++ b/drivers/net/ethernet/microchip/sparx5/sparx5_calendar.c
|
||||
@@ -118,16 +118,22 @@ static enum sparx5_cal_bw sparx5_get_por
|
||||
|
||||
if (portno >= sparx5->data->consts->n_ports) {
|
||||
/* Internal ports */
|
||||
- if (portno == SPX5_PORT_CPU_0 || portno == SPX5_PORT_CPU_1) {
|
||||
+ if (portno ==
|
||||
+ sparx5_get_internal_port(sparx5, SPX5_PORT_CPU_0) ||
|
||||
+ portno ==
|
||||
+ sparx5_get_internal_port(sparx5, SPX5_PORT_CPU_1)) {
|
||||
/* Equals 1.25G */
|
||||
return SPX5_CAL_SPEED_2G5;
|
||||
- } else if (portno == SPX5_PORT_VD0) {
|
||||
+ } else if (portno ==
|
||||
+ sparx5_get_internal_port(sparx5, SPX5_PORT_VD0)) {
|
||||
/* IPMC only idle BW */
|
||||
return SPX5_CAL_SPEED_NONE;
|
||||
- } else if (portno == SPX5_PORT_VD1) {
|
||||
+ } else if (portno ==
|
||||
+ sparx5_get_internal_port(sparx5, SPX5_PORT_VD1)) {
|
||||
/* OAM only idle BW */
|
||||
return SPX5_CAL_SPEED_NONE;
|
||||
- } else if (portno == SPX5_PORT_VD2) {
|
||||
+ } else if (portno ==
|
||||
+ sparx5_get_internal_port(sparx5, SPX5_PORT_VD2)) {
|
||||
/* IPinIP gets only idle BW */
|
||||
return SPX5_CAL_SPEED_NONE;
|
||||
}
|
||||
--- a/drivers/net/ethernet/microchip/sparx5/sparx5_fdma.c
|
||||
+++ b/drivers/net/ethernet/microchip/sparx5/sparx5_fdma.c
|
||||
@@ -364,7 +364,9 @@ static void sparx5_fdma_injection_mode(s
|
||||
sparx5, QS_INJ_GRP_CFG(INJ_QUEUE));
|
||||
|
||||
/* CPU ports capture setup */
|
||||
- for (portno = SPX5_PORT_CPU_0; portno <= SPX5_PORT_CPU_1; portno++) {
|
||||
+ for (portno = sparx5_get_internal_port(sparx5, SPX5_PORT_CPU_0);
|
||||
+ portno <= sparx5_get_internal_port(sparx5, SPX5_PORT_CPU_1);
|
||||
+ portno++) {
|
||||
/* ASM CPU port: No preamble, IFH, enable padding */
|
||||
spx5_wr(ASM_PORT_CFG_PAD_ENA_SET(1) |
|
||||
ASM_PORT_CFG_NO_PREAMBLE_ENA_SET(1) |
|
||||
--- a/drivers/net/ethernet/microchip/sparx5/sparx5_mactable.c
|
||||
+++ b/drivers/net/ethernet/microchip/sparx5/sparx5_mactable.c
|
||||
@@ -129,7 +129,8 @@ int sparx5_mc_sync(struct net_device *de
|
||||
struct sparx5_port *port = netdev_priv(dev);
|
||||
struct sparx5 *sparx5 = port->sparx5;
|
||||
|
||||
- return sparx5_mact_learn(sparx5, PGID_CPU, addr, port->pvid);
|
||||
+ return sparx5_mact_learn(sparx5, sparx5_get_pgid(sparx5, PGID_CPU),
|
||||
+ addr, port->pvid);
|
||||
}
|
||||
|
||||
static int sparx5_mact_get(struct sparx5 *sparx5,
|
||||
--- a/drivers/net/ethernet/microchip/sparx5/sparx5_main.c
|
||||
+++ b/drivers/net/ethernet/microchip/sparx5/sparx5_main.c
|
||||
@@ -649,13 +649,14 @@ static int sparx5_start(struct sparx5 *s
|
||||
sparx5_update_fwd(sparx5);
|
||||
|
||||
/* CPU copy CPU pgids */
|
||||
- spx5_wr(ANA_AC_PGID_MISC_CFG_PGID_CPU_COPY_ENA_SET(1),
|
||||
- sparx5, ANA_AC_PGID_MISC_CFG(PGID_CPU));
|
||||
- spx5_wr(ANA_AC_PGID_MISC_CFG_PGID_CPU_COPY_ENA_SET(1),
|
||||
- sparx5, ANA_AC_PGID_MISC_CFG(PGID_BCAST));
|
||||
+ spx5_wr(ANA_AC_PGID_MISC_CFG_PGID_CPU_COPY_ENA_SET(1), sparx5,
|
||||
+ ANA_AC_PGID_MISC_CFG(sparx5_get_pgid(sparx5, PGID_CPU)));
|
||||
+ spx5_wr(ANA_AC_PGID_MISC_CFG_PGID_CPU_COPY_ENA_SET(1), sparx5,
|
||||
+ ANA_AC_PGID_MISC_CFG(sparx5_get_pgid(sparx5, PGID_BCAST)));
|
||||
|
||||
/* Recalc injected frame FCS */
|
||||
- for (idx = SPX5_PORT_CPU_0; idx <= SPX5_PORT_CPU_1; idx++)
|
||||
+ for (idx = sparx5_get_internal_port(sparx5, SPX5_PORT_CPU_0);
|
||||
+ idx <= sparx5_get_internal_port(sparx5, SPX5_PORT_CPU_1); idx++)
|
||||
spx5_rmw(ANA_CL_FILTER_CTRL_FORCE_FCS_UPDATE_ENA_SET(1),
|
||||
ANA_CL_FILTER_CTRL_FORCE_FCS_UPDATE_ENA,
|
||||
sparx5, ANA_CL_FILTER_CTRL(idx));
|
||||
@@ -670,7 +671,8 @@ static int sparx5_start(struct sparx5 *s
|
||||
sparx5_vlan_init(sparx5);
|
||||
|
||||
/* Add host mode BC address (points only to CPU) */
|
||||
- sparx5_mact_learn(sparx5, PGID_CPU, broadcast, NULL_VID);
|
||||
+ sparx5_mact_learn(sparx5, sparx5_get_pgid(sparx5, PGID_CPU), broadcast,
|
||||
+ NULL_VID);
|
||||
|
||||
/* Enable queue limitation watermarks */
|
||||
sparx5_qlim_set(sparx5);
|
||||
--- a/drivers/net/ethernet/microchip/sparx5/sparx5_main.h
|
||||
+++ b/drivers/net/ethernet/microchip/sparx5/sparx5_main.h
|
||||
@@ -54,23 +54,21 @@ enum sparx5_vlan_port_type {
|
||||
#define SPX5_PORTS 65
|
||||
#define SPX5_PORTS_ALL 70 /* Total number of ports */
|
||||
|
||||
-#define SPX5_PORT_CPU (SPX5_PORTS) /* Next port is CPU port */
|
||||
-#define SPX5_PORT_CPU_0 (SPX5_PORT_CPU + 0) /* CPU Port 65 */
|
||||
-#define SPX5_PORT_CPU_1 (SPX5_PORT_CPU + 1) /* CPU Port 66 */
|
||||
-#define SPX5_PORT_VD0 (SPX5_PORT_CPU + 2) /* VD0/Port 67 used for IPMC */
|
||||
-#define SPX5_PORT_VD1 (SPX5_PORT_CPU + 3) /* VD1/Port 68 used for AFI/OAM */
|
||||
-#define SPX5_PORT_VD2 (SPX5_PORT_CPU + 4) /* VD2/Port 69 used for IPinIP*/
|
||||
-
|
||||
-#define PGID_BASE SPX5_PORTS /* Starts after port PGIDs */
|
||||
-#define PGID_UC_FLOOD (PGID_BASE + 0)
|
||||
-#define PGID_MC_FLOOD (PGID_BASE + 1)
|
||||
-#define PGID_IPV4_MC_DATA (PGID_BASE + 2)
|
||||
-#define PGID_IPV4_MC_CTRL (PGID_BASE + 3)
|
||||
-#define PGID_IPV6_MC_DATA (PGID_BASE + 4)
|
||||
-#define PGID_IPV6_MC_CTRL (PGID_BASE + 5)
|
||||
-#define PGID_BCAST (PGID_BASE + 6)
|
||||
-#define PGID_CPU (PGID_BASE + 7)
|
||||
-#define PGID_MCAST_START (PGID_BASE + 8)
|
||||
+#define SPX5_PORT_CPU_0 0 /* CPU Port 0 */
|
||||
+#define SPX5_PORT_CPU_1 1 /* CPU Port 1 */
|
||||
+#define SPX5_PORT_VD0 2 /* VD0/Port used for IPMC */
|
||||
+#define SPX5_PORT_VD1 3 /* VD1/Port used for AFI/OAM */
|
||||
+#define SPX5_PORT_VD2 4 /* VD2/Port used for IPinIP*/
|
||||
+
|
||||
+#define PGID_UC_FLOOD 0
|
||||
+#define PGID_MC_FLOOD 1
|
||||
+#define PGID_IPV4_MC_DATA 2
|
||||
+#define PGID_IPV4_MC_CTRL 3
|
||||
+#define PGID_IPV6_MC_DATA 4
|
||||
+#define PGID_IPV6_MC_CTRL 5
|
||||
+#define PGID_BCAST 6
|
||||
+#define PGID_CPU 7
|
||||
+#define PGID_MCAST_START 8
|
||||
|
||||
#define PGID_TABLE_SIZE 3290
|
||||
|
||||
@@ -500,6 +498,7 @@ enum sparx5_pgid_type {
|
||||
void sparx5_pgid_init(struct sparx5 *spx5);
|
||||
int sparx5_pgid_alloc_mcast(struct sparx5 *spx5, u16 *idx);
|
||||
int sparx5_pgid_free(struct sparx5 *spx5, u16 idx);
|
||||
+int sparx5_get_pgid(struct sparx5 *sparx5, int pgid);
|
||||
|
||||
/* sparx5_pool.c */
|
||||
struct sparx5_pool_entry {
|
||||
@@ -516,6 +515,7 @@ int sparx5_pool_get_with_idx(struct spar
|
||||
/* sparx5_port.c */
|
||||
int sparx5_port_mux_set(struct sparx5 *sparx5, struct sparx5_port *port,
|
||||
struct sparx5_port_config *conf);
|
||||
+int sparx5_get_internal_port(struct sparx5 *sparx5, int port);
|
||||
|
||||
/* sparx5_sdlb.c */
|
||||
#define SPX5_SDLB_PUP_TOKEN_DISABLE 0x1FFF
|
||||
--- a/drivers/net/ethernet/microchip/sparx5/sparx5_netdev.c
|
||||
+++ b/drivers/net/ethernet/microchip/sparx5/sparx5_netdev.c
|
||||
@@ -68,7 +68,8 @@ void sparx5_set_port_ifh(struct sparx5 *
|
||||
/* MISC.PIPELINE_ACT */
|
||||
ifh_encode_bitfield(ifh_hdr, 1, 42, 3);
|
||||
/* FWD.SRC_PORT = CPU */
|
||||
- ifh_encode_bitfield(ifh_hdr, SPX5_PORT_CPU, 46, 7);
|
||||
+ ifh_encode_bitfield(ifh_hdr, sparx5_get_pgid(sparx5, SPX5_PORT_CPU_0),
|
||||
+ 46, 7);
|
||||
/* FWD.SFLOW_ID (disable SFlow sampling) */
|
||||
ifh_encode_bitfield(ifh_hdr, 124, 57, 7);
|
||||
/* FWD.UPDATE_FCS = Enable. Enforce update of FCS. */
|
||||
@@ -190,7 +191,8 @@ static int sparx5_set_mac_address(struct
|
||||
sparx5_mact_forget(sparx5, dev->dev_addr, port->pvid);
|
||||
|
||||
/* Add new */
|
||||
- sparx5_mact_learn(sparx5, PGID_CPU, addr->sa_data, port->pvid);
|
||||
+ sparx5_mact_learn(sparx5, sparx5_get_pgid(sparx5, PGID_CPU),
|
||||
+ addr->sa_data, port->pvid);
|
||||
|
||||
/* Record the address */
|
||||
eth_hw_addr_set(dev, addr->sa_data);
|
||||
--- a/drivers/net/ethernet/microchip/sparx5/sparx5_packet.c
|
||||
+++ b/drivers/net/ethernet/microchip/sparx5/sparx5_packet.c
|
||||
@@ -317,7 +317,9 @@ int sparx5_manual_injection_mode(struct
|
||||
sparx5, QS_INJ_GRP_CFG(INJ_QUEUE));
|
||||
|
||||
/* CPU ports capture setup */
|
||||
- for (portno = SPX5_PORT_CPU_0; portno <= SPX5_PORT_CPU_1; portno++) {
|
||||
+ for (portno = sparx5_get_internal_port(sparx5, SPX5_PORT_CPU_0);
|
||||
+ portno <= sparx5_get_internal_port(sparx5, SPX5_PORT_CPU_1);
|
||||
+ portno++) {
|
||||
/* ASM CPU port: No preamble, IFH, enable padding */
|
||||
spx5_wr(ASM_PORT_CFG_PAD_ENA_SET(1) |
|
||||
ASM_PORT_CFG_NO_PREAMBLE_ENA_SET(1) |
|
||||
--- a/drivers/net/ethernet/microchip/sparx5/sparx5_pgid.c
|
||||
+++ b/drivers/net/ethernet/microchip/sparx5/sparx5_pgid.c
|
||||
@@ -11,7 +11,7 @@ void sparx5_pgid_init(struct sparx5 *spx
|
||||
/* Reserved for unicast, flood control, broadcast, and CPU.
|
||||
* These cannot be freed.
|
||||
*/
|
||||
- for (i = 0; i <= PGID_CPU; i++)
|
||||
+ for (i = 0; i <= sparx5_get_pgid(spx5, PGID_CPU); i++)
|
||||
spx5->pgid_map[i] = SPX5_PGID_RESERVED;
|
||||
}
|
||||
|
||||
@@ -22,7 +22,8 @@ int sparx5_pgid_alloc_mcast(struct sparx
|
||||
/* The multicast area starts at index 65, but the first 7
|
||||
* are reserved for flood masks and CPU. Start alloc after that.
|
||||
*/
|
||||
- for (i = PGID_MCAST_START; i < spx5->data->consts->n_pgids; i++) {
|
||||
+ for (i = sparx5_get_pgid(spx5, PGID_MCAST_START);
|
||||
+ i < spx5->data->consts->n_pgids; i++) {
|
||||
if (spx5->pgid_map[i] == SPX5_PGID_FREE) {
|
||||
spx5->pgid_map[i] = SPX5_PGID_MULTICAST;
|
||||
*idx = i;
|
||||
@@ -35,7 +36,8 @@ int sparx5_pgid_alloc_mcast(struct sparx
|
||||
|
||||
int sparx5_pgid_free(struct sparx5 *spx5, u16 idx)
|
||||
{
|
||||
- if (idx <= PGID_CPU || idx >= spx5->data->consts->n_pgids)
|
||||
+ if (idx <= sparx5_get_pgid(spx5, PGID_CPU) ||
|
||||
+ idx >= spx5->data->consts->n_pgids)
|
||||
return -EINVAL;
|
||||
|
||||
if (spx5->pgid_map[idx] == SPX5_PGID_FREE)
|
||||
@@ -44,3 +46,8 @@ int sparx5_pgid_free(struct sparx5 *spx5
|
||||
spx5->pgid_map[idx] = SPX5_PGID_FREE;
|
||||
return 0;
|
||||
}
|
||||
+
|
||||
+int sparx5_get_pgid(struct sparx5 *sparx5, int pgid)
|
||||
+{
|
||||
+ return sparx5->data->consts->n_ports + pgid;
|
||||
+}
|
||||
--- a/drivers/net/ethernet/microchip/sparx5/sparx5_port.c
|
||||
+++ b/drivers/net/ethernet/microchip/sparx5/sparx5_port.c
|
||||
@@ -1352,3 +1352,8 @@ int sparx5_port_qos_default_set(const st
|
||||
|
||||
return 0;
|
||||
}
|
||||
+
|
||||
+int sparx5_get_internal_port(struct sparx5 *sparx5, int port)
|
||||
+{
|
||||
+ return sparx5->data->consts->n_ports + port;
|
||||
+}
|
||||
--- a/drivers/net/ethernet/microchip/sparx5/sparx5_switchdev.c
|
||||
+++ b/drivers/net/ethernet/microchip/sparx5/sparx5_switchdev.c
|
||||
@@ -32,24 +32,34 @@ static int sparx5_port_attr_pre_bridge_f
|
||||
static void sparx5_port_update_mcast_ip_flood(struct sparx5_port *port, bool flood_flag)
|
||||
{
|
||||
bool should_flood = flood_flag || port->is_mrouter;
|
||||
+ struct sparx5 *sparx5 = port->sparx5;
|
||||
int pgid;
|
||||
|
||||
- for (pgid = PGID_IPV4_MC_DATA; pgid <= PGID_IPV6_MC_CTRL; pgid++)
|
||||
+ for (pgid = sparx5_get_pgid(sparx5, PGID_IPV4_MC_DATA);
|
||||
+ pgid <= sparx5_get_pgid(sparx5, PGID_IPV6_MC_CTRL); pgid++)
|
||||
sparx5_pgid_update_mask(port, pgid, should_flood);
|
||||
}
|
||||
|
||||
static void sparx5_port_attr_bridge_flags(struct sparx5_port *port,
|
||||
struct switchdev_brport_flags flags)
|
||||
{
|
||||
+ struct sparx5 *sparx5 = port->sparx5;
|
||||
+
|
||||
if (flags.mask & BR_MCAST_FLOOD) {
|
||||
- sparx5_pgid_update_mask(port, PGID_MC_FLOOD, !!(flags.val & BR_MCAST_FLOOD));
|
||||
+ sparx5_pgid_update_mask(port,
|
||||
+ sparx5_get_pgid(sparx5, PGID_MC_FLOOD),
|
||||
+ !!(flags.val & BR_MCAST_FLOOD));
|
||||
sparx5_port_update_mcast_ip_flood(port, !!(flags.val & BR_MCAST_FLOOD));
|
||||
}
|
||||
|
||||
if (flags.mask & BR_FLOOD)
|
||||
- sparx5_pgid_update_mask(port, PGID_UC_FLOOD, !!(flags.val & BR_FLOOD));
|
||||
+ sparx5_pgid_update_mask(port,
|
||||
+ sparx5_get_pgid(sparx5, PGID_UC_FLOOD),
|
||||
+ !!(flags.val & BR_FLOOD));
|
||||
if (flags.mask & BR_BCAST_FLOOD)
|
||||
- sparx5_pgid_update_mask(port, PGID_BCAST, !!(flags.val & BR_BCAST_FLOOD));
|
||||
+ sparx5_pgid_update_mask(port,
|
||||
+ sparx5_get_pgid(sparx5, PGID_BCAST),
|
||||
+ !!(flags.val & BR_BCAST_FLOOD));
|
||||
}
|
||||
|
||||
static void sparx5_attr_stp_state_set(struct sparx5_port *port,
|
||||
@@ -219,7 +229,8 @@ static void sparx5_port_bridge_leave(str
|
||||
port->vid = NULL_VID;
|
||||
|
||||
/* Forward frames to CPU */
|
||||
- sparx5_mact_learn(sparx5, PGID_CPU, port->ndev->dev_addr, 0);
|
||||
+ sparx5_mact_learn(sparx5, sparx5_get_pgid(sparx5, PGID_CPU),
|
||||
+ port->ndev->dev_addr, 0);
|
||||
|
||||
/* Port enters in host more therefore restore mc list */
|
||||
__dev_mc_sync(port->ndev, sparx5_mc_sync, sparx5_mc_unsync);
|
||||
@@ -254,7 +265,8 @@ static int sparx5_port_add_addr(struct n
|
||||
u16 vid = port->pvid;
|
||||
|
||||
if (up)
|
||||
- sparx5_mact_learn(sparx5, PGID_CPU, port->ndev->dev_addr, vid);
|
||||
+ sparx5_mact_learn(sparx5, sparx5_get_pgid(sparx5, PGID_CPU),
|
||||
+ port->ndev->dev_addr, vid);
|
||||
else
|
||||
sparx5_mact_forget(sparx5, port->ndev->dev_addr, vid);
|
||||
|
||||
@@ -330,7 +342,8 @@ static void sparx5_switchdev_bridge_fdb_
|
||||
switch (switchdev_work->event) {
|
||||
case SWITCHDEV_FDB_ADD_TO_DEVICE:
|
||||
if (host_addr)
|
||||
- sparx5_add_mact_entry(sparx5, dev, PGID_CPU,
|
||||
+ sparx5_add_mact_entry(sparx5, dev,
|
||||
+ sparx5_get_pgid(sparx5, PGID_CPU),
|
||||
fdb_info->addr, vid);
|
||||
else
|
||||
sparx5_add_mact_entry(sparx5, port->ndev, port->portno,
|
||||
@@ -418,8 +431,8 @@ static int sparx5_handle_port_vlan_add(s
|
||||
switchdev_blocking_nb);
|
||||
|
||||
/* Flood broadcast to CPU */
|
||||
- sparx5_mact_learn(sparx5, PGID_BCAST, dev->broadcast,
|
||||
- v->vid);
|
||||
+ sparx5_mact_learn(sparx5, sparx5_get_pgid(sparx5, PGID_BCAST),
|
||||
+ dev->broadcast, v->vid);
|
||||
return 0;
|
||||
}
|
||||
|
||||
--- a/drivers/net/ethernet/microchip/sparx5/sparx5_vlan.c
|
||||
+++ b/drivers/net/ethernet/microchip/sparx5/sparx5_vlan.c
|
||||
@@ -168,7 +168,8 @@ void sparx5_update_fwd(struct sparx5 *sp
|
||||
bitmap_to_arr32(mask, sparx5->bridge_fwd_mask, SPX5_PORTS);
|
||||
|
||||
/* Update flood masks */
|
||||
- for (port = PGID_UC_FLOOD; port <= PGID_BCAST; port++) {
|
||||
+ for (port = sparx5_get_pgid(sparx5, PGID_UC_FLOOD);
|
||||
+ port <= sparx5_get_pgid(sparx5, PGID_BCAST); port++) {
|
||||
spx5_wr(mask[0], sparx5, ANA_AC_PGID_CFG(port));
|
||||
if (is_sparx5(sparx5)) {
|
||||
spx5_wr(mask[1], sparx5, ANA_AC_PGID_CFG1(port));
|
||||
@ -0,0 +1,169 @@
|
||||
From 3ba2228de3c42509cddd592fd7e61e1f2738b95e Mon Sep 17 00:00:00 2001
|
||||
From: Daniel Machon <daniel.machon@microchip.com>
|
||||
Date: Thu, 24 Oct 2024 00:01:20 +0200
|
||||
Subject: [PATCH 44/82] net: sparx5: add support for lan969x targets and core
|
||||
clock
|
||||
|
||||
In preparation for lan969x, add lan969x targets to
|
||||
sparx5_target_chiptype and set the core clock frequency for these
|
||||
throughout. Lan969x only supports a core clock frequency of 328MHz.
|
||||
|
||||
Also, set the policer update internal (pol_upd_int) matching the 328 MHz
|
||||
frequency of the lan969x targets.
|
||||
|
||||
Reviewed-by: Steen Hegelund <Steen.Hegelund@microchip.com>
|
||||
Signed-off-by: Daniel Machon <daniel.machon@microchip.com>
|
||||
Link: https://patch.msgid.link/20241024-sparx5-lan969x-switch-driver-2-v2-1-a0b5fae88a0f@microchip.com
|
||||
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
|
||||
---
|
||||
.../microchip/sparx5/sparx5_calendar.c | 17 +++++++++
|
||||
.../ethernet/microchip/sparx5/sparx5_main.c | 16 +++++++++
|
||||
.../ethernet/microchip/sparx5/sparx5_main.h | 35 +++++++++++++------
|
||||
.../ethernet/microchip/sparx5/sparx5_ptp.c | 6 ++++
|
||||
4 files changed, 64 insertions(+), 10 deletions(-)
|
||||
|
||||
--- a/drivers/net/ethernet/microchip/sparx5/sparx5_calendar.c
|
||||
+++ b/drivers/net/ethernet/microchip/sparx5/sparx5_calendar.c
|
||||
@@ -53,6 +53,22 @@ static u32 sparx5_target_bandwidth(struc
|
||||
case SPX5_TARGET_CT_7558:
|
||||
case SPX5_TARGET_CT_7558TSN:
|
||||
return 201000;
|
||||
+ case SPX5_TARGET_CT_LAN9691VAO:
|
||||
+ return 46000;
|
||||
+ case SPX5_TARGET_CT_LAN9694RED:
|
||||
+ case SPX5_TARGET_CT_LAN9694TSN:
|
||||
+ case SPX5_TARGET_CT_LAN9694:
|
||||
+ return 68000;
|
||||
+ case SPX5_TARGET_CT_LAN9696RED:
|
||||
+ case SPX5_TARGET_CT_LAN9696TSN:
|
||||
+ case SPX5_TARGET_CT_LAN9692VAO:
|
||||
+ case SPX5_TARGET_CT_LAN9696:
|
||||
+ return 88000;
|
||||
+ case SPX5_TARGET_CT_LAN9698RED:
|
||||
+ case SPX5_TARGET_CT_LAN9698TSN:
|
||||
+ case SPX5_TARGET_CT_LAN9693VAO:
|
||||
+ case SPX5_TARGET_CT_LAN9698:
|
||||
+ return 101000;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
@@ -74,6 +90,7 @@ static u32 sparx5_clk_to_bandwidth(enum
|
||||
{
|
||||
switch (cclock) {
|
||||
case SPX5_CORE_CLOCK_250MHZ: return 83000; /* 250000 / 3 */
|
||||
+ case SPX5_CORE_CLOCK_328MHZ: return 109375; /* 328000 / 3 */
|
||||
case SPX5_CORE_CLOCK_500MHZ: return 166000; /* 500000 / 3 */
|
||||
case SPX5_CORE_CLOCK_625MHZ: return 208000; /* 625000 / 3 */
|
||||
default: return 0;
|
||||
--- a/drivers/net/ethernet/microchip/sparx5/sparx5_main.c
|
||||
+++ b/drivers/net/ethernet/microchip/sparx5/sparx5_main.c
|
||||
@@ -475,6 +475,20 @@ static int sparx5_init_coreclock(struct
|
||||
else if (sparx5->coreclock == SPX5_CORE_CLOCK_250MHZ)
|
||||
freq = 0; /* Not supported */
|
||||
break;
|
||||
+ case SPX5_TARGET_CT_LAN9694:
|
||||
+ case SPX5_TARGET_CT_LAN9691VAO:
|
||||
+ case SPX5_TARGET_CT_LAN9694TSN:
|
||||
+ case SPX5_TARGET_CT_LAN9694RED:
|
||||
+ case SPX5_TARGET_CT_LAN9696:
|
||||
+ case SPX5_TARGET_CT_LAN9692VAO:
|
||||
+ case SPX5_TARGET_CT_LAN9696TSN:
|
||||
+ case SPX5_TARGET_CT_LAN9696RED:
|
||||
+ case SPX5_TARGET_CT_LAN9698:
|
||||
+ case SPX5_TARGET_CT_LAN9693VAO:
|
||||
+ case SPX5_TARGET_CT_LAN9698TSN:
|
||||
+ case SPX5_TARGET_CT_LAN9698RED:
|
||||
+ freq = SPX5_CORE_CLOCK_328MHZ;
|
||||
+ break;
|
||||
default:
|
||||
dev_err(sparx5->dev, "Target (%#04x) not supported\n",
|
||||
sparx5->target_ct);
|
||||
@@ -516,6 +530,8 @@ static int sparx5_init_coreclock(struct
|
||||
CLKGEN_LCPLL1_CORE_CLK_CFG_CORE_ROT_ENA |
|
||||
CLKGEN_LCPLL1_CORE_CLK_CFG_CORE_CLK_ENA,
|
||||
sparx5, CLKGEN_LCPLL1_CORE_CLK_CFG);
|
||||
+ } else {
|
||||
+ pol_upd_int = 820; // SPX5_CORE_CLOCK_328MHZ
|
||||
}
|
||||
|
||||
/* Update state with chosen frequency */
|
||||
--- a/drivers/net/ethernet/microchip/sparx5/sparx5_main.h
|
||||
+++ b/drivers/net/ethernet/microchip/sparx5/sparx5_main.h
|
||||
@@ -26,16 +26,28 @@
|
||||
|
||||
/* Target chip type */
|
||||
enum spx5_target_chiptype {
|
||||
- SPX5_TARGET_CT_7546 = 0x7546, /* SparX-5-64 Enterprise */
|
||||
- SPX5_TARGET_CT_7549 = 0x7549, /* SparX-5-90 Enterprise */
|
||||
- SPX5_TARGET_CT_7552 = 0x7552, /* SparX-5-128 Enterprise */
|
||||
- SPX5_TARGET_CT_7556 = 0x7556, /* SparX-5-160 Enterprise */
|
||||
- SPX5_TARGET_CT_7558 = 0x7558, /* SparX-5-200 Enterprise */
|
||||
- SPX5_TARGET_CT_7546TSN = 0x47546, /* SparX-5-64i Industrial */
|
||||
- SPX5_TARGET_CT_7549TSN = 0x47549, /* SparX-5-90i Industrial */
|
||||
- SPX5_TARGET_CT_7552TSN = 0x47552, /* SparX-5-128i Industrial */
|
||||
- SPX5_TARGET_CT_7556TSN = 0x47556, /* SparX-5-160i Industrial */
|
||||
- SPX5_TARGET_CT_7558TSN = 0x47558, /* SparX-5-200i Industrial */
|
||||
+ SPX5_TARGET_CT_7546 = 0x7546, /* SparX-5-64 Enterprise */
|
||||
+ SPX5_TARGET_CT_7549 = 0x7549, /* SparX-5-90 Enterprise */
|
||||
+ SPX5_TARGET_CT_7552 = 0x7552, /* SparX-5-128 Enterprise */
|
||||
+ SPX5_TARGET_CT_7556 = 0x7556, /* SparX-5-160 Enterprise */
|
||||
+ SPX5_TARGET_CT_7558 = 0x7558, /* SparX-5-200 Enterprise */
|
||||
+ SPX5_TARGET_CT_7546TSN = 0x47546, /* SparX-5-64i Industrial */
|
||||
+ SPX5_TARGET_CT_7549TSN = 0x47549, /* SparX-5-90i Industrial */
|
||||
+ SPX5_TARGET_CT_7552TSN = 0x47552, /* SparX-5-128i Industrial */
|
||||
+ SPX5_TARGET_CT_7556TSN = 0x47556, /* SparX-5-160i Industrial */
|
||||
+ SPX5_TARGET_CT_7558TSN = 0x47558, /* SparX-5-200i Industrial */
|
||||
+ SPX5_TARGET_CT_LAN9694 = 0x9694, /* lan969x-40 */
|
||||
+ SPX5_TARGET_CT_LAN9691VAO = 0x9691, /* lan969x-40-VAO */
|
||||
+ SPX5_TARGET_CT_LAN9694TSN = 0x9695, /* lan969x-40-TSN */
|
||||
+ SPX5_TARGET_CT_LAN9694RED = 0x969A, /* lan969x-40-RED */
|
||||
+ SPX5_TARGET_CT_LAN9696 = 0x9696, /* lan969x-60 */
|
||||
+ SPX5_TARGET_CT_LAN9692VAO = 0x9692, /* lan969x-65-VAO */
|
||||
+ SPX5_TARGET_CT_LAN9696TSN = 0x9697, /* lan969x-60-TSN */
|
||||
+ SPX5_TARGET_CT_LAN9696RED = 0x969B, /* lan969x-60-RED */
|
||||
+ SPX5_TARGET_CT_LAN9698 = 0x9698, /* lan969x-100 */
|
||||
+ SPX5_TARGET_CT_LAN9693VAO = 0x9693, /* lan969x-100-VAO */
|
||||
+ SPX5_TARGET_CT_LAN9698TSN = 0x9699, /* lan969x-100-TSN */
|
||||
+ SPX5_TARGET_CT_LAN9698RED = 0x969C, /* lan969x-100-RED */
|
||||
};
|
||||
|
||||
enum sparx5_port_max_tags {
|
||||
@@ -192,6 +204,7 @@ struct sparx5_port {
|
||||
enum sparx5_core_clockfreq {
|
||||
SPX5_CORE_CLOCK_DEFAULT, /* Defaults to the highest supported frequency */
|
||||
SPX5_CORE_CLOCK_250MHZ, /* 250MHZ core clock frequency */
|
||||
+ SPX5_CORE_CLOCK_328MHZ, /* 328MHZ core clock frequency */
|
||||
SPX5_CORE_CLOCK_500MHZ, /* 500MHZ core clock frequency */
|
||||
SPX5_CORE_CLOCK_625MHZ, /* 625MHZ core clock frequency */
|
||||
};
|
||||
@@ -641,6 +654,8 @@ static inline u32 sparx5_clk_period(enum
|
||||
switch (cclock) {
|
||||
case SPX5_CORE_CLOCK_250MHZ:
|
||||
return 4000;
|
||||
+ case SPX5_CORE_CLOCK_328MHZ:
|
||||
+ return 3048;
|
||||
case SPX5_CORE_CLOCK_500MHZ:
|
||||
return 2000;
|
||||
case SPX5_CORE_CLOCK_625MHZ:
|
||||
--- a/drivers/net/ethernet/microchip/sparx5/sparx5_ptp.c
|
||||
+++ b/drivers/net/ethernet/microchip/sparx5/sparx5_ptp.c
|
||||
@@ -38,6 +38,9 @@ static u64 sparx5_ptp_get_1ppm(struct sp
|
||||
case SPX5_CORE_CLOCK_250MHZ:
|
||||
res = 2301339409586;
|
||||
break;
|
||||
+ case SPX5_CORE_CLOCK_328MHZ:
|
||||
+ res = 1756832768924;
|
||||
+ break;
|
||||
case SPX5_CORE_CLOCK_500MHZ:
|
||||
res = 1150669704793;
|
||||
break;
|
||||
@@ -60,6 +63,9 @@ static u64 sparx5_ptp_get_nominal_value(
|
||||
case SPX5_CORE_CLOCK_250MHZ:
|
||||
res = 0x1FF0000000000000;
|
||||
break;
|
||||
+ case SPX5_CORE_CLOCK_328MHZ:
|
||||
+ res = 0x18604697DD0F9B5B;
|
||||
+ break;
|
||||
case SPX5_CORE_CLOCK_500MHZ:
|
||||
res = 0x0FF8000000000000;
|
||||
break;
|
||||
@ -0,0 +1,48 @@
|
||||
From 4feb1d4bb1cc58d86ef8c19091ba4b2785784e08 Mon Sep 17 00:00:00 2001
|
||||
From: Daniel Machon <daniel.machon@microchip.com>
|
||||
Date: Thu, 24 Oct 2024 00:01:21 +0200
|
||||
Subject: [PATCH 45/82] net: sparx5: change spx5_wr to spx5_rmw in cal update()
|
||||
|
||||
In preparation for lan969x, use spx5_rmw() for enabling the update of
|
||||
the calendar. This is required to not overwrite the DSM_TAXI_CAL_CFG
|
||||
register, as an additional write will be added before this one, in a
|
||||
subsequent patch.
|
||||
|
||||
Reviewed-by: Steen Hegelund <Steen.Hegelund@microchip.com>
|
||||
Signed-off-by: Daniel Machon <daniel.machon@microchip.com>
|
||||
Link: https://patch.msgid.link/20241024-sparx5-lan969x-switch-driver-2-v2-2-a0b5fae88a0f@microchip.com
|
||||
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
|
||||
---
|
||||
.../ethernet/microchip/sparx5/sparx5_calendar.c | 14 ++++++++------
|
||||
1 file changed, 8 insertions(+), 6 deletions(-)
|
||||
|
||||
--- a/drivers/net/ethernet/microchip/sparx5/sparx5_calendar.c
|
||||
+++ b/drivers/net/ethernet/microchip/sparx5/sparx5_calendar.c
|
||||
@@ -546,9 +546,10 @@ static int sparx5_dsm_calendar_update(st
|
||||
u32 idx;
|
||||
u32 cal_len = sparx5_dsm_cal_len(data->schedule), len;
|
||||
|
||||
- spx5_wr(DSM_TAXI_CAL_CFG_CAL_PGM_ENA_SET(1),
|
||||
- sparx5,
|
||||
- DSM_TAXI_CAL_CFG(taxi));
|
||||
+ spx5_rmw(DSM_TAXI_CAL_CFG_CAL_PGM_ENA_SET(1),
|
||||
+ DSM_TAXI_CAL_CFG_CAL_PGM_ENA,
|
||||
+ sparx5,
|
||||
+ DSM_TAXI_CAL_CFG(taxi));
|
||||
for (idx = 0; idx < cal_len; idx++) {
|
||||
spx5_rmw(DSM_TAXI_CAL_CFG_CAL_IDX_SET(idx),
|
||||
DSM_TAXI_CAL_CFG_CAL_IDX,
|
||||
@@ -559,9 +560,10 @@ static int sparx5_dsm_calendar_update(st
|
||||
sparx5,
|
||||
DSM_TAXI_CAL_CFG(taxi));
|
||||
}
|
||||
- spx5_wr(DSM_TAXI_CAL_CFG_CAL_PGM_ENA_SET(0),
|
||||
- sparx5,
|
||||
- DSM_TAXI_CAL_CFG(taxi));
|
||||
+ spx5_rmw(DSM_TAXI_CAL_CFG_CAL_PGM_ENA_SET(0),
|
||||
+ DSM_TAXI_CAL_CFG_CAL_PGM_ENA,
|
||||
+ sparx5,
|
||||
+ DSM_TAXI_CAL_CFG(taxi));
|
||||
len = DSM_TAXI_CAL_CFG_CAL_CUR_LEN_GET(spx5_rd(sparx5,
|
||||
DSM_TAXI_CAL_CFG(taxi)));
|
||||
if (len != cal_len - 1)
|
||||
@ -0,0 +1,55 @@
|
||||
From 6e50593002ad4886e2d74e99b67e735cbab0c606 Mon Sep 17 00:00:00 2001
|
||||
From: Daniel Machon <daniel.machon@microchip.com>
|
||||
Date: Thu, 24 Oct 2024 00:01:22 +0200
|
||||
Subject: [PATCH 46/82] net: sparx5: change frequency calculation for SDLB's
|
||||
|
||||
In preparation for lan969x, rework the function that calculates the SDLB
|
||||
(Service Dual Leacky Bucket) clock. This is required, as the
|
||||
HSCH_SYS_CLK_PER register is Sparx5-exclusive. Instead derive the clock
|
||||
from the core clock, using the sparx5_clk_period() function. The clock
|
||||
stays the same before and after this patch, only now,
|
||||
sparx5_sdlb_clk_hz_get() can be used for lan969x too.
|
||||
|
||||
Reviewed-by: Steen Hegelund <Steen.Hegelund@microchip.com>
|
||||
Signed-off-by: Daniel Machon <daniel.machon@microchip.com>
|
||||
Link: https://patch.msgid.link/20241024-sparx5-lan969x-switch-driver-2-v2-3-a0b5fae88a0f@microchip.com
|
||||
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
|
||||
---
|
||||
drivers/net/ethernet/microchip/sparx5/sparx5_main.h | 2 +-
|
||||
drivers/net/ethernet/microchip/sparx5/sparx5_sdlb.c | 10 +++-------
|
||||
2 files changed, 4 insertions(+), 8 deletions(-)
|
||||
|
||||
--- a/drivers/net/ethernet/microchip/sparx5/sparx5_main.h
|
||||
+++ b/drivers/net/ethernet/microchip/sparx5/sparx5_main.h
|
||||
@@ -552,7 +552,7 @@ struct sparx5_sdlb_group *sparx5_get_sdl
|
||||
int sparx5_sdlb_pup_token_get(struct sparx5 *sparx5, u32 pup_interval,
|
||||
u64 rate);
|
||||
|
||||
-int sparx5_sdlb_clk_hz_get(struct sparx5 *sparx5);
|
||||
+u64 sparx5_sdlb_clk_hz_get(struct sparx5 *sparx5);
|
||||
int sparx5_sdlb_group_get_by_rate(struct sparx5 *sparx5, u32 rate, u32 burst);
|
||||
int sparx5_sdlb_group_get_by_index(struct sparx5 *sparx5, u32 idx, u32 *group);
|
||||
|
||||
--- a/drivers/net/ethernet/microchip/sparx5/sparx5_sdlb.c
|
||||
+++ b/drivers/net/ethernet/microchip/sparx5/sparx5_sdlb.c
|
||||
@@ -25,17 +25,13 @@ struct sparx5_sdlb_group *sparx5_get_sdl
|
||||
return &sdlb_groups[idx];
|
||||
}
|
||||
|
||||
-int sparx5_sdlb_clk_hz_get(struct sparx5 *sparx5)
|
||||
+u64 sparx5_sdlb_clk_hz_get(struct sparx5 *sparx5)
|
||||
{
|
||||
- u32 clk_per_100ps;
|
||||
u64 clk_hz;
|
||||
|
||||
- clk_per_100ps = HSCH_SYS_CLK_PER_100PS_GET(spx5_rd(sparx5,
|
||||
- HSCH_SYS_CLK_PER));
|
||||
- if (!clk_per_100ps)
|
||||
- clk_per_100ps = SPX5_CLK_PER_100PS_DEFAULT;
|
||||
+ clk_hz = (10 * 1000 * 1000) /
|
||||
+ (sparx5_clk_period(sparx5->coreclock) / 100);
|
||||
|
||||
- clk_hz = (10 * 1000 * 1000) / clk_per_100ps;
|
||||
return clk_hz *= 1000;
|
||||
}
|
||||
|
||||
@ -0,0 +1,122 @@
|
||||
From 6e84c752630600be74db11feae869d333c55fe1c Mon Sep 17 00:00:00 2001
|
||||
From: Daniel Machon <daniel.machon@microchip.com>
|
||||
Date: Thu, 24 Oct 2024 00:01:23 +0200
|
||||
Subject: [PATCH 47/82] net: sparx5: add sparx5 context pointer to a few
|
||||
functions
|
||||
|
||||
In preparation for lan969x, add the sparx5 context pointer to certain
|
||||
IFH (Internal Frame Header) functions. This is required, as the
|
||||
is_sparx5() function will be used here in a subsequent patch.
|
||||
|
||||
Reviewed-by: Steen Hegelund <Steen.Hegelund@microchip.com>
|
||||
Signed-off-by: Daniel Machon <daniel.machon@microchip.com>
|
||||
Link: https://patch.msgid.link/20241024-sparx5-lan969x-switch-driver-2-v2-4-a0b5fae88a0f@microchip.com
|
||||
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
|
||||
---
|
||||
drivers/net/ethernet/microchip/sparx5/sparx5_fdma.c | 2 +-
|
||||
drivers/net/ethernet/microchip/sparx5/sparx5_main.h | 11 +++++++----
|
||||
.../net/ethernet/microchip/sparx5/sparx5_netdev.c | 9 ++++++---
|
||||
.../net/ethernet/microchip/sparx5/sparx5_packet.c | 13 ++++++++-----
|
||||
4 files changed, 22 insertions(+), 13 deletions(-)
|
||||
|
||||
--- a/drivers/net/ethernet/microchip/sparx5/sparx5_fdma.c
|
||||
+++ b/drivers/net/ethernet/microchip/sparx5/sparx5_fdma.c
|
||||
@@ -154,7 +154,7 @@ static bool sparx5_fdma_rx_get_frame(str
|
||||
skb = rx->skb[fdma->dcb_index][fdma->db_index];
|
||||
skb_put(skb, fdma_db_len_get(db_hw));
|
||||
/* Now do the normal processing of the skb */
|
||||
- sparx5_ifh_parse((u32 *)skb->data, &fi);
|
||||
+ sparx5_ifh_parse(sparx5, (u32 *)skb->data, &fi);
|
||||
/* Map to port netdev */
|
||||
port = fi.src_port < sparx5->data->consts->n_ports ?
|
||||
sparx5->ports[fi.src_port] :
|
||||
--- a/drivers/net/ethernet/microchip/sparx5/sparx5_main.h
|
||||
+++ b/drivers/net/ethernet/microchip/sparx5/sparx5_main.h
|
||||
@@ -401,7 +401,7 @@ struct frame_info {
|
||||
};
|
||||
|
||||
void sparx5_xtr_flush(struct sparx5 *sparx5, u8 grp);
|
||||
-void sparx5_ifh_parse(u32 *ifh, struct frame_info *info);
|
||||
+void sparx5_ifh_parse(struct sparx5 *sparx5, u32 *ifh, struct frame_info *info);
|
||||
irqreturn_t sparx5_xtr_handler(int irq, void *_priv);
|
||||
netdev_tx_t sparx5_port_xmit_impl(struct sk_buff *skb, struct net_device *dev);
|
||||
int sparx5_manual_injection_mode(struct sparx5 *sparx5);
|
||||
@@ -469,10 +469,13 @@ static inline int sparx5_dcb_init(struct
|
||||
#endif
|
||||
|
||||
/* sparx5_netdev.c */
|
||||
-void sparx5_set_port_ifh_timestamp(void *ifh_hdr, u64 timestamp);
|
||||
+void sparx5_set_port_ifh_timestamp(struct sparx5 *sparx5, void *ifh_hdr,
|
||||
+ u64 timestamp);
|
||||
void sparx5_set_port_ifh_rew_op(void *ifh_hdr, u32 rew_op);
|
||||
-void sparx5_set_port_ifh_pdu_type(void *ifh_hdr, u32 pdu_type);
|
||||
-void sparx5_set_port_ifh_pdu_w16_offset(void *ifh_hdr, u32 pdu_w16_offset);
|
||||
+void sparx5_set_port_ifh_pdu_type(struct sparx5 *sparx5, void *ifh_hdr,
|
||||
+ u32 pdu_type);
|
||||
+void sparx5_set_port_ifh_pdu_w16_offset(struct sparx5 *sparx5, void *ifh_hdr,
|
||||
+ u32 pdu_w16_offset);
|
||||
void sparx5_set_port_ifh(struct sparx5 *sparx5, void *ifh_hdr, u16 portno);
|
||||
bool sparx5_netdevice_check(const struct net_device *dev);
|
||||
struct net_device *sparx5_create_netdev(struct sparx5 *sparx5, u32 portno);
|
||||
--- a/drivers/net/ethernet/microchip/sparx5/sparx5_netdev.c
|
||||
+++ b/drivers/net/ethernet/microchip/sparx5/sparx5_netdev.c
|
||||
@@ -81,17 +81,20 @@ void sparx5_set_port_ifh_rew_op(void *if
|
||||
ifh_encode_bitfield(ifh_hdr, rew_op, VSTAX + 32, 10);
|
||||
}
|
||||
|
||||
-void sparx5_set_port_ifh_pdu_type(void *ifh_hdr, u32 pdu_type)
|
||||
+void sparx5_set_port_ifh_pdu_type(struct sparx5 *sparx5, void *ifh_hdr,
|
||||
+ u32 pdu_type)
|
||||
{
|
||||
ifh_encode_bitfield(ifh_hdr, pdu_type, 191, 4);
|
||||
}
|
||||
|
||||
-void sparx5_set_port_ifh_pdu_w16_offset(void *ifh_hdr, u32 pdu_w16_offset)
|
||||
+void sparx5_set_port_ifh_pdu_w16_offset(struct sparx5 *sparx5, void *ifh_hdr,
|
||||
+ u32 pdu_w16_offset)
|
||||
{
|
||||
ifh_encode_bitfield(ifh_hdr, pdu_w16_offset, 195, 6);
|
||||
}
|
||||
|
||||
-void sparx5_set_port_ifh_timestamp(void *ifh_hdr, u64 timestamp)
|
||||
+void sparx5_set_port_ifh_timestamp(struct sparx5 *sparx5, void *ifh_hdr,
|
||||
+ u64 timestamp)
|
||||
{
|
||||
ifh_encode_bitfield(ifh_hdr, timestamp, 232, 40);
|
||||
}
|
||||
--- a/drivers/net/ethernet/microchip/sparx5/sparx5_packet.c
|
||||
+++ b/drivers/net/ethernet/microchip/sparx5/sparx5_packet.c
|
||||
@@ -32,7 +32,7 @@ void sparx5_xtr_flush(struct sparx5 *spa
|
||||
spx5_wr(0, sparx5, QS_XTR_FLUSH);
|
||||
}
|
||||
|
||||
-void sparx5_ifh_parse(u32 *ifh, struct frame_info *info)
|
||||
+void sparx5_ifh_parse(struct sparx5 *sparx5, u32 *ifh, struct frame_info *info)
|
||||
{
|
||||
u8 *xtr_hdr = (u8 *)ifh;
|
||||
|
||||
@@ -72,7 +72,7 @@ static void sparx5_xtr_grp(struct sparx5
|
||||
ifh[i] = spx5_rd(sparx5, QS_XTR_RD(grp));
|
||||
|
||||
/* Decode IFH (what's needed) */
|
||||
- sparx5_ifh_parse(ifh, &fi);
|
||||
+ sparx5_ifh_parse(sparx5, ifh, &fi);
|
||||
|
||||
/* Map to port netdev */
|
||||
port = fi.src_port < sparx5->data->consts->n_ports ?
|
||||
@@ -242,9 +242,12 @@ netdev_tx_t sparx5_port_xmit_impl(struct
|
||||
return NETDEV_TX_BUSY;
|
||||
|
||||
sparx5_set_port_ifh_rew_op(ifh, SPARX5_SKB_CB(skb)->rew_op);
|
||||
- sparx5_set_port_ifh_pdu_type(ifh, SPARX5_SKB_CB(skb)->pdu_type);
|
||||
- sparx5_set_port_ifh_pdu_w16_offset(ifh, SPARX5_SKB_CB(skb)->pdu_w16_offset);
|
||||
- sparx5_set_port_ifh_timestamp(ifh, SPARX5_SKB_CB(skb)->ts_id);
|
||||
+ sparx5_set_port_ifh_pdu_type(sparx5, ifh,
|
||||
+ SPARX5_SKB_CB(skb)->pdu_type);
|
||||
+ sparx5_set_port_ifh_pdu_w16_offset(sparx5, ifh,
|
||||
+ SPARX5_SKB_CB(skb)->pdu_w16_offset);
|
||||
+ sparx5_set_port_ifh_timestamp(sparx5, ifh,
|
||||
+ SPARX5_SKB_CB(skb)->ts_id);
|
||||
}
|
||||
|
||||
skb_tx_timestamp(skb);
|
||||
@ -0,0 +1,185 @@
|
||||
From 79009c7ee726a104e4d67c99ef5b53db31a39549 Mon Sep 17 00:00:00 2001
|
||||
From: Daniel Machon <daniel.machon@microchip.com>
|
||||
Date: Thu, 24 Oct 2024 00:01:24 +0200
|
||||
Subject: [PATCH 48/82] net: sparx5: add registers required by lan969x
|
||||
|
||||
Lan969x will require a few additional registers for certain operations.
|
||||
Some are shared, some are not. Add these.
|
||||
|
||||
Reviewed-by: Steen Hegelund <Steen.Hegelund@microchip.com>
|
||||
Signed-off-by: Daniel Machon <daniel.machon@microchip.com>
|
||||
Link: https://patch.msgid.link/20241024-sparx5-lan969x-switch-driver-2-v2-5-a0b5fae88a0f@microchip.com
|
||||
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
|
||||
---
|
||||
.../microchip/sparx5/sparx5_main_regs.h | 132 ++++++++++++++++++
|
||||
1 file changed, 132 insertions(+)
|
||||
|
||||
--- a/drivers/net/ethernet/microchip/sparx5/sparx5_main_regs.h
|
||||
+++ b/drivers/net/ethernet/microchip/sparx5/sparx5_main_regs.h
|
||||
@@ -2666,6 +2666,44 @@ extern const struct sparx5_regs *regs;
|
||||
#define CPU_PROC_CTRL_ACP_DISABLE_GET(x)\
|
||||
FIELD_GET(CPU_PROC_CTRL_ACP_DISABLE, x)
|
||||
|
||||
+/* DEV1G:PHASE_DETECTOR_CTRL:PHAD_CTRL */
|
||||
+#define DEV2G5_PHAD_CTRL(t, g) \
|
||||
+ __REG(TARGET_DEV2G5, t, regs->tsize[TC_DEV2G5], 200, g, 2, \
|
||||
+ regs->gsize[GW_DEV2G5_PHASE_DETECTOR_CTRL], 0, 0, 1, 4)
|
||||
+
|
||||
+#define DEV2G5_PHAD_CTRL_PHAD_ENA\
|
||||
+ BIT(regs->fpos[FP_DEV2G5_PHAD_CTRL_PHAD_ENA])
|
||||
+#define DEV2G5_PHAD_CTRL_PHAD_ENA_SET(x)\
|
||||
+ spx5_field_prep(DEV2G5_PHAD_CTRL_PHAD_ENA, x)
|
||||
+#define DEV2G5_PHAD_CTRL_PHAD_ENA_GET(x)\
|
||||
+ spx5_field_get(DEV2G5_PHAD_CTRL_PHAD_ENA, x)
|
||||
+
|
||||
+/* LAN969X ONLY */
|
||||
+#define DEV2G5_PHAD_CTRL_DIV_CFG GENMASK(11, 9)
|
||||
+#define DEV2G5_PHAD_CTRL_DIV_CFG_SET(x)\
|
||||
+ FIELD_PREP(DEV2G5_PHAD_CTRL_DIV_CFG, x)
|
||||
+#define DEV2G5_PHAD_CTRL_DIV_CFG_GET(x)\
|
||||
+ FIELD_GET(DEV2G5_PHAD_CTRL_DIV_CFG, x)
|
||||
+
|
||||
+/* DEV1G:PHASE_DETECTOR_CTRL:PHAD_CTRL */
|
||||
+#define DEV2G5_PHAD_CTRL(t, g) \
|
||||
+ __REG(TARGET_DEV2G5, t, regs->tsize[TC_DEV2G5], 200, g, 2, \
|
||||
+ regs->gsize[GW_DEV2G5_PHASE_DETECTOR_CTRL], 0, 0, 1, 4)
|
||||
+
|
||||
+#define DEV2G5_PHAD_CTRL_PHAD_ENA\
|
||||
+ BIT(regs->fpos[FP_DEV2G5_PHAD_CTRL_PHAD_ENA])
|
||||
+#define DEV2G5_PHAD_CTRL_PHAD_ENA_SET(x)\
|
||||
+ spx5_field_prep(DEV2G5_PHAD_CTRL_PHAD_ENA, x)
|
||||
+#define DEV2G5_PHAD_CTRL_PHAD_ENA_GET(x)\
|
||||
+ spx5_field_get(DEV2G5_PHAD_CTRL_PHAD_ENA, x)
|
||||
+
|
||||
+/* LAN969X ONLY */
|
||||
+#define DEV2G5_PHAD_CTRL_DIV_CFG GENMASK(11, 9)
|
||||
+#define DEV2G5_PHAD_CTRL_DIV_CFG_SET(x)\
|
||||
+ FIELD_PREP(DEV2G5_PHAD_CTRL_DIV_CFG, x)
|
||||
+#define DEV2G5_PHAD_CTRL_DIV_CFG_GET(x)\
|
||||
+ FIELD_GET(DEV2G5_PHAD_CTRL_DIV_CFG, x)
|
||||
+
|
||||
/* DEV10G:MAC_CFG_STATUS:MAC_ENA_CFG */
|
||||
#define DEV10G_MAC_ENA_CFG(t) \
|
||||
__REG(TARGET_DEV10G, t, regs->tsize[TC_DEV10G], 0, 0, 1, 60, 0, 0, 1, \
|
||||
@@ -2869,6 +2907,11 @@ extern const struct sparx5_regs *regs;
|
||||
#define DEV10G_DEV_RST_CTRL_MAC_RX_RST_GET(x)\
|
||||
FIELD_GET(DEV10G_DEV_RST_CTRL_MAC_RX_RST, x)
|
||||
|
||||
+/* DEV10G:DEV_CFG_STATUS:PTP_STAMPER_CFG */
|
||||
+#define DEV10G_PTP_STAMPER_CFG(t) \
|
||||
+ __REG(TARGET_DEV10G, t, regs->tsize[TC_DEV10G], 436, 0, 1, 52, 20, 0, \
|
||||
+ 1, 4)
|
||||
+
|
||||
/* DEV10G:PCS25G_CFG_STATUS:PCS25G_CFG */
|
||||
#define DEV10G_PCS25G_CFG(t) \
|
||||
__REG(TARGET_DEV10G, t, regs->tsize[TC_DEV10G], 488, 0, 1, 32, 0, 0, 1,\
|
||||
@@ -4267,6 +4310,11 @@ extern const struct sparx5_regs *regs;
|
||||
#define DEV5G_DEV_RST_CTRL_MAC_RX_RST_GET(x)\
|
||||
FIELD_GET(DEV5G_DEV_RST_CTRL_MAC_RX_RST, x)
|
||||
|
||||
+/* DEV10G:DEV_CFG_STATUS:PTP_STAMPER_CFG */
|
||||
+#define DEV5G_PTP_STAMPER_CFG(t) \
|
||||
+ __REG(TARGET_DEV5G, t, regs->tsize[TC_DEV5G], 436, 0, 1, 52, 20, 0, 1, \
|
||||
+ 4)
|
||||
+
|
||||
/* DSM:RAM_CTRL:RAM_INIT */
|
||||
#define DSM_RAM_INIT \
|
||||
__REG(TARGET_DSM, 0, 1, 0, 0, 1, 4, 0, 0, 1, 4)
|
||||
@@ -4444,6 +4492,27 @@ extern const struct sparx5_regs *regs;
|
||||
#define DSM_TAXI_CAL_CFG_CAL_PGM_ENA_GET(x)\
|
||||
FIELD_GET(DSM_TAXI_CAL_CFG_CAL_PGM_ENA, x)
|
||||
|
||||
+/* LAN969X ONLY */
|
||||
+#define DSM_TAXI_CAL_CFG_CAL_SEL_STAT BIT(23)
|
||||
+#define DSM_TAXI_CAL_CFG_CAL_SEL_STAT_SET(x)\
|
||||
+ FIELD_PREP(DSM_TAXI_CAL_CFG_CAL_SEL_STAT, x)
|
||||
+#define DSM_TAXI_CAL_CFG_CAL_SEL_STAT_GET(x)\
|
||||
+ FIELD_GET(DSM_TAXI_CAL_CFG_CAL_SEL_STAT, x)
|
||||
+
|
||||
+/* LAN969X ONLY */
|
||||
+#define DSM_TAXI_CAL_CFG_CAL_SWITCH BIT(22)
|
||||
+#define DSM_TAXI_CAL_CFG_CAL_SWITCH_SET(x)\
|
||||
+ FIELD_PREP(DSM_TAXI_CAL_CFG_CAL_SWITCH, x)
|
||||
+#define DSM_TAXI_CAL_CFG_CAL_SWITCH_GET(x)\
|
||||
+ FIELD_GET(DSM_TAXI_CAL_CFG_CAL_SWITCH, x)
|
||||
+
|
||||
+/* LAN969X ONLY */
|
||||
+#define DSM_TAXI_CAL_CFG_CAL_PGM_SEL BIT(21)
|
||||
+#define DSM_TAXI_CAL_CFG_CAL_PGM_SEL_SET(x)\
|
||||
+ FIELD_PREP(DSM_TAXI_CAL_CFG_CAL_PGM_SEL, x)
|
||||
+#define DSM_TAXI_CAL_CFG_CAL_PGM_SEL_GET(x)\
|
||||
+ FIELD_GET(DSM_TAXI_CAL_CFG_CAL_PGM_SEL, x)
|
||||
+
|
||||
/* EACL:ES2_KEY_SELECT_PROFILE:VCAP_ES2_KEY_SEL */
|
||||
#define EACL_VCAP_ES2_KEY_SEL(g, r) \
|
||||
__REG(TARGET_EACL, 0, 1, regs->gaddr[GA_EACL_ES2_KEY_SELECT_PROFILE], \
|
||||
@@ -6720,6 +6789,69 @@ extern const struct sparx5_regs *regs;
|
||||
regs->gcnt[GC_PTP_PHASE_DETECTOR_CTRL], \
|
||||
regs->gsize[GW_PTP_PHASE_DETECTOR_CTRL], 4, 0, 1, 4)
|
||||
|
||||
+/* LAN969X ONLY */
|
||||
+/* DEVCPU_PTP:PTP_TS_FIFO:PTP_TWOSTEP_CTRL */
|
||||
+#define PTP_TWOSTEP_CTRL \
|
||||
+ __REG(TARGET_PTP, 0, 1, 612, 0, 1, 16, 0, 0, 1, 4)
|
||||
+
|
||||
+#define PTP_TWOSTEP_CTRL_PTP_OVWR_ENA BIT(12)
|
||||
+#define PTP_TWOSTEP_CTRL_PTP_OVWR_ENA_SET(x)\
|
||||
+ FIELD_PREP(PTP_TWOSTEP_CTRL_PTP_OVWR_ENA, x)
|
||||
+#define PTP_TWOSTEP_CTRL_PTP_OVWR_ENA_GET(x)\
|
||||
+ FIELD_GET(PTP_TWOSTEP_CTRL_PTP_OVWR_ENA, x)
|
||||
+
|
||||
+#define PTP_TWOSTEP_CTRL_PTP_NXT BIT(11)
|
||||
+#define PTP_TWOSTEP_CTRL_PTP_NXT_SET(x)\
|
||||
+ FIELD_PREP(PTP_TWOSTEP_CTRL_PTP_NXT, x)
|
||||
+#define PTP_TWOSTEP_CTRL_PTP_NXT_GET(x)\
|
||||
+ FIELD_GET(PTP_TWOSTEP_CTRL_PTP_NXT, x)
|
||||
+
|
||||
+#define PTP_TWOSTEP_CTRL_PTP_VLD BIT(10)
|
||||
+#define PTP_TWOSTEP_CTRL_PTP_VLD_SET(x)\
|
||||
+ FIELD_PREP(PTP_TWOSTEP_CTRL_PTP_VLD, x)
|
||||
+#define PTP_TWOSTEP_CTRL_PTP_VLD_GET(x)\
|
||||
+ FIELD_GET(PTP_TWOSTEP_CTRL_PTP_VLD, x)
|
||||
+
|
||||
+#define PTP_TWOSTEP_CTRL_STAMP_TX BIT(9)
|
||||
+#define PTP_TWOSTEP_CTRL_STAMP_TX_SET(x)\
|
||||
+ FIELD_PREP(PTP_TWOSTEP_CTRL_STAMP_TX, x)
|
||||
+#define PTP_TWOSTEP_CTRL_STAMP_TX_GET(x)\
|
||||
+ FIELD_GET(PTP_TWOSTEP_CTRL_STAMP_TX, x)
|
||||
+
|
||||
+#define PTP_TWOSTEP_CTRL_STAMP_PORT GENMASK(8, 1)
|
||||
+#define PTP_TWOSTEP_CTRL_STAMP_PORT_SET(x)\
|
||||
+ FIELD_PREP(PTP_TWOSTEP_CTRL_STAMP_PORT, x)
|
||||
+#define PTP_TWOSTEP_CTRL_STAMP_PORT_GET(x)\
|
||||
+ FIELD_GET(PTP_TWOSTEP_CTRL_STAMP_PORT, x)
|
||||
+
|
||||
+#define PTP_TWOSTEP_CTRL_PTP_OVFL BIT(0)
|
||||
+#define PTP_TWOSTEP_CTRL_PTP_OVFL_SET(x)\
|
||||
+ FIELD_PREP(PTP_TWOSTEP_CTRL_PTP_OVFL, x)
|
||||
+#define PTP_TWOSTEP_CTRL_PTP_OVFL_GET(x)\
|
||||
+ FIELD_GET(PTP_TWOSTEP_CTRL_PTP_OVFL, x)
|
||||
+
|
||||
+/* LAN969X ONLY */
|
||||
+/* DEVCPU_PTP:PTP_TS_FIFO:PTP_TWOSTEP_STAMP_NSEC */
|
||||
+#define PTP_TWOSTEP_STAMP_NSEC \
|
||||
+ __REG(TARGET_PTP, 0, 1, 612, 0, 1, 16, 4, 0, 1, 4)
|
||||
+
|
||||
+#define PTP_TWOSTEP_STAMP_NSEC_NS GENMASK(29, 0)
|
||||
+#define PTP_TWOSTEP_STAMP_NSEC_NS_SET(x)\
|
||||
+ FIELD_PREP(PTP_TWOSTEP_STAMP_NSEC_NS, x)
|
||||
+#define PTP_TWOSTEP_STAMP_NSEC_NS_GET(x)\
|
||||
+ FIELD_GET(PTP_TWOSTEP_STAMP_NSEC_NS, x)
|
||||
+
|
||||
+/* LAN969X ONLY */
|
||||
+/* DEVCPU_PTP:PTP_TS_FIFO:PTP_TWOSTEP_STAMP_SUBNS */
|
||||
+#define PTP_TWOSTEP_STAMP_SUBNS \
|
||||
+ __REG(TARGET_PTP, 0, 1, 612, 0, 1, 16, 8, 0, 1, 4)
|
||||
+
|
||||
+#define PTP_TWOSTEP_STAMP_SUBNS_NS GENMASK(7, 0)
|
||||
+#define PTP_TWOSTEP_STAMP_SUBNS_NS_SET(x)\
|
||||
+ FIELD_PREP(PTP_TWOSTEP_STAMP_SUBNS_NS, x)
|
||||
+#define PTP_TWOSTEP_STAMP_SUBNS_NS_GET(x)\
|
||||
+ FIELD_GET(PTP_TWOSTEP_STAMP_SUBNS_NS, x)
|
||||
+
|
||||
/* QFWD:SYSTEM:SWITCH_PORT_MODE */
|
||||
#define QFWD_SWITCH_PORT_MODE(r) \
|
||||
__REG(TARGET_QFWD, 0, 1, 0, 0, 1, 340, 0, r, \
|
||||
@ -0,0 +1,216 @@
|
||||
From 033defe6fd3cc5b5b90c31d7bf0effe27772adbd Mon Sep 17 00:00:00 2001
|
||||
From: Daniel Machon <daniel.machon@microchip.com>
|
||||
Date: Thu, 24 Oct 2024 00:01:25 +0200
|
||||
Subject: [PATCH 49/82] net: lan969x: add match data for lan969x
|
||||
|
||||
Add match data for lan969x, with initial fields for iomap, iomap_size
|
||||
and ioranges. Add new Kconfig symbol CONFIG_LAN969X_CONFIG for compiling
|
||||
the lan969x driver.
|
||||
|
||||
It has been decided to give lan969x its own Kconfig symbol, as a
|
||||
considerable amount of code is needed, beside the Sparx5 code, to add
|
||||
full chip support (and more will be added in future series). Also this
|
||||
makes it possible to compile Sparx5 without lan969x.
|
||||
|
||||
Reviewed-by: Steen Hegelund <Steen.Hegelund@microchip.com>
|
||||
Signed-off-by: Daniel Machon <daniel.machon@microchip.com>
|
||||
Link: https://patch.msgid.link/20241024-sparx5-lan969x-switch-driver-2-v2-6-a0b5fae88a0f@microchip.com
|
||||
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
|
||||
---
|
||||
MAINTAINERS | 7 ++
|
||||
drivers/net/ethernet/microchip/Kconfig | 1 +
|
||||
drivers/net/ethernet/microchip/Makefile | 1 +
|
||||
.../net/ethernet/microchip/lan969x/Kconfig | 5 +
|
||||
.../net/ethernet/microchip/lan969x/Makefile | 12 ++
|
||||
.../net/ethernet/microchip/lan969x/lan969x.c | 104 ++++++++++++++++++
|
||||
.../net/ethernet/microchip/lan969x/lan969x.h | 15 +++
|
||||
7 files changed, 145 insertions(+)
|
||||
create mode 100644 drivers/net/ethernet/microchip/lan969x/Kconfig
|
||||
create mode 100644 drivers/net/ethernet/microchip/lan969x/Makefile
|
||||
create mode 100644 drivers/net/ethernet/microchip/lan969x/lan969x.c
|
||||
create mode 100644 drivers/net/ethernet/microchip/lan969x/lan969x.h
|
||||
|
||||
--- a/MAINTAINERS
|
||||
+++ b/MAINTAINERS
|
||||
@@ -15147,6 +15147,13 @@ S: Maintained
|
||||
F: Documentation/devicetree/bindings/interrupt-controller/microchip,lan966x-oic.yaml
|
||||
F: drivers/irqchip/irq-lan966x-oic.c
|
||||
|
||||
+MICROCHIP LAN969X ETHERNET DRIVER
|
||||
+M: Daniel Machon <daniel.machon@microchip.com>
|
||||
+M: UNGLinuxDriver@microchip.com
|
||||
+L: netdev@vger.kernel.org
|
||||
+S: Maintained
|
||||
+F: drivers/net/ethernet/microchip/lan969x/*
|
||||
+
|
||||
MICROCHIP LCDFB DRIVER
|
||||
M: Nicolas Ferre <nicolas.ferre@microchip.com>
|
||||
L: linux-fbdev@vger.kernel.org
|
||||
--- a/drivers/net/ethernet/microchip/Kconfig
|
||||
+++ b/drivers/net/ethernet/microchip/Kconfig
|
||||
@@ -59,6 +59,7 @@ config LAN743X
|
||||
|
||||
source "drivers/net/ethernet/microchip/lan865x/Kconfig"
|
||||
source "drivers/net/ethernet/microchip/lan966x/Kconfig"
|
||||
+source "drivers/net/ethernet/microchip/lan969x/Kconfig"
|
||||
source "drivers/net/ethernet/microchip/sparx5/Kconfig"
|
||||
source "drivers/net/ethernet/microchip/vcap/Kconfig"
|
||||
source "drivers/net/ethernet/microchip/fdma/Kconfig"
|
||||
--- a/drivers/net/ethernet/microchip/Makefile
|
||||
+++ b/drivers/net/ethernet/microchip/Makefile
|
||||
@@ -11,6 +11,7 @@ lan743x-objs := lan743x_main.o lan743x_e
|
||||
|
||||
obj-$(CONFIG_LAN865X) += lan865x/
|
||||
obj-$(CONFIG_LAN966X_SWITCH) += lan966x/
|
||||
+obj-$(CONFIG_LAN969X_SWITCH) += lan969x/
|
||||
obj-$(CONFIG_SPARX5_SWITCH) += sparx5/
|
||||
obj-$(CONFIG_VCAP) += vcap/
|
||||
obj-$(CONFIG_FDMA) += fdma/
|
||||
--- /dev/null
|
||||
+++ b/drivers/net/ethernet/microchip/lan969x/Kconfig
|
||||
@@ -0,0 +1,5 @@
|
||||
+config LAN969X_SWITCH
|
||||
+ tristate "Lan969x switch driver"
|
||||
+ depends on SPARX5_SWITCH
|
||||
+ help
|
||||
+ This driver supports the lan969x family of network switch devices.
|
||||
--- /dev/null
|
||||
+++ b/drivers/net/ethernet/microchip/lan969x/Makefile
|
||||
@@ -0,0 +1,12 @@
|
||||
+# SPDX-License-Identifier: GPL-2.0-only
|
||||
+#
|
||||
+# Makefile for the Microchip lan969x network device drivers.
|
||||
+#
|
||||
+
|
||||
+obj-$(CONFIG_LAN969X_SWITCH) += lan969x-switch.o
|
||||
+
|
||||
+lan969x-switch-y := lan969x.o
|
||||
+
|
||||
+# Provide include files
|
||||
+ccflags-y += -I$(srctree)/drivers/net/ethernet/microchip/fdma
|
||||
+ccflags-y += -I$(srctree)/drivers/net/ethernet/microchip/vcap
|
||||
--- /dev/null
|
||||
+++ b/drivers/net/ethernet/microchip/lan969x/lan969x.c
|
||||
@@ -0,0 +1,104 @@
|
||||
+// SPDX-License-Identifier: GPL-2.0+
|
||||
+/* Microchip lan969x Switch driver
|
||||
+ *
|
||||
+ * Copyright (c) 2024 Microchip Technology Inc. and its subsidiaries.
|
||||
+ */
|
||||
+
|
||||
+#include "lan969x.h"
|
||||
+
|
||||
+static const struct sparx5_main_io_resource lan969x_main_iomap[] = {
|
||||
+ { TARGET_CPU, 0xc0000, 0 }, /* 0xe00c0000 */
|
||||
+ { TARGET_FDMA, 0xc0400, 0 }, /* 0xe00c0400 */
|
||||
+ { TARGET_GCB, 0x2010000, 1 }, /* 0xe2010000 */
|
||||
+ { TARGET_QS, 0x2030000, 1 }, /* 0xe2030000 */
|
||||
+ { TARGET_PTP, 0x2040000, 1 }, /* 0xe2040000 */
|
||||
+ { TARGET_ANA_ACL, 0x2050000, 1 }, /* 0xe2050000 */
|
||||
+ { TARGET_LRN, 0x2060000, 1 }, /* 0xe2060000 */
|
||||
+ { TARGET_VCAP_SUPER, 0x2080000, 1 }, /* 0xe2080000 */
|
||||
+ { TARGET_QSYS, 0x20a0000, 1 }, /* 0xe20a0000 */
|
||||
+ { TARGET_QFWD, 0x20b0000, 1 }, /* 0xe20b0000 */
|
||||
+ { TARGET_XQS, 0x20c0000, 1 }, /* 0xe20c0000 */
|
||||
+ { TARGET_VCAP_ES2, 0x20d0000, 1 }, /* 0xe20d0000 */
|
||||
+ { TARGET_VCAP_ES0, 0x20e0000, 1 }, /* 0xe20e0000 */
|
||||
+ { TARGET_ANA_AC_POL, 0x2200000, 1 }, /* 0xe2200000 */
|
||||
+ { TARGET_QRES, 0x2280000, 1 }, /* 0xe2280000 */
|
||||
+ { TARGET_EACL, 0x22c0000, 1 }, /* 0xe22c0000 */
|
||||
+ { TARGET_ANA_CL, 0x2400000, 1 }, /* 0xe2400000 */
|
||||
+ { TARGET_ANA_L3, 0x2480000, 1 }, /* 0xe2480000 */
|
||||
+ { TARGET_ANA_AC_SDLB, 0x2500000, 1 }, /* 0xe2500000 */
|
||||
+ { TARGET_HSCH, 0x2580000, 1 }, /* 0xe2580000 */
|
||||
+ { TARGET_REW, 0x2600000, 1 }, /* 0xe2600000 */
|
||||
+ { TARGET_ANA_L2, 0x2800000, 1 }, /* 0xe2800000 */
|
||||
+ { TARGET_ANA_AC, 0x2900000, 1 }, /* 0xe2900000 */
|
||||
+ { TARGET_VOP, 0x2a00000, 1 }, /* 0xe2a00000 */
|
||||
+ { TARGET_DEV2G5, 0x3004000, 1 }, /* 0xe3004000 */
|
||||
+ { TARGET_DEV10G, 0x3008000, 1 }, /* 0xe3008000 */
|
||||
+ { TARGET_PCS10G_BR, 0x300c000, 1 }, /* 0xe300c000 */
|
||||
+ { TARGET_DEV2G5 + 1, 0x3010000, 1 }, /* 0xe3010000 */
|
||||
+ { TARGET_DEV2G5 + 2, 0x3014000, 1 }, /* 0xe3014000 */
|
||||
+ { TARGET_DEV2G5 + 3, 0x3018000, 1 }, /* 0xe3018000 */
|
||||
+ { TARGET_DEV2G5 + 4, 0x301c000, 1 }, /* 0xe301c000 */
|
||||
+ { TARGET_DEV10G + 1, 0x3020000, 1 }, /* 0xe3020000 */
|
||||
+ { TARGET_PCS10G_BR + 1, 0x3024000, 1 }, /* 0xe3024000 */
|
||||
+ { TARGET_DEV2G5 + 5, 0x3028000, 1 }, /* 0xe3028000 */
|
||||
+ { TARGET_DEV2G5 + 6, 0x302c000, 1 }, /* 0xe302c000 */
|
||||
+ { TARGET_DEV2G5 + 7, 0x3030000, 1 }, /* 0xe3030000 */
|
||||
+ { TARGET_DEV2G5 + 8, 0x3034000, 1 }, /* 0xe3034000 */
|
||||
+ { TARGET_DEV10G + 2, 0x3038000, 1 }, /* 0xe3038000 */
|
||||
+ { TARGET_PCS10G_BR + 2, 0x303c000, 1 }, /* 0xe303c000 */
|
||||
+ { TARGET_DEV2G5 + 9, 0x3040000, 1 }, /* 0xe3040000 */
|
||||
+ { TARGET_DEV5G, 0x3044000, 1 }, /* 0xe3044000 */
|
||||
+ { TARGET_PCS5G_BR, 0x3048000, 1 }, /* 0xe3048000 */
|
||||
+ { TARGET_DEV2G5 + 10, 0x304c000, 1 }, /* 0xe304c000 */
|
||||
+ { TARGET_DEV2G5 + 11, 0x3050000, 1 }, /* 0xe3050000 */
|
||||
+ { TARGET_DEV2G5 + 12, 0x3054000, 1 }, /* 0xe3054000 */
|
||||
+ { TARGET_DEV10G + 3, 0x3058000, 1 }, /* 0xe3058000 */
|
||||
+ { TARGET_PCS10G_BR + 3, 0x305c000, 1 }, /* 0xe305c000 */
|
||||
+ { TARGET_DEV2G5 + 13, 0x3060000, 1 }, /* 0xe3060000 */
|
||||
+ { TARGET_DEV5G + 1, 0x3064000, 1 }, /* 0xe3064000 */
|
||||
+ { TARGET_PCS5G_BR + 1, 0x3068000, 1 }, /* 0xe3068000 */
|
||||
+ { TARGET_DEV2G5 + 14, 0x306c000, 1 }, /* 0xe306c000 */
|
||||
+ { TARGET_DEV2G5 + 15, 0x3070000, 1 }, /* 0xe3070000 */
|
||||
+ { TARGET_DEV2G5 + 16, 0x3074000, 1 }, /* 0xe3074000 */
|
||||
+ { TARGET_DEV10G + 4, 0x3078000, 1 }, /* 0xe3078000 */
|
||||
+ { TARGET_PCS10G_BR + 4, 0x307c000, 1 }, /* 0xe307c000 */
|
||||
+ { TARGET_DEV2G5 + 17, 0x3080000, 1 }, /* 0xe3080000 */
|
||||
+ { TARGET_DEV5G + 2, 0x3084000, 1 }, /* 0xe3084000 */
|
||||
+ { TARGET_PCS5G_BR + 2, 0x3088000, 1 }, /* 0xe3088000 */
|
||||
+ { TARGET_DEV2G5 + 18, 0x308c000, 1 }, /* 0xe308c000 */
|
||||
+ { TARGET_DEV2G5 + 19, 0x3090000, 1 }, /* 0xe3090000 */
|
||||
+ { TARGET_DEV2G5 + 20, 0x3094000, 1 }, /* 0xe3094000 */
|
||||
+ { TARGET_DEV10G + 5, 0x3098000, 1 }, /* 0xe3098000 */
|
||||
+ { TARGET_PCS10G_BR + 5, 0x309c000, 1 }, /* 0xe309c000 */
|
||||
+ { TARGET_DEV2G5 + 21, 0x30a0000, 1 }, /* 0xe30a0000 */
|
||||
+ { TARGET_DEV5G + 3, 0x30a4000, 1 }, /* 0xe30a4000 */
|
||||
+ { TARGET_PCS5G_BR + 3, 0x30a8000, 1 }, /* 0xe30a8000 */
|
||||
+ { TARGET_DEV2G5 + 22, 0x30ac000, 1 }, /* 0xe30ac000 */
|
||||
+ { TARGET_DEV2G5 + 23, 0x30b0000, 1 }, /* 0xe30b0000 */
|
||||
+ { TARGET_DEV2G5 + 24, 0x30b4000, 1 }, /* 0xe30b4000 */
|
||||
+ { TARGET_DEV10G + 6, 0x30b8000, 1 }, /* 0xe30b8000 */
|
||||
+ { TARGET_PCS10G_BR + 6, 0x30bc000, 1 }, /* 0xe30bc000 */
|
||||
+ { TARGET_DEV2G5 + 25, 0x30c0000, 1 }, /* 0xe30c0000 */
|
||||
+ { TARGET_DEV10G + 7, 0x30c4000, 1 }, /* 0xe30c4000 */
|
||||
+ { TARGET_PCS10G_BR + 7, 0x30c8000, 1 }, /* 0xe30c8000 */
|
||||
+ { TARGET_DEV2G5 + 26, 0x30cc000, 1 }, /* 0xe30cc000 */
|
||||
+ { TARGET_DEV10G + 8, 0x30d0000, 1 }, /* 0xe30d0000 */
|
||||
+ { TARGET_PCS10G_BR + 8, 0x30d4000, 1 }, /* 0xe30d4000 */
|
||||
+ { TARGET_DEV2G5 + 27, 0x30d8000, 1 }, /* 0xe30d8000 */
|
||||
+ { TARGET_DEV10G + 9, 0x30dc000, 1 }, /* 0xe30dc000 */
|
||||
+ { TARGET_PCS10G_BR + 9, 0x30e0000, 1 }, /* 0xe30e0000 */
|
||||
+ { TARGET_DSM, 0x30ec000, 1 }, /* 0xe30ec000 */
|
||||
+ { TARGET_PORT_CONF, 0x30f0000, 1 }, /* 0xe30f0000 */
|
||||
+ { TARGET_ASM, 0x3200000, 1 }, /* 0xe3200000 */
|
||||
+};
|
||||
+
|
||||
+const struct sparx5_match_data lan969x_desc = {
|
||||
+ .iomap = lan969x_main_iomap,
|
||||
+ .iomap_size = ARRAY_SIZE(lan969x_main_iomap),
|
||||
+ .ioranges = 2,
|
||||
+};
|
||||
+EXPORT_SYMBOL_GPL(lan969x_desc);
|
||||
+
|
||||
+MODULE_DESCRIPTION("Microchip lan969x switch driver");
|
||||
+MODULE_AUTHOR("Daniel Machon <daniel.machon@microchip.com>");
|
||||
+MODULE_LICENSE("Dual MIT/GPL");
|
||||
--- /dev/null
|
||||
+++ b/drivers/net/ethernet/microchip/lan969x/lan969x.h
|
||||
@@ -0,0 +1,15 @@
|
||||
+/* SPDX-License-Identifier: GPL-2.0+ */
|
||||
+/* Microchip lan969x Switch driver
|
||||
+ *
|
||||
+ * Copyright (c) 2024 Microchip Technology Inc. and its subsidiaries.
|
||||
+ */
|
||||
+
|
||||
+#ifndef __LAN969X_H__
|
||||
+#define __LAN969X_H__
|
||||
+
|
||||
+#include "../sparx5/sparx5_main.h"
|
||||
+
|
||||
+/* lan969x.c */
|
||||
+extern const struct sparx5_match_data lan969x_desc;
|
||||
+
|
||||
+#endif
|
||||
@ -0,0 +1,365 @@
|
||||
From d68c6bbfd6ba14f5c2987a59f1d6fb4a4688204e Mon Sep 17 00:00:00 2001
|
||||
From: Daniel Machon <daniel.machon@microchip.com>
|
||||
Date: Thu, 24 Oct 2024 00:01:26 +0200
|
||||
Subject: [PATCH 50/82] net: lan969x: add register diffs to match data
|
||||
|
||||
Add new file lan969x_regs.c that defines all the register differences
|
||||
for lan969x, and add it to the lan969x match data.
|
||||
|
||||
GW_DEV2G5_PHASE_DETECTOR_CTRL, FP_DEV2G5_PHAD_CTRL_PHAD_ENA and
|
||||
FP_DEV2G5_PHAD_CTRL_PHAD_FAILED are required by the new register macros
|
||||
which was introduced earlier. Add these for Sparx5 also.
|
||||
|
||||
Reviewed-by: Steen Hegelund <Steen.Hegelund@microchip.com>
|
||||
Signed-off-by: Daniel Machon <daniel.machon@microchip.com>
|
||||
Link: https://patch.msgid.link/20241024-sparx5-lan969x-switch-driver-2-v2-7-a0b5fae88a0f@microchip.com
|
||||
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
|
||||
---
|
||||
.../net/ethernet/microchip/lan969x/Makefile | 2 +-
|
||||
.../net/ethernet/microchip/lan969x/lan969x.c | 12 +
|
||||
.../net/ethernet/microchip/lan969x/lan969x.h | 11 +
|
||||
.../ethernet/microchip/lan969x/lan969x_regs.c | 222 ++++++++++++++++++
|
||||
.../ethernet/microchip/sparx5/sparx5_regs.c | 5 +-
|
||||
.../ethernet/microchip/sparx5/sparx5_regs.h | 5 +-
|
||||
6 files changed, 254 insertions(+), 3 deletions(-)
|
||||
create mode 100644 drivers/net/ethernet/microchip/lan969x/lan969x_regs.c
|
||||
|
||||
--- a/drivers/net/ethernet/microchip/lan969x/Makefile
|
||||
+++ b/drivers/net/ethernet/microchip/lan969x/Makefile
|
||||
@@ -5,7 +5,7 @@
|
||||
|
||||
obj-$(CONFIG_LAN969X_SWITCH) += lan969x-switch.o
|
||||
|
||||
-lan969x-switch-y := lan969x.o
|
||||
+lan969x-switch-y := lan969x_regs.o lan969x.o
|
||||
|
||||
# Provide include files
|
||||
ccflags-y += -I$(srctree)/drivers/net/ethernet/microchip/fdma
|
||||
--- a/drivers/net/ethernet/microchip/lan969x/lan969x.c
|
||||
+++ b/drivers/net/ethernet/microchip/lan969x/lan969x.c
|
||||
@@ -92,10 +92,22 @@ static const struct sparx5_main_io_resou
|
||||
{ TARGET_ASM, 0x3200000, 1 }, /* 0xe3200000 */
|
||||
};
|
||||
|
||||
+static const struct sparx5_regs lan969x_regs = {
|
||||
+ .tsize = lan969x_tsize,
|
||||
+ .gaddr = lan969x_gaddr,
|
||||
+ .gcnt = lan969x_gcnt,
|
||||
+ .gsize = lan969x_gsize,
|
||||
+ .raddr = lan969x_raddr,
|
||||
+ .rcnt = lan969x_rcnt,
|
||||
+ .fpos = lan969x_fpos,
|
||||
+ .fsize = lan969x_fsize,
|
||||
+};
|
||||
+
|
||||
const struct sparx5_match_data lan969x_desc = {
|
||||
.iomap = lan969x_main_iomap,
|
||||
.iomap_size = ARRAY_SIZE(lan969x_main_iomap),
|
||||
.ioranges = 2,
|
||||
+ .regs = &lan969x_regs,
|
||||
};
|
||||
EXPORT_SYMBOL_GPL(lan969x_desc);
|
||||
|
||||
--- a/drivers/net/ethernet/microchip/lan969x/lan969x.h
|
||||
+++ b/drivers/net/ethernet/microchip/lan969x/lan969x.h
|
||||
@@ -8,8 +8,19 @@
|
||||
#define __LAN969X_H__
|
||||
|
||||
#include "../sparx5/sparx5_main.h"
|
||||
+#include "../sparx5/sparx5_regs.h"
|
||||
|
||||
/* lan969x.c */
|
||||
extern const struct sparx5_match_data lan969x_desc;
|
||||
|
||||
+/* lan969x_regs.c */
|
||||
+extern const unsigned int lan969x_tsize[TSIZE_LAST];
|
||||
+extern const unsigned int lan969x_raddr[RADDR_LAST];
|
||||
+extern const unsigned int lan969x_rcnt[RCNT_LAST];
|
||||
+extern const unsigned int lan969x_gaddr[GADDR_LAST];
|
||||
+extern const unsigned int lan969x_gcnt[GCNT_LAST];
|
||||
+extern const unsigned int lan969x_gsize[GSIZE_LAST];
|
||||
+extern const unsigned int lan969x_fpos[FPOS_LAST];
|
||||
+extern const unsigned int lan969x_fsize[FSIZE_LAST];
|
||||
+
|
||||
#endif
|
||||
--- /dev/null
|
||||
+++ b/drivers/net/ethernet/microchip/lan969x/lan969x_regs.c
|
||||
@@ -0,0 +1,222 @@
|
||||
+// SPDX-License-Identifier: GPL-2.0+
|
||||
+/* Microchip lan969x Switch driver
|
||||
+ *
|
||||
+ * Copyright (c) 2024 Microchip Technology Inc.
|
||||
+ */
|
||||
+
|
||||
+/* This file is autogenerated by cml-utils 2024-09-30 11:48:29 +0200.
|
||||
+ * Commit ID: 9d07b8d19363f3cd3590ddb3f7a2e2768e16524b
|
||||
+ */
|
||||
+
|
||||
+#include "lan969x.h"
|
||||
+
|
||||
+const unsigned int lan969x_tsize[TSIZE_LAST] = {
|
||||
+ [TC_DEV10G] = 10,
|
||||
+ [TC_DEV2G5] = 28,
|
||||
+ [TC_DEV5G] = 4,
|
||||
+ [TC_PCS10G_BR] = 10,
|
||||
+ [TC_PCS5G_BR] = 4,
|
||||
+};
|
||||
+
|
||||
+const unsigned int lan969x_raddr[RADDR_LAST] = {
|
||||
+ [RA_CPU_PROC_CTRL] = 160,
|
||||
+ [RA_GCB_SOFT_RST] = 12,
|
||||
+ [RA_GCB_HW_SGPIO_TO_SD_MAP_CFG] = 20,
|
||||
+};
|
||||
+
|
||||
+const unsigned int lan969x_rcnt[RCNT_LAST] = {
|
||||
+ [RC_ANA_AC_OWN_UPSID] = 1,
|
||||
+ [RC_ANA_ACL_VCAP_S2_CFG] = 35,
|
||||
+ [RC_ANA_ACL_OWN_UPSID] = 1,
|
||||
+ [RC_ANA_CL_OWN_UPSID] = 1,
|
||||
+ [RC_ANA_L2_OWN_UPSID] = 1,
|
||||
+ [RC_ASM_PORT_CFG] = 32,
|
||||
+ [RC_DSM_BUF_CFG] = 32,
|
||||
+ [RC_DSM_DEV_TX_STOP_WM_CFG] = 32,
|
||||
+ [RC_DSM_RX_PAUSE_CFG] = 32,
|
||||
+ [RC_DSM_MAC_CFG] = 32,
|
||||
+ [RC_DSM_MAC_ADDR_BASE_HIGH_CFG] = 30,
|
||||
+ [RC_DSM_MAC_ADDR_BASE_LOW_CFG] = 30,
|
||||
+ [RC_DSM_TAXI_CAL_CFG] = 6,
|
||||
+ [RC_GCB_HW_SGPIO_TO_SD_MAP_CFG] = 30,
|
||||
+ [RC_HSCH_PORT_MODE] = 35,
|
||||
+ [RC_QFWD_SWITCH_PORT_MODE] = 35,
|
||||
+ [RC_QSYS_PAUSE_CFG] = 35,
|
||||
+ [RC_QSYS_ATOP] = 35,
|
||||
+ [RC_QSYS_FWD_PRESSURE] = 35,
|
||||
+ [RC_QSYS_CAL_AUTO] = 4,
|
||||
+ [RC_REW_OWN_UPSID] = 1,
|
||||
+ [RC_REW_RTAG_ETAG_CTRL] = 35,
|
||||
+};
|
||||
+
|
||||
+const unsigned int lan969x_gaddr[GADDR_LAST] = {
|
||||
+ [GA_ANA_AC_RAM_CTRL] = 202000,
|
||||
+ [GA_ANA_AC_PS_COMMON] = 202880,
|
||||
+ [GA_ANA_AC_MIRROR_PROBE] = 203232,
|
||||
+ [GA_ANA_AC_SRC] = 201728,
|
||||
+ [GA_ANA_AC_PGID] = 131072,
|
||||
+ [GA_ANA_AC_TSN_SF] = 202028,
|
||||
+ [GA_ANA_AC_TSN_SF_CFG] = 148480,
|
||||
+ [GA_ANA_AC_TSN_SF_STATUS] = 147936,
|
||||
+ [GA_ANA_AC_SG_ACCESS] = 202032,
|
||||
+ [GA_ANA_AC_SG_CONFIG] = 202752,
|
||||
+ [GA_ANA_AC_SG_STATUS] = 147952,
|
||||
+ [GA_ANA_AC_SG_STATUS_STICKY] = 202044,
|
||||
+ [GA_ANA_AC_STAT_GLOBAL_CFG_PORT] = 202048,
|
||||
+ [GA_ANA_AC_STAT_CNT_CFG_PORT] = 204800,
|
||||
+ [GA_ANA_AC_STAT_GLOBAL_CFG_ACL] = 202068,
|
||||
+ [GA_ANA_ACL_COMMON] = 8192,
|
||||
+ [GA_ANA_ACL_KEY_SEL] = 9204,
|
||||
+ [GA_ANA_ACL_CNT_B] = 4096,
|
||||
+ [GA_ANA_ACL_STICKY] = 10852,
|
||||
+ [GA_ANA_AC_POL_POL_ALL_CFG] = 17504,
|
||||
+ [GA_ANA_AC_POL_COMMON_BDLB] = 19464,
|
||||
+ [GA_ANA_AC_POL_COMMON_BUM_SLB] = 19472,
|
||||
+ [GA_ANA_AC_SDLB_LBGRP_TBL] = 31788,
|
||||
+ [GA_ANA_CL_PORT] = 65536,
|
||||
+ [GA_ANA_CL_COMMON] = 87040,
|
||||
+ [GA_ANA_L2_COMMON] = 561928,
|
||||
+ [GA_ANA_L3_COMMON] = 370752,
|
||||
+ [GA_ANA_L3_VLAN_ARP_L3MC_STICKY] = 368580,
|
||||
+ [GA_ASM_CFG] = 18304,
|
||||
+ [GA_ASM_PFC_TIMER_CFG] = 15568,
|
||||
+ [GA_ASM_LBK_WM_CFG] = 15596,
|
||||
+ [GA_ASM_LBK_MISC_CFG] = 15608,
|
||||
+ [GA_ASM_RAM_CTRL] = 15684,
|
||||
+ [GA_EACL_ES2_KEY_SELECT_PROFILE] = 36864,
|
||||
+ [GA_EACL_CNT_TBL] = 30720,
|
||||
+ [GA_EACL_POL_CFG] = 38400,
|
||||
+ [GA_EACL_ES2_STICKY] = 29072,
|
||||
+ [GA_EACL_RAM_CTRL] = 29112,
|
||||
+ [GA_GCB_SIO_CTRL] = 560,
|
||||
+ [GA_HSCH_HSCH_DWRR] = 36480,
|
||||
+ [GA_HSCH_HSCH_MISC] = 36608,
|
||||
+ [GA_HSCH_HSCH_LEAK_LISTS] = 37256,
|
||||
+ [GA_HSCH_SYSTEM] = 37384,
|
||||
+ [GA_HSCH_MMGT] = 36260,
|
||||
+ [GA_HSCH_TAS_CONFIG] = 37696,
|
||||
+ [GA_PTP_PTP_CFG] = 512,
|
||||
+ [GA_PTP_PTP_TOD_DOMAINS] = 528,
|
||||
+ [GA_PTP_PHASE_DETECTOR_CTRL] = 628,
|
||||
+ [GA_QSYS_CALCFG] = 2164,
|
||||
+ [GA_QSYS_RAM_CTRL] = 2204,
|
||||
+ [GA_REW_COMMON] = 98304,
|
||||
+ [GA_REW_PORT] = 49152,
|
||||
+ [GA_REW_VOE_PORT_LM_CNT] = 90112,
|
||||
+ [GA_REW_RAM_CTRL] = 93992,
|
||||
+ [GA_VOP_RAM_CTRL] = 16368,
|
||||
+ [GA_XQS_SYSTEM] = 5744,
|
||||
+ [GA_XQS_QLIMIT_SHR] = 6912,
|
||||
+};
|
||||
+
|
||||
+const unsigned int lan969x_gcnt[GCNT_LAST] = {
|
||||
+ [GC_ANA_AC_SRC] = 67,
|
||||
+ [GC_ANA_AC_PGID] = 1054,
|
||||
+ [GC_ANA_AC_TSN_SF_CFG] = 256,
|
||||
+ [GC_ANA_AC_STAT_CNT_CFG_PORT] = 35,
|
||||
+ [GC_ANA_ACL_KEY_SEL] = 99,
|
||||
+ [GC_ANA_ACL_CNT_A] = 1024,
|
||||
+ [GC_ANA_ACL_CNT_B] = 1024,
|
||||
+ [GC_ANA_AC_SDLB_LBGRP_TBL] = 5,
|
||||
+ [GC_ANA_AC_SDLB_LBSET_TBL] = 496,
|
||||
+ [GC_ANA_CL_PORT] = 35,
|
||||
+ [GC_ANA_L2_ISDX_LIMIT] = 256,
|
||||
+ [GC_ANA_L2_ISDX] = 1024,
|
||||
+ [GC_ANA_L3_VLAN] = 4608,
|
||||
+ [GC_ASM_DEV_STATISTICS] = 30,
|
||||
+ [GC_EACL_ES2_KEY_SELECT_PROFILE] = 68,
|
||||
+ [GC_EACL_CNT_TBL] = 512,
|
||||
+ [GC_GCB_SIO_CTRL] = 1,
|
||||
+ [GC_HSCH_HSCH_CFG] = 1120,
|
||||
+ [GC_HSCH_HSCH_DWRR] = 32,
|
||||
+ [GC_PTP_PTP_PINS] = 8,
|
||||
+ [GC_PTP_PHASE_DETECTOR_CTRL] = 8,
|
||||
+ [GC_REW_PORT] = 35,
|
||||
+ [GC_REW_VOE_PORT_LM_CNT] = 240,
|
||||
+};
|
||||
+
|
||||
+const unsigned int lan969x_gsize[GSIZE_LAST] = {
|
||||
+ [GW_ANA_AC_SRC] = 4,
|
||||
+ [GW_ANA_L2_COMMON] = 712,
|
||||
+ [GW_ASM_CFG] = 1092,
|
||||
+ [GW_CPU_CPU_REGS] = 180,
|
||||
+ [GW_DEV2G5_PHASE_DETECTOR_CTRL] = 12,
|
||||
+ [GW_FDMA_FDMA] = 448,
|
||||
+ [GW_GCB_CHIP_REGS] = 180,
|
||||
+ [GW_HSCH_TAS_CONFIG] = 16,
|
||||
+ [GW_PTP_PHASE_DETECTOR_CTRL] = 12,
|
||||
+ [GW_QSYS_PAUSE_CFG] = 988,
|
||||
+};
|
||||
+
|
||||
+const unsigned int lan969x_fpos[FPOS_LAST] = {
|
||||
+ [FP_CPU_PROC_CTRL_AARCH64_MODE_ENA] = 7,
|
||||
+ [FP_CPU_PROC_CTRL_L2_RST_INVALIDATE_DIS] = 6,
|
||||
+ [FP_CPU_PROC_CTRL_L1_RST_INVALIDATE_DIS] = 5,
|
||||
+ [FP_CPU_PROC_CTRL_BE_EXCEP_MODE] = 4,
|
||||
+ [FP_CPU_PROC_CTRL_VINITHI] = 3,
|
||||
+ [FP_CPU_PROC_CTRL_CFGTE] = 2,
|
||||
+ [FP_CPU_PROC_CTRL_CP15S_DISABLE] = 1,
|
||||
+ [FP_CPU_PROC_CTRL_PROC_CRYPTO_DISABLE] = 0,
|
||||
+ [FP_CPU_PROC_CTRL_L2_FLUSH_REQ] = 8,
|
||||
+ [FP_DEV2G5_PHAD_CTRL_PHAD_ENA] = 5,
|
||||
+ [FP_DEV2G5_PHAD_CTRL_PHAD_FAILED] = 3,
|
||||
+ [FP_FDMA_CH_CFG_CH_XTR_STATUS_MODE] = 5,
|
||||
+ [FP_FDMA_CH_CFG_CH_INTR_DB_EOF_ONLY] = 4,
|
||||
+ [FP_FDMA_CH_CFG_CH_INJ_PORT] = 3,
|
||||
+ [FP_PTP_PTP_PIN_CFG_PTP_PIN_ACTION] = 27,
|
||||
+ [FP_PTP_PTP_PIN_CFG_PTP_PIN_SYNC] = 25,
|
||||
+ [FP_PTP_PTP_PIN_CFG_PTP_PIN_INV_POL] = 24,
|
||||
+ [FP_PTP_PHAD_CTRL_PHAD_ENA] = 5,
|
||||
+ [FP_PTP_PHAD_CTRL_PHAD_FAILED] = 3,
|
||||
+};
|
||||
+
|
||||
+const unsigned int lan969x_fsize[FSIZE_LAST] = {
|
||||
+ [FW_ANA_AC_PROBE_PORT_CFG_PROBE_PORT_MASK] = 30,
|
||||
+ [FW_ANA_AC_SRC_CFG_PORT_MASK] = 30,
|
||||
+ [FW_ANA_AC_PGID_CFG_PORT_MASK] = 30,
|
||||
+ [FW_ANA_AC_TSN_SF_PORT_NUM] = 7,
|
||||
+ [FW_ANA_AC_TSN_SF_CFG_TSN_SGID] = 8,
|
||||
+ [FW_ANA_AC_TSN_SF_STATUS_TSN_SFID] = 8,
|
||||
+ [FW_ANA_AC_SG_ACCESS_CTRL_SGID] = 8,
|
||||
+ [FW_ANA_AC_PORT_SGE_CFG_MASK] = 17,
|
||||
+ [FW_ANA_AC_SDLB_XLB_START_LBSET_START] = 9,
|
||||
+ [FW_ANA_AC_SDLB_LBGRP_MISC_THRES_SHIFT] = 3,
|
||||
+ [FW_ANA_AC_SDLB_LBGRP_STATE_TBL_PUP_LBSET_NEXT] = 9,
|
||||
+ [FW_ANA_AC_SDLB_XLB_NEXT_LBSET_NEXT] = 9,
|
||||
+ [FW_ANA_AC_SDLB_XLB_NEXT_LBGRP] = 3,
|
||||
+ [FW_ANA_AC_SDLB_INH_LBSET_ADDR_INH_LBSET_ADDR] = 9,
|
||||
+ [FW_ANA_L2_AUTO_LRN_CFG_AUTO_LRN_ENA] = 30,
|
||||
+ [FW_ANA_L2_DLB_CFG_DLB_IDX] = 9,
|
||||
+ [FW_ANA_L2_TSN_CFG_TSN_SFID] = 8,
|
||||
+ [FW_ANA_L3_VLAN_MASK_CFG_VLAN_PORT_MASK] = 30,
|
||||
+ [FW_FDMA_CH_CFG_CH_DCB_DB_CNT] = 2,
|
||||
+ [FW_GCB_HW_SGPIO_TO_SD_MAP_CFG_SGPIO_TO_SD_SEL] = 7,
|
||||
+ [FW_HSCH_SE_CFG_SE_DWRR_CNT] = 5,
|
||||
+ [FW_HSCH_SE_CONNECT_SE_LEAK_LINK] = 14,
|
||||
+ [FW_HSCH_SE_DLB_SENSE_SE_DLB_DPORT] = 6,
|
||||
+ [FW_HSCH_HSCH_CFG_CFG_CFG_SE_IDX] = 11,
|
||||
+ [FW_HSCH_HSCH_LEAK_CFG_LEAK_FIRST] = 14,
|
||||
+ [FW_HSCH_FLUSH_CTRL_FLUSH_PORT] = 6,
|
||||
+ [FW_HSCH_FLUSH_CTRL_FLUSH_HIER] = 14,
|
||||
+ [FW_LRN_COMMON_ACCESS_CTRL_CPU_ACCESS_DIRECT_ROW] = 13,
|
||||
+ [FW_LRN_MAC_ACCESS_CFG_3_MAC_ENTRY_ISDX_LIMIT_IDX] = 8,
|
||||
+ [FW_LRN_AUTOAGE_CFG_2_NEXT_ROW] = 13,
|
||||
+ [FW_PTP_PTP_PIN_INTR_INTR_PTP] = 8,
|
||||
+ [FW_PTP_PTP_PIN_INTR_ENA_INTR_PTP_ENA] = 8,
|
||||
+ [FW_PTP_PTP_INTR_IDENT_INTR_PTP_IDENT] = 8,
|
||||
+ [FW_PTP_PTP_PIN_CFG_PTP_PIN_SELECT] = 3,
|
||||
+ [FW_QFWD_FRAME_COPY_CFG_FRMC_PORT_VAL] = 6,
|
||||
+ [FW_QRES_RES_CFG_WM_HIGH] = 11,
|
||||
+ [FW_QRES_RES_STAT_MAXUSE] = 19,
|
||||
+ [FW_QRES_RES_STAT_CUR_INUSE] = 19,
|
||||
+ [FW_QSYS_PAUSE_CFG_PAUSE_START] = 11,
|
||||
+ [FW_QSYS_PAUSE_CFG_PAUSE_STOP] = 11,
|
||||
+ [FW_QSYS_ATOP_ATOP] = 11,
|
||||
+ [FW_QSYS_ATOP_TOT_CFG_ATOP_TOT] = 11,
|
||||
+ [FW_REW_RTAG_ETAG_CTRL_IPE_TBL] = 6,
|
||||
+ [FW_XQS_STAT_CFG_STAT_VIEW] = 10,
|
||||
+ [FW_XQS_QLIMIT_SHR_TOP_CFG_QLIMIT_SHR_TOP] = 14,
|
||||
+ [FW_XQS_QLIMIT_SHR_ATOP_CFG_QLIMIT_SHR_ATOP] = 14,
|
||||
+ [FW_XQS_QLIMIT_SHR_CTOP_CFG_QLIMIT_SHR_CTOP] = 14,
|
||||
+ [FW_XQS_QLIMIT_SHR_QLIM_CFG_QLIMIT_SHR_QLIM] = 14,
|
||||
+};
|
||||
--- a/drivers/net/ethernet/microchip/sparx5/sparx5_regs.c
|
||||
+++ b/drivers/net/ethernet/microchip/sparx5/sparx5_regs.c
|
||||
@@ -4,7 +4,7 @@
|
||||
* Copyright (c) 2024 Microchip Technology Inc.
|
||||
*/
|
||||
|
||||
-/* This file is autogenerated by cml-utils 2024-09-24 14:02:24 +0200.
|
||||
+/* This file is autogenerated by cml-utils 2024-09-30 11:48:29 +0200.
|
||||
* Commit ID: 9d07b8d19363f3cd3590ddb3f7a2e2768e16524b
|
||||
*/
|
||||
|
||||
@@ -140,6 +140,7 @@ const unsigned int sparx5_gsize[GSIZE_LA
|
||||
[GW_ANA_L2_COMMON] = 700,
|
||||
[GW_ASM_CFG] = 1088,
|
||||
[GW_CPU_CPU_REGS] = 204,
|
||||
+ [GW_DEV2G5_PHASE_DETECTOR_CTRL] = 8,
|
||||
[GW_FDMA_FDMA] = 428,
|
||||
[GW_GCB_CHIP_REGS] = 424,
|
||||
[GW_HSCH_TAS_CONFIG] = 12,
|
||||
@@ -157,6 +158,8 @@ const unsigned int sparx5_fpos[FPOS_LAST
|
||||
[FP_CPU_PROC_CTRL_CP15S_DISABLE] = 6,
|
||||
[FP_CPU_PROC_CTRL_PROC_CRYPTO_DISABLE] = 5,
|
||||
[FP_CPU_PROC_CTRL_L2_FLUSH_REQ] = 1,
|
||||
+ [FP_DEV2G5_PHAD_CTRL_PHAD_ENA] = 7,
|
||||
+ [FP_DEV2G5_PHAD_CTRL_PHAD_FAILED] = 6,
|
||||
[FP_FDMA_CH_CFG_CH_XTR_STATUS_MODE] = 7,
|
||||
[FP_FDMA_CH_CFG_CH_INTR_DB_EOF_ONLY] = 6,
|
||||
[FP_FDMA_CH_CFG_CH_INJ_PORT] = 5,
|
||||
--- a/drivers/net/ethernet/microchip/sparx5/sparx5_regs.h
|
||||
+++ b/drivers/net/ethernet/microchip/sparx5/sparx5_regs.h
|
||||
@@ -4,7 +4,7 @@
|
||||
* Copyright (c) 2024 Microchip Technology Inc.
|
||||
*/
|
||||
|
||||
-/* This file is autogenerated by cml-utils 2024-09-24 14:02:24 +0200.
|
||||
+/* This file is autogenerated by cml-utils 2024-09-30 11:48:29 +0200.
|
||||
* Commit ID: 9d07b8d19363f3cd3590ddb3f7a2e2768e16524b
|
||||
*/
|
||||
|
||||
@@ -151,6 +151,7 @@ enum sparx5_gsize_enum {
|
||||
GW_ANA_L2_COMMON,
|
||||
GW_ASM_CFG,
|
||||
GW_CPU_CPU_REGS,
|
||||
+ GW_DEV2G5_PHASE_DETECTOR_CTRL,
|
||||
GW_FDMA_FDMA,
|
||||
GW_GCB_CHIP_REGS,
|
||||
GW_HSCH_TAS_CONFIG,
|
||||
@@ -169,6 +170,8 @@ enum sparx5_fpos_enum {
|
||||
FP_CPU_PROC_CTRL_CP15S_DISABLE,
|
||||
FP_CPU_PROC_CTRL_PROC_CRYPTO_DISABLE,
|
||||
FP_CPU_PROC_CTRL_L2_FLUSH_REQ,
|
||||
+ FP_DEV2G5_PHAD_CTRL_PHAD_ENA,
|
||||
+ FP_DEV2G5_PHAD_CTRL_PHAD_FAILED,
|
||||
FP_FDMA_CH_CFG_CH_XTR_STATUS_MODE,
|
||||
FP_FDMA_CH_CFG_CH_INTR_DB_EOF_ONLY,
|
||||
FP_FDMA_CH_CFG_CH_INJ_PORT,
|
||||
@ -0,0 +1,54 @@
|
||||
From df0ae12e09264cb432472c707ccb33ececc65935 Mon Sep 17 00:00:00 2001
|
||||
From: Daniel Machon <daniel.machon@microchip.com>
|
||||
Date: Thu, 24 Oct 2024 00:01:27 +0200
|
||||
Subject: [PATCH 51/82] net: lan969x: add constants to match data
|
||||
|
||||
Add the lan969x constants to match data. These are already used
|
||||
throughout the Sparx5 code (introduced in earlier series [1]), so no
|
||||
need to update any code use.
|
||||
|
||||
[1] https://lore.kernel.org/netdev/20241004-b4-sparx5-lan969x-switch-driver-v2-0-d3290f581663@microchip.com/
|
||||
|
||||
Reviewed-by: Steen Hegelund <Steen.Hegelund@microchip.com>
|
||||
Signed-off-by: Daniel Machon <daniel.machon@microchip.com>
|
||||
Link: https://patch.msgid.link/20241024-sparx5-lan969x-switch-driver-2-v2-8-a0b5fae88a0f@microchip.com
|
||||
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
|
||||
---
|
||||
.../net/ethernet/microchip/lan969x/lan969x.c | 21 +++++++++++++++++++
|
||||
1 file changed, 21 insertions(+)
|
||||
|
||||
--- a/drivers/net/ethernet/microchip/lan969x/lan969x.c
|
||||
+++ b/drivers/net/ethernet/microchip/lan969x/lan969x.c
|
||||
@@ -103,11 +103,32 @@ static const struct sparx5_regs lan969x_
|
||||
.fsize = lan969x_fsize,
|
||||
};
|
||||
|
||||
+static const struct sparx5_consts lan969x_consts = {
|
||||
+ .n_ports = 30,
|
||||
+ .n_ports_all = 35,
|
||||
+ .n_hsch_l1_elems = 32,
|
||||
+ .n_hsch_queues = 4,
|
||||
+ .n_lb_groups = 5,
|
||||
+ .n_pgids = 1054, /* (1024 + n_ports) */
|
||||
+ .n_sio_clks = 1,
|
||||
+ .n_own_upsids = 1,
|
||||
+ .n_auto_cals = 4,
|
||||
+ .n_filters = 256,
|
||||
+ .n_gates = 256,
|
||||
+ .n_sdlbs = 496,
|
||||
+ .n_dsm_cal_taxis = 5,
|
||||
+ .buf_size = 1572864,
|
||||
+ .qres_max_prio_idx = 315,
|
||||
+ .qres_max_colour_idx = 323,
|
||||
+ .tod_pin = 4,
|
||||
+};
|
||||
+
|
||||
const struct sparx5_match_data lan969x_desc = {
|
||||
.iomap = lan969x_main_iomap,
|
||||
.iomap_size = ARRAY_SIZE(lan969x_main_iomap),
|
||||
.ioranges = 2,
|
||||
.regs = &lan969x_regs,
|
||||
+ .consts = &lan969x_consts,
|
||||
};
|
||||
EXPORT_SYMBOL_GPL(lan969x_desc);
|
||||
|
||||
@ -0,0 +1,205 @@
|
||||
From 487d962349a2be3de1c3dc556b9d2a3529837f3a Mon Sep 17 00:00:00 2001
|
||||
From: Daniel Machon <daniel.machon@microchip.com>
|
||||
Date: Thu, 24 Oct 2024 00:01:28 +0200
|
||||
Subject: [PATCH 52/82] net: lan969x: add lan969x ops to match data
|
||||
|
||||
Add a bunch of small lan969x ops in bulk. These ops are explained in
|
||||
detail in a previous series [1].
|
||||
|
||||
[1] https://lore.kernel.org/netdev/20241004-b4-sparx5-lan969x-switch-driver-v2-8-d3290f581663@microchip.com/
|
||||
|
||||
Reviewed-by: Steen Hegelund <Steen.Hegelund@microchip.com>
|
||||
Signed-off-by: Daniel Machon <daniel.machon@microchip.com>
|
||||
Link: https://patch.msgid.link/20241024-sparx5-lan969x-switch-driver-2-v2-9-a0b5fae88a0f@microchip.com
|
||||
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
|
||||
---
|
||||
.../net/ethernet/microchip/lan969x/lan969x.c | 122 ++++++++++++++++++
|
||||
.../net/ethernet/microchip/lan969x/lan969x.h | 28 ++++
|
||||
2 files changed, 150 insertions(+)
|
||||
|
||||
--- a/drivers/net/ethernet/microchip/lan969x/lan969x.c
|
||||
+++ b/drivers/net/ethernet/microchip/lan969x/lan969x.c
|
||||
@@ -6,6 +6,9 @@
|
||||
|
||||
#include "lan969x.h"
|
||||
|
||||
+#define LAN969X_SDLB_GRP_CNT 5
|
||||
+#define LAN969X_HSCH_LEAK_GRP_CNT 4
|
||||
+
|
||||
static const struct sparx5_main_io_resource lan969x_main_iomap[] = {
|
||||
{ TARGET_CPU, 0xc0000, 0 }, /* 0xe00c0000 */
|
||||
{ TARGET_FDMA, 0xc0400, 0 }, /* 0xe00c0400 */
|
||||
@@ -92,6 +95,112 @@ static const struct sparx5_main_io_resou
|
||||
{ TARGET_ASM, 0x3200000, 1 }, /* 0xe3200000 */
|
||||
};
|
||||
|
||||
+static struct sparx5_sdlb_group lan969x_sdlb_groups[LAN969X_SDLB_GRP_CNT] = {
|
||||
+ { 1000000000, 8192 / 2, 64 }, /* 1 G */
|
||||
+ { 500000000, 8192 / 2, 64 }, /* 500 M */
|
||||
+ { 100000000, 8192 / 4, 64 }, /* 100 M */
|
||||
+ { 50000000, 8192 / 4, 64 }, /* 50 M */
|
||||
+ { 5000000, 8192 / 8, 64 }, /* 10 M */
|
||||
+};
|
||||
+
|
||||
+static u32 lan969x_hsch_max_group_rate[LAN969X_HSCH_LEAK_GRP_CNT] = {
|
||||
+ 655355, 1048568, 6553550, 10485680
|
||||
+};
|
||||
+
|
||||
+static struct sparx5_sdlb_group *lan969x_get_sdlb_group(int idx)
|
||||
+{
|
||||
+ return &lan969x_sdlb_groups[idx];
|
||||
+}
|
||||
+
|
||||
+static u32 lan969x_get_hsch_max_group_rate(int grp)
|
||||
+{
|
||||
+ return lan969x_hsch_max_group_rate[grp];
|
||||
+}
|
||||
+
|
||||
+static u32 lan969x_get_dev_mode_bit(struct sparx5 *sparx5, int port)
|
||||
+{
|
||||
+ if (lan969x_port_is_2g5(port) || lan969x_port_is_5g(port))
|
||||
+ return port;
|
||||
+
|
||||
+ /* 10G */
|
||||
+ switch (port) {
|
||||
+ case 0:
|
||||
+ return 12;
|
||||
+ case 4:
|
||||
+ return 13;
|
||||
+ case 8:
|
||||
+ return 14;
|
||||
+ case 12:
|
||||
+ return 0;
|
||||
+ default:
|
||||
+ return port;
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+static u32 lan969x_port_dev_mapping(struct sparx5 *sparx5, int port)
|
||||
+{
|
||||
+ if (lan969x_port_is_5g(port)) {
|
||||
+ switch (port) {
|
||||
+ case 9:
|
||||
+ return 0;
|
||||
+ case 13:
|
||||
+ return 1;
|
||||
+ case 17:
|
||||
+ return 2;
|
||||
+ case 21:
|
||||
+ return 3;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ if (lan969x_port_is_10g(port)) {
|
||||
+ switch (port) {
|
||||
+ case 0:
|
||||
+ return 0;
|
||||
+ case 4:
|
||||
+ return 1;
|
||||
+ case 8:
|
||||
+ return 2;
|
||||
+ case 12:
|
||||
+ return 3;
|
||||
+ case 16:
|
||||
+ return 4;
|
||||
+ case 20:
|
||||
+ return 5;
|
||||
+ case 24:
|
||||
+ return 6;
|
||||
+ case 25:
|
||||
+ return 7;
|
||||
+ case 26:
|
||||
+ return 8;
|
||||
+ case 27:
|
||||
+ return 9;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ /* 2g5 port */
|
||||
+ return port;
|
||||
+}
|
||||
+
|
||||
+static int lan969x_port_mux_set(struct sparx5 *sparx5, struct sparx5_port *port,
|
||||
+ struct sparx5_port_config *conf)
|
||||
+{
|
||||
+ u32 portno = port->portno;
|
||||
+ u32 inst;
|
||||
+
|
||||
+ if (port->conf.portmode == conf->portmode)
|
||||
+ return 0; /* Nothing to do */
|
||||
+
|
||||
+ switch (conf->portmode) {
|
||||
+ case PHY_INTERFACE_MODE_QSGMII: /* QSGMII: 4x2G5 devices. Mode Q' */
|
||||
+ inst = (portno - portno % 4) / 4;
|
||||
+ spx5_rmw(BIT(inst), BIT(inst), sparx5, PORT_CONF_QSGMII_ENA);
|
||||
+ break;
|
||||
+ default:
|
||||
+ break;
|
||||
+ }
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
static const struct sparx5_regs lan969x_regs = {
|
||||
.tsize = lan969x_tsize,
|
||||
.gaddr = lan969x_gaddr,
|
||||
@@ -123,12 +232,25 @@ static const struct sparx5_consts lan969
|
||||
.tod_pin = 4,
|
||||
};
|
||||
|
||||
+static const struct sparx5_ops lan969x_ops = {
|
||||
+ .is_port_2g5 = &lan969x_port_is_2g5,
|
||||
+ .is_port_5g = &lan969x_port_is_5g,
|
||||
+ .is_port_10g = &lan969x_port_is_10g,
|
||||
+ .is_port_25g = &lan969x_port_is_25g,
|
||||
+ .get_port_dev_index = &lan969x_port_dev_mapping,
|
||||
+ .get_port_dev_bit = &lan969x_get_dev_mode_bit,
|
||||
+ .get_hsch_max_group_rate = &lan969x_get_hsch_max_group_rate,
|
||||
+ .get_sdlb_group = &lan969x_get_sdlb_group,
|
||||
+ .set_port_mux = &lan969x_port_mux_set,
|
||||
+};
|
||||
+
|
||||
const struct sparx5_match_data lan969x_desc = {
|
||||
.iomap = lan969x_main_iomap,
|
||||
.iomap_size = ARRAY_SIZE(lan969x_main_iomap),
|
||||
.ioranges = 2,
|
||||
.regs = &lan969x_regs,
|
||||
.consts = &lan969x_consts,
|
||||
+ .ops = &lan969x_ops,
|
||||
};
|
||||
EXPORT_SYMBOL_GPL(lan969x_desc);
|
||||
|
||||
--- a/drivers/net/ethernet/microchip/lan969x/lan969x.h
|
||||
+++ b/drivers/net/ethernet/microchip/lan969x/lan969x.h
|
||||
@@ -23,4 +23,32 @@ extern const unsigned int lan969x_gsize[
|
||||
extern const unsigned int lan969x_fpos[FPOS_LAST];
|
||||
extern const unsigned int lan969x_fsize[FSIZE_LAST];
|
||||
|
||||
+static inline bool lan969x_port_is_2g5(int portno)
|
||||
+{
|
||||
+ return portno == 1 || portno == 2 || portno == 3 ||
|
||||
+ portno == 5 || portno == 6 || portno == 7 ||
|
||||
+ portno == 10 || portno == 11 || portno == 14 ||
|
||||
+ portno == 15 || portno == 18 || portno == 19 ||
|
||||
+ portno == 22 || portno == 23;
|
||||
+}
|
||||
+
|
||||
+static inline bool lan969x_port_is_5g(int portno)
|
||||
+{
|
||||
+ return portno == 9 || portno == 13 || portno == 17 ||
|
||||
+ portno == 21;
|
||||
+}
|
||||
+
|
||||
+static inline bool lan969x_port_is_10g(int portno)
|
||||
+{
|
||||
+ return portno == 0 || portno == 4 || portno == 8 ||
|
||||
+ portno == 12 || portno == 16 || portno == 20 ||
|
||||
+ portno == 24 || portno == 25 || portno == 26 ||
|
||||
+ portno == 27;
|
||||
+}
|
||||
+
|
||||
+static inline bool lan969x_port_is_25g(int portno)
|
||||
+{
|
||||
+ return false;
|
||||
+}
|
||||
+
|
||||
#endif
|
||||
@ -0,0 +1,180 @@
|
||||
From a84b19eaf3ede71d2e4075dddffc71a529ccbdd9 Mon Sep 17 00:00:00 2001
|
||||
From: Daniel Machon <daniel.machon@microchip.com>
|
||||
Date: Thu, 24 Oct 2024 00:01:29 +0200
|
||||
Subject: [PATCH 53/82] net: lan969x: add PTP handler function
|
||||
|
||||
Add PTP IRQ handler for lan969x. This is required, as the PTP registers
|
||||
are placed in two different targets on Sparx5 and lan969x. The
|
||||
implementation is otherwise the same as on Sparx5.
|
||||
|
||||
Also, expose sparx5_get_hwtimestamp() for use by lan969x.
|
||||
|
||||
Reviewed-by: Steen Hegelund <Steen.Hegelund@microchip.com>
|
||||
Signed-off-by: Daniel Machon <daniel.machon@microchip.com>
|
||||
Link: https://patch.msgid.link/20241024-sparx5-lan969x-switch-driver-2-v2-10-a0b5fae88a0f@microchip.com
|
||||
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
|
||||
---
|
||||
.../net/ethernet/microchip/lan969x/lan969x.c | 90 +++++++++++++++++++
|
||||
.../ethernet/microchip/sparx5/sparx5_main.h | 5 ++
|
||||
.../ethernet/microchip/sparx5/sparx5_ptp.c | 9 +-
|
||||
3 files changed, 99 insertions(+), 5 deletions(-)
|
||||
|
||||
--- a/drivers/net/ethernet/microchip/lan969x/lan969x.c
|
||||
+++ b/drivers/net/ethernet/microchip/lan969x/lan969x.c
|
||||
@@ -201,6 +201,95 @@ static int lan969x_port_mux_set(struct s
|
||||
return 0;
|
||||
}
|
||||
|
||||
+static irqreturn_t lan969x_ptp_irq_handler(int irq, void *args)
|
||||
+{
|
||||
+ int budget = SPARX5_MAX_PTP_ID;
|
||||
+ struct sparx5 *sparx5 = args;
|
||||
+
|
||||
+ while (budget--) {
|
||||
+ struct sk_buff *skb, *skb_tmp, *skb_match = NULL;
|
||||
+ struct skb_shared_hwtstamps shhwtstamps;
|
||||
+ struct sparx5_port *port;
|
||||
+ struct timespec64 ts;
|
||||
+ unsigned long flags;
|
||||
+ u32 val, id, txport;
|
||||
+ u32 delay;
|
||||
+
|
||||
+ val = spx5_rd(sparx5, PTP_TWOSTEP_CTRL);
|
||||
+
|
||||
+ /* Check if a timestamp can be retrieved */
|
||||
+ if (!(val & PTP_TWOSTEP_CTRL_PTP_VLD))
|
||||
+ break;
|
||||
+
|
||||
+ WARN_ON(val & PTP_TWOSTEP_CTRL_PTP_OVFL);
|
||||
+
|
||||
+ if (!(val & PTP_TWOSTEP_CTRL_STAMP_TX))
|
||||
+ continue;
|
||||
+
|
||||
+ /* Retrieve the ts Tx port */
|
||||
+ txport = PTP_TWOSTEP_CTRL_STAMP_PORT_GET(val);
|
||||
+
|
||||
+ /* Retrieve its associated skb */
|
||||
+ port = sparx5->ports[txport];
|
||||
+
|
||||
+ /* Retrieve the delay */
|
||||
+ delay = spx5_rd(sparx5, PTP_TWOSTEP_STAMP_NSEC);
|
||||
+ delay = PTP_TWOSTEP_STAMP_NSEC_NS_GET(delay);
|
||||
+
|
||||
+ /* Get next timestamp from fifo, which needs to be the
|
||||
+ * rx timestamp which represents the id of the frame
|
||||
+ */
|
||||
+ spx5_rmw(PTP_TWOSTEP_CTRL_PTP_NXT_SET(1),
|
||||
+ PTP_TWOSTEP_CTRL_PTP_NXT,
|
||||
+ sparx5, PTP_TWOSTEP_CTRL);
|
||||
+
|
||||
+ val = spx5_rd(sparx5, PTP_TWOSTEP_CTRL);
|
||||
+
|
||||
+ /* Check if a timestamp can be retrieved */
|
||||
+ if (!(val & PTP_TWOSTEP_CTRL_PTP_VLD))
|
||||
+ break;
|
||||
+
|
||||
+ /* Read RX timestamping to get the ID */
|
||||
+ id = spx5_rd(sparx5, PTP_TWOSTEP_STAMP_NSEC);
|
||||
+ id <<= 8;
|
||||
+ id |= spx5_rd(sparx5, PTP_TWOSTEP_STAMP_SUBNS);
|
||||
+
|
||||
+ spin_lock_irqsave(&port->tx_skbs.lock, flags);
|
||||
+ skb_queue_walk_safe(&port->tx_skbs, skb, skb_tmp) {
|
||||
+ if (SPARX5_SKB_CB(skb)->ts_id != id)
|
||||
+ continue;
|
||||
+
|
||||
+ __skb_unlink(skb, &port->tx_skbs);
|
||||
+ skb_match = skb;
|
||||
+ break;
|
||||
+ }
|
||||
+ spin_unlock_irqrestore(&port->tx_skbs.lock, flags);
|
||||
+
|
||||
+ /* Next ts */
|
||||
+ spx5_rmw(PTP_TWOSTEP_CTRL_PTP_NXT_SET(1),
|
||||
+ PTP_TWOSTEP_CTRL_PTP_NXT,
|
||||
+ sparx5, PTP_TWOSTEP_CTRL);
|
||||
+
|
||||
+ if (WARN_ON(!skb_match))
|
||||
+ continue;
|
||||
+
|
||||
+ spin_lock(&sparx5->ptp_ts_id_lock);
|
||||
+ sparx5->ptp_skbs--;
|
||||
+ spin_unlock(&sparx5->ptp_ts_id_lock);
|
||||
+
|
||||
+ /* Get the h/w timestamp */
|
||||
+ sparx5_get_hwtimestamp(sparx5, &ts, delay);
|
||||
+
|
||||
+ /* Set the timestamp in the skb */
|
||||
+ shhwtstamps.hwtstamp = ktime_set(ts.tv_sec, ts.tv_nsec);
|
||||
+ skb_tstamp_tx(skb_match, &shhwtstamps);
|
||||
+
|
||||
+ dev_kfree_skb_any(skb_match);
|
||||
+ }
|
||||
+
|
||||
+ return IRQ_HANDLED;
|
||||
+}
|
||||
+
|
||||
static const struct sparx5_regs lan969x_regs = {
|
||||
.tsize = lan969x_tsize,
|
||||
.gaddr = lan969x_gaddr,
|
||||
@@ -242,6 +331,7 @@ static const struct sparx5_ops lan969x_o
|
||||
.get_hsch_max_group_rate = &lan969x_get_hsch_max_group_rate,
|
||||
.get_sdlb_group = &lan969x_get_sdlb_group,
|
||||
.set_port_mux = &lan969x_port_mux_set,
|
||||
+ .ptp_irq_handler = &lan969x_ptp_irq_handler,
|
||||
};
|
||||
|
||||
const struct sparx5_match_data lan969x_desc = {
|
||||
--- a/drivers/net/ethernet/microchip/sparx5/sparx5_main.h
|
||||
+++ b/drivers/net/ethernet/microchip/sparx5/sparx5_main.h
|
||||
@@ -114,6 +114,8 @@ enum sparx5_vlan_port_type {
|
||||
#define SPX5_DSM_CAL_LEN 64
|
||||
#define SPX5_DSM_CAL_MAX_DEVS_PER_TAXI 13
|
||||
|
||||
+#define SPARX5_MAX_PTP_ID 512
|
||||
+
|
||||
struct sparx5;
|
||||
|
||||
struct sparx5_calendar_data {
|
||||
@@ -499,6 +501,9 @@ void sparx5_ptp_txtstamp_release(struct
|
||||
struct sk_buff *skb);
|
||||
irqreturn_t sparx5_ptp_irq_handler(int irq, void *args);
|
||||
int sparx5_ptp_gettime64(struct ptp_clock_info *ptp, struct timespec64 *ts);
|
||||
+void sparx5_get_hwtimestamp(struct sparx5 *sparx5,
|
||||
+ struct timespec64 *ts,
|
||||
+ u32 nsec);
|
||||
|
||||
/* sparx5_vcap_impl.c */
|
||||
int sparx5_vcap_init(struct sparx5 *sparx5);
|
||||
--- a/drivers/net/ethernet/microchip/sparx5/sparx5_ptp.c
|
||||
+++ b/drivers/net/ethernet/microchip/sparx5/sparx5_ptp.c
|
||||
@@ -11,8 +11,6 @@
|
||||
#include "sparx5_main_regs.h"
|
||||
#include "sparx5_main.h"
|
||||
|
||||
-#define SPARX5_MAX_PTP_ID 512
|
||||
-
|
||||
#define TOD_ACC_PIN 0x4
|
||||
|
||||
enum {
|
||||
@@ -275,9 +273,9 @@ void sparx5_ptp_txtstamp_release(struct
|
||||
spin_unlock_irqrestore(&sparx5->ptp_ts_id_lock, flags);
|
||||
}
|
||||
|
||||
-static void sparx5_get_hwtimestamp(struct sparx5 *sparx5,
|
||||
- struct timespec64 *ts,
|
||||
- u32 nsec)
|
||||
+void sparx5_get_hwtimestamp(struct sparx5 *sparx5,
|
||||
+ struct timespec64 *ts,
|
||||
+ u32 nsec)
|
||||
{
|
||||
/* Read current PTP time to get seconds */
|
||||
const struct sparx5_consts *consts = sparx5->data->consts;
|
||||
@@ -305,6 +303,7 @@ static void sparx5_get_hwtimestamp(struc
|
||||
|
||||
spin_unlock_irqrestore(&sparx5->ptp_clock_lock, flags);
|
||||
}
|
||||
+EXPORT_SYMBOL_GPL(sparx5_get_hwtimestamp);
|
||||
|
||||
irqreturn_t sparx5_ptp_irq_handler(int irq, void *args)
|
||||
{
|
||||
@ -0,0 +1,359 @@
|
||||
From bb44231712c296fa992cf7e0f7206b0798a1b84c Mon Sep 17 00:00:00 2001
|
||||
From: Daniel Machon <daniel.machon@microchip.com>
|
||||
Date: Thu, 24 Oct 2024 00:01:30 +0200
|
||||
Subject: [PATCH 54/82] net: lan969x: add function for calculating the DSM
|
||||
calendar
|
||||
|
||||
Lan969x has support for RedBox / HSR / PRP (not implemented yet). In
|
||||
order to accommodate for this in the future, we need to give lan969x it's
|
||||
own function for calculating the DSM calendar.
|
||||
|
||||
The function calculates the calendar for each taxi bus. The calendar is
|
||||
used for bandwidth allocation towards the ports attached to the taxi
|
||||
bus. A calendar configuration consists of up-to 64 slots, which may be
|
||||
allocated to ports or left unused. Each slot accounts for 1 clock cycle.
|
||||
|
||||
Also expose sparx5_cal_speed_to_value(), sparx5_get_port_cal_speed,
|
||||
sparx5_cal_bw and SPX5_DSM_CAL_EMPTY for use by lan969x.
|
||||
|
||||
Reviewed-by: Steen Hegelund <Steen.Hegelund@microchip.com>
|
||||
Signed-off-by: Daniel Machon <daniel.machon@microchip.com>
|
||||
Link: https://patch.msgid.link/20241024-sparx5-lan969x-switch-driver-2-v2-11-a0b5fae88a0f@microchip.com
|
||||
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
|
||||
---
|
||||
.../net/ethernet/microchip/lan969x/Makefile | 2 +-
|
||||
.../net/ethernet/microchip/lan969x/lan969x.c | 1 +
|
||||
.../net/ethernet/microchip/lan969x/lan969x.h | 3 +
|
||||
.../microchip/lan969x/lan969x_calendar.c | 191 ++++++++++++++++++
|
||||
.../microchip/sparx5/sparx5_calendar.c | 20 +-
|
||||
.../ethernet/microchip/sparx5/sparx5_main.h | 15 ++
|
||||
6 files changed, 215 insertions(+), 17 deletions(-)
|
||||
create mode 100644 drivers/net/ethernet/microchip/lan969x/lan969x_calendar.c
|
||||
|
||||
--- a/drivers/net/ethernet/microchip/lan969x/Makefile
|
||||
+++ b/drivers/net/ethernet/microchip/lan969x/Makefile
|
||||
@@ -5,7 +5,7 @@
|
||||
|
||||
obj-$(CONFIG_LAN969X_SWITCH) += lan969x-switch.o
|
||||
|
||||
-lan969x-switch-y := lan969x_regs.o lan969x.o
|
||||
+lan969x-switch-y := lan969x_regs.o lan969x.o lan969x_calendar.o
|
||||
|
||||
# Provide include files
|
||||
ccflags-y += -I$(srctree)/drivers/net/ethernet/microchip/fdma
|
||||
--- a/drivers/net/ethernet/microchip/lan969x/lan969x.c
|
||||
+++ b/drivers/net/ethernet/microchip/lan969x/lan969x.c
|
||||
@@ -332,6 +332,7 @@ static const struct sparx5_ops lan969x_o
|
||||
.get_sdlb_group = &lan969x_get_sdlb_group,
|
||||
.set_port_mux = &lan969x_port_mux_set,
|
||||
.ptp_irq_handler = &lan969x_ptp_irq_handler,
|
||||
+ .dsm_calendar_calc = &lan969x_dsm_calendar_calc,
|
||||
};
|
||||
|
||||
const struct sparx5_match_data lan969x_desc = {
|
||||
--- a/drivers/net/ethernet/microchip/lan969x/lan969x.h
|
||||
+++ b/drivers/net/ethernet/microchip/lan969x/lan969x.h
|
||||
@@ -51,4 +51,7 @@ static inline bool lan969x_port_is_25g(i
|
||||
return false;
|
||||
}
|
||||
|
||||
+/* lan969x_calendar.c */
|
||||
+int lan969x_dsm_calendar_calc(struct sparx5 *sparx5, u32 taxi,
|
||||
+ struct sparx5_calendar_data *data);
|
||||
#endif
|
||||
--- /dev/null
|
||||
+++ b/drivers/net/ethernet/microchip/lan969x/lan969x_calendar.c
|
||||
@@ -0,0 +1,191 @@
|
||||
+// SPDX-License-Identifier: GPL-2.0+
|
||||
+/* Microchip lan969x Switch driver
|
||||
+ *
|
||||
+ * Copyright (c) 2024 Microchip Technology Inc. and its subsidiaries.
|
||||
+ */
|
||||
+
|
||||
+#include "lan969x.h"
|
||||
+
|
||||
+#define LAN969X_DSM_CAL_DEVS_PER_TAXI 10
|
||||
+#define LAN969X_DSM_CAL_TAXIS 5
|
||||
+
|
||||
+enum lan969x_dsm_cal_dev {
|
||||
+ DSM_CAL_DEV_2G5,
|
||||
+ DSM_CAL_DEV_5G,
|
||||
+ DSM_CAL_DEV_10G,
|
||||
+ DSM_CAL_DEV_OTHER, /* 1G or less */
|
||||
+ DSM_CAL_DEV_MAX
|
||||
+};
|
||||
+
|
||||
+/* Each entry in the following struct defines properties for a given speed
|
||||
+ * (10G, 5G, 2.5G, or 1G or less).
|
||||
+ */
|
||||
+struct lan969x_dsm_cal_dev_speed {
|
||||
+ /* Number of devices that requires this speed. */
|
||||
+ u32 n_devs;
|
||||
+
|
||||
+ /* Array of devices that requires this speed. */
|
||||
+ u32 devs[LAN969X_DSM_CAL_DEVS_PER_TAXI];
|
||||
+
|
||||
+ /* Number of slots required for one device running this speed. */
|
||||
+ u32 n_slots;
|
||||
+
|
||||
+ /* Gap between two slots for one device running this speed. */
|
||||
+ u32 gap;
|
||||
+};
|
||||
+
|
||||
+static u32
|
||||
+lan969x_taxi_ports[LAN969X_DSM_CAL_TAXIS][LAN969X_DSM_CAL_DEVS_PER_TAXI] = {
|
||||
+ { 0, 4, 1, 2, 3, 5, 6, 7, 28, 29 },
|
||||
+ { 8, 12, 9, 13, 10, 11, 14, 15, 99, 99 },
|
||||
+ { 16, 20, 17, 21, 18, 19, 22, 23, 99, 99 },
|
||||
+ { 24, 25, 99, 99, 99, 99, 99, 99, 99, 99 },
|
||||
+ { 26, 27, 99, 99, 99, 99, 99, 99, 99, 99 }
|
||||
+};
|
||||
+
|
||||
+static int lan969x_dsm_cal_idx_get(u32 *calendar, u32 cal_len, u32 *cal_idx)
|
||||
+{
|
||||
+ if (*cal_idx >= cal_len)
|
||||
+ return -EINVAL;
|
||||
+
|
||||
+ do {
|
||||
+ if (calendar[*cal_idx] == SPX5_DSM_CAL_EMPTY)
|
||||
+ return 0;
|
||||
+
|
||||
+ (*cal_idx)++;
|
||||
+ } while (*cal_idx < cal_len);
|
||||
+
|
||||
+ return -ENOENT;
|
||||
+}
|
||||
+
|
||||
+static enum lan969x_dsm_cal_dev lan969x_dsm_cal_get_dev(int speed)
|
||||
+{
|
||||
+ return (speed == 10000 ? DSM_CAL_DEV_10G :
|
||||
+ speed == 5000 ? DSM_CAL_DEV_5G :
|
||||
+ speed == 2500 ? DSM_CAL_DEV_2G5 :
|
||||
+ DSM_CAL_DEV_OTHER);
|
||||
+}
|
||||
+
|
||||
+static int lan969x_dsm_cal_get_speed(enum lan969x_dsm_cal_dev dev)
|
||||
+{
|
||||
+ return (dev == DSM_CAL_DEV_10G ? 10000 :
|
||||
+ dev == DSM_CAL_DEV_5G ? 5000 :
|
||||
+ dev == DSM_CAL_DEV_2G5 ? 2500 :
|
||||
+ 1000);
|
||||
+}
|
||||
+
|
||||
+int lan969x_dsm_calendar_calc(struct sparx5 *sparx5, u32 taxi,
|
||||
+ struct sparx5_calendar_data *data)
|
||||
+{
|
||||
+ struct lan969x_dsm_cal_dev_speed dev_speeds[DSM_CAL_DEV_MAX] = {};
|
||||
+ u32 cal_len, n_slots, taxi_bw, n_devs = 0, required_bw = 0;
|
||||
+ struct lan969x_dsm_cal_dev_speed *speed;
|
||||
+ int err;
|
||||
+
|
||||
+ /* Maximum bandwidth for this taxi */
|
||||
+ taxi_bw = (128 * 1000000) / sparx5_clk_period(sparx5->coreclock);
|
||||
+
|
||||
+ memcpy(data->taxi_ports, &lan969x_taxi_ports[taxi],
|
||||
+ LAN969X_DSM_CAL_DEVS_PER_TAXI * sizeof(u32));
|
||||
+
|
||||
+ for (int i = 0; i < LAN969X_DSM_CAL_DEVS_PER_TAXI; i++) {
|
||||
+ u32 portno = data->taxi_ports[i];
|
||||
+ enum sparx5_cal_bw bw;
|
||||
+
|
||||
+ bw = sparx5_get_port_cal_speed(sparx5, portno);
|
||||
+
|
||||
+ if (portno < sparx5->data->consts->n_ports_all)
|
||||
+ data->taxi_speeds[i] = sparx5_cal_speed_to_value(bw);
|
||||
+ else
|
||||
+ data->taxi_speeds[i] = 0;
|
||||
+ }
|
||||
+
|
||||
+ /* Determine the different port types (10G, 5G, 2.5G, <= 1G) in the
|
||||
+ * this taxi map.
|
||||
+ */
|
||||
+ for (int i = 0; i < LAN969X_DSM_CAL_DEVS_PER_TAXI; i++) {
|
||||
+ u32 taxi_speed = data->taxi_speeds[i];
|
||||
+ enum lan969x_dsm_cal_dev dev;
|
||||
+
|
||||
+ if (taxi_speed == 0)
|
||||
+ continue;
|
||||
+
|
||||
+ required_bw += taxi_speed;
|
||||
+
|
||||
+ dev = lan969x_dsm_cal_get_dev(taxi_speed);
|
||||
+ speed = &dev_speeds[dev];
|
||||
+ speed->devs[speed->n_devs++] = i;
|
||||
+ n_devs++;
|
||||
+ }
|
||||
+
|
||||
+ if (required_bw > taxi_bw) {
|
||||
+ pr_err("Required bandwidth: %u is higher than total taxi bandwidth: %u",
|
||||
+ required_bw, taxi_bw);
|
||||
+ return -EINVAL;
|
||||
+ }
|
||||
+
|
||||
+ if (n_devs == 0) {
|
||||
+ data->schedule[0] = SPX5_DSM_CAL_EMPTY;
|
||||
+ return 0;
|
||||
+ }
|
||||
+
|
||||
+ cal_len = n_devs;
|
||||
+
|
||||
+ /* Search for a calendar length that fits all active devices. */
|
||||
+ while (cal_len < SPX5_DSM_CAL_LEN) {
|
||||
+ u32 bw_per_slot = taxi_bw / cal_len;
|
||||
+
|
||||
+ n_slots = 0;
|
||||
+
|
||||
+ for (int i = 0; i < DSM_CAL_DEV_MAX; i++) {
|
||||
+ speed = &dev_speeds[i];
|
||||
+
|
||||
+ if (speed->n_devs == 0)
|
||||
+ continue;
|
||||
+
|
||||
+ required_bw = lan969x_dsm_cal_get_speed(i);
|
||||
+ speed->n_slots = DIV_ROUND_UP(required_bw, bw_per_slot);
|
||||
+
|
||||
+ if (speed->n_slots)
|
||||
+ speed->gap = DIV_ROUND_UP(cal_len,
|
||||
+ speed->n_slots);
|
||||
+ else
|
||||
+ speed->gap = 0;
|
||||
+
|
||||
+ n_slots += speed->n_slots * speed->n_devs;
|
||||
+ }
|
||||
+
|
||||
+ if (n_slots <= cal_len)
|
||||
+ break; /* Found a suitable calendar length. */
|
||||
+
|
||||
+ /* Not good enough yet. */
|
||||
+ cal_len = n_slots;
|
||||
+ }
|
||||
+
|
||||
+ if (cal_len > SPX5_DSM_CAL_LEN) {
|
||||
+ pr_err("Invalid length: %u for taxi: %u", cal_len, taxi);
|
||||
+ return -EINVAL;
|
||||
+ }
|
||||
+
|
||||
+ for (u32 i = 0; i < SPX5_DSM_CAL_LEN; i++)
|
||||
+ data->schedule[i] = SPX5_DSM_CAL_EMPTY;
|
||||
+
|
||||
+ /* Place the remaining devices */
|
||||
+ for (u32 i = 0; i < DSM_CAL_DEV_MAX; i++) {
|
||||
+ speed = &dev_speeds[i];
|
||||
+ for (u32 dev = 0; dev < speed->n_devs; dev++) {
|
||||
+ u32 idx = 0;
|
||||
+
|
||||
+ for (n_slots = 0; n_slots < speed->n_slots; n_slots++) {
|
||||
+ err = lan969x_dsm_cal_idx_get(data->schedule,
|
||||
+ cal_len, &idx);
|
||||
+ if (err)
|
||||
+ return err;
|
||||
+ data->schedule[idx] = speed->devs[dev];
|
||||
+ idx += speed->gap;
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
--- a/drivers/net/ethernet/microchip/sparx5/sparx5_calendar.c
|
||||
+++ b/drivers/net/ethernet/microchip/sparx5/sparx5_calendar.c
|
||||
@@ -15,7 +15,6 @@
|
||||
#define SPX5_CALBITS_PER_PORT 3 /* Bit per port in calendar register */
|
||||
|
||||
/* DSM calendar information */
|
||||
-#define SPX5_DSM_CAL_EMPTY 0xFFFF
|
||||
#define SPX5_DSM_CAL_TAXIS 8
|
||||
#define SPX5_DSM_CAL_BW_LOSS 553
|
||||
|
||||
@@ -74,18 +73,6 @@ static u32 sparx5_target_bandwidth(struc
|
||||
}
|
||||
}
|
||||
|
||||
-/* This is used in calendar configuration */
|
||||
-enum sparx5_cal_bw {
|
||||
- SPX5_CAL_SPEED_NONE = 0,
|
||||
- SPX5_CAL_SPEED_1G = 1,
|
||||
- SPX5_CAL_SPEED_2G5 = 2,
|
||||
- SPX5_CAL_SPEED_5G = 3,
|
||||
- SPX5_CAL_SPEED_10G = 4,
|
||||
- SPX5_CAL_SPEED_25G = 5,
|
||||
- SPX5_CAL_SPEED_0G5 = 6,
|
||||
- SPX5_CAL_SPEED_12G5 = 7
|
||||
-};
|
||||
-
|
||||
static u32 sparx5_clk_to_bandwidth(enum sparx5_core_clockfreq cclock)
|
||||
{
|
||||
switch (cclock) {
|
||||
@@ -98,7 +85,7 @@ static u32 sparx5_clk_to_bandwidth(enum
|
||||
return 0;
|
||||
}
|
||||
|
||||
-static u32 sparx5_cal_speed_to_value(enum sparx5_cal_bw speed)
|
||||
+u32 sparx5_cal_speed_to_value(enum sparx5_cal_bw speed)
|
||||
{
|
||||
switch (speed) {
|
||||
case SPX5_CAL_SPEED_1G: return 1000;
|
||||
@@ -111,6 +98,7 @@ static u32 sparx5_cal_speed_to_value(enu
|
||||
default: return 0;
|
||||
}
|
||||
}
|
||||
+EXPORT_SYMBOL_GPL(sparx5_cal_speed_to_value);
|
||||
|
||||
static u32 sparx5_bandwidth_to_calendar(u32 bw)
|
||||
{
|
||||
@@ -128,8 +116,7 @@ static u32 sparx5_bandwidth_to_calendar(
|
||||
}
|
||||
}
|
||||
|
||||
-static enum sparx5_cal_bw sparx5_get_port_cal_speed(struct sparx5 *sparx5,
|
||||
- u32 portno)
|
||||
+enum sparx5_cal_bw sparx5_get_port_cal_speed(struct sparx5 *sparx5, u32 portno)
|
||||
{
|
||||
struct sparx5_port *port;
|
||||
|
||||
@@ -163,6 +150,7 @@ static enum sparx5_cal_bw sparx5_get_por
|
||||
return SPX5_CAL_SPEED_NONE;
|
||||
return sparx5_bandwidth_to_calendar(port->conf.bandwidth);
|
||||
}
|
||||
+EXPORT_SYMBOL_GPL(sparx5_get_port_cal_speed);
|
||||
|
||||
/* Auto configure the QSYS calendar based on port configuration */
|
||||
int sparx5_config_auto_calendar(struct sparx5 *sparx5)
|
||||
--- a/drivers/net/ethernet/microchip/sparx5/sparx5_main.h
|
||||
+++ b/drivers/net/ethernet/microchip/sparx5/sparx5_main.h
|
||||
@@ -63,6 +63,18 @@ enum sparx5_vlan_port_type {
|
||||
SPX5_VLAN_PORT_TYPE_S_CUSTOM /* S-port using custom type */
|
||||
};
|
||||
|
||||
+/* This is used in calendar configuration */
|
||||
+enum sparx5_cal_bw {
|
||||
+ SPX5_CAL_SPEED_NONE = 0,
|
||||
+ SPX5_CAL_SPEED_1G = 1,
|
||||
+ SPX5_CAL_SPEED_2G5 = 2,
|
||||
+ SPX5_CAL_SPEED_5G = 3,
|
||||
+ SPX5_CAL_SPEED_10G = 4,
|
||||
+ SPX5_CAL_SPEED_25G = 5,
|
||||
+ SPX5_CAL_SPEED_0G5 = 6,
|
||||
+ SPX5_CAL_SPEED_12G5 = 7
|
||||
+};
|
||||
+
|
||||
#define SPX5_PORTS 65
|
||||
#define SPX5_PORTS_ALL 70 /* Total number of ports */
|
||||
|
||||
@@ -113,6 +125,7 @@ enum sparx5_vlan_port_type {
|
||||
|
||||
#define SPX5_DSM_CAL_LEN 64
|
||||
#define SPX5_DSM_CAL_MAX_DEVS_PER_TAXI 13
|
||||
+#define SPX5_DSM_CAL_EMPTY 0xFFFF
|
||||
|
||||
#define SPARX5_MAX_PTP_ID 512
|
||||
|
||||
@@ -454,6 +467,8 @@ int sparx5_config_auto_calendar(struct s
|
||||
int sparx5_config_dsm_calendar(struct sparx5 *sparx5);
|
||||
int sparx5_dsm_calendar_calc(struct sparx5 *sparx5, u32 taxi,
|
||||
struct sparx5_calendar_data *data);
|
||||
+u32 sparx5_cal_speed_to_value(enum sparx5_cal_bw speed);
|
||||
+enum sparx5_cal_bw sparx5_get_port_cal_speed(struct sparx5 *sparx5, u32 portno);
|
||||
|
||||
|
||||
/* sparx5_ethtool.c */
|
||||
@ -0,0 +1,306 @@
|
||||
From ad3d33e6ac44359d2414f11bcaf1ebb8ba64346d Mon Sep 17 00:00:00 2001
|
||||
From: Daniel Machon <daniel.machon@microchip.com>
|
||||
Date: Thu, 24 Oct 2024 00:01:31 +0200
|
||||
Subject: [PATCH 55/82] net: sparx5: use is_sparx5() macro throughout
|
||||
|
||||
Use the is_sparx5() macro (introduced in earlier series [1]), in places
|
||||
where we need to handle things a bit differently on lan969x.
|
||||
|
||||
These places are:
|
||||
|
||||
- in sparx5_dsm_calendar_update() we need to switch the calendar
|
||||
from a to b on lan969x.
|
||||
|
||||
- in sparx5_start() we need to make sure the HSCH_SYS_CLK_PER
|
||||
register is only touched on Sparx5.
|
||||
|
||||
- in sparx5_start() we need to disable VCAP and FDMA for lan969x
|
||||
(will come in later series).
|
||||
|
||||
- in sparx5_mirror_port_get() we must make sure the
|
||||
ANA_AC_PROBE_PORT_CFG1 register is only read on Sparx5.
|
||||
|
||||
- sparx5_netdev.c and sparx5_packet.c we need to use different IFH
|
||||
(Internal Frame Header) offsets for lan969x.
|
||||
|
||||
- in sparx5_port_fifo_sz() we must bail out on lan969x.
|
||||
|
||||
- in sparx5_port_config_low_set() we must configure the phase
|
||||
detection registers.
|
||||
|
||||
- in sparx5_port_config() and sparx5_port_init() we must do some
|
||||
additional configuration of the port devices.
|
||||
|
||||
- in sparx5_dwrr_conf_set() we must derive the scheduling layer
|
||||
|
||||
[1] https://lore.kernel.org/netdev/20241004-b4-sparx5-lan969x-switch-driver-v2-8-d3290f581663@microchip.com/
|
||||
|
||||
Reviewed-by: Steen Hegelund <Steen.Hegelund@microchip.com>
|
||||
Signed-off-by: Daniel Machon <daniel.machon@microchip.com>
|
||||
Link: https://patch.msgid.link/20241024-sparx5-lan969x-switch-driver-2-v2-12-a0b5fae88a0f@microchip.com
|
||||
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
|
||||
---
|
||||
.../microchip/sparx5/sparx5_calendar.c | 21 ++++++++-
|
||||
.../ethernet/microchip/sparx5/sparx5_main.c | 21 +++++----
|
||||
.../ethernet/microchip/sparx5/sparx5_mirror.c | 10 +++-
|
||||
.../ethernet/microchip/sparx5/sparx5_netdev.c | 17 ++++---
|
||||
.../ethernet/microchip/sparx5/sparx5_packet.c | 3 +-
|
||||
.../ethernet/microchip/sparx5/sparx5_port.c | 46 +++++++++++++++++++
|
||||
.../ethernet/microchip/sparx5/sparx5_qos.c | 3 +-
|
||||
7 files changed, 99 insertions(+), 22 deletions(-)
|
||||
|
||||
--- a/drivers/net/ethernet/microchip/sparx5/sparx5_calendar.c
|
||||
+++ b/drivers/net/ethernet/microchip/sparx5/sparx5_calendar.c
|
||||
@@ -531,8 +531,18 @@ check_err:
|
||||
static int sparx5_dsm_calendar_update(struct sparx5 *sparx5, u32 taxi,
|
||||
struct sparx5_calendar_data *data)
|
||||
{
|
||||
- u32 idx;
|
||||
- u32 cal_len = sparx5_dsm_cal_len(data->schedule), len;
|
||||
+ u32 cal_len = sparx5_dsm_cal_len(data->schedule), len, idx;
|
||||
+
|
||||
+ if (!is_sparx5(sparx5)) {
|
||||
+ u32 val, act;
|
||||
+
|
||||
+ val = spx5_rd(sparx5, DSM_TAXI_CAL_CFG(taxi));
|
||||
+ act = DSM_TAXI_CAL_CFG_CAL_SEL_STAT_GET(val);
|
||||
+
|
||||
+ spx5_rmw(DSM_TAXI_CAL_CFG_CAL_PGM_SEL_SET(!act),
|
||||
+ DSM_TAXI_CAL_CFG_CAL_PGM_SEL,
|
||||
+ sparx5, DSM_TAXI_CAL_CFG(taxi));
|
||||
+ }
|
||||
|
||||
spx5_rmw(DSM_TAXI_CAL_CFG_CAL_PGM_ENA_SET(1),
|
||||
DSM_TAXI_CAL_CFG_CAL_PGM_ENA,
|
||||
@@ -556,6 +566,13 @@ static int sparx5_dsm_calendar_update(st
|
||||
DSM_TAXI_CAL_CFG(taxi)));
|
||||
if (len != cal_len - 1)
|
||||
goto update_err;
|
||||
+
|
||||
+ if (!is_sparx5(sparx5)) {
|
||||
+ spx5_rmw(DSM_TAXI_CAL_CFG_CAL_SWITCH_SET(1),
|
||||
+ DSM_TAXI_CAL_CFG_CAL_SWITCH,
|
||||
+ sparx5, DSM_TAXI_CAL_CFG(taxi));
|
||||
+ }
|
||||
+
|
||||
return 0;
|
||||
update_err:
|
||||
dev_err(sparx5->dev, "Incorrect calendar length: %u\n", len);
|
||||
--- a/drivers/net/ethernet/microchip/sparx5/sparx5_main.c
|
||||
+++ b/drivers/net/ethernet/microchip/sparx5/sparx5_main.c
|
||||
@@ -538,10 +538,11 @@ static int sparx5_init_coreclock(struct
|
||||
sparx5->coreclock = freq;
|
||||
clk_period = sparx5_clk_period(freq);
|
||||
|
||||
- spx5_rmw(HSCH_SYS_CLK_PER_100PS_SET(clk_period / 100),
|
||||
- HSCH_SYS_CLK_PER_100PS,
|
||||
- sparx5,
|
||||
- HSCH_SYS_CLK_PER);
|
||||
+ if (is_sparx5(sparx5))
|
||||
+ spx5_rmw(HSCH_SYS_CLK_PER_100PS_SET(clk_period / 100),
|
||||
+ HSCH_SYS_CLK_PER_100PS,
|
||||
+ sparx5,
|
||||
+ HSCH_SYS_CLK_PER);
|
||||
|
||||
spx5_rmw(ANA_AC_POL_BDLB_DLB_CTRL_CLK_PERIOD_01NS_SET(clk_period / 100),
|
||||
ANA_AC_POL_BDLB_DLB_CTRL_CLK_PERIOD_01NS,
|
||||
@@ -731,15 +732,17 @@ static int sparx5_start(struct sparx5 *s
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
- err = sparx5_vcap_init(sparx5);
|
||||
- if (err) {
|
||||
- sparx5_unregister_notifier_blocks(sparx5);
|
||||
- return err;
|
||||
+ if (is_sparx5(sparx5)) {
|
||||
+ err = sparx5_vcap_init(sparx5);
|
||||
+ if (err) {
|
||||
+ sparx5_unregister_notifier_blocks(sparx5);
|
||||
+ return err;
|
||||
+ }
|
||||
}
|
||||
|
||||
/* Start Frame DMA with fallback to register based INJ/XTR */
|
||||
err = -ENXIO;
|
||||
- if (sparx5->fdma_irq >= 0) {
|
||||
+ if (sparx5->fdma_irq >= 0 && is_sparx5(sparx5)) {
|
||||
if (GCB_CHIP_ID_REV_ID_GET(sparx5->chip_id) > 0)
|
||||
err = devm_request_irq(sparx5->dev,
|
||||
sparx5->fdma_irq,
|
||||
--- a/drivers/net/ethernet/microchip/sparx5/sparx5_mirror.c
|
||||
+++ b/drivers/net/ethernet/microchip/sparx5/sparx5_mirror.c
|
||||
@@ -24,8 +24,14 @@ static u32 sparx5_mirror_to_dir(bool ing
|
||||
/* Get ports belonging to this mirror */
|
||||
static u64 sparx5_mirror_port_get(struct sparx5 *sparx5, u32 idx)
|
||||
{
|
||||
- return (u64)spx5_rd(sparx5, ANA_AC_PROBE_PORT_CFG1(idx)) << 32 |
|
||||
- spx5_rd(sparx5, ANA_AC_PROBE_PORT_CFG(idx));
|
||||
+ u64 val;
|
||||
+
|
||||
+ val = spx5_rd(sparx5, ANA_AC_PROBE_PORT_CFG(idx));
|
||||
+
|
||||
+ if (is_sparx5(sparx5))
|
||||
+ val |= (u64)spx5_rd(sparx5, ANA_AC_PROBE_PORT_CFG1(idx)) << 32;
|
||||
+
|
||||
+ return val;
|
||||
}
|
||||
|
||||
/* Add port to mirror (only front ports) */
|
||||
--- a/drivers/net/ethernet/microchip/sparx5/sparx5_netdev.c
|
||||
+++ b/drivers/net/ethernet/microchip/sparx5/sparx5_netdev.c
|
||||
@@ -64,16 +64,16 @@ void sparx5_set_port_ifh(struct sparx5 *
|
||||
/* MISC.CPU_MASK/DPORT = Destination port */
|
||||
ifh_encode_bitfield(ifh_hdr, portno, 29, 8);
|
||||
/* MISC.PIPELINE_PT */
|
||||
- ifh_encode_bitfield(ifh_hdr, 16, 37, 5);
|
||||
+ ifh_encode_bitfield(ifh_hdr, is_sparx5(sparx5) ? 16 : 17, 37, 5);
|
||||
/* MISC.PIPELINE_ACT */
|
||||
ifh_encode_bitfield(ifh_hdr, 1, 42, 3);
|
||||
/* FWD.SRC_PORT = CPU */
|
||||
ifh_encode_bitfield(ifh_hdr, sparx5_get_pgid(sparx5, SPX5_PORT_CPU_0),
|
||||
- 46, 7);
|
||||
+ 46, is_sparx5(sparx5) ? 7 : 6);
|
||||
/* FWD.SFLOW_ID (disable SFlow sampling) */
|
||||
- ifh_encode_bitfield(ifh_hdr, 124, 57, 7);
|
||||
+ ifh_encode_bitfield(ifh_hdr, 124, is_sparx5(sparx5) ? 57 : 56, 7);
|
||||
/* FWD.UPDATE_FCS = Enable. Enforce update of FCS. */
|
||||
- ifh_encode_bitfield(ifh_hdr, 1, 67, 1);
|
||||
+ ifh_encode_bitfield(ifh_hdr, 1, is_sparx5(sparx5) ? 67 : 66, 1);
|
||||
}
|
||||
|
||||
void sparx5_set_port_ifh_rew_op(void *ifh_hdr, u32 rew_op)
|
||||
@@ -84,19 +84,22 @@ void sparx5_set_port_ifh_rew_op(void *if
|
||||
void sparx5_set_port_ifh_pdu_type(struct sparx5 *sparx5, void *ifh_hdr,
|
||||
u32 pdu_type)
|
||||
{
|
||||
- ifh_encode_bitfield(ifh_hdr, pdu_type, 191, 4);
|
||||
+ ifh_encode_bitfield(ifh_hdr, pdu_type, is_sparx5(sparx5) ? 191 : 190,
|
||||
+ 4);
|
||||
}
|
||||
|
||||
void sparx5_set_port_ifh_pdu_w16_offset(struct sparx5 *sparx5, void *ifh_hdr,
|
||||
u32 pdu_w16_offset)
|
||||
{
|
||||
- ifh_encode_bitfield(ifh_hdr, pdu_w16_offset, 195, 6);
|
||||
+ ifh_encode_bitfield(ifh_hdr, pdu_w16_offset,
|
||||
+ is_sparx5(sparx5) ? 195 : 194, 6);
|
||||
}
|
||||
|
||||
void sparx5_set_port_ifh_timestamp(struct sparx5 *sparx5, void *ifh_hdr,
|
||||
u64 timestamp)
|
||||
{
|
||||
- ifh_encode_bitfield(ifh_hdr, timestamp, 232, 40);
|
||||
+ ifh_encode_bitfield(ifh_hdr, timestamp, 232,
|
||||
+ is_sparx5(sparx5) ? 40 : 38);
|
||||
}
|
||||
|
||||
static int sparx5_port_open(struct net_device *ndev)
|
||||
--- a/drivers/net/ethernet/microchip/sparx5/sparx5_packet.c
|
||||
+++ b/drivers/net/ethernet/microchip/sparx5/sparx5_packet.c
|
||||
@@ -43,7 +43,8 @@ void sparx5_ifh_parse(struct sparx5 *spa
|
||||
((u32)xtr_hdr[29] << 8) |
|
||||
((u32)xtr_hdr[30] << 0);
|
||||
fwd = (fwd >> 5);
|
||||
- info->src_port = FIELD_GET(GENMASK(7, 1), fwd);
|
||||
+ info->src_port = spx5_field_get(GENMASK(is_sparx5(sparx5) ? 7 : 6, 1),
|
||||
+ fwd);
|
||||
|
||||
/*
|
||||
* Bit 270-271 are occasionally unexpectedly set by the hardware,
|
||||
--- a/drivers/net/ethernet/microchip/sparx5/sparx5_port.c
|
||||
+++ b/drivers/net/ethernet/microchip/sparx5/sparx5_port.c
|
||||
@@ -476,6 +476,9 @@ static int sparx5_port_fifo_sz(struct sp
|
||||
u32 mac_width = 8;
|
||||
u32 addition = 0;
|
||||
|
||||
+ if (!is_sparx5(sparx5))
|
||||
+ return 0;
|
||||
+
|
||||
switch (speed) {
|
||||
case SPEED_25000:
|
||||
return 0;
|
||||
@@ -921,6 +924,20 @@ static int sparx5_port_config_low_set(st
|
||||
sparx5,
|
||||
DEV2G5_DEV_RST_CTRL(port->portno));
|
||||
|
||||
+ /* Enable PHAD_CTRL for better timestamping */
|
||||
+ if (!is_sparx5(sparx5)) {
|
||||
+ for (int i = 0; i < 2; ++i) {
|
||||
+ /* Divide the port clock by three for the two
|
||||
+ * phase detection registers.
|
||||
+ */
|
||||
+ spx5_rmw(DEV2G5_PHAD_CTRL_DIV_CFG_SET(3) |
|
||||
+ DEV2G5_PHAD_CTRL_PHAD_ENA_SET(1),
|
||||
+ DEV2G5_PHAD_CTRL_DIV_CFG |
|
||||
+ DEV2G5_PHAD_CTRL_PHAD_ENA,
|
||||
+ sparx5, DEV2G5_PHAD_CTRL(port->portno, i));
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -978,6 +995,7 @@ int sparx5_port_config(struct sparx5 *sp
|
||||
struct sparx5_port_config *conf)
|
||||
{
|
||||
bool high_speed_dev = sparx5_is_baser(conf->portmode);
|
||||
+ const struct sparx5_ops *ops = sparx5->data->ops;
|
||||
int err, urgency, stop_wm;
|
||||
|
||||
err = sparx5_port_verify_speed(sparx5, port, conf);
|
||||
@@ -993,6 +1011,13 @@ int sparx5_port_config(struct sparx5 *sp
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
+ if (!is_sparx5(sparx5) && ops->is_port_10g(port->portno) &&
|
||||
+ conf->speed < SPEED_10000)
|
||||
+ spx5_rmw(DSM_DEV_TX_STOP_WM_CFG_DEV10G_SHADOW_ENA_SET(1),
|
||||
+ DSM_DEV_TX_STOP_WM_CFG_DEV10G_SHADOW_ENA,
|
||||
+ sparx5,
|
||||
+ DSM_DEV_TX_STOP_WM_CFG(port->portno));
|
||||
+
|
||||
/* Set the DSM stop watermark */
|
||||
stop_wm = sparx5_port_fifo_sz(sparx5, port->portno, conf->speed);
|
||||
spx5_rmw(DSM_DEV_TX_STOP_WM_CFG_DEV_TX_STOP_WM_SET(stop_wm),
|
||||
@@ -1144,6 +1169,27 @@ int sparx5_port_init(struct sparx5 *spar
|
||||
DEV25G_PCS25G_SD_CFG(pix));
|
||||
}
|
||||
|
||||
+ if (!is_sparx5(sparx5)) {
|
||||
+ void __iomem *inst;
|
||||
+ u32 dev, tinst;
|
||||
+
|
||||
+ if (ops->is_port_10g(port->portno)) {
|
||||
+ dev = sparx5_to_high_dev(sparx5, port->portno);
|
||||
+ tinst = sparx5_port_dev_index(sparx5, port->portno);
|
||||
+ inst = spx5_inst_get(sparx5, dev, tinst);
|
||||
+
|
||||
+ spx5_inst_wr(5, inst,
|
||||
+ DEV10G_PTP_STAMPER_CFG(port->portno));
|
||||
+ } else if (ops->is_port_5g(port->portno)) {
|
||||
+ dev = sparx5_to_high_dev(sparx5, port->portno);
|
||||
+ tinst = sparx5_port_dev_index(sparx5, port->portno);
|
||||
+ inst = spx5_inst_get(sparx5, dev, tinst);
|
||||
+
|
||||
+ spx5_inst_wr(5, inst,
|
||||
+ DEV5G_PTP_STAMPER_CFG(port->portno));
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
return 0;
|
||||
}
|
||||
|
||||
--- a/drivers/net/ethernet/microchip/sparx5/sparx5_qos.c
|
||||
+++ b/drivers/net/ethernet/microchip/sparx5/sparx5_qos.c
|
||||
@@ -367,9 +367,10 @@ static u32 sparx5_weight_to_hw_cost(u32
|
||||
static int sparx5_dwrr_conf_set(struct sparx5_port *port,
|
||||
struct sparx5_dwrr *dwrr)
|
||||
{
|
||||
+ u32 layer = is_sparx5(port->sparx5) ? 2 : 1;
|
||||
int i;
|
||||
|
||||
- spx5_rmw(HSCH_HSCH_CFG_CFG_HSCH_LAYER_SET(2) |
|
||||
+ spx5_rmw(HSCH_HSCH_CFG_CFG_HSCH_LAYER_SET(layer) |
|
||||
HSCH_HSCH_CFG_CFG_CFG_SE_IDX_SET(port->portno),
|
||||
HSCH_HSCH_CFG_CFG_HSCH_LAYER | HSCH_HSCH_CFG_CFG_CFG_SE_IDX,
|
||||
port->sparx5, HSCH_HSCH_CFG_CFG);
|
||||
@ -0,0 +1,38 @@
|
||||
From a02276501dbc5ae015e56aad0176e9f40703aac9 Mon Sep 17 00:00:00 2001
|
||||
From: Daniel Machon <daniel.machon@microchip.com>
|
||||
Date: Thu, 24 Oct 2024 00:01:33 +0200
|
||||
Subject: [PATCH 56/82] net: sparx5: add compatible string for lan969x
|
||||
|
||||
Add lan9691-switch compatible string to mchp_sparx5_match. Guard it with
|
||||
IS_ENABLED(CONFIG_LAN969X_SWITCH) to make sure Sparx5 can be compiled on
|
||||
its own.
|
||||
|
||||
Reviewed-by: Steen Hegelund <Steen.Hegelund@microchip.com>
|
||||
Signed-off-by: Daniel Machon <daniel.machon@microchip.com>
|
||||
Link: https://patch.msgid.link/20241024-sparx5-lan969x-switch-driver-2-v2-14-a0b5fae88a0f@microchip.com
|
||||
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
|
||||
---
|
||||
drivers/net/ethernet/microchip/sparx5/sparx5_main.c | 5 +++++
|
||||
1 file changed, 5 insertions(+)
|
||||
|
||||
--- a/drivers/net/ethernet/microchip/sparx5/sparx5_main.c
|
||||
+++ b/drivers/net/ethernet/microchip/sparx5/sparx5_main.c
|
||||
@@ -24,6 +24,8 @@
|
||||
#include <linux/types.h>
|
||||
#include <linux/reset.h>
|
||||
|
||||
+#include "../lan969x/lan969x.h" /* for lan969x match data */
|
||||
+
|
||||
#include "sparx5_main_regs.h"
|
||||
#include "sparx5_main.h"
|
||||
#include "sparx5_port.h"
|
||||
@@ -1049,6 +1051,9 @@ static const struct sparx5_match_data sp
|
||||
|
||||
static const struct of_device_id mchp_sparx5_match[] = {
|
||||
{ .compatible = "microchip,sparx5-switch", .data = &sparx5_desc },
|
||||
+#if IS_ENABLED(CONFIG_LAN969X_SWITCH)
|
||||
+ { .compatible = "microchip,lan9691-switch", .data = &lan969x_desc },
|
||||
+#endif
|
||||
{ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, mchp_sparx5_match);
|
||||
@ -0,0 +1,130 @@
|
||||
From 77520fd6b40f129f2b8d6d81d27bd311d30c3250 Mon Sep 17 00:00:00 2001
|
||||
From: Daniel Machon <daniel.machon@microchip.com>
|
||||
Date: Thu, 24 Oct 2024 00:01:34 +0200
|
||||
Subject: [PATCH 57/82] net: sparx5: add feature support
|
||||
|
||||
Lan969x supports a number of different features, depending on the
|
||||
target. Add new field sparx5->features and initialize the features based
|
||||
on the target. Also add the function sparx5_has_feature() and use it
|
||||
throughout. For now, we only need to handle features: PSFP and PTP -
|
||||
more will come in the future.
|
||||
|
||||
[1] https://www.microchip.com/en-us/product/lan9698
|
||||
|
||||
Reviewed-by: Steen Hegelund <Steen.Hegelund@microchip.com>
|
||||
Signed-off-by: Daniel Machon <daniel.machon@microchip.com>
|
||||
Link: https://patch.msgid.link/20241024-sparx5-lan969x-switch-driver-2-v2-15-a0b5fae88a0f@microchip.com
|
||||
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
|
||||
---
|
||||
.../ethernet/microchip/sparx5/sparx5_main.c | 40 ++++++++++++++++++-
|
||||
.../ethernet/microchip/sparx5/sparx5_main.h | 7 ++++
|
||||
.../microchip/sparx5/sparx5_tc_flower.c | 5 +++
|
||||
3 files changed, 51 insertions(+), 1 deletion(-)
|
||||
|
||||
--- a/drivers/net/ethernet/microchip/sparx5/sparx5_main.c
|
||||
+++ b/drivers/net/ethernet/microchip/sparx5/sparx5_main.c
|
||||
@@ -229,6 +229,40 @@ bool is_sparx5(struct sparx5 *sparx5)
|
||||
}
|
||||
}
|
||||
|
||||
+static void sparx5_init_features(struct sparx5 *sparx5)
|
||||
+{
|
||||
+ switch (sparx5->target_ct) {
|
||||
+ case SPX5_TARGET_CT_7546:
|
||||
+ case SPX5_TARGET_CT_7549:
|
||||
+ case SPX5_TARGET_CT_7552:
|
||||
+ case SPX5_TARGET_CT_7556:
|
||||
+ case SPX5_TARGET_CT_7558:
|
||||
+ case SPX5_TARGET_CT_7546TSN:
|
||||
+ case SPX5_TARGET_CT_7549TSN:
|
||||
+ case SPX5_TARGET_CT_7552TSN:
|
||||
+ case SPX5_TARGET_CT_7556TSN:
|
||||
+ case SPX5_TARGET_CT_7558TSN:
|
||||
+ case SPX5_TARGET_CT_LAN9691VAO:
|
||||
+ case SPX5_TARGET_CT_LAN9694TSN:
|
||||
+ case SPX5_TARGET_CT_LAN9694RED:
|
||||
+ case SPX5_TARGET_CT_LAN9692VAO:
|
||||
+ case SPX5_TARGET_CT_LAN9696TSN:
|
||||
+ case SPX5_TARGET_CT_LAN9696RED:
|
||||
+ case SPX5_TARGET_CT_LAN9693VAO:
|
||||
+ case SPX5_TARGET_CT_LAN9698TSN:
|
||||
+ case SPX5_TARGET_CT_LAN9698RED:
|
||||
+ sparx5->features = (SPX5_FEATURE_PSFP | SPX5_FEATURE_PTP);
|
||||
+ break;
|
||||
+ default:
|
||||
+ break;
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+bool sparx5_has_feature(struct sparx5 *sparx5, enum sparx5_feature feature)
|
||||
+{
|
||||
+ return sparx5->features & feature;
|
||||
+}
|
||||
+
|
||||
static int sparx5_create_targets(struct sparx5 *sparx5)
|
||||
{
|
||||
const struct sparx5_main_io_resource *iomap = sparx5->data->iomap;
|
||||
@@ -770,7 +804,8 @@ static int sparx5_start(struct sparx5 *s
|
||||
sparx5->xtr_irq = -ENXIO;
|
||||
}
|
||||
|
||||
- if (sparx5->ptp_irq >= 0) {
|
||||
+ if (sparx5->ptp_irq >= 0 &&
|
||||
+ sparx5_has_feature(sparx5, SPX5_FEATURE_PTP)) {
|
||||
err = devm_request_threaded_irq(sparx5->dev, sparx5->ptp_irq,
|
||||
NULL, ops->ptp_irq_handler,
|
||||
IRQF_ONESHOT, "sparx5-ptp",
|
||||
@@ -914,6 +949,9 @@ static int mchp_sparx5_probe(struct plat
|
||||
sparx5->target_ct = (enum spx5_target_chiptype)
|
||||
GCB_CHIP_ID_PART_ID_GET(sparx5->chip_id);
|
||||
|
||||
+ /* Initialize the features based on the target */
|
||||
+ sparx5_init_features(sparx5);
|
||||
+
|
||||
/* Initialize Switchcore and internal RAMs */
|
||||
err = sparx5_init_switchcore(sparx5);
|
||||
if (err) {
|
||||
--- a/drivers/net/ethernet/microchip/sparx5/sparx5_main.h
|
||||
+++ b/drivers/net/ethernet/microchip/sparx5/sparx5_main.h
|
||||
@@ -75,6 +75,11 @@ enum sparx5_cal_bw {
|
||||
SPX5_CAL_SPEED_12G5 = 7
|
||||
};
|
||||
|
||||
+enum sparx5_feature {
|
||||
+ SPX5_FEATURE_PSFP = BIT(0),
|
||||
+ SPX5_FEATURE_PTP = BIT(1),
|
||||
+};
|
||||
+
|
||||
#define SPX5_PORTS 65
|
||||
#define SPX5_PORTS_ALL 70 /* Total number of ports */
|
||||
|
||||
@@ -337,6 +342,7 @@ struct sparx5 {
|
||||
struct device *dev;
|
||||
u32 chip_id;
|
||||
enum spx5_target_chiptype target_ct;
|
||||
+ u32 features;
|
||||
void __iomem *regs[NUM_TARGETS];
|
||||
int port_count;
|
||||
struct mutex lock; /* MAC reg lock */
|
||||
@@ -404,6 +410,7 @@ struct sparx5 {
|
||||
|
||||
/* sparx5_main.c */
|
||||
bool is_sparx5(struct sparx5 *sparx5);
|
||||
+bool sparx5_has_feature(struct sparx5 *sparx5, enum sparx5_feature feature);
|
||||
|
||||
/* sparx5_switchdev.c */
|
||||
int sparx5_register_notifier_blocks(struct sparx5 *sparx5);
|
||||
--- a/drivers/net/ethernet/microchip/sparx5/sparx5_tc_flower.c
|
||||
+++ b/drivers/net/ethernet/microchip/sparx5/sparx5_tc_flower.c
|
||||
@@ -1284,6 +1284,11 @@ static int sparx5_tc_flower_replace(stru
|
||||
|
||||
/* Setup PSFP */
|
||||
if (tc_sg_idx >= 0 || tc_pol_idx >= 0) {
|
||||
+ if (!sparx5_has_feature(sparx5, SPX5_FEATURE_PSFP)) {
|
||||
+ err = -EOPNOTSUPP;
|
||||
+ goto out;
|
||||
+ }
|
||||
+
|
||||
err = sparx5_tc_flower_psfp_setup(sparx5, vrule, tc_sg_idx,
|
||||
tc_pol_idx, &sg, &fm, &sf);
|
||||
if (err)
|
||||
@ -0,0 +1,116 @@
|
||||
From c7a8ba9eec856c3a1d134a09387df04a13efb163 Mon Sep 17 00:00:00 2001
|
||||
From: Daniel Machon <daniel.machon@microchip.com>
|
||||
Date: Fri, 1 Nov 2024 08:09:07 +0100
|
||||
Subject: [PATCH 58/82] net: sparx5: expose some sparx5 VCAP symbols
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
In preparation for lan969x VCAP support, expose the following symbols for
|
||||
use by the lan969x VCAP implementation:
|
||||
|
||||
- The symbols SPARX5_*_LOOKUPS defines the number of lookups in each
|
||||
VCAP instance. These are the same for lan969x. Move them to the
|
||||
header file.
|
||||
|
||||
- The struct sparx5_vcap_inst encapsulates information about a single
|
||||
VCAP instance. Move this struct to the header file and declare the
|
||||
sparx5_vcap_inst_cfg as extern.
|
||||
|
||||
Reviewed-by: Steen Hegelund <Steen.Hegelund@microchip.com>
|
||||
Reviewed-by: Jens Emil Schulz Østergaard <jensemil.schulzostergaard@microchip.com>
|
||||
Signed-off-by: Daniel Machon <daniel.machon@microchip.com>
|
||||
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
|
||||
---
|
||||
.../microchip/sparx5/sparx5_vcap_impl.c | 18 +---------------
|
||||
.../microchip/sparx5/sparx5_vcap_impl.h | 21 +++++++++++++++++++
|
||||
2 files changed, 22 insertions(+), 17 deletions(-)
|
||||
|
||||
--- a/drivers/net/ethernet/microchip/sparx5/sparx5_vcap_impl.c
|
||||
+++ b/drivers/net/ethernet/microchip/sparx5/sparx5_vcap_impl.c
|
||||
@@ -17,7 +17,6 @@
|
||||
#define SUPER_VCAP_BLK_SIZE 3072 /* addresses per Super VCAP block */
|
||||
#define STREAMSIZE (64 * 4) /* bytes in the VCAP cache area */
|
||||
|
||||
-#define SPARX5_IS2_LOOKUPS 4
|
||||
#define VCAP_IS2_KEYSEL(_ena, _noneth, _v4_mc, _v4_uc, _v6_mc, _v6_uc, _arp) \
|
||||
(ANA_ACL_VCAP_S2_KEY_SEL_KEY_SEL_ENA_SET(_ena) | \
|
||||
ANA_ACL_VCAP_S2_KEY_SEL_NON_ETH_KEY_SEL_SET(_noneth) | \
|
||||
@@ -27,7 +26,6 @@
|
||||
ANA_ACL_VCAP_S2_KEY_SEL_IP6_UC_KEY_SEL_SET(_v6_uc) | \
|
||||
ANA_ACL_VCAP_S2_KEY_SEL_ARP_KEY_SEL_SET(_arp))
|
||||
|
||||
-#define SPARX5_IS0_LOOKUPS 6
|
||||
#define VCAP_IS0_KEYSEL(_ena, _etype, _ipv4, _ipv6, _mpls_uc, _mpls_mc, _mlbs) \
|
||||
(ANA_CL_ADV_CL_CFG_LOOKUP_ENA_SET(_ena) | \
|
||||
ANA_CL_ADV_CL_CFG_ETYPE_CLM_KEY_SEL_SET(_etype) | \
|
||||
@@ -37,31 +35,17 @@
|
||||
ANA_CL_ADV_CL_CFG_MPLS_MC_CLM_KEY_SEL_SET(_mpls_mc) | \
|
||||
ANA_CL_ADV_CL_CFG_MLBS_CLM_KEY_SEL_SET(_mlbs))
|
||||
|
||||
-#define SPARX5_ES0_LOOKUPS 1
|
||||
#define VCAP_ES0_KEYSEL(_key) (REW_RTAG_ETAG_CTRL_ES0_ISDX_KEY_ENA_SET(_key))
|
||||
#define SPARX5_STAT_ESDX_GRN_PKTS 0x300
|
||||
#define SPARX5_STAT_ESDX_YEL_PKTS 0x301
|
||||
|
||||
-#define SPARX5_ES2_LOOKUPS 2
|
||||
#define VCAP_ES2_KEYSEL(_ena, _arp, _ipv4, _ipv6) \
|
||||
(EACL_VCAP_ES2_KEY_SEL_KEY_ENA_SET(_ena) | \
|
||||
EACL_VCAP_ES2_KEY_SEL_ARP_KEY_SEL_SET(_arp) | \
|
||||
EACL_VCAP_ES2_KEY_SEL_IP4_KEY_SEL_SET(_ipv4) | \
|
||||
EACL_VCAP_ES2_KEY_SEL_IP6_KEY_SEL_SET(_ipv6))
|
||||
|
||||
-static struct sparx5_vcap_inst {
|
||||
- enum vcap_type vtype; /* type of vcap */
|
||||
- int vinst; /* instance number within the same type */
|
||||
- int lookups; /* number of lookups in this vcap type */
|
||||
- int lookups_per_instance; /* number of lookups in this instance */
|
||||
- int first_cid; /* first chain id in this vcap */
|
||||
- int last_cid; /* last chain id in this vcap */
|
||||
- int count; /* number of available addresses, not in super vcap */
|
||||
- int map_id; /* id in the super vcap block mapping (if applicable) */
|
||||
- int blockno; /* starting block in super vcap (if applicable) */
|
||||
- int blocks; /* number of blocks in super vcap (if applicable) */
|
||||
- bool ingress; /* is vcap in the ingress path */
|
||||
-} sparx5_vcap_inst_cfg[] = {
|
||||
+const struct sparx5_vcap_inst sparx5_vcap_inst_cfg[] = {
|
||||
{
|
||||
.vtype = VCAP_TYPE_IS0, /* CLM-0 */
|
||||
.vinst = 0,
|
||||
--- a/drivers/net/ethernet/microchip/sparx5/sparx5_vcap_impl.h
|
||||
+++ b/drivers/net/ethernet/microchip/sparx5/sparx5_vcap_impl.h
|
||||
@@ -16,6 +16,11 @@
|
||||
#include "vcap_api.h"
|
||||
#include "vcap_api_client.h"
|
||||
|
||||
+#define SPARX5_IS2_LOOKUPS 4
|
||||
+#define SPARX5_IS0_LOOKUPS 6
|
||||
+#define SPARX5_ES0_LOOKUPS 1
|
||||
+#define SPARX5_ES2_LOOKUPS 2
|
||||
+
|
||||
#define SPARX5_VCAP_CID_IS0_L0 VCAP_CID_INGRESS_L0 /* IS0/CLM lookup 0 */
|
||||
#define SPARX5_VCAP_CID_IS0_L1 VCAP_CID_INGRESS_L1 /* IS0/CLM lookup 1 */
|
||||
#define SPARX5_VCAP_CID_IS0_L2 VCAP_CID_INGRESS_L2 /* IS0/CLM lookup 2 */
|
||||
@@ -40,6 +45,22 @@
|
||||
#define SPARX5_VCAP_CID_ES2_MAX \
|
||||
(VCAP_CID_EGRESS_STAGE2_L1 + VCAP_CID_LOOKUP_SIZE - 1) /* ES2 Max */
|
||||
|
||||
+struct sparx5_vcap_inst {
|
||||
+ enum vcap_type vtype; /* type of vcap */
|
||||
+ int vinst; /* instance number within the same type */
|
||||
+ int lookups; /* number of lookups in this vcap type */
|
||||
+ int lookups_per_instance; /* number of lookups in this instance */
|
||||
+ int first_cid; /* first chain id in this vcap */
|
||||
+ int last_cid; /* last chain id in this vcap */
|
||||
+ int count; /* number of available addresses, not in super vcap */
|
||||
+ int map_id; /* id in the super vcap block mapping (if applicable) */
|
||||
+ int blockno; /* starting block in super vcap (if applicable) */
|
||||
+ int blocks; /* number of blocks in super vcap (if applicable) */
|
||||
+ bool ingress; /* is vcap in the ingress path */
|
||||
+};
|
||||
+
|
||||
+extern const struct sparx5_vcap_inst sparx5_vcap_inst_cfg[];
|
||||
+
|
||||
/* IS0 port keyset selection control */
|
||||
|
||||
/* IS0 ethernet, IPv4, IPv6 traffic type keyset generation */
|
||||
@ -0,0 +1,143 @@
|
||||
From 847d70a1d4583e2a5c00faf48e54d8880d248310 Mon Sep 17 00:00:00 2001
|
||||
From: Daniel Machon <daniel.machon@microchip.com>
|
||||
Date: Fri, 1 Nov 2024 08:09:08 +0100
|
||||
Subject: [PATCH 59/82] net: sparx5: replace SPX5_PORTS with n_ports
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
The Sparx5 VCAP implementation uses the SPX5_PORTS symbol to iterate over
|
||||
the 65 front ports of Sparx5. Replace the use with the n_ports constant
|
||||
from the match data, which translates to 65 of Sparx5 and 30 on lan969x.
|
||||
|
||||
Reviewed-by: Steen Hegelund <Steen.Hegelund@microchip.com>
|
||||
Reviewed-by: Jens Emil Schulz Østergaard <jensemil.schulzostergaard@microchip.com>
|
||||
Signed-off-by: Daniel Machon <daniel.machon@microchip.com>
|
||||
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
|
||||
---
|
||||
.../microchip/sparx5/sparx5_vcap_impl.c | 24 ++++++++++++-------
|
||||
1 file changed, 15 insertions(+), 9 deletions(-)
|
||||
|
||||
--- a/drivers/net/ethernet/microchip/sparx5/sparx5_vcap_impl.c
|
||||
+++ b/drivers/net/ethernet/microchip/sparx5/sparx5_vcap_impl.c
|
||||
@@ -1777,6 +1777,7 @@ void sparx5_vcap_set_port_keyset(struct
|
||||
static void sparx5_vcap_is0_port_key_selection(struct sparx5 *sparx5,
|
||||
struct vcap_admin *admin)
|
||||
{
|
||||
+ const struct sparx5_consts *consts = sparx5->data->consts;
|
||||
int portno, lookup;
|
||||
u32 keysel;
|
||||
|
||||
@@ -1788,7 +1789,7 @@ static void sparx5_vcap_is0_port_key_sel
|
||||
VCAP_IS0_PS_MPLS_FOLLOW_ETYPE,
|
||||
VCAP_IS0_PS_MLBS_FOLLOW_ETYPE);
|
||||
for (lookup = 0; lookup < admin->lookups; ++lookup) {
|
||||
- for (portno = 0; portno < SPX5_PORTS; ++portno) {
|
||||
+ for (portno = 0; portno < consts->n_ports; ++portno) {
|
||||
spx5_wr(keysel, sparx5,
|
||||
ANA_CL_ADV_CL_CFG(portno, lookup));
|
||||
spx5_rmw(ANA_CL_ADV_CL_CFG_LOOKUP_ENA,
|
||||
@@ -1803,6 +1804,7 @@ static void sparx5_vcap_is0_port_key_sel
|
||||
static void sparx5_vcap_is2_port_key_selection(struct sparx5 *sparx5,
|
||||
struct vcap_admin *admin)
|
||||
{
|
||||
+ const struct sparx5_consts *consts = sparx5->data->consts;
|
||||
int portno, lookup;
|
||||
u32 keysel;
|
||||
|
||||
@@ -1813,13 +1815,13 @@ static void sparx5_vcap_is2_port_key_sel
|
||||
VCAP_IS2_PS_IPV6_UC_IP_7TUPLE,
|
||||
VCAP_IS2_PS_ARP_ARP);
|
||||
for (lookup = 0; lookup < admin->lookups; ++lookup) {
|
||||
- for (portno = 0; portno < SPX5_PORTS; ++portno) {
|
||||
+ for (portno = 0; portno < consts->n_ports; ++portno) {
|
||||
spx5_wr(keysel, sparx5,
|
||||
ANA_ACL_VCAP_S2_KEY_SEL(portno, lookup));
|
||||
}
|
||||
}
|
||||
/* IS2 lookups are in bit 0:3 */
|
||||
- for (portno = 0; portno < SPX5_PORTS; ++portno)
|
||||
+ for (portno = 0; portno < consts->n_ports; ++portno)
|
||||
spx5_rmw(ANA_ACL_VCAP_S2_CFG_SEC_ENA_SET(0xf),
|
||||
ANA_ACL_VCAP_S2_CFG_SEC_ENA,
|
||||
sparx5,
|
||||
@@ -1830,11 +1832,12 @@ static void sparx5_vcap_is2_port_key_sel
|
||||
static void sparx5_vcap_es0_port_key_selection(struct sparx5 *sparx5,
|
||||
struct vcap_admin *admin)
|
||||
{
|
||||
+ const struct sparx5_consts *consts = sparx5->data->consts;
|
||||
int portno;
|
||||
u32 keysel;
|
||||
|
||||
keysel = VCAP_ES0_KEYSEL(VCAP_ES0_PS_FORCE_ISDX_LOOKUPS);
|
||||
- for (portno = 0; portno < SPX5_PORTS; ++portno)
|
||||
+ for (portno = 0; portno < consts->n_ports; ++portno)
|
||||
spx5_rmw(keysel, REW_RTAG_ETAG_CTRL_ES0_ISDX_KEY_ENA,
|
||||
sparx5, REW_RTAG_ETAG_CTRL(portno));
|
||||
|
||||
@@ -1846,6 +1849,7 @@ static void sparx5_vcap_es0_port_key_sel
|
||||
static void sparx5_vcap_es2_port_key_selection(struct sparx5 *sparx5,
|
||||
struct vcap_admin *admin)
|
||||
{
|
||||
+ const struct sparx5_consts *consts = sparx5->data->consts;
|
||||
int portno, lookup;
|
||||
u32 keysel;
|
||||
|
||||
@@ -1853,7 +1857,7 @@ static void sparx5_vcap_es2_port_key_sel
|
||||
VCAP_ES2_PS_IPV4_IP4_TCP_UDP_OTHER,
|
||||
VCAP_ES2_PS_IPV6_IP_7TUPLE);
|
||||
for (lookup = 0; lookup < admin->lookups; ++lookup)
|
||||
- for (portno = 0; portno < SPX5_PORTS; ++portno)
|
||||
+ for (portno = 0; portno < consts->n_ports; ++portno)
|
||||
spx5_wr(keysel, sparx5,
|
||||
EACL_VCAP_ES2_KEY_SEL(portno, lookup));
|
||||
}
|
||||
@@ -1885,19 +1889,20 @@ static void sparx5_vcap_port_key_selecti
|
||||
static void sparx5_vcap_port_key_deselection(struct sparx5 *sparx5,
|
||||
struct vcap_admin *admin)
|
||||
{
|
||||
+ const struct sparx5_consts *consts = sparx5->data->consts;
|
||||
int portno, lookup;
|
||||
|
||||
switch (admin->vtype) {
|
||||
case VCAP_TYPE_IS0:
|
||||
for (lookup = 0; lookup < admin->lookups; ++lookup)
|
||||
- for (portno = 0; portno < SPX5_PORTS; ++portno)
|
||||
+ for (portno = 0; portno < consts->n_ports; ++portno)
|
||||
spx5_rmw(ANA_CL_ADV_CL_CFG_LOOKUP_ENA_SET(0),
|
||||
ANA_CL_ADV_CL_CFG_LOOKUP_ENA,
|
||||
sparx5,
|
||||
ANA_CL_ADV_CL_CFG(portno, lookup));
|
||||
break;
|
||||
case VCAP_TYPE_IS2:
|
||||
- for (portno = 0; portno < SPX5_PORTS; ++portno)
|
||||
+ for (portno = 0; portno < consts->n_ports; ++portno)
|
||||
spx5_rmw(ANA_ACL_VCAP_S2_CFG_SEC_ENA_SET(0),
|
||||
ANA_ACL_VCAP_S2_CFG_SEC_ENA,
|
||||
sparx5,
|
||||
@@ -1909,7 +1914,7 @@ static void sparx5_vcap_port_key_deselec
|
||||
break;
|
||||
case VCAP_TYPE_ES2:
|
||||
for (lookup = 0; lookup < admin->lookups; ++lookup)
|
||||
- for (portno = 0; portno < SPX5_PORTS; ++portno)
|
||||
+ for (portno = 0; portno < consts->n_ports; ++portno)
|
||||
spx5_rmw(EACL_VCAP_ES2_KEY_SEL_KEY_ENA_SET(0),
|
||||
EACL_VCAP_ES2_KEY_SEL_KEY_ENA,
|
||||
sparx5,
|
||||
@@ -2026,6 +2031,7 @@ static void sparx5_vcap_block_alloc(stru
|
||||
/* Allocate a vcap control and vcap instances and configure the system */
|
||||
int sparx5_vcap_init(struct sparx5 *sparx5)
|
||||
{
|
||||
+ const struct sparx5_consts *consts = sparx5->data->consts;
|
||||
const struct sparx5_vcap_inst *cfg;
|
||||
struct vcap_control *ctrl;
|
||||
struct vcap_admin *admin;
|
||||
@@ -2069,7 +2075,7 @@ int sparx5_vcap_init(struct sparx5 *spar
|
||||
list_add_tail(&admin->list, &ctrl->list);
|
||||
}
|
||||
dir = vcap_debugfs(sparx5->dev, sparx5->debugfs_root, ctrl);
|
||||
- for (idx = 0; idx < SPX5_PORTS; ++idx)
|
||||
+ for (idx = 0; idx < consts->n_ports; ++idx)
|
||||
if (sparx5->ports[idx])
|
||||
vcap_port_debugfs(sparx5->dev, dir, ctrl,
|
||||
sparx5->ports[idx]->ndev);
|
||||
@ -0,0 +1,97 @@
|
||||
From 6deea25857672a2ae9742499634b07f83508b35a Mon Sep 17 00:00:00 2001
|
||||
From: Daniel Machon <daniel.machon@microchip.com>
|
||||
Date: Fri, 1 Nov 2024 08:09:09 +0100
|
||||
Subject: [PATCH 60/82] net: sparx5: add new VCAP constants to match data
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
In preparation for lan969x VCAP support, add the following three new
|
||||
VCAP constants to match data:
|
||||
|
||||
- vcaps_cfg (contains configuration data for each VCAP).
|
||||
|
||||
- vcaps (contains auto-generated information about VCAP keys and
|
||||
actions).
|
||||
|
||||
- vcap_stats: (contains auto-generated string names of all the keys
|
||||
and actions)
|
||||
|
||||
Add these constants to the Sparx5 match data constants and use them to
|
||||
initialize the VCAP's in sparx5_vcap_init().
|
||||
|
||||
Reviewed-by: Steen Hegelund <Steen.Hegelund@microchip.com>
|
||||
Reviewed-by: Jens Emil Schulz Østergaard <jensemil.schulzostergaard@microchip.com>
|
||||
Signed-off-by: Daniel Machon <daniel.machon@microchip.com>
|
||||
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
|
||||
---
|
||||
drivers/net/ethernet/microchip/sparx5/sparx5_main.c | 5 +++++
|
||||
drivers/net/ethernet/microchip/sparx5/sparx5_main.h | 3 +++
|
||||
drivers/net/ethernet/microchip/sparx5/sparx5_vcap_ag_api.h | 2 ++
|
||||
drivers/net/ethernet/microchip/sparx5/sparx5_vcap_impl.c | 6 +++---
|
||||
4 files changed, 13 insertions(+), 3 deletions(-)
|
||||
|
||||
--- a/drivers/net/ethernet/microchip/sparx5/sparx5_main.c
|
||||
+++ b/drivers/net/ethernet/microchip/sparx5/sparx5_main.c
|
||||
@@ -30,6 +30,8 @@
|
||||
#include "sparx5_main.h"
|
||||
#include "sparx5_port.h"
|
||||
#include "sparx5_qos.h"
|
||||
+#include "sparx5_vcap_ag_api.h"
|
||||
+#include "sparx5_vcap_impl.h"
|
||||
|
||||
const struct sparx5_regs *regs;
|
||||
|
||||
@@ -1062,6 +1064,9 @@ static const struct sparx5_consts sparx5
|
||||
.qres_max_prio_idx = 630,
|
||||
.qres_max_colour_idx = 638,
|
||||
.tod_pin = 4,
|
||||
+ .vcaps = sparx5_vcaps,
|
||||
+ .vcaps_cfg = sparx5_vcap_inst_cfg,
|
||||
+ .vcap_stats = &sparx5_vcap_stats,
|
||||
};
|
||||
|
||||
static const struct sparx5_ops sparx5_ops = {
|
||||
--- a/drivers/net/ethernet/microchip/sparx5/sparx5_main.h
|
||||
+++ b/drivers/net/ethernet/microchip/sparx5/sparx5_main.h
|
||||
@@ -303,6 +303,9 @@ struct sparx5_consts {
|
||||
u32 qres_max_prio_idx; /* Maximum QRES prio index */
|
||||
u32 qres_max_colour_idx; /* Maximum QRES colour index */
|
||||
u32 tod_pin; /* PTP TOD pin */
|
||||
+ const struct sparx5_vcap_inst *vcaps_cfg;
|
||||
+ const struct vcap_info *vcaps;
|
||||
+ const struct vcap_statistics *vcap_stats;
|
||||
};
|
||||
|
||||
struct sparx5_ops {
|
||||
--- a/drivers/net/ethernet/microchip/sparx5/sparx5_vcap_ag_api.h
|
||||
+++ b/drivers/net/ethernet/microchip/sparx5/sparx5_vcap_ag_api.h
|
||||
@@ -10,6 +10,8 @@
|
||||
#ifndef __SPARX5_VCAP_AG_API_H__
|
||||
#define __SPARX5_VCAP_AG_API_H__
|
||||
|
||||
+#include "vcap_api.h"
|
||||
+
|
||||
/* VCAPs */
|
||||
extern const struct vcap_info sparx5_vcaps[];
|
||||
extern const struct vcap_statistics sparx5_vcap_stats;
|
||||
--- a/drivers/net/ethernet/microchip/sparx5/sparx5_vcap_impl.c
|
||||
+++ b/drivers/net/ethernet/microchip/sparx5/sparx5_vcap_impl.c
|
||||
@@ -2053,14 +2053,14 @@ int sparx5_vcap_init(struct sparx5 *spar
|
||||
|
||||
sparx5->vcap_ctrl = ctrl;
|
||||
/* select the sparx5 VCAP model */
|
||||
- ctrl->vcaps = sparx5_vcaps;
|
||||
- ctrl->stats = &sparx5_vcap_stats;
|
||||
+ ctrl->vcaps = consts->vcaps;
|
||||
+ ctrl->stats = consts->vcap_stats;
|
||||
/* Setup callbacks to allow the API to use the VCAP HW */
|
||||
ctrl->ops = &sparx5_vcap_ops;
|
||||
|
||||
INIT_LIST_HEAD(&ctrl->list);
|
||||
for (idx = 0; idx < ARRAY_SIZE(sparx5_vcap_inst_cfg); ++idx) {
|
||||
- cfg = &sparx5_vcap_inst_cfg[idx];
|
||||
+ cfg = &consts->vcaps_cfg[idx];
|
||||
admin = sparx5_vcap_admin_alloc(sparx5, ctrl, cfg);
|
||||
if (IS_ERR(admin)) {
|
||||
err = PTR_ERR(admin);
|
||||
@ -0,0 +1,39 @@
|
||||
From 41742f746f4860ad7658484ec24a2971476a9d05 Mon Sep 17 00:00:00 2001
|
||||
From: Daniel Machon <daniel.machon@microchip.com>
|
||||
Date: Fri, 1 Nov 2024 08:09:10 +0100
|
||||
Subject: [PATCH 61/82] net: sparx5: execute sparx5_vcap_init() on lan969x
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
The is_sparx5() check was introduced in an earlier series, to make sure
|
||||
the sparx5_vcap_init() was not executed on lan969x, as it was not
|
||||
implemented there yet. Now that it is, remove that check.
|
||||
|
||||
Reviewed-by: Steen Hegelund <Steen.Hegelund@microchip.com>
|
||||
Reviewed-by: Jens Emil Schulz Østergaard <jensemil.schulzostergaard@microchip.com>
|
||||
Signed-off-by: Daniel Machon <daniel.machon@microchip.com>
|
||||
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
|
||||
---
|
||||
drivers/net/ethernet/microchip/sparx5/sparx5_main.c | 10 ++++------
|
||||
1 file changed, 4 insertions(+), 6 deletions(-)
|
||||
|
||||
--- a/drivers/net/ethernet/microchip/sparx5/sparx5_main.c
|
||||
+++ b/drivers/net/ethernet/microchip/sparx5/sparx5_main.c
|
||||
@@ -770,12 +770,10 @@ static int sparx5_start(struct sparx5 *s
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
- if (is_sparx5(sparx5)) {
|
||||
- err = sparx5_vcap_init(sparx5);
|
||||
- if (err) {
|
||||
- sparx5_unregister_notifier_blocks(sparx5);
|
||||
- return err;
|
||||
- }
|
||||
+ err = sparx5_vcap_init(sparx5);
|
||||
+ if (err) {
|
||||
+ sparx5_unregister_notifier_blocks(sparx5);
|
||||
+ return err;
|
||||
}
|
||||
|
||||
/* Start Frame DMA with fallback to register based INJ/XTR */
|
||||
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,166 @@
|
||||
From 4a4336e333f869544dabc729812f57f99f5f2ff8 Mon Sep 17 00:00:00 2001
|
||||
From: Daniel Machon <daniel.machon@microchip.com>
|
||||
Date: Fri, 1 Nov 2024 08:09:12 +0100
|
||||
Subject: [PATCH 63/82] net: lan969x: add VCAP configuration data
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
Add configuration data (for consumption by the VCAP API) for the four
|
||||
VCAP's that we are going to support. The following VCAP's will be
|
||||
supported:
|
||||
|
||||
- VCAP CLM: (also known as IS0) is part of the analyzer and enables
|
||||
frame classification using VCAP functionality.
|
||||
|
||||
- VCAP IS2: is part of ANA_ACL and enables access control lists, using
|
||||
VCAP functionality.
|
||||
|
||||
- VCAP ES0: is part of the rewriter and enables rewriting of frames
|
||||
using VCAP functionality.
|
||||
|
||||
- VCAP ES2: is part of EACL and enables egress access control lists
|
||||
using VCAP functionality
|
||||
|
||||
The two VCAP's: CLM and IS2 use shared resources from the SUPER VCAP.
|
||||
The SUPER VCAP is a shared pool of 6 blocks that can be distributed
|
||||
freely among CLM and IS2. Each block in the pool has 3,072 addresses
|
||||
with entries, actions, and counters. ES0 and ES2 does not use shared
|
||||
resources.
|
||||
|
||||
In the configuration data for lan969x CLM uses blocks 2-4 with a total
|
||||
of 6 lookups. IS2 uses blocks 0-1 with a total of 4 lookups.
|
||||
|
||||
Reviewed-by: Steen Hegelund <Steen.Hegelund@microchip.com>
|
||||
Reviewed-by: Jens Emil Schulz Østergaard <jensemil.schulzostergaard@microchip.com>
|
||||
Signed-off-by: Daniel Machon <daniel.machon@microchip.com>
|
||||
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
|
||||
---
|
||||
.../net/ethernet/microchip/lan969x/Makefile | 2 +-
|
||||
.../net/ethernet/microchip/lan969x/lan969x.c | 1 +
|
||||
.../net/ethernet/microchip/lan969x/lan969x.h | 3 +
|
||||
.../microchip/lan969x/lan969x_vcap_impl.c | 85 +++++++++++++++++++
|
||||
4 files changed, 90 insertions(+), 1 deletion(-)
|
||||
create mode 100644 drivers/net/ethernet/microchip/lan969x/lan969x_vcap_impl.c
|
||||
|
||||
--- a/drivers/net/ethernet/microchip/lan969x/Makefile
|
||||
+++ b/drivers/net/ethernet/microchip/lan969x/Makefile
|
||||
@@ -6,7 +6,7 @@
|
||||
obj-$(CONFIG_LAN969X_SWITCH) += lan969x-switch.o
|
||||
|
||||
lan969x-switch-y := lan969x_regs.o lan969x.o lan969x_calendar.o \
|
||||
- lan969x_vcap_ag_api.o
|
||||
+ lan969x_vcap_ag_api.o lan969x_vcap_impl.o
|
||||
|
||||
# Provide include files
|
||||
ccflags-y += -I$(srctree)/drivers/net/ethernet/microchip/fdma
|
||||
--- a/drivers/net/ethernet/microchip/lan969x/lan969x.c
|
||||
+++ b/drivers/net/ethernet/microchip/lan969x/lan969x.c
|
||||
@@ -321,6 +321,7 @@ static const struct sparx5_consts lan969
|
||||
.tod_pin = 4,
|
||||
.vcaps = lan969x_vcaps,
|
||||
.vcap_stats = &lan969x_vcap_stats,
|
||||
+ .vcaps_cfg = lan969x_vcap_inst_cfg,
|
||||
};
|
||||
|
||||
static const struct sparx5_ops lan969x_ops = {
|
||||
--- a/drivers/net/ethernet/microchip/lan969x/lan969x.h
|
||||
+++ b/drivers/net/ethernet/microchip/lan969x/lan969x.h
|
||||
@@ -18,6 +18,9 @@ extern const struct sparx5_match_data la
|
||||
extern const struct vcap_statistics lan969x_vcap_stats;
|
||||
extern const struct vcap_info lan969x_vcaps[];
|
||||
|
||||
+/* lan969x_vcap_impl.c */
|
||||
+extern const struct sparx5_vcap_inst lan969x_vcap_inst_cfg[];
|
||||
+
|
||||
/* lan969x_regs.c */
|
||||
extern const unsigned int lan969x_tsize[TSIZE_LAST];
|
||||
extern const unsigned int lan969x_raddr[RADDR_LAST];
|
||||
--- /dev/null
|
||||
+++ b/drivers/net/ethernet/microchip/lan969x/lan969x_vcap_impl.c
|
||||
@@ -0,0 +1,85 @@
|
||||
+// SPDX-License-Identifier: GPL-2.0+
|
||||
+
|
||||
+#include "vcap_api.h"
|
||||
+#include "lan969x.h"
|
||||
+
|
||||
+const struct sparx5_vcap_inst lan969x_vcap_inst_cfg[] = {
|
||||
+ {
|
||||
+ .vtype = VCAP_TYPE_IS0, /* CLM-0 */
|
||||
+ .vinst = 0,
|
||||
+ .map_id = 1,
|
||||
+ .lookups = SPARX5_IS0_LOOKUPS,
|
||||
+ .lookups_per_instance = SPARX5_IS0_LOOKUPS / 3,
|
||||
+ .first_cid = SPARX5_VCAP_CID_IS0_L0,
|
||||
+ .last_cid = SPARX5_VCAP_CID_IS0_L2 - 1,
|
||||
+ .blockno = 2,
|
||||
+ .blocks = 1,
|
||||
+ .ingress = true,
|
||||
+ },
|
||||
+ {
|
||||
+ .vtype = VCAP_TYPE_IS0, /* CLM-1 */
|
||||
+ .vinst = 1,
|
||||
+ .map_id = 2,
|
||||
+ .lookups = SPARX5_IS0_LOOKUPS,
|
||||
+ .lookups_per_instance = SPARX5_IS0_LOOKUPS / 3,
|
||||
+ .first_cid = SPARX5_VCAP_CID_IS0_L2,
|
||||
+ .last_cid = SPARX5_VCAP_CID_IS0_L4 - 1,
|
||||
+ .blockno = 3,
|
||||
+ .blocks = 1,
|
||||
+ .ingress = true,
|
||||
+ },
|
||||
+ {
|
||||
+ .vtype = VCAP_TYPE_IS0, /* CLM-2 */
|
||||
+ .vinst = 2,
|
||||
+ .map_id = 3,
|
||||
+ .lookups = SPARX5_IS0_LOOKUPS,
|
||||
+ .lookups_per_instance = SPARX5_IS0_LOOKUPS / 3,
|
||||
+ .first_cid = SPARX5_VCAP_CID_IS0_L4,
|
||||
+ .last_cid = SPARX5_VCAP_CID_IS0_MAX,
|
||||
+ .blockno = 4,
|
||||
+ .blocks = 1,
|
||||
+ .ingress = true,
|
||||
+ },
|
||||
+ {
|
||||
+ .vtype = VCAP_TYPE_IS2, /* IS2-0 */
|
||||
+ .vinst = 0,
|
||||
+ .map_id = 4,
|
||||
+ .lookups = SPARX5_IS2_LOOKUPS,
|
||||
+ .lookups_per_instance = SPARX5_IS2_LOOKUPS / 2,
|
||||
+ .first_cid = SPARX5_VCAP_CID_IS2_L0,
|
||||
+ .last_cid = SPARX5_VCAP_CID_IS2_L2 - 1,
|
||||
+ .blockno = 0,
|
||||
+ .blocks = 1,
|
||||
+ .ingress = true,
|
||||
+ },
|
||||
+ {
|
||||
+ .vtype = VCAP_TYPE_IS2, /* IS2-1 */
|
||||
+ .vinst = 1,
|
||||
+ .map_id = 5,
|
||||
+ .lookups = SPARX5_IS2_LOOKUPS,
|
||||
+ .lookups_per_instance = SPARX5_IS2_LOOKUPS / 2,
|
||||
+ .first_cid = SPARX5_VCAP_CID_IS2_L2,
|
||||
+ .last_cid = SPARX5_VCAP_CID_IS2_MAX,
|
||||
+ .blockno = 1,
|
||||
+ .blocks = 1,
|
||||
+ .ingress = true,
|
||||
+ },
|
||||
+ {
|
||||
+ .vtype = VCAP_TYPE_ES0,
|
||||
+ .lookups = SPARX5_ES0_LOOKUPS,
|
||||
+ .lookups_per_instance = SPARX5_ES0_LOOKUPS,
|
||||
+ .first_cid = SPARX5_VCAP_CID_ES0_L0,
|
||||
+ .last_cid = SPARX5_VCAP_CID_ES0_MAX,
|
||||
+ .count = 1536,
|
||||
+ .ingress = false,
|
||||
+ },
|
||||
+ {
|
||||
+ .vtype = VCAP_TYPE_ES2,
|
||||
+ .lookups = SPARX5_ES2_LOOKUPS,
|
||||
+ .lookups_per_instance = SPARX5_ES2_LOOKUPS,
|
||||
+ .first_cid = SPARX5_VCAP_CID_ES2_L0,
|
||||
+ .last_cid = SPARX5_VCAP_CID_ES2_MAX,
|
||||
+ .count = 1024,
|
||||
+ .ingress = false,
|
||||
+ },
|
||||
+};
|
||||
@ -0,0 +1,45 @@
|
||||
From e63e43479af9d5817eecd34e26af67a5064937b4 Mon Sep 17 00:00:00 2001
|
||||
From: Arnd Bergmann <arnd@arndb.de>
|
||||
Date: Wed, 13 Nov 2024 12:55:08 +0100
|
||||
Subject: [PATCH 64/82] net: sparx5: add missing lan969x Kconfig dependency
|
||||
|
||||
The sparx5 switchdev driver can be built either with or without support
|
||||
for the Lan969x switch. However, it cannot be built-in when the lan969x
|
||||
driver is a loadable module because of a link-time dependency:
|
||||
|
||||
arm-linux-gnueabi-ld: drivers/net/ethernet/microchip/sparx5/sparx5_main.o:(.rodata+0xd44): undefined reference to `lan969x_desc'
|
||||
|
||||
Add a Kconfig dependency to reflect this in Kconfig, allowing all
|
||||
the valid configurations but forcing sparx5 to be a loadable module
|
||||
as well if lan969x is.
|
||||
|
||||
Fixes: 98a01119608d ("net: sparx5: add compatible string for lan969x")
|
||||
Signed-off-by: Arnd Bergmann <arnd@arndb.de>
|
||||
Reviewed-by: Daniel Machon <daniel.machon@microchip.com>
|
||||
Link: https://patch.msgid.link/20241113115513.4132548-1-arnd@kernel.org
|
||||
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
|
||||
---
|
||||
drivers/net/ethernet/microchip/lan969x/Kconfig | 2 +-
|
||||
drivers/net/ethernet/microchip/lan969x/Makefile | 2 +-
|
||||
2 files changed, 2 insertions(+), 2 deletions(-)
|
||||
|
||||
--- a/drivers/net/ethernet/microchip/lan969x/Kconfig
|
||||
+++ b/drivers/net/ethernet/microchip/lan969x/Kconfig
|
||||
@@ -1,5 +1,5 @@
|
||||
config LAN969X_SWITCH
|
||||
- tristate "Lan969x switch driver"
|
||||
+ bool "Lan969x switch driver"
|
||||
depends on SPARX5_SWITCH
|
||||
help
|
||||
This driver supports the lan969x family of network switch devices.
|
||||
--- a/drivers/net/ethernet/microchip/lan969x/Makefile
|
||||
+++ b/drivers/net/ethernet/microchip/lan969x/Makefile
|
||||
@@ -3,7 +3,7 @@
|
||||
# Makefile for the Microchip lan969x network device drivers.
|
||||
#
|
||||
|
||||
-obj-$(CONFIG_LAN969X_SWITCH) += lan969x-switch.o
|
||||
+obj-$(CONFIG_SPARX5_SWITCH) += lan969x-switch.o
|
||||
|
||||
lan969x-switch-y := lan969x_regs.o lan969x.o lan969x_calendar.o \
|
||||
lan969x_vcap_ag_api.o lan969x_vcap_impl.o
|
||||
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,33 @@
|
||||
From f7a21fee946712acc54102479f0ebaaff48164e4 Mon Sep 17 00:00:00 2001
|
||||
From: Daniel Machon <daniel.machon@microchip.com>
|
||||
Date: Thu, 5 Dec 2024 14:54:25 +0100
|
||||
Subject: [PATCH 66/82] net: lan969x: fix the use of spin_lock in PTP handler
|
||||
|
||||
We are mixing the use of spin_lock() and spin_lock_irqsave() functions
|
||||
in the PTP handler of lan969x. Fix this by correctly using the _irqsave
|
||||
variants.
|
||||
|
||||
Fixes: 24fe83541755 ("net: lan969x: add PTP handler function")
|
||||
Signed-off-by: Daniel Machon <daniel.machon@microchip.com>
|
||||
|
||||
[1]: https://lore.kernel.org/netdev/20241024-sparx5-lan969x-switch-driver-2-v2-10-a0b5fae88a0f@microchip.com/
|
||||
|
||||
Signed-off-by: David S. Miller <davem@davemloft.net>
|
||||
---
|
||||
drivers/net/ethernet/microchip/sparx5/lan969x/lan969x.c | 4 ++--
|
||||
1 file changed, 2 insertions(+), 2 deletions(-)
|
||||
|
||||
--- a/drivers/net/ethernet/microchip/sparx5/lan969x/lan969x.c
|
||||
+++ b/drivers/net/ethernet/microchip/sparx5/lan969x/lan969x.c
|
||||
@@ -273,9 +273,9 @@ static irqreturn_t lan969x_ptp_irq_handl
|
||||
if (WARN_ON(!skb_match))
|
||||
continue;
|
||||
|
||||
- spin_lock(&sparx5->ptp_ts_id_lock);
|
||||
+ spin_lock_irqsave(&sparx5->ptp_ts_id_lock, flags);
|
||||
sparx5->ptp_skbs--;
|
||||
- spin_unlock(&sparx5->ptp_ts_id_lock);
|
||||
+ spin_unlock_irqrestore(&sparx5->ptp_ts_id_lock, flags);
|
||||
|
||||
/* Get the h/w timestamp */
|
||||
sparx5_get_hwtimestamp(sparx5, &ts, delay);
|
||||
@ -0,0 +1,42 @@
|
||||
From e647f95a65d299fbb58ef8d44795abab3bc63d41 Mon Sep 17 00:00:00 2001
|
||||
From: Daniel Machon <daniel.machon@microchip.com>
|
||||
Date: Thu, 5 Dec 2024 14:54:27 +0100
|
||||
Subject: [PATCH 67/82] net: sparx5: fix default value of monitor ports
|
||||
|
||||
When doing port mirroring, the physical port to send the frame to, is
|
||||
written to the FRMC_PORT_VAL field of the QFWD_FRAME_COPY_CFG register.
|
||||
This field is 7 bits wide on sparx5 and 6 bits wide on lan969x, and has
|
||||
a default value of 65 and 30, respectively (the number of front ports).
|
||||
|
||||
On mirror deletion, we set the default value of the monitor port to
|
||||
65 for this field, in case no more ports exists for the mirror. Needless
|
||||
to say, this will not fit the 6 bits on lan969x.
|
||||
|
||||
Fix this by correctly using the n_ports constant instead.
|
||||
|
||||
Fixes: 3f9e46347a46 ("net: sparx5: use SPX5_CONST for constants which already have a symbol")
|
||||
Signed-off-by: Daniel Machon <daniel.machon@microchip.com>
|
||||
Signed-off-by: David S. Miller <davem@davemloft.net>
|
||||
---
|
||||
drivers/net/ethernet/microchip/sparx5/sparx5_mirror.c | 3 +--
|
||||
1 file changed, 1 insertion(+), 2 deletions(-)
|
||||
|
||||
--- a/drivers/net/ethernet/microchip/sparx5/sparx5_mirror.c
|
||||
+++ b/drivers/net/ethernet/microchip/sparx5/sparx5_mirror.c
|
||||
@@ -12,7 +12,6 @@
|
||||
#define SPX5_MIRROR_DISABLED 0
|
||||
#define SPX5_MIRROR_EGRESS 1
|
||||
#define SPX5_MIRROR_INGRESS 2
|
||||
-#define SPX5_MIRROR_MONITOR_PORT_DEFAULT 65
|
||||
#define SPX5_QFWD_MP_OFFSET 9 /* Mirror port offset in the QFWD register */
|
||||
|
||||
/* Convert from bool ingress/egress to mirror direction */
|
||||
@@ -200,7 +199,7 @@ void sparx5_mirror_del(struct sparx5_mal
|
||||
|
||||
sparx5_mirror_monitor_set(sparx5,
|
||||
mirror_idx,
|
||||
- SPX5_MIRROR_MONITOR_PORT_DEFAULT);
|
||||
+ sparx5->data->consts->n_ports);
|
||||
}
|
||||
|
||||
void sparx5_mirror_stats(struct sparx5_mall_entry *entry,
|
||||
@ -0,0 +1,78 @@
|
||||
From 4bb216d318259f940eb2248dc91ade01edea1cc4 Mon Sep 17 00:00:00 2001
|
||||
From: Daniel Machon <daniel.machon@microchip.com>
|
||||
Date: Fri, 20 Dec 2024 14:48:40 +0100
|
||||
Subject: [PATCH 68/82] net: sparx5: do some preparation work
|
||||
|
||||
The sparx5_port_init() does initial configuration of a variety of
|
||||
different features and options for each port. Some are shared for all
|
||||
types of devices, some are not. As it is now, common configuration is
|
||||
done after configuration of low-speed devices. This will not work when
|
||||
adding RGMII support in a subsequent patch.
|
||||
|
||||
In preparation for lan969x RGMII support, move a block of code, that
|
||||
configures 2g5 devices, down. This ensures that the configuration common
|
||||
to all devices is done before configuration of 2g5, 5g, 10g and 25g
|
||||
devices.
|
||||
|
||||
Reviewed-by: Steen Hegelund <Steen.Hegelund@microchip.com>
|
||||
Reviewed-by: Horatiu Vultur <horatiu.vultur@microchip.com>
|
||||
Tested-by: Robert Marko <robert.marko@sartura.hr>
|
||||
Signed-off-by: Daniel Machon <daniel.machon@microchip.com>
|
||||
Link: https://patch.msgid.link/20241220-sparx5-lan969x-switch-driver-4-v5-1-fa8ba5dff732@microchip.com
|
||||
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
|
||||
---
|
||||
.../ethernet/microchip/sparx5/sparx5_port.c | 36 +++++++++----------
|
||||
1 file changed, 18 insertions(+), 18 deletions(-)
|
||||
|
||||
--- a/drivers/net/ethernet/microchip/sparx5/sparx5_port.c
|
||||
+++ b/drivers/net/ethernet/microchip/sparx5/sparx5_port.c
|
||||
@@ -1067,24 +1067,6 @@ int sparx5_port_init(struct sparx5 *spar
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
- /* Configure MAC vlan awareness */
|
||||
- err = sparx5_port_max_tags_set(sparx5, port);
|
||||
- if (err)
|
||||
- return err;
|
||||
-
|
||||
- /* Set Max Length */
|
||||
- spx5_rmw(DEV2G5_MAC_MAXLEN_CFG_MAX_LEN_SET(ETH_MAXLEN),
|
||||
- DEV2G5_MAC_MAXLEN_CFG_MAX_LEN,
|
||||
- sparx5,
|
||||
- DEV2G5_MAC_MAXLEN_CFG(port->portno));
|
||||
-
|
||||
- /* 1G/2G5: Signal Detect configuration */
|
||||
- spx5_wr(DEV2G5_PCS1G_SD_CFG_SD_POL_SET(sd_pol) |
|
||||
- DEV2G5_PCS1G_SD_CFG_SD_SEL_SET(sd_sel) |
|
||||
- DEV2G5_PCS1G_SD_CFG_SD_ENA_SET(sd_ena),
|
||||
- sparx5,
|
||||
- DEV2G5_PCS1G_SD_CFG(port->portno));
|
||||
-
|
||||
/* Set Pause WM hysteresis */
|
||||
spx5_rmw(QSYS_PAUSE_CFG_PAUSE_START_SET(pause_start) |
|
||||
QSYS_PAUSE_CFG_PAUSE_STOP_SET(pause_stop) |
|
||||
@@ -1108,6 +1090,24 @@ int sparx5_port_init(struct sparx5 *spar
|
||||
ANA_CL_FILTER_CTRL_FILTER_SMAC_MC_DIS,
|
||||
sparx5, ANA_CL_FILTER_CTRL(port->portno));
|
||||
|
||||
+ /* Configure MAC vlan awareness */
|
||||
+ err = sparx5_port_max_tags_set(sparx5, port);
|
||||
+ if (err)
|
||||
+ return err;
|
||||
+
|
||||
+ /* Set Max Length */
|
||||
+ spx5_rmw(DEV2G5_MAC_MAXLEN_CFG_MAX_LEN_SET(ETH_MAXLEN),
|
||||
+ DEV2G5_MAC_MAXLEN_CFG_MAX_LEN,
|
||||
+ sparx5,
|
||||
+ DEV2G5_MAC_MAXLEN_CFG(port->portno));
|
||||
+
|
||||
+ /* 1G/2G5: Signal Detect configuration */
|
||||
+ spx5_wr(DEV2G5_PCS1G_SD_CFG_SD_POL_SET(sd_pol) |
|
||||
+ DEV2G5_PCS1G_SD_CFG_SD_SEL_SET(sd_sel) |
|
||||
+ DEV2G5_PCS1G_SD_CFG_SD_ENA_SET(sd_ena),
|
||||
+ sparx5,
|
||||
+ DEV2G5_PCS1G_SD_CFG(port->portno));
|
||||
+
|
||||
if (conf->portmode == PHY_INTERFACE_MODE_QSGMII ||
|
||||
conf->portmode == PHY_INTERFACE_MODE_SGMII) {
|
||||
err = sparx5_serdes_set(sparx5, port, conf);
|
||||
@ -0,0 +1,82 @@
|
||||
From b479572cf00c11a1b57c2fc61e2d2e0f4fb84c4e Mon Sep 17 00:00:00 2001
|
||||
From: Daniel Machon <daniel.machon@microchip.com>
|
||||
Date: Fri, 20 Dec 2024 14:48:41 +0100
|
||||
Subject: [PATCH 69/82] net: sparx5: add function for RGMII port check
|
||||
|
||||
The lan969x device contains two RGMII port interfaces, sitting at port
|
||||
28 and 29. Add function: is_port_rgmii() to the match data ops, that
|
||||
checks if a given port is an RGMII port or not. For Sparx5, this
|
||||
function always returns false.
|
||||
|
||||
Reviewed-by: Steen Hegelund <Steen.Hegelund@microchip.com>
|
||||
Reviewed-by: Horatiu Vultur <horatiu.vultur@microchip.com>
|
||||
Tested-by: Robert Marko <robert.marko@sartura.hr>
|
||||
Signed-off-by: Daniel Machon <daniel.machon@microchip.com>
|
||||
Link: https://patch.msgid.link/20241220-sparx5-lan969x-switch-driver-4-v5-2-fa8ba5dff732@microchip.com
|
||||
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
|
||||
---
|
||||
drivers/net/ethernet/microchip/sparx5/lan969x/lan969x.c | 1 +
|
||||
drivers/net/ethernet/microchip/sparx5/lan969x/lan969x.h | 5 +++++
|
||||
drivers/net/ethernet/microchip/sparx5/sparx5_main.c | 1 +
|
||||
drivers/net/ethernet/microchip/sparx5/sparx5_main.h | 1 +
|
||||
drivers/net/ethernet/microchip/sparx5/sparx5_port.h | 5 +++++
|
||||
5 files changed, 13 insertions(+)
|
||||
|
||||
--- a/drivers/net/ethernet/microchip/sparx5/lan969x/lan969x.c
|
||||
+++ b/drivers/net/ethernet/microchip/sparx5/lan969x/lan969x.c
|
||||
@@ -329,6 +329,7 @@ static const struct sparx5_ops lan969x_o
|
||||
.is_port_5g = &lan969x_port_is_5g,
|
||||
.is_port_10g = &lan969x_port_is_10g,
|
||||
.is_port_25g = &lan969x_port_is_25g,
|
||||
+ .is_port_rgmii = &lan969x_port_is_rgmii,
|
||||
.get_port_dev_index = &lan969x_port_dev_mapping,
|
||||
.get_port_dev_bit = &lan969x_get_dev_mode_bit,
|
||||
.get_hsch_max_group_rate = &lan969x_get_hsch_max_group_rate,
|
||||
--- a/drivers/net/ethernet/microchip/sparx5/lan969x/lan969x.h
|
||||
+++ b/drivers/net/ethernet/microchip/sparx5/lan969x/lan969x.h
|
||||
@@ -59,6 +59,11 @@ static inline bool lan969x_port_is_25g(i
|
||||
return false;
|
||||
}
|
||||
|
||||
+static inline bool lan969x_port_is_rgmii(int portno)
|
||||
+{
|
||||
+ return portno == 28 || portno == 29;
|
||||
+}
|
||||
+
|
||||
/* lan969x_calendar.c */
|
||||
int lan969x_dsm_calendar_calc(struct sparx5 *sparx5, u32 taxi,
|
||||
struct sparx5_calendar_data *data);
|
||||
--- a/drivers/net/ethernet/microchip/sparx5/sparx5_main.c
|
||||
+++ b/drivers/net/ethernet/microchip/sparx5/sparx5_main.c
|
||||
@@ -1072,6 +1072,7 @@ static const struct sparx5_ops sparx5_op
|
||||
.is_port_5g = &sparx5_port_is_5g,
|
||||
.is_port_10g = &sparx5_port_is_10g,
|
||||
.is_port_25g = &sparx5_port_is_25g,
|
||||
+ .is_port_rgmii = &sparx5_port_is_rgmii,
|
||||
.get_port_dev_index = &sparx5_port_dev_mapping,
|
||||
.get_port_dev_bit = &sparx5_port_dev_mapping,
|
||||
.get_hsch_max_group_rate = &sparx5_get_hsch_max_group_rate,
|
||||
--- a/drivers/net/ethernet/microchip/sparx5/sparx5_main.h
|
||||
+++ b/drivers/net/ethernet/microchip/sparx5/sparx5_main.h
|
||||
@@ -313,6 +313,7 @@ struct sparx5_ops {
|
||||
bool (*is_port_5g)(int portno);
|
||||
bool (*is_port_10g)(int portno);
|
||||
bool (*is_port_25g)(int portno);
|
||||
+ bool (*is_port_rgmii)(int portno);
|
||||
u32 (*get_port_dev_index)(struct sparx5 *sparx5, int port);
|
||||
u32 (*get_port_dev_bit)(struct sparx5 *sparx5, int port);
|
||||
u32 (*get_hsch_max_group_rate)(int grp);
|
||||
--- a/drivers/net/ethernet/microchip/sparx5/sparx5_port.h
|
||||
+++ b/drivers/net/ethernet/microchip/sparx5/sparx5_port.h
|
||||
@@ -40,6 +40,11 @@ static inline bool sparx5_port_is_25g(in
|
||||
return portno >= 56 && portno <= 63;
|
||||
}
|
||||
|
||||
+static inline bool sparx5_port_is_rgmii(int portno)
|
||||
+{
|
||||
+ return false;
|
||||
+}
|
||||
+
|
||||
static inline u32 sparx5_to_high_dev(struct sparx5 *sparx5, int port)
|
||||
{
|
||||
const struct sparx5_ops *ops = sparx5->data->ops;
|
||||
@ -0,0 +1,115 @@
|
||||
From 1593303768bbf218cb4a7a8f9a9b1968e5e63aa7 Mon Sep 17 00:00:00 2001
|
||||
From: Daniel Machon <daniel.machon@microchip.com>
|
||||
Date: Fri, 20 Dec 2024 14:48:42 +0100
|
||||
Subject: [PATCH 70/82] net: sparx5: use is_port_rgmii() throughout
|
||||
|
||||
Now that we can check if a given port is an RGMII port, use it in the
|
||||
following cases:
|
||||
|
||||
- To set RGMII PHY modes for RGMII port devices.
|
||||
|
||||
- To avoid checking for a SerDes node in the devicetree, when the port
|
||||
is an RGMII port.
|
||||
|
||||
- To bail out of sparx5_port_init() when the common configuration is
|
||||
done.
|
||||
|
||||
Reviewed-by: Steen Hegelund <Steen.Hegelund@microchip.com>
|
||||
Reviewed-by: Horatiu Vultur <horatiu.vultur@microchip.com>
|
||||
Tested-by: Robert Marko <robert.marko@sartura.hr>
|
||||
Signed-off-by: Daniel Machon <daniel.machon@microchip.com>
|
||||
Link: https://patch.msgid.link/20241220-sparx5-lan969x-switch-driver-4-v5-3-fa8ba5dff732@microchip.com
|
||||
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
|
||||
---
|
||||
.../ethernet/microchip/sparx5/sparx5_main.c | 28 +++++++++++++------
|
||||
.../ethernet/microchip/sparx5/sparx5_port.c | 3 ++
|
||||
2 files changed, 23 insertions(+), 8 deletions(-)
|
||||
|
||||
--- a/drivers/net/ethernet/microchip/sparx5/sparx5_main.c
|
||||
+++ b/drivers/net/ethernet/microchip/sparx5/sparx5_main.c
|
||||
@@ -313,10 +313,13 @@ static int sparx5_create_port(struct spa
|
||||
struct initial_port_config *config)
|
||||
{
|
||||
struct sparx5_port *spx5_port;
|
||||
+ const struct sparx5_ops *ops;
|
||||
struct net_device *ndev;
|
||||
struct phylink *phylink;
|
||||
int err;
|
||||
|
||||
+ ops = sparx5->data->ops;
|
||||
+
|
||||
ndev = sparx5_create_netdev(sparx5, config->portno);
|
||||
if (IS_ERR(ndev)) {
|
||||
dev_err(sparx5->dev, "Could not create net device: %02u\n",
|
||||
@@ -357,6 +360,9 @@ static int sparx5_create_port(struct spa
|
||||
MAC_SYM_PAUSE | MAC_10 | MAC_100 | MAC_1000FD |
|
||||
MAC_2500FD | MAC_5000FD | MAC_10000FD | MAC_25000FD;
|
||||
|
||||
+ if (ops->is_port_rgmii(spx5_port->portno))
|
||||
+ phy_interface_set_rgmii(spx5_port->phylink_config.supported_interfaces);
|
||||
+
|
||||
__set_bit(PHY_INTERFACE_MODE_SGMII,
|
||||
spx5_port->phylink_config.supported_interfaces);
|
||||
__set_bit(PHY_INTERFACE_MODE_QSGMII,
|
||||
@@ -830,6 +836,7 @@ static int mchp_sparx5_probe(struct plat
|
||||
struct initial_port_config *configs, *config;
|
||||
struct device_node *np = pdev->dev.of_node;
|
||||
struct device_node *ports, *portnp;
|
||||
+ const struct sparx5_ops *ops;
|
||||
struct reset_control *reset;
|
||||
struct sparx5 *sparx5;
|
||||
int idx = 0, err = 0;
|
||||
@@ -851,6 +858,7 @@ static int mchp_sparx5_probe(struct plat
|
||||
return -EINVAL;
|
||||
|
||||
regs = sparx5->data->regs;
|
||||
+ ops = sparx5->data->ops;
|
||||
|
||||
/* Do switch core reset if available */
|
||||
reset = devm_reset_control_get_optional_shared(&pdev->dev, "switch");
|
||||
@@ -880,7 +888,7 @@ static int mchp_sparx5_probe(struct plat
|
||||
|
||||
for_each_available_child_of_node(ports, portnp) {
|
||||
struct sparx5_port_config *conf;
|
||||
- struct phy *serdes;
|
||||
+ struct phy *serdes = NULL;
|
||||
u32 portno;
|
||||
|
||||
err = of_property_read_u32(portnp, "reg", &portno);
|
||||
@@ -910,13 +918,17 @@ static int mchp_sparx5_probe(struct plat
|
||||
conf->sd_sgpio = ~0;
|
||||
else
|
||||
sparx5->sd_sgpio_remapping = true;
|
||||
- serdes = devm_of_phy_get(sparx5->dev, portnp, NULL);
|
||||
- if (IS_ERR(serdes)) {
|
||||
- err = dev_err_probe(sparx5->dev, PTR_ERR(serdes),
|
||||
- "port %u: missing serdes\n",
|
||||
- portno);
|
||||
- of_node_put(portnp);
|
||||
- goto cleanup_config;
|
||||
+ /* There is no SerDes node for RGMII ports. */
|
||||
+ if (!ops->is_port_rgmii(portno)) {
|
||||
+ serdes = devm_of_phy_get(sparx5->dev, portnp, NULL);
|
||||
+ if (IS_ERR(serdes)) {
|
||||
+ err = dev_err_probe(sparx5->dev,
|
||||
+ PTR_ERR(serdes),
|
||||
+ "port %u: missing serdes\n",
|
||||
+ portno);
|
||||
+ of_node_put(portnp);
|
||||
+ goto cleanup_config;
|
||||
+ }
|
||||
}
|
||||
config->portno = portno;
|
||||
config->node = portnp;
|
||||
--- a/drivers/net/ethernet/microchip/sparx5/sparx5_port.c
|
||||
+++ b/drivers/net/ethernet/microchip/sparx5/sparx5_port.c
|
||||
@@ -1090,6 +1090,9 @@ int sparx5_port_init(struct sparx5 *spar
|
||||
ANA_CL_FILTER_CTRL_FILTER_SMAC_MC_DIS,
|
||||
sparx5, ANA_CL_FILTER_CTRL(port->portno));
|
||||
|
||||
+ if (ops->is_port_rgmii(port->portno))
|
||||
+ return 0; /* RGMII device - nothing more to configure */
|
||||
+
|
||||
/* Configure MAC vlan awareness */
|
||||
err = sparx5_port_max_tags_set(sparx5, port);
|
||||
if (err)
|
||||
@ -0,0 +1,40 @@
|
||||
From 013f57f35a14c04449ff58684d9986bb663375d7 Mon Sep 17 00:00:00 2001
|
||||
From: Daniel Machon <daniel.machon@microchip.com>
|
||||
Date: Fri, 20 Dec 2024 14:48:43 +0100
|
||||
Subject: [PATCH 71/82] net: sparx5: skip low-speed configuration when port is
|
||||
RGMII
|
||||
|
||||
When doing a port config, we configure low-speed port devices, among
|
||||
other things. We have a check to ensure, that the device is indeed a
|
||||
low-speed device, an not a high-speed device. Add an additional check,
|
||||
to ensure that the device is not an RGMII device.
|
||||
|
||||
Reviewed-by: Steen Hegelund <Steen.Hegelund@microchip.com>
|
||||
Reviewed-by: Horatiu Vultur <horatiu.vultur@microchip.com>
|
||||
Tested-by: Robert Marko <robert.marko@sartura.hr>
|
||||
Signed-off-by: Daniel Machon <daniel.machon@microchip.com>
|
||||
Link: https://patch.msgid.link/20241220-sparx5-lan969x-switch-driver-4-v5-4-fa8ba5dff732@microchip.com
|
||||
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
|
||||
---
|
||||
drivers/net/ethernet/microchip/sparx5/sparx5_port.c | 3 ++-
|
||||
1 file changed, 2 insertions(+), 1 deletion(-)
|
||||
|
||||
--- a/drivers/net/ethernet/microchip/sparx5/sparx5_port.c
|
||||
+++ b/drivers/net/ethernet/microchip/sparx5/sparx5_port.c
|
||||
@@ -994,6 +994,7 @@ int sparx5_port_config(struct sparx5 *sp
|
||||
struct sparx5_port *port,
|
||||
struct sparx5_port_config *conf)
|
||||
{
|
||||
+ bool rgmii = phy_interface_mode_is_rgmii(conf->phy_mode);
|
||||
bool high_speed_dev = sparx5_is_baser(conf->portmode);
|
||||
const struct sparx5_ops *ops = sparx5->data->ops;
|
||||
int err, urgency, stop_wm;
|
||||
@@ -1003,7 +1004,7 @@ int sparx5_port_config(struct sparx5 *sp
|
||||
return err;
|
||||
|
||||
/* high speed device is already configured */
|
||||
- if (!high_speed_dev)
|
||||
+ if (!rgmii && !high_speed_dev)
|
||||
sparx5_port_config_low_set(sparx5, port, conf);
|
||||
|
||||
/* Configure flow control */
|
||||
@ -0,0 +1,40 @@
|
||||
From be45d246122e57af37216fa846439205ed2cf671 Mon Sep 17 00:00:00 2001
|
||||
From: Daniel Machon <daniel.machon@microchip.com>
|
||||
Date: Fri, 20 Dec 2024 14:48:44 +0100
|
||||
Subject: [PATCH 72/82] net: sparx5: only return PCS for modes that require it
|
||||
|
||||
The RGMII ports have no PCS to configure. Make sure we only return the
|
||||
PCS for port modes that require it.
|
||||
|
||||
Reviewed-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
|
||||
Tested-by: Robert Marko <robert.marko@sartura.hr>
|
||||
Signed-off-by: Daniel Machon <daniel.machon@microchip.com>
|
||||
Link: https://patch.msgid.link/20241220-sparx5-lan969x-switch-driver-4-v5-5-fa8ba5dff732@microchip.com
|
||||
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
|
||||
---
|
||||
.../net/ethernet/microchip/sparx5/sparx5_phylink.c | 14 +++++++++++++-
|
||||
1 file changed, 13 insertions(+), 1 deletion(-)
|
||||
|
||||
--- a/drivers/net/ethernet/microchip/sparx5/sparx5_phylink.c
|
||||
+++ b/drivers/net/ethernet/microchip/sparx5/sparx5_phylink.c
|
||||
@@ -32,7 +32,19 @@ sparx5_phylink_mac_select_pcs(struct phy
|
||||
{
|
||||
struct sparx5_port *port = netdev_priv(to_net_dev(config->dev));
|
||||
|
||||
- return &port->phylink_pcs;
|
||||
+ /* Return the PCS for all the modes that require it. */
|
||||
+ switch (interface) {
|
||||
+ case PHY_INTERFACE_MODE_SGMII:
|
||||
+ case PHY_INTERFACE_MODE_QSGMII:
|
||||
+ case PHY_INTERFACE_MODE_1000BASEX:
|
||||
+ case PHY_INTERFACE_MODE_2500BASEX:
|
||||
+ case PHY_INTERFACE_MODE_5GBASER:
|
||||
+ case PHY_INTERFACE_MODE_10GBASER:
|
||||
+ case PHY_INTERFACE_MODE_25GBASER:
|
||||
+ return &port->phylink_pcs;
|
||||
+ default:
|
||||
+ return NULL;
|
||||
+ }
|
||||
}
|
||||
|
||||
static void sparx5_phylink_mac_config(struct phylink_config *config,
|
||||
@ -0,0 +1,37 @@
|
||||
From 3695a85ef07bf3ac9a2ecc458a4c199b5ab755b1 Mon Sep 17 00:00:00 2001
|
||||
From: Daniel Machon <daniel.machon@microchip.com>
|
||||
Date: Fri, 20 Dec 2024 14:48:45 +0100
|
||||
Subject: [PATCH 73/82] net: sparx5: verify RGMII speeds
|
||||
|
||||
When doing a port config, we verify the port speed against the PHY mode
|
||||
and supported speeds of that PHY mode. Add checks for the four RGMII phy
|
||||
modes: RGMII, RGMII_ID, RGMII_TXID and RGMII_RXID.
|
||||
|
||||
Reviewed-by: Steen Hegelund <Steen.Hegelund@microchip.com>
|
||||
Reviewed-by: Horatiu Vultur <horatiu.vultur@microchip.com>
|
||||
Tested-by: Robert Marko <robert.marko@sartura.hr>
|
||||
Signed-off-by: Daniel Machon <daniel.machon@microchip.com>
|
||||
Link: https://patch.msgid.link/20241220-sparx5-lan969x-switch-driver-4-v5-6-fa8ba5dff732@microchip.com
|
||||
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
|
||||
---
|
||||
drivers/net/ethernet/microchip/sparx5/sparx5_port.c | 9 +++++++++
|
||||
1 file changed, 9 insertions(+)
|
||||
|
||||
--- a/drivers/net/ethernet/microchip/sparx5/sparx5_port.c
|
||||
+++ b/drivers/net/ethernet/microchip/sparx5/sparx5_port.c
|
||||
@@ -257,6 +257,15 @@ static int sparx5_port_verify_speed(stru
|
||||
conf->speed != SPEED_25000))
|
||||
return sparx5_port_error(port, conf, SPX5_PERR_SPEED);
|
||||
break;
|
||||
+ case PHY_INTERFACE_MODE_RGMII:
|
||||
+ case PHY_INTERFACE_MODE_RGMII_ID:
|
||||
+ case PHY_INTERFACE_MODE_RGMII_TXID:
|
||||
+ case PHY_INTERFACE_MODE_RGMII_RXID:
|
||||
+ if (conf->speed != SPEED_1000 &&
|
||||
+ conf->speed != SPEED_100 &&
|
||||
+ conf->speed != SPEED_10)
|
||||
+ return sparx5_port_error(port, conf, SPX5_PERR_SPEED);
|
||||
+ break;
|
||||
default:
|
||||
return sparx5_port_error(port, conf, SPX5_PERR_IFTYPE);
|
||||
}
|
||||
@ -0,0 +1,211 @@
|
||||
From 49fbe4bb20903f595b1c22b51aa6a9d3bf0ed5de Mon Sep 17 00:00:00 2001
|
||||
From: Daniel Machon <daniel.machon@microchip.com>
|
||||
Date: Fri, 20 Dec 2024 14:48:46 +0100
|
||||
Subject: [PATCH 74/82] net: lan969x: add RGMII registers
|
||||
|
||||
Configuration of RGMII is done by configuring the GPIO and clock
|
||||
settings in the HSIOWRAP target, and configuring the RGMII port devices
|
||||
in the DEVRGMII target. Both targets contain registers replicated for
|
||||
the number of RGMII port devices, which is two.
|
||||
|
||||
Add said targets and register macros required to configure RGMII.
|
||||
|
||||
Reviewed-by: Steen Hegelund <Steen.Hegelund@microchip.com>
|
||||
Reviewed-by: Horatiu Vultur <horatiu.vultur@microchip.com>
|
||||
Tested-by: Robert Marko <robert.marko@sartura.hr>
|
||||
Signed-off-by: Daniel Machon <daniel.machon@microchip.com>
|
||||
Link: https://patch.msgid.link/20241220-sparx5-lan969x-switch-driver-4-v5-7-fa8ba5dff732@microchip.com
|
||||
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
|
||||
---
|
||||
.../microchip/sparx5/lan969x/lan969x.c | 3 +
|
||||
.../microchip/sparx5/sparx5_main_regs.h | 145 ++++++++++++++++++
|
||||
2 files changed, 148 insertions(+)
|
||||
|
||||
--- a/drivers/net/ethernet/microchip/sparx5/lan969x/lan969x.c
|
||||
+++ b/drivers/net/ethernet/microchip/sparx5/lan969x/lan969x.c
|
||||
@@ -90,9 +90,12 @@ static const struct sparx5_main_io_resou
|
||||
{ TARGET_DEV2G5 + 27, 0x30d8000, 1 }, /* 0xe30d8000 */
|
||||
{ TARGET_DEV10G + 9, 0x30dc000, 1 }, /* 0xe30dc000 */
|
||||
{ TARGET_PCS10G_BR + 9, 0x30e0000, 1 }, /* 0xe30e0000 */
|
||||
+ { TARGET_DEVRGMII, 0x30e4000, 1 }, /* 0xe30e4000 */
|
||||
+ { TARGET_DEVRGMII + 1, 0x30e8000, 1 }, /* 0xe30e8000 */
|
||||
{ TARGET_DSM, 0x30ec000, 1 }, /* 0xe30ec000 */
|
||||
{ TARGET_PORT_CONF, 0x30f0000, 1 }, /* 0xe30f0000 */
|
||||
{ TARGET_ASM, 0x3200000, 1 }, /* 0xe3200000 */
|
||||
+ { TARGET_HSIO_WRAP, 0x3408000, 1 }, /* 0xe3408000 */
|
||||
};
|
||||
|
||||
static struct sparx5_sdlb_group lan969x_sdlb_groups[LAN969X_SDLB_GRP_CNT] = {
|
||||
--- a/drivers/net/ethernet/microchip/sparx5/sparx5_main_regs.h
|
||||
+++ b/drivers/net/ethernet/microchip/sparx5/sparx5_main_regs.h
|
||||
@@ -37,6 +37,7 @@ enum sparx5_target {
|
||||
TARGET_FDMA = 117,
|
||||
TARGET_GCB = 118,
|
||||
TARGET_HSCH = 119,
|
||||
+ TARGET_HSIO_WRAP = 120,
|
||||
TARGET_LRN = 122,
|
||||
TARGET_PCEP = 129,
|
||||
TARGET_PCS10G_BR = 132,
|
||||
@@ -54,6 +55,7 @@ enum sparx5_target {
|
||||
TARGET_VCAP_SUPER = 326,
|
||||
TARGET_VOP = 327,
|
||||
TARGET_XQS = 331,
|
||||
+ TARGET_DEVRGMII = 392,
|
||||
NUM_TARGETS = 517
|
||||
};
|
||||
|
||||
@@ -5367,6 +5369,69 @@ extern const struct sparx5_regs *regs;
|
||||
#define HSCH_TAS_STATEMACHINE_CFG_REVISIT_DLY_GET(x)\
|
||||
FIELD_GET(HSCH_TAS_STATEMACHINE_CFG_REVISIT_DLY, x)
|
||||
|
||||
+/* LAN969X ONLY */
|
||||
+/* HSIOWRAP:XMII_CFG:XMII_CFG */
|
||||
+#define HSIO_WRAP_XMII_CFG(g) \
|
||||
+ __REG(TARGET_HSIO_WRAP, 0, 1, 116, g, 2, 20, 0, 0, 1, 4)
|
||||
+
|
||||
+#define HSIO_WRAP_XMII_CFG_GPIO_XMII_CFG GENMASK(2, 1)
|
||||
+#define HSIO_WRAP_XMII_CFG_GPIO_XMII_CFG_SET(x)\
|
||||
+ FIELD_PREP(HSIO_WRAP_XMII_CFG_GPIO_XMII_CFG, x)
|
||||
+#define HSIO_WRAP_XMII_CFG_GPIO_XMII_CFG_GET(x)\
|
||||
+ FIELD_GET(HSIO_WRAP_XMII_CFG_GPIO_XMII_CFG, x)
|
||||
+
|
||||
+/* LAN969X ONLY */
|
||||
+/* HSIOWRAP:XMII_CFG:RGMII_CFG */
|
||||
+#define HSIO_WRAP_RGMII_CFG(g) \
|
||||
+ __REG(TARGET_HSIO_WRAP, 0, 1, 116, g, 2, 20, 4, 0, 1, 4)
|
||||
+
|
||||
+#define HSIO_WRAP_RGMII_CFG_TX_CLK_CFG GENMASK(4, 2)
|
||||
+#define HSIO_WRAP_RGMII_CFG_TX_CLK_CFG_SET(x)\
|
||||
+ FIELD_PREP(HSIO_WRAP_RGMII_CFG_TX_CLK_CFG, x)
|
||||
+#define HSIO_WRAP_RGMII_CFG_TX_CLK_CFG_GET(x)\
|
||||
+ FIELD_GET(HSIO_WRAP_RGMII_CFG_TX_CLK_CFG, x)
|
||||
+
|
||||
+#define HSIO_WRAP_RGMII_CFG_RGMII_TX_RST BIT(1)
|
||||
+#define HSIO_WRAP_RGMII_CFG_RGMII_TX_RST_SET(x)\
|
||||
+ FIELD_PREP(HSIO_WRAP_RGMII_CFG_RGMII_TX_RST, x)
|
||||
+#define HSIO_WRAP_RGMII_CFG_RGMII_TX_RST_GET(x)\
|
||||
+ FIELD_GET(HSIO_WRAP_RGMII_CFG_RGMII_TX_RST, x)
|
||||
+
|
||||
+#define HSIO_WRAP_RGMII_CFG_RGMII_RX_RST BIT(0)
|
||||
+#define HSIO_WRAP_RGMII_CFG_RGMII_RX_RST_SET(x)\
|
||||
+ FIELD_PREP(HSIO_WRAP_RGMII_CFG_RGMII_RX_RST, x)
|
||||
+#define HSIO_WRAP_RGMII_CFG_RGMII_RX_RST_GET(x)\
|
||||
+ FIELD_GET(HSIO_WRAP_RGMII_CFG_RGMII_RX_RST, x)
|
||||
+
|
||||
+/* LAN969X ONLY */
|
||||
+/* HSIOWRAP:XMII_CFG:DLL_CFG */
|
||||
+#define HSIO_WRAP_DLL_CFG(g, r) \
|
||||
+ __REG(TARGET_HSIO_WRAP, 0, 1, 116, g, 2, 20, 12, r, 2, 4)
|
||||
+
|
||||
+#define HSIO_WRAP_DLL_CFG_DLL_ENA BIT(19)
|
||||
+#define HSIO_WRAP_DLL_CFG_DLL_ENA_SET(x)\
|
||||
+ FIELD_PREP(HSIO_WRAP_DLL_CFG_DLL_ENA, x)
|
||||
+#define HSIO_WRAP_DLL_CFG_DLL_ENA_GET(x)\
|
||||
+ FIELD_GET(HSIO_WRAP_DLL_CFG_DLL_ENA, x)
|
||||
+
|
||||
+#define HSIO_WRAP_DLL_CFG_DLL_CLK_ENA BIT(18)
|
||||
+#define HSIO_WRAP_DLL_CFG_DLL_CLK_ENA_SET(x)\
|
||||
+ FIELD_PREP(HSIO_WRAP_DLL_CFG_DLL_CLK_ENA, x)
|
||||
+#define HSIO_WRAP_DLL_CFG_DLL_CLK_ENA_GET(x)\
|
||||
+ FIELD_GET(HSIO_WRAP_DLL_CFG_DLL_CLK_ENA, x)
|
||||
+
|
||||
+#define HSIO_WRAP_DLL_CFG_DLL_CLK_SEL GENMASK(17, 15)
|
||||
+#define HSIO_WRAP_DLL_CFG_DLL_CLK_SEL_SET(x)\
|
||||
+ FIELD_PREP(HSIO_WRAP_DLL_CFG_DLL_CLK_SEL, x)
|
||||
+#define HSIO_WRAP_DLL_CFG_DLL_CLK_SEL_GET(x)\
|
||||
+ FIELD_GET(HSIO_WRAP_DLL_CFG_DLL_CLK_SEL, x)
|
||||
+
|
||||
+#define HSIO_WRAP_DLL_CFG_DLL_RST BIT(0)
|
||||
+#define HSIO_WRAP_DLL_CFG_DLL_RST_SET(x)\
|
||||
+ FIELD_PREP(HSIO_WRAP_DLL_CFG_DLL_RST, x)
|
||||
+#define HSIO_WRAP_DLL_CFG_DLL_RST_GET(x)\
|
||||
+ FIELD_GET(HSIO_WRAP_DLL_CFG_DLL_RST, x)
|
||||
+
|
||||
/* LRN:COMMON:COMMON_ACCESS_CTRL */
|
||||
#define LRN_COMMON_ACCESS_CTRL \
|
||||
__REG(TARGET_LRN, 0, 1, 0, 0, 1, 72, 0, 0, 1, 4)
|
||||
@@ -8110,4 +8175,84 @@ extern const struct sparx5_regs *regs;
|
||||
#define XQS_CNT(g) \
|
||||
__REG(TARGET_XQS, 0, 1, 0, g, 1024, 4, 0, 0, 1, 4)
|
||||
|
||||
+/* LAN969X ONLY */
|
||||
+/* DEV1G:DEV_CFG_STATUS:DEV_RST_CTRL */
|
||||
+#define DEVRGMII_DEV_RST_CTRL(t) \
|
||||
+ __REG(TARGET_DEVRGMII, t, 2, 0, 0, 1, 36, 0, 0, 1, 4)
|
||||
+
|
||||
+#define DEVRGMII_DEV_RST_CTRL_SPEED_SEL GENMASK(22, 20)
|
||||
+#define DEVRGMII_DEV_RST_CTRL_SPEED_SEL_SET(x)\
|
||||
+ FIELD_PREP(DEVRGMII_DEV_RST_CTRL_SPEED_SEL, x)
|
||||
+#define DEVRGMII_DEV_RST_CTRL_SPEED_SEL_GET(x)\
|
||||
+ FIELD_GET(DEVRGMII_DEV_RST_CTRL_SPEED_SEL, x)
|
||||
+
|
||||
+/* LAN969X ONLY */
|
||||
+/* DEV1G:MAC_CFG_STATUS:MAC_ENA_CFG */
|
||||
+#define DEVRGMII_MAC_ENA_CFG(t) \
|
||||
+ __REG(TARGET_DEVRGMII, t, 2, 36, 0, 1, 36, 0, 0, 1, 4)
|
||||
+
|
||||
+#define DEVRGMII_MAC_ENA_CFG_RX_ENA BIT(4)
|
||||
+#define DEVRGMII_MAC_ENA_CFG_RX_ENA_SET(x)\
|
||||
+ FIELD_PREP(DEVRGMII_MAC_ENA_CFG_RX_ENA, x)
|
||||
+#define DEVRGMII_MAC_ENA_CFG_RX_ENA_GET(x)\
|
||||
+ FIELD_GET(DEVRGMII_MAC_ENA_CFG_RX_ENA, x)
|
||||
+
|
||||
+#define DEVRGMII_MAC_ENA_CFG_TX_ENA BIT(0)
|
||||
+#define DEVRGMII_MAC_ENA_CFG_TX_ENA_SET(x)\
|
||||
+ FIELD_PREP(DEVRGMII_MAC_ENA_CFG_TX_ENA, x)
|
||||
+#define DEVRGMII_MAC_ENA_CFG_TX_ENA_GET(x)\
|
||||
+ FIELD_GET(DEVRGMII_MAC_ENA_CFG_TX_ENA, x)
|
||||
+
|
||||
+/* LAN969X ONLY */
|
||||
+/* DEV1G:MAC_CFG_STATUS:MAC_TAGS_CFG */
|
||||
+#define DEVRGMII_MAC_TAGS_CFG(t) \
|
||||
+ __REG(TARGET_DEVRGMII, t, 2, 36, 0, 1, 36, 12, 0, 1, 4)
|
||||
+
|
||||
+#define DEVRGMII_MAC_TAGS_CFG_TAG_ID GENMASK(31, 16)
|
||||
+#define DEVRGMII_MAC_TAGS_CFG_TAG_ID_SET(x)\
|
||||
+ FIELD_PREP(DEVRGMII_MAC_TAGS_CFG_TAG_ID, x)
|
||||
+#define DEVRGMII_MAC_TAGS_CFG_TAG_ID_GET(x)\
|
||||
+ FIELD_GET(DEVRGMII_MAC_TAGS_CFG_TAG_ID, x)
|
||||
+
|
||||
+#define DEVRGMII_MAC_TAGS_CFG_VLAN_LEN_AWR_ENA BIT(3)
|
||||
+#define DEVRGMII_MAC_TAGS_CFG_VLAN_LEN_AWR_ENA_SET(x)\
|
||||
+ FIELD_PREP(DEVRGMII_MAC_TAGS_CFG_VLAN_LEN_AWR_ENA, x)
|
||||
+#define DEVRGMII_MAC_TAGS_CFG_VLAN_LEN_AWR_ENA_GET(x)\
|
||||
+ FIELD_GET(DEVRGMII_MAC_TAGS_CFG_VLAN_LEN_AWR_ENA, x)
|
||||
+
|
||||
+#define DEVRGMII_MAC_TAGS_CFG_PB_ENA GENMASK(2, 1)
|
||||
+#define DEVRGMII_MAC_TAGS_CFG_PB_ENA_SET(x)\
|
||||
+ FIELD_PREP(DEVRGMII_MAC_TAGS_CFG_PB_ENA, x)
|
||||
+#define DEVRGMII_MAC_TAGS_CFG_PB_ENA_GET(x)\
|
||||
+ FIELD_GET(DEVRGMII_MAC_TAGS_CFG_PB_ENA, x)
|
||||
+
|
||||
+#define DEVRGMII_MAC_TAGS_CFG_VLAN_AWR_ENA BIT(0)
|
||||
+#define DEVRGMII_MAC_TAGS_CFG_VLAN_AWR_ENA_SET(x)\
|
||||
+ FIELD_PREP(DEVRGMII_MAC_TAGS_CFG_VLAN_AWR_ENA, x)
|
||||
+#define DEVRGMII_MAC_TAGS_CFG_VLAN_AWR_ENA_GET(x)\
|
||||
+ FIELD_GET(DEVRGMII_MAC_TAGS_CFG_VLAN_AWR_ENA, x)
|
||||
+
|
||||
+/* LAN969X ONLY */
|
||||
+/* DEV1G:MAC_CFG_STATUS:MAC_IFG_CFG */
|
||||
+#define DEVRGMII_MAC_IFG_CFG(t) \
|
||||
+ __REG(TARGET_DEVRGMII, t, 2, 36, 0, 1, 36, 24, 0, 1, 4)
|
||||
+
|
||||
+#define DEVRGMII_MAC_IFG_CFG_TX_IFG GENMASK(12, 8)
|
||||
+#define DEVRGMII_MAC_IFG_CFG_TX_IFG_SET(x)\
|
||||
+ FIELD_PREP(DEVRGMII_MAC_IFG_CFG_TX_IFG, x)
|
||||
+#define DEVRGMII_MAC_IFG_CFG_TX_IFG_GET(x)\
|
||||
+ FIELD_GET(DEVRGMII_MAC_IFG_CFG_TX_IFG, x)
|
||||
+
|
||||
+#define DEVRGMII_MAC_IFG_CFG_RX_IFG2 GENMASK(7, 4)
|
||||
+#define DEVRGMII_MAC_IFG_CFG_RX_IFG2_SET(x)\
|
||||
+ FIELD_PREP(DEVRGMII_MAC_IFG_CFG_RX_IFG2, x)
|
||||
+#define DEVRGMII_MAC_IFG_CFG_RX_IFG2_GET(x)\
|
||||
+ FIELD_GET(DEVRGMII_MAC_IFG_CFG_RX_IFG2, x)
|
||||
+
|
||||
+#define DEVRGMII_MAC_IFG_CFG_RX_IFG1 GENMASK(3, 0)
|
||||
+#define DEVRGMII_MAC_IFG_CFG_RX_IFG1_SET(x)\
|
||||
+ FIELD_PREP(DEVRGMII_MAC_IFG_CFG_RX_IFG1, x)
|
||||
+#define DEVRGMII_MAC_IFG_CFG_RX_IFG1_GET(x)\
|
||||
+ FIELD_GET(DEVRGMII_MAC_IFG_CFG_RX_IFG1, x)
|
||||
+
|
||||
#endif /* _SPARX5_MAIN_REGS_H_ */
|
||||
@ -0,0 +1,320 @@
|
||||
From d5444792be67ed47aed76685e62b0f0c29c5e22c Mon Sep 17 00:00:00 2001
|
||||
From: Daniel Machon <daniel.machon@microchip.com>
|
||||
Date: Fri, 20 Dec 2024 14:48:47 +0100
|
||||
Subject: [PATCH 75/82] net: lan969x: add RGMII implementation
|
||||
|
||||
The lan969x switch device includes two RGMII port interfaces (port 28
|
||||
and 29) supporting data speeds of 1 Gbps, 100 Mbps and 10 Mbps. MAC
|
||||
level delays are configurable through the HSIO_WRAP target, by choosing
|
||||
a phase shift selector, corresponding to a certain time delay in nano
|
||||
seconds.
|
||||
|
||||
Add new file: lan969x_rgmii.c that contains the implementation for
|
||||
configuring the RGMII port devices. MAC level delays are configured
|
||||
using the "{rx,tx}-internal-delay-ps" properties. These properties must
|
||||
be specified independently of the phy-mode. If missing, or set to zero,
|
||||
the MAC will not apply any delay.
|
||||
|
||||
Reviewed-by: Steen Hegelund <Steen.Hegelund@microchip.com>
|
||||
Reviewed-by: Horatiu Vultur <horatiu.vultur@microchip.com>
|
||||
Tested-by: Robert Marko <robert.marko@sartura.hr>
|
||||
Signed-off-by: Daniel Machon <daniel.machon@microchip.com>
|
||||
Link: https://patch.msgid.link/20241220-sparx5-lan969x-switch-driver-4-v5-8-fa8ba5dff732@microchip.com
|
||||
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
|
||||
---
|
||||
.../net/ethernet/microchip/sparx5/Makefile | 3 +-
|
||||
.../microchip/sparx5/lan969x/lan969x.c | 1 +
|
||||
.../microchip/sparx5/lan969x/lan969x.h | 5 +
|
||||
.../microchip/sparx5/lan969x/lan969x_rgmii.c | 224 ++++++++++++++++++
|
||||
.../ethernet/microchip/sparx5/sparx5_main.h | 2 +
|
||||
.../ethernet/microchip/sparx5/sparx5_port.c | 6 +
|
||||
6 files changed, 240 insertions(+), 1 deletion(-)
|
||||
create mode 100644 drivers/net/ethernet/microchip/sparx5/lan969x/lan969x_rgmii.c
|
||||
|
||||
--- a/drivers/net/ethernet/microchip/sparx5/Makefile
|
||||
+++ b/drivers/net/ethernet/microchip/sparx5/Makefile
|
||||
@@ -20,7 +20,8 @@ sparx5-switch-$(CONFIG_LAN969X_SWITCH) +
|
||||
lan969x/lan969x.o \
|
||||
lan969x/lan969x_calendar.o \
|
||||
lan969x/lan969x_vcap_ag_api.o \
|
||||
- lan969x/lan969x_vcap_impl.o
|
||||
+ lan969x/lan969x_vcap_impl.o \
|
||||
+ lan969x/lan969x_rgmii.o
|
||||
|
||||
# Provide include files
|
||||
ccflags-y += -I$(srctree)/drivers/net/ethernet/microchip/vcap
|
||||
--- a/drivers/net/ethernet/microchip/sparx5/lan969x/lan969x.c
|
||||
+++ b/drivers/net/ethernet/microchip/sparx5/lan969x/lan969x.c
|
||||
@@ -340,6 +340,7 @@ static const struct sparx5_ops lan969x_o
|
||||
.set_port_mux = &lan969x_port_mux_set,
|
||||
.ptp_irq_handler = &lan969x_ptp_irq_handler,
|
||||
.dsm_calendar_calc = &lan969x_dsm_calendar_calc,
|
||||
+ .port_config_rgmii = &lan969x_port_config_rgmii,
|
||||
};
|
||||
|
||||
const struct sparx5_match_data lan969x_desc = {
|
||||
--- a/drivers/net/ethernet/microchip/sparx5/lan969x/lan969x.h
|
||||
+++ b/drivers/net/ethernet/microchip/sparx5/lan969x/lan969x.h
|
||||
@@ -67,4 +67,9 @@ static inline bool lan969x_port_is_rgmii
|
||||
/* lan969x_calendar.c */
|
||||
int lan969x_dsm_calendar_calc(struct sparx5 *sparx5, u32 taxi,
|
||||
struct sparx5_calendar_data *data);
|
||||
+
|
||||
+/* lan969x_rgmii.c */
|
||||
+int lan969x_port_config_rgmii(struct sparx5_port *port,
|
||||
+ struct sparx5_port_config *conf);
|
||||
+
|
||||
#endif
|
||||
--- /dev/null
|
||||
+++ b/drivers/net/ethernet/microchip/sparx5/lan969x/lan969x_rgmii.c
|
||||
@@ -0,0 +1,224 @@
|
||||
+// SPDX-License-Identifier: GPL-2.0+
|
||||
+/* Microchip lan969x Switch driver
|
||||
+ *
|
||||
+ * Copyright (c) 2024 Microchip Technology Inc. and its subsidiaries.
|
||||
+ */
|
||||
+
|
||||
+#include "lan969x.h"
|
||||
+
|
||||
+/* Tx clock selectors */
|
||||
+#define LAN969X_RGMII_TX_CLK_SEL_125MHZ 1 /* 1000Mbps */
|
||||
+#define LAN969X_RGMII_TX_CLK_SEL_25MHZ 2 /* 100Mbps */
|
||||
+#define LAN969X_RGMII_TX_CLK_SEL_2M5MHZ 3 /* 10Mbps */
|
||||
+
|
||||
+/* Port speed selectors */
|
||||
+#define LAN969X_RGMII_SPEED_SEL_10 0 /* Select 10Mbps speed */
|
||||
+#define LAN969X_RGMII_SPEED_SEL_100 1 /* Select 100Mbps speed */
|
||||
+#define LAN969X_RGMII_SPEED_SEL_1000 2 /* Select 1000Mbps speed */
|
||||
+
|
||||
+/* Clock delay selectors */
|
||||
+#define LAN969X_RGMII_CLK_DELAY_SEL_1_0_NS 2 /* Phase shift 45deg */
|
||||
+#define LAN969X_RGMII_CLK_DELAY_SEL_1_7_NS 3 /* Phase shift 77deg */
|
||||
+#define LAN969X_RGMII_CLK_DELAY_SEL_2_0_NS 4 /* Phase shift 90deg */
|
||||
+#define LAN969X_RGMII_CLK_DELAY_SEL_2_5_NS 5 /* Phase shift 112deg */
|
||||
+#define LAN969X_RGMII_CLK_DELAY_SEL_3_0_NS 6 /* Phase shift 135deg */
|
||||
+#define LAN969X_RGMII_CLK_DELAY_SEL_3_3_NS 7 /* Phase shift 147deg */
|
||||
+
|
||||
+#define LAN969X_RGMII_PORT_START_IDX 28 /* Index of the first RGMII port */
|
||||
+#define LAN969X_RGMII_IFG_TX 4 /* TX Inter Frame Gap value */
|
||||
+#define LAN969X_RGMII_IFG_RX1 5 /* RX1 Inter Frame Gap value */
|
||||
+#define LAN969X_RGMII_IFG_RX2 1 /* RX2 Inter Frame Gap value */
|
||||
+
|
||||
+#define RGMII_PORT_IDX(port) ((port)->portno - LAN969X_RGMII_PORT_START_IDX)
|
||||
+
|
||||
+/* Get the tx clock selector based on the port speed. */
|
||||
+static int lan969x_rgmii_get_clk_sel(int speed)
|
||||
+{
|
||||
+ return (speed == SPEED_10 ? LAN969X_RGMII_TX_CLK_SEL_2M5MHZ :
|
||||
+ speed == SPEED_100 ? LAN969X_RGMII_TX_CLK_SEL_25MHZ :
|
||||
+ LAN969X_RGMII_TX_CLK_SEL_125MHZ);
|
||||
+}
|
||||
+
|
||||
+/* Get the port speed selector based on the port speed. */
|
||||
+static int lan969x_rgmii_get_speed_sel(int speed)
|
||||
+{
|
||||
+ return (speed == SPEED_10 ? LAN969X_RGMII_SPEED_SEL_10 :
|
||||
+ speed == SPEED_100 ? LAN969X_RGMII_SPEED_SEL_100 :
|
||||
+ LAN969X_RGMII_SPEED_SEL_1000);
|
||||
+}
|
||||
+
|
||||
+/* Get the clock delay selector based on the clock delay in picoseconds. */
|
||||
+static int lan969x_rgmii_get_clk_delay_sel(struct sparx5_port *port,
|
||||
+ u32 delay_ps, u32 *clk_delay_sel)
|
||||
+{
|
||||
+ switch (delay_ps) {
|
||||
+ case 0:
|
||||
+ /* Hardware default selector. */
|
||||
+ *clk_delay_sel = LAN969X_RGMII_CLK_DELAY_SEL_2_5_NS;
|
||||
+ break;
|
||||
+ case 1000:
|
||||
+ *clk_delay_sel = LAN969X_RGMII_CLK_DELAY_SEL_1_0_NS;
|
||||
+ break;
|
||||
+ case 1700:
|
||||
+ *clk_delay_sel = LAN969X_RGMII_CLK_DELAY_SEL_1_7_NS;
|
||||
+ break;
|
||||
+ case 2000:
|
||||
+ *clk_delay_sel = LAN969X_RGMII_CLK_DELAY_SEL_2_0_NS;
|
||||
+ break;
|
||||
+ case 2500:
|
||||
+ *clk_delay_sel = LAN969X_RGMII_CLK_DELAY_SEL_2_5_NS;
|
||||
+ break;
|
||||
+ case 3000:
|
||||
+ *clk_delay_sel = LAN969X_RGMII_CLK_DELAY_SEL_3_0_NS;
|
||||
+ break;
|
||||
+ case 3300:
|
||||
+ *clk_delay_sel = LAN969X_RGMII_CLK_DELAY_SEL_3_3_NS;
|
||||
+ break;
|
||||
+ default:
|
||||
+ dev_err(port->sparx5->dev, "Invalid RGMII delay: %u", delay_ps);
|
||||
+ return -EINVAL;
|
||||
+ }
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+/* Configure the RGMII tx clock frequency. */
|
||||
+static void lan969x_rgmii_tx_clk_config(struct sparx5_port *port,
|
||||
+ struct sparx5_port_config *conf)
|
||||
+{
|
||||
+ u32 clk_sel = lan969x_rgmii_get_clk_sel(conf->speed);
|
||||
+ u32 idx = RGMII_PORT_IDX(port);
|
||||
+
|
||||
+ /* Take the RGMII clock domain out of reset and set tx clock
|
||||
+ * frequency.
|
||||
+ */
|
||||
+ spx5_rmw(HSIO_WRAP_RGMII_CFG_TX_CLK_CFG_SET(clk_sel) |
|
||||
+ HSIO_WRAP_RGMII_CFG_RGMII_TX_RST_SET(0) |
|
||||
+ HSIO_WRAP_RGMII_CFG_RGMII_RX_RST_SET(0),
|
||||
+ HSIO_WRAP_RGMII_CFG_TX_CLK_CFG |
|
||||
+ HSIO_WRAP_RGMII_CFG_RGMII_TX_RST |
|
||||
+ HSIO_WRAP_RGMII_CFG_RGMII_RX_RST,
|
||||
+ port->sparx5, HSIO_WRAP_RGMII_CFG(idx));
|
||||
+}
|
||||
+
|
||||
+/* Configure the RGMII port device. */
|
||||
+static void lan969x_rgmii_port_device_config(struct sparx5_port *port,
|
||||
+ struct sparx5_port_config *conf)
|
||||
+{
|
||||
+ u32 dtag, dotag, etype, speed_sel, idx = RGMII_PORT_IDX(port);
|
||||
+
|
||||
+ speed_sel = lan969x_rgmii_get_speed_sel(conf->speed);
|
||||
+
|
||||
+ etype = (port->vlan_type == SPX5_VLAN_PORT_TYPE_S_CUSTOM ?
|
||||
+ port->custom_etype :
|
||||
+ port->vlan_type == SPX5_VLAN_PORT_TYPE_C ?
|
||||
+ ETH_P_8021Q : ETH_P_8021AD);
|
||||
+
|
||||
+ dtag = port->max_vlan_tags == SPX5_PORT_MAX_TAGS_TWO;
|
||||
+ dotag = port->max_vlan_tags != SPX5_PORT_MAX_TAGS_NONE;
|
||||
+
|
||||
+ /* Enable the MAC. */
|
||||
+ spx5_wr(DEVRGMII_MAC_ENA_CFG_RX_ENA_SET(1) |
|
||||
+ DEVRGMII_MAC_ENA_CFG_TX_ENA_SET(1),
|
||||
+ port->sparx5, DEVRGMII_MAC_ENA_CFG(idx));
|
||||
+
|
||||
+ /* Configure the Inter Frame Gap. */
|
||||
+ spx5_wr(DEVRGMII_MAC_IFG_CFG_TX_IFG_SET(LAN969X_RGMII_IFG_TX) |
|
||||
+ DEVRGMII_MAC_IFG_CFG_RX_IFG1_SET(LAN969X_RGMII_IFG_RX1) |
|
||||
+ DEVRGMII_MAC_IFG_CFG_RX_IFG2_SET(LAN969X_RGMII_IFG_RX2),
|
||||
+ port->sparx5, DEVRGMII_MAC_IFG_CFG(idx));
|
||||
+
|
||||
+ /* Configure port data rate. */
|
||||
+ spx5_wr(DEVRGMII_DEV_RST_CTRL_SPEED_SEL_SET(speed_sel),
|
||||
+ port->sparx5, DEVRGMII_DEV_RST_CTRL(idx));
|
||||
+
|
||||
+ /* Configure VLAN awareness. */
|
||||
+ spx5_wr(DEVRGMII_MAC_TAGS_CFG_TAG_ID_SET(etype) |
|
||||
+ DEVRGMII_MAC_TAGS_CFG_PB_ENA_SET(dtag) |
|
||||
+ DEVRGMII_MAC_TAGS_CFG_VLAN_AWR_ENA_SET(dotag) |
|
||||
+ DEVRGMII_MAC_TAGS_CFG_VLAN_LEN_AWR_ENA_SET(dotag),
|
||||
+ port->sparx5,
|
||||
+ DEVRGMII_MAC_TAGS_CFG(idx));
|
||||
+}
|
||||
+
|
||||
+/* Configure the RGMII delay lines in the MAC.
|
||||
+ *
|
||||
+ * We use the rx-internal-delay-ps" and "tx-internal-delay-ps" properties to
|
||||
+ * configure the rx and tx delays for the MAC. If these properties are missing
|
||||
+ * or set to zero, the MAC will not apply any delay.
|
||||
+ *
|
||||
+ * The PHY side delays are determined by the PHY mode
|
||||
+ * (e.g. PHY_INTERFACE_MODE_RGMII_{ID, RXID, TXID}), and ignored by the MAC side
|
||||
+ * entirely.
|
||||
+ */
|
||||
+static int lan969x_rgmii_delay_config(struct sparx5_port *port,
|
||||
+ struct sparx5_port_config *conf)
|
||||
+{
|
||||
+ u32 tx_clk_sel, rx_clk_sel, tx_delay_ps = 0, rx_delay_ps = 0;
|
||||
+ u32 idx = RGMII_PORT_IDX(port);
|
||||
+ int err;
|
||||
+
|
||||
+ of_property_read_u32(port->of_node, "rx-internal-delay-ps",
|
||||
+ &rx_delay_ps);
|
||||
+
|
||||
+ of_property_read_u32(port->of_node, "tx-internal-delay-ps",
|
||||
+ &tx_delay_ps);
|
||||
+
|
||||
+ err = lan969x_rgmii_get_clk_delay_sel(port, rx_delay_ps, &rx_clk_sel);
|
||||
+ if (err)
|
||||
+ return err;
|
||||
+
|
||||
+ err = lan969x_rgmii_get_clk_delay_sel(port, tx_delay_ps, &tx_clk_sel);
|
||||
+ if (err)
|
||||
+ return err;
|
||||
+
|
||||
+ /* Configure rx delay. */
|
||||
+ spx5_rmw(HSIO_WRAP_DLL_CFG_DLL_RST_SET(0) |
|
||||
+ HSIO_WRAP_DLL_CFG_DLL_ENA_SET(1) |
|
||||
+ HSIO_WRAP_DLL_CFG_DLL_CLK_ENA_SET(!!rx_delay_ps) |
|
||||
+ HSIO_WRAP_DLL_CFG_DLL_CLK_SEL_SET(rx_clk_sel),
|
||||
+ HSIO_WRAP_DLL_CFG_DLL_RST |
|
||||
+ HSIO_WRAP_DLL_CFG_DLL_ENA |
|
||||
+ HSIO_WRAP_DLL_CFG_DLL_CLK_ENA |
|
||||
+ HSIO_WRAP_DLL_CFG_DLL_CLK_SEL,
|
||||
+ port->sparx5, HSIO_WRAP_DLL_CFG(idx, 0));
|
||||
+
|
||||
+ /* Configure tx delay. */
|
||||
+ spx5_rmw(HSIO_WRAP_DLL_CFG_DLL_RST_SET(0) |
|
||||
+ HSIO_WRAP_DLL_CFG_DLL_ENA_SET(1) |
|
||||
+ HSIO_WRAP_DLL_CFG_DLL_CLK_ENA_SET(!!tx_delay_ps) |
|
||||
+ HSIO_WRAP_DLL_CFG_DLL_CLK_SEL_SET(tx_clk_sel),
|
||||
+ HSIO_WRAP_DLL_CFG_DLL_RST |
|
||||
+ HSIO_WRAP_DLL_CFG_DLL_ENA |
|
||||
+ HSIO_WRAP_DLL_CFG_DLL_CLK_ENA |
|
||||
+ HSIO_WRAP_DLL_CFG_DLL_CLK_SEL,
|
||||
+ port->sparx5, HSIO_WRAP_DLL_CFG(idx, 1));
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+/* Configure GPIO's to be used as RGMII interface. */
|
||||
+static void lan969x_rgmii_gpio_config(struct sparx5_port *port)
|
||||
+{
|
||||
+ u32 idx = RGMII_PORT_IDX(port);
|
||||
+
|
||||
+ /* Enable the RGMII on the GPIOs. */
|
||||
+ spx5_wr(HSIO_WRAP_XMII_CFG_GPIO_XMII_CFG_SET(1), port->sparx5,
|
||||
+ HSIO_WRAP_XMII_CFG(!idx));
|
||||
+}
|
||||
+
|
||||
+int lan969x_port_config_rgmii(struct sparx5_port *port,
|
||||
+ struct sparx5_port_config *conf)
|
||||
+{
|
||||
+ int err;
|
||||
+
|
||||
+ err = lan969x_rgmii_delay_config(port, conf);
|
||||
+ if (err)
|
||||
+ return err;
|
||||
+
|
||||
+ lan969x_rgmii_tx_clk_config(port, conf);
|
||||
+ lan969x_rgmii_gpio_config(port);
|
||||
+ lan969x_rgmii_port_device_config(port, conf);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
--- a/drivers/net/ethernet/microchip/sparx5/sparx5_main.h
|
||||
+++ b/drivers/net/ethernet/microchip/sparx5/sparx5_main.h
|
||||
@@ -324,6 +324,8 @@ struct sparx5_ops {
|
||||
irqreturn_t (*ptp_irq_handler)(int irq, void *args);
|
||||
int (*dsm_calendar_calc)(struct sparx5 *sparx5, u32 taxi,
|
||||
struct sparx5_calendar_data *data);
|
||||
+ int (*port_config_rgmii)(struct sparx5_port *port,
|
||||
+ struct sparx5_port_config *conf);
|
||||
};
|
||||
|
||||
struct sparx5_main_io_resource {
|
||||
--- a/drivers/net/ethernet/microchip/sparx5/sparx5_port.c
|
||||
+++ b/drivers/net/ethernet/microchip/sparx5/sparx5_port.c
|
||||
@@ -1012,6 +1012,12 @@ int sparx5_port_config(struct sparx5 *sp
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
+ if (rgmii) {
|
||||
+ err = ops->port_config_rgmii(port, conf);
|
||||
+ if (err)
|
||||
+ return err;
|
||||
+ }
|
||||
+
|
||||
/* high speed device is already configured */
|
||||
if (!rgmii && !high_speed_dev)
|
||||
sparx5_port_config_low_set(sparx5, port, conf);
|
||||
@ -0,0 +1,32 @@
|
||||
From f7c39a31269c23cba94476b0fa99f547cde1a4ed Mon Sep 17 00:00:00 2001
|
||||
From: Daniel Machon <daniel.machon@microchip.com>
|
||||
Date: Mon, 13 Jan 2025 20:36:05 +0100
|
||||
Subject: [PATCH 76/82] net: sparx5: enable FDMA on lan969x
|
||||
|
||||
In a previous series, we made sure that FDMA was not initialized and
|
||||
started on lan969x. Now that we are going to support it, undo that
|
||||
change. In addition, make sure the chip ID check is only applicable on
|
||||
Sparx5, as this is a check that is only relevant on this platform.
|
||||
|
||||
Reviewed-by: Steen Hegelund <Steen.Hegelund@microchip.com>
|
||||
Signed-off-by: Daniel Machon <daniel.machon@microchip.com>
|
||||
Link: https://patch.msgid.link/20250113-sparx5-lan969x-switch-driver-5-v2-1-c468f02fd623@microchip.com
|
||||
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
|
||||
---
|
||||
drivers/net/ethernet/microchip/sparx5/sparx5_main.c | 5 +++--
|
||||
1 file changed, 3 insertions(+), 2 deletions(-)
|
||||
|
||||
--- a/drivers/net/ethernet/microchip/sparx5/sparx5_main.c
|
||||
+++ b/drivers/net/ethernet/microchip/sparx5/sparx5_main.c
|
||||
@@ -784,8 +784,9 @@ static int sparx5_start(struct sparx5 *s
|
||||
|
||||
/* Start Frame DMA with fallback to register based INJ/XTR */
|
||||
err = -ENXIO;
|
||||
- if (sparx5->fdma_irq >= 0 && is_sparx5(sparx5)) {
|
||||
- if (GCB_CHIP_ID_REV_ID_GET(sparx5->chip_id) > 0)
|
||||
+ if (sparx5->fdma_irq >= 0) {
|
||||
+ if (GCB_CHIP_ID_REV_ID_GET(sparx5->chip_id) > 0 ||
|
||||
+ !is_sparx5(sparx5))
|
||||
err = devm_request_irq(sparx5->dev,
|
||||
sparx5->fdma_irq,
|
||||
sparx5_fdma_handler,
|
||||
@ -0,0 +1,135 @@
|
||||
From c4448d20c23c45be9d59b40f3892e134d2e3f155 Mon Sep 17 00:00:00 2001
|
||||
From: Daniel Machon <daniel.machon@microchip.com>
|
||||
Date: Mon, 13 Jan 2025 20:36:06 +0100
|
||||
Subject: [PATCH 77/82] net: sparx5: split sparx5_fdma_{start(),stop()}
|
||||
|
||||
The two functions: sparx5_fdma_{start(),stop()} are responsible for a
|
||||
number of things, namely: allocation and initialization of FDMA buffers,
|
||||
activation FDMA channels in hardware and activation of the NAPI
|
||||
instance.
|
||||
|
||||
This patch splits the buffer allocation and initialization into init and
|
||||
deinit functions, and the channel and NAPI activation into start and
|
||||
stop functions. This serves two purposes: 1) the start() and stop()
|
||||
functions can be reused for lan969x and 2) prepares for future MTU
|
||||
change support, where we must be able to stop and start the FDMA
|
||||
channels and NAPI instance, without free'ing and reallocating the FDMA
|
||||
buffers.
|
||||
|
||||
Reviewed-by: Steen Hegelund <Steen.Hegelund@microchip.com>
|
||||
Signed-off-by: Daniel Machon <daniel.machon@microchip.com>
|
||||
Link: https://patch.msgid.link/20250113-sparx5-lan969x-switch-driver-5-v2-2-c468f02fd623@microchip.com
|
||||
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
|
||||
---
|
||||
.../ethernet/microchip/sparx5/sparx5_fdma.c | 44 ++++++++++++++-----
|
||||
.../ethernet/microchip/sparx5/sparx5_main.c | 7 ++-
|
||||
.../ethernet/microchip/sparx5/sparx5_main.h | 2 +
|
||||
3 files changed, 41 insertions(+), 12 deletions(-)
|
||||
|
||||
--- a/drivers/net/ethernet/microchip/sparx5/sparx5_fdma.c
|
||||
+++ b/drivers/net/ethernet/microchip/sparx5/sparx5_fdma.c
|
||||
@@ -260,10 +260,6 @@ static int sparx5_fdma_rx_alloc(struct s
|
||||
fdma_dcbs_init(fdma, FDMA_DCB_INFO_DATAL(fdma->db_size),
|
||||
FDMA_DCB_STATUS_INTR);
|
||||
|
||||
- netif_napi_add_weight(rx->ndev, &rx->napi, sparx5_fdma_napi_callback,
|
||||
- FDMA_WEIGHT);
|
||||
- napi_enable(&rx->napi);
|
||||
- sparx5_fdma_rx_activate(sparx5, rx);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -410,7 +406,7 @@ static void sparx5_fdma_injection_mode(s
|
||||
}
|
||||
}
|
||||
|
||||
-int sparx5_fdma_start(struct sparx5 *sparx5)
|
||||
+int sparx5_fdma_init(struct sparx5 *sparx5)
|
||||
{
|
||||
int err;
|
||||
|
||||
@@ -443,24 +439,52 @@ int sparx5_fdma_start(struct sparx5 *spa
|
||||
return err;
|
||||
}
|
||||
|
||||
+int sparx5_fdma_deinit(struct sparx5 *sparx5)
|
||||
+{
|
||||
+ sparx5_fdma_stop(sparx5);
|
||||
+ fdma_free_phys(&sparx5->rx.fdma);
|
||||
+ fdma_free_phys(&sparx5->tx.fdma);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
static u32 sparx5_fdma_port_ctrl(struct sparx5 *sparx5)
|
||||
{
|
||||
return spx5_rd(sparx5, FDMA_PORT_CTRL(0));
|
||||
}
|
||||
|
||||
+int sparx5_fdma_start(struct sparx5 *sparx5)
|
||||
+{
|
||||
+ struct sparx5_rx *rx = &sparx5->rx;
|
||||
+
|
||||
+ netif_napi_add_weight(rx->ndev,
|
||||
+ &rx->napi,
|
||||
+ sparx5_fdma_napi_callback,
|
||||
+ FDMA_WEIGHT);
|
||||
+
|
||||
+ napi_enable(&rx->napi);
|
||||
+
|
||||
+ sparx5_fdma_rx_activate(sparx5, rx);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
int sparx5_fdma_stop(struct sparx5 *sparx5)
|
||||
{
|
||||
+ struct sparx5_rx *rx = &sparx5->rx;
|
||||
+ struct sparx5_tx *tx = &sparx5->tx;
|
||||
u32 val;
|
||||
|
||||
- napi_disable(&sparx5->rx.napi);
|
||||
+ napi_disable(&rx->napi);
|
||||
+
|
||||
/* Stop the fdma and channel interrupts */
|
||||
- sparx5_fdma_rx_deactivate(sparx5, &sparx5->rx);
|
||||
- sparx5_fdma_tx_deactivate(sparx5, &sparx5->tx);
|
||||
+ sparx5_fdma_rx_deactivate(sparx5, rx);
|
||||
+ sparx5_fdma_tx_deactivate(sparx5, tx);
|
||||
+
|
||||
/* Wait for the RX channel to stop */
|
||||
read_poll_timeout(sparx5_fdma_port_ctrl, val,
|
||||
FDMA_PORT_CTRL_XTR_BUF_IS_EMPTY_GET(val) == 0,
|
||||
500, 10000, 0, sparx5);
|
||||
- fdma_free_phys(&sparx5->rx.fdma);
|
||||
- fdma_free_phys(&sparx5->tx.fdma);
|
||||
+
|
||||
return 0;
|
||||
}
|
||||
--- a/drivers/net/ethernet/microchip/sparx5/sparx5_main.c
|
||||
+++ b/drivers/net/ethernet/microchip/sparx5/sparx5_main.c
|
||||
@@ -792,8 +792,11 @@ static int sparx5_start(struct sparx5 *s
|
||||
sparx5_fdma_handler,
|
||||
0,
|
||||
"sparx5-fdma", sparx5);
|
||||
- if (!err)
|
||||
- err = sparx5_fdma_start(sparx5);
|
||||
+ if (!err) {
|
||||
+ err = sparx5_fdma_init(sparx5);
|
||||
+ if (!err)
|
||||
+ sparx5_fdma_start(sparx5);
|
||||
+ }
|
||||
if (err)
|
||||
sparx5->fdma_irq = -ENXIO;
|
||||
} else {
|
||||
--- a/drivers/net/ethernet/microchip/sparx5/sparx5_main.h
|
||||
+++ b/drivers/net/ethernet/microchip/sparx5/sparx5_main.h
|
||||
@@ -436,6 +436,8 @@ int sparx5_manual_injection_mode(struct
|
||||
void sparx5_port_inj_timer_setup(struct sparx5_port *port);
|
||||
|
||||
/* sparx5_fdma.c */
|
||||
+int sparx5_fdma_init(struct sparx5 *sparx5);
|
||||
+int sparx5_fdma_deinit(struct sparx5 *sparx5);
|
||||
int sparx5_fdma_start(struct sparx5 *sparx5);
|
||||
int sparx5_fdma_stop(struct sparx5 *sparx5);
|
||||
int sparx5_fdma_xmit(struct sparx5 *sparx5, u32 *ifh, struct sk_buff *skb);
|
||||
@ -0,0 +1,61 @@
|
||||
From 9415d95bb109ed59b4487ff2a90ef8309a8e7e06 Mon Sep 17 00:00:00 2001
|
||||
From: Daniel Machon <daniel.machon@microchip.com>
|
||||
Date: Mon, 13 Jan 2025 20:36:07 +0100
|
||||
Subject: [PATCH 78/82] net: sparx5: activate FDMA tx in start()
|
||||
|
||||
The function sparx5_fdma_tx_activate() is responsible for configuring
|
||||
the TX FDMA instance and activating the channel. TX activation has
|
||||
previously been done in the xmit() function, when the first frame is
|
||||
transmitted. Now that we have separate functions for starting and
|
||||
stopping the FDMA, it seems reasonable to move the TX activation to the
|
||||
start function. This change has no implications on the functionality.
|
||||
|
||||
Reviewed-by: Steen Hegelund <Steen.Hegelund@microchip.com>
|
||||
Signed-off-by: Daniel Machon <daniel.machon@microchip.com>
|
||||
Link: https://patch.msgid.link/20250113-sparx5-lan969x-switch-driver-5-v2-3-c468f02fd623@microchip.com
|
||||
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
|
||||
---
|
||||
drivers/net/ethernet/microchip/sparx5/sparx5_fdma.c | 11 ++++-------
|
||||
1 file changed, 4 insertions(+), 7 deletions(-)
|
||||
|
||||
--- a/drivers/net/ethernet/microchip/sparx5/sparx5_fdma.c
|
||||
+++ b/drivers/net/ethernet/microchip/sparx5/sparx5_fdma.c
|
||||
@@ -217,7 +217,6 @@ int sparx5_fdma_xmit(struct sparx5 *spar
|
||||
{
|
||||
struct sparx5_tx *tx = &sparx5->tx;
|
||||
struct fdma *fdma = &tx->fdma;
|
||||
- static bool first_time = true;
|
||||
void *virt_addr;
|
||||
|
||||
fdma_dcb_advance(fdma);
|
||||
@@ -238,12 +237,8 @@ int sparx5_fdma_xmit(struct sparx5 *spar
|
||||
FDMA_DCB_STATUS_BLOCKO(0) |
|
||||
FDMA_DCB_STATUS_BLOCKL(skb->len + IFH_LEN * 4 + 4));
|
||||
|
||||
- if (first_time) {
|
||||
- sparx5_fdma_tx_activate(sparx5, tx);
|
||||
- first_time = false;
|
||||
- } else {
|
||||
- sparx5_fdma_reload(sparx5, fdma);
|
||||
- }
|
||||
+ sparx5_fdma_reload(sparx5, fdma);
|
||||
+
|
||||
return NETDEV_TX_OK;
|
||||
}
|
||||
|
||||
@@ -456,6 +451,7 @@ static u32 sparx5_fdma_port_ctrl(struct
|
||||
int sparx5_fdma_start(struct sparx5 *sparx5)
|
||||
{
|
||||
struct sparx5_rx *rx = &sparx5->rx;
|
||||
+ struct sparx5_tx *tx = &sparx5->tx;
|
||||
|
||||
netif_napi_add_weight(rx->ndev,
|
||||
&rx->napi,
|
||||
@@ -465,6 +461,7 @@ int sparx5_fdma_start(struct sparx5 *spa
|
||||
napi_enable(&rx->napi);
|
||||
|
||||
sparx5_fdma_rx_activate(sparx5, rx);
|
||||
+ sparx5_fdma_tx_activate(sparx5, tx);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -0,0 +1,146 @@
|
||||
From 72d96799c80510f1bec9d72e6b4f9b5273069201 Mon Sep 17 00:00:00 2001
|
||||
From: Daniel Machon <daniel.machon@microchip.com>
|
||||
Date: Mon, 13 Jan 2025 20:36:08 +0100
|
||||
Subject: [PATCH 79/82] net: sparx5: ops out certain FDMA functions
|
||||
|
||||
We are going to implement the RX and TX paths a bit differently on
|
||||
lan969x and therefore need to introduce new ops for FDMA functions:
|
||||
init, deinit, xmit and poll. Assign the Sparx5 equivalents for these and
|
||||
update the code throughout. Also add a 'struct net_device' argument to
|
||||
the xmit() function, as we will be needing that for lan969x.
|
||||
|
||||
Reviewed-by: Steen Hegelund <Steen.Hegelund@microchip.com>
|
||||
Signed-off-by: Daniel Machon <daniel.machon@microchip.com>
|
||||
Link: https://patch.msgid.link/20250113-sparx5-lan969x-switch-driver-5-v2-4-c468f02fd623@microchip.com
|
||||
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
|
||||
---
|
||||
drivers/net/ethernet/microchip/sparx5/sparx5_fdma.c | 8 +++++---
|
||||
drivers/net/ethernet/microchip/sparx5/sparx5_main.c | 9 +++++++--
|
||||
drivers/net/ethernet/microchip/sparx5/sparx5_main.h | 9 ++++++++-
|
||||
drivers/net/ethernet/microchip/sparx5/sparx5_packet.c | 5 ++++-
|
||||
4 files changed, 24 insertions(+), 7 deletions(-)
|
||||
|
||||
--- a/drivers/net/ethernet/microchip/sparx5/sparx5_fdma.c
|
||||
+++ b/drivers/net/ethernet/microchip/sparx5/sparx5_fdma.c
|
||||
@@ -183,7 +183,7 @@ static bool sparx5_fdma_rx_get_frame(str
|
||||
return true;
|
||||
}
|
||||
|
||||
-static int sparx5_fdma_napi_callback(struct napi_struct *napi, int weight)
|
||||
+int sparx5_fdma_napi_callback(struct napi_struct *napi, int weight)
|
||||
{
|
||||
struct sparx5_rx *rx = container_of(napi, struct sparx5_rx, napi);
|
||||
struct sparx5 *sparx5 = container_of(rx, struct sparx5, rx);
|
||||
@@ -213,7 +213,8 @@ static int sparx5_fdma_napi_callback(str
|
||||
return counter;
|
||||
}
|
||||
|
||||
-int sparx5_fdma_xmit(struct sparx5 *sparx5, u32 *ifh, struct sk_buff *skb)
|
||||
+int sparx5_fdma_xmit(struct sparx5 *sparx5, u32 *ifh, struct sk_buff *skb,
|
||||
+ struct net_device *dev)
|
||||
{
|
||||
struct sparx5_tx *tx = &sparx5->tx;
|
||||
struct fdma *fdma = &tx->fdma;
|
||||
@@ -450,12 +451,13 @@ static u32 sparx5_fdma_port_ctrl(struct
|
||||
|
||||
int sparx5_fdma_start(struct sparx5 *sparx5)
|
||||
{
|
||||
+ const struct sparx5_ops *ops = sparx5->data->ops;
|
||||
struct sparx5_rx *rx = &sparx5->rx;
|
||||
struct sparx5_tx *tx = &sparx5->tx;
|
||||
|
||||
netif_napi_add_weight(rx->ndev,
|
||||
&rx->napi,
|
||||
- sparx5_fdma_napi_callback,
|
||||
+ ops->fdma_poll,
|
||||
FDMA_WEIGHT);
|
||||
|
||||
napi_enable(&rx->napi);
|
||||
--- a/drivers/net/ethernet/microchip/sparx5/sparx5_main.c
|
||||
+++ b/drivers/net/ethernet/microchip/sparx5/sparx5_main.c
|
||||
@@ -793,7 +793,7 @@ static int sparx5_start(struct sparx5 *s
|
||||
0,
|
||||
"sparx5-fdma", sparx5);
|
||||
if (!err) {
|
||||
- err = sparx5_fdma_init(sparx5);
|
||||
+ err = ops->fdma_init(sparx5);
|
||||
if (!err)
|
||||
sparx5_fdma_start(sparx5);
|
||||
}
|
||||
@@ -1030,6 +1030,7 @@ cleanup_pnode:
|
||||
static void mchp_sparx5_remove(struct platform_device *pdev)
|
||||
{
|
||||
struct sparx5 *sparx5 = platform_get_drvdata(pdev);
|
||||
+ const struct sparx5_ops *ops = sparx5->data->ops;
|
||||
|
||||
debugfs_remove_recursive(sparx5->debugfs_root);
|
||||
if (sparx5->xtr_irq) {
|
||||
@@ -1041,7 +1042,7 @@ static void mchp_sparx5_remove(struct pl
|
||||
sparx5->fdma_irq = -ENXIO;
|
||||
}
|
||||
sparx5_ptp_deinit(sparx5);
|
||||
- sparx5_fdma_stop(sparx5);
|
||||
+ ops->fdma_deinit(sparx5);
|
||||
sparx5_cleanup_ports(sparx5);
|
||||
sparx5_vcap_destroy(sparx5);
|
||||
/* Unregister netdevs */
|
||||
@@ -1096,6 +1097,10 @@ static const struct sparx5_ops sparx5_op
|
||||
.set_port_mux = &sparx5_port_mux_set,
|
||||
.ptp_irq_handler = &sparx5_ptp_irq_handler,
|
||||
.dsm_calendar_calc = &sparx5_dsm_calendar_calc,
|
||||
+ .fdma_init = &sparx5_fdma_init,
|
||||
+ .fdma_deinit = &sparx5_fdma_deinit,
|
||||
+ .fdma_poll = &sparx5_fdma_napi_callback,
|
||||
+ .fdma_xmit = &sparx5_fdma_xmit,
|
||||
};
|
||||
|
||||
static const struct sparx5_match_data sparx5_desc = {
|
||||
--- a/drivers/net/ethernet/microchip/sparx5/sparx5_main.h
|
||||
+++ b/drivers/net/ethernet/microchip/sparx5/sparx5_main.h
|
||||
@@ -326,6 +326,11 @@ struct sparx5_ops {
|
||||
struct sparx5_calendar_data *data);
|
||||
int (*port_config_rgmii)(struct sparx5_port *port,
|
||||
struct sparx5_port_config *conf);
|
||||
+ int (*fdma_init)(struct sparx5 *sparx5);
|
||||
+ int (*fdma_deinit)(struct sparx5 *sparx5);
|
||||
+ int (*fdma_poll)(struct napi_struct *napi, int weight);
|
||||
+ int (*fdma_xmit)(struct sparx5 *sparx5, u32 *ifh, struct sk_buff *skb,
|
||||
+ struct net_device *dev);
|
||||
};
|
||||
|
||||
struct sparx5_main_io_resource {
|
||||
@@ -440,7 +445,9 @@ int sparx5_fdma_init(struct sparx5 *spar
|
||||
int sparx5_fdma_deinit(struct sparx5 *sparx5);
|
||||
int sparx5_fdma_start(struct sparx5 *sparx5);
|
||||
int sparx5_fdma_stop(struct sparx5 *sparx5);
|
||||
-int sparx5_fdma_xmit(struct sparx5 *sparx5, u32 *ifh, struct sk_buff *skb);
|
||||
+int sparx5_fdma_napi_callback(struct napi_struct *napi, int weight);
|
||||
+int sparx5_fdma_xmit(struct sparx5 *sparx5, u32 *ifh, struct sk_buff *skb,
|
||||
+ struct net_device *dev);
|
||||
irqreturn_t sparx5_fdma_handler(int irq, void *args);
|
||||
|
||||
/* sparx5_mactable.c */
|
||||
--- a/drivers/net/ethernet/microchip/sparx5/sparx5_packet.c
|
||||
+++ b/drivers/net/ethernet/microchip/sparx5/sparx5_packet.c
|
||||
@@ -232,9 +232,12 @@ netdev_tx_t sparx5_port_xmit_impl(struct
|
||||
struct net_device_stats *stats = &dev->stats;
|
||||
struct sparx5_port *port = netdev_priv(dev);
|
||||
struct sparx5 *sparx5 = port->sparx5;
|
||||
+ const struct sparx5_ops *ops;
|
||||
u32 ifh[IFH_LEN];
|
||||
netdev_tx_t ret;
|
||||
|
||||
+ ops = sparx5->data->ops;
|
||||
+
|
||||
memset(ifh, 0, IFH_LEN * 4);
|
||||
sparx5_set_port_ifh(sparx5, ifh, port->portno);
|
||||
|
||||
@@ -254,7 +257,7 @@ netdev_tx_t sparx5_port_xmit_impl(struct
|
||||
skb_tx_timestamp(skb);
|
||||
spin_lock(&sparx5->tx_lock);
|
||||
if (sparx5->fdma_irq > 0)
|
||||
- ret = sparx5_fdma_xmit(sparx5, ifh, skb);
|
||||
+ ret = ops->fdma_xmit(sparx5, ifh, skb, dev);
|
||||
else
|
||||
ret = sparx5_inject(sparx5, ifh, skb, dev);
|
||||
spin_unlock(&sparx5->tx_lock);
|
||||
@ -0,0 +1,609 @@
|
||||
From 181ee0484e3a966b02ddb238c2abfdbecebafe97 Mon Sep 17 00:00:00 2001
|
||||
From: Daniel Machon <daniel.machon@microchip.com>
|
||||
Date: Mon, 13 Jan 2025 20:36:09 +0100
|
||||
Subject: [PATCH 80/82] net: lan969x: add FDMA implementation
|
||||
|
||||
The lan969x switch device supports manual frame injection and extraction
|
||||
to and from the switch core, using a number of injection and extraction
|
||||
queues. This technique is currently supported, but delivers poor
|
||||
performance compared to Frame DMA (FDMA).
|
||||
|
||||
This lan969x implementation of FDMA, hooks into the existing FDMA for
|
||||
Sparx5, but requires its own RX and TX handling, as lan969x does not
|
||||
support the same native cache coherency that Sparx5 does. Effectively,
|
||||
this means that we are going to use the DMA mapping API for mapping and
|
||||
unmapping TX buffers. The RX loop will utilize the page pool API for
|
||||
efficient RX handling. Other than that, the implementation is largely
|
||||
the same, and utilizes the FDMA library for DCB and DB handling.
|
||||
|
||||
Some numbers:
|
||||
|
||||
Manual injection/extraction (before this series):
|
||||
|
||||
// iperf3 -c 1.0.1.1
|
||||
|
||||
[ ID] Interval Transfer Bitrate
|
||||
[ 5] 0.00-10.02 sec 345 MBytes 289 Mbits/sec sender
|
||||
[ 5] 0.00-10.06 sec 345 MBytes 288 Mbits/sec receiver
|
||||
|
||||
FDMA (after this series):
|
||||
|
||||
// iperf3 -c 1.0.1.1
|
||||
|
||||
[ ID] Interval Transfer Bitrate
|
||||
[ 5] 0.00-10.03 sec 1.10 GBytes 940 Mbits/sec sender
|
||||
[ 5] 0.00-10.07 sec 1.10 GBytes 936 Mbits/sec receiver
|
||||
|
||||
Reviewed-by: Steen Hegelund <Steen.Hegelund@microchip.com>
|
||||
Signed-off-by: Daniel Machon <daniel.machon@microchip.com>
|
||||
Link: https://patch.msgid.link/20250113-sparx5-lan969x-switch-driver-5-v2-5-c468f02fd623@microchip.com
|
||||
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
|
||||
---
|
||||
drivers/net/ethernet/microchip/sparx5/Kconfig | 1 +
|
||||
.../net/ethernet/microchip/sparx5/Makefile | 3 +-
|
||||
.../microchip/sparx5/lan969x/lan969x.c | 4 +
|
||||
.../microchip/sparx5/lan969x/lan969x.h | 7 +
|
||||
.../microchip/sparx5/lan969x/lan969x_fdma.c | 406 ++++++++++++++++++
|
||||
.../ethernet/microchip/sparx5/sparx5_fdma.c | 7 +-
|
||||
.../ethernet/microchip/sparx5/sparx5_main.h | 21 +-
|
||||
.../ethernet/microchip/sparx5/sparx5_packet.c | 6 +
|
||||
8 files changed, 448 insertions(+), 7 deletions(-)
|
||||
create mode 100644 drivers/net/ethernet/microchip/sparx5/lan969x/lan969x_fdma.c
|
||||
|
||||
--- a/drivers/net/ethernet/microchip/sparx5/Kconfig
|
||||
+++ b/drivers/net/ethernet/microchip/sparx5/Kconfig
|
||||
@@ -28,5 +28,6 @@ config SPARX5_DCB
|
||||
config LAN969X_SWITCH
|
||||
bool "Lan969x switch driver"
|
||||
depends on SPARX5_SWITCH
|
||||
+ select PAGE_POOL
|
||||
help
|
||||
This driver supports the lan969x family of network switch devices.
|
||||
--- a/drivers/net/ethernet/microchip/sparx5/Makefile
|
||||
+++ b/drivers/net/ethernet/microchip/sparx5/Makefile
|
||||
@@ -21,7 +21,8 @@ sparx5-switch-$(CONFIG_LAN969X_SWITCH) +
|
||||
lan969x/lan969x_calendar.o \
|
||||
lan969x/lan969x_vcap_ag_api.o \
|
||||
lan969x/lan969x_vcap_impl.o \
|
||||
- lan969x/lan969x_rgmii.o
|
||||
+ lan969x/lan969x_rgmii.o \
|
||||
+ lan969x/lan969x_fdma.o
|
||||
|
||||
# Provide include files
|
||||
ccflags-y += -I$(srctree)/drivers/net/ethernet/microchip/vcap
|
||||
--- a/drivers/net/ethernet/microchip/sparx5/lan969x/lan969x.c
|
||||
+++ b/drivers/net/ethernet/microchip/sparx5/lan969x/lan969x.c
|
||||
@@ -341,6 +341,10 @@ static const struct sparx5_ops lan969x_o
|
||||
.ptp_irq_handler = &lan969x_ptp_irq_handler,
|
||||
.dsm_calendar_calc = &lan969x_dsm_calendar_calc,
|
||||
.port_config_rgmii = &lan969x_port_config_rgmii,
|
||||
+ .fdma_init = &lan969x_fdma_init,
|
||||
+ .fdma_deinit = &lan969x_fdma_deinit,
|
||||
+ .fdma_poll = &lan969x_fdma_napi_poll,
|
||||
+ .fdma_xmit = &lan969x_fdma_xmit,
|
||||
};
|
||||
|
||||
const struct sparx5_match_data lan969x_desc = {
|
||||
--- a/drivers/net/ethernet/microchip/sparx5/lan969x/lan969x.h
|
||||
+++ b/drivers/net/ethernet/microchip/sparx5/lan969x/lan969x.h
|
||||
@@ -72,4 +72,11 @@ int lan969x_dsm_calendar_calc(struct spa
|
||||
int lan969x_port_config_rgmii(struct sparx5_port *port,
|
||||
struct sparx5_port_config *conf);
|
||||
|
||||
+/* lan969x_fdma.c */
|
||||
+int lan969x_fdma_init(struct sparx5 *sparx5);
|
||||
+int lan969x_fdma_deinit(struct sparx5 *sparx5);
|
||||
+int lan969x_fdma_napi_poll(struct napi_struct *napi, int weight);
|
||||
+int lan969x_fdma_xmit(struct sparx5 *sparx5, u32 *ifh, struct sk_buff *skb,
|
||||
+ struct net_device *dev);
|
||||
+
|
||||
#endif
|
||||
--- /dev/null
|
||||
+++ b/drivers/net/ethernet/microchip/sparx5/lan969x/lan969x_fdma.c
|
||||
@@ -0,0 +1,406 @@
|
||||
+// SPDX-License-Identifier: GPL-2.0+
|
||||
+/* Microchip lan969x Switch driver
|
||||
+ *
|
||||
+ * Copyright (c) 2025 Microchip Technology Inc. and its subsidiaries.
|
||||
+ */
|
||||
+#include <net/page_pool/helpers.h>
|
||||
+
|
||||
+#include "../sparx5_main.h"
|
||||
+#include "../sparx5_main_regs.h"
|
||||
+#include "../sparx5_port.h"
|
||||
+
|
||||
+#include "fdma_api.h"
|
||||
+#include "lan969x.h"
|
||||
+
|
||||
+#define FDMA_PRIV(fdma) ((struct sparx5 *)((fdma)->priv))
|
||||
+
|
||||
+static int lan969x_fdma_tx_dataptr_cb(struct fdma *fdma, int dcb, int db,
|
||||
+ u64 *dataptr)
|
||||
+{
|
||||
+ *dataptr = FDMA_PRIV(fdma)->tx.dbs[dcb].dma_addr;
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static int lan969x_fdma_rx_dataptr_cb(struct fdma *fdma, int dcb, int db,
|
||||
+ u64 *dataptr)
|
||||
+{
|
||||
+ struct sparx5_rx *rx = &FDMA_PRIV(fdma)->rx;
|
||||
+ struct page *page;
|
||||
+
|
||||
+ page = page_pool_dev_alloc_pages(rx->page_pool);
|
||||
+ if (unlikely(!page))
|
||||
+ return -ENOMEM;
|
||||
+
|
||||
+ rx->page[dcb][db] = page;
|
||||
+
|
||||
+ *dataptr = page_pool_get_dma_addr(page);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static int lan969x_fdma_get_next_dcb(struct sparx5_tx *tx)
|
||||
+{
|
||||
+ struct fdma *fdma = &tx->fdma;
|
||||
+
|
||||
+ for (int i = 0; i < fdma->n_dcbs; ++i)
|
||||
+ if (!tx->dbs[i].used && !fdma_is_last(fdma, &fdma->dcbs[i]))
|
||||
+ return i;
|
||||
+
|
||||
+ return -ENOSPC;
|
||||
+}
|
||||
+
|
||||
+static void lan969x_fdma_tx_clear_buf(struct sparx5 *sparx5, int weight)
|
||||
+{
|
||||
+ struct fdma *fdma = &sparx5->tx.fdma;
|
||||
+ struct sparx5_tx_buf *db;
|
||||
+ unsigned long flags;
|
||||
+ int i;
|
||||
+
|
||||
+ spin_lock_irqsave(&sparx5->tx_lock, flags);
|
||||
+
|
||||
+ for (i = 0; i < fdma->n_dcbs; ++i) {
|
||||
+ db = &sparx5->tx.dbs[i];
|
||||
+
|
||||
+ if (!db->used)
|
||||
+ continue;
|
||||
+
|
||||
+ if (!fdma_db_is_done(fdma_db_get(fdma, i, 0)))
|
||||
+ continue;
|
||||
+
|
||||
+ db->dev->stats.tx_bytes += db->skb->len;
|
||||
+ db->dev->stats.tx_packets++;
|
||||
+ sparx5->tx.packets++;
|
||||
+
|
||||
+ dma_unmap_single(sparx5->dev,
|
||||
+ db->dma_addr,
|
||||
+ db->skb->len,
|
||||
+ DMA_TO_DEVICE);
|
||||
+
|
||||
+ if (!db->ptp)
|
||||
+ napi_consume_skb(db->skb, weight);
|
||||
+
|
||||
+ db->used = false;
|
||||
+ }
|
||||
+
|
||||
+ spin_unlock_irqrestore(&sparx5->tx_lock, flags);
|
||||
+}
|
||||
+
|
||||
+static void lan969x_fdma_free_pages(struct sparx5_rx *rx)
|
||||
+{
|
||||
+ struct fdma *fdma = &rx->fdma;
|
||||
+
|
||||
+ for (int i = 0; i < fdma->n_dcbs; ++i) {
|
||||
+ for (int j = 0; j < fdma->n_dbs; ++j)
|
||||
+ page_pool_put_full_page(rx->page_pool,
|
||||
+ rx->page[i][j], false);
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+static struct sk_buff *lan969x_fdma_rx_get_frame(struct sparx5 *sparx5,
|
||||
+ struct sparx5_rx *rx)
|
||||
+{
|
||||
+ const struct sparx5_consts *consts = sparx5->data->consts;
|
||||
+ struct fdma *fdma = &rx->fdma;
|
||||
+ struct sparx5_port *port;
|
||||
+ struct frame_info fi;
|
||||
+ struct sk_buff *skb;
|
||||
+ struct fdma_db *db;
|
||||
+ struct page *page;
|
||||
+
|
||||
+ db = &fdma->dcbs[fdma->dcb_index].db[fdma->db_index];
|
||||
+ page = rx->page[fdma->dcb_index][fdma->db_index];
|
||||
+
|
||||
+ sparx5_ifh_parse(sparx5, page_address(page), &fi);
|
||||
+ port = fi.src_port < consts->n_ports ? sparx5->ports[fi.src_port] :
|
||||
+ NULL;
|
||||
+ if (WARN_ON(!port))
|
||||
+ goto free_page;
|
||||
+
|
||||
+ skb = build_skb(page_address(page), fdma->db_size);
|
||||
+ if (unlikely(!skb))
|
||||
+ goto free_page;
|
||||
+
|
||||
+ skb_mark_for_recycle(skb);
|
||||
+ skb_put(skb, fdma_db_len_get(db));
|
||||
+ skb_pull(skb, IFH_LEN * sizeof(u32));
|
||||
+
|
||||
+ skb->dev = port->ndev;
|
||||
+
|
||||
+ if (likely(!(skb->dev->features & NETIF_F_RXFCS)))
|
||||
+ skb_trim(skb, skb->len - ETH_FCS_LEN);
|
||||
+
|
||||
+ sparx5_ptp_rxtstamp(sparx5, skb, fi.timestamp);
|
||||
+ skb->protocol = eth_type_trans(skb, skb->dev);
|
||||
+
|
||||
+ if (test_bit(port->portno, sparx5->bridge_mask))
|
||||
+ skb->offload_fwd_mark = 1;
|
||||
+
|
||||
+ skb->dev->stats.rx_bytes += skb->len;
|
||||
+ skb->dev->stats.rx_packets++;
|
||||
+
|
||||
+ return skb;
|
||||
+
|
||||
+free_page:
|
||||
+ page_pool_recycle_direct(rx->page_pool, page);
|
||||
+
|
||||
+ return NULL;
|
||||
+}
|
||||
+
|
||||
+static int lan969x_fdma_rx_alloc(struct sparx5 *sparx5)
|
||||
+{
|
||||
+ struct sparx5_rx *rx = &sparx5->rx;
|
||||
+ struct fdma *fdma = &rx->fdma;
|
||||
+ int err;
|
||||
+
|
||||
+ struct page_pool_params pp_params = {
|
||||
+ .order = 0,
|
||||
+ .flags = PP_FLAG_DMA_MAP | PP_FLAG_DMA_SYNC_DEV,
|
||||
+ .pool_size = fdma->n_dcbs * fdma->n_dbs,
|
||||
+ .nid = NUMA_NO_NODE,
|
||||
+ .dev = sparx5->dev,
|
||||
+ .dma_dir = DMA_FROM_DEVICE,
|
||||
+ .offset = 0,
|
||||
+ .max_len = fdma->db_size -
|
||||
+ SKB_DATA_ALIGN(sizeof(struct skb_shared_info)),
|
||||
+ };
|
||||
+
|
||||
+ rx->page_pool = page_pool_create(&pp_params);
|
||||
+ if (IS_ERR(rx->page_pool))
|
||||
+ return PTR_ERR(rx->page_pool);
|
||||
+
|
||||
+ err = fdma_alloc_coherent(sparx5->dev, fdma);
|
||||
+ if (err)
|
||||
+ return err;
|
||||
+
|
||||
+ fdma_dcbs_init(fdma,
|
||||
+ FDMA_DCB_INFO_DATAL(fdma->db_size),
|
||||
+ FDMA_DCB_STATUS_INTR);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static int lan969x_fdma_tx_alloc(struct sparx5 *sparx5)
|
||||
+{
|
||||
+ struct sparx5_tx *tx = &sparx5->tx;
|
||||
+ struct fdma *fdma = &tx->fdma;
|
||||
+ int err;
|
||||
+
|
||||
+ tx->dbs = kcalloc(fdma->n_dcbs,
|
||||
+ sizeof(struct sparx5_tx_buf),
|
||||
+ GFP_KERNEL);
|
||||
+ if (!tx->dbs)
|
||||
+ return -ENOMEM;
|
||||
+
|
||||
+ err = fdma_alloc_coherent(sparx5->dev, fdma);
|
||||
+ if (err) {
|
||||
+ kfree(tx->dbs);
|
||||
+ return err;
|
||||
+ }
|
||||
+
|
||||
+ fdma_dcbs_init(fdma,
|
||||
+ FDMA_DCB_INFO_DATAL(fdma->db_size),
|
||||
+ FDMA_DCB_STATUS_DONE);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static void lan969x_fdma_rx_init(struct sparx5 *sparx5)
|
||||
+{
|
||||
+ struct fdma *fdma = &sparx5->rx.fdma;
|
||||
+
|
||||
+ fdma->channel_id = FDMA_XTR_CHANNEL;
|
||||
+ fdma->n_dcbs = FDMA_DCB_MAX;
|
||||
+ fdma->n_dbs = 1;
|
||||
+ fdma->priv = sparx5;
|
||||
+ fdma->size = fdma_get_size(fdma);
|
||||
+ fdma->db_size = PAGE_SIZE;
|
||||
+ fdma->ops.dataptr_cb = &lan969x_fdma_rx_dataptr_cb;
|
||||
+ fdma->ops.nextptr_cb = &fdma_nextptr_cb;
|
||||
+
|
||||
+ /* Fetch a netdev for SKB and NAPI use, any will do */
|
||||
+ for (int idx = 0; idx < sparx5->data->consts->n_ports; ++idx) {
|
||||
+ struct sparx5_port *port = sparx5->ports[idx];
|
||||
+
|
||||
+ if (port && port->ndev) {
|
||||
+ sparx5->rx.ndev = port->ndev;
|
||||
+ break;
|
||||
+ }
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+static void lan969x_fdma_tx_init(struct sparx5 *sparx5)
|
||||
+{
|
||||
+ struct fdma *fdma = &sparx5->tx.fdma;
|
||||
+
|
||||
+ fdma->channel_id = FDMA_INJ_CHANNEL;
|
||||
+ fdma->n_dcbs = FDMA_DCB_MAX;
|
||||
+ fdma->n_dbs = 1;
|
||||
+ fdma->priv = sparx5;
|
||||
+ fdma->size = fdma_get_size(fdma);
|
||||
+ fdma->db_size = PAGE_SIZE;
|
||||
+ fdma->ops.dataptr_cb = &lan969x_fdma_tx_dataptr_cb;
|
||||
+ fdma->ops.nextptr_cb = &fdma_nextptr_cb;
|
||||
+}
|
||||
+
|
||||
+int lan969x_fdma_napi_poll(struct napi_struct *napi, int weight)
|
||||
+{
|
||||
+ struct sparx5_rx *rx = container_of(napi, struct sparx5_rx, napi);
|
||||
+ struct sparx5 *sparx5 = container_of(rx, struct sparx5, rx);
|
||||
+ int old_dcb, dcb_reload, counter = 0;
|
||||
+ struct fdma *fdma = &rx->fdma;
|
||||
+ struct sk_buff *skb;
|
||||
+
|
||||
+ dcb_reload = fdma->dcb_index;
|
||||
+
|
||||
+ lan969x_fdma_tx_clear_buf(sparx5, weight);
|
||||
+
|
||||
+ /* Process RX data */
|
||||
+ while (counter < weight) {
|
||||
+ if (!fdma_has_frames(fdma))
|
||||
+ break;
|
||||
+
|
||||
+ skb = lan969x_fdma_rx_get_frame(sparx5, rx);
|
||||
+ if (!skb)
|
||||
+ break;
|
||||
+
|
||||
+ napi_gro_receive(&rx->napi, skb);
|
||||
+
|
||||
+ fdma_db_advance(fdma);
|
||||
+ counter++;
|
||||
+ /* Check if the DCB can be reused */
|
||||
+ if (fdma_dcb_is_reusable(fdma))
|
||||
+ continue;
|
||||
+
|
||||
+ fdma_db_reset(fdma);
|
||||
+ fdma_dcb_advance(fdma);
|
||||
+ }
|
||||
+
|
||||
+ /* Allocate new pages and map them */
|
||||
+ while (dcb_reload != fdma->dcb_index) {
|
||||
+ old_dcb = dcb_reload;
|
||||
+ dcb_reload++;
|
||||
+ /* n_dcbs must be a power of 2 */
|
||||
+ dcb_reload &= fdma->n_dcbs - 1;
|
||||
+
|
||||
+ fdma_dcb_add(fdma,
|
||||
+ old_dcb,
|
||||
+ FDMA_DCB_INFO_DATAL(fdma->db_size),
|
||||
+ FDMA_DCB_STATUS_INTR);
|
||||
+
|
||||
+ sparx5_fdma_reload(sparx5, fdma);
|
||||
+ }
|
||||
+
|
||||
+ if (counter < weight && napi_complete_done(napi, counter))
|
||||
+ spx5_wr(0xff, sparx5, FDMA_INTR_DB_ENA);
|
||||
+
|
||||
+ return counter;
|
||||
+}
|
||||
+
|
||||
+int lan969x_fdma_xmit(struct sparx5 *sparx5, u32 *ifh, struct sk_buff *skb,
|
||||
+ struct net_device *dev)
|
||||
+{
|
||||
+ int next_dcb, needed_headroom, needed_tailroom, err;
|
||||
+ struct sparx5_tx *tx = &sparx5->tx;
|
||||
+ struct fdma *fdma = &tx->fdma;
|
||||
+ struct sparx5_tx_buf *db_buf;
|
||||
+ u64 status;
|
||||
+
|
||||
+ next_dcb = lan969x_fdma_get_next_dcb(tx);
|
||||
+ if (next_dcb < 0)
|
||||
+ return -EBUSY;
|
||||
+
|
||||
+ needed_headroom = max_t(int, IFH_LEN * 4 - skb_headroom(skb), 0);
|
||||
+ needed_tailroom = max_t(int, ETH_FCS_LEN - skb_tailroom(skb), 0);
|
||||
+ if (needed_headroom || needed_tailroom || skb_header_cloned(skb)) {
|
||||
+ err = pskb_expand_head(skb, needed_headroom, needed_tailroom,
|
||||
+ GFP_ATOMIC);
|
||||
+ if (unlikely(err))
|
||||
+ return err;
|
||||
+ }
|
||||
+
|
||||
+ skb_push(skb, IFH_LEN * 4);
|
||||
+ memcpy(skb->data, ifh, IFH_LEN * 4);
|
||||
+ skb_put(skb, ETH_FCS_LEN);
|
||||
+
|
||||
+ db_buf = &tx->dbs[next_dcb];
|
||||
+ db_buf->dma_addr = dma_map_single(sparx5->dev,
|
||||
+ skb->data,
|
||||
+ skb->len,
|
||||
+ DMA_TO_DEVICE);
|
||||
+ if (dma_mapping_error(sparx5->dev, db_buf->dma_addr))
|
||||
+ return -ENOMEM;
|
||||
+
|
||||
+ db_buf->dev = dev;
|
||||
+ db_buf->skb = skb;
|
||||
+ db_buf->ptp = false;
|
||||
+ db_buf->used = true;
|
||||
+
|
||||
+ if (skb_shinfo(skb)->tx_flags & SKBTX_HW_TSTAMP &&
|
||||
+ SPARX5_SKB_CB(skb)->rew_op == IFH_REW_OP_TWO_STEP_PTP)
|
||||
+ db_buf->ptp = true;
|
||||
+
|
||||
+ status = FDMA_DCB_STATUS_SOF |
|
||||
+ FDMA_DCB_STATUS_EOF |
|
||||
+ FDMA_DCB_STATUS_BLOCKO(0) |
|
||||
+ FDMA_DCB_STATUS_BLOCKL(skb->len) |
|
||||
+ FDMA_DCB_STATUS_INTR;
|
||||
+
|
||||
+ fdma_dcb_advance(fdma);
|
||||
+ fdma_dcb_add(fdma, next_dcb, 0, status);
|
||||
+
|
||||
+ sparx5_fdma_reload(sparx5, fdma);
|
||||
+
|
||||
+ return NETDEV_TX_OK;
|
||||
+}
|
||||
+
|
||||
+int lan969x_fdma_init(struct sparx5 *sparx5)
|
||||
+{
|
||||
+ struct sparx5_rx *rx = &sparx5->rx;
|
||||
+ int err;
|
||||
+
|
||||
+ lan969x_fdma_rx_init(sparx5);
|
||||
+ lan969x_fdma_tx_init(sparx5);
|
||||
+ sparx5_fdma_injection_mode(sparx5);
|
||||
+
|
||||
+ err = dma_set_mask_and_coherent(sparx5->dev, DMA_BIT_MASK(64));
|
||||
+ if (err) {
|
||||
+ dev_err(sparx5->dev, "Failed to set 64-bit FDMA mask");
|
||||
+ return err;
|
||||
+ }
|
||||
+
|
||||
+ err = lan969x_fdma_rx_alloc(sparx5);
|
||||
+ if (err) {
|
||||
+ dev_err(sparx5->dev, "Failed to allocate RX buffers: %d\n",
|
||||
+ err);
|
||||
+ return err;
|
||||
+ }
|
||||
+
|
||||
+ err = lan969x_fdma_tx_alloc(sparx5);
|
||||
+ if (err) {
|
||||
+ fdma_free_coherent(sparx5->dev, &rx->fdma);
|
||||
+ dev_err(sparx5->dev, "Failed to allocate TX buffers: %d\n",
|
||||
+ err);
|
||||
+ return err;
|
||||
+ }
|
||||
+
|
||||
+ /* Reset FDMA state */
|
||||
+ spx5_wr(FDMA_CTRL_NRESET_SET(0), sparx5, FDMA_CTRL);
|
||||
+ spx5_wr(FDMA_CTRL_NRESET_SET(1), sparx5, FDMA_CTRL);
|
||||
+
|
||||
+ return err;
|
||||
+}
|
||||
+
|
||||
+int lan969x_fdma_deinit(struct sparx5 *sparx5)
|
||||
+{
|
||||
+ struct sparx5_rx *rx = &sparx5->rx;
|
||||
+ struct sparx5_tx *tx = &sparx5->tx;
|
||||
+
|
||||
+ sparx5_fdma_stop(sparx5);
|
||||
+ fdma_free_coherent(sparx5->dev, &tx->fdma);
|
||||
+ fdma_free_coherent(sparx5->dev, &rx->fdma);
|
||||
+ lan969x_fdma_free_pages(rx);
|
||||
+ page_pool_destroy(rx->page_pool);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
--- a/drivers/net/ethernet/microchip/sparx5/sparx5_fdma.c
|
||||
+++ b/drivers/net/ethernet/microchip/sparx5/sparx5_fdma.c
|
||||
@@ -18,9 +18,6 @@
|
||||
#include "sparx5_main.h"
|
||||
#include "sparx5_port.h"
|
||||
|
||||
-#define FDMA_XTR_CHANNEL 6
|
||||
-#define FDMA_INJ_CHANNEL 0
|
||||
-
|
||||
#define FDMA_XTR_BUFFER_SIZE 2048
|
||||
#define FDMA_WEIGHT 4
|
||||
|
||||
@@ -133,7 +130,7 @@ static void sparx5_fdma_tx_deactivate(st
|
||||
sparx5, FDMA_CH_ACTIVATE);
|
||||
}
|
||||
|
||||
-static void sparx5_fdma_reload(struct sparx5 *sparx5, struct fdma *fdma)
|
||||
+void sparx5_fdma_reload(struct sparx5 *sparx5, struct fdma *fdma)
|
||||
{
|
||||
/* Reload the RX channel */
|
||||
spx5_wr(BIT(fdma->channel_id), sparx5, FDMA_CH_RELOAD);
|
||||
@@ -340,7 +337,7 @@ irqreturn_t sparx5_fdma_handler(int irq,
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
-static void sparx5_fdma_injection_mode(struct sparx5 *sparx5)
|
||||
+void sparx5_fdma_injection_mode(struct sparx5 *sparx5)
|
||||
{
|
||||
const int byte_swap = 1;
|
||||
int portno;
|
||||
--- a/drivers/net/ethernet/microchip/sparx5/sparx5_main.h
|
||||
+++ b/drivers/net/ethernet/microchip/sparx5/sparx5_main.h
|
||||
@@ -112,6 +112,8 @@ enum sparx5_feature {
|
||||
#define XTR_QUEUE 0
|
||||
#define INJ_QUEUE 0
|
||||
|
||||
+#define FDMA_XTR_CHANNEL 6
|
||||
+#define FDMA_INJ_CHANNEL 0
|
||||
#define FDMA_DCB_MAX 64
|
||||
#define FDMA_RX_DCB_MAX_DBS 15
|
||||
#define FDMA_TX_DCB_MAX_DBS 1
|
||||
@@ -157,11 +159,25 @@ struct sparx5_calendar_data {
|
||||
*/
|
||||
struct sparx5_rx {
|
||||
struct fdma fdma;
|
||||
- struct sk_buff *skb[FDMA_DCB_MAX][FDMA_RX_DCB_MAX_DBS];
|
||||
+ struct page_pool *page_pool;
|
||||
+ union {
|
||||
+ struct sk_buff *skb[FDMA_DCB_MAX][FDMA_RX_DCB_MAX_DBS];
|
||||
+ struct page *page[FDMA_DCB_MAX][FDMA_RX_DCB_MAX_DBS];
|
||||
+ };
|
||||
dma_addr_t dma;
|
||||
struct napi_struct napi;
|
||||
struct net_device *ndev;
|
||||
u64 packets;
|
||||
+ u8 page_order;
|
||||
+};
|
||||
+
|
||||
+/* Used to store information about TX buffers. */
|
||||
+struct sparx5_tx_buf {
|
||||
+ struct net_device *dev;
|
||||
+ struct sk_buff *skb;
|
||||
+ dma_addr_t dma_addr;
|
||||
+ bool used;
|
||||
+ bool ptp;
|
||||
};
|
||||
|
||||
/* Frame DMA transmit state:
|
||||
@@ -169,6 +185,7 @@ struct sparx5_rx {
|
||||
*/
|
||||
struct sparx5_tx {
|
||||
struct fdma fdma;
|
||||
+ struct sparx5_tx_buf *dbs;
|
||||
u64 packets;
|
||||
u64 dropped;
|
||||
};
|
||||
@@ -449,6 +466,8 @@ int sparx5_fdma_napi_callback(struct nap
|
||||
int sparx5_fdma_xmit(struct sparx5 *sparx5, u32 *ifh, struct sk_buff *skb,
|
||||
struct net_device *dev);
|
||||
irqreturn_t sparx5_fdma_handler(int irq, void *args);
|
||||
+void sparx5_fdma_reload(struct sparx5 *sparx5, struct fdma *fdma);
|
||||
+void sparx5_fdma_injection_mode(struct sparx5 *sparx5);
|
||||
|
||||
/* sparx5_mactable.c */
|
||||
void sparx5_mact_pull_work(struct work_struct *work);
|
||||
--- a/drivers/net/ethernet/microchip/sparx5/sparx5_packet.c
|
||||
+++ b/drivers/net/ethernet/microchip/sparx5/sparx5_packet.c
|
||||
@@ -267,6 +267,12 @@ netdev_tx_t sparx5_port_xmit_impl(struct
|
||||
if (ret < 0)
|
||||
goto drop;
|
||||
|
||||
+ if (!is_sparx5(sparx5))
|
||||
+ /* When lan969x and TX_OK, stats and SKB consumption is handled
|
||||
+ * in the TX completion loop, so dont go any further.
|
||||
+ */
|
||||
+ return NETDEV_TX_OK;
|
||||
+
|
||||
stats->tx_bytes += skb->len;
|
||||
stats->tx_packets++;
|
||||
sparx5->tx.packets++;
|
||||
@ -0,0 +1,62 @@
|
||||
From b3461fb971b0db9158653bdbcb99d1327f7eeff0 Mon Sep 17 00:00:00 2001
|
||||
From: Daniel Machon <daniel.machon@microchip.com>
|
||||
Date: Wed, 17 Sep 2025 13:49:43 +0200
|
||||
Subject: [PATCH 82/82] net: sparx5/lan969x: Add support for ethtool pause
|
||||
parameters
|
||||
|
||||
Implement get_pauseparam() and set_pauseparam() ethtool operations for
|
||||
Sparx5 ports. This allows users to query and configure IEEE 802.3x
|
||||
pause frame settings via:
|
||||
|
||||
ethtool -a ethX
|
||||
ethtool -A ethX rx on|off tx on|off autoneg on|off
|
||||
|
||||
The driver delegates pause parameter handling to phylink through
|
||||
phylink_ethtool_get_pauseparam() and phylink_ethtool_set_pauseparam().
|
||||
|
||||
The underlying configuration of pause frame generation and reception is
|
||||
already implemented in the driver; this patch only wires it up to the
|
||||
standard ethtool interface, making the feature accessible to userspace.
|
||||
|
||||
Signed-off-by: Daniel Machon <daniel.machon@microchip.com>
|
||||
Reviewed-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
|
||||
Link: https://patch.msgid.link/20250917-802-3x-pause-v1-1-3d1565a68a96@microchip.com
|
||||
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
|
||||
---
|
||||
.../ethernet/microchip/sparx5/sparx5_ethtool.c | 18 ++++++++++++++++++
|
||||
1 file changed, 18 insertions(+)
|
||||
|
||||
--- a/drivers/net/ethernet/microchip/sparx5/sparx5_ethtool.c
|
||||
+++ b/drivers/net/ethernet/microchip/sparx5/sparx5_ethtool.c
|
||||
@@ -1212,6 +1212,22 @@ static int sparx5_get_ts_info(struct net
|
||||
return 0;
|
||||
}
|
||||
|
||||
+static void sparx5_get_pauseparam(struct net_device *dev,
|
||||
+ struct ethtool_pauseparam *pause)
|
||||
+{
|
||||
+ struct sparx5_port *port = netdev_priv(dev);
|
||||
+
|
||||
+ phylink_ethtool_get_pauseparam(port->phylink, pause);
|
||||
+}
|
||||
+
|
||||
+static int sparx5_set_pauseparam(struct net_device *dev,
|
||||
+ struct ethtool_pauseparam *pause)
|
||||
+{
|
||||
+ struct sparx5_port *port = netdev_priv(dev);
|
||||
+
|
||||
+ return phylink_ethtool_set_pauseparam(port->phylink, pause);
|
||||
+}
|
||||
+
|
||||
const struct ethtool_ops sparx5_ethtool_ops = {
|
||||
.get_sset_count = sparx5_get_sset_count,
|
||||
.get_strings = sparx5_get_sset_strings,
|
||||
@@ -1224,6 +1240,8 @@ const struct ethtool_ops sparx5_ethtool_
|
||||
.get_eth_ctrl_stats = sparx5_get_eth_mac_ctrl_stats,
|
||||
.get_rmon_stats = sparx5_get_eth_rmon_stats,
|
||||
.get_ts_info = sparx5_get_ts_info,
|
||||
+ .get_pauseparam = sparx5_get_pauseparam,
|
||||
+ .set_pauseparam = sparx5_set_pauseparam,
|
||||
};
|
||||
|
||||
int sparx_stats_init(struct sparx5 *sparx5)
|
||||
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,181 @@
|
||||
From 36087601ba5fed2fe42134bf59f6ba75029fd7f7 Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Bence=20Cs=C3=B3k=C3=A1s?= <csokas.bence@prolan.hu>
|
||||
Date: Wed, 18 Dec 2024 16:17:54 +0100
|
||||
Subject: [PATCH 099/112] spi: atmel-quadspi: Factor out switching to Serial
|
||||
Memory Mode to function
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
SAMA7G5 support (that was forward-ported from v6.1) re-introduced
|
||||
a bug that was fixed in v6.12, thankfully only in the codepath of
|
||||
the new SoC. But to prevent similar mistakes in the future, we
|
||||
split out the offending code to a function, and use this, fixed
|
||||
version everywhere.
|
||||
|
||||
To facilitate this, support function `atmel_qspi_update_config()`
|
||||
also had to be moved upwards. For best viewing experience, use
|
||||
`--color-moved-ws="allow-indentation-change" --color-moved`.
|
||||
|
||||
Fixes: 5af42209a4d2 ("spi: atmel-quadspi: Add support for sama7g5 QSPI")
|
||||
Reported-by: Alexander Dahl <ada@thorsis.com>
|
||||
Closes: https://lore.kernel.org/linux-spi/20241218-appliance-jaws-90773405977a@thorsis.com/
|
||||
Signed-off-by: Bence Csókás <csokas.bence@prolan.hu>
|
||||
Link: https://patch.msgid.link/20241218151754.365519-1-csokas.bence@prolan.hu
|
||||
Signed-off-by: Mark Brown <broonie@kernel.org>
|
||||
---
|
||||
drivers/spi/atmel-quadspi.c | 101 +++++++++++++++++++-----------------
|
||||
1 file changed, 53 insertions(+), 48 deletions(-)
|
||||
|
||||
--- a/drivers/spi/atmel-quadspi.c
|
||||
+++ b/drivers/spi/atmel-quadspi.c
|
||||
@@ -414,6 +414,28 @@ static void atmel_qspi_write(u32 value,
|
||||
writel_relaxed(value, aq->regs + offset);
|
||||
}
|
||||
|
||||
+static int atmel_qspi_reg_sync(struct atmel_qspi *aq)
|
||||
+{
|
||||
+ u32 val;
|
||||
+ int ret;
|
||||
+
|
||||
+ ret = readl_poll_timeout(aq->regs + QSPI_SR2, val,
|
||||
+ !(val & QSPI_SR2_SYNCBSY), 40,
|
||||
+ ATMEL_QSPI_SYNC_TIMEOUT);
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
+static int atmel_qspi_update_config(struct atmel_qspi *aq)
|
||||
+{
|
||||
+ int ret;
|
||||
+
|
||||
+ ret = atmel_qspi_reg_sync(aq);
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+ atmel_qspi_write(QSPI_CR_UPDCFG, aq, QSPI_CR);
|
||||
+ return atmel_qspi_reg_sync(aq);
|
||||
+}
|
||||
+
|
||||
static inline bool atmel_qspi_is_compatible(const struct spi_mem_op *op,
|
||||
const struct atmel_qspi_mode *mode)
|
||||
{
|
||||
@@ -476,6 +498,25 @@ static bool atmel_qspi_supports_op(struc
|
||||
return true;
|
||||
}
|
||||
|
||||
+/*
|
||||
+ * If the QSPI controller is set in regular SPI mode, set it in
|
||||
+ * Serial Memory Mode (SMM).
|
||||
+ */
|
||||
+static int atmel_qspi_set_serial_memory_mode(struct atmel_qspi *aq)
|
||||
+{
|
||||
+ int ret = 0;
|
||||
+
|
||||
+ if (!(aq->mr & QSPI_MR_SMM)) {
|
||||
+ aq->mr |= QSPI_MR_SMM;
|
||||
+ atmel_qspi_write(aq->mr, aq, QSPI_MR);
|
||||
+
|
||||
+ if (aq->caps->has_gclk)
|
||||
+ ret = atmel_qspi_update_config(aq);
|
||||
+ }
|
||||
+
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
static int atmel_qspi_set_cfg(struct atmel_qspi *aq,
|
||||
const struct spi_mem_op *op, u32 *offset)
|
||||
{
|
||||
@@ -555,14 +596,9 @@ static int atmel_qspi_set_cfg(struct atm
|
||||
ifr |= QSPI_IFR_TFRTYP_MEM;
|
||||
}
|
||||
|
||||
- /*
|
||||
- * If the QSPI controller is set in regular SPI mode, set it in
|
||||
- * Serial Memory Mode (SMM).
|
||||
- */
|
||||
- if (!(aq->mr & QSPI_MR_SMM)) {
|
||||
- aq->mr |= QSPI_MR_SMM;
|
||||
- atmel_qspi_write(aq->mr, aq, QSPI_MR);
|
||||
- }
|
||||
+ mode = atmel_qspi_set_serial_memory_mode(aq);
|
||||
+ if (mode < 0)
|
||||
+ return mode;
|
||||
|
||||
/* Clear pending interrupts */
|
||||
(void)atmel_qspi_read(aq, QSPI_SR);
|
||||
@@ -645,28 +681,6 @@ static int atmel_qspi_transfer(struct sp
|
||||
return atmel_qspi_wait_for_completion(aq, QSPI_SR_CMD_COMPLETED);
|
||||
}
|
||||
|
||||
-static int atmel_qspi_reg_sync(struct atmel_qspi *aq)
|
||||
-{
|
||||
- u32 val;
|
||||
- int ret;
|
||||
-
|
||||
- ret = readl_poll_timeout(aq->regs + QSPI_SR2, val,
|
||||
- !(val & QSPI_SR2_SYNCBSY), 40,
|
||||
- ATMEL_QSPI_SYNC_TIMEOUT);
|
||||
- return ret;
|
||||
-}
|
||||
-
|
||||
-static int atmel_qspi_update_config(struct atmel_qspi *aq)
|
||||
-{
|
||||
- int ret;
|
||||
-
|
||||
- ret = atmel_qspi_reg_sync(aq);
|
||||
- if (ret)
|
||||
- return ret;
|
||||
- atmel_qspi_write(QSPI_CR_UPDCFG, aq, QSPI_CR);
|
||||
- return atmel_qspi_reg_sync(aq);
|
||||
-}
|
||||
-
|
||||
static int atmel_qspi_sama7g5_set_cfg(struct atmel_qspi *aq,
|
||||
const struct spi_mem_op *op, u32 *offset)
|
||||
{
|
||||
@@ -720,18 +734,9 @@ static int atmel_qspi_sama7g5_set_cfg(st
|
||||
ifr |= QSPI_IFR_TFRTYP_MEM;
|
||||
}
|
||||
|
||||
- /*
|
||||
- * If the QSPI controller is set in regular SPI mode, set it in
|
||||
- * Serial Memory Mode (SMM).
|
||||
- */
|
||||
- if (aq->mr != QSPI_MR_SMM) {
|
||||
- atmel_qspi_write(QSPI_MR_SMM | QSPI_MR_DQSDLYEN, aq, QSPI_MR);
|
||||
- aq->mr = QSPI_MR_SMM;
|
||||
-
|
||||
- ret = atmel_qspi_update_config(aq);
|
||||
- if (ret)
|
||||
- return ret;
|
||||
- }
|
||||
+ ret = atmel_qspi_set_serial_memory_mode(aq);
|
||||
+ if (ret < 0)
|
||||
+ return ret;
|
||||
|
||||
/* Clear pending interrupts */
|
||||
(void)atmel_qspi_read(aq, QSPI_SR);
|
||||
@@ -1099,10 +1104,9 @@ static int atmel_qspi_sama7g5_init(struc
|
||||
}
|
||||
|
||||
/* Set the QSPI controller by default in Serial Memory Mode */
|
||||
- atmel_qspi_write(QSPI_MR_SMM | QSPI_MR_DQSDLYEN, aq, QSPI_MR);
|
||||
- aq->mr = QSPI_MR_SMM;
|
||||
- ret = atmel_qspi_update_config(aq);
|
||||
- if (ret)
|
||||
+ aq->mr |= QSPI_MR_DQSDLYEN;
|
||||
+ ret = atmel_qspi_set_serial_memory_mode(aq);
|
||||
+ if (ret < 0)
|
||||
return ret;
|
||||
|
||||
/* Enable the QSPI controller. */
|
||||
@@ -1223,8 +1227,9 @@ static int atmel_qspi_init(struct atmel_
|
||||
atmel_qspi_write(QSPI_CR_SWRST, aq, QSPI_CR);
|
||||
|
||||
/* Set the QSPI controller by default in Serial Memory Mode */
|
||||
- aq->mr |= QSPI_MR_SMM;
|
||||
- atmel_qspi_write(aq->mr, aq, QSPI_MR);
|
||||
+ ret = atmel_qspi_set_serial_memory_mode(aq);
|
||||
+ if (ret < 0)
|
||||
+ return ret;
|
||||
|
||||
/* Enable the QSPI controller */
|
||||
atmel_qspi_write(QSPI_CR_QSPIEN, aq, QSPI_CR);
|
||||
@ -0,0 +1,131 @@
|
||||
From 7c8bec1bb999e6f44e326fdf7157d5e37b748aca Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Bence=20Cs=C3=B3k=C3=A1s?= <csokas.bence@prolan.hu>
|
||||
Date: Thu, 19 Dec 2024 15:28:51 +0100
|
||||
Subject: [PATCH 100/112] spi: atmel-quadspi: Use devm_ clock management
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
Clean up error handling by using the new devm_
|
||||
clock handling functions. This should make it
|
||||
easier to add new code, as we can eliminate the
|
||||
"goto ladder" in probe().
|
||||
|
||||
Signed-off-by: Bence Csókás <csokas.bence@prolan.hu>
|
||||
Link: https://patch.msgid.link/20241219142851.430959-1-csokas.bence@prolan.hu
|
||||
Signed-off-by: Mark Brown <broonie@kernel.org>
|
||||
---
|
||||
drivers/spi/atmel-quadspi.c | 42 ++++++++++---------------------------
|
||||
1 file changed, 11 insertions(+), 31 deletions(-)
|
||||
|
||||
--- a/drivers/spi/atmel-quadspi.c
|
||||
+++ b/drivers/spi/atmel-quadspi.c
|
||||
@@ -1365,50 +1365,37 @@ static int atmel_qspi_probe(struct platf
|
||||
aq->mmap_phys_base = (dma_addr_t)res->start;
|
||||
|
||||
/* Get the peripheral clock */
|
||||
- aq->pclk = devm_clk_get(&pdev->dev, "pclk");
|
||||
+ aq->pclk = devm_clk_get_enabled(&pdev->dev, "pclk");
|
||||
if (IS_ERR(aq->pclk))
|
||||
- aq->pclk = devm_clk_get(&pdev->dev, NULL);
|
||||
+ aq->pclk = devm_clk_get_enabled(&pdev->dev, NULL);
|
||||
|
||||
if (IS_ERR(aq->pclk))
|
||||
return dev_err_probe(&pdev->dev, PTR_ERR(aq->pclk),
|
||||
"missing peripheral clock\n");
|
||||
|
||||
- /* Enable the peripheral clock */
|
||||
- err = clk_prepare_enable(aq->pclk);
|
||||
- if (err)
|
||||
- return dev_err_probe(&pdev->dev, err,
|
||||
- "failed to enable the peripheral clock\n");
|
||||
-
|
||||
if (aq->caps->has_qspick) {
|
||||
/* Get the QSPI system clock */
|
||||
- aq->qspick = devm_clk_get(&pdev->dev, "qspick");
|
||||
+ aq->qspick = devm_clk_get_enabled(&pdev->dev, "qspick");
|
||||
if (IS_ERR(aq->qspick)) {
|
||||
dev_err(&pdev->dev, "missing system clock\n");
|
||||
err = PTR_ERR(aq->qspick);
|
||||
- goto disable_pclk;
|
||||
+ return err;
|
||||
}
|
||||
|
||||
- /* Enable the QSPI system clock */
|
||||
- err = clk_prepare_enable(aq->qspick);
|
||||
- if (err) {
|
||||
- dev_err(&pdev->dev,
|
||||
- "failed to enable the QSPI system clock\n");
|
||||
- goto disable_pclk;
|
||||
- }
|
||||
} else if (aq->caps->has_gclk) {
|
||||
/* Get the QSPI generic clock */
|
||||
aq->gclk = devm_clk_get(&pdev->dev, "gclk");
|
||||
if (IS_ERR(aq->gclk)) {
|
||||
dev_err(&pdev->dev, "missing Generic clock\n");
|
||||
err = PTR_ERR(aq->gclk);
|
||||
- goto disable_pclk;
|
||||
+ return err;
|
||||
}
|
||||
}
|
||||
|
||||
if (aq->caps->has_dma) {
|
||||
err = atmel_qspi_dma_init(ctrl);
|
||||
if (err == -EPROBE_DEFER)
|
||||
- goto disable_qspick;
|
||||
+ return err;
|
||||
}
|
||||
|
||||
/* Request the IRQ */
|
||||
@@ -1448,10 +1435,6 @@ static int atmel_qspi_probe(struct platf
|
||||
dma_release:
|
||||
if (aq->caps->has_dma)
|
||||
atmel_qspi_dma_release(aq);
|
||||
-disable_qspick:
|
||||
- clk_disable_unprepare(aq->qspick);
|
||||
-disable_pclk:
|
||||
- clk_disable_unprepare(aq->pclk);
|
||||
|
||||
return err;
|
||||
}
|
||||
@@ -1490,7 +1473,6 @@ static int atmel_qspi_sama7g5_suspend(st
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
- clk_disable_unprepare(aq->pclk);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1515,8 +1497,6 @@ static void atmel_qspi_remove(struct pla
|
||||
}
|
||||
|
||||
atmel_qspi_write(QSPI_CR_QSPIDIS, aq, QSPI_CR);
|
||||
- clk_disable(aq->qspick);
|
||||
- clk_disable(aq->pclk);
|
||||
} else {
|
||||
/*
|
||||
* atmel_qspi_runtime_{suspend,resume} just disable and enable
|
||||
@@ -1526,9 +1506,6 @@ static void atmel_qspi_remove(struct pla
|
||||
dev_warn(&pdev->dev, "Failed to resume device on remove\n");
|
||||
}
|
||||
|
||||
- clk_unprepare(aq->qspick);
|
||||
- clk_unprepare(aq->pclk);
|
||||
-
|
||||
pm_runtime_disable(&pdev->dev);
|
||||
pm_runtime_dont_use_autosuspend(&pdev->dev);
|
||||
pm_runtime_put_noidle(&pdev->dev);
|
||||
@@ -1544,8 +1521,11 @@ static int __maybe_unused atmel_qspi_sus
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
- if (aq->caps->has_gclk)
|
||||
- return atmel_qspi_sama7g5_suspend(aq);
|
||||
+ if (aq->caps->has_gclk) {
|
||||
+ ret = atmel_qspi_sama7g5_suspend(aq);
|
||||
+ clk_disable_unprepare(aq->pclk);
|
||||
+ return ret;
|
||||
+ }
|
||||
|
||||
atmel_qspi_write(QSPI_CR_QSPIDIS, aq, QSPI_CR);
|
||||
|
||||
@ -0,0 +1,66 @@
|
||||
From 2eaa23a57b91442f98ae2c77ab1258a2bf0065b9 Mon Sep 17 00:00:00 2001
|
||||
From: Alexander Dahl <ada@thorsis.com>
|
||||
Date: Thu, 9 Jan 2025 10:48:43 +0100
|
||||
Subject: [PATCH 101/112] spi: atmel-quadspi: Update to current device naming
|
||||
terminology
|
||||
|
||||
For v6.9 the spi subsystem changed the terminology to host and target
|
||||
devices, see commit 99769a52464d ("spi: Update the "master/slave"
|
||||
terminology in documentation") for reference. Support for SAMA7G5 was
|
||||
forward ported recently from an old vendor branch before that
|
||||
terminology change, so naming for the new struct member is adapted to
|
||||
follow the current scheme.
|
||||
|
||||
Signed-off-by: Alexander Dahl <ada@thorsis.com>
|
||||
Link: https://patch.msgid.link/20250109094843.36014-1-ada@thorsis.com
|
||||
Signed-off-by: Mark Brown <broonie@kernel.org>
|
||||
---
|
||||
drivers/spi/atmel-quadspi.c | 12 ++++++------
|
||||
1 file changed, 6 insertions(+), 6 deletions(-)
|
||||
|
||||
--- a/drivers/spi/atmel-quadspi.c
|
||||
+++ b/drivers/spi/atmel-quadspi.c
|
||||
@@ -280,7 +280,7 @@ struct atmel_qspi {
|
||||
u32 irq_mask;
|
||||
u32 mr;
|
||||
u32 scr;
|
||||
- u32 slave_max_speed_hz;
|
||||
+ u32 target_max_speed_hz;
|
||||
struct completion cmd_completion;
|
||||
struct completion dma_completion;
|
||||
dma_addr_t mmap_phys_base;
|
||||
@@ -1041,7 +1041,7 @@ static int atmel_qspi_set_pad_calibratio
|
||||
|
||||
/* Refresh analogic blocks every 1 ms.*/
|
||||
atmel_qspi_write(FIELD_PREP(QSPI_REFRESH_DELAY_COUNTER,
|
||||
- aq->slave_max_speed_hz / 1000),
|
||||
+ aq->target_max_speed_hz / 1000),
|
||||
aq, QSPI_REFRESH);
|
||||
|
||||
return ret;
|
||||
@@ -1064,12 +1064,12 @@ static int atmel_qspi_set_gclk(struct at
|
||||
return ret;
|
||||
}
|
||||
|
||||
- if (aq->slave_max_speed_hz > QSPI_DLLCFG_THRESHOLD_FREQ)
|
||||
+ if (aq->target_max_speed_hz > QSPI_DLLCFG_THRESHOLD_FREQ)
|
||||
atmel_qspi_write(QSPI_DLLCFG_RANGE, aq, QSPI_DLLCFG);
|
||||
else
|
||||
atmel_qspi_write(0, aq, QSPI_DLLCFG);
|
||||
|
||||
- ret = clk_set_rate(aq->gclk, aq->slave_max_speed_hz);
|
||||
+ ret = clk_set_rate(aq->gclk, aq->target_max_speed_hz);
|
||||
if (ret) {
|
||||
dev_err(&aq->pdev->dev, "Failed to set generic clock rate.\n");
|
||||
return ret;
|
||||
@@ -1131,8 +1131,8 @@ static int atmel_qspi_sama7g5_setup(stru
|
||||
{
|
||||
struct atmel_qspi *aq = spi_controller_get_devdata(spi->controller);
|
||||
|
||||
- /* The controller can communicate with a single slave. */
|
||||
- aq->slave_max_speed_hz = spi->max_speed_hz;
|
||||
+ /* The controller can communicate with a single peripheral device (target). */
|
||||
+ aq->target_max_speed_hz = spi->max_speed_hz;
|
||||
|
||||
return atmel_qspi_sama7g5_init(aq);
|
||||
}
|
||||
@ -0,0 +1,34 @@
|
||||
From 9a39bca30a65f571fae33ac9c76e67ebca44b2a4 Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Bence=20Cs=C3=B3k=C3=A1s?= <csokas.bence@prolan.hu>
|
||||
Date: Mon, 3 Feb 2025 16:12:49 +0100
|
||||
Subject: [PATCH 102/112] spi: atmel-quadspi: Fix warning in doc-comment
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
The doc-comment for `struct atmel_qspi_pcal` had a typo in one of the
|
||||
struct members' name, causing a warning with the `W=1` option.
|
||||
|
||||
Fixes: 5af42209a4d2 ("spi: atmel-quadspi: Add support for sama7g5 QSPI")
|
||||
Reported-by: kernel test robot <lkp@intel.com>
|
||||
Closes: https://lore.kernel.org/oe-kbuild-all/202501311707.Ltj0qXse-lkp@intel.com/
|
||||
Signed-off-by: Bence Csókás <csokas.bence@prolan.hu>
|
||||
Link: https://patch.msgid.link/20250203151249.79876-2-csokas.bence@prolan.hu
|
||||
Signed-off-by: Mark Brown <broonie@kernel.org>
|
||||
---
|
||||
drivers/spi/atmel-quadspi.c | 4 ++--
|
||||
1 file changed, 2 insertions(+), 2 deletions(-)
|
||||
|
||||
--- a/drivers/spi/atmel-quadspi.c
|
||||
+++ b/drivers/spi/atmel-quadspi.c
|
||||
@@ -235,8 +235,8 @@
|
||||
/**
|
||||
* struct atmel_qspi_pcal - Pad Calibration Clock Division
|
||||
* @pclk_rate: peripheral clock rate.
|
||||
- * @pclkdiv: calibration clock division. The clock applied to the calibration
|
||||
- * cell is divided by pclkdiv + 1.
|
||||
+ * @pclk_div: calibration clock division. The clock applied to the calibration
|
||||
+ * cell is divided by pclk_div + 1.
|
||||
*/
|
||||
struct atmel_qspi_pcal {
|
||||
u32 pclk_rate;
|
||||
@ -0,0 +1,41 @@
|
||||
From 74a3cec06e0d0604d9e075e4976a9f434f112488 Mon Sep 17 00:00:00 2001
|
||||
From: Claudiu Beznea <claudiu.beznea@microchip.com>
|
||||
Date: Fri, 7 Feb 2025 13:21:45 +0100
|
||||
Subject: [PATCH 103/112] spi: atmel-quadspi: remove references to runtime PM
|
||||
on error path
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
There is no need to call runtime PM put APIs on error path of
|
||||
`atmel_qspi_sama7g5_transfer()` as the caller (`atmel_qspi_exec_op()`)
|
||||
of it will take care of this if needed.
|
||||
|
||||
Fixes: 5af42209a4d2 ("spi: atmel-quadspi: Add support for sama7g5 QSPI")
|
||||
Signed-off-by: Claudiu Beznea <claudiu.beznea@microchip.com>
|
||||
Signed-off-by: Durai Manickam KR <durai.manickamkr@microchip.com>
|
||||
Reported-by: Alexander Dahl <ada@thorsis.com>
|
||||
Closes: https://lore.kernel.org/linux-spi/20250109-carat-festivity-5f088e1add3c@thorsis.com/
|
||||
[ csokas.bence: Rebase and clarify msg, fix/add tags ]
|
||||
Signed-off-by: Bence Csókás <csokas.bence@prolan.hu>
|
||||
Link: https://patch.msgid.link/20250207122145.162183-2-csokas.bence@prolan.hu
|
||||
Signed-off-by: Mark Brown <broonie@kernel.org>
|
||||
---
|
||||
drivers/spi/atmel-quadspi.c | 5 +----
|
||||
1 file changed, 1 insertion(+), 4 deletions(-)
|
||||
|
||||
--- a/drivers/spi/atmel-quadspi.c
|
||||
+++ b/drivers/spi/atmel-quadspi.c
|
||||
@@ -930,11 +930,8 @@ static int atmel_qspi_sama7g5_transfer(s
|
||||
|
||||
/* Release the chip-select. */
|
||||
ret = atmel_qspi_reg_sync(aq);
|
||||
- if (ret) {
|
||||
- pm_runtime_mark_last_busy(&aq->pdev->dev);
|
||||
- pm_runtime_put_autosuspend(&aq->pdev->dev);
|
||||
+ if (ret)
|
||||
return ret;
|
||||
- }
|
||||
atmel_qspi_write(QSPI_CR_LASTXFER, aq, QSPI_CR);
|
||||
|
||||
return atmel_qspi_wait_for_completion(aq, QSPI_SR_CSRA);
|
||||
@ -0,0 +1,49 @@
|
||||
From c015516392a271e179e4f898908c402ec93ce13a Mon Sep 17 00:00:00 2001
|
||||
From: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
|
||||
Date: Thu, 1 May 2025 17:01:59 +0200
|
||||
Subject: [PATCH 104/112] spi: atmel-quadspi: Fix printed error code during DMA
|
||||
setup
|
||||
|
||||
On dma_request_chan() failure driver NULL-ifies the 'rx_chan' and
|
||||
immediately uses it as PTR_ERR() so dev_err_probe() prints incorrect
|
||||
error code. Rework the code so proper error code will be printed and
|
||||
NULL-ifying of 'rx_chan' will happen in common error handling block
|
||||
(failure of DMA setup is not fatal for the driver and further code
|
||||
depends on 'rx_chan' being non-NULL for DMA operations).
|
||||
|
||||
Reported by Smatch:
|
||||
drivers/spi/atmel-quadspi.c:1287 atmel_qspi_dma_init() warn: passing zero to 'PTR_ERR'
|
||||
|
||||
Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
|
||||
Link: https://patch.msgid.link/20250501-n-smatch-fixes-v2-1-d2ad9c1f2e67@linaro.org
|
||||
Signed-off-by: Mark Brown <broonie@kernel.org>
|
||||
---
|
||||
drivers/spi/atmel-quadspi.c | 9 +++++----
|
||||
1 file changed, 5 insertions(+), 4 deletions(-)
|
||||
|
||||
--- a/drivers/spi/atmel-quadspi.c
|
||||
+++ b/drivers/spi/atmel-quadspi.c
|
||||
@@ -1259,9 +1259,9 @@ static int atmel_qspi_dma_init(struct sp
|
||||
|
||||
aq->rx_chan = dma_request_chan(&aq->pdev->dev, "rx");
|
||||
if (IS_ERR(aq->rx_chan)) {
|
||||
- aq->rx_chan = NULL;
|
||||
- return dev_err_probe(&aq->pdev->dev, PTR_ERR(aq->rx_chan),
|
||||
- "RX DMA channel is not available\n");
|
||||
+ ret = dev_err_probe(&aq->pdev->dev, PTR_ERR(aq->rx_chan),
|
||||
+ "RX DMA channel is not available\n");
|
||||
+ goto null_rx_chan;
|
||||
}
|
||||
|
||||
aq->tx_chan = dma_request_chan(&aq->pdev->dev, "tx");
|
||||
@@ -1282,8 +1282,9 @@ static int atmel_qspi_dma_init(struct sp
|
||||
|
||||
release_rx_chan:
|
||||
dma_release_channel(aq->rx_chan);
|
||||
- aq->rx_chan = NULL;
|
||||
aq->tx_chan = NULL;
|
||||
+null_rx_chan:
|
||||
+ aq->rx_chan = NULL;
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -0,0 +1,62 @@
|
||||
From e56d9480ea806b1d92d16b882c40e7216f2cf2f2 Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Bence=20Cs=C3=B3k=C3=A1s?= <csokas.bence@prolan.hu>
|
||||
Date: Thu, 27 Mar 2025 20:59:27 +0100
|
||||
Subject: [PATCH 106/112] spi: atmel-quadspi: Fix unbalanced pm_runtime by
|
||||
using devm_ API
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
Fix unbalanced PM in error path of `atmel_qspi_probe()`
|
||||
by using `devm_pm_runtime_*()` functions.
|
||||
|
||||
Reported-by: Alexander Dahl <ada@thorsis.com>
|
||||
Closes: https://lore.kernel.org/linux-spi/20250110-paycheck-irregular-bcddab1276c7@thorsis.com/
|
||||
Fixes: 5af42209a4d2 ("spi: atmel-quadspi: Add support for sama7g5 QSPI")
|
||||
Signed-off-by: Bence Csókás <csokas.bence@prolan.hu>
|
||||
Link: https://patch.msgid.link/20250327195928.680771-4-csokas.bence@prolan.hu
|
||||
Signed-off-by: Mark Brown <broonie@kernel.org>
|
||||
---
|
||||
drivers/spi/atmel-quadspi.c | 17 ++++-------------
|
||||
1 file changed, 4 insertions(+), 13 deletions(-)
|
||||
|
||||
--- a/drivers/spi/atmel-quadspi.c
|
||||
+++ b/drivers/spi/atmel-quadspi.c
|
||||
@@ -1409,22 +1409,17 @@ static int atmel_qspi_probe(struct platf
|
||||
|
||||
pm_runtime_set_autosuspend_delay(&pdev->dev, 500);
|
||||
pm_runtime_use_autosuspend(&pdev->dev);
|
||||
- pm_runtime_set_active(&pdev->dev);
|
||||
- pm_runtime_enable(&pdev->dev);
|
||||
- pm_runtime_get_noresume(&pdev->dev);
|
||||
+ devm_pm_runtime_set_active_enabled(&pdev->dev);
|
||||
+ devm_pm_runtime_get_noresume(&pdev->dev);
|
||||
|
||||
err = atmel_qspi_init(aq);
|
||||
if (err)
|
||||
goto dma_release;
|
||||
|
||||
err = spi_register_controller(ctrl);
|
||||
- if (err) {
|
||||
- pm_runtime_put_noidle(&pdev->dev);
|
||||
- pm_runtime_disable(&pdev->dev);
|
||||
- pm_runtime_set_suspended(&pdev->dev);
|
||||
- pm_runtime_dont_use_autosuspend(&pdev->dev);
|
||||
+ if (err)
|
||||
goto dma_release;
|
||||
- }
|
||||
+
|
||||
pm_runtime_mark_last_busy(&pdev->dev);
|
||||
pm_runtime_put_autosuspend(&pdev->dev);
|
||||
|
||||
@@ -1503,10 +1498,6 @@ static void atmel_qspi_remove(struct pla
|
||||
*/
|
||||
dev_warn(&pdev->dev, "Failed to resume device on remove\n");
|
||||
}
|
||||
-
|
||||
- pm_runtime_disable(&pdev->dev);
|
||||
- pm_runtime_dont_use_autosuspend(&pdev->dev);
|
||||
- pm_runtime_put_noidle(&pdev->dev);
|
||||
}
|
||||
|
||||
static int __maybe_unused atmel_qspi_suspend(struct device *dev)
|
||||
@ -0,0 +1,81 @@
|
||||
From 92da9095958114aca94d7ab0c8fa76ee556d412d Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Bence=20Cs=C3=B3k=C3=A1s?= <csokas.bence@prolan.hu>
|
||||
Date: Tue, 10 Jun 2025 10:22:53 +0200
|
||||
Subject: [PATCH 107/112] dmaengine: Add devm_dma_request_chan()
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
Expand the arsenal of devm functions for DMA devices, this time for
|
||||
requesting channels.
|
||||
|
||||
Signed-off-by: Bence Csókás <csokas.bence@prolan.hu>
|
||||
Link: https://lore.kernel.org/r/20250610082256.400492-2-csokas.bence@prolan.hu
|
||||
Signed-off-by: Vinod Koul <vkoul@kernel.org>
|
||||
---
|
||||
drivers/dma/dmaengine.c | 30 ++++++++++++++++++++++++++++++
|
||||
include/linux/dmaengine.h | 7 +++++++
|
||||
2 files changed, 37 insertions(+)
|
||||
|
||||
--- a/drivers/dma/dmaengine.c
|
||||
+++ b/drivers/dma/dmaengine.c
|
||||
@@ -926,6 +926,36 @@ void dma_release_channel(struct dma_chan
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(dma_release_channel);
|
||||
|
||||
+static void dmaenginem_release_channel(void *chan)
|
||||
+{
|
||||
+ dma_release_channel(chan);
|
||||
+}
|
||||
+
|
||||
+/**
|
||||
+ * devm_dma_request_chan - try to allocate an exclusive slave channel
|
||||
+ * @dev: pointer to client device structure
|
||||
+ * @name: slave channel name
|
||||
+ *
|
||||
+ * Returns pointer to appropriate DMA channel on success or an error pointer.
|
||||
+ *
|
||||
+ * The operation is managed and will be undone on driver detach.
|
||||
+ */
|
||||
+
|
||||
+struct dma_chan *devm_dma_request_chan(struct device *dev, const char *name)
|
||||
+{
|
||||
+ struct dma_chan *chan = dma_request_chan(dev, name);
|
||||
+ int ret = 0;
|
||||
+
|
||||
+ if (!IS_ERR(chan))
|
||||
+ ret = devm_add_action_or_reset(dev, dmaenginem_release_channel, chan);
|
||||
+
|
||||
+ if (ret)
|
||||
+ return ERR_PTR(ret);
|
||||
+
|
||||
+ return chan;
|
||||
+}
|
||||
+EXPORT_SYMBOL_GPL(devm_dma_request_chan);
|
||||
+
|
||||
/**
|
||||
* dmaengine_get - register interest in dma_channels
|
||||
*/
|
||||
--- a/include/linux/dmaengine.h
|
||||
+++ b/include/linux/dmaengine.h
|
||||
@@ -1521,6 +1521,7 @@ struct dma_chan *__dma_request_channel(c
|
||||
|
||||
struct dma_chan *dma_request_chan(struct device *dev, const char *name);
|
||||
struct dma_chan *dma_request_chan_by_mask(const dma_cap_mask_t *mask);
|
||||
+struct dma_chan *devm_dma_request_chan(struct device *dev, const char *name);
|
||||
|
||||
void dma_release_channel(struct dma_chan *chan);
|
||||
int dma_get_slave_caps(struct dma_chan *chan, struct dma_slave_caps *caps);
|
||||
@@ -1557,6 +1558,12 @@ static inline struct dma_chan *dma_reque
|
||||
{
|
||||
return ERR_PTR(-ENODEV);
|
||||
}
|
||||
+
|
||||
+static inline struct dma_chan *devm_dma_request_chan(struct device *dev, const char *name)
|
||||
+{
|
||||
+ return ERR_PTR(-ENODEV);
|
||||
+}
|
||||
+
|
||||
static inline void dma_release_channel(struct dma_chan *chan)
|
||||
{
|
||||
}
|
||||
@ -0,0 +1,122 @@
|
||||
From 4b031c48133b762ef9bb6cb40b9ec040acaef970 Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Bence=20Cs=C3=B3k=C3=A1s?= <csokas.bence@prolan.hu>
|
||||
Date: Tue, 10 Jun 2025 10:22:54 +0200
|
||||
Subject: [PATCH 108/112] spi: atmel-quadspi: Use `devm_dma_request_chan()`
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
Leave releasing of DMA channels up to the devm facilities. This way we can
|
||||
eliminate the rest of the "goto ladder".
|
||||
|
||||
Signed-off-by: Bence Csókás <csokas.bence@prolan.hu>
|
||||
Link: https://patch.msgid.link/20250610082256.400492-3-csokas.bence@prolan.hu
|
||||
Signed-off-by: Mark Brown <broonie@kernel.org>
|
||||
---
|
||||
drivers/spi/atmel-quadspi.c | 48 ++++++++++---------------------------
|
||||
1 file changed, 13 insertions(+), 35 deletions(-)
|
||||
|
||||
--- a/drivers/spi/atmel-quadspi.c
|
||||
+++ b/drivers/spi/atmel-quadspi.c
|
||||
@@ -1257,18 +1257,21 @@ static int atmel_qspi_dma_init(struct sp
|
||||
struct atmel_qspi *aq = spi_controller_get_devdata(ctrl);
|
||||
int ret;
|
||||
|
||||
- aq->rx_chan = dma_request_chan(&aq->pdev->dev, "rx");
|
||||
+ aq->rx_chan = devm_dma_request_chan(&aq->pdev->dev, "rx");
|
||||
if (IS_ERR(aq->rx_chan)) {
|
||||
ret = dev_err_probe(&aq->pdev->dev, PTR_ERR(aq->rx_chan),
|
||||
"RX DMA channel is not available\n");
|
||||
- goto null_rx_chan;
|
||||
+ aq->rx_chan = NULL;
|
||||
+ return ret;
|
||||
}
|
||||
|
||||
- aq->tx_chan = dma_request_chan(&aq->pdev->dev, "tx");
|
||||
+ aq->tx_chan = devm_dma_request_chan(&aq->pdev->dev, "tx");
|
||||
if (IS_ERR(aq->tx_chan)) {
|
||||
ret = dev_err_probe(&aq->pdev->dev, PTR_ERR(aq->tx_chan),
|
||||
"TX DMA channel is not available\n");
|
||||
- goto release_rx_chan;
|
||||
+ aq->rx_chan = NULL;
|
||||
+ aq->tx_chan = NULL;
|
||||
+ return ret;
|
||||
}
|
||||
|
||||
ctrl->dma_rx = aq->rx_chan;
|
||||
@@ -1279,21 +1282,6 @@ static int atmel_qspi_dma_init(struct sp
|
||||
dma_chan_name(aq->tx_chan), dma_chan_name(aq->rx_chan));
|
||||
|
||||
return 0;
|
||||
-
|
||||
-release_rx_chan:
|
||||
- dma_release_channel(aq->rx_chan);
|
||||
- aq->tx_chan = NULL;
|
||||
-null_rx_chan:
|
||||
- aq->rx_chan = NULL;
|
||||
- return ret;
|
||||
-}
|
||||
-
|
||||
-static void atmel_qspi_dma_release(struct atmel_qspi *aq)
|
||||
-{
|
||||
- if (aq->rx_chan)
|
||||
- dma_release_channel(aq->rx_chan);
|
||||
- if (aq->tx_chan)
|
||||
- dma_release_channel(aq->tx_chan);
|
||||
}
|
||||
|
||||
static const struct atmel_qspi_ops atmel_qspi_ops = {
|
||||
@@ -1398,14 +1386,13 @@ static int atmel_qspi_probe(struct platf
|
||||
|
||||
/* Request the IRQ */
|
||||
irq = platform_get_irq(pdev, 0);
|
||||
- if (irq < 0) {
|
||||
- err = irq;
|
||||
- goto dma_release;
|
||||
- }
|
||||
+ if (irq < 0)
|
||||
+ return irq;
|
||||
+
|
||||
err = devm_request_irq(&pdev->dev, irq, atmel_qspi_interrupt,
|
||||
0, dev_name(&pdev->dev), aq);
|
||||
if (err)
|
||||
- goto dma_release;
|
||||
+ return err;
|
||||
|
||||
pm_runtime_set_autosuspend_delay(&pdev->dev, 500);
|
||||
pm_runtime_use_autosuspend(&pdev->dev);
|
||||
@@ -1414,22 +1401,16 @@ static int atmel_qspi_probe(struct platf
|
||||
|
||||
err = atmel_qspi_init(aq);
|
||||
if (err)
|
||||
- goto dma_release;
|
||||
+ return err;
|
||||
|
||||
err = spi_register_controller(ctrl);
|
||||
if (err)
|
||||
- goto dma_release;
|
||||
+ return err;
|
||||
|
||||
pm_runtime_mark_last_busy(&pdev->dev);
|
||||
pm_runtime_put_autosuspend(&pdev->dev);
|
||||
|
||||
return 0;
|
||||
-
|
||||
-dma_release:
|
||||
- if (aq->caps->has_dma)
|
||||
- atmel_qspi_dma_release(aq);
|
||||
-
|
||||
- return err;
|
||||
}
|
||||
|
||||
static int atmel_qspi_sama7g5_suspend(struct atmel_qspi *aq)
|
||||
@@ -1479,9 +1460,6 @@ static void atmel_qspi_remove(struct pla
|
||||
|
||||
ret = pm_runtime_get_sync(&pdev->dev);
|
||||
if (ret >= 0) {
|
||||
- if (aq->caps->has_dma)
|
||||
- atmel_qspi_dma_release(aq);
|
||||
-
|
||||
if (aq->caps->has_gclk) {
|
||||
ret = atmel_qspi_sama7g5_suspend(aq);
|
||||
if (ret)
|
||||
@ -0,0 +1,178 @@
|
||||
From 0f52d98240cdce03944c967d4fe4faab032f8f57 Mon Sep 17 00:00:00 2001
|
||||
From: Varshini Rajendran <varshini.rajendran@microchip.com>
|
||||
Date: Mon, 8 Sep 2025 09:44:18 +0530
|
||||
Subject: [PATCH 109/112] spi: atmel-quadspi: add padcalib, 2xgclk, and dllon
|
||||
capabilities
|
||||
|
||||
Introduce capability flags for SoC-specific variations of the QuadSPI
|
||||
controller:
|
||||
|
||||
- has_padcalib: controller supports pad calibration
|
||||
- has_2xgclk: requires GCLK at half the data rate (2x clocking)
|
||||
- has_dllon: controller supports DLL clock
|
||||
|
||||
Set `has_padcalib` for Octal controllers that provide pad calibration
|
||||
support. Use `has_2xgclk` for controllers that require the GCLK to run
|
||||
at twice the data rate. Differentiate SoC integration variants with the
|
||||
`has_dllon` flag and set it as needed.
|
||||
|
||||
Signed-off-by: Varshini Rajendran <varshini.rajendran@microchip.com>
|
||||
Signed-off-by: Dharma Balasubiramani <dharma.b@microchip.com>
|
||||
Link: https://patch.msgid.link/20250908-microchip-qspi-v2-3-8f3d69fdd5c9@microchip.com
|
||||
Signed-off-by: Mark Brown <broonie@kernel.org>
|
||||
---
|
||||
drivers/spi/atmel-quadspi.c | 92 ++++++++++++++++++++++++-------------
|
||||
1 file changed, 60 insertions(+), 32 deletions(-)
|
||||
|
||||
--- a/drivers/spi/atmel-quadspi.c
|
||||
+++ b/drivers/spi/atmel-quadspi.c
|
||||
@@ -262,6 +262,9 @@ struct atmel_qspi_caps {
|
||||
bool has_ricr;
|
||||
bool octal;
|
||||
bool has_dma;
|
||||
+ bool has_2xgclk;
|
||||
+ bool has_padcalib;
|
||||
+ bool has_dllon;
|
||||
};
|
||||
|
||||
struct atmel_qspi_ops;
|
||||
@@ -1028,13 +1031,25 @@ static int atmel_qspi_set_pad_calibratio
|
||||
aq, QSPI_PCALCFG);
|
||||
|
||||
/* DLL On + start calibration. */
|
||||
- atmel_qspi_write(QSPI_CR_DLLON | QSPI_CR_STPCAL, aq, QSPI_CR);
|
||||
+ if (aq->caps->has_dllon)
|
||||
+ atmel_qspi_write(QSPI_CR_DLLON | QSPI_CR_STPCAL, aq, QSPI_CR);
|
||||
+ /* If there is no DLL support only start calibration. */
|
||||
+ else
|
||||
+ atmel_qspi_write(QSPI_CR_STPCAL, aq, QSPI_CR);
|
||||
|
||||
- /* Check synchronization status before updating configuration. */
|
||||
- ret = readl_poll_timeout(aq->regs + QSPI_SR2, val,
|
||||
- (val & QSPI_SR2_DLOCK) &&
|
||||
- !(val & QSPI_SR2_CALBSY), 40,
|
||||
- ATMEL_QSPI_TIMEOUT);
|
||||
+ /*
|
||||
+ * Check DLL clock lock and synchronization status before updating
|
||||
+ * configuration.
|
||||
+ */
|
||||
+ if (aq->caps->has_dllon)
|
||||
+ ret = readl_poll_timeout(aq->regs + QSPI_SR2, val,
|
||||
+ (val & QSPI_SR2_DLOCK) &&
|
||||
+ !(val & QSPI_SR2_CALBSY), 40,
|
||||
+ ATMEL_QSPI_TIMEOUT);
|
||||
+ else
|
||||
+ ret = readl_poll_timeout(aq->regs + QSPI_SR2, val,
|
||||
+ !(val & QSPI_SR2_CALBSY), 40,
|
||||
+ ATMEL_QSPI_TIMEOUT);
|
||||
|
||||
/* Refresh analogic blocks every 1 ms.*/
|
||||
atmel_qspi_write(FIELD_PREP(QSPI_REFRESH_DELAY_COUNTER,
|
||||
@@ -1050,23 +1065,28 @@ static int atmel_qspi_set_gclk(struct at
|
||||
int ret;
|
||||
|
||||
/* Disable DLL before setting GCLK */
|
||||
- status = atmel_qspi_read(aq, QSPI_SR2);
|
||||
- if (status & QSPI_SR2_DLOCK) {
|
||||
- atmel_qspi_write(QSPI_CR_DLLOFF, aq, QSPI_CR);
|
||||
+ if (aq->caps->has_dllon) {
|
||||
+ status = atmel_qspi_read(aq, QSPI_SR2);
|
||||
+ if (status & QSPI_SR2_DLOCK) {
|
||||
+ atmel_qspi_write(QSPI_CR_DLLOFF, aq, QSPI_CR);
|
||||
+ ret = readl_poll_timeout(aq->regs + QSPI_SR2, val,
|
||||
+ !(val & QSPI_SR2_DLOCK), 40,
|
||||
+ ATMEL_QSPI_TIMEOUT);
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+ }
|
||||
|
||||
- ret = readl_poll_timeout(aq->regs + QSPI_SR2, val,
|
||||
- !(val & QSPI_SR2_DLOCK), 40,
|
||||
- ATMEL_QSPI_TIMEOUT);
|
||||
- if (ret)
|
||||
- return ret;
|
||||
+ if (aq->target_max_speed_hz > QSPI_DLLCFG_THRESHOLD_FREQ)
|
||||
+ atmel_qspi_write(QSPI_DLLCFG_RANGE, aq, QSPI_DLLCFG);
|
||||
+ else
|
||||
+ atmel_qspi_write(0, aq, QSPI_DLLCFG);
|
||||
}
|
||||
|
||||
- if (aq->target_max_speed_hz > QSPI_DLLCFG_THRESHOLD_FREQ)
|
||||
- atmel_qspi_write(QSPI_DLLCFG_RANGE, aq, QSPI_DLLCFG);
|
||||
+ if (aq->caps->has_2xgclk)
|
||||
+ ret = clk_set_rate(aq->gclk, 2 * aq->target_max_speed_hz);
|
||||
else
|
||||
- atmel_qspi_write(0, aq, QSPI_DLLCFG);
|
||||
+ ret = clk_set_rate(aq->gclk, aq->target_max_speed_hz);
|
||||
|
||||
- ret = clk_set_rate(aq->gclk, aq->target_max_speed_hz);
|
||||
if (ret) {
|
||||
dev_err(&aq->pdev->dev, "Failed to set generic clock rate.\n");
|
||||
return ret;
|
||||
@@ -1089,11 +1109,16 @@ static int atmel_qspi_sama7g5_init(struc
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
- if (aq->caps->octal) {
|
||||
+ /*
|
||||
+ * Check if the SoC supports pad calibration in Octal SPI mode.
|
||||
+ * Proceed only if both the capabilities are true.
|
||||
+ */
|
||||
+ if (aq->caps->octal && aq->caps->has_padcalib) {
|
||||
ret = atmel_qspi_set_pad_calibration(aq);
|
||||
if (ret)
|
||||
return ret;
|
||||
- } else {
|
||||
+ /* Start DLL on only if the SoC supports the same */
|
||||
+ } else if (aq->caps->has_dllon) {
|
||||
atmel_qspi_write(QSPI_CR_DLLON, aq, QSPI_CR);
|
||||
ret = readl_poll_timeout(aq->regs + QSPI_SR2, val,
|
||||
(val & QSPI_SR2_DLOCK), 40,
|
||||
@@ -1434,19 +1459,19 @@ static int atmel_qspi_sama7g5_suspend(st
|
||||
|
||||
clk_disable_unprepare(aq->gclk);
|
||||
|
||||
- atmel_qspi_write(QSPI_CR_DLLOFF, aq, QSPI_CR);
|
||||
- ret = readl_poll_timeout(aq->regs + QSPI_SR2, val,
|
||||
- !(val & QSPI_SR2_DLOCK), 40,
|
||||
- ATMEL_QSPI_TIMEOUT);
|
||||
- if (ret)
|
||||
- return ret;
|
||||
-
|
||||
- ret = readl_poll_timeout(aq->regs + QSPI_SR2, val,
|
||||
- !(val & QSPI_SR2_CALBSY), 40,
|
||||
- ATMEL_QSPI_TIMEOUT);
|
||||
- if (ret)
|
||||
- return ret;
|
||||
+ if (aq->caps->has_dllon) {
|
||||
+ atmel_qspi_write(QSPI_CR_DLLOFF, aq, QSPI_CR);
|
||||
+ ret = readl_poll_timeout(aq->regs + QSPI_SR2, val,
|
||||
+ !(val & QSPI_SR2_DLOCK), 40,
|
||||
+ ATMEL_QSPI_TIMEOUT);
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+ }
|
||||
|
||||
+ if (aq->caps->has_padcalib)
|
||||
+ return readl_poll_timeout(aq->regs + QSPI_SR2, val,
|
||||
+ !(val & QSPI_SR2_CALBSY), 40,
|
||||
+ ATMEL_QSPI_TIMEOUT);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1584,12 +1609,15 @@ static const struct atmel_qspi_caps atme
|
||||
.has_gclk = true,
|
||||
.octal = true,
|
||||
.has_dma = true,
|
||||
+ .has_padcalib = true,
|
||||
+ .has_dllon = true,
|
||||
};
|
||||
|
||||
static const struct atmel_qspi_caps atmel_sama7g5_qspi_caps = {
|
||||
.max_speed_hz = SAMA7G5_QSPI1_SDR_MAX_SPEED_HZ,
|
||||
.has_gclk = true,
|
||||
.has_dma = true,
|
||||
+ .has_dllon = true,
|
||||
};
|
||||
|
||||
static const struct of_device_id atmel_qspi_dt_ids[] = {
|
||||
@ -0,0 +1,58 @@
|
||||
From ea6e579557cf85f3b0ed3c94c3e4d69afbcba46c Mon Sep 17 00:00:00 2001
|
||||
From: Varshini Rajendran <varshini.rajendran@microchip.com>
|
||||
Date: Mon, 8 Sep 2025 09:44:19 +0530
|
||||
Subject: [PATCH 110/112] spi: atmel-quadspi: add support for SAM9X7 QSPI
|
||||
controller
|
||||
|
||||
Add support for the QuadSPI controller found on the SAM9X7 SoC.
|
||||
|
||||
This controller does not implement pad calibration. It supports
|
||||
operation up to 100 MHz, and requires the GCK to run at twice
|
||||
the data rate.
|
||||
|
||||
Signed-off-by: Varshini Rajendran <varshini.rajendran@microchip.com>
|
||||
Signed-off-by: Dharma Balasubiramani <dharma.b@microchip.com>
|
||||
Link: https://patch.msgid.link/20250908-microchip-qspi-v2-4-8f3d69fdd5c9@microchip.com
|
||||
Signed-off-by: Mark Brown <broonie@kernel.org>
|
||||
---
|
||||
drivers/spi/atmel-quadspi.c | 15 +++++++++++++++
|
||||
1 file changed, 15 insertions(+)
|
||||
|
||||
--- a/drivers/spi/atmel-quadspi.c
|
||||
+++ b/drivers/spi/atmel-quadspi.c
|
||||
@@ -63,6 +63,7 @@
|
||||
|
||||
#define SAMA7G5_QSPI0_MAX_SPEED_HZ 200000000
|
||||
#define SAMA7G5_QSPI1_SDR_MAX_SPEED_HZ 133000000
|
||||
+#define SAM9X7_QSPI_MAX_SPEED_HZ 100000000
|
||||
|
||||
/* Bitfields in QSPI_CR (Control Register) */
|
||||
#define QSPI_CR_QSPIEN BIT(0)
|
||||
@@ -1604,6 +1605,16 @@ static const struct atmel_qspi_caps atme
|
||||
.has_ricr = true,
|
||||
};
|
||||
|
||||
+static const struct atmel_qspi_caps atmel_sam9x7_ospi_caps = {
|
||||
+ .max_speed_hz = SAM9X7_QSPI_MAX_SPEED_HZ,
|
||||
+ .has_gclk = true,
|
||||
+ .octal = true,
|
||||
+ .has_dma = true,
|
||||
+ .has_2xgclk = true,
|
||||
+ .has_padcalib = false,
|
||||
+ .has_dllon = false,
|
||||
+};
|
||||
+
|
||||
static const struct atmel_qspi_caps atmel_sama7g5_ospi_caps = {
|
||||
.max_speed_hz = SAMA7G5_QSPI0_MAX_SPEED_HZ,
|
||||
.has_gclk = true,
|
||||
@@ -1637,6 +1648,10 @@ static const struct of_device_id atmel_q
|
||||
.compatible = "microchip,sama7g5-qspi",
|
||||
.data = &atmel_sama7g5_qspi_caps,
|
||||
},
|
||||
+ {
|
||||
+ .compatible = "microchip,sam9x7-ospi",
|
||||
+ .data = &atmel_sam9x7_ospi_caps,
|
||||
+ },
|
||||
|
||||
{ /* sentinel */ }
|
||||
};
|
||||
@ -0,0 +1,57 @@
|
||||
From f157bc4635178eccb282031d7c2ba2867bd3274c Mon Sep 17 00:00:00 2001
|
||||
From: Varshini Rajendran <varshini.rajendran@microchip.com>
|
||||
Date: Mon, 8 Sep 2025 09:44:20 +0530
|
||||
Subject: [PATCH 111/112] spi: atmel-quadspi: Add support for sama7d65 QSPI
|
||||
|
||||
Add support for sama7d65 QSPI controller and define its caps.
|
||||
|
||||
Signed-off-by: Varshini Rajendran <varshini.rajendran@microchip.com>
|
||||
Link: https://patch.msgid.link/20250908-microchip-qspi-v2-5-8f3d69fdd5c9@microchip.com
|
||||
Signed-off-by: Mark Brown <broonie@kernel.org>
|
||||
---
|
||||
drivers/spi/atmel-quadspi.c | 27 +++++++++++++++++++++++++++
|
||||
1 file changed, 27 insertions(+)
|
||||
|
||||
--- a/drivers/spi/atmel-quadspi.c
|
||||
+++ b/drivers/spi/atmel-quadspi.c
|
||||
@@ -1615,6 +1615,24 @@ static const struct atmel_qspi_caps atme
|
||||
.has_dllon = false,
|
||||
};
|
||||
|
||||
+static const struct atmel_qspi_caps atmel_sama7d65_ospi_caps = {
|
||||
+ .max_speed_hz = SAMA7G5_QSPI0_MAX_SPEED_HZ,
|
||||
+ .has_gclk = true,
|
||||
+ .octal = true,
|
||||
+ .has_dma = true,
|
||||
+ .has_2xgclk = true,
|
||||
+ .has_padcalib = true,
|
||||
+ .has_dllon = false,
|
||||
+};
|
||||
+
|
||||
+static const struct atmel_qspi_caps atmel_sama7d65_qspi_caps = {
|
||||
+ .max_speed_hz = SAMA7G5_QSPI1_SDR_MAX_SPEED_HZ,
|
||||
+ .has_gclk = true,
|
||||
+ .has_dma = true,
|
||||
+ .has_2xgclk = true,
|
||||
+ .has_dllon = false,
|
||||
+};
|
||||
+
|
||||
static const struct atmel_qspi_caps atmel_sama7g5_ospi_caps = {
|
||||
.max_speed_hz = SAMA7G5_QSPI0_MAX_SPEED_HZ,
|
||||
.has_gclk = true,
|
||||
@@ -1652,6 +1670,15 @@ static const struct of_device_id atmel_q
|
||||
.compatible = "microchip,sam9x7-ospi",
|
||||
.data = &atmel_sam9x7_ospi_caps,
|
||||
},
|
||||
+ {
|
||||
+ .compatible = "microchip,sama7d65-ospi",
|
||||
+ .data = &atmel_sama7d65_ospi_caps,
|
||||
+ },
|
||||
+ {
|
||||
+ .compatible = "microchip,sama7d65-qspi",
|
||||
+ .data = &atmel_sama7d65_qspi_caps,
|
||||
+ },
|
||||
+
|
||||
|
||||
{ /* sentinel */ }
|
||||
};
|
||||
@ -0,0 +1,137 @@
|
||||
From c9d1b0b54258ba13b567dd116ead3c7c30cba7d8 Mon Sep 17 00:00:00 2001
|
||||
From: Daniel Machon <daniel.machon@microchip.com>
|
||||
Date: Fri, 3 Oct 2025 14:35:59 +0200
|
||||
Subject: [PATCH] net: sparx5/lan969x: fix flooding configuration on bridge
|
||||
join/leave
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
The sparx5 driver programs UC/MC/BC flooding in sparx5_update_fwd() by
|
||||
unconditionally applying bridge_fwd_mask to all flood PGIDs. Any bridge
|
||||
topology change that triggers sparx5_update_fwd() (for example enslaving
|
||||
another port) therefore reinstalls flooding in hardware for already
|
||||
bridged ports, regardless of their per-port flood flags.
|
||||
|
||||
This results in clobbering of the flood masks, and desynchronization
|
||||
between software and hardware: the bridge still reports “flood off” for
|
||||
the port, but hardware has flooding enabled due to unconditional PGID
|
||||
reprogramming.
|
||||
|
||||
Steps to reproduce:
|
||||
|
||||
$ ip link add br0 type bridge
|
||||
$ ip link set br0 up
|
||||
$ ip link set eth0 master br0
|
||||
$ ip link set eth0 up
|
||||
$ bridge link set dev eth0 flood off
|
||||
$ ip link set eth1 master br0
|
||||
$ ip link set eth1 up
|
||||
|
||||
At this point, flooding is silently re-enabled for eth0. Software still
|
||||
shows “flood off” for eth0, but hardware has flooding enabled.
|
||||
|
||||
To fix this, flooding is now set explicitly during bridge join/leave,
|
||||
through sparx5_port_attr_bridge_flags():
|
||||
|
||||
On bridge join, UC/MC/BC flooding is enabled by default.
|
||||
|
||||
On bridge leave, UC/MC/BC flooding is disabled.
|
||||
|
||||
sparx5_update_fwd() no longer touches the flood PGIDs, clobbering
|
||||
the flood masks, and desynchronizing software and hardware.
|
||||
|
||||
Initialization of the flooding PGIDs have been moved to
|
||||
sparx5_start(). This is required as flooding PGIDs defaults to
|
||||
0x3fffffff in hardware and the initialization was previously handled
|
||||
in sparx5_update_fwd(), which was removed.
|
||||
|
||||
With this change, user-configured flooding flags persist across bridge
|
||||
updates and are no longer overridden by sparx5_update_fwd().
|
||||
|
||||
Fixes: d6fce5141929 ("net: sparx5: add switching support")
|
||||
Signed-off-by: Daniel Machon <daniel.machon@microchip.com>
|
||||
Reviewed-by: Simon Horman <horms@kernel.org>
|
||||
Link: https://patch.msgid.link/20251003-fix-flood-fwd-v1-1-48eb478b2904@microchip.com
|
||||
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
|
||||
---
|
||||
drivers/net/ethernet/microchip/sparx5/sparx5_main.c | 5 +++++
|
||||
.../net/ethernet/microchip/sparx5/sparx5_switchdev.c | 12 ++++++++++++
|
||||
drivers/net/ethernet/microchip/sparx5/sparx5_vlan.c | 10 ----------
|
||||
3 files changed, 17 insertions(+), 10 deletions(-)
|
||||
|
||||
--- a/drivers/net/ethernet/microchip/sparx5/sparx5_main.c
|
||||
+++ b/drivers/net/ethernet/microchip/sparx5/sparx5_main.c
|
||||
@@ -709,6 +709,11 @@ static int sparx5_start(struct sparx5 *s
|
||||
/* Init masks */
|
||||
sparx5_update_fwd(sparx5);
|
||||
|
||||
+ /* Init flood masks */
|
||||
+ for (int pgid = sparx5_get_pgid(sparx5, PGID_UC_FLOOD);
|
||||
+ pgid <= sparx5_get_pgid(sparx5, PGID_BCAST); pgid++)
|
||||
+ sparx5_pgid_clear(sparx5, pgid);
|
||||
+
|
||||
/* CPU copy CPU pgids */
|
||||
spx5_wr(ANA_AC_PGID_MISC_CFG_PGID_CPU_COPY_ENA_SET(1), sparx5,
|
||||
ANA_AC_PGID_MISC_CFG(sparx5_get_pgid(sparx5, PGID_CPU)));
|
||||
--- a/drivers/net/ethernet/microchip/sparx5/sparx5_switchdev.c
|
||||
+++ b/drivers/net/ethernet/microchip/sparx5/sparx5_switchdev.c
|
||||
@@ -176,6 +176,7 @@ static int sparx5_port_bridge_join(struc
|
||||
struct net_device *bridge,
|
||||
struct netlink_ext_ack *extack)
|
||||
{
|
||||
+ struct switchdev_brport_flags flags = {0};
|
||||
struct sparx5 *sparx5 = port->sparx5;
|
||||
struct net_device *ndev = port->ndev;
|
||||
int err;
|
||||
@@ -205,6 +206,11 @@ static int sparx5_port_bridge_join(struc
|
||||
*/
|
||||
__dev_mc_unsync(ndev, sparx5_mc_unsync);
|
||||
|
||||
+ /* Enable uc/mc/bc flooding */
|
||||
+ flags.mask = BR_FLOOD | BR_MCAST_FLOOD | BR_BCAST_FLOOD;
|
||||
+ flags.val = flags.mask;
|
||||
+ sparx5_port_attr_bridge_flags(port, flags);
|
||||
+
|
||||
return 0;
|
||||
|
||||
err_switchdev_offload:
|
||||
@@ -215,6 +221,7 @@ err_switchdev_offload:
|
||||
static void sparx5_port_bridge_leave(struct sparx5_port *port,
|
||||
struct net_device *bridge)
|
||||
{
|
||||
+ struct switchdev_brport_flags flags = {0};
|
||||
struct sparx5 *sparx5 = port->sparx5;
|
||||
|
||||
switchdev_bridge_port_unoffload(port->ndev, NULL, NULL, NULL);
|
||||
@@ -234,6 +241,11 @@ static void sparx5_port_bridge_leave(str
|
||||
|
||||
/* Port enters in host more therefore restore mc list */
|
||||
__dev_mc_sync(port->ndev, sparx5_mc_sync, sparx5_mc_unsync);
|
||||
+
|
||||
+ /* Disable uc/mc/bc flooding */
|
||||
+ flags.mask = BR_FLOOD | BR_MCAST_FLOOD | BR_BCAST_FLOOD;
|
||||
+ flags.val = 0;
|
||||
+ sparx5_port_attr_bridge_flags(port, flags);
|
||||
}
|
||||
|
||||
static int sparx5_port_changeupper(struct net_device *dev,
|
||||
--- a/drivers/net/ethernet/microchip/sparx5/sparx5_vlan.c
|
||||
+++ b/drivers/net/ethernet/microchip/sparx5/sparx5_vlan.c
|
||||
@@ -167,16 +167,6 @@ void sparx5_update_fwd(struct sparx5 *sp
|
||||
/* Divide up fwd mask in 32 bit words */
|
||||
bitmap_to_arr32(mask, sparx5->bridge_fwd_mask, SPX5_PORTS);
|
||||
|
||||
- /* Update flood masks */
|
||||
- for (port = sparx5_get_pgid(sparx5, PGID_UC_FLOOD);
|
||||
- port <= sparx5_get_pgid(sparx5, PGID_BCAST); port++) {
|
||||
- spx5_wr(mask[0], sparx5, ANA_AC_PGID_CFG(port));
|
||||
- if (is_sparx5(sparx5)) {
|
||||
- spx5_wr(mask[1], sparx5, ANA_AC_PGID_CFG1(port));
|
||||
- spx5_wr(mask[2], sparx5, ANA_AC_PGID_CFG2(port));
|
||||
- }
|
||||
- }
|
||||
-
|
||||
/* Update SRC masks */
|
||||
for (port = 0; port < sparx5->data->consts->n_ports; port++) {
|
||||
if (test_bit(port, sparx5->bridge_fwd_mask)) {
|
||||
@ -0,0 +1,26 @@
|
||||
From 78d996ea8dbc6fa21ecb28d1b6167d6f2e0043cb Mon Sep 17 00:00:00 2001
|
||||
From: Robert Marko <robert.marko@sartura.hr>
|
||||
Date: Fri, 8 Nov 2024 12:22:34 +0100
|
||||
Subject: [PATCH 07/25] clk: lan966x: make it selectable for ARCH_LAN969X
|
||||
|
||||
LAN969x uses the same LAN966x clock driver so make it selectable for
|
||||
ARCH_LAN969X.
|
||||
|
||||
Signed-off-by: Robert Marko <robert.marko@sartura.hr>
|
||||
Link: https://lore.kernel.org/r/20241108112355.20251-1-robert.marko@sartura.hr
|
||||
Signed-off-by: Stephen Boyd <sboyd@kernel.org>
|
||||
---
|
||||
drivers/clk/Kconfig | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
--- a/drivers/clk/Kconfig
|
||||
+++ b/drivers/clk/Kconfig
|
||||
@@ -259,7 +259,7 @@ config COMMON_CLK_LAN966X
|
||||
tristate "Generic Clock Controller driver for LAN966X SoC"
|
||||
depends on HAS_IOMEM
|
||||
depends on OF
|
||||
- depends on SOC_LAN966 || COMPILE_TEST
|
||||
+ depends on SOC_LAN966 || ARCH_LAN969X || COMPILE_TEST
|
||||
help
|
||||
This driver provides support for Generic Clock Controller(GCK) on
|
||||
LAN966X SoC. GCK generates and supplies clock to various peripherals
|
||||
@ -0,0 +1,25 @@
|
||||
From f11759a7a2c10d32324adf3cc5d4fe95ef74df77 Mon Sep 17 00:00:00 2001
|
||||
From: Robert Marko <robert.marko@sartura.hr>
|
||||
Date: Wed, 17 Sep 2025 12:55:14 +0200
|
||||
Subject: [PATCH 16/25] phy: sparx5-serdes: make it selectable for ARCH_LAN969X
|
||||
|
||||
LAN969x uses the SparX-5 SERDES driver, so make it selectable for
|
||||
ARCH_LAN969X.
|
||||
|
||||
Signed-off-by: Robert Marko <robert.marko@sartura.hr>
|
||||
Reviewed-by: Daniel Machon <daniel.machon@microchip.com>
|
||||
---
|
||||
drivers/phy/microchip/Kconfig | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
--- a/drivers/phy/microchip/Kconfig
|
||||
+++ b/drivers/phy/microchip/Kconfig
|
||||
@@ -6,7 +6,7 @@
|
||||
config PHY_SPARX5_SERDES
|
||||
tristate "Microchip Sparx5 SerDes PHY driver"
|
||||
select GENERIC_PHY
|
||||
- depends on ARCH_SPARX5 || COMPILE_TEST
|
||||
+ depends on ARCH_SPARX5 || ARCH_LAN969X || COMPILE_TEST
|
||||
depends on OF
|
||||
depends on HAS_IOMEM
|
||||
help
|
||||
@ -0,0 +1,40 @@
|
||||
From 7dffd83ae4ae02a43d61b15af6edb199fcc7ebb3 Mon Sep 17 00:00:00 2001
|
||||
From: Robert Marko <robert.marko@sartura.hr>
|
||||
Date: Tue, 5 Nov 2024 12:08:06 +0100
|
||||
Subject: [PATCH] include: dt-bindings: add LAN969x clock bindings
|
||||
|
||||
Add the required LAN969x clock bindings.
|
||||
|
||||
Signed-off-by: Robert Marko <robert.marko@sartura.hr>
|
||||
---
|
||||
include/dt-bindings/clock/microchip,lan969x.h | 24 +++++++++++++++++++
|
||||
1 file changed, 24 insertions(+)
|
||||
create mode 100644 include/dt-bindings/clock/microchip,lan969x.h
|
||||
|
||||
--- /dev/null
|
||||
+++ b/include/dt-bindings/clock/microchip,lan969x.h
|
||||
@@ -0,0 +1,24 @@
|
||||
+/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) */
|
||||
+
|
||||
+#ifndef _DT_BINDINGS_CLK_LAN969X_H
|
||||
+#define _DT_BINDINGS_CLK_LAN969X_H
|
||||
+
|
||||
+#define GCK_ID_QSPI0 0
|
||||
+#define GCK_ID_QSPI2 1
|
||||
+#define GCK_ID_SDMMC0 2
|
||||
+#define GCK_ID_SDMMC1 3
|
||||
+#define GCK_ID_MCAN0 4
|
||||
+#define GCK_ID_MCAN1 5
|
||||
+#define GCK_ID_FLEXCOM0 6
|
||||
+#define GCK_ID_FLEXCOM1 7
|
||||
+#define GCK_ID_FLEXCOM2 8
|
||||
+#define GCK_ID_FLEXCOM3 9
|
||||
+#define GCK_ID_TIMER 10
|
||||
+#define GCK_ID_USB_REFCLK 11
|
||||
+
|
||||
+/* Gate clocks */
|
||||
+#define GCK_GATE_USB_DRD 12
|
||||
+#define GCK_GATE_MCRAMC 13
|
||||
+#define GCK_GATE_HMATRIX 14
|
||||
+
|
||||
+#endif
|
||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user