mirror of
https://github.com/LiBwrt-op/openwrt-6.x.git
synced 2025-12-16 08:44:50 +00:00
Merge Official Source
Signed-off-by: Tianling Shen <cnsztl@immortalwrt.org>
This commit is contained in:
commit
cdaf3756de
@ -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
|
||||
|
||||
78
package/boot/arm-trusted-firmware-microchipsw/Makefile
Normal file
78
package/boot/arm-trusted-firmware-microchipsw/Makefile
Normal file
@ -0,0 +1,78 @@
|
||||
include $(TOPDIR)/rules.mk
|
||||
|
||||
PKG_NAME:=arm-trusted-firmware-microchipsw
|
||||
PKG_RELEASE:=1
|
||||
|
||||
PKG_SOURCE_PROTO:=git
|
||||
PKG_SOURCE_URL=https://github.com/microchip-ung/arm-trusted-firmware.git
|
||||
PKG_SOURCE_DATE:=2024-08-13
|
||||
PKG_SOURCE_VERSION:=67fcfcab71f78ac7d4af834c37b29f8c98dd5ff1
|
||||
PKG_MIRROR_HASH:=777c68273e84028de77750f3fe8a1219b02f01d43ce35948893ac642d8eb10d7
|
||||
|
||||
PKG_MAINTAINER:=Robert Marko <robert.marko@sartura.hr>
|
||||
|
||||
include $(INCLUDE_DIR)/kernel.mk
|
||||
include $(INCLUDE_DIR)/trusted-firmware-a.mk
|
||||
include $(INCLUDE_DIR)/package.mk
|
||||
|
||||
define Trusted-Firmware-A/Default
|
||||
BUILD_TARGET:=microchipsw
|
||||
TFA_IMAGE:=fip.bin fwu_fip.bin fwu.html
|
||||
endef
|
||||
|
||||
define Trusted-Firmware-A/ev23x71a
|
||||
NAME:=Microchip EV23X71A
|
||||
BUILD_SUBTARGET:=lan969x
|
||||
BUILD_DEVICES:=microchip_ev23x71a
|
||||
PLAT:=lan969x_a0
|
||||
DEPENDS:=+u-boot-ev23x71a
|
||||
endef
|
||||
|
||||
TFA_TARGETS:= ev23x71a
|
||||
|
||||
MBEDTLS_NAME:=mbedtls
|
||||
MBEDTLS_RELEASE:=2.28.10
|
||||
MBEDTLS_SOURCE:=$(MBEDTLS_NAME)-$(MBEDTLS_RELEASE).tar.zst
|
||||
|
||||
define Download/mbedtls
|
||||
FILE:=$(MBEDTLS_SOURCE)
|
||||
PROTO:=git
|
||||
URL:=https://github.com/Mbed-TLS/mbedtls.git
|
||||
SOURCE_VERSION:=2fc8413bfcb51354c8e679141b17b3f1a5942561
|
||||
MIRROR_HASH:=40b94a76572ad1ca89738929ab81d6024f678f22691eb3bd633c076ac18a334a
|
||||
SUBDIR:=$(MBEDTLS_NAME)
|
||||
endef
|
||||
|
||||
define Build/Prepare
|
||||
# Download mbedtls
|
||||
$(eval $(call Download,mbedtls))
|
||||
|
||||
$(call Build/Prepare/Default,)
|
||||
|
||||
$(TAR) -C $(PKG_BUILD_DIR) -xf $(DL_DIR)/$(MBEDTLS_SOURCE)
|
||||
endef
|
||||
|
||||
# We must not pass OPENSSL_DIR as locally built mbedtls is used
|
||||
define Build/Compile
|
||||
+unset CC; \
|
||||
$(MAKE) $(PKG_JOBS) -C $(PKG_BUILD_DIR) \
|
||||
CROSS_COMPILE=$(TARGET_CROSS) \
|
||||
$(if $(DTC),DTC="$(DTC)") \
|
||||
PLAT=$(PLAT) \
|
||||
BUILD_STRING="OpenWrt $(PKG_VERSION_PREFIX)$(PKG_VERSION)-$(PKG_RELEASE) ($(VARIANT))" \
|
||||
$(TFA_MAKE_FLAGS)
|
||||
endef
|
||||
|
||||
TFA_MAKE_FLAGS += \
|
||||
MBEDTLS_DIR=$(PKG_BUILD_DIR)/$(MBEDTLS_NAME) \
|
||||
BL33=$(STAGING_DIR_IMAGE)/$(BUILD_VARIANT)-u-boot.bin \
|
||||
KEY_ALG=ecdsa GENERATE_COT=1 TRUSTED_BOARD_BOOT=1 \
|
||||
all fip fwu_fip
|
||||
|
||||
define Package/trusted-firmware-a/install
|
||||
$(INSTALL_DIR) $(STAGING_DIR_IMAGE)
|
||||
$(INSTALL_DATA) $(PKG_BUILD_DIR)/build/$(PLAT)/release/fip.bin $(STAGING_DIR_IMAGE)/$(BUILD_VARIANT)-fip.bin
|
||||
$(CP) $(patsubst %,$(PKG_BUILD_DIR)/build/$(PLAT)/release/%,$(TFA_IMAGE)) $(1)/
|
||||
endef
|
||||
|
||||
$(eval $(call BuildPackage/Trusted-Firmware-A))
|
||||
37
package/boot/uboot-microchipsw/Makefile
Normal file
37
package/boot/uboot-microchipsw/Makefile
Normal file
@ -0,0 +1,37 @@
|
||||
include $(TOPDIR)/rules.mk
|
||||
|
||||
PKG_RELEASE:=1
|
||||
|
||||
PKG_SOURCE_PROTO:=git
|
||||
PKG_SOURCE_URL:=https://github.com/microchip-ung/u-boot.git
|
||||
PKG_SOURCE_DATE:=2025-09-22
|
||||
PKG_SOURCE_VERSION:=c1abab62a00a6b8f43f663a0a30dd0a7fd6a4e95
|
||||
PKG_MIRROR_HASH:=6405c426afd8bacbb4cc985da4ca1bd04b54a0d2aa3bb3ba8f7571dbe5913055
|
||||
|
||||
PKG_MAINTAINER:=Robert Marko <robert.marko@sartura.hr>
|
||||
|
||||
include $(INCLUDE_DIR)/u-boot.mk
|
||||
include $(INCLUDE_DIR)/package.mk
|
||||
include $(INCLUDE_DIR)/kernel.mk
|
||||
|
||||
define U-Boot/Default
|
||||
BUILD_TARGET:=microchipsw
|
||||
HIDDEN:=1
|
||||
UBOOT_IMAGE:=u-boot.bin
|
||||
endef
|
||||
|
||||
define U-Boot/ev23x71a
|
||||
NAME:=Microchip EV23X71A
|
||||
BUILD_DEVICES:=microchip_ev23x71a
|
||||
BUILD_SUBTARGET:=lan969x
|
||||
UBOOT_CONFIG:=mchp_lan969x
|
||||
endef
|
||||
|
||||
UBOOT_TARGETS:= ev23x71a
|
||||
|
||||
define Build/InstallDev
|
||||
$(INSTALL_DIR) $(STAGING_DIR_IMAGE)
|
||||
$(CP) $(PKG_BUILD_DIR)/$(UBOOT_IMAGE) $(STAGING_DIR_IMAGE)/$(BUILD_VARIANT)-$(UBOOT_IMAGE)
|
||||
endef
|
||||
|
||||
$(eval $(call BuildPackage/U-Boot))
|
||||
@ -0,0 +1,139 @@
|
||||
--- a/cmd/bootm.c
|
||||
+++ b/cmd/bootm.c
|
||||
@@ -260,6 +260,76 @@ U_BOOT_CMD(
|
||||
/* iminfo - print header info for a requested image */
|
||||
/*******************************************************************/
|
||||
#if defined(CONFIG_CMD_IMI)
|
||||
+#define SECTOR_SHIFT 9
|
||||
+static int image_totalsize(struct cmd_tbl *cmdtp, int flag, int argc,
|
||||
+ char *const argv[], short int in_blocks)
|
||||
+{
|
||||
+ ulong addr;
|
||||
+ void *hdr;
|
||||
+ uint32_t bsize, tsize = 0;
|
||||
+ char buf[16];
|
||||
+
|
||||
+ if (argc >= 2)
|
||||
+ addr = simple_strtoul(argv[1], NULL, 16);
|
||||
+ else
|
||||
+ addr = image_load_addr;
|
||||
+
|
||||
+ hdr = (void *)map_sysmem(addr, 0);
|
||||
+
|
||||
+ switch (genimg_get_format(hdr)) {
|
||||
+ case IMAGE_FORMAT_LEGACY:
|
||||
+ if(CONFIG_IS_ENABLED(LEGACY_IMAGE_FORMAT))
|
||||
+ tsize = image_get_image_size(hdr);
|
||||
+ break;
|
||||
+ case IMAGE_FORMAT_FIT:
|
||||
+ if(CONFIG_IS_ENABLED(FIT))
|
||||
+ tsize = fit_get_totalsize(hdr);
|
||||
+ break;
|
||||
+ }
|
||||
+
|
||||
+ unmap_sysmem(hdr);
|
||||
+ if (tsize == 0)
|
||||
+ return 1;
|
||||
+
|
||||
+ bsize = (tsize >> SECTOR_SHIFT) + ((tsize & ((1 << SECTOR_SHIFT) - 1))?1:0);
|
||||
+
|
||||
+ if (!in_blocks)
|
||||
+ snprintf(buf, sizeof(buf), "%x", tsize);
|
||||
+ else
|
||||
+ snprintf(buf, sizeof(buf), "%x", bsize);
|
||||
+
|
||||
+ if (argc >= 3)
|
||||
+ return env_set(argv[2], buf);
|
||||
+ else
|
||||
+ printf("%s\n", buf);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static int do_imsz(struct cmd_tbl *cmdtp, int flag, int argc,
|
||||
+ char *const argv[])
|
||||
+{
|
||||
+ return image_totalsize(cmdtp, flag, argc, argv, 0);
|
||||
+}
|
||||
+
|
||||
+static int do_imszb(struct cmd_tbl *cmdtp, int flag, int argc,
|
||||
+ char *const argv[])
|
||||
+{
|
||||
+ return image_totalsize(cmdtp, flag, argc, argv, 1);
|
||||
+}
|
||||
+
|
||||
+U_BOOT_CMD(
|
||||
+ imsz, CONFIG_SYS_MAXARGS, 1, do_imsz,
|
||||
+ "get image total size (in bytes)",
|
||||
+ "addr [maxhdrlen] [varname]\n"
|
||||
+);
|
||||
+
|
||||
+U_BOOT_CMD(
|
||||
+ imszb, CONFIG_SYS_MAXARGS, 1, do_imszb,
|
||||
+ "get image total size (in blocks)",
|
||||
+ "addr [maxhdrlen] [varname]\n"
|
||||
+);
|
||||
+
|
||||
static int do_iminfo(struct cmd_tbl *cmdtp, int flag, int argc,
|
||||
char *const argv[])
|
||||
{
|
||||
--- a/boot/image-fit.c
|
||||
+++ b/boot/image-fit.c
|
||||
@@ -2054,6 +2054,47 @@ static const char *fit_get_image_type_pr
|
||||
return "unknown";
|
||||
}
|
||||
|
||||
+size_t fit_get_totalsize(const void *fit)
|
||||
+{
|
||||
+ int ret, ndepth, noffset, images_noffset;
|
||||
+ size_t data_size, hdrsize, img_total, max_size = 0;
|
||||
+ const void *data;
|
||||
+
|
||||
+ ret = fdt_check_header(fit);
|
||||
+ if (ret) {
|
||||
+ debug("Wrong FIT format: not a flattened device tree (err=%d)\n",
|
||||
+ ret);
|
||||
+ return 0;
|
||||
+ }
|
||||
+
|
||||
+ hdrsize = fdt_totalsize(fit);
|
||||
+
|
||||
+ /* take care of simple FIT with internal images */
|
||||
+ max_size = hdrsize;
|
||||
+
|
||||
+ images_noffset = fdt_path_offset(fit, FIT_IMAGES_PATH);
|
||||
+ if (images_noffset < 0)
|
||||
+ goto out;
|
||||
+
|
||||
+ for (ndepth = 0,
|
||||
+ noffset = fdt_next_node(fit, images_noffset, &ndepth);
|
||||
+ (noffset >= 0) && (ndepth > 0);
|
||||
+ noffset = fdt_next_node(fit, noffset, &ndepth)) {
|
||||
+ if (ndepth == 1) {
|
||||
+ ret = fit_image_get_data(fit, noffset, &data, &data_size);
|
||||
+ if (ret)
|
||||
+ goto out;
|
||||
+
|
||||
+ img_total = data_size + (data - fit);
|
||||
+
|
||||
+ max_size = (max_size > img_total) ? max_size : img_total;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+out:
|
||||
+ return max_size;
|
||||
+}
|
||||
+
|
||||
int fit_image_load(struct bootm_headers *images, ulong addr,
|
||||
const char **fit_unamep, const char **fit_uname_configp,
|
||||
int arch, int ph_type, int bootstage_id,
|
||||
--- a/include/image.h
|
||||
+++ b/include/image.h
|
||||
@@ -1113,6 +1113,7 @@ int fit_parse_subimage(const char *spec,
|
||||
ulong *addr, const char **image_name);
|
||||
|
||||
int fit_get_subimage_count(const void *fit, int images_noffset);
|
||||
+size_t fit_get_totalsize(const void *fit);
|
||||
void fit_print_contents(const void *fit);
|
||||
void fit_image_print(const void *fit, int noffset, const char *p);
|
||||
|
||||
@ -0,0 +1,10 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
|
||||
|
||||
fdt_high=0xffffffff
|
||||
baudrate=115200
|
||||
bootdelay=3
|
||||
loadaddr=0x64000000
|
||||
bootargs=console=ttyAT0,115200 root=PARTLABEL=rootfs rootwait
|
||||
mmc_read_kernel=mmc read $loadaddr $part_addr 0x100 && imszb $loadaddr image_size && test 0x$image_size -le 0x$part_size && mmc read $loadaddr $part_addr $image_size
|
||||
boot_system=part start mmc 0 kernel part_addr && part size mmc 0 kernel part_size && run mmc_read_kernel && bootm
|
||||
bootcmd=run boot_system
|
||||
@ -220,7 +220,7 @@ static inline void clear_share_buffer(void)
|
||||
* int --- 0: Success
|
||||
* else: Error Code
|
||||
*/
|
||||
static inline int pp32_download_code(u32 *code_src, unsigned int code_dword_len, u32 *data_src, unsigned int data_dword_len)
|
||||
static inline int pp32_download_code(const u32 *code_src, unsigned int code_dword_len, const u32 *data_src, unsigned int data_dword_len)
|
||||
{
|
||||
volatile u32 *dest;
|
||||
|
||||
|
||||
@ -159,7 +159,7 @@ static inline void clear_share_buffer(void)
|
||||
IFX_REG_W32(0, p++);
|
||||
}
|
||||
|
||||
static inline int pp32_download_code(u32 *code_src, unsigned int code_dword_len, u32 *data_src, unsigned int data_dword_len)
|
||||
static inline int pp32_download_code(const u32 *code_src, unsigned int code_dword_len, const u32 *data_src, unsigned int data_dword_len)
|
||||
{
|
||||
volatile u32 *dest;
|
||||
|
||||
|
||||
@ -106,7 +106,7 @@ static inline void reset_ppe(struct platform_device *pdev)
|
||||
* int --- 0: Success
|
||||
* else: Error Code
|
||||
*/
|
||||
static inline int danube_pp32_download_code(u32 *code_src, unsigned int code_dword_len, u32 *data_src, unsigned int data_dword_len)
|
||||
static inline int danube_pp32_download_code(const u32 *code_src, unsigned int code_dword_len, const u32 *data_src, unsigned int data_dword_len)
|
||||
{
|
||||
volatile u32 *dest;
|
||||
|
||||
|
||||
@ -91,7 +91,7 @@ static inline int vr9_reset_ppe(struct platform_device *pdev)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int vr9_pp32_download_code(int pp32, u32 *code_src, unsigned int code_dword_len, u32 *data_src, unsigned int data_dword_len)
|
||||
static inline int vr9_pp32_download_code(int pp32, const u32 *code_src, unsigned int code_dword_len, const u32 *data_src, unsigned int data_dword_len)
|
||||
{
|
||||
unsigned int clr, set;
|
||||
volatile u32 *dest;
|
||||
|
||||
@ -219,7 +219,7 @@ static inline void clear_share_buffer(void)
|
||||
* int --- 0: Success
|
||||
* else: Error Code
|
||||
*/
|
||||
static inline int pp32_download_code(u32 *code_src, unsigned int code_dword_len, u32 *data_src, unsigned int data_dword_len)
|
||||
static inline int pp32_download_code(const u32 *code_src, unsigned int code_dword_len, const u32 *data_src, unsigned int data_dword_len)
|
||||
{
|
||||
volatile u32 *dest;
|
||||
|
||||
|
||||
@ -242,7 +242,7 @@ static inline void clear_share_buffer(void)
|
||||
* int --- 0: Success
|
||||
* else: Error Code
|
||||
*/
|
||||
static inline int pp32_download_code(u32 *code_src, unsigned int code_dword_len, u32 *data_src, unsigned int data_dword_len)
|
||||
static inline int pp32_download_code(const u32 *code_src, unsigned int code_dword_len, const u32 *data_src, unsigned int data_dword_len)
|
||||
{
|
||||
volatile u32 *dest;
|
||||
|
||||
|
||||
@ -214,7 +214,7 @@ static inline void clear_share_buffer(void)
|
||||
* int --- 0: Success
|
||||
* else: Error Code
|
||||
*/
|
||||
static inline int pp32_download_code(u32 *code_src, unsigned int code_dword_len, u32 *data_src, unsigned int data_dword_len)
|
||||
static inline int pp32_download_code(const u32 *code_src, unsigned int code_dword_len, const u32 *data_src, unsigned int data_dword_len)
|
||||
{
|
||||
volatile u32 *dest;
|
||||
|
||||
|
||||
@ -202,7 +202,7 @@ static inline void clear_share_buffer(void)
|
||||
* int --- 0: Success
|
||||
* else: Error Code
|
||||
*/
|
||||
static inline int pp32_download_code(int pp32, u32 *code_src, unsigned int code_dword_len, u32 *data_src, unsigned int data_dword_len)
|
||||
static inline int pp32_download_code(int pp32, const u32 *code_src, unsigned int code_dword_len, const u32 *data_src, unsigned int data_dword_len)
|
||||
{
|
||||
unsigned int clr, set;
|
||||
volatile u32 *dest;
|
||||
|
||||
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))
|
||||
787
target/linux/microchipsw/dts/lan9696-ev23x71a.dts
Normal file
787
target/linux/microchipsw/dts/lan9696-ev23x71a.dts
Normal file
@ -0,0 +1,787 @@
|
||||
/dts-v1/;
|
||||
|
||||
#include <dt-bindings/gpio/gpio.h>
|
||||
#include <dt-bindings/leds/common.h>
|
||||
#include "lan969x.dtsi"
|
||||
|
||||
/ {
|
||||
model = "Microchip EV23X71A";
|
||||
compatible = "microchip,ev23x71a", "microchip,lan969x";
|
||||
|
||||
aliases {
|
||||
serial0 = &usart0;
|
||||
led-boot = &led_status;
|
||||
led-failsafe = &led_status;
|
||||
led-running = &led_status;
|
||||
led-upgrade = &led_status;
|
||||
};
|
||||
|
||||
chosen {
|
||||
stdout-path = "serial0:115200n8";
|
||||
};
|
||||
|
||||
gpio-restart {
|
||||
compatible = "gpio-restart";
|
||||
gpios = <&gpio 60 GPIO_ACTIVE_LOW>;
|
||||
open-source;
|
||||
priority = <200>;
|
||||
};
|
||||
|
||||
i2c-mux {
|
||||
compatible = "i2c-mux-gpio";
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
i2c-parent = <&i2c3>;
|
||||
|
||||
mux-gpios = <&sgpio_out 0 1 GPIO_ACTIVE_HIGH
|
||||
&sgpio_out 0 2 GPIO_ACTIVE_HIGH
|
||||
&sgpio_out 0 3 GPIO_ACTIVE_HIGH>;
|
||||
idle-state = <0x8>;
|
||||
|
||||
i2c_sfp0: i2c@0 {
|
||||
reg = <0x0>;
|
||||
};
|
||||
|
||||
i2c_sfp1: i2c@1 {
|
||||
reg = <0x1>;
|
||||
};
|
||||
|
||||
i2c_sfp2: i2c@2 {
|
||||
reg = <0x2>;
|
||||
};
|
||||
|
||||
i2c_sfp3: i2c@3 {
|
||||
reg = <0x3>;
|
||||
};
|
||||
|
||||
i2c_poe: i2c@7 {
|
||||
reg = <0x7>;
|
||||
};
|
||||
};
|
||||
|
||||
leds {
|
||||
compatible = "gpio-leds";
|
||||
|
||||
led_status: led-status {
|
||||
color = <LED_COLOR_ID_GREEN>;
|
||||
function = LED_FUNCTION_STATUS;
|
||||
gpios = <&gpio 61 GPIO_ACTIVE_LOW>;
|
||||
};
|
||||
|
||||
led-sfp1-green {
|
||||
color = <LED_COLOR_ID_GREEN>;
|
||||
function = LED_FUNCTION_LAN;
|
||||
function-enumerator = <0>;
|
||||
gpios = <&sgpio_out 6 0 GPIO_ACTIVE_LOW>;
|
||||
default-state = "off";
|
||||
};
|
||||
|
||||
led-sfp1-yellow {
|
||||
color = <LED_COLOR_ID_YELLOW>;
|
||||
function = LED_FUNCTION_LAN;
|
||||
function-enumerator = <0>;
|
||||
gpios = <&sgpio_out 6 1 GPIO_ACTIVE_LOW>;
|
||||
default-state = "off";
|
||||
};
|
||||
|
||||
led-sfp2-green {
|
||||
color = <LED_COLOR_ID_GREEN>;
|
||||
function = LED_FUNCTION_LAN;
|
||||
function-enumerator = <1>;
|
||||
gpios = <&sgpio_out 7 0 GPIO_ACTIVE_LOW>;
|
||||
default-state = "off";
|
||||
};
|
||||
|
||||
led-sfp2-yellow {
|
||||
color = <LED_COLOR_ID_YELLOW>;
|
||||
function = LED_FUNCTION_LAN;
|
||||
function-enumerator = <1>;
|
||||
gpios = <&sgpio_out 7 1 GPIO_ACTIVE_LOW>;
|
||||
default-state = "off";
|
||||
};
|
||||
|
||||
led-sfp3-green {
|
||||
color = <LED_COLOR_ID_GREEN>;
|
||||
function = LED_FUNCTION_LAN;
|
||||
function-enumerator = <2>;
|
||||
gpios = <&sgpio_out 8 0 GPIO_ACTIVE_LOW>;
|
||||
default-state = "off";
|
||||
};
|
||||
|
||||
led-sfp3-yellow {
|
||||
color = <LED_COLOR_ID_YELLOW>;
|
||||
function = LED_FUNCTION_LAN;
|
||||
function-enumerator = <2>;
|
||||
gpios = <&sgpio_out 8 1 GPIO_ACTIVE_LOW>;
|
||||
default-state = "off";
|
||||
};
|
||||
|
||||
led-sfp4-green {
|
||||
color = <LED_COLOR_ID_GREEN>;
|
||||
function = LED_FUNCTION_LAN;
|
||||
function-enumerator = <3>;
|
||||
gpios = <&sgpio_out 9 0 GPIO_ACTIVE_LOW>;
|
||||
default-state = "off";
|
||||
};
|
||||
|
||||
led-sfp4-yellow {
|
||||
color = <LED_COLOR_ID_YELLOW>;
|
||||
function = LED_FUNCTION_LAN;
|
||||
function-enumerator = <3>;
|
||||
gpios = <&sgpio_out 9 1 GPIO_ACTIVE_LOW>;
|
||||
default-state = "off";
|
||||
};
|
||||
};
|
||||
|
||||
mux-controller {
|
||||
compatible = "gpio-mux";
|
||||
#mux-control-cells = <0>;
|
||||
|
||||
mux-gpios = <&sgpio_out 1 2 GPIO_ACTIVE_LOW>,
|
||||
<&sgpio_out 1 3 GPIO_ACTIVE_LOW>;
|
||||
};
|
||||
|
||||
sfp0: sfp0 {
|
||||
compatible = "sff,sfp";
|
||||
i2c-bus = <&i2c_sfp0>;
|
||||
tx-disable-gpios = <&sgpio_out 6 2 GPIO_ACTIVE_HIGH>;
|
||||
los-gpios = <&sgpio_in 6 0 GPIO_ACTIVE_HIGH>;
|
||||
mod-def0-gpios = <&sgpio_in 6 1 GPIO_ACTIVE_LOW>;
|
||||
tx-fault-gpios = <&sgpio_in 6 2 GPIO_ACTIVE_HIGH>;
|
||||
};
|
||||
|
||||
sfp1: sfp1 {
|
||||
compatible = "sff,sfp";
|
||||
i2c-bus = <&i2c_sfp1>;
|
||||
tx-disable-gpios = <&sgpio_out 7 2 GPIO_ACTIVE_HIGH>;
|
||||
los-gpios = <&sgpio_in 7 0 GPIO_ACTIVE_HIGH>;
|
||||
mod-def0-gpios = <&sgpio_in 7 1 GPIO_ACTIVE_LOW>;
|
||||
tx-fault-gpios = <&sgpio_in 7 2 GPIO_ACTIVE_HIGH>;
|
||||
};
|
||||
|
||||
sfp2: sfp2 {
|
||||
compatible = "sff,sfp";
|
||||
i2c-bus = <&i2c_sfp2>;
|
||||
tx-disable-gpios = <&sgpio_out 8 2 GPIO_ACTIVE_HIGH>;
|
||||
los-gpios = <&sgpio_in 8 0 GPIO_ACTIVE_HIGH>;
|
||||
mod-def0-gpios = <&sgpio_in 8 1 GPIO_ACTIVE_LOW>;
|
||||
tx-fault-gpios = <&sgpio_in 8 2 GPIO_ACTIVE_HIGH>;
|
||||
};
|
||||
|
||||
sfp3: sfp3 {
|
||||
compatible = "sff,sfp";
|
||||
i2c-bus = <&i2c_sfp3>;
|
||||
tx-disable-gpios = <&sgpio_out 9 2 GPIO_ACTIVE_HIGH>;
|
||||
los-gpios = <&sgpio_in 9 0 GPIO_ACTIVE_HIGH>;
|
||||
mod-def0-gpios = <&sgpio_in 9 1 GPIO_ACTIVE_LOW>;
|
||||
tx-fault-gpios = <&sgpio_in 9 2 GPIO_ACTIVE_HIGH>;
|
||||
};
|
||||
};
|
||||
|
||||
&flx0 {
|
||||
atmel,flexcom-mode = <ATMEL_FLEXCOM_MODE_USART>;
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
&usart0 {
|
||||
pinctrl-0 = <&fc0_pins>;
|
||||
pinctrl-names = "default";
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
&flx2 {
|
||||
atmel,flexcom-mode = <ATMEL_FLEXCOM_MODE_SPI>;
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
&spi2 {
|
||||
pinctrl-0 = <&fc2_pins>;
|
||||
pinctrl-names = "default";
|
||||
cs-gpios = <&gpio 63 GPIO_ACTIVE_LOW>;
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
&flx3 {
|
||||
atmel,flexcom-mode = <ATMEL_FLEXCOM_MODE_TWI>;
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
&i2c3 {
|
||||
pinctrl-0 = <&fc3_pins>;
|
||||
pinctrl-names = "default";
|
||||
i2c-analog-filter;
|
||||
i2c-digital-filter;
|
||||
i2c-digital-filter-width-ns = <35>;
|
||||
i2c-sda-hold-time-ns = <1500>;
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
&gpio {
|
||||
emmc_sd_pins: emmc-sd-pins {
|
||||
/* eMMC_SD - CMD, CLK, D0, D1, D2, D3, D4, D5, D6, D7, RSTN */
|
||||
pins = "GPIO_14", "GPIO_15", "GPIO_16", "GPIO_17",
|
||||
"GPIO_18", "GPIO_19", "GPIO_20", "GPIO_21",
|
||||
"GPIO_22", "GPIO_23", "GPIO_24";
|
||||
function = "emmc_sd";
|
||||
};
|
||||
|
||||
fan_pins: fan-pins {
|
||||
pins = "GPIO_25", "GPIO_26";
|
||||
function = "fan";
|
||||
};
|
||||
|
||||
fc0_pins: fc0-pins {
|
||||
pins = "GPIO_3", "GPIO_4";
|
||||
function = "fc";
|
||||
};
|
||||
|
||||
fc2_pins: fc2-pins {
|
||||
pins = "GPIO_64", "GPIO_65", "GPIO_66";
|
||||
function = "fc";
|
||||
};
|
||||
|
||||
fc3_pins: fc3-pins {
|
||||
pins = "GPIO_55", "GPIO_56";
|
||||
function = "fc";
|
||||
};
|
||||
|
||||
mdio_pins: mdio-pins {
|
||||
pins = "GPIO_9", "GPIO_10";
|
||||
function = "miim";
|
||||
};
|
||||
|
||||
mdio_irq_pins: mdio-irq-pins {
|
||||
pins = "GPIO_11";
|
||||
function = "miim_irq";
|
||||
};
|
||||
|
||||
sgpio_pins: sgpio-pins {
|
||||
/* SCK, D0, D1, LD */
|
||||
pins = "GPIO_5", "GPIO_6", "GPIO_7", "GPIO_8";
|
||||
function = "sgpio_a";
|
||||
};
|
||||
|
||||
usb_ulpi_pins: usb-ulpi-pins {
|
||||
pins = "GPIO_30", "GPIO_31", "GPIO_32", "GPIO_33",
|
||||
"GPIO_34", "GPIO_35", "GPIO_36", "GPIO_37",
|
||||
"GPIO_38", "GPIO_39", "GPIO_40", "GPIO_41";
|
||||
function = "usb_ulpi";
|
||||
};
|
||||
|
||||
usb_rst_pins: usb-rst-pins {
|
||||
pins = "GPIO_12";
|
||||
function = "usb2phy_rst";
|
||||
};
|
||||
|
||||
usb_over_pins: usb-over-pins {
|
||||
pins = "GPIO_13";
|
||||
function = "usb_over_detect";
|
||||
};
|
||||
|
||||
usb_power_pins: usb-power-pins {
|
||||
pins = "GPIO_1";
|
||||
function = "usb_power";
|
||||
};
|
||||
|
||||
ptp_out_pins: ptp-out-pins {
|
||||
pins = "GPIO_58";
|
||||
function = "ptpsync_4";
|
||||
};
|
||||
|
||||
ptp_ext_pins: ptp-ext-pins {
|
||||
pins = "GPIO_59";
|
||||
function = "ptpsync_5";
|
||||
};
|
||||
};
|
||||
|
||||
&qspi0 {
|
||||
status = "okay";
|
||||
|
||||
flash@0 {
|
||||
compatible = "jedec,spi-nor";
|
||||
reg = <0>;
|
||||
spi-max-frequency = <100000000>;
|
||||
#address-cells = <1>;
|
||||
#size-cells = <1>;
|
||||
spi-tx-bus-width = <1>;
|
||||
spi-rx-bus-width = <4>;
|
||||
m25p,fast-read;
|
||||
};
|
||||
};
|
||||
|
||||
&sdmmc0 {
|
||||
pinctrl-0 = <&emmc_sd_pins>;
|
||||
pinctrl-names = "default";
|
||||
max-frequency = <100000000>;
|
||||
bus-width = <8>;
|
||||
mmc-ddr-1_8v;
|
||||
mmc-hs200-1_8v;
|
||||
non-removable;
|
||||
disable-wp;
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
&tmon {
|
||||
pinctrl-0 = <&fan_pins>;
|
||||
pinctrl-names = "default";
|
||||
};
|
||||
|
||||
&mdio0 {
|
||||
pinctrl-0 = <&mdio_pins>, <&mdio_irq_pins>;
|
||||
pinctrl-names = "default";
|
||||
reset-gpios = <&gpio 62 GPIO_ACTIVE_LOW>;
|
||||
status = "okay";
|
||||
|
||||
phy3: phy@3 {
|
||||
compatible = "ethernet-phy-ieee802.3-c22";
|
||||
reg = <3>;
|
||||
interrupts = <11 IRQ_TYPE_LEVEL_LOW>;
|
||||
interrupt-parent = <&gpio>;
|
||||
};
|
||||
|
||||
phy4: phy@4 {
|
||||
compatible = "ethernet-phy-ieee802.3-c22";
|
||||
reg = <4>;
|
||||
interrupts = <11 IRQ_TYPE_LEVEL_LOW>;
|
||||
interrupt-parent = <&gpio>;
|
||||
};
|
||||
|
||||
phy5: phy@5 {
|
||||
compatible = "ethernet-phy-ieee802.3-c22";
|
||||
reg = <5>;
|
||||
interrupts = <11 IRQ_TYPE_LEVEL_LOW>;
|
||||
interrupt-parent = <&gpio>;
|
||||
};
|
||||
|
||||
phy6: phy@6 {
|
||||
compatible = "ethernet-phy-ieee802.3-c22";
|
||||
reg = <6>;
|
||||
interrupts = <11 IRQ_TYPE_LEVEL_LOW>;
|
||||
interrupt-parent = <&gpio>;
|
||||
};
|
||||
|
||||
phy7: phy@7 {
|
||||
compatible = "ethernet-phy-ieee802.3-c22";
|
||||
reg = <7>;
|
||||
interrupts = <11 IRQ_TYPE_LEVEL_LOW>;
|
||||
interrupt-parent = <&gpio>;
|
||||
};
|
||||
|
||||
phy8: phy@8 {
|
||||
compatible = "ethernet-phy-ieee802.3-c22";
|
||||
reg = <8>;
|
||||
interrupts = <11 IRQ_TYPE_LEVEL_LOW>;
|
||||
interrupt-parent = <&gpio>;
|
||||
};
|
||||
|
||||
phy9: phy@9 {
|
||||
compatible = "ethernet-phy-ieee802.3-c22";
|
||||
reg = <9>;
|
||||
interrupts = <11 IRQ_TYPE_LEVEL_LOW>;
|
||||
interrupt-parent = <&gpio>;
|
||||
};
|
||||
|
||||
phy10: phy@10 {
|
||||
compatible = "ethernet-phy-ieee802.3-c22";
|
||||
reg = <10>;
|
||||
interrupts = <11 IRQ_TYPE_LEVEL_LOW>;
|
||||
interrupt-parent = <&gpio>;
|
||||
};
|
||||
|
||||
phy11: phy@11 {
|
||||
compatible = "ethernet-phy-ieee802.3-c22";
|
||||
reg = <11>;
|
||||
interrupts = <11 IRQ_TYPE_LEVEL_LOW>;
|
||||
interrupt-parent = <&gpio>;
|
||||
};
|
||||
|
||||
phy12: phy@12 {
|
||||
compatible = "ethernet-phy-ieee802.3-c22";
|
||||
reg = <12>;
|
||||
interrupts = <11 IRQ_TYPE_LEVEL_LOW>;
|
||||
interrupt-parent = <&gpio>;
|
||||
};
|
||||
|
||||
phy13: phy@13 {
|
||||
compatible = "ethernet-phy-ieee802.3-c22";
|
||||
reg = <13>;
|
||||
interrupts = <11 IRQ_TYPE_LEVEL_LOW>;
|
||||
interrupt-parent = <&gpio>;
|
||||
};
|
||||
|
||||
phy14: phy@14 {
|
||||
compatible = "ethernet-phy-ieee802.3-c22";
|
||||
reg = <14>;
|
||||
interrupts = <11 IRQ_TYPE_LEVEL_LOW>;
|
||||
interrupt-parent = <&gpio>;
|
||||
};
|
||||
|
||||
phy15: phy@15 {
|
||||
compatible = "ethernet-phy-ieee802.3-c22";
|
||||
reg = <15>;
|
||||
interrupts = <11 IRQ_TYPE_LEVEL_LOW>;
|
||||
interrupt-parent = <&gpio>;
|
||||
};
|
||||
|
||||
phy16: phy@16 {
|
||||
compatible = "ethernet-phy-ieee802.3-c22";
|
||||
reg = <16>;
|
||||
interrupts = <11 IRQ_TYPE_LEVEL_LOW>;
|
||||
interrupt-parent = <&gpio>;
|
||||
};
|
||||
|
||||
phy17: phy@17 {
|
||||
compatible = "ethernet-phy-ieee802.3-c22";
|
||||
reg = <17>;
|
||||
interrupts = <11 IRQ_TYPE_LEVEL_LOW>;
|
||||
interrupt-parent = <&gpio>;
|
||||
};
|
||||
|
||||
phy18: phy@18 {
|
||||
compatible = "ethernet-phy-ieee802.3-c22";
|
||||
reg = <18>;
|
||||
interrupts = <11 IRQ_TYPE_LEVEL_LOW>;
|
||||
interrupt-parent = <&gpio>;
|
||||
};
|
||||
|
||||
phy19: phy@19 {
|
||||
compatible = "ethernet-phy-ieee802.3-c22";
|
||||
reg = <19>;
|
||||
interrupts = <11 IRQ_TYPE_LEVEL_LOW>;
|
||||
interrupt-parent = <&gpio>;
|
||||
};
|
||||
|
||||
phy20: phy@20 {
|
||||
compatible = "ethernet-phy-ieee802.3-c22";
|
||||
reg = <20>;
|
||||
interrupts = <11 IRQ_TYPE_LEVEL_LOW>;
|
||||
interrupt-parent = <&gpio>;
|
||||
};
|
||||
|
||||
phy21: phy@21 {
|
||||
compatible = "ethernet-phy-ieee802.3-c22";
|
||||
reg = <21>;
|
||||
interrupts = <11 IRQ_TYPE_LEVEL_LOW>;
|
||||
interrupt-parent = <&gpio>;
|
||||
};
|
||||
|
||||
phy22: phy@22 {
|
||||
compatible = "ethernet-phy-ieee802.3-c22";
|
||||
reg = <22>;
|
||||
interrupts = <11 IRQ_TYPE_LEVEL_LOW>;
|
||||
interrupt-parent = <&gpio>;
|
||||
};
|
||||
|
||||
phy23: phy@23 {
|
||||
compatible = "ethernet-phy-ieee802.3-c22";
|
||||
reg = <23>;
|
||||
interrupts = <11 IRQ_TYPE_LEVEL_LOW>;
|
||||
interrupt-parent = <&gpio>;
|
||||
};
|
||||
|
||||
phy24: phy@24 {
|
||||
compatible = "ethernet-phy-ieee802.3-c22";
|
||||
reg = <24>;
|
||||
interrupts = <11 IRQ_TYPE_LEVEL_LOW>;
|
||||
interrupt-parent = <&gpio>;
|
||||
};
|
||||
|
||||
phy25: phy@25 {
|
||||
compatible = "ethernet-phy-ieee802.3-c22";
|
||||
reg = <25>;
|
||||
interrupts = <11 IRQ_TYPE_LEVEL_LOW>;
|
||||
interrupt-parent = <&gpio>;
|
||||
};
|
||||
|
||||
phy26: phy@26 {
|
||||
compatible = "ethernet-phy-ieee802.3-c22";
|
||||
reg = <26>;
|
||||
interrupts = <11 IRQ_TYPE_LEVEL_LOW>;
|
||||
interrupt-parent = <&gpio>;
|
||||
};
|
||||
|
||||
phy27: phy@27 {
|
||||
compatible = "ethernet-phy-ieee802.3-c22";
|
||||
reg = <27>;
|
||||
interrupts = <11 IRQ_TYPE_LEVEL_LOW>;
|
||||
interrupt-parent = <&gpio>;
|
||||
};
|
||||
};
|
||||
|
||||
&serdes {
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
&sgpio {
|
||||
pinctrl-0 = <&sgpio_pins>;
|
||||
pinctrl-names = "default";
|
||||
|
||||
microchip,sgpio-port-ranges = <0 1>, <6 9>;
|
||||
status = "okay";
|
||||
|
||||
gpio@0 {
|
||||
ngpios = <128>;
|
||||
};
|
||||
gpio@1 {
|
||||
ngpios = <128>;
|
||||
};
|
||||
};
|
||||
|
||||
&switch {
|
||||
pinctrl-0 = <&ptp_out_pins>, <&ptp_ext_pins>;
|
||||
pinctrl-names = "default";
|
||||
|
||||
status = "okay";
|
||||
ethernet-ports {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
port0: port@0 {
|
||||
reg = <0>;
|
||||
microchip,bandwidth = <1000>;
|
||||
phy-handle = <&phy4>;
|
||||
phy-mode = "qsgmii";
|
||||
phys = <&serdes 0>;
|
||||
};
|
||||
|
||||
port1: port@1 {
|
||||
reg = <1>;
|
||||
microchip,bandwidth = <1000>;
|
||||
phy-handle = <&phy5>;
|
||||
phy-mode = "qsgmii";
|
||||
phys = <&serdes 0>;
|
||||
};
|
||||
|
||||
port2: port@2 {
|
||||
reg = <2>;
|
||||
microchip,bandwidth = <1000>;
|
||||
phy-handle = <&phy6>;
|
||||
phy-mode = "qsgmii";
|
||||
phys = <&serdes 0>;
|
||||
};
|
||||
|
||||
port3: port@3 {
|
||||
reg = <3>;
|
||||
microchip,bandwidth = <1000>;
|
||||
phy-handle = <&phy7>;
|
||||
phy-mode = "qsgmii";
|
||||
phys = <&serdes 0>;
|
||||
};
|
||||
|
||||
port4: port@4 {
|
||||
reg = <4>;
|
||||
microchip,bandwidth = <1000>;
|
||||
phy-handle = <&phy8>;
|
||||
phy-mode = "qsgmii";
|
||||
phys = <&serdes 1>;
|
||||
};
|
||||
|
||||
port5: port@5 {
|
||||
reg = <5>;
|
||||
microchip,bandwidth = <1000>;
|
||||
phy-handle = <&phy9>;
|
||||
phy-mode = "qsgmii";
|
||||
phys = <&serdes 1>;
|
||||
};
|
||||
|
||||
port6: port@6 {
|
||||
reg = <6>;
|
||||
microchip,bandwidth = <1000>;
|
||||
phy-handle = <&phy10>;
|
||||
phy-mode = "qsgmii";
|
||||
phys = <&serdes 1>;
|
||||
};
|
||||
|
||||
port7: port@7 {
|
||||
reg = <7>;
|
||||
microchip,bandwidth = <1000>;
|
||||
phy-handle = <&phy11>;
|
||||
phy-mode = "qsgmii";
|
||||
phys = <&serdes 1>;
|
||||
};
|
||||
|
||||
port8: port@8 {
|
||||
reg = <8>;
|
||||
microchip,bandwidth = <1000>;
|
||||
phy-handle = <&phy12>;
|
||||
phy-mode = "qsgmii";
|
||||
phys = <&serdes 2>;
|
||||
};
|
||||
|
||||
port9: port@9 {
|
||||
reg = <9>;
|
||||
microchip,bandwidth = <1000>;
|
||||
phy-handle = <&phy13>;
|
||||
phy-mode = "qsgmii";
|
||||
phys = <&serdes 2>;
|
||||
};
|
||||
|
||||
port10: port@10 {
|
||||
reg = <10>;
|
||||
microchip,bandwidth = <1000>;
|
||||
phy-handle = <&phy14>;
|
||||
phy-mode = "qsgmii";
|
||||
phys = <&serdes 2>;
|
||||
};
|
||||
|
||||
port11: port@11 {
|
||||
reg = <11>;
|
||||
microchip,bandwidth = <1000>;
|
||||
phy-handle = <&phy15>;
|
||||
phy-mode = "qsgmii";
|
||||
phys = <&serdes 2>;
|
||||
};
|
||||
|
||||
port12: port@12 {
|
||||
reg = <12>;
|
||||
microchip,bandwidth = <1000>;
|
||||
phy-handle = <&phy16>;
|
||||
phy-mode = "qsgmii";
|
||||
phys = <&serdes 3>;
|
||||
};
|
||||
|
||||
port13: port@13 {
|
||||
reg = <13>;
|
||||
microchip,bandwidth = <1000>;
|
||||
phy-handle = <&phy17>;
|
||||
phy-mode = "qsgmii";
|
||||
phys = <&serdes 3>;
|
||||
};
|
||||
|
||||
port14: port@14 {
|
||||
reg = <14>;
|
||||
microchip,bandwidth = <1000>;
|
||||
phy-handle = <&phy18>;
|
||||
phy-mode = "qsgmii";
|
||||
phys = <&serdes 3>;
|
||||
};
|
||||
|
||||
port15: port@15 {
|
||||
reg = <15>;
|
||||
microchip,bandwidth = <1000>;
|
||||
phy-handle = <&phy19>;
|
||||
phy-mode = "qsgmii";
|
||||
phys = <&serdes 3>;
|
||||
};
|
||||
|
||||
port16: port@16 {
|
||||
reg = <16>;
|
||||
microchip,bandwidth = <1000>;
|
||||
phy-handle = <&phy20>;
|
||||
phy-mode = "qsgmii";
|
||||
phys = <&serdes 4>;
|
||||
};
|
||||
|
||||
port17: port@17 {
|
||||
reg = <17>;
|
||||
microchip,bandwidth = <1000>;
|
||||
phy-handle = <&phy21>;
|
||||
phy-mode = "qsgmii";
|
||||
phys = <&serdes 4>;
|
||||
};
|
||||
|
||||
port18: port@18 {
|
||||
reg = <18>;
|
||||
microchip,bandwidth = <1000>;
|
||||
phy-handle = <&phy22>;
|
||||
phy-mode = "qsgmii";
|
||||
phys = <&serdes 4>;
|
||||
};
|
||||
|
||||
port19: port@19 {
|
||||
reg = <19>;
|
||||
microchip,bandwidth = <1000>;
|
||||
phy-handle = <&phy23>;
|
||||
phy-mode = "qsgmii";
|
||||
phys = <&serdes 4>;
|
||||
};
|
||||
|
||||
port20: port@20 {
|
||||
reg = <20>;
|
||||
microchip,bandwidth = <1000>;
|
||||
phy-handle = <&phy24>;
|
||||
phy-mode = "qsgmii";
|
||||
phys = <&serdes 5>;
|
||||
};
|
||||
|
||||
port21: port@21 {
|
||||
reg = <21>;
|
||||
microchip,bandwidth = <1000>;
|
||||
phy-handle = <&phy25>;
|
||||
phy-mode = "qsgmii";
|
||||
phys = <&serdes 5>;
|
||||
};
|
||||
|
||||
port22: port@22 {
|
||||
reg = <22>;
|
||||
microchip,bandwidth = <1000>;
|
||||
phy-handle = <&phy26>;
|
||||
phy-mode = "qsgmii";
|
||||
phys = <&serdes 5>;
|
||||
};
|
||||
|
||||
port23: port@23 {
|
||||
reg = <23>;
|
||||
microchip,bandwidth = <1000>;
|
||||
phy-handle = <&phy27>;
|
||||
phy-mode = "qsgmii";
|
||||
phys = <&serdes 5>;
|
||||
};
|
||||
|
||||
port24: port@24 {
|
||||
reg = <24>;
|
||||
microchip,bandwidth = <10000>;
|
||||
phys = <&serdes 6>;
|
||||
phy-mode = "10gbase-r";
|
||||
sfp = <&sfp0>;
|
||||
microchip,sd-sgpio = <24>;
|
||||
managed = "in-band-status";
|
||||
};
|
||||
|
||||
port25: port@25 {
|
||||
reg = <25>;
|
||||
microchip,bandwidth = <10000>;
|
||||
phys = <&serdes 7>;
|
||||
phy-mode = "10gbase-r";
|
||||
sfp = <&sfp1>;
|
||||
microchip,sd-sgpio = <28>;
|
||||
managed = "in-band-status";
|
||||
};
|
||||
|
||||
port26: port@26 {
|
||||
reg = <26>;
|
||||
microchip,bandwidth = <10000>;
|
||||
phys = <&serdes 8>;
|
||||
phy-mode = "10gbase-r";
|
||||
sfp = <&sfp2>;
|
||||
microchip,sd-sgpio = <32>;
|
||||
managed = "in-band-status";
|
||||
};
|
||||
|
||||
port27: port@27 {
|
||||
reg = <27>;
|
||||
microchip,bandwidth = <10000>;
|
||||
phys = <&serdes 9>;
|
||||
phy-mode = "10gbase-r";
|
||||
sfp = <&sfp3>;
|
||||
microchip,sd-sgpio = <36>;
|
||||
managed = "in-band-status";
|
||||
};
|
||||
|
||||
port29: port@29 {
|
||||
reg = <29>;
|
||||
microchip,bandwidth = <1000>;
|
||||
phys = <&serdes 11>;
|
||||
phy-handle = <&phy3>;
|
||||
phy-mode = "rgmii";
|
||||
rx-internal-delay-ps = <1000>;
|
||||
tx-internal-delay-ps = <1000>;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
&usb {
|
||||
status = "okay";
|
||||
pinctrl-0 = <&usb_ulpi_pins>, <&usb_rst_pins>, <&usb_over_pins>, <&usb_power_pins>;
|
||||
pinctrl-names = "default";
|
||||
};
|
||||
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>;
|
||||
};
|
||||
};
|
||||
};
|
||||
23
target/linux/microchipsw/image/Makefile
Normal file
23
target/linux/microchipsw/image/Makefile
Normal file
@ -0,0 +1,23 @@
|
||||
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
|
||||
|
||||
include $(SUBTARGET).mk
|
||||
|
||||
$(eval $(call BuildImage))
|
||||
41
target/linux/microchipsw/image/lan969x.mk
Normal file
41
target/linux/microchipsw/image/lan969x.mk
Normal file
@ -0,0 +1,41 @@
|
||||
define Build/lan969x-fip
|
||||
cat $(STAGING_DIR_IMAGE)/$1-fip.bin >> $@
|
||||
endef
|
||||
|
||||
define Build/lan969x-gpt-emmc
|
||||
cp $@ $@.tmp 2>/dev/null || true
|
||||
ptgen -g -o $@.tmp -a 1 -l 1024 \
|
||||
-t 0x83 -N fip -r -p 8M@1M \
|
||||
-t 0x83 -N fip.bak -r -p 8M@9M \
|
||||
-t 0x83 -N Env -r -p 2M@17M \
|
||||
$(if $(findstring flash,$1), \
|
||||
-t 0x2e -N kernel -p $(CONFIG_TARGET_KERNEL_PARTSIZE)M@19M \
|
||||
-t 0x2e -N rootfs -p $(CONFIG_TARGET_ROOTFS_PARTSIZE)M
|
||||
)
|
||||
cat $@.tmp >> $@
|
||||
rm $@.tmp
|
||||
endef
|
||||
|
||||
define Build/append-kernel-part
|
||||
dd if=$(IMAGE_KERNEL) bs=$(CONFIG_TARGET_KERNEL_PARTSIZE)M conv=sync >> $@
|
||||
endef
|
||||
|
||||
define Device/microchip_ev23x71a
|
||||
$(call Device/FitImage)
|
||||
DEVICE_VENDOR := Microchip
|
||||
DEVICE_MODEL := EV23X71A
|
||||
SOC := lan9696
|
||||
DEVICE_PACKAGES := kmod-i2c-mux-gpio
|
||||
IMAGES += emmc-atf-gpt.gz emmc-gpt.img.gz
|
||||
IMAGE/emmc-atf-gpt.gz := lan969x-gpt-emmc |\
|
||||
pad-to 1M | lan969x-fip ev23x71a |\
|
||||
pad-to 9M | lan969x-fip ev23x71a |\
|
||||
gzip
|
||||
IMAGE/emmc-gpt.img.gz := lan969x-gpt-emmc flash |\
|
||||
pad-to 1M | lan969x-fip ev23x71a |\
|
||||
pad-to 9M | lan969x-fip ev23x71a |\
|
||||
pad-to 19M | append-kernel-part |\
|
||||
append-rootfs |\
|
||||
gzip
|
||||
endef
|
||||
TARGET_DEVICES += microchip_ev23x71a
|
||||
@ -0,0 +1,23 @@
|
||||
|
||||
. /lib/functions/uci-defaults.sh
|
||||
|
||||
board_config_update
|
||||
|
||||
board=$(board_name)
|
||||
|
||||
case "$board" in
|
||||
microchip,ev23x71a)
|
||||
ucidef_set_led_netdev "sfp1-link" "SFP1-LINK" "green:lan-0" "eth24" "link"
|
||||
ucidef_set_led_netdev "sfp1-traffic" "SFP1-TRAFFIC" "yellow:lan-0" "eth24" "tx rx"
|
||||
ucidef_set_led_netdev "sfp2-link" "SFP2-LINK" "green:lan-1" "eth25" "link"
|
||||
ucidef_set_led_netdev "sfp2-traffic" "SFP2-TRAFFIC" "yellow:lan-1" "eth25" "tx rx"
|
||||
ucidef_set_led_netdev "sfp3-link" "SFP3-LINK" "green:lan-2" "eth26" "link"
|
||||
ucidef_set_led_netdev "sfp3-traffic" "SFP3-TRAFFIC" "yellow:lan-2" "eth26" "tx rx"
|
||||
ucidef_set_led_netdev "sfp4-link" "SFP4-LINK" "green:lan-3" "eth27" "link"
|
||||
ucidef_set_led_netdev "sfp4-traffic" "SFP4-TRAFFIC" "yellow:lan-3" "eth27" "tx rx"
|
||||
;;
|
||||
esac
|
||||
|
||||
board_config_flush
|
||||
|
||||
exit 0
|
||||
@ -0,0 +1,25 @@
|
||||
|
||||
. /lib/functions/uci-defaults.sh
|
||||
. /lib/functions/system.sh
|
||||
|
||||
lan969x_setup_interfaces()
|
||||
{
|
||||
local board="$1"
|
||||
|
||||
case "$board" in
|
||||
microchip,ev23x71a)
|
||||
lan_list=$(ls -1 -v -d /sys/class/net/eth* | xargs -n1 basename | xargs)
|
||||
ucidef_set_interface_lan "$lan_list"
|
||||
;;
|
||||
*)
|
||||
echo "Unsupported hardware. Network interfaces not initialized"
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
board_config_update
|
||||
board=$(board_name)
|
||||
lan969x_setup_interfaces $board
|
||||
board_config_flush
|
||||
|
||||
exit 0
|
||||
@ -0,0 +1,31 @@
|
||||
PART_NAME=firmware
|
||||
REQUIRE_IMAGE_METADATA=1
|
||||
|
||||
RAMFS_COPY_BIN='fw_printenv fw_setenv'
|
||||
RAMFS_COPY_DATA='/etc/fw_env.config /var/lock/fw_printenv.lock'
|
||||
|
||||
platform_check_image() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
platform_do_upgrade() {
|
||||
case "$(board_name)" in
|
||||
microchip,ev23x71a)
|
||||
CI_KERNPART="kernel"
|
||||
CI_ROOTPART="rootfs"
|
||||
emmc_do_upgrade "$1"
|
||||
;;
|
||||
*)
|
||||
default_do_upgrade "$1"
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
platform_copy_config() {
|
||||
case "$(board_name)" in
|
||||
microchip,ev23x71a)
|
||||
emmc_copy_config
|
||||
;;
|
||||
esac
|
||||
return 0;
|
||||
}
|
||||
273
target/linux/microchipsw/lan969x/config-default
Normal file
273
target/linux/microchipsw/lan969x/config-default
Normal file
@ -0,0 +1,273 @@
|
||||
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_BLK_DEV_LOOP=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
|
||||
11
target/linux/microchipsw/lan969x/target.mk
Normal file
11
target/linux/microchipsw/lan969x/target.mk
Normal file
@ -0,0 +1,11 @@
|
||||
SUBTARGET:=lan969x
|
||||
BOARDNAME:=Microchip LAN969x switches
|
||||
FEATURES+= boot-part rootfs-part
|
||||
|
||||
DEFAULT_PACKAGES += kmod-usb3 kmod-usb-dwc3 \
|
||||
e2fsprogs kmod-fs-ext4 losetup \
|
||||
kmod-fs-f2fs f2fs-tools
|
||||
|
||||
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
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user