Merge Official Source

Signed-off-by: Tianling Shen <cnsztl@immortalwrt.org>
This commit is contained in:
Tianling Shen 2023-01-17 18:34:04 +08:00
commit 771411ebc4
No known key found for this signature in database
GPG Key ID: 6850B6345C862176
258 changed files with 41051 additions and 46 deletions

View File

@ -17,6 +17,7 @@ menu "Target Images"
default TARGET_INITRAMFS_COMPRESSION_LZMA if TARGET_lantiq
default TARGET_INITRAMFS_COMPRESSION_LZMA if TARGET_mpc85xx
default TARGET_INITRAMFS_COMPRESSION_LZMA if TARGET_ramips
default TARGET_INITRAMFS_COMPRESSION_ZSTD if TARGET_ipq807x
default TARGET_INITRAMFS_COMPRESSION_XZ if USES_SEPARATE_INITRAMFS
default TARGET_INITRAMFS_COMPRESSION_NONE
depends on TARGET_ROOTFS_INITRAMFS
@ -36,11 +37,9 @@ menu "Target Images"
bool "lzma"
config TARGET_INITRAMFS_COMPRESSION_LZO
depends on !TARGET_ROOTFS_INITRAMFS_SEPARATE
bool "lzo"
config TARGET_INITRAMFS_COMPRESSION_LZ4
depends on !TARGET_ROOTFS_INITRAMFS_SEPARATE
bool "lz4"
config TARGET_INITRAMFS_COMPRESSION_XZ

View File

@ -277,7 +277,9 @@ endef
define Build/initrd_compression
$(if $(CONFIG_TARGET_INITRAMFS_COMPRESSION_BZIP2),.bzip2) \
$(if $(CONFIG_TARGET_INITRAMFS_COMPRESSION_GZIP),.gzip) \
$(if $(CONFIG_TARGET_INITRAMFS_COMPRESSION_LZ4),.lz4) \
$(if $(CONFIG_TARGET_INITRAMFS_COMPRESSION_LZMA),.lzma) \
$(if $(CONFIG_TARGET_INITRAMFS_COMPRESSION_LZO),.lzo) \
$(if $(CONFIG_TARGET_INITRAMFS_COMPRESSION_XZ),.xz) \
$(if $(CONFIG_TARGET_INITRAMFS_COMPRESSION_ZSTD),.zstd)
endef

View File

@ -179,10 +179,10 @@ endif
$(if $(SOURCE_DATE_EPOCH),touch -hcd "@$(SOURCE_DATE_EPOCH)" $(KERNEL_BUILD_DIR)/initrd.cpio)
$(if $(CONFIG_TARGET_INITRAMFS_COMPRESSION_BZIP2),bzip2 -9 -c < $(KERNEL_BUILD_DIR)/initrd.cpio > $(KERNEL_BUILD_DIR)/initrd.cpio.bzip2)
$(if $(CONFIG_TARGET_INITRAMFS_COMPRESSION_GZIP),gzip -n -f -S .gzip -9n $(KERNEL_BUILD_DIR)/initrd.cpio)
$(if $(CONFIG_TARGET_INITRAMFS_COMPRESSION_LZ4),$(STAGING_DIR_HOST)/bin/lz4c -l -c1 -fz --favor-decSpeed $(KERNEL_BUILD_DIR)/initrd.cpio)
$(if $(CONFIG_TARGET_INITRAMFS_COMPRESSION_LZMA),$(STAGING_DIR_HOST)/bin/lzma e -lc1 -lp2 -pb2 $(KERNEL_BUILD_DIR)/initrd.cpio $(KERNEL_BUILD_DIR)/initrd.cpio.lzma)
# ? $(if $(CONFIG_TARGET_INITRAMFS_COMPRESSION_LZO),)
$(if $(CONFIG_TARGET_INITRAMFS_COMPRESSION_LZO),$(STAGING_DIR_HOST)/bin/lzop -9 -f $(KERNEL_BUILD_DIR)/initrd.cpio)
$(if $(CONFIG_TARGET_INITRAMFS_COMPRESSION_XZ),$(STAGING_DIR_HOST)/bin/xz -T$(if $(filter 1,$(NPROC)),2,0) -9 -fz --check=crc32 $(KERNEL_BUILD_DIR)/initrd.cpio)
# ? $(if $(CONFIG_TARGET_INITRAMFS_COMPRESSION_LZ4),)
$(if $(CONFIG_TARGET_INITRAMFS_COMPRESSION_ZSTD),$(STAGING_DIR_HOST)/bin/zstd -T0 -f -o $(KERNEL_BUILD_DIR)/initrd.cpio.zstd $(KERNEL_BUILD_DIR)/initrd.cpio)
endif
+$(KERNEL_MAKE) $(KERNEL_MAKEOPTS_IMAGE) $(if $(KERNELNAME),$(KERNELNAME),all) modules

View File

@ -0,0 +1,46 @@
[ -e /etc/config/ubootenv ] && exit 0
touch /etc/config/ubootenv
. /lib/uboot-envtools.sh
. /lib/functions.sh
board=$(board_name)
case "$board" in
dynalink,dl-wrx36)
idx="$(find_mtd_index 0:appsblenv)"
[ -n "$idx" ] && \
ubootenv_add_uci_config "/dev/mtd$idx" "0x0" "0x40000" "0x20000" "2"
;;
edgecore,eap102)
idx="$(find_mtd_index 0:appsblenv)"
[ -n "$idx" ] && \
ubootenv_add_uci_config "/dev/mtd$idx" "0x0" "0x10000" "0x10000" "1"
;;
edimax,cax1800)
idx="$(find_mtd_index 0:appsblenv)"
[ -n "$idx" ] && \
ubootenv_add_uci_config "/dev/mtd$idx" "0x0" "0x10000" "0x20000"
;;
redmi,ax6|\
xiaomi,ax3600|\
xiaomi,ax9000)
idx="$(find_mtd_index 0:appsblenv)"
[ -n "$idx" ] && \
ubootenv_add_uci_config "/dev/mtd$idx" "0x0" "0x10000" "0x20000"
idx2="$(find_mtd_index bdata)"
[ -n "$idx2" ] && \
ubootenv_add_uci_sys_config "/dev/mtd$idx2" "0x0" "0x10000" "0x20000"
;;
qnap,301w)
idx="$(find_mtd_index 0:appsblenv)"
[ -n "$idx" ] && \
ubootenv_add_uci_config "/dev/mtd$idx" "0x0" "0x20000" "0x20000" "1"
;;
esac
config_load ubootenv
config_foreach ubootenv_add_app_config
exit 0

View File

@ -0,0 +1,66 @@
#
# Copyright (C) 2022 OpenWrt.org
#
# This is free software, licensed under the GNU General Public License v2.
# See /LICENSE for more information.
#
include $(TOPDIR)/rules.mk
PKG_NAME:=ath11k-firmware
PKG_SOURCE_DATE:=2022-12-14
PKG_SOURCE_VERSION:=ab1229f94591ec4ffb16410e359b7f618be75a33
PKG_MIRROR_HASH:=48a2526971e56a3be1c80b72cd82b9932c196b4ab9b7d5dc35117f0548a8fe57
PKG_RELEASE:=1
PKG_SOURCE_PROTO:=git
PKG_SOURCE_URL:=https://github.com/kvalo/ath11k-firmware.git
PKG_LICENSE_FILES:=LICENSE.qca_firmware
PKG_MAINTAINER:=Robert Marko <robimarko@gmail.com>
include $(INCLUDE_DIR)/package.mk
RSTRIP:=:
STRIP:=:
define Package/ath11k-firmware-default
SECTION:=firmware
CATEGORY:=Firmware
URL:=$(PKG_SOURCE_URL)
DEPENDS:=
endef
define Package/ath11k-firmware-ipq8074
$(Package/ath11k-firmware-default)
TITLE:=IPQ8074 ath11k firmware
endef
define Package/ath11k-firmware-qcn9074
$(Package/ath11k-firmware-default)
TITLE:=QCN9074 ath11k firmware
endef
define Build/Compile
endef
define Package/ath11k-firmware-ipq8074/install
$(INSTALL_DIR) $(1)/lib/firmware/IPQ8074
$(INSTALL_DATA) \
$(PKG_BUILD_DIR)/IPQ8074/hw2.0/2.5.0.1/WLAN.HK.2.5.0.1-01208-QCAHKSWPL_SILICONZ-1/* \
$(1)/lib/firmware/IPQ8074/
endef
define Package/ath11k-firmware-qcn9074/install
$(INSTALL_DIR) $(1)/lib/firmware/ath11k/QCN9074/hw1.0
$(INSTALL_DATA) \
$(PKG_BUILD_DIR)/QCN9074/hw1.0/2.5.0.1/WLAN.HK.2.5.0.1-01208-QCAHKSWPL_SILICONZ-1/* \
$(1)/lib/firmware/ath11k/QCN9074/hw1.0/
$(INSTALL_BIN) \
$(PKG_BUILD_DIR)/QCN9074/hw1.0/board-2.bin $(1)/lib/firmware/ath11k/QCN9074/hw1.0/board-2.bin
endef
$(eval $(call BuildPackage,ath11k-firmware-ipq8074))
$(eval $(call BuildPackage,ath11k-firmware-qcn9074))

View File

@ -27,8 +27,11 @@ endef
ALLWIFIBOARDS:= \
aruba_ap-365 \
devolo_magic-2-wifi-next \
dynalink_dl-wrx36 \
edgecore_eap102 \
edgecore_ecw5410 \
edgecore_oap100 \
edimax_cax1800 \
extreme-networks_ws-ap3915i \
glinet_gl-a1300 \
glinet_gl-ap1300 \
@ -37,10 +40,14 @@ ALLWIFIBOARDS:= \
linksys_whw03v2 \
p2w_r619ac \
pakedge_wr-1 \
qnap_301w \
qxwlan_e2600ac-c1 \
qxwlan_e2600ac-c2 \
redmi_ax6 \
sony_ncp-hg100-cellular \
teltonika_rutx \
xiaomi_ax3600 \
xiaomi_ax9000 \
zte_mf18a \
zte_mf289f
@ -50,7 +57,7 @@ define Package/ipq-wifi-default
SUBMENU:=ath10k Board-Specific Overrides
SECTION:=firmware
CATEGORY:=Firmware
DEPENDS:=@(TARGET_ipq40xx||TARGET_ipq806x)
DEPENDS:=@(TARGET_ipq40xx||TARGET_ipq806x||TARGET_ipq807x)
TITLE:=Custom Board
endef
@ -59,17 +66,28 @@ define ipq-wifi-install-one-to
$(INSTALL_DATA) $(1) $(2)/lib/firmware/ath10k/$(3)/board-2.bin
endef
define ipq-wifi-install-ath11-one-to
$(INSTALL_DIR) $(2)/lib/firmware/ath11k/$(3)/
$(INSTALL_DATA) $(1) $(2)/lib/firmware/ath11k/$(3)/board-2.bin
endef
define ipq-wifi-install-one
$(if $(filter $(suffix $(1)),.QCA4019 .qca4019),\
$(call ipq-wifi-install-one-to,$(1),$(2),QCA4019/hw1.0),\
$(if $(filter $(suffix $(1)),.QCA9888 .qca9888),\
$(call ipq-wifi-install-one-to,$(1),$(2),QCA9888/hw2.0),\
$(if $(filter $(suffix $(1)),.QCA9889 .qca9889),\
$(call ipq-wifi-install-one-to,$(1),$(2),QCA9887/hw1.0),\
$(if $(filter $(suffix $(1)),.QCA9984 .qca9984),\
$(call ipq-wifi-install-one-to,$(1),$(2),QCA9984/hw1.0),\
$(if $(filter $(suffix $(1)),.QCA99X0 .qca99x0),\
$(call ipq-wifi-install-one-to,$(1),$(2),QCA99X0/hw2.0),\
$(if $(filter $(suffix $(1)),.IPQ8074 .ipq8074),\
$(call ipq-wifi-install-ath11-one-to,$(1),$(2),IPQ8074/hw2.0),\
$(if $(filter $(suffix $(1)),.QCN9074 .qcn9074),\
$(call ipq-wifi-install-ath11-one-to,$(1),$(2),QCN9074/hw1.0),\
$(error Unrecognized board-file suffix '$(suffix $(1))' for '$(1)')\
))))
)))))))
endef
# Blank line required at end of above define due to foreach context
@ -102,13 +120,16 @@ Do not install it for any other device!
endef
# Add board name to ALLWIFIBOARDS
# Place files in this directory as board-<devicename>.<qca4019|qca9888|qca9984|qca99x0>
# Place files in this directory as board-<devicename>.<qca4019|qca9888|qca9889|qca9984|qca99x0|ipq8074>
# Add $(eval $(call generate-ipq-wifi-package,<devicename>,<display name>))
$(eval $(call generate-ipq-wifi-package,aruba_ap-365,Aruba AP-365))
$(eval $(call generate-ipq-wifi-package,devolo_magic-2-wifi-next,devolo Magic 2 WiFi next))
$(eval $(call generate-ipq-wifi-package,dynalink_dl-wrx36,Dynalink DL-WRX36))
$(eval $(call generate-ipq-wifi-package,edgecore_eap102,Edgecore EAP102))
$(eval $(call generate-ipq-wifi-package,edgecore_ecw5410,Edgecore ECW5410))
$(eval $(call generate-ipq-wifi-package,edgecore_oap100,Edgecore OAP100))
$(eval $(call generate-ipq-wifi-package,edimax_cax1800,Edimax CAX1800))
$(eval $(call generate-ipq-wifi-package,extreme-networks_ws-ap3915i,Edgecore OAP100))
$(eval $(call generate-ipq-wifi-package,glinet_gl-a1300,GL.iNet GL-A1300))
$(eval $(call generate-ipq-wifi-package,glinet_gl-ap1300,GL.iNet GL-AP1300))
@ -117,10 +138,14 @@ $(eval $(call generate-ipq-wifi-package,linksys_ea8300,Linksys EA8300))
$(eval $(call generate-ipq-wifi-package,linksys_whw03v2,Linksys WHW03 V2))
$(eval $(call generate-ipq-wifi-package,p2w_r619ac,P&W R619AC))
$(eval $(call generate-ipq-wifi-package,pakedge_wr-1,Pakedge WR-1))
$(eval $(call generate-ipq-wifi-package,qnap_301w,QNAP 301w))
$(eval $(call generate-ipq-wifi-package,qxwlan_e2600ac-c1,Qxwlan E2600AC C1))
$(eval $(call generate-ipq-wifi-package,qxwlan_e2600ac-c2,Qxwlan E2600AC C2))
$(eval $(call generate-ipq-wifi-package,redmi_ax6,Redmi AX6))
$(eval $(call generate-ipq-wifi-package,sony_ncp-hg100-cellular,Sony NCP-HG100/Cellular))
$(eval $(call generate-ipq-wifi-package,teltonika_rutx,Teltonika RUTX))
$(eval $(call generate-ipq-wifi-package,xiaomi_ax3600,Xiaomi AX3600))
$(eval $(call generate-ipq-wifi-package,xiaomi_ax9000,Xiaomi AX9000))
$(eval $(call generate-ipq-wifi-package,zte_mf18a,ZTE MF18A))
$(eval $(call generate-ipq-wifi-package,zte_mf289f,ZTE MF289F))

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -32,7 +32,7 @@ define KernelPackage/ltq-ifxos
SUBMENU:=Libraries
TITLE:=Lantiq OS abstraction library
URL:=http://www.lantiq.com/
DEPENDS:=@TARGET_lantiq
DEPENDS:=@(TARGET_lantiq||TARGET_ipq40xx)
FILES:=$(PKG_BUILD_DIR)/src/drv_ifxos.ko
AUTOLOAD:=$(call AutoLoad,10,drv_ifxos)
endef
@ -44,13 +44,11 @@ CONFIGURE_ARGS += \
--enable-kernelincl="$(LINUX_DIR)/include" \
--with-kernel-module
ifdef CONFIG_TARGET_lantiq
define Build/InstallDev
define Build/InstallDev
$(INSTALL_DIR) $(1)/usr/{lib,include/ifxos}
$(CP) $(PKG_BUILD_DIR)/src/include/* $(1)/usr/include/ifxos
mkdir -p $(1)/usr/lib
$(CP) $(PKG_BUILD_DIR)/src/.libs/libifxos.a $(1)/usr/lib/libifxos.a
endef
endif
endef
$(eval $(call KernelPackage,ltq-ifxos))

View File

@ -0,0 +1,113 @@
# Copyright (C) 2012 OpenWrt.org
# Copyright (C) 2015-2016 Lantiq Beteiligungs GmbH & Co KG.
#
# This is free software, licensed under the GNU General Public License v2.
# See /LICENSE for more information.
include $(TOPDIR)/rules.mk
include $(INCLUDE_DIR)/kernel.mk
PKG_NAME:=ltq-vdsl-vr11-mei
PKG_VERSION:=1.11.1
PKG_RELEASE:=$(AUTORELEASE)
PKG_BASE_NAME:=dsl_cpe_mei
UGW_VERSION=8.5.2.10
UGW_BASENAME=$(PKG_BASE_NAME)-ugw_$(UGW_VERSION)
PKG_SOURCE:=$(UGW_BASENAME).tar.bz2
PKG_SOURCE_URL:=https://gitlab.com/prpl-foundation/intel/$(PKG_BASE_NAME)/-/archive/ugw_$(UGW_VERSION)/
PKG_HASH:=337614473d50ed64de010adaed99a16103e08eea8fc67fe9d6caf155bea33d1d
PKG_BUILD_DIR:=$(KERNEL_BUILD_DIR)/$(UGW_BASENAME)
PKG_LICENSE:=GPL-2.0 BSD-2-Clause
PKG_LICENSE_FILES:=LICENSE
PKG_EXTMOD_SUBDIRS:=src
PKG_FIXUP:=autoreconf
PKG_FLAGS:=nonshared
include $(INCLUDE_DIR)/package.mk
define KernelPackage/ltq-vdsl-vr11-mei
TITLE:=mei driver for vdsl
SECTION:=sys
SUBMENU:=Network Devices
DEPENDS:=@TARGET_ipq40xx +kmod-ltq-ifxos +kmod-vrx518_tc
FILES:=$(PKG_BUILD_DIR)/src/drv_mei_cpe.ko
AUTOLOAD:=$(call AutoLoad,50,drv_mei_cpe)
endef
define KernelPackage/ltq-vdsl-vr11-mei/description
Lantiq MEI CPE Kernel Module Driver
endef
define Package/ltq-vdsl-vr11-mei-test
SECTION:=net
CATEGORY:=Network
TITLE:=Lantiq mei driver test tool
URL:=http://www.lantiq.com/
DEPENDS:=@TARGET_ipq40xx +kmod-ltq-vdsl-vr11-mei
endef
define Package/ltq-vdsl-vr11-mei-test/description
Userland tool to directly control the mei driver, this is only needed
for test and development purposes.
endef
MAKE_FLAGS += \
$(KERNEL_MAKE_FLAGS) \
SHELL="$(BASH)"
# ltq-vdsl-app uses a header provided by the MEI driver which has some
# conditionals.
# Define the conditionals here to have the same view on both sides. If you
# change them, you need to change them for the ltq-vdsl-app as well
MEI_DRV_CFLAGS = \
-DMEI_DRV_ATM_PTM_INTERFACE_ENABLE=1 \
-DMEI_SUPPORT_DEBUG_STREAMS=1 \
-DMEI_SUPPORT_OPTIMIZED_FW_DL=1
#MEI_DRV_CFLAGS+= \
# -DMEI_SUPPORT_OPTIMIZED_FW_DL=0 \
# -DIRQ_POLLING_FORCE=99
CONFIGURE_ARGS += \
--enable-debug-logger-support=no
# --enable-debug-stream-support=no
# This looks weird, but it's necessary to address the right device.
# (pdev->dev.parent instead of pdev->dev)
MEI_DRV_CFLAGS+= \
-DMEI_TARGET_x86=1
CONFIGURE_ARGS += \
--enable-kernelincl="$(LINUX_DIR)/include" \
--enable-device=vr11 \
--enable-debug \
--enable-error_print \
--enable-ifxos-include="-I$(STAGING_DIR)/usr/include/ifxos/" \
--enable-ifxos-library="-L$(STAGING_DIR)/usr/lib" \
--enable-add_drv_cflags="$(MEI_DRV_CFLAGS)" \
--enable-linux-26 \
--enable-kernelbuild="$(LINUX_DIR)" \
--enable-drv_test_appl=yes \
ARCH=$(LINUX_KARCH)
define Build/InstallDev
$(INSTALL_DIR) $(1)/usr/include/vdsl
$(CP) $(PKG_BUILD_DIR)/src/drv_mei_cpe_api_intern.h $(1)/usr/include/vdsl/
$(CP) $(PKG_BUILD_DIR)/src/drv_mei_cpe_api_atm_ptm_intern.h $(1)/usr/include/vdsl/
$(CP) $(PKG_BUILD_DIR)/src/drv_mei_cpe_interface.h $(1)/usr/include/vdsl
$(CP) $(PKG_BUILD_DIR)/src/drv_mei_cpe_config.h $(1)/usr/include/vdsl/
$(CP) $(PKG_BUILD_DIR)/src/cmv_message_format.h $(1)/usr/include/vdsl/
endef
$(eval $(call KernelPackage,ltq-vdsl-vr11-mei))
define Package/ltq-vdsl-vr11-mei-test/install
$(INSTALL_DIR) $(1)/bin
$(INSTALL_BIN) $(PKG_BUILD_DIR)/src/mei_cpe_drv_test $(1)/bin
endef
$(eval $(call BuildPackage,ltq-vdsl-vr11-mei-test))

View File

@ -0,0 +1,88 @@
--- a/src/drv_mei_cpe_linux.c
+++ b/src/drv_mei_cpe_linux.c
@@ -1534,7 +1534,7 @@ struct proc_entry {
char name[32];
proc_rd_callback_t rd;
proc_wr_callback_t wr;
- struct file_operations ops;
+ struct proc_ops ops;
int entity;
};
@@ -2068,16 +2068,15 @@ static int mei_proc_single_open(struct i
static void mei_proc_entry_create(struct proc_dir_entry *parent_node,
struct proc_entry *proc_entry)
{
- memset(&proc_entry->ops, 0, sizeof(struct file_operations));
- proc_entry->ops.owner = THIS_MODULE;
+ memset(&proc_entry->ops, 0, sizeof(struct proc_ops));
- proc_entry->ops.open = mei_proc_single_open;
- proc_entry->ops.release = single_release;
+ proc_entry->ops.proc_open = mei_proc_single_open;
+ proc_entry->ops.proc_release = single_release;
- proc_entry->ops.read = seq_read;
- proc_entry->ops.llseek = seq_lseek;
+ proc_entry->ops.proc_read = seq_read;
+ proc_entry->ops.proc_lseek = seq_lseek;
if (proc_entry->wr)
- proc_entry->ops.write = proc_entry->wr;
+ proc_entry->ops.proc_write = proc_entry->wr;
proc_create_data(proc_entry->name,
(S_IFREG | S_IRUGO),
--- a/src/drv_mei_cpe_linux.h
+++ b/src/drv_mei_cpe_linux.h
@@ -31,6 +31,7 @@
#include <linux/module.h>
#include <linux/sched.h>
+#include <linux/sched/signal.h>
#include <linux/interrupt.h>
#include <linux/version.h>
#include <linux/crc32.h>
@@ -122,7 +123,7 @@ typedef int (*MEI_RequestIrq_WrapLinux_t
/**
Function typedef for the Linux free_irq()
*/
-typedef void (*MEI_FreeIrq_WrapLinux_t)( unsigned int usedIrq,
+typedef const void *(*MEI_FreeIrq_WrapLinux_t)( unsigned int usedIrq,
void *usedDevId );
--- a/src/drv_mei_cpe_linux_proc_config.c
+++ b/src/drv_mei_cpe_linux_proc_config.c
@@ -1277,13 +1277,12 @@ static int mei_proc_single_open(struct i
return single_open(file, mei_seq_single_show, PDE_DATA(inode));
}
-static struct file_operations proc_ops = {
- .owner = THIS_MODULE,
- .open = mei_proc_single_open,
- .release = single_release,
- .read = seq_read,
- .llseek = seq_lseek,
- .write = MEI_ProcWriteConfig
+static struct proc_ops proc_ops = {
+ .proc_open = mei_proc_single_open,
+ .proc_release = single_release,
+ .proc_read = seq_read,
+ .proc_lseek = seq_lseek,
+ .proc_write = MEI_ProcWriteConfig
};
/**
--- a/src/mei_cpe_appl_osmap.h
+++ b/src/mei_cpe_appl_osmap.h
@@ -38,10 +38,6 @@ extern "C"
#include <errno.h>
#include <ctype.h>
#include <sys/ioctl.h>
-
-extern int snprintf (char *__restrict __s, size_t __maxlen,
- __const char *__restrict __format, ...)
- __THROW __attribute__ ((__format__ (__printf__, 3, 4)));
#endif
/* ==========================================================================

View File

@ -0,0 +1,20 @@
--- a/src/drv_mei_cpe_dbg_driver.c
+++ b/src/drv_mei_cpe_dbg_driver.c
@@ -309,7 +309,7 @@ MEI_STATIC IFX_void_t MEI_DbgMsgDumpLogW
IFX_int32_t i;
unsigned short paylSize;
union {IFX_uint8_t d8[2]; IFX_uint16_t d16;} temp16;
- union {IFX_uint8_t d8[4]; IFX_uint16_t d32;} temp32;
+ union {IFX_uint8_t d8[4]; IFX_uint32_t d32;} temp32;
MEI_DbgMsgDumpLogLabel(pCmvMsg, fctOpCode);
@@ -368,7 +368,7 @@ MEI_STATIC IFX_void_t MEI_DbgMsgDumpTrcW
IFX_int32_t i;
unsigned short paylSize;
union {IFX_uint8_t d8[2]; IFX_uint16_t d16;} temp16;
- union {IFX_uint8_t d8[4]; IFX_uint16_t d32;} temp32;
+ union {IFX_uint8_t d8[4]; IFX_uint32_t d32;} temp32;
MEI_DbgMsgDumpTraceLabel(pCmvMsg, fctOpCode);

View File

@ -0,0 +1,12 @@
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -213,8 +213,7 @@ drv_mei_cpe_common_cflags = $(AM_CFLAGS)
else
drv_mei_cpe_common_cflags = \
- $(AM_CFLAGS) -D__KERNEL__ -DLINUX -D__linux__ -DMODULE -DEXPORT_SYMTAB \
- -pipe -Wall -Wimplicit -Wunused -Wuninitialized -Wstrict-aliasing -Wno-date-time
+ -D__KERNEL__ -DLINUX -D__linux__ -DMODULE -DEXPORT_SYMTAB
endif

View File

@ -0,0 +1,10 @@
--- a/src/drv_mei_cpe_linux.c
+++ b/src/drv_mei_cpe_linux.c
@@ -4530,7 +4530,6 @@ module_exit (MEI_module_exit);
#ifdef MODULE
MODULE_AUTHOR("www.lantiq.com");
MODULE_DESCRIPTION("MEI CPE Driver - www.lantiq.com");
-MODULE_SUPPORTED_DEVICE("MEI CPE Interface");
MODULE_LICENSE ("GPL");
#endif /* #ifdef MODULE*/

View File

@ -0,0 +1,13 @@
--- a/src/drv_mei_cpe_linux.c
+++ b/src/drv_mei_cpe_linux.c
@@ -1556,8 +1556,8 @@ static void MEI_GetVersionProc(struct se
}
seq_printf(s, "%s" MEI_DRV_CRLF, &MEI_WHATVERSION[4]);
- seq_printf(s, "Compiled on %s, %s for Linux kernel %s (jiffies: %ld)" MEI_DRV_CRLF,
- __DATE__, __TIME__, UTS_RELEASE, jiffies);
+ seq_printf(s, "Compiled for Linux kernel %s (jiffies: %ld)" MEI_DRV_CRLF,
+ UTS_RELEASE, jiffies);
}
/**

View File

@ -0,0 +1,12 @@
--- a/src/drv_mei_cpe_api_atm_ptm_intern.c
+++ b/src/drv_mei_cpe_api_atm_ptm_intern.c
@@ -152,6 +152,9 @@ IFX_int32_t MEI_InternalXtmSwhowtimeExit
/* Get line number*/
dslLineNum = pMeiDynCntrl->pMeiDev->meiDrvCntrl.dslLineNum;
+ g_tx_link_rate[dslLineNum][0] = 0;
+ g_tx_link_rate[dslLineNum][1] = 0;
+
#ifdef PPA_SUPPORTS_CALLBACKS
/* get NULL or function pointer */
mei_showtime_exit =

View File

@ -0,0 +1,10 @@
--- a/src/drv_mei_cpe_mei_access_vrx.c
+++ b/src/drv_mei_cpe_mei_access_vrx.c
@@ -1691,7 +1691,6 @@ IFX_int32_t MEI_InterfaceDetect(
{
MEI_REG_ACCESS_ME_VERSION_SET(pMeiDrvCntrl, 0x00000000);
hwVers = MEI_REG_ACCESS_ME_VERSION_GET(pMeiDrvCntrl);
- printk ("hwVers=0x%08X\n", hwVers);
if (MEI_DEVICE_CFG_IS_PLATFORM(e_MEI_DEV_PLATFORM_CONFIG_VR9))
{

View File

@ -0,0 +1,80 @@
# Copyright (C) 2012 OpenWrt.org
# Copyright (C) 2015-2016 Lantiq Beteiligungs GmbH & Co KG.
#
# This is free software, licensed under the GNU General Public License v2.
# See /LICENSE for more information.
include $(TOPDIR)/rules.mk
include $(INCLUDE_DIR)/kernel.mk
PKG_NAME:=ltq-vdsl-vr11
PKG_VERSION:=4.23.1
PKG_RELEASE:=$(AUTORELEASE)
PKG_BASE_NAME:=dsl_cpe_api
UGW_VERSION=8.5.2.10
UGW_BASENAME=$(PKG_BASE_NAME)-ugw_$(UGW_VERSION)
PKG_SOURCE:=$(UGW_BASENAME).tar.bz2
PKG_SOURCE_URL:=https://gitlab.com/prpl-foundation/intel/$(PKG_BASE_NAME)/-/archive/ugw_$(UGW_VERSION)/
PKG_HASH:=5e8bbab841d67dc16e329d9b3774f6db4189dd1d01f575d0e921ccf2c426dd9f
PKG_BUILD_DIR:=$(KERNEL_BUILD_DIR)/$(UGW_BASENAME)
PKG_LICENSE:=GPL-2.0 BSD-2-Clause
PKG_LICENSE_FILES:=LICENSE
PKG_FIXUP:=autoreconf
include $(INCLUDE_DIR)/package.mk
# TODO this driver depends on the vrx518 dsl firmware, add this dependency if
# that ever gets a compatible license
define KernelPackage/ltq-vdsl-vr11
TITLE:=vdsl driver
SECTION:=sys
SUBMENU:=Network Devices
DEPENDS:=@TARGET_ipq40xx +kmod-ltq-vdsl-vr11-mei
FILES:=$(PKG_BUILD_DIR)/src/drv_dsl_cpe_api.ko
AUTOLOAD:=$(call AutoLoad,51,drv_dsl_cpe_api)
endef
define Package/ltq-vdsl-vr11/description
This package contains the Lantiq DSL CPE API driver.
Supported Devices:
- VRX500 Family
endef
MAKE_FLAGS += \
$(KERNEL_MAKE_FLAGS) \
SHELL="$(BASH)"
CONFIGURE_ARGS += \
--enable-add-drv-cflags="" \
--enable-add_ext_drv_cflags="-DDSL_DRV_ATM_PTM_INTERFACE_ENABLE=1" \
--enable-debug-logger-support=no
CONFIGURE_ARGS += --enable-kernel-include="$(LINUX_DIR)/include" \
--enable-vrx \
--enable-vrx-device=vr11 \
--enable-ifxos \
--enable-ifxos-include="-I$(STAGING_DIR)/usr/include/ifxos" \
--enable-driver-include="-I$(STAGING_DIR)/usr/include/vdsl" \
--enable-linux-26 \
--enable-kernelbuild="$(LINUX_DIR)" \
--enable-debug-prints=no \
ARCH=$(LINUX_KARCH)
CONFIGURE_ARGS += \
--enable-model=full \
--enable-dsl-ceoc=no
#CONFIGURE_ARGS += --enable-model=lite
#CONFIGURE_ARGS += --enable-model=footprint
#CONFIGURE_ARGS += --enable-model=typical
#CONFIGURE_ARGS += --enable-model=debug
define Build/InstallDev
$(INSTALL_DIR) $(1)/usr/include/drv_vdsl_cpe_api
$(CP) $(PKG_BUILD_DIR)/src/include/drv_dsl_cpe*.h $(1)/usr/include/drv_vdsl_cpe_api/
endef
$(eval $(call KernelPackage,ltq-vdsl-vr11))

View File

@ -0,0 +1,84 @@
--- a/src/include/drv_dsl_cpe_os_linux.h
+++ b/src/include/drv_dsl_cpe_os_linux.h
@@ -36,6 +36,7 @@
#endif
#include <linux/sched.h>
+#include <linux/sched/signal.h>
#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,33))
#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,17))
--- a/configure.in
+++ b/configure.in
@@ -422,7 +422,7 @@ AC_ARG_ENABLE(debug-prints,
AC_SUBST([DSL_DBG_MAX_LEVEL_SET],[no])
AC_SUBST([DSL_DBG_MAX_LEVEL_PRE],[n/a])
- AC_SUBST([INCLUDE_DSL_CPE_DEBUG_LOGGER_SUPPORT],[no])
+ AC_SUBST([INCLUDE_DSL_CPE_DEBUG_LOGGER_SUPPORT],[yes])
;;
no | none )
AC_DEFINE(DSL_DEBUG_DISABLE,,[Disabled debug prints])
@@ -433,7 +433,7 @@ AC_ARG_ENABLE(debug-prints,
AC_SUBST([DSL_DBG_MAX_LEVEL_SET],[no])
AC_SUBST([DSL_DBG_MAX_LEVEL_PRE],[n/a])
- AC_SUBST([INCLUDE_DSL_CPE_DEBUG_LOGGER_SUPPORT],[yes])
+ AC_SUBST([INCLUDE_DSL_CPE_DEBUG_LOGGER_SUPPORT],[no])
;;
prn | 0x1 )
AC_SUBST([DSL_DEBUG_DISABLE],[no])
--- a/src/common/drv_dsl_cpe_api.c
+++ b/src/common/drv_dsl_cpe_api.c
@@ -88,8 +88,12 @@ static DSL_uint32_t g_VRxPD_IOctlWhiteli
DSL_FIO_BAND_PLAN_STATUS_GET,
DSL_FIO_DBG_MODULE_LEVEL_GET,
DSL_FIO_DBG_MODULE_LEVEL_SET,
+#ifdef INCLUDE_DSL_CPE_DEBUG_LOGGER_SUPPORT
+#ifndef DSL_DEBUG_DISABLE
DSL_FIO_DBG_MODULE_DESTINATION_GET,
DSL_FIO_DBG_MODULE_DESTINATION_SET,
+#endif /* DSL_DEBUG_DISABLE*/
+#endif /* INCLUDE_DSL_CPE_DEBUG_LOGGER_SUPPORT */
DSL_FIO_OPERATOR_CONFIG_GET,
DSL_FIO_OPERATOR_CONFIG_SET,
/* Delimeter only. Keep it! */
--- a/src/common/drv_dsl_cpe_os_linux.c
+++ b/src/common/drv_dsl_cpe_os_linux.c
@@ -625,7 +625,7 @@ DSL_void_t* DSL_DRV_VMalloc(
DSL_DRV_size_t nSize)
{
/* VRX500-BU: Better to use vmalloc or vzmalloc here?! */
- return __vmalloc((unsigned long)nSize, GFP_KERNEL, PAGE_KERNEL);
+ return __vmalloc((unsigned long)nSize, GFP_KERNEL);
/* return vmalloc(nSize);*/
}
--- a/src/include/drv_dsl_cpe_debug.h
+++ b/src/include/drv_dsl_cpe_debug.h
@@ -99,6 +99,7 @@ DSL_void_t DSL_DRV_ErrorSet(DSL_void_t *
/** Terminate execution if assertion fails */
#define DSL_ASSERT(exp) ((void)0)
+ #define DSL_DEBUG_LIMIT(level, body) ((void)0)
#else
#define DSL_DEBUG_SET_ERROR(code) DSL_DRV_ErrorSet(pContext, code);
--- a/src/pm/drv_dsl_cpe_pm_core.c
+++ b/src/pm/drv_dsl_cpe_pm_core.c
@@ -26,6 +26,7 @@
#define DSL_DBG_BLOCK DSL_DBG_PM
#ifdef __LINUX__
+#ifndef DSL_DEBUG_DISABLE
#define DSL_PM_CORE_RATELIMIT_INTERVAL 20 * HZ /* for each 20 seconds */
#define DSL_PM_CORE_RATELIMIT_BURST 1 /* 1 occurrence */
/* struct ratelimit_state to be used in DSL_DEBUG_LIMIT */
@@ -33,6 +34,7 @@ static DEFINE_RATELIMIT_STATE(
DSL_DBG_RATELIMIT_STRUCT_NAME(DSL_DBG_BLOCK),
DSL_PM_CORE_RATELIMIT_INTERVAL,
DSL_PM_CORE_RATELIMIT_BURST);
+#endif
#endif/* __LINUX__ */
DSL_boolean_t DSL_DRV_PM_IsPmReady(

View File

@ -0,0 +1,23 @@
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -283,10 +283,7 @@ else
drv_dsl_cpe_api_common_mod_cflags =
endif
-drv_dsl_cpe_api_common_cflags = -DLINUX -D__LINUX__ -D__KERNEL__ -DEXPORT_SYMTAB \
- -pipe -Wall -Wformat -Wimplicit -Wunused -Wswitch -Wcomment -Winline \
- -Wuninitialized -Wparentheses -Wreturn-type \
- -Wstrict-prototypes -Wno-trigraphs -fno-strict-aliasing -fno-common
+drv_dsl_cpe_api_common_cflags = -DLINUX -D__LINUX__ -D__KERNEL__ -DEXPORT_SYMTAB
if DSL_DBG_MAX_LEVEL_SET
drv_dsl_cpe_api_common_cflags += -DDSL_DBG_MAX_LEVEL=$(DSL_DBG_MAX_LEVEL_PRE)
@@ -296,7 +293,7 @@ endif
drv_dsl_cpe_api_target_cflags = $(ADD_DRV_CFLAGS)
# compile cflags
-drv_dsl_cpe_api_compile_cflags = $(EXTRA_DRV_CFLAGS)
+drv_dsl_cpe_api_compile_cflags =
if !KERNEL_2_6
# the headerfile of linux kernels 2.6.x contain to much arithmetic

View File

@ -0,0 +1,18 @@
--- a/src/common/drv_dsl_cpe_os_linux.c
+++ b/src/common/drv_dsl_cpe_os_linux.c
@@ -1051,12 +1051,11 @@ DSL_int32_t DSL_DRV_ThreadShutdown(
DSL_uint32_t DSL_DRV_SysTimeGet(DSL_uint32_t nOffset)
{
- struct timeval tv;
+ struct timespec64 now;
DSL_uint32_t nTime = 0;
- memset(&tv, 0, sizeof(tv));
- do_gettimeofday(&tv);
- nTime = (DSL_uint32_t)tv.tv_sec;
+ ktime_get_real_ts64(&now);
+ nTime = (DSL_uint32_t)now.tv_sec;
if ( (nOffset == 0) || (nOffset > nTime) )
{

View File

@ -0,0 +1,122 @@
--- a/src/include/drv_dsl_cpe_pm_core.h
+++ b/src/include/drv_dsl_cpe_pm_core.h
@@ -1554,9 +1554,9 @@ typedef struct
DSL_boolean_t bShowtimeProcessingStart;
/** Showtime reached flag*/
DSL_boolean_t bShowtimeInvTrigger;
- /** Current Showtime synchronization time to be used, (msec) */
+ /** Current Showtime synchronization time to be used, (sec) */
DSL_uint32_t nCurrShowtimeTime;
- /** Showtime synchronization time to be used, (msec) */
+ /** Showtime synchronization time to be used, (sec) */
DSL_uint32_t nElapsedShowtimeTime;
/** Actual Line state*/
DSL_LineStateValue_t nLineState;
--- a/src/pm/drv_dsl_cpe_api_pm.c
+++ b/src/pm/drv_dsl_cpe_api_pm.c
@@ -1633,7 +1633,7 @@ DSL_Error_t DSL_DRV_PM_ChannelCountersTo
}
/* Fill Total Counters elapsed time*/
- pCounters->total.nElapsedTime = DSL_DRV_PM_CONTEXT(pContext)->nPmTotalElapsedTime/DSL_PM_MSEC;
+ pCounters->total.nElapsedTime = DSL_DRV_PM_CONTEXT(pContext)->nPmTotalElapsedTime;
pChCounters = DSL_DRV_PM_PTR_CHANNEL_COUNTERS_TOTAL(pCounters->nChannel,pCounters->nDirection);
@@ -1693,7 +1693,7 @@ DSL_Error_t DSL_DRV_PM_ChannelCountersEx
}
/* Fill Total Counters elapsed time*/
- pCounters->total.nElapsedTime = DSL_DRV_PM_CONTEXT(pContext)->nPmTotalElapsedTime/DSL_PM_MSEC;
+ pCounters->total.nElapsedTime = DSL_DRV_PM_CONTEXT(pContext)->nPmTotalElapsedTime;
pChCounters = DSL_DRV_PM_PTR_CHANNEL_COUNTERS_TOTAL_EXT(pCounters->nChannel);
@@ -2764,7 +2764,7 @@ DSL_Error_t DSL_DRV_PM_DataPathCountersT
}
/* Fill Total Counters elapsed time*/
- pCounters->total.nElapsedTime = DSL_DRV_PM_CONTEXT(pContext)->nPmTotalElapsedTime/DSL_PM_MSEC;
+ pCounters->total.nElapsedTime = DSL_DRV_PM_CONTEXT(pContext)->nPmTotalElapsedTime;
pDpCounters = DSL_DRV_PM_PTR_DATAPATH_COUNTERS_TOTAL(pCounters->nChannel,pCounters->nDirection);
@@ -3678,7 +3678,7 @@ DSL_Error_t DSL_DRV_PM_DataPathFailureCo
}
/* Fill Total Counters elapsed time*/
- pCounters->total.nElapsedTime = DSL_DRV_PM_CONTEXT(pContext)->nPmTotalElapsedTime/DSL_PM_MSEC;
+ pCounters->total.nElapsedTime = DSL_DRV_PM_CONTEXT(pContext)->nPmTotalElapsedTime;
pDpCounters = DSL_DRV_PM_PTR_DATAPATH_FAILURE_COUNTERS_TOTAL(pCounters->nChannel,pCounters->nDirection);
@@ -4536,7 +4536,7 @@ DSL_Error_t DSL_DRV_PM_LineSecCountersTo
}
/* Fill Total Counters elapsed time*/
- pCounters->total.nElapsedTime = DSL_DRV_PM_CONTEXT(pContext)->nPmTotalElapsedTime/DSL_PM_MSEC;
+ pCounters->total.nElapsedTime = DSL_DRV_PM_CONTEXT(pContext)->nPmTotalElapsedTime;
pLineCounters = DSL_DRV_PM_PTR_LINE_SEC_COUNTERS_TOTAL(pCounters->nDirection);
@@ -5273,7 +5273,7 @@ DSL_Error_t DSL_DRV_PM_LineInitCountersT
}
/* Fill Total Counters elapsed time*/
- pCounters->total.nElapsedTime = DSL_DRV_PM_CONTEXT(pContext)->nPmTotalElapsedTime/DSL_PM_MSEC;
+ pCounters->total.nElapsedTime = DSL_DRV_PM_CONTEXT(pContext)->nPmTotalElapsedTime;
pLinitCounters = DSL_DRV_PM_PTR_LINE_INIT_COUNTERS_TOTAL();
@@ -5774,7 +5774,7 @@ DSL_Error_t DSL_DRV_PM_LineEventShowtime
}
/* Fill Total Counters elapsed time*/
- pCounters->total.nElapsedTime = DSL_DRV_PM_CONTEXT(pContext)->nPmTotalElapsedTime/DSL_PM_MSEC;
+ pCounters->total.nElapsedTime = DSL_DRV_PM_CONTEXT(pContext)->nPmTotalElapsedTime;
pLfCounters = DSL_DRV_PM_PTR_LINE_EVENT_SHOWTIME_COUNTERS_TOTAL(pCounters->nDirection);
@@ -6302,7 +6302,7 @@ DSL_Error_t DSL_DRV_PM_ReTxCountersTotal
}
/* Fill Total Counters elapsed time*/
- pCounters->total.nElapsedTime = DSL_DRV_PM_CONTEXT(pContext)->nPmTotalElapsedTime/DSL_PM_MSEC;
+ pCounters->total.nElapsedTime = DSL_DRV_PM_CONTEXT(pContext)->nPmTotalElapsedTime;
pReTxCounters = DSL_DRV_PM_PTR_RETX_COUNTERS_TOTAL(pCounters->nDirection);
--- a/src/pm/drv_dsl_cpe_pm_core.c
+++ b/src/pm/drv_dsl_cpe_pm_core.c
@@ -78,6 +78,7 @@ static DSL_Error_t DSL_DRV_PM_SyncTimeUp
{
DSL_Error_t nErrCode = DSL_SUCCESS;
DSL_uint32_t msecTimeFrame = DSL_PM_COUNTER_POLLING_CYCLE,
+ secTimeFrame = DSL_PM_COUNTER_POLLING_CYCLE/DSL_PM_MSEC,
nCurrMsTime = 0;
#ifdef INCLUDE_DSL_CPE_PM_HISTORY
DSL_uint32_t nCurrSysTime = 0, nPrevElapsedTime = 0;
@@ -117,10 +118,13 @@ static DSL_Error_t DSL_DRV_PM_SyncTimeUp
{
/* Get elapsed time [msec] since the last entry*/
msecTimeFrame = nCurrMsTime - DSL_DRV_PM_CONTEXT(pContext)->nLastMsTimeCheck;
+
+ /* Get elapsed time [sec] since the last entry*/
+ secTimeFrame = (nCurrMsTime/DSL_PM_MSEC) - (DSL_DRV_PM_CONTEXT(pContext)->nLastMsTimeCheck/DSL_PM_MSEC);
}
/* Get Total Elapsed Time Since the PM module startup*/
- DSL_DRV_PM_CONTEXT(pContext)->nPmTotalElapsedTime += msecTimeFrame;
+ DSL_DRV_PM_CONTEXT(pContext)->nPmTotalElapsedTime += secTimeFrame;
/* Set last time check to the current time*/
DSL_DRV_PM_CONTEXT(pContext)->nLastMsTimeCheck = nCurrMsTime;
@@ -158,7 +162,7 @@ static DSL_Error_t DSL_DRV_PM_SyncTimeUp
else
{
/* Update current showtime elapsed time*/
- DSL_DRV_PM_CONTEXT(pContext)->nCurrShowtimeTime += (msecTimeFrame/DSL_PM_MSEC);
+ DSL_DRV_PM_CONTEXT(pContext)->nCurrShowtimeTime += secTimeFrame;
DSL_DRV_PM_CONTEXT(pContext)->nElapsedShowtimeTime =
DSL_DRV_PM_CONTEXT(pContext)->nCurrShowtimeTime;
}

View File

@ -0,0 +1,22 @@
--- a/src/pm/drv_dsl_cpe_api_pm_vrx.c
+++ b/src/pm/drv_dsl_cpe_api_pm_vrx.c
@@ -1482,9 +1482,16 @@ DSL_Error_t DSL_DRV_PM_DEV_ReTxCountersG
/* ignore zero value*/
if (nEftrMin)
{
- /* Fw Format: kBit/s */
- /* API format: bit/s */
- pCounters->nEftrMin = nEftrMin*1000;
+ if (nDirection == DSL_NEAR_END)
+ {
+ /* Fw Format: kBit/s */
+ /* API format: bit/s */
+ pCounters->nEftrMin = nEftrMin*1000;
+ }
+ else
+ {
+ pCounters->nEftrMin = nEftrMin;
+ }
}
}
else

View File

@ -0,0 +1,57 @@
#
# Copyright (C) 2019 OpenWrt.org
#
# This is free software, licensed under the GNU General Public License v2.
# See /LICENSE for more information.
#
include $(TOPDIR)/rules.mk
include $(INCLUDE_DIR)/kernel.mk
PKG_NAME:=vrx518_ep
PKG_VERSION:=2.1.0
PKG_RELEASE:=$(AUTORELEASE)
PKG_LICENSE:=GPL-2.0
include $(INCLUDE_DIR)/package.mk
# TODO this driver depends on the vrx518 aca firmware, add this dependency if
# that ever gets a compatible license
define KernelPackage/vrx518_ep
SECTION:=sys
CATEGORY:=Kernel modules
SUBMENU:=Network Devices
TITLE:=VRX518 EP Support
DEPENDS:=@TARGET_ipq40xx
AUTOLOAD:=$(call AutoLoad,26,vrx518)
FILES:=$(PKG_BUILD_DIR)/vrx518.ko
endef
define KernelPackage/vrx518_ep/description
VRX518 endpoint driver
endef
define Build/InstallDev
$(INSTALL_DIR) $(1)/usr/include/net/
$(CP) $(PKG_BUILD_DIR)/include/net/dc_ep.h $(1)/usr/include/net/
endef
EXTRA_KCONFIG:= \
CONFIG_VRX518=m
# CONFIG_TEST=m
# CONFIG_VRX518_PCIE_SWITCH_BONDING=y
EXTRA_CFLAGS:= \
$(patsubst CONFIG_%, -DCONFIG_%=1, $(patsubst %=m,%,$(filter %=m,$(EXTRA_KCONFIG)))) \
$(patsubst CONFIG_%, -DCONFIG_%=1, $(patsubst %=y,%,$(filter %=y,$(EXTRA_KCONFIG)))) \
-I$(PKG_BUILD_DIR)/include
define Build/Compile
$(KERNEL_MAKE) \
M="$(PKG_BUILD_DIR)" \
EXTRA_CFLAGS="$(EXTRA_CFLAGS)" \
$(EXTRA_KCONFIG) \
modules
endef
$(eval $(call KernelPackage,vrx518_ep))

View File

@ -0,0 +1,73 @@
--- a/ep.c
+++ b/ep.c
@@ -373,23 +373,23 @@ int dc_ep_dev_info_req(int dev_idx, enum
switch (module) {
case DC_EP_INT_PPE:
- dev->irq = priv->irq_base;
+ dev->irq = pci_irq_vector(priv->pdev, 0);
if (priv->msi_mode == DC_EP_8_MSI_MODE) {
- dev->aca_tx_irq = priv->irq_base + 7;
- dev->aca_rx_irq = priv->irq_base + 6;
+ dev->aca_tx_irq = pci_irq_vector(priv->pdev, 7);
+ dev->aca_rx_irq = pci_irq_vector(priv->pdev, 6);
} else if (priv->msi_mode == DC_EP_4_MSI_MODE) {
- dev->aca_tx_irq = priv->irq_base + 2;
- dev->aca_rx_irq = priv->irq_base + 3;
+ dev->aca_tx_irq = pci_irq_vector(priv->pdev, 2);
+ dev->aca_rx_irq = pci_irq_vector(priv->pdev, 3);
} else {
dev_err(dev->dev, "%s ACA should never occur\n",
__func__);
}
break;
case DC_EP_INT_MEI:
- dev->irq = priv->irq_base + 1;
+ dev->irq = pci_irq_vector(priv->pdev, 1);
break;
default:
- dev->irq = priv->irq_base;
+ dev->irq = pci_irq_vector(priv->pdev, 0);
break;
}
@@ -466,8 +466,8 @@ static int dc_ep_msi_enable(struct pci_d
return -EIO;
}
- err = pci_enable_msi_exact(pdev, nvec);
- if (err) {
+ err = pci_alloc_irq_vectors(pdev, nvec, nvec, PCI_IRQ_MSI | PCI_IRQ_LEGACY);
+ if (err < 0) {
dev_err(&pdev->dev,
"%s: Failed to enable MSI interrupts error code: %d\n",
__func__, err);
@@ -654,7 +654,7 @@ static int dc_ep_probe(struct pci_dev *p
goto err_iomap;
spin_lock(&dc_ep_lock);
- priv->irq_base = pdev->irq;
+ priv->irq_base = pci_irq_vector(pdev, 0);
spin_unlock(&dc_ep_lock);
#ifndef CONFIG_OF
@@ -715,7 +715,7 @@ static void dc_ep_remove(struct pci_dev
dc_ep_icu_disable(priv);
pci_iounmap(pdev, priv->mem);
pci_release_region(pdev, DC_EP_BAR_NUM);
- pci_disable_msi(pdev);
+ pci_free_irq_vectors(pdev);
wmb();
pci_clear_master(pdev);
pci_disable_device(pdev);
--- a/aca.c
+++ b/aca.c
@@ -756,7 +756,7 @@ static void aca_hif_param_init_done(stru
addr = fw_param->init_addr;
dev_dbg(priv->dev, "init_addr: %x\n", addr);
memcpy_toio(priv->mem + addr, hif_params, sizeof(*hif_params));
- kzfree(hif_params);
+ kfree(hif_params);
dev_dbg(priv->dev, "%s\n", __func__);
}

View File

@ -0,0 +1,49 @@
Fix double negation of bitmask in dc_ep_icu_disable andwr32_mask.
Also add locking to ensure the masking is applied atomically.
--- a/misc.c
+++ b/misc.c
@@ -68,12 +68,22 @@ void dc_ep_icu_disable(struct dc_ep_priv
void dc_ep_icu_dis_intr(struct dc_ep_priv *priv, u32 bits)
{
- wr32_mask(~bits, 0, ICU_IMER);
+ struct dc_aca *aca = to_aca(priv);
+ unsigned long flags;
+
+ spin_lock_irqsave(&aca->icu_lock, flags);
+ wr32_mask(bits, 0, ICU_IMER);
+ spin_unlock_irqrestore(&aca->icu_lock, flags);
}
void dc_ep_icu_en_intr(struct dc_ep_priv *priv, u32 bits)
{
+ struct dc_aca *aca = to_aca(priv);
+ unsigned long flags;
+
+ spin_lock_irqsave(&aca->icu_lock, flags);
wr32_mask(0, bits, ICU_IMER);
+ spin_unlock_irqrestore(&aca->icu_lock, flags);
}
void dc_ep_assert_device(struct dc_ep_priv *priv, u32 bits)
--- a/aca.c
+++ b/aca.c
@@ -1158,6 +1158,7 @@ void dc_aca_info_init(struct dc_ep_priv
struct dc_aca *aca = to_aca(priv);
aca->initialized = false;
+ spin_lock_init(&aca->icu_lock);
spin_lock_init(&aca->clk_lock);
spin_lock_init(&aca->rcu_lock);
mutex_init(&aca->pin_lock);
--- a/aca.h
+++ b/aca.h
@@ -470,6 +470,7 @@ struct aca_hif_params {
struct dc_aca {
bool initialized;
+ spinlock_t icu_lock;
spinlock_t clk_lock;
spinlock_t rcu_lock;
struct mutex pin_lock;

View File

@ -0,0 +1,9 @@
config TEST
tristate "Intel(R) VRX518 SmartPHY DSL Test Driver"
depends on VRX518
---help---
This driver supports Intel(R) VRX518 DSL interrupt and ACA test.
To compile this driver as a module, choose M here. The module
will be called vrx518. MSI interrupt support is required for
this driver to work correctly.

View File

@ -0,0 +1,33 @@
################################################################################
#
# Intel SmartPHY DSL PCIe EP/ACA Linux driver
# Copyright(c) 2016 Intel Corporation.
#
# This program is free software; you can redistribute it and/or modify it
# under the terms and conditions of the GNU General Public License,
# version 2, as published by the Free Software Foundation.
#
# This program is distributed in the hope it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
# more details.
#
# You should have received a copy of the GNU General Public License along with
# this program; if not, write to the Free Software Foundation, Inc.,
# 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
#
# The full GNU General Public License is included in this distribution in
# the file called "COPYING".
#
################################################################################
#
# Makefile for the Intel(R) SmartPHY PCIe/ACA driver
#
obj-$(CONFIG_VRX518) += vrx518.o
vrx518-objs := ep.o aca.o misc.o
obj-$(CONFIG_TEST) += test/

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,481 @@
/*******************************************************************************
Intel SmartPHY DSL PCIe Endpoint/ACA Linux driver
Copyright(c) 2016 Intel Corporation.
This program is free software; you can redistribute it and/or modify it
under the terms and conditions of the GNU General Public License,
version 2, as published by the Free Software Foundation.
This program is distributed in the hope it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
more details.
You should have received a copy of the GNU General Public License along with
this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
The full GNU General Public License is included in this distribution in
the file called "COPYING".
*******************************************************************************/
#ifndef ACA_H
#define ACA_H
#define HOST_IF_BASE 0x50000
#define ACA_CORE_BASE 0x50800
#define GENRISC_IRAM_BASE 0x58000
#define GENRISC_SPRAM_BASE 0x5C000
#define GENRISC_BASE 0x5D000
#define MAC_HT_EXT_BASE 0x5D400
#define ACA_SRAM_BASE 0x100000
#define ACA_SRAM_SIZE 0x2000 /* Project specific */
#define ACA_HOSTIF_ADDR_SHIFT 2
#define ACA_HOSTIF_ADDR(addr) ((addr) >> ACA_HOSTIF_ADDR_SHIFT)
#define ACA_HIF_LOC_POS 0x100060
#define ACA_HIF_PARAM_ADDR 0x100064
#define ACA_ACC_FW_SIZE 0x400
#define ACA_LOOP_CNT 1000
/* TODO: change name after karthik explained */
#define TXIN_DST_OWNBIT 0xC4
#define TXOUT_DST_OWNBIT 0x1C4
#define RXOUT_SRC_OWNBIT 0x3C4
#define RXIN_DST_OWNBIT 0x2C4
/* Genrisc Internal Host Descriptor(Ping/Pong) decided by ACA fw header */
/* ACA Core */
#define ACA_CORE_REG(X) (ACA_CORE_BASE + (X))
#define TXIN_CFG1 ACA_CORE_REG(0x0)
#define TXIN_CFG2 ACA_CORE_REG(0x4)
#define TXIN_CFG3 ACA_CORE_REG(0x8)
#define TXIN_DST_OWWBIT_CFG4 ACA_CORE_REG(TXIN_DST_OWNBIT)
#define TXOUT_CFG1 ACA_CORE_REG(0x100)
#define TXOUT_CFG2 ACA_CORE_REG(0x104)
#define TXOUT_CFG3 ACA_CORE_REG(0x108)
#define TXOUT_DST_OWWBIT_CFG4 ACA_CORE_REG(TXOUT_DST_OWNBIT)
#define RXOUT_CFG1 ACA_CORE_REG(0x300)
#define RXOUT_CFG2 ACA_CORE_REG(0x304)
#define RXOUT_CFG3 ACA_CORE_REG(0x308)
#define RXOUT_SRC_OWNBIT_CFG3 ACA_CORE_REG(RXOUT_SRC_OWNBIT)
#define RXIN_CFG1 ACA_CORE_REG(0x200)
#define RXIN_CFG2 ACA_CORE_REG(0x204)
#define RXIN_CFG3 ACA_CORE_REG(0x208)
#define RXIN_SRC_OWNBIT_CFG3 ACA_CORE_REG(RXIN_DST_OWNBIT)
/* Genrisc */
#define GNRC_REG(X) (GENRISC_BASE + (X))
#define GNRC_STOP_OP GNRC_REG(0x60)
#define GNRC_CONTINUE_OP GNRC_REG(0x64)
#define GNRC_START_OP GNRC_REG(0x90)
/* HOST Interface Register */
#define HOST_IF_REG(X) (HOST_IF_BASE + (X))
#define HD_DESC_IN_DW 0x7u
#define HD_DESC_IN_DW_S 0
#define PD_DESC_IN_DW 0x70u
#define PD_DESC_IN_DW_S 4
#define BYTE_SWAP_EN BIT(28)
#define TXIN_CONV_CFG HOST_IF_REG(0x14)
#define TXOUT_CONV_CFG HOST_IF_REG(0x18)
#define RXIN_CONV_CFG HOST_IF_REG(0x1C)
#define RXOUT_CONV_CFG HOST_IF_REG(0x20)
#define TXIN_COUNTERS HOST_IF_REG(0x44)
#define TXOUT_COUNTERS HOST_IF_REG(0x48)
#define RXIN_COUNTERS HOST_IF_REG(0x4c)
#define RXOUT_COUNTERS HOST_IF_REG(0x50)
#define TXOUT_RING_CFG HOST_IF_REG(0x98)
#define RXOUT_RING_CFG HOST_IF_REG(0x9C)
#define ACA_PENDING_JOB 0x00000300
#define ACA_PENDING_JOB_S 8
#define ACA_AVAIL_BUF 0x00030000
#define ACA_AVAIL_BUF_S 16
#define ACA_PP_BUFS 2
#define HOST_TYPE HOST_IF_REG(0xA0)
#define TXOUT_COUNTERS_UPDATE HOST_IF_REG(0xAC)
#define RXOUT_COUNTERS_UPDATE HOST_IF_REG(0xB4)
#define RXIN_HD_ACCUM_ADD HOST_IF_REG(0xC8) /* UMT Message trigger */
#define TXIN_HD_ACCUM_ADD HOST_IF_REG(0xCC) /* UMT Message trigger */
#define RXOUT_HD_ACCUM_ADD HOST_IF_REG(0xD0)
#define TXOUT_HD_ACCUM_ADD HOST_IF_REG(0xD4)
#define RXOUT_ACA_ACCUM_ADD HOST_IF_REG(0xE0) /* PPE FW tigger */
#define TXOUT_ACA_ACCUM_ADD HOST_IF_REG(0xE4) /* PPE FW tigger */
#define RXOUT_HD_ACCUM_SUB HOST_IF_REG(0xF8)
#define TXOUT_HD_ACCUM_SUB HOST_IF_REG(0xFC)
#define RXIN_ACA_ACCUM_SUB HOST_IF_REG(0x100)
#define TXIN_ACA_ACCUM_SUB HOST_IF_REG(0x104)
#define TXIN_ACA_HD_ACC_CNT HOST_IF_REG(0x11C)
#define UMT_ORDER_CFG HOST_IF_REG(0x234)
#define RXIN_HD_ACCUM_ADD_BE HOST_IF_REG(0x250)
#define TXIN_HD_ACCUM_ADD_BE HOST_IF_REG(0x254)
#define RXOUT_HD_ACCUM_SUB_BE HOST_IF_REG(0x268)
#define TXOUT_HD_ACCUM_SUB_BE HOST_IF_REG(0x26c)
/* MAC_HT_EXTENSION Register */
#define MAC_HT_EXT_REG(X) (MAC_HT_EXT_BASE + (X))
#define HT_GCLK_ENABLE MAC_HT_EXT_REG(0)
#define HT_SW_RST_RELEASE MAC_HT_EXT_REG(0x4)
#define HT_SW_RST_ASSRT MAC_HT_EXT_REG(0x1C)
#define SW_RST_GENRISC BIT(14)
#define SW_RST_RXOUT BIT(26)
#define SW_RST_RXIN BIT(27)
#define SW_RST_TXOUT BIT(28)
#define SW_RST_TXIN BIT(29)
#define SW_RST_HOSTIF_REG BIT(30)
#define OCP_ARB_ACC_PAGE_REG MAC_HT_EXT_REG(0x1C4)
#define AHB_ARB_HP_REG MAC_HT_EXT_REG(0x1C8)
/* Genrisc FW Configuration */
#define GNRC_SPRAM_REG(X) (GENRISC_SPRAM_BASE + (X))
/* TX IN */
#define GNRC_TXIN_TGT_STAT GNRC_SPRAM_REG(0x04)
#define GNRC_TXIN_TGT_PD_OFF GNRC_SPRAM_REG(0x08)
#define GNRC_TXIN_TGT_ACCM_CNT GNRC_SPRAM_REG(0x0C)
/* TX OUT */
#define GNRC_TXOUT_TGT_STAT GNRC_SPRAM_REG(0x10)
#define GNRC_TXOUT_TGT_PD_OFF GNRC_SPRAM_REG(0x14)
#define GNRC_TXOUT_TGT_ACCM_CNT GNRC_SPRAM_REG(0x18)
/* RX IN */
#define GNRC_RXIN_TGT_STAT GNRC_SPRAM_REG(0x1C)
#define GNRC_RXIN_TGT_PD_OFF GNRC_SPRAM_REG(0x20)
#define GNRC_RXIN_TGT_ACCM_CNT GNRC_SPRAM_REG(0x24)
/* RX OUT XXX not consistent */
#define GNRC_RXOUT_TGT_STAT GNRC_SPRAM_REG(0x28)
#define GNRC_RXOUT_TGT_PD_OFF GNRC_SPRAM_REG(0x2C)
#define GNRC_RXOUT_TGT_ACCM_CNT GNRC_SPRAM_REG(0x30)
/* 4 Ring 8 UMT case SoC cumulative counter address configuration */
#define GNRC_TXIN_CMLT_CNT_ADDR GNRC_SPRAM_REG(0x34)
#define GNRC_TXOUT_CMLT_CNT_ADDR GNRC_SPRAM_REG(0x38)
#define GNRC_RXOUT_CMLT_CNT_ADDR GNRC_SPRAM_REG(0x3C)
#define GNRC_RXIN_CMLT_CNT_ADDR GNRC_SPRAM_REG(0x40)
#define GNRC_SOURCE_TXIN_CMLT_CNT_ADDR GNRC_SPRAM_REG(0x54)
#define GNRC_SOURCE_TXOUT_CMLT_CNT_ADDR GNRC_SPRAM_REG(0x58)
#define GNRC_SOURCE_RXOUT_CMLT_CNT_ADDR GNRC_SPRAM_REG(0x5c)
#define GNRC_SOURCE_RXIN_CMLT_CNT_ADDR GNRC_SPRAM_REG(0x60)
/* Txin index prefill */
#define GNRC_TXIN_BUF_PREFILL GNRC_SPRAM_REG(0x44)
/* Task enable bitmap */
#define GNRC_EN_TASK_BITMAP GNRC_SPRAM_REG(0x64)
#define ACA_SRAM_REG(X) (ACA_SRAM_BASE + (X))
#define ACA_TXOUT_PING_BUFFER_START ACA_SRAM_REG(0x1528)
/* XBAR SSX0 */
#define ACA_SSX0_BASE 0x180000
#define ACA_SSX0_IA_BASE(id) (ACA_SSX0_BASE + (((id) - 1) << 10))
#define ACA_AGENT_CTRL(id) (ACA_SSX0_IA_BASE(id) + 0x20)
#define ACA_AGENT_STATUS(id) (ACA_SSX0_IA_BASE(id) + 0x28)
#define XBAR_CTRL_CORE_RESET BIT(0)
#define XBAR_CTRL_REJECT BIT(4)
#define XBAR_STAT_CORE_RESET BIT(0)
#define XBAR_STAT_REQ_ACTIVE BIT(4)
#define XBAR_STAT_RESP_WAITING BIT(5)
#define XBAR_STAT_BURST BIT(6)
#define XBAR_STAT_READEX BIT(7)
enum {
ACA_ACC_IA04 = 4,
ACA_M_IA06 = 6,
};
/* Should be passed from ACA FW header */
#define DESC_NUM_PER_CH 1
/* ACA DMA REG */
#define ACA_DMA_BASE 0x60000
#define ACA_DMA_REG(X) (ACA_DMA_BASE + (X))
#define ADMA_CLC ACA_DMA_REG(0x0)
#define ADMA_ID ACA_DMA_REG(0x8)
#define ADMA_CTRL ACA_DMA_REG(0x10)
#define ADMA_CPOLL ACA_DMA_REG(0x14)
#define ADMA_ID_REV 0x1Fu
#define ADMA_ID_REV_S 0
#define ADMA_ID_ID 0xFF00u
#define ADMA_ID_ID_S 8
#define ADMA_ID_PRTNR 0xF0000u
#define ADMA_ID_PRTNR_S 16
#define ADMA_ID_CHNR 0x7F00000u
#define ADMA_ID_CHNR_S 20
#define ADMA_CPOLL_EN BIT(31)
#define ADMA_CPOLL_CNT 0xFFF0u
#define ADMA_CPOLL_CNT_S 4
#define ADMA_DEFAULT_POLL 24
#define ADMA_CS ACA_DMA_REG(0x18)
#define ADMA_CCTRL ACA_DMA_REG(0x1C)
#define ADMA_CDBA ACA_DMA_REG(0x20)
#define ADMA_CDLEN ACA_DMA_REG(0x24)
#define ADMA_CIS ACA_DMA_REG(0x28)
#define ADMA_CIE ACA_DMA_REG(0x2C)
#define ADMA_CI_EOP BIT(1)
#define ADMA_CI_DUR BIT(2)
#define ADMA_CI_DESCPT BIT(3)
#define ADMA_CI_CHOFF BIT(4)
#define ADMA_CI_RDERR BIT(5)
#define ADMA_CI_ALL (ADMA_CI_EOP | ADMA_CI_DUR | ADMA_CI_DESCPT\
| ADMA_CI_CHOFF | ADMA_CI_RDERR)
#define ADMA_CDPTNRD ACA_DMA_REG(0x34)
#define ADMA_PS ACA_DMA_REG(0x40)
#define ADMA_PCTRL ACA_DMA_REG(0x44)
/* DMA CCTRL BIT */
#define CCTRL_RST 1 /* Channel Reset */
#define CCTRL_ONOFF 0 /* Channel On/Off */
/* DMA CTRL BIT */
#define CTRL_PKTARB 31 /* Packet Arbitration */
#define CTRL_MDC 15 /* Meta data copy */
#define CTRL_DDBR 14 /* Dynamic Burst */
#define CTRL_DCNF 13 /* Descriptor Length CFG*/
#define CTRL_ENBE 9 /* Byte Enable */
#define CTRL_DRB 8 /* Descriptor read back */
#define CTRL_DSRAM 1 /* Dedicated Descriptor Access port Enable */
#define CTRL_RST 0 /* Global Reset */
/* DMA PORT BIT */
#define PCTRL_FLUSH 16
#define PCTRL_TXENDI 10 /* TX DIR Endianess */
#define PCTRL_RXENDI 8 /* RX DIR Endianess */
#define PCTRL_TXBL 4 /* TX burst 2/4/8 */
#define PCTRL_RXBL 2 /* RX burst 2/4/8 */
#define PCTRL_TXBL16 1 /* TX burst of 16 */
#define PCTRL_RXBL16 0 /* RX burst of 16 */
/*DMA ID BIT */
#define ID_CHNR 20 /* Channel Number */
/*DMA POLLING BIT */
#define POLL_EN 31 /* Polling Enable */
#define POLL_CNT 4 /* Polling Counter */
#define ACA_DMA_CHAN_MAX 12
enum aca_sec_id {
ACA_SEC_HIF = 0x1,
ACA_SEC_GNR = 0x2,
ACA_SEC_MAC_HT = 0x3,
ACA_SEC_MEM_TXIN = 0x4,
ACA_SEC_MEM_TXIN_PDRING = 0x5,
ACA_SEC_MEM_TXOUT = 0x6,
ACA_SEC_MEM_TXOUT_PDRING = 0x7,
ACA_SEC_MEM_RXOUT = 0x8,
ACA_SEC_MEM_RXOUT_PDRING = 0x9,
ACA_SEC_MEM_RXIN = 0xa,
ACA_SEC_MEM_RXIN_PDRING = 0xb,
ACA_SEC_DMA = 0xc,
ACA_SEC_FW_INIT = 0xd,
ACA_SEC_FW = 0x88,
};
enum aca_fw_id {
ACA_FW_TXIN = 1,
ACA_FW_TXOUT = 2,
ACA_FW_RXIN = 3,
ACA_FW_RXOUT = 4,
ACA_FW_GNRC = 5,
ACA_FW_MAX = 5,
};
enum aca_img_type {
ACA_VRX518_IMG,
ACA_VRX618_IMG,
ACA_FALCON_IMG,
ACA_PUMA_IMG,
ACA_IMG_MAX,
};
enum aca_soc_type {
ACA_SOC_XRX300 = 1,
ACA_SOC_XRX500 = 2,
ACA_SOC_PUMA = 4,
ACA_SOC_3RD_PARTY = 8,
};
#define ACA_SOC_MASK 0xf
/* Common information element, len has different variants */
struct aca_fw_ie {
__be32 id;
__be32 len;
} __packed;
struct aca_fw_reg {
__be32 offset;
__be32 value;
} __packed;
struct aca_sram_desc {
__be32 dnum;
__be32 dbase;
} __packed;
struct aca_fw_dma {
__be32 cid;
__be32 base;
} __packed;
/* ACA internal header part */
struct aca_int_hdr {
__be32 id;
__be32 offset;
__be32 size;
__be32 load_addr;
} __packed;
struct aca_fw_param {
__be32 st_sz;
__be32 init_addr;
} __packed;
struct aca_mem_layout {
u32 txin_host_desc_base;
u32 txin_host_dnum;
u32 txout_host_desc_base;
u32 txout_host_dnum;
u32 rxin_host_desc_base;
u32 rxin_host_dnum;
u32 rxout_host_desc_base;
u32 rxout_host_dnum;
};
struct aca_pdmem_layout {
u32 txin_pd_desc_base;
u32 txin_pd_dnum;
u32 txout_pd_desc_base;
u32 txout_pd_dnum;
u32 rxin_pd_desc_base;
u32 rxin_pd_dnum;
u32 rxout_pd_desc_base;
u32 rxout_pd_dnum;
};
struct aca_fw_addr_tuple {
u32 fw_id;
u32 fw_load_addr;
size_t fw_size;
const char *fw_base;
};
struct aca_fw_dl_addr {
u32 fw_num;
struct aca_fw_addr_tuple fw_addr[ACA_FW_MAX];
};
struct aca_fw_info {
const struct firmware *fw;
const void *fw_data;
size_t fw_len;
struct aca_mem_layout mem_layout;
struct aca_pdmem_layout pdmem_layout;
struct aca_fw_param fw_param;
struct aca_fw_dl_addr fw_dl;
u32 chan_num;
u32 adma_desc_base[ACA_DMA_CHAN_MAX];
};
union fw_ver {
#ifdef CONFIG_CPU_BIG_ENDIAN
struct {
u32 build:4;
u32 branch:4;
u32 major:8;
u32 minor:16;
} __packed field;
#else
struct {
u32 minor:16;
u32 major:8;
u32 branch:4;
u32 build:4;
} __packed field;
#endif /* CONFIG_CPU_BIG_ENDIAN */
u32 all;
} __packed;
union img_soc_type {
#ifdef CONFIG_CPU_BIG_ENDIAN
struct {
u32 img_type:16;
u32 soc_type:16;
} __packed field;
#else
struct {
u32 soc_type:16;
u32 img_type:16;
} __packed field;
#endif /* CONFIG_CPU_BIG_ENDIAN */
u32 all;
} __packed;
/* Fixed header part */
struct aca_fw_f_hdr {
__be32 ver;
__be32 type;
__be32 hdr_size;
__be32 fw_size;
__be32 num_section;
} __packed;
struct aca_hif_param {
u32 soc_desc_base;
u32 soc_desc_num;
u32 pp_buf_base;
u32 pp_buf_num;
u32 pd_desc_base;
u32 pd_desc_num;
u32 pd_desc_threshold;
} __packed;
struct aca_hif_params {
u32 task_mask;
struct aca_hif_param txin;
struct aca_hif_param txout;
struct aca_hif_param rxin;
struct aca_hif_param rxout;
u32 dbg_base;
u32 dbg_size;
u32 magic;
} __packed;
#define ACA_MAGIC 0x25062016
struct dc_aca {
bool initialized;
spinlock_t clk_lock;
spinlock_t rcu_lock;
struct mutex pin_lock;
struct aca_fw_info fw_info;
struct aca_hif_params *hif_params;
u32 max_gpio;
u32 adma_chans;
};
#endif /* ACA_H */

View File

@ -0,0 +1,770 @@
/*******************************************************************************
Intel SmartPHY DSL PCIe Endpoint/ACA Linux driver
Copyright(c) 2016 Intel Corporation.
This program is free software; you can redistribute it and/or modify it
under the terms and conditions of the GNU General Public License,
version 2, as published by the Free Software Foundation.
This program is distributed in the hope it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
more details.
You should have received a copy of the GNU General Public License along with
this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
The full GNU General Public License is included in this distribution in
the file called "COPYING".
*******************************************************************************/
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
#include <linux/module.h>
#include <linux/init.h>
#include <linux/types.h>
#include <linux/atomic.h>
#include <linux/log2.h>
#include <linux/uaccess.h>
#include <linux/bitops.h>
#include <linux/delay.h>
#include <linux/io.h>
#include <linux/pci.h>
#include <linux/pci_regs.h>
#include <linux/platform_device.h>
#include "ep.h"
#include "aca.h"
#include "misc.h"
#define DC_EP_DBG
#define MAJ 2
#define MIN 1
#define BUILD 0
#define DRV_VERSION __stringify(MAJ) "." __stringify(MIN) "." \
__stringify(BUILD) "-k"
static bool pcie_switch_exist;
module_param(pcie_switch_exist, bool, 0644);
MODULE_PARM_DESC(pcie_switch_exist, "pcie switch existed or not");
static const char dc_ep_driver_name[] = "vrx518";
static const char dc_ep_driver_version[] = DRV_VERSION;
static const char dc_ep_driver_string[] =
"Intel(R) SmartPHY DSL(VRX518) PCIe EP/ACA Driver";
static const char dc_ep_copyright[] =
"Copyright (c) 2016 Intel Corporation.";
static struct dc_ep_info g_dc_ep_info;
static DEFINE_SPINLOCK(dc_ep_lock);
static inline void reset_assert_device(struct dc_ep_dev *dev, u32 bits)
{
if (WARN_ON(!dev))
return;
if (WARN_ON(!dev->priv))
return;
dc_ep_assert_device(dev->priv, bits);
}
static inline void reset_deassert_device(struct dc_ep_dev *dev, u32 bits)
{
if (WARN_ON(!dev))
return;
if (WARN_ON(!dev->priv))
return;
dc_ep_deassert_device(dev->priv, bits);
}
static inline void icu_disable_intr(struct dc_ep_dev *dev, u32 bits)
{
if (WARN_ON(!dev))
return;
if (WARN_ON(!dev->priv))
return;
dc_ep_icu_dis_intr(dev->priv, bits);
}
static inline void icu_enable_intr(struct dc_ep_dev *dev, u32 bits)
{
if (WARN_ON(!dev))
return;
if (WARN_ON(!dev->priv))
return;
dc_ep_icu_en_intr(dev->priv, bits);
}
static inline int reset_device(struct dc_ep_dev *dev, u32 bits)
{
if (WARN_ON(!dev))
return -EINVAL;
if (WARN_ON(!dev->priv))
return -EINVAL;
return dc_ep_reset_device(dev->priv, bits);
}
static inline int clk_on(struct dc_ep_dev *dev, u32 bits)
{
if (WARN_ON(!dev))
return -EINVAL;
if (WARN_ON(!dev->priv))
return -EINVAL;
return dc_ep_clk_on(dev->priv, bits);
}
static inline int clk_off(struct dc_ep_dev *dev, u32 bits)
{
if (WARN_ON(!dev))
return -EINVAL;
if (WARN_ON(!dev->priv))
return -EINVAL;
return dc_ep_clk_off(dev->priv, bits);
}
static inline int clk_set(struct dc_ep_dev *dev, u32 sysclk, u32 ppeclk)
{
if (WARN_ON(!dev))
return -EINVAL;
if (WARN_ON(!dev->priv))
return -EINVAL;
return dc_ep_clk_set(dev->priv, sysclk, ppeclk);
}
static inline int clk_get(struct dc_ep_dev *dev, u32 *sysclk, u32 *ppeclk)
{
if (WARN_ON(!dev || !sysclk || !ppeclk))
return -EINVAL;
if (WARN_ON(!dev->priv))
return -EINVAL;
return dc_ep_clk_get(dev->priv, sysclk, ppeclk);
}
static inline int gpio_dir(struct dc_ep_dev *dev, u32 gpio, int dir)
{
if (WARN_ON(!dev))
return -EINVAL;
if (WARN_ON(!dev->priv))
return -EINVAL;
return dc_ep_gpio_dir(dev->priv, gpio, dir);
}
static inline int gpio_set(struct dc_ep_dev *dev, u32 gpio, int val)
{
if (WARN_ON(!dev))
return -EINVAL;
if (WARN_ON(!dev->priv))
return -EINVAL;
return dc_ep_gpio_set(dev->priv, gpio, val);
}
static inline int gpio_get(struct dc_ep_dev *dev, u32 gpio, int *val)
{
if (WARN_ON(!dev || !val))
return -EINVAL;
if (WARN_ON(!dev->priv))
return -EINVAL;
return dc_ep_gpio_get(dev->priv, gpio, val);
}
static inline int pinmux_set(struct dc_ep_dev *dev, u32 gpio, int func)
{
if (WARN_ON(!dev))
return -EINVAL;
if (WARN_ON(!dev->priv))
return -EINVAL;
return dc_ep_pinmux_set(dev->priv, gpio, func);
}
static inline int pinmux_get(struct dc_ep_dev *dev, u32 gpio, int *func)
{
if (WARN_ON(!dev || !func))
return -EINVAL;
if (WARN_ON(!dev->priv))
return -EINVAL;
return dc_ep_pinmux_get(dev->priv, gpio, func);
}
static inline int gpio_pupd_set(struct dc_ep_dev *dev, u32 gpio, u32 val)
{
if (WARN_ON(!dev))
return -EINVAL;
if (WARN_ON(!dev->priv))
return -EINVAL;
return dc_ep_gpio_pupd_set(dev->priv, gpio, val);
}
static inline int gpio_od_set(struct dc_ep_dev *dev, u32 gpio, int val)
{
if (WARN_ON(!dev))
return -EINVAL;
if (WARN_ON(!dev->priv))
return -EINVAL;
return dc_ep_gpio_od_set(dev->priv, gpio, val);
}
static inline int gpio_src_set(struct dc_ep_dev *dev, u32 gpio, int val)
{
if (WARN_ON(!dev))
return -EINVAL;
if (WARN_ON(!dev->priv))
return -EINVAL;
return dc_ep_gpio_src_set(dev->priv, gpio, val);
}
static inline int gpio_dcc_set(struct dc_ep_dev *dev, u32 gpio, u32 val)
{
if (WARN_ON(!dev))
return -EINVAL;
if (WARN_ON(!dev->priv))
return -EINVAL;
return dc_ep_gpio_dcc_set(dev->priv, gpio, val);
}
static inline int aca_start(struct dc_ep_dev *dev, u32 func, int start)
{
if (WARN_ON(!dev))
return -EINVAL;
if (WARN_ON(!dev->priv))
return -EINVAL;
return dc_aca_start(dev->priv, func, start);
}
static inline int aca_stop(struct dc_ep_dev *dev, u32 *func, int reset)
{
if (WARN_ON(!dev || !func))
return -EINVAL;
if (WARN_ON(!dev->priv))
return -EINVAL;
return dc_aca_stop(dev->priv, func, reset);
}
static inline int aca_init(struct dc_ep_dev *dev, struct aca_param *aca,
struct aca_modem_param *mdm)
{
if (WARN_ON(!dev || !aca))
return -EINVAL;
if (WARN_ON(!dev->priv))
return -EINVAL;
return dc_aca_init(dev->priv, aca, mdm);
}
static inline void aca_event_addr_get(struct dc_ep_dev *dev,
struct aca_event_reg_addr *regs)
{
if (WARN_ON(!dev || !regs))
return;
if (WARN_ON(!dev->priv))
return;
dc_aca_event_addr_get(dev->priv, regs);
}
static inline u32 umt_msg_addr(struct dc_ep_dev *dev, u32 endian, u32 type)
{
if (WARN_ON(!dev))
return -EINVAL;
if (WARN_ON(!dev->priv))
return -EINVAL;
return aca_umt_msg_addr(dev->priv, endian, type);
}
static inline void aca_txin_sub_ack(struct dc_ep_dev *dev, u32 val)
{
if (WARN_ON(!dev))
return;
if (WARN_ON(!dev->priv))
return;
dc_aca_txin_sub_ack(dev->priv, val);
}
static inline u32 aca_txin_hd_cnt(struct dc_ep_dev *dev)
{
if (WARN_ON(!dev))
return -EINVAL;
if (WARN_ON(!dev->priv))
return -EINVAL;
return dc_aca_txin_hd_cnt(dev->priv);
}
static const struct aca_hw_ops dc_ep_hw_ops = {
.reset_assert = reset_assert_device,
.reset_deassert = reset_deassert_device,
.reset_device = reset_device,
.icu_en = icu_enable_intr,
.icu_mask = icu_disable_intr,
.clk_on = clk_on,
.clk_off = clk_off,
.clk_set = clk_set,
.clk_get = clk_get,
.gpio_dir = gpio_dir,
.gpio_set = gpio_set,
.gpio_get = gpio_get,
.pinmux_set = pinmux_set,
.pinmux_get = pinmux_get,
.gpio_pupd_set = gpio_pupd_set,
.gpio_od_set = gpio_od_set,
.gpio_src_set = gpio_src_set,
.gpio_dcc_set = gpio_dcc_set,
.aca_start = aca_start,
.aca_stop = aca_stop,
.aca_init = aca_init,
.aca_event_addr_get = aca_event_addr_get,
.umt_msg_addr = umt_msg_addr,
.aca_txin_ack_sub = aca_txin_sub_ack,
.aca_txin_hd_cnt = aca_txin_hd_cnt,
};
int dc_ep_dev_num_get(int *dev_num)
{
if ((g_dc_ep_info.dev_num <= 0)
|| (g_dc_ep_info.dev_num > DC_EP_MAX_NUM))
return -EIO;
*dev_num = g_dc_ep_info.dev_num;
return 0;
}
EXPORT_SYMBOL_GPL(dc_ep_dev_num_get);
int dc_ep_dev_info_req(int dev_idx, enum dc_ep_int module,
struct dc_ep_dev *dev)
{
int i;
struct dc_ep_priv *priv;
if ((dev_idx < 0) || (dev_idx >= DC_EP_MAX_NUM)) {
dev_err(dev->dev, "%s invalid device index %d\n",
__func__, dev_idx);
return -EIO;
}
priv = &g_dc_ep_info.pcie_ep[dev_idx];
if (atomic_read(&priv->refcnt) >= DC_EP_MAX_REFCNT) {
dev_err(dev->dev,
"%s mismatch request/release module usage\n", __func__);
return -EIO;
}
switch (module) {
case DC_EP_INT_PPE:
dev->irq = priv->irq_base;
if (priv->msi_mode == DC_EP_8_MSI_MODE) {
dev->aca_tx_irq = priv->irq_base + 7;
dev->aca_rx_irq = priv->irq_base + 6;
} else if (priv->msi_mode == DC_EP_4_MSI_MODE) {
dev->aca_tx_irq = priv->irq_base + 2;
dev->aca_rx_irq = priv->irq_base + 3;
} else {
dev_err(dev->dev, "%s ACA should never occur\n",
__func__);
}
break;
case DC_EP_INT_MEI:
dev->irq = priv->irq_base + 1;
break;
default:
dev->irq = priv->irq_base;
break;
}
dev->dev = priv->dev;
dev->membase = priv->mem;
dev->phy_membase = priv->phymem;
dev->peer_num = priv->peer_num;
for (i = 0; i < dev->peer_num; i++) {
dev->peer_membase[i] = priv->peer_mem[i];
dev->peer_phy_membase[i] = priv->peer_phymem[i];
}
dev->switch_attached = priv->switch_attached;
dev->priv = priv;
dev->hw_ops = &dc_ep_hw_ops;
atomic_inc(&priv->refcnt);
return 0;
}
EXPORT_SYMBOL_GPL(dc_ep_dev_info_req);
int dc_ep_dev_info_release(int dev_idx)
{
struct dc_ep_priv *priv;
if ((dev_idx < 0) || (dev_idx >= DC_EP_MAX_NUM)) {
pr_err("%s invalid device index %d\n",
__func__, dev_idx);
return -EIO;
}
priv = &g_dc_ep_info.pcie_ep[dev_idx];
if (atomic_read(&priv->refcnt) <= 0) {
pr_err("%s mismatch request/release module usage\n",
__func__);
return -EIO;
}
atomic_dec(&priv->refcnt);
return 0;
}
EXPORT_SYMBOL_GPL(dc_ep_dev_info_release);
static int pci_msi_vec_set(struct pci_dev *dev, int nvec)
{
int pos;
u16 msgctl;
if (!is_power_of_2(nvec))
return -EINVAL;
pos = pci_find_capability(dev, PCI_CAP_ID_MSI);
if (!pos)
return -EINVAL;
pci_read_config_word(dev, pos + PCI_MSI_FLAGS, &msgctl);
msgctl &= ~PCI_MSI_FLAGS_QSIZE;
msgctl |= ((ffs(nvec) - 1) << 4);
pci_write_config_word(dev, pos + PCI_MSI_FLAGS, msgctl);
pci_read_config_word(dev, pos + PCI_MSI_FLAGS, &msgctl);
return 0;
}
static int dc_ep_msi_enable(struct pci_dev *pdev, int nvec)
{
int err;
struct dc_ep_priv *priv = pci_get_drvdata(pdev);
/* NB, ICU initailize first */
dc_ep_icu_init(priv);
err = pci_msi_vec_set(pdev, nvec);
if (err) {
dev_err(&pdev->dev, "%s: Failed to set maximum MSI vector\n",
__func__);
return -EIO;
}
err = pci_enable_msi_exact(pdev, nvec);
if (err) {
dev_err(&pdev->dev,
"%s: Failed to enable MSI interrupts error code: %d\n",
__func__, err);
return -EIO;
}
return 0;
}
static void dc_ep_info_xchange(struct pci_dev *pdev, int card_num)
{
/* More cards supported, exchange address information
* For example, suppose three cards dected.
* 0, <1, 2>
* 1, <0, 2>
* 2, <0, 1>
* For four cards detected
* 0, <1, 2, 3>
* 1, <0, 2, 3>
* 2, <0, 1, 3>
* 3, <0, 1, 2>
* and etc
*/
int i, j, k;
int peer_num;
#ifdef DC_EP_DBG
struct dc_ep_priv *priv;
#endif /* DC_EP_DBG */
spin_lock(&dc_ep_lock);
if (card_num > 1) {
peer_num = card_num - 1;
for (i = 0; i < card_num; i++) {
struct dc_ep_priv *ep = &g_dc_ep_info.pcie_ep[i];
j = 0;
k = 0;
ep->peer_num = peer_num;
do {
struct dc_ep_priv *partner;
if (j == i) {
j++;
continue;
}
partner = &g_dc_ep_info.pcie_ep[j];
ep->peer_mem[k] = partner->mem;
ep->peer_phymem[k] = partner->phymem;
ep->peer_memsize[k] = partner->memsize;
k++;
j++;
} while ((k < peer_num) && (j < card_num));
}
}
spin_unlock(&dc_ep_lock);
#ifdef DC_EP_DBG
dev_dbg(&pdev->dev, "Total cards found %d\n", card_num);
/* Dump detailed debug information */
for (i = 0; i < card_num; i++) {
priv = &g_dc_ep_info.pcie_ep[i];
dev_dbg(&pdev->dev, "card %d attached\n", priv->ep_idx);
dev_dbg(&pdev->dev, "irq base %d irq numbers %d\n",
priv->irq_base, priv->irq_num);
dev_dbg(&pdev->dev,
"its own phymem 0x%08x mem 0x%p size 0x%08x\n",
priv->phymem, priv->mem, priv->memsize);
if (card_num > 1) {
for (j = 0; j < priv->peer_num; j++)
dev_dbg(&pdev->dev,
"its peer phymem 0x%08x mem 0x%p size 0x%08x\n",
priv->peer_phymem[j],
priv->peer_mem[j], priv->peer_memsize[j]);
}
}
#endif /* DC_EP_DBG */
}
static int pci_msi_vec_num(struct pci_dev *dev)
{
int ret;
u16 msgctl;
if (!dev->msi_cap)
return -EINVAL;
pci_read_config_word(dev, dev->msi_cap + PCI_MSI_FLAGS, &msgctl);
ret = 1 << ((msgctl & PCI_MSI_FLAGS_QMASK) >> 1);
return ret;
}
static int dc_ep_probe(struct pci_dev *pdev, const struct pci_device_id *id)
{
int ret;
int nvec;
bool switch_exist;
int current_ep;
unsigned long phymem;
void __iomem *mem;
size_t memsize;
int msi_mode;
static int cards_found;
#ifndef CONFIG_OF
struct pcie_ep_adapter *adapter;
#endif
struct dc_ep_priv *priv;
ret = pci_enable_device(pdev);
if (ret) {
dev_err(&pdev->dev, "can't enable PCI device %d\n", ret);
goto err_pci;
}
/* Physical address */
ret = pci_request_region(pdev, DC_EP_BAR_NUM, dc_ep_driver_name);
if (ret) {
dev_err(&pdev->dev, "PCI MMIO reservation error: %d\n", ret);
goto err_device;
}
/* Target structures have a limit of 32 bit DMA pointers.
* DMA pointers can be wider than 32 bits by default on some systems.
*/
ret = pci_set_dma_mask(pdev, DMA_BIT_MASK(32));
if (ret) {
dev_err(&pdev->dev, "32-bit DMA not available: %d\n", ret);
goto err_region;
}
ret = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(32));
if (ret) {
dev_err(&pdev->dev, "cannot enable 32-bit consistent DMA\n");
goto err_region;
}
/* Set bus master bit in PCI_COMMAND to enable DMA */
pci_set_master(pdev);
/* NB, some delay may need due to BME reset */
udelay(1);
/* Arrange for access to Target SoC registers. */
mem = pci_iomap(pdev, DC_EP_BAR_NUM, 0);
if (!mem) {
dev_err(&pdev->dev, "PCI iomap error\n");
ret = -EIO;
goto err_master;
}
phymem = pci_resource_start(pdev, DC_EP_BAR_NUM);
memsize = pci_resource_len(pdev, DC_EP_BAR_NUM);
nvec = pci_msi_vec_num(pdev);
/* Overwrite maximum vector number according to
* the specific requirement
*/
if ((DC_PCIE_SWITCH_ATTACH > 0) || pcie_switch_exist)
switch_exist = true;
else
switch_exist = false;
/* Always use 4 vector mode */
nvec = DC_EP_DEFAULT_MSI_VECTOR;
msi_mode = DC_EP_4_MSI_MODE;
current_ep = cards_found++;
priv = &g_dc_ep_info.pcie_ep[current_ep];
memset(priv, 0, sizeof(*priv));
pci_set_drvdata(pdev, priv);
/* Collect basic info for further operations */
spin_lock(&dc_ep_lock);
g_dc_ep_info.dev_num = cards_found;
atomic_set(&priv->refcnt, 0);
priv->pdev = pdev;
priv->device_id = pdev->device;
priv->dev = &pdev->dev;
priv->ep_idx = current_ep;
priv->mem = mem;
priv->phymem = phymem;
priv->memsize = memsize;
priv->irq_num = nvec;
priv->switch_attached = switch_exist;
priv->msi_mode = msi_mode;
spin_unlock(&dc_ep_lock);
ret = dc_ep_msi_enable(pdev, nvec);
if (ret)
goto err_iomap;
spin_lock(&dc_ep_lock);
priv->irq_base = pdev->irq;
spin_unlock(&dc_ep_lock);
#ifndef CONFIG_OF
adapter = kmalloc(sizeof(struct pcie_ep_adapter), GFP_KERNEL);
if (adapter == NULL)
goto err_iomap;
pci_set_drvdata(pdev, adapter);
adapter->mei_dev = platform_device_register_data(&pdev->dev, "mei_cpe",
PLATFORM_DEVID_AUTO,
NULL, 0);
if (IS_ERR(adapter->mei_dev)) {
dev_err(&pdev->dev, "can not register mei device, err: %li, ignore this\n",
PTR_ERR(adapter->mei_dev));
goto err_msi;
}
#endif
dc_ep_info_xchange(pdev, cards_found);
/* Disable output clock to save power */
dc_ep_clkod_disable(priv);
dc_aca_info_init(priv);
return 0;
#ifndef CONFIG_OF
err_msi:
kfree(adapter);
#endif
err_iomap:
pci_iounmap(pdev, mem);
err_master:
pci_clear_master(pdev);
err_region:
pci_release_region(pdev, DC_EP_BAR_NUM);
err_device:
pci_disable_device(pdev);
err_pci:
return ret;
}
static void dc_ep_remove(struct pci_dev *pdev)
{
struct dc_ep_priv *priv = pci_get_drvdata(pdev);
#ifndef CONFIG_OF
struct pcie_ep_adapter *adapter =
(struct pcie_ep_adapter *) pci_get_drvdata(pdev);
platform_device_unregister(adapter->mei_dev);
#endif
if (priv == NULL)
return;
if (atomic_read(&priv->refcnt) != 0) {
dev_err(&pdev->dev, "%s still being used, can't remove\n",
__func__);
return;
}
dc_aca_free_fw_file(priv);
dc_aca_shutdown(priv);
dc_ep_icu_disable(priv);
pci_iounmap(pdev, priv->mem);
pci_release_region(pdev, DC_EP_BAR_NUM);
pci_disable_msi(pdev);
wmb();
pci_clear_master(pdev);
pci_disable_device(pdev);
}
static const struct pci_device_id dc_ep_id_table[] = {
{0x8086, 0x09a9, PCI_ANY_ID, PCI_ANY_ID}, /* VRX518 */
{0},
};
MODULE_DEVICE_TABLE(pci, dc_ep_id_table);
static struct pci_driver dc_ep_driver = {
.name = (char *)dc_ep_driver_name,
.id_table = dc_ep_id_table,
.probe = dc_ep_probe,
.remove = dc_ep_remove,
.shutdown = dc_ep_remove,
/* PM not supported */
/* AER is controlled by RC */
};
static int __init dc_ep_init(void)
{
pr_info("%s - version %s\n",
dc_ep_driver_string, dc_ep_driver_version);
pr_info("%s\n", dc_ep_copyright);
memset(&g_dc_ep_info, 0, sizeof(struct dc_ep_info));
if (pci_register_driver(&dc_ep_driver) < 0) {
pr_err("%s: No devices found, driver not installed.\n",
__func__);
return -ENODEV;
}
return 0;
}
module_init(dc_ep_init);
static void __exit dc_ep_exit(void)
{
pci_unregister_driver(&dc_ep_driver);
pr_info("%s: %s driver unloaded\n", __func__,
dc_ep_driver_name);
}
module_exit(dc_ep_exit);
MODULE_AUTHOR("Intel Corporation, <Chuanhua.lei@intel.com>");
MODULE_DESCRIPTION("Intel(R) SmartPHY PCIe EP/ACA Driver");
MODULE_LICENSE("GPL");
MODULE_VERSION(DRV_VERSION);

View File

@ -0,0 +1,127 @@
/*******************************************************************************
Intel SmartPHY DSL PCIe Endpoint/ACA Linux driver
Copyright(c) 2016 Intel Corporation.
This program is free software; you can redistribute it and/or modify it
under the terms and conditions of the GNU General Public License,
version 2, as published by the Free Software Foundation.
This program is distributed in the hope it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
more details.
You should have received a copy of the GNU General Public License along with
this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
The full GNU General Public License is included in this distribution in
the file called "COPYING".
*******************************************************************************/
#ifndef EP_H
#define EP_H
#include <net/dc_ep.h>
#include "aca.h"
#define DC_EP_MAX_NUM (DC_EP_MAX_PEER + 1)
#define DC_EP_BAR_NUM 0
/* Maximum 8, if PCIe switch attached, 4 is used. 8 is also default one */
#ifdef CONFIG_VRX518_PCIE_SWITCH_BONDING
#define DC_PCIE_SWITCH_ATTACH 1
#else
#define DC_PCIE_SWITCH_ATTACH 0
#endif /* CONFIG_VRX518_PCIE_SWITCH_BONDING */
#define DC_EP_DEFAULT_MSI_VECTOR 4
#define DC_EP_MAX_REFCNT DC_EP_INT_MAX
#define MS(_v, _f) (((_v) & (_f)) >> _f##_S)
#define SM(_v, _f) (((_v) << _f##_S) & (_f))
enum dc_ep_msi_mode {
DC_EP_8_MSI_MODE = 0,
DC_EP_4_MSI_MODE,
DC_EP_1_MSI_MODE,
};
/* Structure used to extract attached EP detailed information for
* PPE/DSL_MEI driver/Bonding
*/
struct dc_ep_priv {
struct pci_dev *pdev;
struct device *dev;
u32 ep_idx; /*!< EP logical index, the first found one will be 0
regardless of RC physical index
*/
u32 irq_base; /*!< The first MSI interrupt number */
u32 irq_num; /*!< How many MSI interrupt supported */
enum dc_ep_msi_mode msi_mode;
u8 __iomem *mem; /*!< The EP inbound memory base address
derived from BAR0, SoC virtual address
for PPE/DSL_MEI driver
*/
u32 phymem; /*!< The EP inbound memory base address
derived from BAR0, physical address for
PPE FW
*/
size_t memsize; /*!< The EP inbound memory window size */
u32 peer_num; /*!< Bonding peer number available */
/*!< The bonding peer EP inbound memory base address derived from
* its BAR0, SoC virtual address for PPE/DSL_MEI driver
*/
u8 __iomem *peer_mem[DC_EP_MAX_PEER];
/*!< The bonding peer EP inbound memory base address derived from
* its BAR0, physical address for PPE FW
*/
u32 peer_phymem[DC_EP_MAX_PEER];
/*!< The bonding peer inbound memory window size */
size_t peer_memsize[DC_EP_MAX_PEER];
atomic_t refcnt; /*!< The EP mapping driver referenced times
by other modules
*/
u16 device_id; /* Potential usage for different EP */
bool switch_attached;
struct dc_aca aca;
};
struct dc_ep_info {
int dev_num;
int msi_mode;
struct dc_ep_priv pcie_ep[DC_EP_MAX_NUM];
};
static inline struct dc_aca *to_aca(struct dc_ep_priv *priv)
{
return &priv->aca;
}
void dc_aca_shutdown(struct dc_ep_priv *priv);
void dc_aca_info_init(struct dc_ep_priv *priv);
int dc_aca_start(struct dc_ep_priv *priv, u32 func, int start);
int dc_aca_stop(struct dc_ep_priv *priv, u32 *func, int reset);
int dc_aca_init(struct dc_ep_priv *priv, struct aca_param *aca,
struct aca_modem_param *mdm);
void dc_aca_event_addr_get(struct dc_ep_priv *priv,
struct aca_event_reg_addr *regs);
void dc_aca_txin_sub_ack(struct dc_ep_priv *priv, u32 val);
u32 aca_umt_msg_addr(struct dc_ep_priv *priv, u32 endian, u32 type);
u32 dc_aca_txin_hd_cnt(struct dc_ep_priv *priv);
void dc_aca_free_fw_file(struct dc_ep_priv *priv);
/* Card specific private data structure */
struct pcie_ep_adapter {
struct platform_device *mei_dev; /* the mei driver */
};
#endif /* EP_H */

View File

@ -0,0 +1,349 @@
/*******************************************************************************
Intel SmartPHY DSL PCIe Endpoint/ACA Linux driver
Copyright(c) 2016 Intel Corporation.
This program is free software; you can redistribute it and/or modify it
under the terms and conditions of the GNU General Public License,
version 2, as published by the Free Software Foundation.
This program is distributed in the hope it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
more details.
You should have received a copy of the GNU General Public License along with
this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
The full GNU General Public License is included in this distribution in
the file called "COPYING".
*******************************************************************************/
#ifndef DC_EP_H
#define DC_EP_H
#include <linux/types.h>
#include <linux/pci.h>
#include <linux/device.h>
/* @{ */
/*! \def DC_EP_MAX_PEER
* \brief how many EP partners existed. In most cases, this number should be
* one for bonding application. For the future extension, it could be bigger
* value. For example, multiple bonding
*/
#define DC_EP_MAX_PEER 1
/* Reset related module bit definition */
#define RST_GPIO BIT(2)
#define RST_DSL_IF BIT(3)
#define RST_DFE BIT(7)
#define RST_PPE BIT(8)
#define RST_CDMA BIT(9)
#define RST_SPI BIT(10)
#define RST_IMCU BIT(11)
#define RST_ACA_DMA BIT(14)
#define RST_AFE BIT(16)
#define RST_ACA_HOSTIF BIT(17)
#define RST_PCIE BIT(22)
#define RST_PPE_ATM_TC BIT(23)
#define RST_FPI_SLAVE BIT(25)
#define RST_GLOBAL BIT(30)
/* PMU related module definition */
#define PMU_ADMA BIT(0)
#define PMU_CDMA BIT(2)
#define PMU_SPI BIT(8)
#define PMU_DSL BIT(9)
#define PMU_PPE_QSB BIT(18)
#define PMU_PPE_SLL01 BIT(19)
#define PMU_PPE_TC BIT(21)
#define PMU_EMA BIT(22)
#define PMU_PPM2 BIT(23)
#define PMU_PPE_TOP BIT(29)
/* IMER bit definition */
#define PPE2HOST_INT0 BIT(0)
#define PPE2HOST_INT1 BIT(1)
#define DYING_GASP_INT BIT(3)
#define MEI_IRQ BIT(8)
#define ACA_XBAR_INT BIT(9)
#define MODEM_XBAR_INT BIT(12)
#define LED0_INT BIT(13)
#define LED1_INT BIT(14)
#define NMI_PLL BIT(15)
#define DMA_TX BIT(16)
#define DMA_RX BIT(17)
#define ACA_HOSTIF_TX BIT(20)
#define ACA_HOSTIF_RX BIT(21)
#define ACA_RXOUT_PD_RING_FULL BIT(22)
#define ACA_TXOUT_PD_RING_FULL BIT(23)
/*
* Structure used to specify available pin mux functions for gpio pinx
* It will be used in pinmux_set() function
*/
enum gpio_padc_func {
MUX_FUNC_GPIO = 0,
MUX_FUNC_ALT1,
MUX_FUNC_ALT2,
MUX_FUNC_RES,
};
/*
* Structure used to specify interrupt source so that EP can assign unique
* interruot to it
*/
enum dc_ep_int {
DC_EP_INT_PPE, /*!< PPE2HOST_INT 0/1 */
DC_EP_INT_MEI, /*!< DSL MEI_IRQ */
DC_EP_INT_MAX,
};
/* Clock setting for system clock */
enum {
SYS_CLK_36MHZ = 0,
SYS_CLK_288MHZ,
SYS_CLK_MAX,
};
/* Clock setting for PPE clock */
enum {
PPE_CLK_36MHZ = 0,
PPE_CLK_576MHZ,
PPE_CLK_494MHZ,
PPE_CLK_432MHZ,
PPE_CLK_288MHZ,
PPE_CLK_MAX,
};
/* GPIO direction IN/OUT */
enum {
GPIO_DIR_IN = 0,
GPIO_DIR_OUT,
GPIO_DIR_MAX,
};
/* GPIO Pullup/Pulldown setting */
enum {
GPIO_PUPD_DISABLE = 0,
GPIO_PULL_UP,
GPIO_PULL_DOWN,
GPIO_PUPD_BOTH,
};
/* GPIO slew rate setting */
enum {
GPIO_SLEW_RATE_SLOW = 0,
GPIO_SLEW_RATE_FAST,
};
/* GPIO driver current setting */
enum {
GPIO_DRV_CUR_2MA = 0,
GPIO_DRV_CUR_4MA,
GPIO_DRV_CUR_8MA,
GPIO_DRV_CUR_12MA,
GPIO_DRV_CUR_MAX,
};
enum {
ACA_LITTLE_ENDIAN = 0,
ACA_BIG_ENDIAN,
ACA_ENDIAN_MAX,
};
enum {
ACA_TXIN = 0,
ACA_TXOUT,
ACA_RXIN,
ACA_RXOUT,
ACA_MAX,
};
/* ACA four major direction functions for start/stop */
#define ACA_TXIN_EN BIT(0)
#define ACA_TXOUT_EN BIT(1)
#define ACA_RXIN_EN BIT(2)
#define ACA_RXOUT_EN BIT(3)
#define ACA_ALL_EN 0xF
struct dc_ep_dev;
/*
* ACA SoC specific parameters. The caller needs to fill up all necessary info
* according to specific SoC and specific project
* For each function, different parameters are needed.
*/
struct aca_cfg_param {
u32 soc_desc_base; /*!< SoC CBM or DDR descriptor base address */
u32 soc_desc_num; /*!< SoC and HostIF (same) descriptor number */
u32 soc_cmlt_cnt_addr; /*! SoC cumulative counter address */
u32 pp_buf_desc_num; /*!< ACA ping pong buffer descriptor number */
u32 pd_desc_base; /*!< Packet Descriptor base address in modem */
u32 pd_desc_num; /*!< Packet Descriptor number in modem */
u32 hd_size_in_dw; /*!< Host(SoC) descriptor size in dwords */
u32 pd_size_in_dw; /*!< Packet descriptor size in dwords */
u32 byteswap; /*!< Byte swap enabled or not in ACA FW */
u32 prefill_cnt; /*!< Prefill counter special required for some platform */
};
struct aca_param {
struct aca_cfg_param aca_txin;
struct aca_cfg_param aca_txout;
struct aca_cfg_param aca_rxin;
struct aca_cfg_param aca_rxout;
};
/* ACA project/modem specific parameters. It is only valid for VRX518 */
struct aca_proj_param {
u32 stat; /*!< Target state */
u32 pd; /*!< Target packet descripor */
u32 acc_cnt; /*!< Target accumulate counter */
};
/* Project specific configuration */
struct aca_modem_param {
struct aca_proj_param mdm_txout;
struct aca_proj_param mdm_rxin;
struct aca_proj_param mdm_rxout;
};
/* Event trigger register address <offset> */
struct aca_event_reg_addr {
u32 txin_acc_sub;
u32 txout_acc_add;
u32 rxin_acc_sub;
u32 rxout_acc_add;
};
/*
* ACA common hardware low level APIs, presented as callbacks instead of
* separate APIs to support mulitple instances
*/
struct aca_hw_ops {
/* RCU Callbacks */
void (*reset_assert)(struct dc_ep_dev *pdev, u32 rd);
void (*reset_deassert)(struct dc_ep_dev *pdev, u32 rd);
/* For hardware self-clear reset, most apply except PCIe */
int (*reset_device)(struct dc_ep_dev *pdev, u32 hd);
/* PMU Callbacks */
int (*clk_on)(struct dc_ep_dev *pdev, u32 cd);
int (*clk_off)(struct dc_ep_dev *pdev, u32 cd);
/* CGU Callbacks */
int (*clk_set)(struct dc_ep_dev *pdev, u32 sysclk, u32 ppeclk);
int (*clk_get)(struct dc_ep_dev *pdev, u32 *sysclk, u32 *ppeclk);
/* GPIO Callbacks */
int (*gpio_dir)(struct dc_ep_dev *pdev, u32 gpio, int dir);
int (*gpio_set)(struct dc_ep_dev *pdev, u32 gpio, int val);
int (*gpio_get)(struct dc_ep_dev *pdev, u32 gpio, int *val);
/* PinMux Callbacks */
int (*pinmux_set)(struct dc_ep_dev *pdev, u32 gpio, int func);
int (*pinmux_get)(struct dc_ep_dev *pdev, u32 gpio, int *func);
int (*gpio_pupd_set)(struct dc_ep_dev *pdev, u32 gpio, u32 val);
int (*gpio_od_set)(struct dc_ep_dev *pdev, u32 gpio, int val);
int (*gpio_src_set)(struct dc_ep_dev *pdev, u32 gpio, int val);
int (*gpio_dcc_set)(struct dc_ep_dev *pdev, u32 gpio, u32 val);
/* ICU Callbacks */
void (*icu_en)(struct dc_ep_dev *pdev, u32 bit);
void (*icu_mask)(struct dc_ep_dev *pdev, u32 bit);
/* ACA related stuff */
int (*aca_start)(struct dc_ep_dev *pdev, u32 func, int start);
int (*aca_stop)(struct dc_ep_dev *pdev, u32 *func, int reset);
/* If there is no project specific parameters, input NULL */
int (*aca_init)(struct dc_ep_dev *pdev, struct aca_param *aca,
struct aca_modem_param *mdm);
void (*aca_event_addr_get)(struct dc_ep_dev *pdev,
struct aca_event_reg_addr *regs);
/* UMT address needed for SoC filled in to trigger UMT msg */
u32 (*umt_msg_addr)(struct dc_ep_dev *pdev, u32 endian, u32 type);
/* TXIN accum sub to ack PPE already processed */
void (*aca_txin_ack_sub)(struct dc_ep_dev *pdev, u32 val);
u32 (*aca_txin_hd_cnt)(struct dc_ep_dev *pdev);
};
/*
* Structure used to extract attached EP detailed information
* for PPE/DSL_MEI driver/Bonding
*/
struct dc_ep_dev {
struct device *dev;
u32 irq; /*!< MSI interrupt number for this device */
u32 aca_tx_irq; /*!< ACA Non-empty TX irq number for PPE driver */
u32 aca_rx_irq; /*!< ACA Non-empty RX irq number for PPE driver */
/*!< The EP inbound memory base address derived from BAR0, SoC
virtual address for PPE/DSL_MEI driver
*/
bool switch_attached; /*!< EP attach switch */
u8 __iomem *membase; /*!< virtual memory base address to access EP */
u32 phy_membase; /*!< The EP inbound memory base address derived
from BAR0, physical address for PPE FW
*/
u32 peer_num; /*!< Bonding peer number available */
/*!< The bonding peer EP inbound memory base address derived from
its BAR0, SoC virtual address for PPE/DSL_MEI driver
*/
u8 __iomem *peer_membase[DC_EP_MAX_PEER];
/*!< The bonding peer EP inbound memory base address derived from
its BAR0, physical address for PPE FW
*/
u32 peer_phy_membase[DC_EP_MAX_PEER];
const struct aca_hw_ops *hw_ops;
void *priv; /* Pointer to driver proprietary data for internal use */
};
/*
* This function returns the total number of EPs attached. Normally,
* the number should be one <standard smartPHY EP> or two <smartPHY
* off-chip bonding cases>. Extended case is also considered
* \param[in/out] dev_num Pointer to detected EP numbers in total.
* \return -EIO Invalid total EP number which means this
* module is not initialized properly
* \return 0 Successfully return the detected EP numbers
*/
int dc_ep_dev_num_get(int *dev_num);
/*
* This function returns detailed EP device information for PPE/DSL/Bonding
* partner by its logical index obtained
* by \ref dc_ep_dev_num_get and its interrupt module number
* \ref dc_ep_int
* \param[in] dev_idx Logical device index referred to the related
* device
* \param[in] module EP interrupt module user<PPE/MEI>
* \param[in/out] dev Pointer to returned detail device structure
* \ref dc_ep_dev
* \return -EIO Invalid logical device index or too many modules
* referred to this module
* \return 0 Successfully return required device information
* \remarks This function normally will be called to trace the detailed device
* information after calling \ref dc_ep_dev_num_get
*/
int dc_ep_dev_info_req(int dev_idx, enum dc_ep_int module,
struct dc_ep_dev *dev);
/*
* This function releases the usage of this module by PPE/DSL
* \param[in] dev_idx Logical device index referred to the related device
* \return -EIO Invalid logical device index or release too many
* times to refer to this module
* \return 0 Successfully release the usage of this module
* \remarks This function should be called once their reference is over.
* The reference usage must matches \ref dc_ep_dev_info_req
*/
int dc_ep_dev_info_release(int dev_idx);
#endif /* DC_EP_H */

View File

@ -0,0 +1,325 @@
/*******************************************************************************
Intel SmartPHY DSL PCIe Endpoint/ACA Linux driver
Copyright(c) 2016 Intel Corporation.
This program is free software; you can redistribute it and/or modify it
under the terms and conditions of the GNU General Public License,
version 2, as published by the Free Software Foundation.
This program is distributed in the hope it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
more details.
You should have received a copy of the GNU General Public License along with
this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
The full GNU General Public License is included in this distribution in
the file called "COPYING".
*******************************************************************************/
#include <linux/delay.h>
#include <linux/mutex.h>
#include "regs.h"
#include "ep.h"
#include "misc.h"
#define padc_getbit(p, r) (!!(rd32(r) & (1 << p)))
#define padc_setbit(p, r) wr32_mask(0, BIT(p), r)
#define padc_clearbit(p, r) wr32_mask(BIT(p), 0, r)
void dc_ep_clkod_disable(struct dc_ep_priv *priv)
{
wr32_mask(0, IF_CLKOD_ALL, IF_CLK);
}
void dc_ep_icu_init(struct dc_ep_priv *priv)
{
/* Enable all interrupts in ICU level */
wr32(ICU_DMA_TX_ALL, ICU_DMA_TX_IMER);
wr32(ICU_DMA_RX_ALL, ICU_DMA_RX_IMER);
wr32(ICU_TOP_ALL, ICU_IMER);
if (priv->msi_mode == DC_EP_4_MSI_MODE)
wr32(PCI_MSI_4_MODE, RCU_MSI);
else
wr32(PCI_MSI_8_MODE, RCU_MSI);
/* PCIe app has to enable all MSI interrupts regardless of MSI mode */
wr32(PCIE_MSI_EN_ALL, PCIE_APPL_MSI_EN);
}
void dc_ep_icu_disable(struct dc_ep_priv *priv)
{
/* Disable all PCIe related interrupts */
wr32(0, PCIE_APPL_MSI_EN);
wr32(PCI_MSI_8_MODE, RCU_MSI);
/* Disable all interrupts in ICU level */
wr32(0, ICU_DMA_TX_IMER);
wr32(0, ICU_DMA_RX_IMER);
wr32(0, ICU_IMER);
}
void dc_ep_icu_dis_intr(struct dc_ep_priv *priv, u32 bits)
{
wr32_mask(~bits, 0, ICU_IMER);
}
void dc_ep_icu_en_intr(struct dc_ep_priv *priv, u32 bits)
{
wr32_mask(0, bits, ICU_IMER);
}
void dc_ep_assert_device(struct dc_ep_priv *priv, u32 bits)
{
struct dc_aca *aca = to_aca(priv);
spin_lock(&aca->rcu_lock);
wr32_mask(0, bits, RCU_REQ);
spin_unlock(&aca->rcu_lock);
}
void dc_ep_deassert_device(struct dc_ep_priv *priv, u32 bits)
{
struct dc_aca *aca = to_aca(priv);
spin_lock(&aca->rcu_lock);
wr32_mask(bits, 0, RCU_REQ);
spin_unlock(&aca->rcu_lock);
}
int dc_ep_reset_device(struct dc_ep_priv *priv, u32 bits)
{
int retry = EP_TIMEOUT;
wr32(bits, RCU_REQ);
do { } while (retry-- && (!(rd32(RCU_STAT) & bits)));
if (retry == 0) {
dev_err(priv->dev, "%s failed to reset\n", __func__);
return -ETIME;
}
return 0;
}
int dc_ep_clk_on(struct dc_ep_priv *priv, u32 bits)
{
int retry = EP_TIMEOUT;
struct dc_aca *aca = to_aca(priv);
spin_lock(&aca->clk_lock);
wr32_mask(bits, 0, PMU_PWDCR);
spin_unlock(&aca->clk_lock);
do { } while (--retry && (rd32(PMU_SR) & bits));
if (!retry) {
dev_err(priv->dev, "%s failed\n", __func__);
return -ETIME;
}
return 0;
}
int dc_ep_clk_off(struct dc_ep_priv *priv, u32 bits)
{
int retry = EP_TIMEOUT;
struct dc_aca *aca = to_aca(priv);
spin_lock(&aca->clk_lock);
wr32_mask(0, bits, PMU_PWDCR);
spin_unlock(&aca->clk_lock);
do {} while (--retry
&& (!(rd32(PMU_SR) & bits)));
if (!retry) {
dev_err(priv->dev, "%s failed\n", __func__);
return -ETIME;
}
return 0;
}
int dc_ep_clk_set(struct dc_ep_priv *priv, u32 sysclk, u32 ppeclk)
{
struct dc_aca *aca = to_aca(priv);
if (sysclk > SYS_CLK_MAX || ppeclk > PPE_CLK_MAX)
return -EINVAL;
spin_lock(&aca->clk_lock);
wr32_mask(PPE_CLK | SYS_CLK,
SM(sysclk, SYS_CLK) | SM(ppeclk, PPE_CLK), PLL_OMCFG);
spin_unlock(&aca->clk_lock);
return 0;
}
int dc_ep_clk_get(struct dc_ep_priv *priv, u32 *sysclk, u32 *ppeclk)
{
u32 val;
val = rd32(PLL_OMCFG);
*sysclk = MS(val, SYS_CLK);
*ppeclk = MS(val, PPE_CLK);
return 0;
}
int dc_ep_gpio_dir(struct dc_ep_priv *priv, u32 gpio, int dir)
{
struct dc_aca *aca = to_aca(priv);
if (gpio > aca->max_gpio)
return -EINVAL;
if ((dir != GPIO_DIR_IN) && (dir != GPIO_DIR_OUT))
return -EINVAL;
if (dir == GPIO_DIR_IN)
wr32(BIT(gpio), GPIO_DIRCLR);
else
wr32(BIT(gpio), GPIO_DIRSET);
return 0;
}
int dc_ep_gpio_set(struct dc_ep_priv *priv, u32 gpio, int val)
{
struct dc_aca *aca = to_aca(priv);
if (gpio > aca->max_gpio)
return -EINVAL;
dc_ep_gpio_dir(priv, gpio, GPIO_DIR_OUT);
if (val)
wr32(BIT(gpio), GPIO_OUTSET);
else
wr32(BIT(gpio), GPIO_OUTCLR);
return 0;
}
int dc_ep_gpio_get(struct dc_ep_priv *priv, u32 gpio, int *val)
{
u32 dir;
struct dc_aca *aca = to_aca(priv);
if (gpio > aca->max_gpio)
return -EINVAL;
dir = rd32(GPIO_DIR);
if ((dir >> gpio) & 0x1)
*val = (rd32(GPIO_OUT) >> gpio) & 0x1;
else
*val = (rd32(GPIO_IN) >> gpio) & 0x1;
return 0;
}
int dc_ep_pinmux_set(struct dc_ep_priv *priv, u32 gpio, int func)
{
struct dc_aca *aca = to_aca(priv);
if (gpio > aca->max_gpio)
return -EINVAL;
if (func >= MUX_FUNC_RES)
return -EINVAL;
mutex_lock(&aca->pin_lock);
wr32_mask(PADC_MUX_M, func, PADC_MUX(gpio));
mutex_unlock(&aca->pin_lock);
return 0;
}
int dc_ep_pinmux_get(struct dc_ep_priv *priv, u32 gpio, int *func)
{
struct dc_aca *aca = to_aca(priv);
if (gpio > aca->max_gpio)
return -EINVAL;
*func = rd32(PADC_MUX(gpio));
return 0;
}
int dc_ep_gpio_pupd_set(struct dc_ep_priv *priv, u32 gpio, u32 val)
{
struct dc_aca *aca = to_aca(priv);
if (gpio > aca->max_gpio)
return -EINVAL;
/* Not support for both enabled */
if (val >= GPIO_PUPD_BOTH)
return -EINVAL;
mutex_lock(&aca->pin_lock);
switch (val) {
case GPIO_PUPD_DISABLE:
padc_clearbit(gpio, PADC_PUEN);
padc_clearbit(gpio, PADC_PDEN);
break;
case GPIO_PULL_UP:
padc_setbit(gpio, PADC_PUEN);
padc_clearbit(gpio, PADC_PDEN);
break;
case GPIO_PULL_DOWN:
padc_setbit(gpio, PADC_PDEN);
padc_clearbit(gpio, PADC_PUEN);
break;
default:
break;
}
mutex_unlock(&aca->pin_lock);
return 0;
}
int dc_ep_gpio_od_set(struct dc_ep_priv *priv, u32 gpio, int val)
{
struct dc_aca *aca = to_aca(priv);
if (gpio > aca->max_gpio)
return -EINVAL;
mutex_lock(&aca->pin_lock);
if (!!val)
padc_setbit(gpio, PADC_OD);
else
padc_clearbit(gpio, PADC_OD);
mutex_unlock(&aca->pin_lock);
return 0;
}
int dc_ep_gpio_src_set(struct dc_ep_priv *priv, u32 gpio, int val)
{
struct dc_aca *aca = to_aca(priv);
if (gpio > aca->max_gpio)
return -EINVAL;
mutex_lock(&aca->pin_lock);
if (!!val)
padc_setbit(gpio, PADC_SRC);
else
padc_clearbit(gpio, PADC_SRC);
mutex_unlock(&aca->pin_lock);
return 0;
}
int dc_ep_gpio_dcc_set(struct dc_ep_priv *priv, u32 gpio, u32 val)
{
struct dc_aca *aca = to_aca(priv);
if (gpio > aca->max_gpio)
return -EINVAL;
if (val >= GPIO_DRV_CUR_MAX)
return -EINVAL;
mutex_lock(&aca->pin_lock);
wr32_mask((0x3 << (gpio * 2)), (val << (gpio * 2)), PADC_DCC);
mutex_unlock(&aca->pin_lock);
return 0;
}

View File

@ -0,0 +1,51 @@
/*******************************************************************************
Intel SmartPHY DSL PCIe Endpoint/ACA Linux driver
Copyright(c) 2016 Intel Corporation.
This program is free software; you can redistribute it and/or modify it
under the terms and conditions of the GNU General Public License,
version 2, as published by the Free Software Foundation.
This program is distributed in the hope it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
more details.
You should have received a copy of the GNU General Public License along with
this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
The full GNU General Public License is included in this distribution in
the file called "COPYING".
*******************************************************************************/
#ifndef MISC_H
#define MISC_H
#define EP_TIMEOUT 10000
void dc_ep_clkod_disable(struct dc_ep_priv *priv);
void dc_ep_icu_init(struct dc_ep_priv *priv);
void dc_ep_icu_disable(struct dc_ep_priv *priv);
void dc_ep_assert_device(struct dc_ep_priv *priv, u32 bits);
void dc_ep_deassert_device(struct dc_ep_priv *priv, u32 bits);
int dc_ep_reset_device(struct dc_ep_priv *priv, u32 bits);
int dc_ep_clk_on(struct dc_ep_priv *priv, u32 bits);
int dc_ep_clk_off(struct dc_ep_priv *priv, u32 bits);
int dc_ep_clk_set(struct dc_ep_priv *priv, u32 sysclk, u32 ppeclk);
int dc_ep_clk_get(struct dc_ep_priv *priv, u32 *sysclk, u32 *ppeclk);
int dc_ep_gpio_dir(struct dc_ep_priv *priv, u32 gpio, int dir);
int dc_ep_gpio_set(struct dc_ep_priv *priv, u32 gpio, int val);
int dc_ep_gpio_get(struct dc_ep_priv *priv, u32 gpio, int *val);
int dc_ep_pinmux_set(struct dc_ep_priv *priv, u32 gpio, int func);
int dc_ep_pinmux_get(struct dc_ep_priv *priv, u32 gpio, int *func);
int dc_ep_gpio_pupd_set(struct dc_ep_priv *priv, u32 gpio, u32 val);
int dc_ep_gpio_od_set(struct dc_ep_priv *priv, u32 gpio, int val);
int dc_ep_gpio_src_set(struct dc_ep_priv *priv, u32 gpio, int val);
int dc_ep_gpio_dcc_set(struct dc_ep_priv *priv, u32 gpio, u32 val);
void dc_ep_icu_dis_intr(struct dc_ep_priv *priv, u32 bits);
void dc_ep_icu_en_intr(struct dc_ep_priv *priv, u32 bits);
#endif /* MISC_H */

View File

@ -0,0 +1,138 @@
/*******************************************************************************
Intel SmartPHY DSL PCIe Endpoint/ACA Linux driver
Copyright(c) 2016 Intel Corporation.
This program is free software; you can redistribute it and/or modify it
under the terms and conditions of the GNU General Public License,
version 2, as published by the Free Software Foundation.
This program is distributed in the hope it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
more details.
You should have received a copy of the GNU General Public License along with
this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
The full GNU General Public License is included in this distribution in
the file called "COPYING".
*******************************************************************************/
#ifndef REGS_H
#define REGS_H
#include <linux/bitops.h>
/* APPL defined */
#define PCIE_APPL_BASE 0x00048000
#define PCIE_APPL_REG(X) (PCIE_APPL_BASE + (X))
#define PCIE_APPL_PHY_CFG1 PCIE_APPL_REG(0x3C)
#define PCIE_APPL_PHY_CFG2 PCIE_APPL_REG(0x40)
#define PCIE_APPL_PHY_CFG3 PCIE_APPL_REG(0x58)
#define PCIE_APPL_PHY_CFG4 PCIE_APPL_REG(0x28)
#define PCIE_APPL_INTR_VEC PCIE_APPL_REG(0x48)
#define PCIE_APPL_MSI_EN PCIE_APPL_REG(0x4C)
#define PCIE_MSI_EN_ALL 0xFF
/* RCU defined */
#define RCU_BASE 0x00008000
#define RCU_REG(X) (RCU_BASE + (X))
#define RCU_STAT RCU_REG(0x00)
#define RCU_REQ RCU_REG(0x10)
#define RCU_MSI RCU_REG(0x80)
#define PCI_MSI_4_MODE 1
#define PCI_MSI_8_MODE 0
/* CGU */
#define CGU_BASE 0x00000000
#define CGU_REG(X) (CGU_BASE + (X))
#define PMU_PWDCR CGU_REG(0x011C)
#define PMU_SR CGU_REG(0x0120)
#define PMU_ALL 0x20ec0305
#define PLL_OMCFG CGU_REG(0x0064)
#define SYS_CLK 0x3
#define SYS_CLK_S 0
#define PPE_CLK 0x700
#define PPE_CLK_S 8
#define IF_CLK CGU_REG(0x0024)
#define CLK_PD BIT(10)
#define CLK_OD BIT(11)
#define PCIE_CLKOD (BIT(12) | BIT(13))
#define AFE_CLKOD BIT(14)
#define IF_CLKOD_ALL (CLK_PD | CLK_OD | PCIE_CLKOD | AFE_CLKOD)
/* GPIO */
#define GPIO_BASE 0x00020000
#define GPIO_REG(X) (GPIO_BASE + (X))
#define GPIO_OUT GPIO_REG(0x00)
#define GPIO_IN GPIO_REG(0x04)
#define GPIO_DIR GPIO_REG(0x08)
#define GPIO_OUTSET GPIO_REG(0x40)
#define GPIO_OUTCLR GPIO_REG(0x44)
#define GPIO_DIRSET GPIO_REG(0x48)
#define GPIO_DIRCLR GPIO_REG(0x4c)
/* PADC */
#define PADC_BASE 0x00024000
#define PADC_REG(X) (PADC_BASE + (X))
#define PADC_MUX(pin) PADC_REG(((pin) << 2))
#define PADC_PUEN PADC_REG(0x80)
#define PADC_PDEN PADC_REG(0x84)
#define PADC_SRC PADC_REG(0x88)
#define PADC_DCC PADC_REG(0x8c)
#define PADC_OD PADC_REG(0x94)
#define PADC_AVAIL PADC_REG(0x98)
#define PADC_MUX_M 0x7
/* ICU defined */
#define ICU_BASE 0x00010000
#define ICU_REG(X) (ICU_BASE + (X))
#define ICU_IMSR ICU_REG(0x40)
#define ICU_IMER ICU_REG(0x44)
#define ICU_IMOSR ICU_REG(0x48)
#define ICU_DMA_TX_STATUS ICU_REG(0x50)
#define ICU_DMA_RX_STATUS ICU_REG(0x54)
#define ICU_DMA_TX_IMER ICU_REG(0x58)
#define ICU_DMA_RX_IMER ICU_REG(0x5C)
#define ICU_DMA_TX_IMOSR ICU_REG(0x60)
#define ICU_DMA_RX_IMOSR ICU_REG(0x64)
#define PPE2HOST_INT0 BIT(0)
#define PPE2HOST_INT1 BIT(1)
#define DYING_GASP_INT BIT(3)
#define MEI_IRQ BIT(8)
#define ACA_XBAR_INT BIT(9)
#define MODEM_XBAR_INT BIT(12)
#define LED0_INT BIT(13)
#define LED1_INT BIT(14)
#define NMI_PLL BIT(15)
#define DMA_TX BIT(16)
#define DMA_RX BIT(17)
#define ACA_HOSTIF_TX BIT(20)
#define ACA_HOSTIF_RX BIT(21)
#define ACA_RXOUT_PD_RING_FULL BIT(22)
#define ACA_TXOUT_PD_RING_FULL BIT(23)
#define ICU_TOP_ALL 0x0003f30B /* Except ACA related */
#define ICU_DMA_TX_ALL 0x003f03FF
#define ICU_DMA_RX_ALL 0x003F03FF
#define wr32(value, reg) (writel(value, (priv->mem + (reg))))
#define rd32(reg) (readl(priv->mem + (reg)))
#define wrfl() ((void)rd32(RCU_STAT))
#define wr32_mask(clr, set, reg) \
wr32(((rd32(reg) & ~(clr)) | (set)), (reg))
#endif /* REGS_H */

View File

@ -0,0 +1,2 @@
obj-$(CONFIG_TEST) += ep_test.o

View File

@ -0,0 +1,924 @@
/*******************************************************************************
Intel SmartPHY DSL PCIe Endpoint/ACA Linux Test driver
Copyright(c) 2016 Intel Corporation.
This program is free software; you can redistribute it and/or modify it
under the terms and conditions of the GNU General Public License,
version 2, as published by the Free Software Foundation.
This program is distributed in the hope it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
more details.
You should have received a copy of the GNU General Public License along with
this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
The full GNU General Public License is included in this distribution in
the file called "COPYING".
*******************************************************************************/
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/version.h>
#include <linux/init.h>
#include <linux/types.h>
#include <linux/interrupt.h>
#include <linux/delay.h>
#include <net/dc_ep.h>
#include "ep_test.h"
#define DRV_VERSION "1.0.0"
static const char ep_test_driver_version[] = DRV_VERSION;
static struct dc_ep_dev pcie_dev[DC_EP_MAX_PEER + 1];
static int ppe_irq_num;
#define ep_wr32(value, reg) (writel(value, dev->membase + reg))
#define ep_rd32(reg) (readl(dev->membase + reg))
#define ep_wr32_mask(clr, set, reg) \
ep_wr32(((ep_rd32(reg) & ~(clr)) | (set)), (reg))
struct aca_hd_desc {
void *base;
dma_addr_t phy_base;
size_t size;/* in bytes */
};
struct aca_hd_desc_cfg {
struct aca_hd_desc txin;
struct aca_hd_desc txout;
struct aca_hd_desc rxout;
};
static struct aca_hd_desc_cfg aca_soc_hd_desc[DC_EP_MAX_PEER + 1];
static void ep_mem_write(u8 __iomem *dst, const void *src, size_t len)
{
int i;
const u32 *src_addr = src;
if (len % 4)
pr_info("Warning!!: Copy len is not multiple of 4\n");
len = len >> 2;
for (i = 0; i < len; i++)
writel(src_addr[i], (dst + (i << 2)));
}
static irqreturn_t dc_ep_ppe_intr(int irq, void *dev_id)
{
struct dc_ep_dev *dev = dev_id;
ppe_irq_num++;
if (ep_rd32(MBOX_IGU0_ISR) == 0) {
pr_err("Fatal error, dummy interrupt\n");
return IRQ_NONE;
}
ep_wr32(PPE_MBOX_TEST_BIT, MBOX_IGU0_ISRC);
ep_rd32(MBOX_IGU0_ISR);
return IRQ_HANDLED;
}
static void dc_ep_ppe_mbox_reg_dump(struct dc_ep_dev *dev)
{
pr_info("MBOX_IGU0_ISRS addr %p data 0x%08x\n",
dev->membase + MBOX_IGU0_ISRS,
ep_rd32(MBOX_IGU0_ISRS));
pr_info("MBOX_IGU0_ISRC addr %p data 0x%08x\n",
dev->membase + MBOX_IGU0_ISRC,
ep_rd32(MBOX_IGU0_ISRC));
pr_info("MBOX_IGU0_ISR addr %p data 0x%08x\n",
dev->membase + MBOX_IGU0_ISR,
ep_rd32(MBOX_IGU0_ISR));
pr_info("MBOX_IGU0_IER addr %p data 0x%08x\n",
dev->membase + MBOX_IGU0_IER,
ep_rd32(MBOX_IGU0_IER));
}
#define PPE_INT_TIMEOUT 10
static int dc_ep_ppe_mbox_int_stress_test(struct dc_ep_dev *dev)
{
int i;
int j;
int ret;
/* Clear it first */
ep_wr32(PPE_MBOX_TEST_BIT, MBOX_IGU0_ISRC);
ret = request_irq(dev->irq, dc_ep_ppe_intr, 0, "PPE_MSI", dev);
if (ret) {
pr_err("%s request irq %d failed\n", __func__, dev->irq);
return -1;
}
pr_info("PPE test\n");
ep_wr32(PPE_MBOX_TEST_BIT, MBOX_IGU0_IER);
ppe_irq_num = 0;
/* Purposely trigger interrupt */
for (i = 0; i < PPE_MBOX_IRQ_TEST_NUM; i++) {
j = 0;
while ((ep_rd32(MBOX_IGU0_ISR) & PPE_MBOX_TEST_BIT)) {
j++;
if (j > PPE_INT_TIMEOUT)
break;
}
ep_wr32(PPE_MBOX_TEST_BIT, MBOX_IGU0_ISRS);
/* Write flush */
ep_rd32(MBOX_IGU0_ISR);
}
mdelay(10);
pr_info("irq triggered %d expected %d\n", ppe_irq_num,
PPE_MBOX_IRQ_TEST_NUM);
dc_ep_ppe_mbox_reg_dump(dev);
ppe_irq_num = 0;
return 0;
}
static void umt_txin_send(struct dc_ep_dev *dev,
u8 __iomem *soc_dbase, int num)
{
int i;
struct aca_dma_desc desc;
memset(&desc, 0, sizeof(desc));
desc.own = 0;
desc.sop = 1;
desc.eop = 1;
desc.dic = 1;
desc.pdu_type = 1;
desc.data_len = 127;
desc.data_pointer = 0x26000000;
desc.dw1 = 0x700;
desc.dw0 = 0x0000007f;
for (i = 0; i < num; i++) {
desc.data_pointer += roundup(desc.data_len, 4);
ep_mem_write(soc_dbase + i * sizeof(desc),
(void *)&desc, sizeof(desc));
}
ep_wr32(num, TXIN_HD_ACCUM_ADD);
}
static void ppe_txout_send(struct dc_ep_dev *dev,
u8 __iomem *ppe_sb_base, int num)
{
int i;
struct aca_dma_desc_2dw desc;
memset(&desc, 0, sizeof(desc));
desc.status.field.own = 1;
desc.status.field.sop = 1;
desc.status.field.eop = 1;
desc.status.field.data_len = 127;
desc.data_pointer = 0x26100000;
for (i = 0; i < num; i++) {
desc.data_pointer += roundup(desc.status.field.data_len, 4);
ep_mem_write(ppe_sb_base + i * sizeof(desc),
(void *)&desc, sizeof(desc));
}
ep_wr32(num, TXOUT_ACA_ACCUM_ADD);
}
static void ppe_rxout_send(struct dc_ep_dev *dev,
u8 __iomem *ppe_sb_base, int num)
{
int i;
struct aca_dma_desc_2dw desc;
memset(&desc, 0, sizeof(desc));
desc.status.field.own = 0;
desc.status.field.sop = 1;
desc.status.field.eop = 1;
desc.status.field.meta_data0 = 0x3;
desc.status.field.meta_data1 = 0x7f;
desc.status.field.data_len = 127;
desc.data_pointer = 0x26200000;
for (i = 0; i < num; i++) {
desc.data_pointer += roundup(desc.status.field.data_len, 4);
ep_mem_write(ppe_sb_base + i * sizeof(desc),
(void *)&desc, sizeof(desc));
}
ep_wr32(num, RXOUT_ACA_ACCUM_ADD);
}
static void dc_aca_test_init(struct dc_ep_dev *dev, void *soc_base)
{
umt_txin_send(dev, (u8 __iomem *)soc_base, 8);
ppe_txout_send(dev, (TXOUT_PD_DBASE + dev->membase), 8);
ppe_rxout_send(dev, (RXOUT_PD_DBASE + dev->membase), 8);
}
static const char *sysclk_str[SYS_CLK_MAX] = {
"36MHz",
"288MHz",
};
static const char *ppeclk_str[PPE_CLK_MAX] = {
"36MHz",
"576MHz",
"494MHz",
"432MHz",
"288MHz",
};
#define ACA_PMU_CTRL 0x11C
#define ACA_PMU_DMA BIT(2)
#define ACA_PMU_EMA BIT(22)
enum {
DMA_ENDIAN_TYPE0 = 0,
DMA_ENDIAN_TYPE1, /*!< Byte Swap(B0B1B2B3 => B1B0B3B2) */
DMA_ENDIAN_TYPE2, /*!< Word Swap (B0B1B2B3 => B2B3B0B1) */
DMA_ENDIAN_TYPE3, /*!< DWord Swap (B0B1B2B3 => B3B2B1B0) */
DMA_ENDIAN_MAX,
};
#ifdef CONFIG_CPU_BIG_ENDIAN
#define DMA_ENDIAN_DEFAULT DMA_ENDIAN_TYPE3
#else
#define DMA_ENDIAN_DEFAULT DMA_ENDIAN_TYPE0
#endif
enum {
DMA_BURSTL_2DW = 1, /*!< 2 DWORD DMA burst length */
DMA_BURSTL_4DW = 2, /*!< 4 DWORD DMA burst length */
DMA_BURSTL_8DW = 3, /*!< 8 DWORD DMA burst length */
DMA_BURSTL_16DW = 16,
};
#define DMA_BURSTL_DEFAULT DMA_BURSTL_16DW
#define DMA_TX_PORT_DEFAULT_WEIGHT 1
/** Default Port Transmit weight value */
#define DMA_TX_CHAN_DEFAULT_WEIGHT 1
enum {
DMA_RX_CH = 0, /*!< Rx channel */
DMA_TX_CH = 1, /*!< Tx channel */
};
enum {
DMA_PKT_DROP_DISABLE = 0,
DMA_PKT_DROP_ENABLE,
};
#ifdef CONFIG_CPU_BIG_ENDIAN
/* 2 DWs format descriptor */
struct rx_desc_2dw {
u32 data_pointer; /* Descriptor data pointer */
union {
struct {
u32 own:1;
u32 c:1;
u32 sop:1;
u32 eop:1;
u32 meta:2;
u32 byte_offset:3;
u32 meta_data:7;
u32 data_len:16;
} __packed field;
u32 word;
} __packed status;
} __packed __aligned(8);
struct tx_desc_2dw {
u32 data_pointer; /* Descriptor data pointer */
union {
struct {
u32 own:1;
u32 c:1;
u32 sop:1;
u32 eop:1;
u32 meta:2;
u32 byte_offset:3;
u32 meta_data:7;
u32 data_len:16;
} __packed field;
u32 word;
} __packed status;
} __packed __aligned(8);
#else
/* 2 DWs format descriptor */
struct rx_desc_2dw {
u32 data_pointer; /* Descriptor data pointer */
union {
struct {
u32 data_len:16;
u32 meta_data:7;
u32 byte_offset:3;
u32 meta:2;
u32 eop:1;
u32 sop:1;
u32 c:1;
u32 own:1;
} __packed field;
u32 word;
} __packed status;
} __packed __aligned(8);
struct tx_desc_2dw {
u32 data_pointer; /* Descriptor data pointer */
union {
struct {
u32 data_len:16;
u32 meta_data:7;
u32 byte_offset:3;
u32 meta:2;
u32 eop:1;
u32 sop:1;
u32 c:1;
u32 own:1;
} __packed field;
u32 word;
} __packed status;
} __packed __aligned(8);
#endif
enum {
SOC_TO_EP = 0,
EP_TO_SOC,
};
static int dma_pkt_size = 1024;
static int dma_mode = SOC_TO_EP;
static int dma_burst = 16;
static int desc_num = 32;
module_param(dma_pkt_size, int, 0);
MODULE_PARM_DESC(dma_pkt_size, "Single packet length");
module_param(dma_mode, int, 0);
MODULE_PARM_DESC(dma_mode, "mode 0 -- Soc->EP, mode 1-- EP->SoC");
static void dma_ctrl_rst(struct dc_ep_dev *dev)
{
ep_wr32_mask(ACA_PMU_DMA | ACA_PMU_EMA, 0, ACA_PMU_CTRL);
udelay(10);
ep_wr32_mask(0, 1, DMA_CTRL);
udelay(10);
ep_wr32(0, DMA_CLC);
}
static void dma_chan_rst(struct dc_ep_dev *dev, int cn)
{
ep_wr32(cn, DMA_CS);
ep_wr32(0x2, DMA_CCTRL);
while (ep_rd32(DMA_CCTRL) & 0x01)
udelay(10);
}
static void dma_port_cfg(struct dc_ep_dev *dev)
{
u32 reg = 0;
reg |= (DMA_TX_PORT_DEFAULT_WEIGHT << 12);
reg |= (DMA_ENDIAN_TYPE0 << 10);
reg |= (DMA_ENDIAN_TYPE0 << 8);
reg |= (DMA_PKT_DROP_DISABLE << 6);
reg |= 0x3;
ep_wr32(0, DMA_PS);
ep_wr32(reg, DMA_PCTRL);
}
static void dma_byte_enable(struct dc_ep_dev *dev, int enable)
{
if (enable)
ep_wr32_mask(0, BIT(9), DMA_CTRL);
else
ep_wr32_mask(BIT(9), 0, DMA_CTRL);
}
static void dma_tx_ch_cfg(struct dc_ep_dev *dev, int ch, u32 desc_base,
u32 desc_phys, dma_addr_t data_base, int desc_num)
{
int i;
struct tx_desc_2dw *tx_desc;
for (i = 0; i < desc_num; i++) {
tx_desc = (struct tx_desc_2dw *)
(desc_base + (i * sizeof(*tx_desc)));
tx_desc->data_pointer = (((u32)(data_base +
(i * dma_pkt_size))) & 0xfffffff8);
tx_desc->status.word = 0;
tx_desc->status.field.byte_offset = 0;
tx_desc->status.field.data_len = dma_pkt_size;
tx_desc->status.field.sop = 1;
tx_desc->status.field.eop = 1;
tx_desc->status.field.own = 1;
wmb();
#if 0
pr_info("Tx desc num %d word 0x%08x data pointer 0x%08x\n",
i, tx_desc->status.word, tx_desc->data_pointer);
#endif
}
ep_wr32(ch, DMA_CS);
ep_wr32(desc_phys, DMA_CDBA);
ep_wr32(desc_num, DMA_CDLEN);
ep_wr32(0, DMA_CIE);
}
static void dma_rx_ch_cfg(struct dc_ep_dev *dev, int ch, u32 desc_base,
u32 desc_phys, dma_addr_t data_base, int desc_num)
{
int i;
struct rx_desc_2dw *rx_desc;
for (i = 0; i < desc_num; i++) {
rx_desc = (struct rx_desc_2dw *)(desc_base
+ (i * sizeof(*rx_desc)));
rx_desc->data_pointer = (((u32)(data_base +
(i * dma_pkt_size))) & 0xfffffff8);
rx_desc->status.word = 0;
rx_desc->status.field.sop = 1;
rx_desc->status.field.eop = 1;
rx_desc->status.field.byte_offset = 0;
rx_desc->status.field.data_len = dma_pkt_size;
rx_desc->status.field.own = 1; /* DMA own the descriptor */
wmb();
#if 0
pr_info("Rx desc num %d word 0x%08x data pointer 0x%08x\n",
i, rx_desc->status.word, rx_desc->data_pointer);
#endif
}
ep_wr32(ch, DMA_CS);
ep_wr32(desc_phys, DMA_CDBA);
ep_wr32(desc_num, DMA_CDLEN);
ep_wr32(0, DMA_CIE);
}
static void dma_chan_on(struct dc_ep_dev *dev, u8 cn)
{
ep_wr32(cn, DMA_CS);
ep_wr32_mask(0, BIT(0), DMA_CCTRL);
}
static void dma_chan_off(struct dc_ep_dev *dev, u8 cn)
{
ep_wr32(cn, DMA_CS);
ep_wr32_mask(BIT(0), 0, DMA_CCTRL);
udelay(10);
}
#define DEFAULT_TEST_PATTEN 0x12345678
#define REG32(addr) (*((volatile u32*)(addr)))
#ifdef CONFIG_CPU_BIG_ENDIAN
#define ___swab32(x) ((u32)( \
(((u32)(x) & (u32)0x000000ffUL) << 24) | \
(((u32)(x) & (u32)0x0000ff00UL) << 8) | \
(((u32)(x) & (u32)0x00ff0000UL) >> 8) | \
(((u32)(x) & (u32)0xff000000UL) >> 24)))
#else
#define ___swab32(x) (x)
#endif
static void dma_sdram_preload(void *sdram_data_tx_ptr, void *sdram_data_rx_ptr)
{
int i;
int j;
u32 testaddr = (u32)sdram_data_tx_ptr;
for (i = 0; i < desc_num; i++) {
for (j = 0; j < dma_pkt_size; j = j + 4) {
REG32(testaddr + i * dma_pkt_size + j)
= DEFAULT_TEST_PATTEN;
}
}
pr_info("SDR Preload(0x55aa00ff) with data on TX location done\n");
testaddr = (u32)sdram_data_rx_ptr;
pr_info("RX Preload start address:0x%08x\n", (u32)(testaddr));
for (i = 0; i < desc_num; i++) {
for (j = 0; j < roundup(dma_pkt_size,
dma_burst << 2); j = j + 4)
REG32(testaddr + i * dma_pkt_size + j) = 0xcccccccc;
}
pr_info("SDR locations for Memcopy RX preset to 0xcccccccc done\n");
}
static void memcopy_data_check(u32 rx_data_addr)
{
int i, j;
u32 read_data;
for (i = 0; i < desc_num; i++) {
for (j = 0; j < dma_pkt_size; j = j + 4) {
read_data = REG32(rx_data_addr + i * dma_pkt_size + j);
if (read_data != ___swab32(DEFAULT_TEST_PATTEN))
pr_info("Memcopy ERROR at addr 0x%08x data 0x%08x\n",
(rx_data_addr + j), read_data);
}
}
}
static u32 plat_throughput_calc(u32 payload, int cycles)
{
return (u32)((payload * 300) / cycles);
}
#define DMA_CPOLL_CNT_MASK 0xFFF0u
static void dma_ctrl_global_polling_enable(struct dc_ep_dev *dev, int interval)
{
u32 reg = 0;
reg |= (1 << 31);
reg |= (interval << 4);
ep_wr32_mask(DMA_CPOLL_CNT_MASK,
reg, DMA_CPOLL);
}
static void dma_controller_cfg(struct dc_ep_dev *dev)
{
ep_wr32_mask(0, BIT(31), DMA_CTRL);
ep_wr32_mask(BIT(30), 0, DMA_CTRL);
ep_wr32_mask(0, BIT(1), DMA_CTRL);
ep_wr32_mask(0, BIT(13), DMA_CTRL);
}
#define PDRAM_OFFSET 0x200200
#define PDRAM_TX_DESC_OFFSET 0x200000
#define PDRAM_RX_DESC_OFFSET 0x200100
#define ACA_SRAM_OFFSET 0x100000
#define PPE_SB_TX_DESC_OFFSET 0x280000
#define PPE_SB_RX_DESC_OFFSET 0x281000
#define PPE_FPI_TX_DESC_OFFSET 0x320000
#define PPE_FPI_RX_DESC_OFFSET 0x321000
static void dma_test(struct dc_ep_dev *dev, int mode, int rcn, int tcn)
{
u32 loop = 0;
void *tx_data;
void *rx_data;
dma_addr_t tx_data_phys = 0;
dma_addr_t rx_data_phys = 0;
u32 start, end;
u32 cycles;
struct rx_desc_2dw *rx_desc;
struct tx_desc_2dw *tx_desc;
struct tx_desc_2dw *last_tx_desc;
struct rx_desc_2dw *last_rx_desc;
dma_addr_t tx_desc_phys;
dma_addr_t rx_desc_phys;
u32 membase = (u32)(dev->membase);
rx_desc = (struct rx_desc_2dw *)(membase + PDRAM_RX_DESC_OFFSET);
rx_desc_phys = (dev->phy_membase + PDRAM_RX_DESC_OFFSET);
tx_desc = (struct tx_desc_2dw *)(membase + PDRAM_TX_DESC_OFFSET);
tx_desc_phys = (dev->phy_membase + PDRAM_TX_DESC_OFFSET);
last_rx_desc = rx_desc + (desc_num - 1);
last_tx_desc = tx_desc + (desc_num - 1);
if (mode == SOC_TO_EP) { /* Read from SoC DDR to local PDBRAM */
tx_data = dma_alloc_coherent(NULL,
desc_num * dma_pkt_size, &tx_data_phys, GFP_DMA);
rx_data_phys = (dma_addr_t)(dev->phy_membase + PDRAM_OFFSET);
rx_data = (void *)(membase + PDRAM_OFFSET);
} else { /* Write from local PDBRAM to remote DDR */
tx_data_phys = (dma_addr_t)(dev->phy_membase + PDRAM_OFFSET);
tx_data = (void *)(membase + PDRAM_OFFSET);
rx_data = dma_alloc_coherent(NULL, desc_num * dma_pkt_size,
&rx_data_phys, GFP_DMA);
}
pr_info("tx_desc_base %p tx_desc_phys 0x%08x tx_data %p tx_data_phys 0x%08x\n",
tx_desc, (u32)tx_desc_phys, tx_data, (u32)tx_data_phys);
pr_info("rx_desc_base %p rx_desc_phys 0x%08x rx_data %p rx_data_phys 0x%08x\n",
rx_desc, (u32)rx_desc_phys, rx_data, (u32)rx_data_phys);
pr_info("dma burst %d desc number %d packet size %d\n",
dma_burst, desc_num, dma_pkt_size);
dma_ctrl_rst(dev);
dma_chan_rst(dev, rcn);
dma_chan_rst(dev, tcn);
dma_port_cfg(dev);
dma_controller_cfg(dev);
dma_byte_enable(dev, 1);
dma_ctrl_global_polling_enable(dev, 24);
dma_sdram_preload(tx_data, rx_data);
dma_tx_ch_cfg(dev, tcn, (u32)tx_desc, tx_desc_phys,
tx_data_phys, desc_num);
dma_rx_ch_cfg(dev, rcn, (u32)rx_desc, rx_desc_phys,
rx_data_phys, desc_num);
udelay(5); /* Make sure that RX descriptor prefetched */
start = get_cycles();
dma_chan_on(dev, rcn);
dma_chan_on(dev, tcn);
/* wait till tx chan desc own is 0 */
while (last_tx_desc->status.field.own == 1) {
loop++;
udelay(1);
}
end = get_cycles();
cycles = end - start;
pr_info("cylces %d throughput %dMb\n", cycles,
plat_throughput_calc(desc_num * dma_pkt_size * 8, cycles));
pr_info("loop times %d\n", loop);
while (last_rx_desc->status.field.own == 1) {
loop++;
udelay(1);
}
memcopy_data_check((u32)rx_data);
dma_chan_off(dev, rcn);
dma_chan_off(dev, tcn);
if (mode == SOC_TO_EP) {
dma_free_coherent(NULL, desc_num * dma_pkt_size,
tx_data, tx_data_phys);
} else {
dma_free_coherent(NULL, desc_num * dma_pkt_size,
rx_data, rx_data_phys);
}
}
static int aca_soc_desc_alloc(int dev)
{
dma_addr_t phy_addr;
void *base;
u32 size;
if (dev < 0 || dev > (DC_EP_MAX_PEER + 1))
return -EINVAL;
/* TXIN */
size = TXIN_SOC_DES_NUM * TXIN_HD_DES_SIZE * 4;
base = dma_alloc_coherent(NULL, size, &phy_addr, GFP_DMA);
if (!base)
goto txin;
aca_soc_hd_desc[dev].txin.base = base;
aca_soc_hd_desc[dev].txin.phy_base = phy_addr;
aca_soc_hd_desc[dev].txin.size = size;
pr_info("txin soc desc base %p phy 0x%08x size 0x%08x\n",
base, (u32)phy_addr, size);
/* TXOUT */
size = TXOUT_SOC_DES_NUM * TXOUT_HD_DES_SIZE * 4;
base = dma_alloc_coherent(NULL, size, &phy_addr, GFP_DMA);
if (!base)
goto txout;
aca_soc_hd_desc[dev].txout.base = base;
aca_soc_hd_desc[dev].txout.phy_base = phy_addr;
aca_soc_hd_desc[dev].txout.size = size;
pr_info("txout soc desc base %p phy 0x%08x size 0x%08x\n",
base, (u32)phy_addr, size);
/* RXOUT */
size = RXOUT_SOC_DES_NUM * RXOUT_HD_DES_SIZE * 4;
base = dma_alloc_coherent(NULL, size, &phy_addr, GFP_DMA);
if (!base)
goto rxout;
aca_soc_hd_desc[dev].rxout.base = base;
aca_soc_hd_desc[dev].rxout.phy_base = phy_addr;
aca_soc_hd_desc[dev].rxout.size = size;
pr_info("rxout soc desc base %p phy 0x%08x size 0x%08x\n",
base, (u32)phy_addr, size);
return 0;
rxout:
dma_free_coherent(NULL, aca_soc_hd_desc[dev].txout.size,
aca_soc_hd_desc[dev].txout.base,
aca_soc_hd_desc[dev].txout.phy_base);
txout:
dma_free_coherent(NULL, aca_soc_hd_desc[dev].txin.size,
aca_soc_hd_desc[dev].txin.base,
aca_soc_hd_desc[dev].txin.phy_base);
txin:
return -ENOMEM;
}
static int aca_soc_desc_free(int dev)
{
dma_addr_t phy_addr;
void *base;
size_t size;
if (dev < 0 || dev > (DC_EP_MAX_PEER + 1))
return -EINVAL;
/* TXIN */
base = aca_soc_hd_desc[dev].txin.base;
phy_addr = aca_soc_hd_desc[dev].txin.phy_base;
size = aca_soc_hd_desc[dev].txin.size;
dma_free_coherent(NULL, size, base, phy_addr);
/* TXOUT */
base = aca_soc_hd_desc[dev].txout.base;
phy_addr = aca_soc_hd_desc[dev].txout.phy_base;
size = aca_soc_hd_desc[dev].txout.size;
dma_free_coherent(NULL, size, base, phy_addr);
/* RXOUT */
base = aca_soc_hd_desc[dev].rxout.base;
phy_addr = aca_soc_hd_desc[dev].rxout.phy_base;
size = aca_soc_hd_desc[dev].rxout.size;
dma_free_coherent(NULL, size, base, phy_addr);
return 0;
}
static int __init dc_ep_test_init(void)
{
int i, j;
int dev_num;
struct dc_ep_dev dev;
int func = 0;
u32 sysclk = 0;
u32 ppeclk = 0;
if (dc_ep_dev_num_get(&dev_num)) {
pr_err("%s failed to get total device number\n", __func__);
return -EIO;
}
pr_info("%s: total %d EPs found\n", __func__, dev_num);
for (i = 0; i < dev_num; i++)
aca_soc_desc_alloc(i);
for (i = 0; i < dev_num; i++) {
struct aca_param aca_cfg = {
.aca_txin = {
.soc_desc_base
= aca_soc_hd_desc[i].txin.phy_base,
.soc_desc_num = TXIN_SOC_DES_NUM,
.pp_buf_desc_num = 32,
.pd_desc_base = TXIN_PD_DBASE,
.pd_desc_num = TXIN_PD_DES_NUM,
.hd_size_in_dw = TXIN_HD_DES_SIZE,
.pd_size_in_dw = TXIN_PD_DES_SIZE,
.byteswap = 1,
},
.aca_txout = {
.soc_desc_base
= aca_soc_hd_desc[i].txout.phy_base,
.soc_desc_num = TXOUT_SOC_DES_NUM,
.pp_buf_desc_num = 32,
.pd_desc_base = TXOUT_PD_DBASE,
.pd_desc_num = TXOUT_PD_DES_NUM,
.hd_size_in_dw = TXOUT_HD_DES_SIZE,
.pd_size_in_dw = TXOUT_PD_DES_SIZE,
.byteswap = 1,
},
.aca_rxout = {
.soc_desc_base
= aca_soc_hd_desc[i].rxout.phy_base,
.soc_desc_num = RXOUT_SOC_DES_NUM,
.pp_buf_desc_num = 32,
.pd_desc_base = RXOUT_PD_DBASE,
.pd_desc_num = RXOUT_PD_DES_NUM,
.hd_size_in_dw = RXOUT_HD_DES_SIZE,
.pd_size_in_dw = RXOUT_PD_DES_SIZE,
.byteswap = 1,
},
};
struct aca_modem_param modem_cfg = {
.mdm_txout = {
.stat = SB_XBAR_ADDR(__TX_OUT_ACA_ACCUM_STATUS),
.pd = SB_XBAR_ADDR(__TX_OUT_QUEUE_PD_BASE_ADDR_OFFSET),
.acc_cnt = SB_XBAR_ADDR(__TX_OUT_ACA_ACCUM_COUNT),
},
.mdm_rxout = {
.stat = SB_XBAR_ADDR(__RX_OUT_ACA_ACCUM_STATUS),
.pd = SB_XBAR_ADDR(__RX_OUT_QUEUE_PD_BASE_ADDR_OFFSET),
.acc_cnt = SB_XBAR_ADDR(__RX_OUT_ACA_ACCUM_COUNT),
},
.mdm_rxin = {
.stat = SB_XBAR_ADDR(__RX_IN_ACA_ACCUM_STATUS),
.pd = SB_XBAR_ADDR(__RX_IN_QUEUE_PD_BASE_ADDR_OFFSET),
.acc_cnt = SB_XBAR_ADDR(__RX_IN_ACA_ACCUM_COUNT),
},
};
if (dc_ep_dev_info_req(i, DC_EP_INT_PPE, &dev))
pr_info("%s failed to get pcie ep %d information\n",
__func__, i);
pr_info("irq %d\n", dev.irq);
pr_info("phyiscal membase 0x%08x virtual membase 0x%p\n",
dev.phy_membase, dev.membase);
if (dev_num > 1) {
for (j = 0; j < dev.peer_num; j++) {
pr_info("phyiscal peer membase 0x%08x virtual peer membase 0x%p\n",
dev.peer_phy_membase[j], dev.peer_membase[j]);
}
}
/* For module unload perpose */
memcpy(&pcie_dev[i], &dev, sizeof(struct dc_ep_dev));
dc_ep_ppe_mbox_int_stress_test(&pcie_dev[i]);
dev.hw_ops->clk_on(&dev, PMU_CDMA | PMU_EMA | PMU_PPM2);
dev.hw_ops->clk_set(&dev, SYS_CLK_288MHZ, PPE_CLK_576MHZ);
dev.hw_ops->pinmux_set(&dev, 14, MUX_FUNC_ALT1);
dev.hw_ops->pinmux_set(&dev, 15, MUX_FUNC_ALT2);
dev.hw_ops->pinmux_get(&dev, 15, &func);
pr_info("gpio 15 func %d\n", func);
dev.hw_ops->pinmux_set(&dev, 13, MUX_FUNC_GPIO);
dev.hw_ops->gpio_dir(&dev, 13, GPIO_DIR_OUT);
dev.hw_ops->gpio_set(&dev, 13, 1);
dev.hw_ops->gpio_get(&dev, 13, &func);
pr_info("gpio 13 value %d\n", func);
dev.hw_ops->gpio_pupd_set(&dev, 14, GPIO_PULL_DOWN);
dev.hw_ops->gpio_od_set(&dev, 0, 1);
dev.hw_ops->gpio_src_set(&dev, 0, GPIO_SLEW_RATE_FAST);
dev.hw_ops->gpio_dcc_set(&dev, 0, GPIO_DRV_CUR_8MA);
dev.hw_ops->clk_get(&dev, &sysclk, &ppeclk);
pr_info("ppe clk %s sys clk %s\n", ppeclk_str[ppeclk],
sysclk_str[sysclk]);
dev.hw_ops->aca_init(&dev, &aca_cfg, &modem_cfg);
dev.hw_ops->aca_start(&dev, ACA_ALL_EN, 1);
pr_info("ACA test\n");
dc_aca_test_init(&dev, aca_soc_hd_desc[i].txin.base);
pr_info("DMA test\n");
dma_pkt_size = 64;
dma_test(&dev, dma_mode, 0, 1);
#if 0
dma_pkt_size = 128;
dma_test(&dev, dma_mode, 0, 1);
dma_pkt_size = 256;
dma_test(&dev, dma_mode, 0, 1);
dma_pkt_size = 512;
dma_test(&dev, dma_mode, 0, 1);
dma_pkt_size = 1024;
dma_test(&dev, dma_mode, 0, 1);
dma_pkt_size = 2048;
dma_test(&dev, dma_mode, 0, 1);
dma_mode = EP_TO_SOC;
dma_pkt_size = 64;
dma_test(&dev, dma_mode, 0, 1);
dma_pkt_size = 128;
dma_test(&dev, dma_mode, 0, 1);
dma_pkt_size = 256;
dma_test(&dev, dma_mode, 0, 1);
dma_pkt_size = 512;
dma_test(&dev, dma_mode, 0, 1);
dma_pkt_size = 1024;
dma_test(&dev, dma_mode, 0, 1);
dma_pkt_size = 2048;
dma_test(&dev, dma_mode, 0, 1);
#endif
}
pr_info("Intel(R) SmartPHY DSL(VRX518) PCIe EP Test Driver - %s\n",
ep_test_driver_version);
return 0;
}
static void __exit dc_ep_test_exit(void)
{
int i;
int dev_num;
u32 func = ACA_ALL_EN;
struct dc_ep_dev *dev;
if (dc_ep_dev_num_get(&dev_num)) {
pr_err("%s failed to get total device number\n", __func__);
return;
}
pr_info("%s: total %d EPs found\n", __func__, dev_num);
for (i = 0; i < dev_num; i++) {
dev = &pcie_dev[i];
free_irq(dev->irq, dev);
dev->hw_ops->aca_stop(dev, &func, 1);
dev->hw_ops->clk_off(dev, PMU_EMA);
if (dc_ep_dev_info_release(i)) {
pr_info("%s failed to release pcie ep %d information\n",
__func__, i);
}
aca_soc_desc_free(i);
}
}
module_init(dc_ep_test_init);
module_exit(dc_ep_test_exit);
MODULE_AUTHOR("Intel Corporation, <Chuanhua.lei@intel.com>");
MODULE_DESCRIPTION("Intel(R) SmartPHY (VRX518) PCIe EP/ACA test driver");
MODULE_LICENSE("GPL");

View File

@ -0,0 +1,273 @@
/*******************************************************************************
Intel SmartPHY DSL PCIe Endpoint/ACA Linux driver
Copyright(c) 2016 Intel Corporation.
This program is free software; you can redistribute it and/or modify it
under the terms and conditions of the GNU General Public License,
version 2, as published by the Free Software Foundation.
This program is distributed in the hope it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
more details.
You should have received a copy of the GNU General Public License along with
this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
The full GNU General Public License is included in this distribution in
the file called "COPYING".
*******************************************************************************/
#ifndef EP_TEST_H
#define EP_TEST_H
/* SB address on xBar */
#define SB_XBAR_BASE 0x280000
#define SB_XBAR_DES_RXBASE SB_XBAR_BASE
#define SB_XBAR_DES_TXBASE (SB_XBAR_BASE + 0x400)
#define SB_XBAR_DATA_BASE (SB_XBAR_BASE + 0x800)
#define SB_XBAR_ADDR(x) (SB_XBAR_BASE + ((((x) - 0xA000)) << 2))
/*----------------------------------------------------------
* ACA Shadow Registers
* 3 * 4 = 12
* *_STATUS need to be initialized to nonzero by PPE driver
*----------------------------------------------------------
*/
#define __ACA_SHADOW_REG_BASE 0xADF0
#define __TX_IN_ACA_ACCUM_COUNT 0xADF0
#define __TX_IN_ACA_ACCUM_STATUS 0xADF1
#define __TX_IN_QUEUE_PD_BASE_ADDR_OFFSET 0xADF2
#define __TX_OUT_ACA_ACCUM_COUNT 0xADF3
#define __TX_OUT_ACA_ACCUM_STATUS 0xADF4
#define __TX_OUT_QUEUE_PD_BASE_ADDR_OFFSET 0xADF5
#define __RX_IN_ACA_ACCUM_COUNT 0xADF6
#define __RX_IN_ACA_ACCUM_STATUS 0xADF7
#define __RX_IN_QUEUE_PD_BASE_ADDR_OFFSET 0xADF8
#define __RX_OUT_ACA_ACCUM_COUNT 0xADF9
#define __RX_OUT_ACA_ACCUM_STATUS 0xADFA
#define __RX_OUT_QUEUE_PD_BASE_ADDR_OFFSET 0xADFB
#define TXIN_PD_DES_NUM 64
#define TXIN_PD_DBASE 0x105400
#define TXIN_SOC_DES_NUM 32
#define TXIN_SOC_DBASE 0x24000000
#define TXIN_HOST_DES_NUM 32
#define TXIN_HD_DES_SIZE 4 /* size in DWORD */
#define TXIN_PD_DES_SIZE 2 /* size in DWORD */
#define TXOUT_PD_DES_NUM 32
#define TXOUT_PD_DBASE 0x105700
#define TXOUT_SOC_DES_NUM 32
#define TXOUT_SOC_DBASE 0x24001000
#define TXOUT_HOST_DES_NUM 32
#define TXOUT_HD_DES_SIZE 1 /* size in DWORD */
#define TXOUT_PD_DES_SIZE 2 /* size in DWORD */
#define RXOUT_PD_DES_NUM 32
#define RXOUT_PD_DBASE 0x105C00
#define RXOUT_SOC_DES_NUM 32
#define RXOUT_SOC_DBASE 0x24002000
#define RXOUT_HOST_DES_NUM 32
#define RXOUT_HD_DES_SIZE 4 /* size in DWORD */
#define RXOUT_PD_DES_SIZE 2 /* size in DWORD */
/* PPE interrupt */
#define PPE_MBOX_TEST_BIT 0x1
#define PPE_MBOX_IRQ_TEST_NUM 100
#define PPE_MBOX_BASE 0x334800
#define MBOX_REG(X) (PPE_MBOX_BASE + (X))
#define MBOX_IGU0_ISRS MBOX_REG(0x0)
#define MBOX_IGU0_ISRC MBOX_REG(0x4)
#define MBOX_IGU0_ISR MBOX_REG(0x8)
#define MBOX_IGU0_IER MBOX_REG(0xc)
#define HOST_IF_BASE 0x50000
#define HOST_IF_REG(X) (HOST_IF_BASE + (X))
#define TXIN_CONV_CFG HOST_IF_REG(0x14)
#define RXIN_HD_ACCUM_ADD HOST_IF_REG(0xC8) /* UMT Message trigger */
#define TXIN_HD_ACCUM_ADD HOST_IF_REG(0xCC) /* UMT Message trigger */
#define RXOUT_ACA_ACCUM_ADD HOST_IF_REG(0xE0) /* PPE FW tigger */
#define TXOUT_ACA_ACCUM_ADD HOST_IF_REG(0xE4) /* PPE FW tigger */
#define CDMA_BASE 0x2D0000
#define CDMA_REG(X) (CDMA_BASE + (X))
#define DMA_CLC CDMA_REG(0x00)
#define DMA_ID CDMA_REG(0x08)
#define DMA_CTRL CDMA_REG(0x10)
#define DMA_CTRL_RST BIT(0)
#define DMA_CTRL_DSRAM_PATH BIT(1)
#define DMA_CTRL_CH_FL BIT(6)
#define DMA_CTRL_DS_FOD BIT(7)
#define DMA_CTRL_DRB BIT(8)
#define DMA_CTRL_ENBE BIT(9)
#define DMA_CTRL_PRELOAD_INT_S 10
#define DMA_CTRL_PRELOAD_INT 0x0C00u
#define DMA_CTRL_PRELOAD_EN BIT(12)
#define DMA_CTRL_MBRST_CNT_S 16
#define DMA_CTRL_MBRST_CNT 0x3FF0000u
#define DMA_CTRL_MBRSTARB BIT(30)
#define DMA_CTRL_PKTARB BIT(31)
#define DMA_CPOLL CDMA_REG(0x14)
#define DMA_CPOLL_CNT_S 4
#define DMA_CPOLL_CNT 0xFFF0u
#define DMA_CPOLL_EN BIT(31)
#define DMA_CS CDMA_REG(0x18)
#define DMA_CCTRL CDMA_REG(0x1C)
#define DMA_CCTRL_ON BIT(0)
#define DMA_CCTRL_RST BIT(1)
#define DMA_CCTRL_DIR_TX BIT(8)
#define DMA_CCTRL_CLASS_S 9
#define DMA_CCTRL_CLASS 0xE00u
#define DMA_CCTRL_PRTNR_S 12
#define DMA_CCTRL_PRTNR 0xF000u
#define DMA_CCTRL_TXWGT_S 16
#define DMA_CCTRL_TXWGT 0x30000u
#define DMA_CCTRL_CLASSH_S 18
#define DMA_CCTRL_CLASSH 0xC0000u
#define DMA_CCTRL_PDEN BIT(23)
#define DMA_CCTRL_P2PCPY BIT(24)
#define DMA_CCTRL_LBEN BIT(25)
#define DMA_CCTRL_LBCHNR_S 26
#define DMA_CCTRL_LBCHNR 0xFC000000u
#define DMA_CDBA CDMA_REG(0x20)
#define DMA_CDLEN CDMA_REG(0x24)
#define DMA_CIS CDMA_REG(0x28)
#define DMA_CIE CDMA_REG(0x2C)
#define DMA_CI_EOP BIT(1)
#define DMA_CI_DUR BIT(2)
#define DMA_CI_DESCPT BIT(3)
#define DMA_CI_CHOFF BIT(4)
#define DMA_CI_RDERR BIT(5)
#define DMA_CI_ALL (DMA_CI_EOP | DMA_CI_DUR | DMA_CI_DESCPT\
| DMA_CI_CHOFF | DMA_CI_RDERR)
#define DMA_CI_DEFAULT (DMA_CI_EOP | DMA_CI_DESCPT)
#define DMA_CDPTNRD CDMA_REG(0x34)
#define DMA_PS CDMA_REG(0x40)
#define DMA_PCTRL CDMA_REG(0x44)
#define DMA_PCTRL_RXBL16 BIT(0)
#define DMA_PCTRL_TXBL16 BIT(1)
#define DMA_PCTRL_RXBL_S 2
#define DMA_PCTRL_RXBL 0xCu
#define DMA_PCTRL_TXBL_S 4
#define DMA_PCTRL_TXBL 0x30u
#define DMA_PCTRL_PDEN BIT(6)
#define DMA_PCTRL_PDEN_S 6
#define DMA_PCTRL_RXENDI_S 8
#define DMA_PCTRL_RXENDI 0x300u
#define DMA_PCTRL_TXENDI_S 10
#define DMA_PCTRL_TXENDI 0xC00u
#define DMA_PCTRL_TXWGT_S 12
#define DMA_PCTRL_TXWGT 0x7000u
#define DMA_PCTRL_MEM_FLUSH BIT(16)
#define DMA_IRNEN CDMA_REG(0xF4)
#define DMA_IRNCR CDMA_REG(0xF8)
#define DMA_IRNICR CDMA_REG(0xFC)
#ifdef CONFIG_CPU_BIG_ENDIAN
struct aca_dma_desc {
/* DW0 */
u32 dw0;
/* DW1 */
u32 dw1;
/* DW2 */
u32 data_pointer;
/* DW3 */
u32 own:1;
u32 c:1;
u32 sop:1;
u32 eop:1;
u32 dic:1;
u32 pdu_type:1;
u32 byte_off:3;
u32 qid:4;
u32 mpoa_pt:1;
u32 mpoa_mode:2;
u32 data_len:16;
}__packed __aligned(16);
/* 2 DWs format descriptor */
struct aca_dma_desc_2dw {
u32 data_pointer; /* Descriptor data pointer */
union {
struct {
u32 own:1;
u32 c:1;
u32 sop:1;
u32 eop:1;
u32 meta_data0:2;
u32 byte_offset:3;
u32 meta_data1:7;
u32 data_len:16;
} __packed field;
u32 word;
} __packed status;
} __packed __aligned(8);
#else
struct aca_dma_desc {
/* DW0 */
u32 dw0;
/* DW1 */
u32 dw1;
/* DW2 */
u32 data_pointer;
/* DW 3 */
u32 data_len:16;
u32 mpoa_mode:2;
u32 mpoa_pt:1;
u32 qid:4;
u32 byte_off:3;
u32 pdu_type:1;
u32 dic:1;
u32 eop:1;
u32 sop:1;
u32 c:1;
u32 own:1;
}__packed __aligned(16);
/* 2 DWs format descriptor */
struct aca_dma_desc_2dw {
u32 data_pointer; /* Descriptor data pointer */
union {
struct {
u32 data_len:16;
u32 meta_data1:7;
u32 byte_offset:3;
u32 meta_data0:2;
u32 eop:1;
u32 sop:1;
u32 c:1;
u32 own:1;
} __packed field;
u32 word;
} __packed status;
} __packed __aligned(8);
#endif
#endif /* EP_TEST_H */

View File

@ -0,0 +1,74 @@
#
# Copyright (C) 2019 OpenWrt.org
#
# This is free software, licensed under the GNU General Public License v2.
# See /LICENSE for more information.
#
include $(TOPDIR)/rules.mk
include $(INCLUDE_DIR)/kernel.mk
PKG_NAME:=vrx518_tc
PKG_VERSION:=1.5.12.4
PKG_RELEASE:=$(AUTORELEASE)
PKG_BASE_NAME:=vrx518_tc_drv
UGW_VERSION=8.5.2.10
UGW_BASENAME=$(PKG_BASE_NAME)-ugw_$(UGW_VERSION)
PKG_SOURCE:=$(UGW_BASENAME).tar.bz2
PKG_SOURCE_URL:=https://gitlab.com/prpl-foundation/intel/$(PKG_BASE_NAME)/-/archive/ugw_$(UGW_VERSION)/
PKG_HASH:=0c5bb0f9a06dc4cc4bbb8b930d01a673daba1b66615e8328818356d32c8f1548
PKG_BUILD_DIR:=$(KERNEL_BUILD_DIR)/$(UGW_BASENAME)
PKG_LICENSE:=GPL-2.0
PKG_LICENSE_FILES:=LICENSE
include $(INCLUDE_DIR)/package.mk
PLAT_DIR:=dcdp
PKG_EXTMOD_SUBDIRS:=$(PLAT_DIR)
# TODO this driver depends on the vrx518 ppe firmware, add this dependency if
# that ever gets a compatible license
define KernelPackage/$(PKG_NAME)
SECTION:=sys
CATEGORY:=Kernel modules
SUBMENU:=Network Devices
TITLE:=VRX518 TC driver
KCONFIG:= \
CONFIG_ATM_LANE=m \
CONFIG_ATM_MPOA=m \
CONFIG_ATM_MPOA_INTEL_DSL_PHY_SUPPORT=y
DEPENDS:=@TARGET_ipq40xx +kmod-vrx518_ep +kmod-crypto-md5 +kmod-atm +kmod-ipoa +br2684ctl
AUTOLOAD:=$(call AutoLoad,27,vrx518_tc)
FILES:=$(PKG_BUILD_DIR)/$(PLAT_DIR)/$(PKG_NAME).ko
endef
define KernelPackage/$(PKG_NAME)/description
VRX518 TC Driver
endef
define Build/Prepare
$(PKG_UNPACK)
# eliminate all carriage returns / convert to unix encoding
(cd $(PKG_BUILD_DIR) && find . -type f -exec sed -i 's/\r//g' {} +)
$(Build/Patch)
endef
define Build/InstallDev
$(INSTALL_DIR) $(1)/usr/include/net/
$(CP) $(PKG_BUILD_DIR)/$(PLAT_DIR)/inc/dsl_tc.h $(1)/usr/include/net/
endef
EXTRA_CFLAGS:= \
-I$(STAGING_DIR)/usr/include
define Build/Compile
$(KERNEL_MAKE) \
M="$(PKG_BUILD_DIR)/$(PLAT_DIR)" \
EXTRA_CFLAGS="$(EXTRA_CFLAGS)" \
FEATURE_VRX518_CPU=y \
modules
endef
$(eval $(call KernelPackage,$(PKG_NAME)))

View File

@ -0,0 +1,859 @@
--- a/dcdp/atm_tc.c
+++ b/dcdp/atm_tc.c
@@ -44,9 +44,9 @@
#include <linux/atmioc.h>
#include <linux/skbuff.h>
#include "inc/dsl_tc.h"
-#include <net/datapath_proc_api.h>
+// #include <net/datapath_proc_api.h>
#include <linux/atm.h>
-#include <net/datapath_api.h>
+// #include <net/datapath_api.h>
#include <net/dc_ep.h>
#include<linux/sched.h>
#include<linux/kthread.h>
@@ -730,20 +730,16 @@ static void atm_aca_init(struct atm_priv
ACA_TXOUT_EN | ACA_RXIN_EN | ACA_RXOUT_EN, 1);
}
-static int print_datetime(char *buffer, const struct timespec *datetime)
+static int print_datetime(char *buffer, const struct timespec64 *datetime)
{
- struct timeval tv;
struct tm nowtm;
char tmbuf[64];
- s64 nsec;
if (buffer == NULL || datetime == NULL) {
pr_err("%s : Invalid arguments\n", __func__);
return -1;
}
- nsec = timespec_to_ns(datetime);
- tv = ns_to_timeval(nsec);
- time_to_tm(tv.tv_sec, 0, &nowtm);
+ time64_to_tm(datetime->tv_sec, 0, &nowtm);
memset(tmbuf, 0, 64);
snprintf(tmbuf, sizeof(tmbuf), "%ld-%d-%d %d:%d:%d",
@@ -753,7 +749,7 @@ static int print_datetime(char *buffer,
nowtm.tm_hour,
nowtm.tm_min,
nowtm.tm_sec);
- snprintf(buffer, sizeof(buffer), "%s.%06d", tmbuf, (int)tv.tv_usec);
+ snprintf(buffer, sizeof(buffer), "%s.%06d", tmbuf, (int)datetime->tv_nsec / 1000);
return 0;
}
@@ -1313,7 +1309,7 @@ static int ppe_send(struct atm_vcc *vcc,
/* assume LLC header + Ethernet ID: 6+2 */
if ((priv->conn[conn].mpoa_type == MPOA_TYPE_EOA_WO_FCS) ||
(priv->conn[conn].mpoa_type == MPOA_TYPE_EOA_W_FCS)) {
- if (__skb_put_padto(skb, ETH_ZLEN + 8))
+ if (__skb_put_padto(skb, ETH_ZLEN + 8, false))
goto CHECK_SHOWTIME_FAIL;
}
@@ -1418,7 +1414,7 @@ int ppe_send_oam(struct atm_vcc *vcc, vo
struct atm_priv *priv = g_atm_tc;
struct sk_buff *skb;
unsigned int conn;
- dp_subif_t dp_id;
+// dp_subif_t dp_id;
#ifdef OAM_FIX_GRX750
unsigned char *dest_cell;
#endif
@@ -1465,8 +1461,8 @@ int ppe_send_oam(struct atm_vcc *vcc, vo
priv->tc_priv->param.oam_prio = 0;
qid = priv->conn[conn].prio_queue_map[priv->tc_priv->param.oam_prio];
vid = priv->conn[conn].subif_id;
- dp_id.subif = (vid & (~0x7f)) |
- ATM_DESC_SUBIF_ID(qid, mpoa_pt, mpoa_type);
+// dp_id.subif = (vid & (~0x7f)) |
+// ATM_DESC_SUBIF_ID(qid, mpoa_pt, mpoa_type);
#ifdef OAM_FIX_GRX750
dest_cell = kmalloc(CELL_SIZE, GFP_KERNEL);
if (dest_cell == NULL) {
@@ -1494,18 +1490,18 @@ int ppe_send_oam(struct atm_vcc *vcc, vo
#else
memcpy(skb->data, cell, CELL_SIZE);
#endif
- /* SET SUBIFID */
- skb->DW0 = (skb->DW0 & ~0x7FFF) | dp_id.subif;
- skb->dev = priv->conn[conn].dev;
- tc_dbg(priv->tc_priv, MSG_TX, "conn: %d, dev name: %s, qid: 0x%x len:%d\n",
- conn, skb->dev->name, dp_id.subif, skb->len);
- #ifdef OAM_FIX_GRX750
- if (priv->tc_priv->tc_ops.send(NULL,
- skb, dp_id.subif, ATM_OAM_PKT) == 0) {
- #else
+// /* SET SUBIFID */
+// skb->DW0 = (skb->DW0 & ~0x7FFF) | dp_id.subif;
+// skb->dev = priv->conn[conn].dev;
+// tc_dbg(priv->tc_priv, MSG_TX, "conn: %d, dev name: %s, qid: 0x%x len:%d\n",
+// conn, skb->dev->name, dp_id.subif, skb->len);
+// #ifdef OAM_FIX_GRX750
+// if (priv->tc_priv->tc_ops.send(NULL,
+// skb, dp_id.subif, ATM_OAM_PKT) == 0) {
+// #else
if (priv->tc_priv->tc_ops.send(NULL,
skb, qid, ATM_OAM_PKT) == 0) {
- #endif
+// #endif
priv->stats.oam_tx_pkts++;
priv->stats.oam_tx_bytes += skb->len;
priv->conn[conn].stats.oam_tx_pkts++;
@@ -1604,7 +1600,7 @@ static void oam_push(struct atm_priv *pr
conn = -1; /* invalid */
if (conn_valid(conn) && priv->conn[conn].vcc != NULL) {
vcc = priv->conn[conn].vcc;
- priv->conn[conn].access_time = current_kernel_time();
+ ktime_get_coarse_ts64(&priv->conn[conn].access_time);
tc_dbg(priv->tc_priv, MSG_OAM_RX, "conn=%d, vpi: %d, vci:%d\n",
conn, header->vpi, header->vci);
@@ -2547,30 +2543,29 @@ static void ppe_atm_fw_hw_init(struct at
static int atm_dev_init(struct atm_priv *atm_priv, int ep_id)
{
int i, err;
- struct atm_dev *dev;
- dev = atm_dev_register(g_atm_dev_name,
- atm_priv->tc_priv->ep_dev[ep_id].dev,
- &g_ppe_atm_ops, -1, NULL);
- if (!dev) {
- err = -EIO;
- goto ATM_DEV_REGISTER_FAIL;
- }
- dev->ci_range.vpi_bits = 8;
- dev->ci_range.vci_bits = 16;
- /* assume 3200 cell rate
- * before get real information
- */
- dev->link_rate =
- DEFAULT_CELL_RATE;
- dev->dev_data = atm_priv;
- dev->phy_data =
- (void *)(unsigned long)0;
for (i = 0; i < ATM_PORT_NUMBER; i++) {
if (atm_priv->port[i].dev)
continue;
atm_priv->port[i].tx_max_cell_rate = DEFAULT_CELL_RATE;
- atm_priv->port[i].dev = dev;
+ atm_priv->port[i].dev = atm_dev_register(g_atm_dev_name,
+ atm_priv->tc_priv->ep_dev[ep_id].dev,
+ &g_ppe_atm_ops, -1, NULL);
+ if (!atm_priv->port[i].dev) {
+ err = -EIO;
+ goto ATM_DEV_REGISTER_FAIL;
+ } else {
+ atm_priv->port[i].dev->ci_range.vpi_bits = 8;
+ atm_priv->port[i].dev->ci_range.vci_bits = 16;
+ /* assume 3200 cell rate
+ * before get real information
+ */
+ atm_priv->port[i].dev->link_rate =
+ DEFAULT_CELL_RATE;
+ atm_priv->port[i].dev->dev_data = atm_priv;
+ atm_priv->port[i].dev->phy_data =
+ (void *)(unsigned long)i;
+ }
}
//TODO : check for SoC PMAC, current fix
#ifdef CONFIG_SOC_TYPE_XWAY
@@ -2985,7 +2980,8 @@ static unsigned int atm_get_pvc_id(struc
return -EINVAL;
}
- return (skb->DW0 >> 3) & 0xF;
+// return (skb->DW0 >> 3) & 0xF;
+ return 1;
}
static int atm_get_qid_by_vcc(struct net_device *dev, struct sk_buff *skb,
@@ -3292,7 +3288,7 @@ static void atm_push(struct net_device *
+= skb->len;
} else
priv->stats.aal5_rx_errors++;
- priv->conn[conn].access_time = current_kernel_time();
+ ktime_get_coarse_ts64(&priv->conn[conn].access_time);
spin_unlock_bh(&priv->atm_lock);
vcc->push(vcc, skb);
--- a/dcdp/inc/atm_tc.h
+++ b/dcdp/inc/atm_tc.h
@@ -449,7 +449,7 @@ struct atm_port {
struct atm_pvc {
struct atm_vcc *vcc; /* opened VCC */
struct net_device *dev; /* net device associated with atm VCC */
- struct timespec access_time; /* time when last user cell arrived */
+ struct timespec64 access_time; /* time when last user cell arrived */
int prio_queue_map[ATM_PRIO_Q_NUM];
unsigned int prio_tx_packets[ATM_PRIO_Q_NUM];
struct atm_stats stats;
--- a/dcdp/inc/tc_api.h
+++ b/dcdp/inc/tc_api.h
@@ -196,19 +196,6 @@ static inline void aca_ring_addr_init(st
ring->aca_cnt_phyaddr = ep_dev->phy_membase + addr;
}
-static inline int __skb_put_padto(struct sk_buff *skb, unsigned int len)
-{
- unsigned int size = skb->len;
-
- if (unlikely(size < len)) {
- len -= size;
- if (skb_pad(skb, len))
- return -ENOMEM;
- __skb_put(skb, len);
- }
- return 0;
-}
-
extern int showtime_stat(struct tc_priv *);
extern void dump_skb_info(struct tc_priv *, struct sk_buff *, u32);
extern void *tc_buf_alloc(void *, size_t, u32 *,
--- a/dcdp/inc/tc_proc.h
+++ b/dcdp/inc/tc_proc.h
@@ -23,6 +23,8 @@
#ifndef __TC_PROC_H__
#define __TC_PROC_H__
+#include <linux/version.h>
+
#define TC_PROC_DIR "driver/vrx518"
#define TC_PROC_ATM_DIR "atm"
#define TC_PROC_PTM_DIR "ptm"
@@ -41,7 +43,7 @@ enum {
struct tc_proc_list {
char proc_name[32];
umode_t mode;
- const struct file_operations *fops;
+ const struct proc_ops *fops;
int is_folder;
};
--- a/dcdp/ptm_tc.c
+++ b/dcdp/ptm_tc.c
@@ -39,7 +39,7 @@
#include <linux/seq_file.h>
#include <linux/printk.h>
#include <linux/etherdevice.h>
-#include <net/datapath_proc_api.h>
+// #include <net/datapath_proc_api.h>
#include "inc/tc_main.h"
#include "inc/reg_addr.h"
@@ -182,8 +182,8 @@ static int ptm_get_qid(struct net_device
return qid;
}
-static struct rtnl_link_stats64 *ptm_get_stats(struct net_device *dev,
- struct rtnl_link_stats64 *storage)
+static void ptm_get_stats(struct net_device *dev,
+ struct rtnl_link_stats64 *storage)
{
struct ptm_priv *ptm_tc = netdev_priv(dev);
@@ -191,8 +191,6 @@ static struct rtnl_link_stats64 *ptm_get
memcpy(storage, &ptm_tc->stats64, sizeof(ptm_tc->stats64));
else
storage->tx_errors += ptm_tc->stats64.tx_errors;
-
- return storage;
}
static int ptm_set_mac_address(struct net_device *dev, void *p)
@@ -209,7 +207,7 @@ static int ptm_set_mac_address(struct ne
return 0;
}
-static void ptm_tx_timeout(struct net_device *dev)
+static void ptm_tx_timeout(struct net_device *dev, unsigned int txqueue)
{
struct ptm_priv *ptm_tc = netdev_priv(dev);
@@ -503,7 +501,7 @@ static int ptm_xmit(struct sk_buff *skb,
if (!showtime_stat(ptm_tc->tc_priv))
goto PTM_XMIT_DROP;
- if (__skb_put_padto(skb, ETH_ZLEN))
+ if (__skb_put_padto(skb, ETH_ZLEN, false))
goto PTM_XMIT_DROP;
dump_skb_info(ptm_tc->tc_priv, skb, (MSG_TX | MSG_TXDATA));
@@ -632,11 +630,8 @@ static int ptm_dev_init(struct tc_priv *
struct ptm_priv *ptm_tc;
const char macaddr[ETH_ALEN]
= {0xAC, 0x9A, 0x96, 0x11, 0x22, 0x33};
-#if LINUX_VERSION_CODE < KERNEL_VERSION(4,8,0)
- dev = alloc_netdev_mq(sizeof(*ptm_tc), "ptm%d", ptm_setup, 4);
-#else
- dev = alloc_netdev_mq(sizeof(*ptm_tc), "ptm%d", NET_NAME_ENUM, ptm_setup, 4);
-#endif
+
+ dev = alloc_netdev_mq(sizeof(*ptm_tc), "dsl%d", NET_NAME_ENUM, ptm_setup, 4);
if (!dev) {
tc_dbg(tc_priv, MSG_INIT, "Cannot alloc net device\n");
return -ENOMEM;
@@ -2103,7 +2098,6 @@ static int ptm_showtime_exit(const unsig
struct ptm_ep_priv *priv = tc_ep_priv(idx);
u32 stop = ACA_TXIN_EN;
struct dc_ep_dev *ep;
- int i = 0;
tc_info(priv->tc_priv, MSG_EVENT, "Line[%d]: show time exit!\n", idx);
ep = priv->ep;
--- a/dcdp/tc_api.c
+++ b/dcdp/tc_api.c
@@ -52,18 +52,24 @@ static const char ppe_fw_name[] = "ppe_f
#define VRX518_PPE_FW_ID 0xB
#define MD5_LEN 16
+enum tc_multicast_groups {
+ TC_MCGRP,
+};
+
+/* TC message multicast group */
+static const struct genl_multicast_group tc_ml_grps[] = {
+ [TC_MCGRP] = { .name = TC_MCAST_GRP_NAME, },
+};
+
/* TC message genelink family */
static struct genl_family tc_gnl_family = {
- .id = GENL_ID_GENERATE, /* To generate an id for the family*/
+// .id = GENL_ID_GENERATE, /* To generate an id for the family*/
.hdrsize = 0,
.name = TC_FAMILY_NAME, /*family name, used by userspace application*/
.version = 1, /*version number */
.maxattr = TC_A_MAX - 1,
-};
-
-/* TC message multicast group */
-static struct genl_multicast_group tc_ml_grp = {
- .name = TC_MCAST_GRP_NAME,
+ .mcgrps = tc_ml_grps,
+ .n_mcgrps = ARRAY_SIZE(tc_ml_grps),
};
/**
@@ -568,7 +574,8 @@ int tc_ntlk_msg_send(struct tc_priv *pri
nla_put_u32(skb, TC_A_LINENO, ln_no);
genlmsg_end(skb, msg_head);
- ret = genlmsg_multicast(skb, pid, tc_ml_grp.id, GFP_KERNEL);
+ ret = genlmsg_multicast(&tc_gnl_family, skb, pid, TC_MCGRP,
+ GFP_KERNEL);
if (ret) {
tc_err(priv, MSG_EVENT, "Sent TC multicast message Fail!\n");
goto err1;
@@ -590,21 +597,11 @@ int tc_gentlk_init(struct tc_priv *priv)
return ret;
}
- ret = genl_register_mc_group(&tc_gnl_family, &tc_ml_grp);
- if (ret) {
- tc_err(priv, MSG_EVENT, "register mc group fail: %i, grp name: %s\n",
- ret, tc_ml_grp.name);
- genl_unregister_family(&tc_gnl_family);
- return ret;
- }
-
return 0;
}
void tc_gentlk_exit(void)
{
- /* unregister mc groups */
- genl_unregister_mc_group(&tc_gnl_family, &tc_ml_grp);
/*unregister the family*/
genl_unregister_family(&tc_gnl_family);
}
@@ -666,7 +663,7 @@ void dump_skb_info(struct tc_priv *tcpri
(u32)skb->end, skb->len);
tc_dbg(tcpriv, type,
"skb: clone: %d, users: %d\n",
- skb->cloned, atomic_read(&skb->users));
+ skb->cloned, refcount_read(&skb->users));
tc_dbg(tcpriv, type,
"skb: nfrag: %d\n", skb_shinfo(skb)->nr_frags);
@@ -936,7 +933,6 @@ static int fw_md5_check(struct tc_priv *
}
desc->tfm = md5;
- desc->flags = 0;
ret = crypto_shash_init(desc);
if (ret) {
--- a/dcdp/tc_proc.c
+++ b/dcdp/tc_proc.c
@@ -22,7 +22,9 @@
*******************************************************************************/
#include <linux/fs.h>
#include <linux/seq_file.h>
-#include <net/datapath_api.h>
+// #include <net/datapath_api.h>
+#include <linux/etherdevice.h>
+#include <linux/atmdev.h>
#include <net/genetlink.h>
#include <linux/time.h>
#include "inc/tc_main.h"
@@ -353,7 +355,7 @@ static ssize_t mem_proc_write(struct fil
}
addr = set_val = repeat_cnt = 0;
- if (!access_ok(VERIFY_READ, buf, count))
+ if (!access_ok(buf, count))
return -EFAULT;
len = count < sizeof(str) ? count : sizeof(str) - 1;
@@ -450,13 +452,12 @@ static int proc_read_mem_seq_open(struct
return single_open(file, proc_read_mem, NULL);
}
-static const struct file_operations mem_proc_fops = {
- .owner = THIS_MODULE,
- .open = proc_read_mem_seq_open,
- .read = seq_read,
- .llseek = seq_lseek,
- .release = single_release,
- .write = mem_proc_write,
+static const struct proc_ops mem_proc_fops = {
+ .proc_open = proc_read_mem_seq_open,
+ .proc_read = seq_read,
+ .proc_lseek = seq_lseek,
+ .proc_release = single_release,
+ .proc_write = mem_proc_write,
};
static ssize_t pp32_proc_write(struct file *file, const char __user *buf,
@@ -748,13 +749,12 @@ static int proc_read_pp32_seq_open(struc
return single_open(file, proc_read_pp32, PDE_DATA(inode));
}
-static const struct file_operations pp32_proc_fops = {
- .owner = THIS_MODULE,
- .open = proc_read_pp32_seq_open,
- .read = seq_read,
- .llseek = seq_lseek,
- .release = single_release,
- .write = pp32_proc_write,
+static const struct proc_ops pp32_proc_fops = {
+ .proc_open = proc_read_pp32_seq_open,
+ .proc_read = seq_read,
+ .proc_lseek = seq_lseek,
+ .proc_release = single_release,
+ .proc_write = pp32_proc_write,
};
static int proc_read_tc_cfg(struct seq_file *seq, void *v)
@@ -865,13 +865,12 @@ static int proc_read_tc_cfg_seq_open(str
return single_open(file, proc_read_tc_cfg, PDE_DATA(inode));
}
-static const struct file_operations tc_cfg_proc_fops = {
- .owner = THIS_MODULE,
- .open = proc_read_tc_cfg_seq_open,
- .read = seq_read,
- .llseek = seq_lseek,
- .release = single_release,
- .write = proc_write_cfg,
+static const struct proc_ops tc_cfg_proc_fops = {
+ .proc_open = proc_read_tc_cfg_seq_open,
+ .proc_read = seq_read,
+ .proc_lseek = seq_lseek,
+ .proc_release = single_release,
+ .proc_write = proc_write_cfg,
};
static ssize_t proc_write_dbg(struct file *file, const char __user *buf,
@@ -951,13 +950,12 @@ static int proc_read_dbg_seq_open(struct
return single_open(file, proc_read_dbg, PDE_DATA(inode));
}
-static const struct file_operations tc_dbg_proc_fops = {
- .owner = THIS_MODULE,
- .open = proc_read_dbg_seq_open,
- .read = seq_read,
- .write = proc_write_dbg,
- .llseek = seq_lseek,
- .release = single_release,
+static const struct proc_ops tc_dbg_proc_fops = {
+ .proc_open = proc_read_dbg_seq_open,
+ .proc_read = seq_read,
+ .proc_write = proc_write_dbg,
+ .proc_lseek = seq_lseek,
+ .proc_release = single_release,
};
static ssize_t proc_write_tc_switch(struct file *file, const char __user *buf,
@@ -1018,11 +1016,11 @@ proc_tc_switch_help:
return count;
}
-static const struct file_operations tc_switch_proc_fops = {
- .owner = THIS_MODULE,
- .write = proc_write_tc_switch,
- .llseek = noop_llseek,
+static const struct proc_ops tc_switch_proc_fops = {
+ .proc_write = proc_write_tc_switch,
+ .proc_lseek = noop_llseek,
};
+
static ssize_t proc_write_show_time(struct file *file, const char __user *buf,
size_t count, loff_t *data)
{
@@ -1077,10 +1075,9 @@ proc_show_time_help:
return count;
}
-static const struct file_operations tc_show_time_proc_fops = {
- .owner = THIS_MODULE,
- .write = proc_write_show_time,
- .llseek = noop_llseek,
+static const struct proc_ops tc_show_time_proc_fops = {
+ .proc_write = proc_write_show_time,
+ .proc_lseek = noop_llseek,
};
static int proc_read_ver(struct seq_file *seq, void *v)
@@ -1128,12 +1125,11 @@ static int proc_read_ver_seq_open(struct
return single_open(file, proc_read_ver, PDE_DATA(inode));
}
-static const struct file_operations tc_ver_proc_fops = {
- .owner = THIS_MODULE,
- .open = proc_read_ver_seq_open,
- .read = seq_read,
- .llseek = seq_lseek,
- .release = single_release,
+static const struct proc_ops tc_ver_proc_fops = {
+ .proc_open = proc_read_ver_seq_open,
+ .proc_read = seq_read,
+ .proc_lseek = seq_lseek,
+ .proc_release = single_release,
};
static int proc_read_soc(struct seq_file *seq, void *v)
@@ -1142,20 +1138,18 @@ static int proc_read_soc(struct seq_file
tcpriv = (struct tc_priv *)seq->private;
-#if 0
seq_printf(seq, "TXIN Base: 0x%08x, TXIN num: %d\n",
- tcpriv->cfg.txin_dbase,
- tcpriv->cfg.txin_dnum);
+ tcpriv->cfg.txin.soc_phydbase,
+ tcpriv->cfg.txin.soc_dnum);
seq_printf(seq, "TXOUT Base: 0x%08x, TXOUT num: %d\n",
- tcpriv->cfg.txout_dbase,
- tcpriv->cfg.txout_dnum);
+ tcpriv->cfg.txout.soc_phydbase,
+ tcpriv->cfg.txout.soc_dnum);
seq_printf(seq, "RXIN Base: 0x%08x, RXIN num: %d\n",
- tcpriv->cfg.rxin_dbase,
- tcpriv->cfg.rxin_dnum);
+ tcpriv->cfg.rxin.soc_phydbase,
+ tcpriv->cfg.rxin.soc_dnum);
seq_printf(seq, "RXOUT Base: 0x%08x, RXOUT num: %d\n",
- tcpriv->cfg.rxout_dbase,
- tcpriv->cfg.rxout_dnum);
-#endif
+ tcpriv->cfg.rxout.soc_phydbase,
+ tcpriv->cfg.rxout.soc_dnum);
return 0;
}
@@ -1165,15 +1159,13 @@ static int proc_read_soc_seq_open(struct
return single_open(file, proc_read_soc, PDE_DATA(inode));
}
-static const struct file_operations tc_soc_proc_fops = {
- .owner = THIS_MODULE,
- .open = proc_read_soc_seq_open,
- .read = seq_read,
- .llseek = seq_lseek,
- .release = single_release,
+static const struct proc_ops tc_soc_proc_fops = {
+ .proc_open = proc_read_soc_seq_open,
+ .proc_read = seq_read,
+ .proc_lseek = seq_lseek,
+ .proc_release = single_release,
};
-
static struct tc_proc_list tc_procs[] = {
{TC_PROC_DIR, 0, NULL, 1},
{"cfg", 0644, &tc_cfg_proc_fops, 0},
@@ -1241,13 +1233,12 @@ static int proc_read_ptm_wanmib_seq_open
return single_open(file, proc_read_ptm_wanmib, PDE_DATA(inode));
}
-static const struct file_operations ptm_wanmib_proc_fops = {
- .owner = THIS_MODULE,
- .open = proc_read_ptm_wanmib_seq_open,
- .read = seq_read,
- .write = proc_write_ptm_wanmib,
- .llseek = seq_lseek,
- .release = single_release,
+static const struct proc_ops ptm_wanmib_proc_fops = {
+ .proc_open = proc_read_ptm_wanmib_seq_open,
+ .proc_read = seq_read,
+ .proc_write = proc_write_ptm_wanmib,
+ .proc_lseek = seq_lseek,
+ .proc_release = single_release,
};
static int proc_ptm_read_cfg(struct seq_file *seq, void *v)
@@ -1300,7 +1291,7 @@ static ssize_t ptm_cfg_proc_write(struct
return -EINVAL;
}
- if (!access_ok(VERIFY_READ, buf, count))
+ if (!access_ok(buf, count))
return -EFAULT;
len = count < sizeof(str) ? count : sizeof(str) - 1;
@@ -1343,13 +1334,12 @@ proc_ptm_cfg_help:
}
-static const struct file_operations ptm_cfg_proc_fops = {
- .owner = THIS_MODULE,
- .open = proc_read_cfg_seq_open,
- .read = seq_read,
- .llseek = seq_lseek,
- .write = ptm_cfg_proc_write,
- .release = single_release,
+static const struct proc_ops ptm_cfg_proc_fops = {
+ .proc_open = proc_read_cfg_seq_open,
+ .proc_read = seq_read,
+ .proc_lseek = seq_lseek,
+ .proc_write = ptm_cfg_proc_write,
+ .proc_release = single_release,
};
static ssize_t proc_ptm_write_prio(struct file *file, const char __user *buf,
@@ -1455,13 +1445,12 @@ static int proc_ptm_read_prio_seq_open(s
return single_open(file, proc_ptm_read_prio, PDE_DATA(inode));
}
-static const struct file_operations ptm_prio_proc_fops = {
- .owner = THIS_MODULE,
- .open = proc_ptm_read_prio_seq_open,
- .read = seq_read,
- .llseek = seq_lseek,
- .write = proc_ptm_write_prio,
- .release = single_release,
+static const struct proc_ops ptm_prio_proc_fops = {
+ .proc_open = proc_ptm_read_prio_seq_open,
+ .proc_read = seq_read,
+ .proc_lseek = seq_lseek,
+ .proc_write = proc_ptm_write_prio,
+ .proc_release = single_release,
};
static int proc_ptm_read_bond_seq_open(struct inode *inode, struct file *file)
@@ -1469,12 +1458,11 @@ static int proc_ptm_read_bond_seq_open(s
return single_open(file, proc_ptm_read_bond, PDE_DATA(inode));
}
-static const struct file_operations ptm_bond_proc_fops = {
- .owner = THIS_MODULE,
- .open = proc_ptm_read_bond_seq_open,
- .read = seq_read,
- .llseek = seq_lseek,
- .release = single_release,
+static const struct proc_ops ptm_bond_proc_fops = {
+ .proc_open = proc_ptm_read_bond_seq_open,
+ .proc_read = seq_read,
+ .proc_lseek = seq_lseek,
+ .proc_release = single_release,
};
static int proc_ptm_read_bondmib_seq_open(struct inode *inode,
@@ -1483,13 +1471,12 @@ static int proc_ptm_read_bondmib_seq_ope
return single_open(file, proc_ptm_read_bondmib, PDE_DATA(inode));
}
-static const struct file_operations ptm_bondmib_proc_fops = {
- .owner = THIS_MODULE,
- .open = proc_ptm_read_bondmib_seq_open,
- .read = seq_read,
- .llseek = seq_lseek,
- .write = proc_ptm_write_bondmib,
- .release = single_release,
+static const struct proc_ops ptm_bondmib_proc_fops = {
+ .proc_open = proc_ptm_read_bondmib_seq_open,
+ .proc_read = seq_read,
+ .proc_lseek = seq_lseek,
+ .proc_write = proc_ptm_write_bondmib,
+ .proc_release = single_release,
};
struct fwdbg_t {
@@ -1910,14 +1897,14 @@ static int proc_read_fwdbg_seq_open(stru
{
return single_open(file, proc_read_fwdbg, NULL);
}
-static const struct file_operations fwdbg_proc_fops = {
- .owner = THIS_MODULE,
- .open = proc_read_fwdbg_seq_open,
- .read = seq_read,
- .write = proc_write_fwdbg_seq,
- .llseek = seq_lseek,
- .release = single_release,
+static const struct proc_ops fwdbg_proc_fops = {
+ .proc_open = proc_read_fwdbg_seq_open,
+ .proc_read = seq_read,
+ .proc_write = proc_write_fwdbg_seq,
+ .proc_lseek = seq_lseek,
+ .proc_release = single_release,
};
+
static struct tc_proc_list ptm_sl_procs[] = {
{TC_PROC_PTM_DIR, 0, NULL, 1},
{"mem", 0644, &mem_proc_fops, 0},
@@ -2077,7 +2064,7 @@ static ssize_t atm_cfg_proc_write(struct
priv = (struct atm_priv *)PDE_DATA(file_inode(file));
- if (!access_ok(VERIFY_READ, buf, count))
+ if (!access_ok(buf, count))
return -EFAULT;
len = count < sizeof(str) ? count : sizeof(str) - 1;
@@ -2119,13 +2106,12 @@ proc_atm_cfg_help:
return count;
}
-static const struct file_operations atm_cfg_proc_fops = {
- .owner = THIS_MODULE,
- .open = proc_read_atm_cfg_seq_open,
- .read = seq_read,
- .write = atm_cfg_proc_write,
- .llseek = seq_lseek,
- .release = single_release,
+static const struct proc_ops atm_cfg_proc_fops = {
+ .proc_open = proc_read_atm_cfg_seq_open,
+ .proc_read = seq_read,
+ .proc_write = atm_cfg_proc_write,
+ .proc_lseek = seq_lseek,
+ .proc_release = single_release,
};
static ssize_t proc_write_atm_wanmib(struct file *file, const char __user *buf,
@@ -2173,13 +2159,12 @@ static int proc_read_atm_wanmib_seq_open
-static const struct file_operations atm_wanmib_proc_fops = {
- .owner = THIS_MODULE,
- .open = proc_read_atm_wanmib_seq_open,
- .read = seq_read,
- .write = proc_write_atm_wanmib,
- .llseek = seq_lseek,
- .release = single_release,
+static const struct proc_ops atm_wanmib_proc_fops = {
+ .proc_open = proc_read_atm_wanmib_seq_open,
+ .proc_read = seq_read,
+ .proc_write = proc_write_atm_wanmib,
+ .proc_lseek = seq_lseek,
+ .proc_release = single_release,
};
static int proc_read_htu_seq_open(struct inode *inode, struct file *file)
@@ -2187,12 +2172,11 @@ static int proc_read_htu_seq_open(struct
return single_open(file, proc_read_htu, PDE_DATA(inode));
}
-static const struct file_operations htu_proc_fops = {
- .owner = THIS_MODULE,
- .open = proc_read_htu_seq_open,
- .read = seq_read,
- .llseek = seq_lseek,
- .release = single_release,
+static const struct proc_ops htu_proc_fops = {
+ .proc_open = proc_read_htu_seq_open,
+ .proc_read = seq_read,
+ .proc_lseek = seq_lseek,
+ .proc_release = single_release,
};
static int proc_read_queue_seq_open(struct inode *inode, struct file *file)
@@ -2200,12 +2184,11 @@ static int proc_read_queue_seq_open(stru
return single_open(file, proc_read_queue, PDE_DATA(inode));
}
-static const struct file_operations queue_proc_fops = {
- .owner = THIS_MODULE,
- .open = proc_read_queue_seq_open,
- .read = seq_read,
- .llseek = seq_lseek,
- .release = single_release,
+static const struct proc_ops queue_proc_fops = {
+ .proc_open = proc_read_queue_seq_open,
+ .proc_read = seq_read,
+ .proc_lseek = seq_lseek,
+ .proc_release = single_release,
};
static void set_q_prio(struct atm_priv *priv,
@@ -2428,13 +2411,12 @@ static const struct seq_operations pvc_m
.show = pvc_mib_seq_show,
};
-static const struct file_operations atm_prio_proc_fops = {
- .owner = THIS_MODULE,
- .open = proc_atm_read_prio_seq_open,
- .read = seq_read,
- .llseek = seq_lseek,
- .write = proc_atm_write_prio,
- .release = single_release,
+static const struct proc_ops atm_prio_proc_fops = {
+ .proc_open = proc_atm_read_prio_seq_open,
+ .proc_read = seq_read,
+ .proc_lseek = seq_lseek,
+ .proc_write = proc_atm_write_prio,
+ .proc_release = single_release,
};
static int proc_read_pvc_mib_seq_open(struct inode *inode, struct file *file)
@@ -2447,12 +2429,11 @@ static int proc_read_pvc_mib_seq_open(st
return ret;
}
-static const struct file_operations atm_pvc_mib_proc_fops = {
- .owner = THIS_MODULE,
- .open = proc_read_pvc_mib_seq_open,
- .read = seq_read,
- .llseek = seq_lseek,
- .release = seq_release,
+static const struct proc_ops atm_pvc_mib_proc_fops = {
+ .proc_open = proc_read_pvc_mib_seq_open,
+ .proc_read = seq_read,
+ .proc_lseek = seq_lseek,
+ .proc_release = seq_release,
};
static ssize_t proc_write_cell(struct file *file,
@@ -2592,13 +2573,12 @@ static int proc_read_cell_seq_open(struc
return single_open(file, proc_read_cell, NULL);
}
-static const struct file_operations atm_cell_proc_fops = {
- .owner = THIS_MODULE,
- .open = proc_read_cell_seq_open,
- .read = seq_read,
- .write = proc_write_cell,
- .llseek = seq_lseek,
- .release = single_release,
+static const struct proc_ops atm_cell_proc_fops = {
+ .proc_open = proc_read_cell_seq_open,
+ .proc_read = seq_read,
+ .proc_write = proc_write_cell,
+ .proc_lseek = seq_lseek,
+ .proc_release = single_release,
};
static struct tc_proc_list atm_procs[] = {

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,342 @@
Port FEATURE_CONF_DESC_LENGTH from the grx500 variant of the driver.
This also reduces the default length of some descriptors, resulting in
significantly lower latencies when the line is saturated.
--- a/dcdp/inc/tc_common.h
+++ b/dcdp/inc/tc_common.h
@@ -27,7 +27,11 @@
#define UMT_DEF_PERIOD 400 /* microseconds */
#define MAX_MTU (DMA_PACKET_SZ - ETH_HLEN - HD_RSRV_SZ)
+#ifdef FEATURE_CONF_DESC_LENGTH
+#define QOSQ_NUM 8
+#else
#define QOSQ_NUM 2
+#endif
#define FW_STOP_TIMEOUT 20 /* millisecond */
#define QOS_DISPATCH_OWN 0
#define ACA_TXIN_POLL_INTVAL 10 /* millisecond */
--- a/dcdp/inc/tc_main.h
+++ b/dcdp/inc/tc_main.h
@@ -30,6 +30,7 @@
#define TCPRIV_ALIGN 32
#define DMA_PACKET_SZ 2048
+#define FEATURE_CONF_DESC_LENGTH 1
#define FEATURE_POWER_DOWN 1
enum {
@@ -157,6 +158,25 @@ struct tc_param {
unsigned int txout_dnum;
unsigned int rxin_dnum;
unsigned int rxout_dnum;
+
+#ifdef FEATURE_CONF_DESC_LENGTH
+ /* __US_FAST_PATH_DES_LIST_NUM:64
+ * __ACA_TX_IN_PD_LIST_NUM
+ * __ACA_TX_OUT_PD_LIST_NUM
+ * */
+ u32 conf_us_fp_desq_len;
+ /*
+ * Number of queue per QoS queue: QOS_DES_NUM / QOSQ_NUM
+ * */
+ u32 conf_us_qos_queue_len;
+ /* __US_OUTQ0_DES_LIST_NUM: 32
+ * __US_OUTQ1_DES_LIST_NUM: 32
+ * OUTQ_DESC_PER_Q
+ * */
+ u32 conf_us_outq_len;
+ /**/
+ u32 conf_us_local_q0_desq_len;
+#endif
};
struct cdma {
--- a/dcdp/ptm_tc.c
+++ b/dcdp/ptm_tc.c
@@ -75,7 +75,11 @@ static const u32 tx_kvec[] = {
0x30B1B233, 0xB43536B7, 0xB8393ABB, 0x3CBDBE3F,
0xC04142C3, 0x44C5C647, 0x48C9CA4B, 0xCC4D4ECF
};
+#ifndef FEATURE_CONF_DESC_LENGTH
static const u32 def_outq_map[OUTQ_PNUM] = {0x1, 0xFE};
+#else
+static const u32 def_outq_map[OUTQ_PNUM] = {0x0, 0xFF};
+#endif
static const char ptm_drv_name[] = "PTM SL";
static const char ptm_bond_name[][IFNAMSIZ] = {"PTM US BOND", "PTM DS BOND"};
@@ -1005,6 +1009,10 @@ static void us_fp_desq_cfg_ctxt_init(str
int i;
u32 desc_addr;
rx_descriptor_t desc;
+#ifdef FEATURE_CONF_DESC_LENGTH
+ struct tc_priv *tc_priv;
+ tc_priv = priv->tc_priv;
+#endif
memset(&desq_cfg, 0, sizeof(desq_cfg));
/* Initialize US Fast-Path Descriptor Queue Config/Context */
@@ -1012,7 +1020,11 @@ static void us_fp_desq_cfg_ctxt_init(str
desq_cfg.fast_path = 1;
desq_cfg.mbox_int_en = 0;
desq_cfg.des_sync_needed = 0;
+#ifndef FEATURE_CONF_DESC_LENGTH
desq_cfg.des_num = __US_FAST_PATH_DES_LIST_NUM;
+#else
+ desq_cfg.des_num = tc_priv->param.conf_us_fp_desq_len;
+#endif
desq_cfg.des_base_addr = __US_FAST_PATH_DES_LIST_BASE;
tc_mem_write(priv, fpi_addr(__US_FP_INQ_DES_CFG_CTXT),
@@ -1036,12 +1048,20 @@ static void us_qos_desq_cfg_ctxt_init(st
int offset, i;
rx_descriptor_t desc;
u32 phy_addr;
+#ifdef FEATURE_CONF_DESC_LENGTH
+ struct tc_priv *tc_priv;
+ tc_priv = priv->tc_priv;
+#endif
/* Setup QoSQ_CFG_CTXT */
memset(&qosq_cfg_ctxt, 0, sizeof(qosq_cfg_ctxt));
qosq_cfg_ctxt.threshold = 8;
+#ifdef FEATURE_CONF_DESC_LENGTH
+ qosq_cfg_ctxt.des_num = tc_priv->param.conf_us_qos_queue_len;
+#else
qosq_cfg_ctxt.des_num = QOS_DES_NUM / QOSQ_NUM;
+#endif
offset = 0;
for (i = 0; i < QOSQ_NUM; i++) {
@@ -1080,6 +1100,10 @@ static void us_outq_desq_cfg_ctxt_init(s
u32 phy_addr;
int i;
u32 offset;
+#ifdef FEATURE_CONF_DESC_LENGTH
+ struct tc_priv *tc_priv;
+ tc_priv = priv->tc_priv;
+#endif
/* Setup OUTQ_QoS_CFG_CTXT */
/* NOTE: By default, Shaping & WFQ both are DISABLED!! */
@@ -1108,7 +1132,11 @@ static void us_outq_desq_cfg_ctxt_init(s
desq_cfg.des_in_own_val = US_OUTQ_DES_OWN;
desq_cfg.mbox_int_en = 0;
desq_cfg.des_sync_needed = 0;
- desq_cfg.des_num = 32;
+#ifndef FEATURE_CONF_DESC_LENGTH
+ desq_cfg.des_num = OUTQ_DESC_PER_Q;
+#else
+ desq_cfg.des_num = tc_priv->param.conf_us_outq_len;
+#endif
/**
* Only BC0 is used in VRX518
*/
@@ -1174,7 +1202,11 @@ static void us_qos_cfg_init(struct ptm_e
/* Set QoS NO DROP */
sb_w32(1, __QOSQ_NO_DROP);
/* Enable Preemption function/Disable QoS by default */
+#ifdef FEATURE_CONF_DESC_LENGTH
+ sb_w32(0, _CHK_PREEMP_MAP);
+#else
sb_w32(1, _CHK_PREEMP_MAP);
+#endif
/* By default, all qid mappint to non-preemption queue */
sb_w32(0x0, _QID2PREEMP_MAP);
@@ -1376,6 +1408,11 @@ static void ptm_local_desq_cfg_ctxt_init
u32 dcnt, addr, pdbram_base;
unsigned int us_des_alloc[] = {
__US_TC_LOCAL_Q0_DES_LIST_NUM, __US_TC_LOCAL_Q1_DES_LIST_NUM};
+#ifdef FEATURE_CONF_DESC_LENGTH
+ struct tc_priv *tc_priv;
+ tc_priv = priv->tc_priv;
+ us_des_alloc[0] = tc_priv->param.conf_us_local_q0_desq_len;
+#endif
/* Setup the Local DESQ Configuration/Context for UpStream Queues */
memset(&desq_cfg, 0, sizeof(desq_cfg));
@@ -2321,6 +2358,10 @@ static void ptm_aca_init(struct ptm_ep_p
u32 phybase = priv->ep->phy_membase;
u32 start;
u32 type;
+#ifdef FEATURE_CONF_DESC_LENGTH
+ struct tc_priv *tc_priv;
+ tc_priv = priv->tc_priv;
+#endif
priv->tc_priv->tc_ops.soc_cfg_get(&priv->tc_priv->cfg, ptm_id(priv));
memset(&param, 0, sizeof(param));
@@ -2334,7 +2375,11 @@ static void ptm_aca_init(struct ptm_ep_p
#endif
txin->hd_size_in_dw = cfg->txin.soc_desc_dwsz;
txin->pd_desc_base = SB_XBAR_ADDR(__ACA_TX_IN_PD_LIST_BASE);
+#ifndef FEATURE_CONF_DESC_LENGTH
txin->pd_desc_num = __ACA_TX_IN_PD_LIST_NUM;
+#else
+ txin->pd_desc_num = tc_priv->param.conf_us_fp_desq_len;
+#endif
txin->pd_size_in_dw = DESC_DWSZ;
txin->soc_desc_base = cfg->txin.soc_phydbase;
txin->soc_desc_num = cfg->txin.soc_dnum;
--- a/dcdp/tc_main.c
+++ b/dcdp/tc_main.c
@@ -182,6 +182,12 @@ static inline void init_local_param(stru
priv->param.txout_dnum = txout_num;
priv->param.rxin_dnum = rxin_num;
priv->param.rxout_dnum = rxout_num;
+#ifdef FEATURE_CONF_DESC_LENGTH
+ priv->param.conf_us_fp_desq_len = 32;
+ priv->param.conf_us_qos_queue_len = 32;
+ priv->param.conf_us_outq_len = 32;
+ priv->param.conf_us_local_q0_desq_len = 16;
+#endif
priv->tc_mode = TC_NONE_MODE;
priv->tc_stat = NO_TC;
--- a/dcdp/tc_proc.c
+++ b/dcdp/tc_proc.c
@@ -1114,6 +1114,9 @@ static int proc_read_ver(struct seq_file
(date >> 16) & 0xff,
(date & 0xffff));
+#ifdef FEATURE_CONF_DESC_LENGTH
+ seq_puts(seq, " + Support QoS and Configurable descriptor length\n");
+#endif
#ifdef FEATURE_POWER_DOWN
seq_puts(seq, " + Support Power Down enhancement feature\n");
#endif
@@ -1166,6 +1169,113 @@ static const struct proc_ops tc_soc_proc
.proc_release = single_release,
};
+#ifdef FEATURE_CONF_DESC_LENGTH
+static ssize_t proc_write_desc_conf(struct file *file, const char __user *buf,
+ size_t count, loff_t *data)
+{
+ struct tc_priv *priv;
+ char str[32];
+ int len, rlen, temp;
+ int num, temp_num;
+ char *param_list[20];
+ len = count < sizeof(str) ? count : sizeof(str) - 1;
+ rlen = len - copy_from_user(str, buf, len);
+ str[rlen] = 0;
+
+ if (!capable(CAP_SYS_ADMIN))
+ return -EPERM;
+
+ priv = (struct tc_priv *)PDE_DATA(file_inode(file));
+ if (priv == NULL)
+ return count;
+
+ num = vrx_split_buffer(str, param_list, ARRAY_SIZE(param_list));
+ if (num < 1 || num > 4)
+ goto proc_dbg_desc_conf;
+
+ temp_num = num;
+ if (num-- != 0) {
+ temp = vrx_atoi(param_list[0]);
+ if (temp < 1 || temp > 128) {
+ pr_info("Fastpath valid range: 1 -> 128\n");
+ goto proc_dbg_desc_conf;
+ }
+ }
+ if (num-- != 0) {
+ temp = vrx_atoi(param_list[1]);
+ if (temp < 1 || temp > 63) {
+ pr_info("QoS valid range: 1 -> 63\n");
+ goto proc_dbg_desc_conf;
+ }
+ }
+ if (num-- != 0) {
+ temp = vrx_atoi(param_list[2]);
+ if (temp < 1 || temp > 128) {
+ pr_info("OutQ valid range: 1 -> 128\n");
+ goto proc_dbg_desc_conf;
+ }
+ }
+ if (num-- != 0) {
+ temp = vrx_atoi(param_list[3]);
+ if (temp < 4 || temp > 16) {
+ pr_info("Local Q0 valid range: 4 -> 16\n");
+ goto proc_dbg_desc_conf;
+ }
+ }
+ num = temp_num;
+ if (num-- != 0) {
+ priv->param.conf_us_fp_desq_len = vrx_atoi(param_list[0]);
+ }
+ if (num-- != 0) {
+ priv->param.conf_us_qos_queue_len = vrx_atoi(param_list[1]);
+ }
+ if (num-- != 0) {
+ priv->param.conf_us_outq_len = vrx_atoi(param_list[2]);
+ }
+ if (num-- != 0) {
+ priv->param.conf_us_local_q0_desq_len = vrx_atoi(param_list[3]);
+ }
+
+ return count;
+
+proc_dbg_desc_conf:
+ pr_info("echo [FP] [QoS] [OutQ] [LocalQ0]> desc_conf\n");
+ return count;
+}
+
+static int proc_read_desc_conf(struct seq_file *seq, void *v)
+{
+ struct tc_priv *priv;
+ priv = (struct tc_priv *)seq->private;
+ if (priv == NULL)
+ return -1;
+ seq_puts(seq, "Upstream descriptor length information:\n");
+ seq_printf(seq, " - Fastpath: %d\n",
+ priv->param.conf_us_fp_desq_len);
+ seq_printf(seq, " - QoS: %d\n",
+ priv->param.conf_us_qos_queue_len);
+ seq_printf(seq, " - OutQ: %d\n",
+ priv->param.conf_us_outq_len);
+ seq_printf(seq, " - Local Q0: %d\n",
+ priv->param.conf_us_local_q0_desq_len);
+ seq_puts(seq, "\n");
+ return 0;
+}
+
+static int proc_read_desc_conf_seq_open(struct inode *inode, struct file *file)
+{
+ return single_open(file, proc_read_desc_conf, PDE_DATA(inode));
+}
+#endif
+
+static const struct proc_ops tc_desc_conf_proc_fops = {
+ .proc_open = proc_read_desc_conf_seq_open,
+ .proc_read = seq_read,
+ .proc_write = proc_write_desc_conf,
+ .proc_lseek = seq_lseek,
+ .proc_release = single_release,
+};
+
static struct tc_proc_list tc_procs[] = {
{TC_PROC_DIR, 0, NULL, 1},
{"cfg", 0644, &tc_cfg_proc_fops, 0},
@@ -1174,6 +1284,9 @@ static struct tc_proc_list tc_procs[] =
{"showtime", 0200, &tc_show_time_proc_fops, 0},
{"ver", 0644, &tc_ver_proc_fops, 0},
{"soc", 0644, &tc_soc_proc_fops, 0},
+#ifdef FEATURE_CONF_DESC_LENGTH
+ {"desc_conf", 0644, &tc_desc_conf_proc_fops, 0},
+#endif
};
int tc_proc_init(struct tc_priv *priv)
@@ -1333,7 +1446,6 @@ proc_ptm_cfg_help:
return count;
}
-
static const struct proc_ops ptm_cfg_proc_fops = {
.proc_open = proc_read_cfg_seq_open,
.proc_read = seq_read,

View File

@ -0,0 +1,423 @@
--- a/dcdp/platform/sw_plat.c
+++ b/dcdp/platform/sw_plat.c
@@ -208,6 +208,8 @@ struct plat_priv {
struct tc_req req_work;
struct aca_ring_grp soc_rings;
struct net_device *netdev;
+ struct napi_struct *napi_tx;
+ struct napi_struct *napi_rx;
DECLARE_HASHTABLE(mem_map, 8);
};
@@ -472,7 +474,7 @@ err2:
return -1;
}
-static void txout_action(struct tc_priv *priv, struct aca_ring *txout)
+static int txout_action(struct tc_priv *priv, struct aca_ring *txout, int budget)
{
struct aca_ring *txin = &g_plat_priv->soc_rings.txin;
struct tx_list *txlist = &g_plat_priv->soc_rings.txlist;
@@ -490,7 +492,10 @@ static void txout_action(struct tc_priv
spin_lock_irqsave(&tx_spinlock, flags);
}
- for (i = 0; i < txout->dnum; i++) {
+ if (budget == 0 || budget > txout->dnum)
+ budget = txout->dnum;
+
+ for (i = 0; i < budget; i++) {
desc = txout->dbase_mem;
desc += txout->idx;
@@ -540,6 +545,8 @@ static void txout_action(struct tc_priv
if (cnt && g_plat_priv->netdev && netif_queue_stopped(g_plat_priv->netdev)) {
netif_wake_queue(g_plat_priv->netdev);
}
+
+ return cnt;
}
static void rxin_action(struct tc_priv *priv,
@@ -549,7 +556,7 @@ static void rxin_action(struct tc_priv *
writel(cnt, rxin->umt_dst);
}
-static int rxout_action(struct tc_priv *priv, struct aca_ring *rxout)
+static int rxout_action(struct tc_priv *priv, struct aca_ring *rxout, int budget)
{
struct device *pdev = priv->ep_dev[0].dev;
int i, cnt;
@@ -559,8 +566,11 @@ static int rxout_action(struct tc_priv *
size_t len;
struct sk_buff *skb;
+ if (budget == 0 || budget > rxout->dnum)
+ budget = rxout->dnum;
+
cnt = 0;
- for (i = 0; i < rxout->dnum; i++) {
+ for (i = 0; i < budget; i++) {
desc = rxout->dbase_mem;
desc += rxout->idx;
@@ -593,14 +603,30 @@ static int rxout_action(struct tc_priv *
ring_idx_inc(rxout);
}
- if (!cnt)
- tc_err(priv, MSG_RX, "RXOUT spurious interrupt\n");
- else
+ if (cnt)
writel(cnt, rxout->umt_dst+0x28); // RXOUT_HD_ACCUM_SUB instead of RXOUT_HD_ACCUM_ADD
return cnt;
}
+static int plat_txout_napi(struct napi_struct *napi, int budget)
+{
+ struct plat_priv *priv = g_plat_priv;
+ struct tc_priv *tcpriv = plat_to_tcpriv();
+ struct aca_ring *txout = &priv->soc_rings.txout;
+ struct dc_ep_dev *ep_dev = &tcpriv->ep_dev[txout->ep_dev_idx];
+ int cnt;
+
+ cnt = txout_action(tcpriv, txout, budget);
+
+ if (cnt < budget) {
+ if (napi_complete_done(napi, cnt))
+ ep_dev->hw_ops->icu_en(ep_dev, ACA_HOSTIF_TX);
+ }
+
+ return cnt;
+}
+
static void plat_txout_tasklet(unsigned long arg)
{
struct plat_priv *priv = g_plat_priv;
@@ -608,12 +634,33 @@ static void plat_txout_tasklet(unsigned
struct aca_ring *txout = &priv->soc_rings.txout;
struct dc_ep_dev *ep_dev = &tcpriv->ep_dev[txout->ep_dev_idx];
- txout_action(tcpriv, txout);
+ txout_action(tcpriv, txout, 0);
/* Enable interrupt */
ep_dev->hw_ops->icu_en(ep_dev, ACA_HOSTIF_TX);
}
+static int plat_rxout_napi(struct napi_struct *napi, int budget)
+{
+ struct plat_priv *priv = g_plat_priv;
+ struct tc_priv *tcpriv = plat_to_tcpriv();
+ struct aca_ring *rxout = &priv->soc_rings.rxout;
+ struct aca_ring *rxin = &priv->soc_rings.rxin;
+ struct dc_ep_dev *ep_dev = &tcpriv->ep_dev[rxout->ep_dev_idx];
+ int cnt;
+
+ cnt = rxout_action(tcpriv, rxout, budget);
+ if (cnt)
+ rxin_action(tcpriv, rxin, DMA_PACKET_SZ, cnt);
+
+ if (cnt < budget) {
+ if (napi_complete_done(napi, cnt))
+ ep_dev->hw_ops->icu_en(ep_dev, ACA_HOSTIF_RX);
+ }
+
+ return cnt;
+}
+
static void plat_rxout_tasklet(unsigned long arg)
{
struct plat_priv *priv = g_plat_priv;
@@ -623,7 +670,7 @@ static void plat_rxout_tasklet(unsigned
struct dc_ep_dev *ep_dev = &tcpriv->ep_dev[rxout->ep_dev_idx];
int cnt;
- cnt = rxout_action(tcpriv, rxout);
+ cnt = rxout_action(tcpriv, rxout, 0);
if (cnt)
rxin_action(tcpriv, rxin, DMA_PACKET_SZ, cnt);
@@ -783,11 +830,22 @@ static irqreturn_t aca_rx_irq_handler(in
{
struct dc_ep_dev *ep_dev = dev_id;
- /* Disable IRQ in IMCU */
- ep_dev->hw_ops->icu_mask(ep_dev, ACA_HOSTIF_RX);
+ if (g_plat_priv->napi_rx) {
+
+ if (napi_schedule_prep(g_plat_priv->napi_rx)) {
+ ep_dev->hw_ops->icu_mask(ep_dev, ACA_HOSTIF_RX);
+ __napi_schedule(g_plat_priv->napi_rx);
+ }
+
+ } else {
+
+ /* Disable IRQ in IMCU */
+ ep_dev->hw_ops->icu_mask(ep_dev, ACA_HOSTIF_RX);
- /* Start tasklet */
- tasklet_schedule(&rxout_task);
+ /* Start tasklet */
+ tasklet_schedule(&rxout_task);
+
+ }
return IRQ_HANDLED;
}
@@ -796,15 +854,62 @@ static irqreturn_t aca_tx_irq_handler(in
{
struct dc_ep_dev *ep_dev = dev_id;
- /* Disable IRQ in IMCU */
- ep_dev->hw_ops->icu_mask(ep_dev, ACA_HOSTIF_TX);
+ if (g_plat_priv->napi_tx) {
- /* Start tasklet */
- tasklet_schedule(&txout_task);
+ if (napi_schedule_prep(g_plat_priv->napi_tx)) {
+ ep_dev->hw_ops->icu_mask(ep_dev, ACA_HOSTIF_TX);
+ __napi_schedule(g_plat_priv->napi_tx);
+ }
+
+ } else {
+
+ /* Disable IRQ in IMCU */
+ ep_dev->hw_ops->icu_mask(ep_dev, ACA_HOSTIF_TX);
+
+ /* Start tasklet */
+ tasklet_schedule(&txout_task);
+
+ }
return IRQ_HANDLED;
}
+static void plat_net_open(void)
+{
+ struct plat_priv *priv = g_plat_priv;
+ struct tc_priv *tcpriv = plat_to_tcpriv();
+ struct aca_ring *rxout = &priv->soc_rings.rxout;
+ struct aca_ring *txout = &priv->soc_rings.txout;
+ struct dc_ep_dev *ep_dev_rx = &tcpriv->ep_dev[rxout->ep_dev_idx];
+ struct dc_ep_dev *ep_dev_tx = &tcpriv->ep_dev[txout->ep_dev_idx];
+
+ if (priv->napi_rx)
+ napi_enable(priv->napi_rx);
+ ep_dev_rx->hw_ops->icu_en(ep_dev_rx, ACA_HOSTIF_RX);
+
+ if (priv->napi_tx)
+ napi_enable(priv->napi_tx);
+ ep_dev_tx->hw_ops->icu_en(ep_dev_tx, ACA_HOSTIF_TX);
+}
+
+static void plat_net_stop(void)
+{
+ struct plat_priv *priv = g_plat_priv;
+ struct tc_priv *tcpriv = plat_to_tcpriv();
+ struct aca_ring *rxout = &priv->soc_rings.rxout;
+ struct aca_ring *txout = &priv->soc_rings.txout;
+ struct dc_ep_dev *ep_dev_rx = &tcpriv->ep_dev[rxout->ep_dev_idx];
+ struct dc_ep_dev *ep_dev_tx = &tcpriv->ep_dev[txout->ep_dev_idx];
+
+ if (priv->napi_tx)
+ napi_disable(priv->napi_tx);
+ ep_dev_tx->hw_ops->icu_mask(ep_dev_tx, ACA_HOSTIF_TX);
+
+ if (priv->napi_rx)
+ napi_disable(priv->napi_rx);
+ ep_dev_rx->hw_ops->icu_mask(ep_dev_rx, ACA_HOSTIF_RX);
+}
+
static void plat_irq_init(struct tc_priv *priv, const char *dev_name)
{
int ret;
@@ -988,17 +1093,49 @@ static int plat_soc_cfg_get(struct soc_c
}
static int plat_open(struct net_device *pdev, const char *dev_name,
+ struct napi_struct *napi_tx, struct napi_struct *napi_rx,
int id, int flag)
{
+ struct tc_priv *priv = g_plat_priv->tc_priv;
+ int i;
+
+ for (i = 0; i < EP_MAX_NUM && i < priv->ep_num; i++) {
+ disable_irq(priv->ep_dev[i].aca_rx_irq);
+ disable_irq(priv->ep_dev[i].aca_tx_irq);
+ }
+
g_plat_priv->netdev = pdev;
+ g_plat_priv->napi_tx = napi_tx;
+ g_plat_priv->napi_rx = napi_rx;
+
+ for (i = 0; i < EP_MAX_NUM && i < priv->ep_num; i++) {
+ enable_irq(priv->ep_dev[i].aca_rx_irq);
+ enable_irq(priv->ep_dev[i].aca_tx_irq);
+ }
return 0;
}
static void plat_close(struct net_device *pdev, const char *dev_name,
+ struct napi_struct *napi_tx, struct napi_struct *napi_rx,
int flag)
{
+ struct tc_priv *priv = g_plat_priv->tc_priv;
+ int i;
+
+ for (i = 0; i < EP_MAX_NUM && i < priv->ep_num; i++) {
+ disable_irq(priv->ep_dev[i].aca_rx_irq);
+ disable_irq(priv->ep_dev[i].aca_tx_irq);
+ }
+
g_plat_priv->netdev = NULL;
+ g_plat_priv->napi_tx = NULL;
+ g_plat_priv->napi_rx = NULL;
+
+ for (i = 0; i < EP_MAX_NUM && i < priv->ep_num; i++) {
+ enable_irq(priv->ep_dev[i].aca_rx_irq);
+ enable_irq(priv->ep_dev[i].aca_tx_irq);
+ }
return;
}
@@ -1084,6 +1221,10 @@ static void plat_tc_ops_setup(struct tc_
priv->tc_ops.free = plat_mem_free;
priv->tc_ops.dev_reg = plat_open;
priv->tc_ops.dev_unreg = plat_close;
+ priv->tc_ops.net_open = plat_net_open;
+ priv->tc_ops.net_stop = plat_net_stop;
+ priv->tc_ops.napi_tx = plat_txout_napi;
+ priv->tc_ops.napi_rx = plat_rxout_napi;
priv->tc_ops.umt_init = plat_umt_init;
priv->tc_ops.umt_exit = plat_umt_exit;
priv->tc_ops.umt_start = plat_umt_start;
--- a/dcdp/atm_tc.c
+++ b/dcdp/atm_tc.c
@@ -3650,7 +3650,7 @@ static void atm_aca_ring_config_init(str
static int atm_ring_init(struct atm_priv *priv)
{
atm_aca_ring_config_init(priv);
- return priv->tc_priv->tc_ops.dev_reg(NULL, g_atm_dev_name, 0, 0);
+ return priv->tc_priv->tc_ops.dev_reg(NULL, g_atm_dev_name, NULL, NULL, 0, 0);
}
static int atm_init(struct tc_priv *tcpriv, u32 ep_id)
@@ -4020,7 +4020,7 @@ void atm_tc_unload(void)
/* unregister device */
if (priv->tc_priv->tc_ops.dev_unreg != NULL)
priv->tc_priv->tc_ops.dev_unreg(NULL,
- g_atm_dev_name, 0);
+ g_atm_dev_name, NULL, NULL, 0);
/* atm_dev_deinit(priv); */
/* modem module power off */
--- a/dcdp/inc/tc_main.h
+++ b/dcdp/inc/tc_main.h
@@ -209,9 +209,15 @@ struct tc_hw_ops {
void (*subif_unreg)(struct net_device *pdev, const char *dev_name,
int subif_id, int flag);
int (*dev_reg)(struct net_device *pdev, const char *dev_name,
+ struct napi_struct *napi_tx, struct napi_struct *napi_rx,
int id, int flag);
void (*dev_unreg)(struct net_device *pdev, const char *dev_name,
+ struct napi_struct *napi_tx, struct napi_struct *napi_rx,
int flag);
+ void (*net_open)(void);
+ void (*net_stop)(void);
+ int (*napi_tx)(struct napi_struct *napi, int budget);
+ int (*napi_rx)(struct napi_struct *napi, int budget);
/*umt init/exit including the corresponding DMA init/exit */
int (*umt_init)(u32 umt_id, u32 umt_period, u32 umt_dst);
--- a/dcdp/ptm_tc.c
+++ b/dcdp/ptm_tc.c
@@ -141,7 +141,11 @@ static int ptm_open(struct net_device *d
struct ptm_priv *ptm_tc = netdev_priv(dev);
tc_info(ptm_tc->tc_priv, MSG_EVENT, "ptm open\n");
+
+ ptm_tc->tc_priv->tc_ops.net_open();
+
netif_tx_start_all_queues(dev);
+
#ifdef CONFIG_SOC_TYPE_XWAY
xet_phy_wan_port(7, NULL, 1, 1);
if (ppa_hook_ppa_phys_port_add_fn)
@@ -158,7 +162,11 @@ static int ptm_stop(struct net_device *d
struct ptm_priv *ptm_tc = netdev_priv(dev);
tc_info(ptm_tc->tc_priv, MSG_EVENT, "ptm stop\n");
+
netif_tx_stop_all_queues(dev);
+
+ ptm_tc->tc_priv->tc_ops.net_stop();
+
#ifdef CONFIG_SOC_TYPE_XWAY
if (ppa_drv_datapath_mac_entry_setting)
ppa_drv_datapath_mac_entry_setting(dev->dev_addr, 0, 6, 10, 1, 2);
@@ -555,7 +563,7 @@ static void ptm_rx(struct net_device *de
ptm_tc->stats64.rx_packets++;
ptm_tc->stats64.rx_bytes += skb->len;
- if (netif_rx(skb) == NET_RX_DROP)
+ if (netif_receive_skb(skb) == NET_RX_DROP)
ptm_tc->stats64.rx_dropped++;
return;
@@ -651,6 +659,9 @@ static int ptm_dev_init(struct tc_priv *
memcpy(ptm_tc->outq_map, def_outq_map, sizeof(def_outq_map));
SET_NETDEV_DEV(ptm_tc->dev, tc_priv->ep_dev[id].dev);
+ netif_napi_add(ptm_tc->dev, &ptm_tc->napi_rx, tc_priv->tc_ops.napi_rx, NAPI_POLL_WEIGHT);
+ netif_tx_napi_add(ptm_tc->dev, &ptm_tc->napi_tx, tc_priv->tc_ops.napi_tx, NAPI_POLL_WEIGHT);
+
err = register_netdev(ptm_tc->dev);
if (err)
goto err1;
@@ -2605,7 +2616,9 @@ static int ptm_ring_init(struct ptm_ep_p
{
ptm_aca_ring_config_init(priv, id, bonding);
return priv->tc_priv->tc_ops.dev_reg(priv->ptm_tc->dev,
- priv->ptm_tc->dev->name, id, bonding);
+ priv->ptm_tc->dev->name,
+ &priv->ptm_tc->napi_tx, &priv->ptm_tc->napi_rx,
+ id, bonding);
}
/**
@@ -2960,7 +2973,9 @@ void ptm_tc_unload(enum dsl_tc_mode tc_m
/* unregister device */
if (ptm_tc->tc_priv->tc_ops.dev_unreg != NULL)
ptm_tc->tc_priv->tc_ops.dev_unreg(ptm_tc->dev,
- ptm_tc->dev->name, 0);
+ ptm_tc->dev->name,
+ &priv->ptm_tc->napi_tx, &priv->ptm_tc->napi_rx,
+ 0);
/* remove PTM callback function */
ptm_cb_setup(ptm_tc, 0);
@@ -2978,6 +2993,10 @@ void ptm_exit(void)
if (!priv)
return;
+
+ netif_napi_del(&priv->napi_tx);
+ netif_napi_del(&priv->napi_rx);
+
unregister_netdev(priv->dev);
free_netdev(priv->dev);
--- a/dcdp/inc/ptm_tc.h
+++ b/dcdp/inc/ptm_tc.h
@@ -119,6 +119,8 @@ struct ptm_priv {
u32 ep_id;
struct ppe_fw fw;
struct net_device *dev;
+ struct napi_struct napi_tx;
+ struct napi_struct napi_rx;
spinlock_t ptm_lock;
struct rtnl_link_stats64 stats64;
int subif_id;

View File

@ -0,0 +1,120 @@
--- a/dcdp/platform/sw_plat.c
+++ b/dcdp/platform/sw_plat.c
@@ -85,6 +85,7 @@ struct aca_ring {
u32 dnum;
u32 dsize;
int idx; /* SoC RX/TX index */
+ u64 cnt;
int ep_dev_idx;
};
@@ -210,6 +211,8 @@ struct plat_priv {
struct net_device *netdev;
struct napi_struct *napi_tx;
struct napi_struct *napi_rx;
+ u64 napi_tx_stats[NAPI_POLL_WEIGHT+1];
+ u64 napi_rx_stats[NAPI_POLL_WEIGHT+1];
DECLARE_HASHTABLE(mem_map, 8);
};
@@ -362,6 +365,7 @@ static void txlist_free(struct tx_list *
static inline void ring_idx_inc(struct aca_ring *ring)
{
ring->idx = (ring->idx + 1) % ring->dnum;
+ ring->cnt += 1;
}
static struct sk_buff *txin_skb_prepare(struct sk_buff *skb)
@@ -619,6 +623,8 @@ static int plat_txout_napi(struct napi_s
cnt = txout_action(tcpriv, txout, budget);
+ priv->napi_tx_stats[cnt] += 1;
+
if (cnt < budget) {
if (napi_complete_done(napi, cnt))
ep_dev->hw_ops->icu_en(ep_dev, ACA_HOSTIF_TX);
@@ -653,6 +659,8 @@ static int plat_rxout_napi(struct napi_s
if (cnt)
rxin_action(tcpriv, rxin, DMA_PACKET_SZ, cnt);
+ priv->napi_rx_stats[cnt] += 1;
+
if (cnt < budget) {
if (napi_complete_done(napi, cnt))
ep_dev->hw_ops->icu_en(ep_dev, ACA_HOSTIF_RX);
@@ -1092,6 +1100,56 @@ static int plat_soc_cfg_get(struct soc_c
return 0;
}
+static struct proc_dir_entry *g_proc_entry;
+
+static int proc_show(struct seq_file *m, void *p)
+{
+ struct aca_ring *txin = &g_plat_priv->soc_rings.txin;
+ struct aca_ring *txout = &g_plat_priv->soc_rings.txout;
+ struct aca_ring *rxin = &g_plat_priv->soc_rings.rxin;
+ struct aca_ring *rxout = &g_plat_priv->soc_rings.rxout;
+ int i;
+
+ seq_printf(m, "napi_tx_stats: ");
+ for (i = 0; i < sizeof(g_plat_priv->napi_tx_stats) / sizeof(g_plat_priv->napi_tx_stats[0]); i++) {
+ if (i == 0) {
+ seq_printf(m, "%llu", g_plat_priv->napi_tx_stats[i]);
+ } else {
+ seq_printf(m, ", %llu", g_plat_priv->napi_tx_stats[i]);
+ }
+ }
+ seq_printf(m, "\n");
+
+ seq_printf(m, "napi_rx_stats: ");
+ for (i = 0; i < sizeof(g_plat_priv->napi_rx_stats) / sizeof(g_plat_priv->napi_rx_stats[0]); i++) {
+ if (i == 0) {
+ seq_printf(m, "%llu", g_plat_priv->napi_rx_stats[i]);
+ } else {
+ seq_printf(m, ", %llu", g_plat_priv->napi_rx_stats[i]);
+ }
+ }
+ seq_printf(m, "\n");
+
+ seq_printf(m, "txin: %d/%u, %llu\n", txin->idx, txin->dnum, txin->cnt);
+ seq_printf(m, "txout: %d/%u, %llu\n", txout->idx, txout->dnum, txout->cnt);
+ seq_printf(m, "rxin: %d/%u, %llu\n", rxin->idx, rxin->dnum, rxin->cnt);
+ seq_printf(m, "rxout: %d/%u, %llu\n", rxout->idx, rxout->dnum, rxout->cnt);
+
+ return 0;
+}
+
+static int proc_open(struct inode *inode, struct file *file)
+{
+ return single_open(file, proc_show, NULL);
+}
+
+static struct proc_ops proc_operations = {
+ .proc_open = proc_open,
+ .proc_read = seq_read,
+ .proc_lseek = seq_lseek,
+ .proc_release = single_release
+};
+
static int plat_open(struct net_device *pdev, const char *dev_name,
struct napi_struct *napi_tx, struct napi_struct *napi_rx,
int id, int flag)
@@ -1099,6 +1157,8 @@ static int plat_open(struct net_device *
struct tc_priv *priv = g_plat_priv->tc_priv;
int i;
+ g_proc_entry = proc_create("swplat", 0600, priv->proc_dir, &proc_operations);
+
for (i = 0; i < EP_MAX_NUM && i < priv->ep_num; i++) {
disable_irq(priv->ep_dev[i].aca_rx_irq);
disable_irq(priv->ep_dev[i].aca_tx_irq);
@@ -1137,6 +1197,8 @@ static void plat_close(struct net_device
enable_irq(priv->ep_dev[i].aca_tx_irq);
}
+ proc_remove(g_proc_entry);
+
return;
}

View File

@ -494,7 +494,7 @@ $(eval $(call KernelPackage,usb-dwc3))
define KernelPackage/usb-dwc3-qcom
TITLE:=DWC3 Qualcomm USB driver
DEPENDS:=@(TARGET_ipq40xx||TARGET_ipq806x) +kmod-usb-dwc3
DEPENDS:=@(TARGET_ipq40xx||TARGET_ipq806x||TARGET_ipq807x) +kmod-usb-dwc3
KCONFIG:= CONFIG_USB_DWC3_QCOM
FILES:= $(LINUX_DIR)/drivers/usb/dwc3/dwc3-qcom.ko
AUTOLOAD:=$(call AutoLoad,53,dwc3-qcom,1)

View File

@ -11,7 +11,7 @@ include $(INCLUDE_DIR)/kernel.mk
PKG_NAME:=mac80211
PKG_VERSION:=6.1-rc8
PKG_RELEASE:=2
PKG_RELEASE:=3
# PKG_SOURCE_URL:=@KERNEL/linux/kernel/projects/backports/stable/v5.15.58/
PKG_SOURCE_URL:=http://mirror2.openwrt.org/sources/
PKG_HASH:=7f3d96c2573183cd79d6a3ebe5e1b7b73c19d1326d443c85b69c4181f14e6e2b

View File

@ -1,6 +1,6 @@
PKG_DRIVERS += \
ath ath5k ath6kl ath6kl-sdio ath6kl-usb ath9k ath9k-common ath9k-htc ath10k ath10k-smallbuffers \
ath11k ath11k-pci carl9170 owl-loader ar5523 wil6210
ath11k ath11k-ahb ath11k-pci carl9170 owl-loader ar5523 wil6210
PKG_CONFIG_DEPENDS += \
CONFIG_PACKAGE_ATH_DEBUG \
@ -61,6 +61,7 @@ config-$(call config_package,ath9k-htc) += ATH9K_HTC
config-$(call config_package,ath10k) += ATH10K ATH10K_PCI
config-$(call config_package,ath10k-smallbuffers) += ATH10K ATH10K_PCI ATH10K_SMALLBUFFERS
config-$(call config_package,ath11k) += ATH11K
config-$(call config_package,ath11k-ahb) += ATH11K_AHB
config-$(call config_package,ath11k-pci) += ATH11K_PCI
config-$(call config_package,ath5k) += ATH5K
@ -317,9 +318,24 @@ define KernelPackage/ath11k/config
config ATH11K_THERMAL
bool "Enable thermal sensors and throttling support"
depends on PACKAGE_kmod-ath11k
default y if TARGET_ipq807x
endef
define KernelPackage/ath11k-ahb
$(call KernelPackage/mac80211/Default)
TITLE:=Qualcomm 802.11ax AHB wireless chipset support
URL:=https://wireless.wiki.kernel.org/en/users/drivers/ath11k
DEPENDS+= @TARGET_ipq807x +kmod-ath11k +kmod-qrtr-smd
FILES:=$(PKG_BUILD_DIR)/drivers/net/wireless/ath/ath11k/ath11k_ahb.ko
AUTOLOAD:=$(call AutoProbe,ath11k_ahb)
endef
define KernelPackage/ath11k-ahb/description
This module adds support for Qualcomm Technologies 802.11ax family of
chipsets with AHB bus.
endef
define KernelPackage/ath11k-pci
$(call KernelPackage/mac80211/Default)
TITLE:=Qualcomm 802.11ax PCI wireless chipset support

View File

@ -0,0 +1,139 @@
From 323d91d4684d238f6bc3693fed93caf795378fe0 Mon Sep 17 00:00:00 2001
From: Kalle Valo <quic_kvalo@quicinc.com>
Date: Thu, 22 Dec 2022 19:15:59 +0200
Subject: [PATCH] wifi: ath11k: debugfs: fix to work with multiple PCI devices
ath11k fails to load if there are multiple ath11k PCI devices with same name:
ath11k_pci 0000:01:00.0: Hardware name qcn9074 hw1.0
debugfs: Directory 'ath11k' with parent '/' already present!
ath11k_pci 0000:01:00.0: failed to create ath11k debugfs
ath11k_pci 0000:01:00.0: failed to create soc core: -17
ath11k_pci 0000:01:00.0: failed to init core: -17
ath11k_pci: probe of 0000:01:00.0 failed with error -17
Fix this by creating a directory for each ath11k device using schema
<bus>-<devname>, for example "pci-0000:06:00.0". This directory created under
the top-level ath11k directory, for example /sys/kernel/debug/ath11k.
The reference to the toplevel ath11k directory is not stored anymore within ath11k, instead
it's retrieved using debugfs_lookup(). If the directory does not exist it will
be created. After the last directory from the ath11k directory is removed, for
example when doing rmmod ath11k, the empty ath11k directory is left in place,
it's a minor cosmetic issue anyway.
Here's an example hierarchy with one WCN6855:
ath11k
`-- pci-0000:06:00.0
|-- mac0
| |-- dfs_block_radar_events
| |-- dfs_simulate_radar
| |-- ext_rx_stats
| |-- ext_tx_stats
| |-- fw_dbglog_config
| |-- fw_stats
| | |-- beacon_stats
| | |-- pdev_stats
| | `-- vdev_stats
| |-- htt_stats
| |-- htt_stats_reset
| |-- htt_stats_type
| `-- pktlog_filter
|-- simulate_fw_crash
`-- soc_dp_stats
I didn't have a test setup where I could connect multiple ath11k devices to the
same the host, so I have only tested this with one device.
Tested-on: WCN6855 hw2.0 PCI WLAN.HSP.1.1-03125-QCAHSPSWPL_V1_V2_SILICONZ_LITE-3.6510.9
Tested-on: IPQ8074 hw2.0 AHB WLAN.HK.2.5.0.1-01208-QCAHKSWPL_SILICONZ-1
Tested-on: QCN9074 hw1.0 PCI WLAN.HK.2.5.0.1-01208-QCAHKSWPL_SILICONZ-1
Tested-by: Robert Marko <robert.marko@sartura.hr>
Signed-off-by: Kalle Valo <quic_kvalo@quicinc.com>
Link: https://lore.kernel.org/r/20221220121231.20120-1-kvalo@kernel.org
---
drivers/net/wireless/ath/ath11k/core.h | 1 -
drivers/net/wireless/ath/ath11k/debugfs.c | 48 +++++++++++++++++++----
2 files changed, 40 insertions(+), 9 deletions(-)
--- a/drivers/net/wireless/ath/ath11k/core.h
+++ b/drivers/net/wireless/ath/ath11k/core.h
@@ -912,7 +912,6 @@ struct ath11k_base {
enum ath11k_dfs_region dfs_region;
#ifdef CPTCFG_ATH11K_DEBUGFS
struct dentry *debugfs_soc;
- struct dentry *debugfs_ath11k;
#endif
struct ath11k_soc_dp_stats soc_stats;
--- a/drivers/net/wireless/ath/ath11k/debugfs.c
+++ b/drivers/net/wireless/ath/ath11k/debugfs.c
@@ -976,10 +976,6 @@ int ath11k_debugfs_pdev_create(struct at
if (test_bit(ATH11K_FLAG_REGISTERED, &ab->dev_flags))
return 0;
- ab->debugfs_soc = debugfs_create_dir(ab->hw_params.name, ab->debugfs_ath11k);
- if (IS_ERR(ab->debugfs_soc))
- return PTR_ERR(ab->debugfs_soc);
-
debugfs_create_file("simulate_fw_crash", 0600, ab->debugfs_soc, ab,
&fops_simulate_fw_crash);
@@ -1001,15 +997,51 @@ void ath11k_debugfs_pdev_destroy(struct
int ath11k_debugfs_soc_create(struct ath11k_base *ab)
{
- ab->debugfs_ath11k = debugfs_create_dir("ath11k", NULL);
+ struct dentry *root;
+ bool dput_needed;
+ char name[64];
+ int ret;
+
+ root = debugfs_lookup("ath11k", NULL);
+ if (!root) {
+ root = debugfs_create_dir("ath11k", NULL);
+ if (IS_ERR_OR_NULL(root))
+ return PTR_ERR(root);
+
+ dput_needed = false;
+ } else {
+ /* a dentry from lookup() needs dput() after we don't use it */
+ dput_needed = true;
+ }
+
+ scnprintf(name, sizeof(name), "%s-%s", ath11k_bus_str(ab->hif.bus),
+ dev_name(ab->dev));
+
+ ab->debugfs_soc = debugfs_create_dir(name, root);
+ if (IS_ERR_OR_NULL(ab->debugfs_soc)) {
+ ret = PTR_ERR(ab->debugfs_soc);
+ goto out;
+ }
+
+ ret = 0;
+
+out:
+ if (dput_needed)
+ dput(root);
- return PTR_ERR_OR_ZERO(ab->debugfs_ath11k);
+ return ret;
}
void ath11k_debugfs_soc_destroy(struct ath11k_base *ab)
{
- debugfs_remove_recursive(ab->debugfs_ath11k);
- ab->debugfs_ath11k = NULL;
+ debugfs_remove_recursive(ab->debugfs_soc);
+ ab->debugfs_soc = NULL;
+
+ /* We are not removing ath11k directory on purpose, even if it
+ * would be empty. This simplifies the directory handling and it's
+ * a minor cosmetic issue to leave an empty ath11k directory to
+ * debugfs.
+ */
}
EXPORT_SYMBOL(ath11k_debugfs_soc_destroy);

View File

@ -0,0 +1,162 @@
From 534a5f99d589cfa6b244b4433c192b6a278a67ff Mon Sep 17 00:00:00 2001
From: Robert Marko <robimarko@gmail.com>
Date: Sat, 5 Nov 2022 20:15:40 +0100
Subject: [PATCH] wifi: ath11k: use unique QRTR instance ID
Currently, trying to use AHB + PCI/MHI cards or multiple PCI/MHI cards
will cause a clash in the QRTR instance node ID and prevent the driver
from talking via QMI to the card and thus initializing it with:
[ 9.836329] ath11k c000000.wifi: host capability request failed: 1 90
[ 9.842047] ath11k c000000.wifi: failed to send qmi host cap: -22
So, in order to allow for this combination of cards, especially AHB + PCI
cards like IPQ8074 + QCN9074 (Used by me and tested on) set the desired
QRTR instance ID offset by calculating a unique one based on PCI domain
and bus ID-s and writing it to bits 7-0 of BHI_ERRDBG2 MHI register by
using the SBL state callback that is added as part of the series.
We also have to make sure that new QRTR offset is added on top of the
default QRTR instance ID-s that are currently used in the driver.
This finally allows using AHB + PCI or multiple PCI cards on the same
system.
Since this is not supported on QCA6390 and like, its limited to QCN9074
which is known to support changing QRTR instance ID.
Before:
root@OpenWrt:/# qrtr-lookup
Service Version Instance Node Port
1054 1 0 7 1 <unknown>
69 1 2 7 3 ATH10k WLAN firmware service
After:
root@OpenWrt:/# qrtr-lookup
Service Version Instance Node Port
1054 1 0 7 1 <unknown>
69 1 2 7 3 ATH10k WLAN firmware service
15 1 0 8 1 Test service
69 1 8 8 2 ATH10k WLAN firmware service
Tested-on: IPQ8074 hw2.0 AHB WLAN.HK.2.5.0.1-01208-QCAHKSWPL_SILICONZ-1
Tested-on: QCN9074 hw1.0 PCI WLAN.HK.2.5.0.1-01208-QCAHKSWPL_SILICONZ-1
Signed-off-by: Robert Marko <robimarko@gmail.com>
---
drivers/net/wireless/ath/ath11k/mhi.c | 49 ++++++++++++++++++---------
drivers/net/wireless/ath/ath11k/mhi.h | 3 ++
drivers/net/wireless/ath/ath11k/pci.c | 9 ++++-
3 files changed, 44 insertions(+), 17 deletions(-)
--- a/drivers/net/wireless/ath/ath11k/mhi.c
+++ b/drivers/net/wireless/ath/ath11k/mhi.c
@@ -294,6 +294,34 @@ static void ath11k_mhi_op_runtime_put(st
{
}
+static int ath11k_mhi_op_read_reg(struct mhi_controller *mhi_cntrl,
+ void __iomem *addr,
+ u32 *out)
+{
+ *out = readl(addr);
+
+ return 0;
+}
+
+static void ath11k_mhi_op_write_reg(struct mhi_controller *mhi_cntrl,
+ void __iomem *addr,
+ u32 val)
+{
+ writel(val, addr);
+}
+
+static void ath11k_mhi_qrtr_instance_set(struct mhi_controller *mhi_cntrl)
+{
+ struct ath11k_base *ab = dev_get_drvdata(mhi_cntrl->cntrl_dev);
+
+ if (ab->hw_rev == ATH11K_HW_QCN9074_HW10) {
+ ath11k_mhi_op_write_reg(mhi_cntrl,
+ mhi_cntrl->bhi + BHI_ERRDBG2,
+ FIELD_PREP(QRTR_INSTANCE_MASK,
+ ab->qmi.service_ins_id - ab->hw_params.qmi_service_ins_id));
+ }
+}
+
static char *ath11k_mhi_op_callback_to_str(enum mhi_callback reason)
{
switch (reason) {
@@ -315,6 +343,8 @@ static char *ath11k_mhi_op_callback_to_s
return "MHI_CB_FATAL_ERROR";
case MHI_CB_BW_REQ:
return "MHI_CB_BW_REQ";
+ case MHI_CB_EE_SBL_MODE:
+ return "MHI_CB_EE_SBL_MODE";
default:
return "UNKNOWN";
}
@@ -336,27 +366,14 @@ static void ath11k_mhi_op_status_cb(stru
if (!(test_bit(ATH11K_FLAG_UNREGISTERING, &ab->dev_flags)))
queue_work(ab->workqueue_aux, &ab->reset_work);
break;
+ case MHI_CB_EE_SBL_MODE:
+ ath11k_mhi_qrtr_instance_set(mhi_cntrl);
+ break;
default:
break;
}
}
-static int ath11k_mhi_op_read_reg(struct mhi_controller *mhi_cntrl,
- void __iomem *addr,
- u32 *out)
-{
- *out = readl(addr);
-
- return 0;
-}
-
-static void ath11k_mhi_op_write_reg(struct mhi_controller *mhi_cntrl,
- void __iomem *addr,
- u32 val)
-{
- writel(val, addr);
-}
-
static int ath11k_mhi_read_addr_from_dt(struct mhi_controller *mhi_ctrl)
{
struct device_node *np;
--- a/drivers/net/wireless/ath/ath11k/mhi.h
+++ b/drivers/net/wireless/ath/ath11k/mhi.h
@@ -16,6 +16,9 @@
#define MHICTRL 0x38
#define MHICTRL_RESET_MASK 0x2
+#define BHI_ERRDBG2 0x38
+#define QRTR_INSTANCE_MASK GENMASK(7, 0)
+
int ath11k_mhi_start(struct ath11k_pci *ar_pci);
void ath11k_mhi_stop(struct ath11k_pci *ar_pci);
int ath11k_mhi_register(struct ath11k_pci *ar_pci);
--- a/drivers/net/wireless/ath/ath11k/pci.c
+++ b/drivers/net/wireless/ath/ath11k/pci.c
@@ -370,13 +370,20 @@ static void ath11k_pci_sw_reset(struct a
static void ath11k_pci_init_qmi_ce_config(struct ath11k_base *ab)
{
struct ath11k_qmi_ce_cfg *cfg = &ab->qmi.ce_cfg;
+ struct ath11k_pci *ab_pci = ath11k_pci_priv(ab);
+ struct pci_bus *bus = ab_pci->pdev->bus;
cfg->tgt_ce = ab->hw_params.target_ce_config;
cfg->tgt_ce_len = ab->hw_params.target_ce_count;
cfg->svc_to_ce_map = ab->hw_params.svc_to_ce_map;
cfg->svc_to_ce_map_len = ab->hw_params.svc_to_ce_map_len;
- ab->qmi.service_ins_id = ab->hw_params.qmi_service_ins_id;
+
+ if (ab->hw_rev == ATH11K_HW_QCN9074_HW10) {
+ ab->qmi.service_ins_id = ab->hw_params.qmi_service_ins_id +
+ (((pci_domain_nr(bus) & 0xF) << 4) | (bus->number & 0xF));
+ } else
+ ab->qmi.service_ins_id = ab->hw_params.qmi_service_ins_id;
ath11k_ce_get_shadow_config(ab, &cfg->shadow_reg_v2,
&cfg->shadow_reg_v2_len);

View File

@ -15,7 +15,7 @@ Signed-off-by: Robert Marko <robimarko@gmail.com>
--- a/drivers/net/wireless/ath/ath11k/pci.c
+++ b/drivers/net/wireless/ath/ath11k/pci.c
@@ -451,7 +451,11 @@ static int ath11k_pci_alloc_msi(struct a
@@ -458,7 +458,11 @@ static int ath11k_pci_alloc_msi(struct a
pci_read_config_dword(pci_dev, pci_dev->msi_cap + PCI_MSI_ADDRESS_LO,
&ab->pci.msi.addr_lo);

View File

@ -0,0 +1,24 @@
From dd3b9c59cfa1e9e0b73a575f4646be905691eaef Mon Sep 17 00:00:00 2001
From: Robert Marko <robimarko@gmail.com>
Date: Sat, 16 Oct 2021 19:34:10 +0200
Subject: [PATCH 241/241] ath11k: Disable coldboot calibration for IPQ8074
There is a bug with the remoteproc reset after coldboot calibration,
so until that is resolved disabled it to allow using the radio.
Signed-off-by: Robert Marko <robimarko@gmail.com>
---
drivers/net/wireless/ath/ath11k/core.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
--- a/drivers/net/wireless/ath/ath11k/core.c
+++ b/drivers/net/wireless/ath/ath11k/core.c
@@ -81,7 +81,7 @@ static const struct ath11k_hw_params ath
.supports_shadow_regs = false,
.idle_ps = false,
.supports_sta_ps = false,
- .cold_boot_calib = true,
+ .cold_boot_calib = false,
.cbcal_restart_fw = true,
.fw_mem_mode = 0,
.num_vdevs = 16 + 1,

View File

@ -0,0 +1,74 @@
From fb1c40c225cbc413d82c872dd8c8af3469b2b921 Mon Sep 17 00:00:00 2001
From: Robert Marko <robimarko@gmail.com>
Date: Fri, 16 Dec 2022 17:17:52 +0100
Subject: [PATCH] ath11k: support setting FW memory mode via DT
ath11k is really memory intensive for devices with less that 1GB of RAM,
so lets allow saving a significant amount of memory by setting the FW to
Mode-1 via DTS for devices that need it.
However the drawback is reduced number of VDEV-s and peers which is a
reasonable tradeoff.
Mode-2 allows for further reduction, but it has further restrictions.
While we are here, lets add a print to be able to easily determine what
FW memory mode is being used.
Signed-off-by: Robert Marko <robimarko@gmail.com>
---
drivers/net/wireless/ath/ath11k/core.c | 28 ++++++++++++++++++++++++--
1 file changed, 26 insertions(+), 2 deletions(-)
--- a/drivers/net/wireless/ath/ath11k/core.c
+++ b/drivers/net/wireless/ath/ath11k/core.c
@@ -32,7 +32,7 @@ module_param_named(frame_mode, ath11k_fr
MODULE_PARM_DESC(frame_mode,
"Datapath frame mode (0: raw, 1: native wifi (default), 2: ethernet)");
-static const struct ath11k_hw_params ath11k_hw_params[] = {
+static struct ath11k_hw_params ath11k_hw_params[] = {
{
.hw_rev = ATH11K_HW_IPQ8074,
.name = "ipq8074 hw2.0",
@@ -1826,7 +1826,8 @@ static void ath11k_core_reset(struct wor
static int ath11k_init_hw_params(struct ath11k_base *ab)
{
const struct ath11k_hw_params *hw_params = NULL;
- int i;
+ u32 fw_mem_mode;
+ int i, ret;
for (i = 0; i < ARRAY_SIZE(ath11k_hw_params); i++) {
hw_params = &ath11k_hw_params[i];
@@ -1842,7 +1843,30 @@ static int ath11k_init_hw_params(struct
ab->hw_params = *hw_params;
+ ret = of_property_read_u32(ab->dev->of_node,
+ "qcom,ath11k-fw-memory-mode",
+ &fw_mem_mode);
+ if (!ret) {
+ if (fw_mem_mode == 0) {
+ ab->hw_params.fw_mem_mode = 0;
+ ab->hw_params.num_vdevs = 16 + 1;
+ ab->hw_params.num_peers = 512;
+ }
+ else if (fw_mem_mode == 1) {
+ ab->hw_params.fw_mem_mode = 1;
+ ab->hw_params.num_vdevs = 8;
+ ab->hw_params.num_peers = 128;
+ } else if (fw_mem_mode == 2) {
+ ab->hw_params.fw_mem_mode = 2;
+ ab->hw_params.num_vdevs = 8;
+ ab->hw_params.num_peers = 128;
+ ab->hw_params.cold_boot_calib = false;
+ } else
+ ath11k_info(ab, "Unsupported FW memory mode: %u\n", fw_mem_mode);
+ }
+
ath11k_info(ab, "%s\n", ab->hw_params.name);
+ ath11k_info(ab, "FW memory mode: %d\n", ab->hw_params.fw_mem_mode);
return 0;
}

View File

@ -0,0 +1,57 @@
include $(TOPDIR)/rules.mk
PKG_NAME:=qca-nss-dp
PKG_RELEASE:=1
PKG_SOURCE_URL:=https://git.codelinaro.org/clo/qsdk/oss/lklm/nss-dp.git
PKG_SOURCE_PROTO:=git
PKG_SOURCE_DATE:=2022-04-30
PKG_SOURCE_VERSION:=72e9ec4187414461cbcf6ccff100e8b5ebe5f40b
PKG_MIRROR_HASH:=805f16e59c75511132922f97740ebf6bf953845b0bbfd2089c4615456893bb37
PKG_BUILD_PARALLEL:=1
PKG_FLAGS:=nonshared
include $(INCLUDE_DIR)/kernel.mk
include $(INCLUDE_DIR)/package.mk
define KernelPackage/qca-nss-dp
SECTION:=kernel
CATEGORY:=Kernel modules
SUBMENU:=Network Devices
DEPENDS:=@TARGET_ipq807x +kmod-qca-ssdk
TITLE:=Qualcom NSS dataplane ethernet driver
FILES:=$(PKG_BUILD_DIR)/qca-nss-dp.ko
AUTOLOAD:=$(call AutoLoad,31,qca-nss-dp,1)
endef
define KernelPackage/qca-nss-dp/Description
NSS dataplane ethernet driver for Qualcom SoCs.
endef
define Build/InstallDev
mkdir -p $(1)/usr/include/qca-nss-dp
$(CP) $(PKG_BUILD_DIR)/exports/* $(1)/usr/include/qca-nss-dp/
endef
EXTRA_CFLAGS+= \
-I$(STAGING_DIR)/usr/include/qca-ssdk
NSS_DP_HAL_DIR:=$(PKG_BUILD_DIR)/hal
define Build/Configure
$(LN) $(NSS_DP_HAL_DIR)/soc_ops/$(CONFIG_TARGET_BOARD)/nss_$(CONFIG_TARGET_BOARD).h \
$(PKG_BUILD_DIR)/exports/nss_dp_arch.h
endef
define Build/Compile
+$(MAKE) -C "$(LINUX_DIR)" \
CROSS_COMPILE="$(TARGET_CROSS)" \
ARCH="$(LINUX_KARCH)" \
M="$(PKG_BUILD_DIR)" \
EXTRA_CFLAGS="$(EXTRA_CFLAGS)" SoC="$(CONFIG_TARGET_BOARD)" \
$(KERNEL_MAKE_FLAGS) \
$(PKG_JOBS) \
modules
endef
$(eval $(call KernelPackage,qca-nss-dp))

View File

@ -0,0 +1,44 @@
From 40979666b4371012405715ffa61ab5760fcdc6b3 Mon Sep 17 00:00:00 2001
Message-Id: <40979666b4371012405715ffa61ab5760fcdc6b3.1620066716.git.baruch@tkos.co.il>
From: Baruch Siach <baruch@tkos.co.il>
Date: Mon, 3 May 2021 20:07:36 +0300
Subject: [PATCH 1/3] edma_tx_rx: support newer kernels time stamping API
---
hal/dp_ops/edma_dp/edma_v1/edma_tx_rx.c | 11 +++++++++++
1 file changed, 11 insertions(+)
--- a/hal/dp_ops/edma_dp/edma_v1/edma_tx_rx.c
+++ b/hal/dp_ops/edma_dp/edma_v1/edma_tx_rx.c
@@ -227,10 +227,16 @@ void nss_phy_tstamp_rx_buf(__attribute__
* set to the correct PTP class value by calling ptp_classify_raw
* in drv->rxtstamp function.
*/
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(5, 6, 0))
if (ndev && ndev->phydev && ndev->phydev->drv &&
ndev->phydev->drv->rxtstamp)
if(ndev->phydev->drv->rxtstamp(ndev->phydev, skb, 0))
return;
+#else
+ if (ndev && phy_has_rxtstamp(ndev->phydev))
+ if (phy_rxtstamp(ndev->phydev, skb, 0))
+ return;
+#endif
netif_receive_skb(skb);
}
@@ -248,9 +254,14 @@ void nss_phy_tstamp_tx_buf(struct net_de
* set to the correct PTP class value by calling ptp_classify_raw
* in the drv->txtstamp function.
*/
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(5, 6, 0))
if (ndev && ndev->phydev && ndev->phydev->drv &&
ndev->phydev->drv->txtstamp)
ndev->phydev->drv->txtstamp(ndev->phydev, skb, 0);
+#else
+ if (ndev && phy_has_txtstamp(ndev->phydev))
+ phy_rxtstamp(ndev->phydev, skb, 0);
+#endif
}
EXPORT_SYMBOL(nss_phy_tstamp_tx_buf);

View File

@ -0,0 +1,48 @@
From cef7873a2d77df13ee702d902ed4e06b2248904b Mon Sep 17 00:00:00 2001
Message-Id: <cef7873a2d77df13ee702d902ed4e06b2248904b.1620066716.git.baruch@tkos.co.il>
In-Reply-To: <40979666b4371012405715ffa61ab5760fcdc6b3.1620066716.git.baruch@tkos.co.il>
References: <40979666b4371012405715ffa61ab5760fcdc6b3.1620066716.git.baruch@tkos.co.il>
From: Baruch Siach <baruch@tkos.co.il>
Date: Mon, 3 May 2021 20:17:22 +0300
Subject: [PATCH 2/3] nss_dp_main: make phy mode code compatible with newer
kernels
---
include/nss_dp_dev.h | 4 ++--
nss_dp_main.c | 4 ++++
2 files changed, 6 insertions(+), 2 deletions(-)
--- a/include/nss_dp_dev.h
+++ b/include/nss_dp_dev.h
@@ -22,7 +22,7 @@
#include <linux/etherdevice.h>
#include <linux/netdevice.h>
#include <linux/platform_device.h>
-#include <linux/switch.h>
+#include <linux/phy.h>
#include <linux/version.h>
#include "nss_dp_api_if.h"
@@ -99,7 +99,7 @@ struct nss_dp_dev {
/* Phy related stuff */
struct phy_device *phydev; /* Phy device */
struct mii_bus *miibus; /* MII bus */
- uint32_t phy_mii_type; /* RGMII/SGMII/QSGMII */
+ phy_interface_t phy_mii_type; /* RGMII/SGMII/QSGMII */
uint32_t phy_mdio_addr; /* Mdio address */
bool link_poll; /* Link polling enable? */
uint32_t forced_speed; /* Forced speed? */
--- a/nss_dp_main.c
+++ b/nss_dp_main.c
@@ -584,7 +584,11 @@ static int32_t nss_dp_of_get_pdata(struc
hal_pdata->netdev = netdev;
hal_pdata->macid = dp_priv->macid;
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(5, 5, 0))
dp_priv->phy_mii_type = of_get_phy_mode(np);
+#else
+ of_get_phy_mode(np, &dp_priv->phy_mii_type);
+#endif
dp_priv->link_poll = of_property_read_bool(np, "qcom,link-poll");
if (of_property_read_u32(np, "qcom,phy-mdio-addr",
&dp_priv->phy_mdio_addr) && dp_priv->link_poll) {

View File

@ -0,0 +1,48 @@
From c8c52512ff48bee578901c381a42f027e79eadf9 Mon Sep 17 00:00:00 2001
Message-Id: <c8c52512ff48bee578901c381a42f027e79eadf9.1620066716.git.baruch@tkos.co.il>
In-Reply-To: <40979666b4371012405715ffa61ab5760fcdc6b3.1620066716.git.baruch@tkos.co.il>
References: <40979666b4371012405715ffa61ab5760fcdc6b3.1620066716.git.baruch@tkos.co.il>
From: Baruch Siach <baruch@tkos.co.il>
Date: Mon, 3 May 2021 20:20:29 +0300
Subject: [PATCH 3/3] Drop _nocache variants of ioremap()
Recent kernels removed them.
---
hal/dp_ops/edma_dp/edma_v1/edma_data_plane.c | 2 +-
hal/gmac_ops/qcom/qcom_if.c | 2 +-
hal/gmac_ops/syn/xgmac/syn_if.c | 2 +-
3 files changed, 3 insertions(+), 3 deletions(-)
--- a/hal/dp_ops/edma_dp/edma_v1/edma_data_plane.c
+++ b/hal/dp_ops/edma_dp/edma_v1/edma_data_plane.c
@@ -279,7 +279,7 @@ int edma_init(void)
/*
* Remap register resource
*/
- edma_hw.reg_base = ioremap_nocache((edma_hw.reg_resource)->start,
+ edma_hw.reg_base = ioremap((edma_hw.reg_resource)->start,
resource_size(edma_hw.reg_resource));
if (!edma_hw.reg_base) {
pr_warn("Unable to remap EDMA register memory.\n");
--- a/hal/gmac_ops/qcom/qcom_if.c
+++ b/hal/gmac_ops/qcom/qcom_if.c
@@ -418,7 +418,7 @@ static void *qcom_init(struct nss_gmac_h
qhd->nghd.mac_id = gmacpdata->macid;
/* Populate the mac base addresses */
- qhd->nghd.mac_base = devm_ioremap_nocache(&dp_priv->pdev->dev,
+ qhd->nghd.mac_base = devm_ioremap(&dp_priv->pdev->dev,
res->start, resource_size(res));
if (!qhd->nghd.mac_base) {
netdev_dbg(ndev, "ioremap fail.\n");
--- a/hal/gmac_ops/syn/xgmac/syn_if.c
+++ b/hal/gmac_ops/syn/xgmac/syn_if.c
@@ -432,7 +432,7 @@ static void *syn_init(struct nss_gmac_ha
/* Populate the mac base addresses */
shd->nghd.mac_base =
- devm_ioremap_nocache(&dp_priv->pdev->dev, res->start,
+ devm_ioremap(&dp_priv->pdev->dev, res->start,
resource_size(res));
if (!shd->nghd.mac_base) {
netdev_dbg(ndev, "ioremap fail.\n");

View File

@ -0,0 +1,31 @@
From d74920e2a7c413ef40eed72f9cf287cf6fbd5fb8 Mon Sep 17 00:00:00 2001
From: Robert Marko <robimarko@gmail.com>
Date: Thu, 20 May 2021 14:56:46 +0200
Subject: [PATCH 1/2] EDMA: Fix NAPI packet counting
There is a bug in the NAPI packet counting that will
cause NAPI over budget warnings.
Signed-off-by: Baruch Siach <baruch@tkos.co.il>
Signed-off-by: Robert Marko <robimarko@gmail.com>
---
hal/dp_ops/edma_dp/edma_v1/edma_tx_rx.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
--- a/hal/dp_ops/edma_dp/edma_v1/edma_tx_rx.c
+++ b/hal/dp_ops/edma_dp/edma_v1/edma_tx_rx.c
@@ -459,12 +459,12 @@ int edma_napi(struct napi_struct *napi,
for (i = 0; i < ehw->txcmpl_rings; i++) {
txcmpl_ring = &ehw->txcmpl_ring[i];
- work_done += edma_clean_tx(ehw, txcmpl_ring);
+ edma_clean_tx(ehw, txcmpl_ring);
}
for (i = 0; i < ehw->rxfill_rings; i++) {
rxfill_ring = &ehw->rxfill_ring[i];
- work_done += edma_alloc_rx_buffer(ehw, rxfill_ring);
+ edma_alloc_rx_buffer(ehw, rxfill_ring);
}
/*

View File

@ -0,0 +1,41 @@
From 44a30d94abcbb10aacc21db29be212518a6b1bf7 Mon Sep 17 00:00:00 2001
From: Robert Marko <robimarko@gmail.com>
Date: Thu, 20 May 2021 14:57:46 +0200
Subject: [PATCH] EDMA: Use NAPI_POLL_WEIGHT as NAPI weight
Currently a weight of 100 is used by the EDMA, according
to upstream max of 64 should be used and that is used for
almost any driver.
They also introduced NAPI_POLL_WEIGHT define which equals
to 64.
So use NAPI_POLL_WEIGHT as the weight.
Signed-off-by: Robert Marko <robimarko@gmail.com>
---
hal/dp_ops/edma_dp/edma_v1/edma_data_plane.c | 2 +-
hal/dp_ops/edma_dp/edma_v1/edma_data_plane.h | 1 -
2 files changed, 1 insertion(+), 2 deletions(-)
--- a/hal/dp_ops/edma_dp/edma_v1/edma_data_plane.c
+++ b/hal/dp_ops/edma_dp/edma_v1/edma_data_plane.c
@@ -837,7 +837,7 @@ static int edma_register_netdevice(struc
*/
if (!edma_hw.napi_added) {
netif_napi_add(netdev, &edma_hw.napi, edma_napi,
- EDMA_NAPI_WORK);
+ NAPI_POLL_WEIGHT);
/*
* Register the interrupt handlers and enable interrupts
*/
--- a/hal/dp_ops/edma_dp/edma_v1/edma_data_plane.h
+++ b/hal/dp_ops/edma_dp/edma_v1/edma_data_plane.h
@@ -26,7 +26,6 @@
#define EDMA_RX_PREHDR_SIZE (sizeof(struct edma_rx_preheader))
#define EDMA_TX_PREHDR_SIZE (sizeof(struct edma_tx_preheader))
#define EDMA_RING_SIZE 128
-#define EDMA_NAPI_WORK 100
#define EDMA_START_GMACS NSS_DP_HAL_START_IFNUM
#define EDMA_MAX_GMACS NSS_DP_HAL_MAX_PORTS
#define EDMA_TX_PKT_MIN_SIZE 33 /* IPQ807x EDMA needs a minimum packet size of 33 bytes */

View File

@ -0,0 +1,46 @@
From cadeb62a42296563141d6954eec58e34ef86778d Mon Sep 17 00:00:00 2001
From: Robert Marko <robimarko@gmail.com>
Date: Fri, 13 Aug 2021 20:12:08 +0200
Subject: [PATCH] NSS-DP: fix of_get_mac_address()
Recently OpenWrt backported the updated of_get_mac_address()
function which returns and error code instead.
So, patch the SSDK to use it and fix the compilation error.
Signed-off-by: Robert Marko <robimarko@gmail.com>
---
nss_dp_main.c | 13 ++++---------
1 file changed, 4 insertions(+), 9 deletions(-)
--- a/nss_dp_main.c
+++ b/nss_dp_main.c
@@ -555,9 +555,10 @@ static int32_t nss_dp_of_get_pdata(struc
struct net_device *netdev,
struct nss_gmac_hal_platform_data *hal_pdata)
{
- uint8_t *maddr;
+ u8 maddr[ETH_ALEN];
struct nss_dp_dev *dp_priv;
struct resource memres_devtree = {0};
+ int ret;
dp_priv = netdev_priv(netdev);
@@ -600,14 +601,8 @@ static int32_t nss_dp_of_get_pdata(struc
of_property_read_u32(np, "qcom,forced-speed", &dp_priv->forced_speed);
of_property_read_u32(np, "qcom,forced-duplex", &dp_priv->forced_duplex);
- maddr = (uint8_t *)of_get_mac_address(np);
-#if (LINUX_VERSION_CODE > KERNEL_VERSION(5, 4, 0))
- if (IS_ERR((void *)maddr)) {
- maddr = NULL;
- }
-#endif
-
- if (maddr && is_valid_ether_addr(maddr)) {
+ ret = of_get_mac_address(np, maddr);
+ if (!ret && is_valid_ether_addr(maddr)) {
ether_addr_copy(netdev->dev_addr, maddr);
} else {
random_ether_addr(netdev->dev_addr);

View File

@ -0,0 +1,29 @@
From 5da62ba19f554bf437752a44360fb5ae9f1a7f5e Mon Sep 17 00:00:00 2001
From: Robert Marko <robimarko@gmail.com>
Date: Tue, 8 Mar 2022 10:48:32 +0100
Subject: [PATCH] NSS-DP: implement ethernet IOCTL-s
Since kernel 5.15 ethernet/PHY related IOCTL-s have been split from the
generic IOCTL netdev op.
So, implement the new op instead of the generic one which is considered
for private IOCTL-s only now for 5.15+.
Signed-off-by: Robert Marko <robimarko@gmail.com>
---
nss_dp_main.c | 4 ++++
1 file changed, 4 insertions(+)
--- a/nss_dp_main.c
+++ b/nss_dp_main.c
@@ -532,7 +532,11 @@ static const struct net_device_ops nss_d
.ndo_set_mac_address = nss_dp_set_mac_address,
.ndo_validate_addr = eth_validate_addr,
.ndo_change_mtu = nss_dp_change_mtu,
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(5, 15, 0))
.ndo_do_ioctl = nss_dp_do_ioctl,
+#else
+ .ndo_eth_ioctl = nss_dp_do_ioctl,
+#endif
#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 5, 0))
.ndo_bridge_setlink = switchdev_port_bridge_setlink,

View File

@ -0,0 +1,48 @@
From c9afdcdd2642485a6476906be9da2e811090fc7a Mon Sep 17 00:00:00 2001
From: Robert Marko <robimarko@gmail.com>
Date: Fri, 18 Mar 2022 18:06:03 +0100
Subject: [PATCH] switchdev: remove the transaction structure
Since 5.12 there is no transaction structure anymore, so drop it for
5.12 and newer.
Signed-off-by: Robert Marko <robimarko@gmail.com>
---
nss_dp_switchdev.c | 10 ++++++++++
1 file changed, 10 insertions(+)
--- a/nss_dp_switchdev.c
+++ b/nss_dp_switchdev.c
@@ -279,13 +279,19 @@ void nss_dp_switchdev_setup(struct net_d
* Sets attributes
*/
static int nss_dp_port_attr_set(struct net_device *dev,
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(5, 12, 0))
const struct switchdev_attr *attr,
struct switchdev_trans *trans)
+#else
+ const struct switchdev_attr *attr)
+#endif
{
struct nss_dp_dev *dp_priv = (struct nss_dp_dev *)netdev_priv(dev);
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(5, 12, 0))
if (switchdev_trans_ph_prepare(trans))
return 0;
+#endif
switch (attr->id) {
case SWITCHDEV_ATTR_ID_PORT_BRIDGE_FLAGS:
@@ -309,8 +315,12 @@ static int nss_dp_switchdev_port_attr_se
{
int err;
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(5, 12, 0))
err = nss_dp_port_attr_set(netdev, port_attr_info->attr,
port_attr_info->trans);
+#else
+ err = nss_dp_port_attr_set(netdev, port_attr_info->attr);
+#endif
port_attr_info->handled = true;
return notifier_from_errno(err);

View File

@ -0,0 +1,51 @@
From f95868d54301c0f54e968ec9d978c9caa02ee425 Mon Sep 17 00:00:00 2001
From: Robert Marko <robimarko@gmail.com>
Date: Fri, 18 Mar 2022 18:24:18 +0100
Subject: [PATCH] switchdev: use new switchdev flags
Since kernel 5.12 switched utilizes a new way of setting the flags by
using a dedicated structure with flags and mask.
So fix using kernels 5.12 and later.
Signed-off-by: Robert Marko <robimarko@gmail.com>
---
include/nss_dp_dev.h | 7 +++++++
nss_dp_switchdev.c | 2 +-
2 files changed, 8 insertions(+), 1 deletion(-)
--- a/include/nss_dp_dev.h
+++ b/include/nss_dp_dev.h
@@ -24,6 +24,9 @@
#include <linux/platform_device.h>
#include <linux/phy.h>
#include <linux/version.h>
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 12, 0))
+#include <net/switchdev.h>
+#endif
#include "nss_dp_api_if.h"
#include "nss_dp_hal_if.h"
@@ -126,7 +129,11 @@ struct nss_dp_dev {
/* switchdev related attributes */
#ifdef CONFIG_NET_SWITCHDEV
u8 stp_state; /* STP state of this physical port */
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(5, 12, 0))
unsigned long brport_flags; /* bridge port flags */
+#else
+ struct switchdev_brport_flags brport_flags; /* bridge port flags */
+#endif
#endif
uint32_t rx_page_mode; /* page mode for Rx processing */
uint32_t rx_jumbo_mru; /* Jumbo mru value for Rx processing */
--- a/nss_dp_switchdev.c
+++ b/nss_dp_switchdev.c
@@ -296,7 +296,7 @@ static int nss_dp_port_attr_set(struct n
switch (attr->id) {
case SWITCHDEV_ATTR_ID_PORT_BRIDGE_FLAGS:
dp_priv->brport_flags = attr->u.brport_flags;
- netdev_dbg(dev, "set brport_flags %lu\n", attr->u.brport_flags);
+ netdev_dbg(dev, "set brport_flags %lu\n", attr->u.brport_flags.val);
return 0;
case SWITCHDEV_ATTR_ID_PORT_STP_STATE:
return nss_dp_stp_state_set(dp_priv, attr->u.stp_state);

View File

@ -0,0 +1,110 @@
From d16102cad769f430144ca8094d928762b445e9b0 Mon Sep 17 00:00:00 2001
From: Robert Marko <robimarko@gmail.com>
Date: Fri, 18 Mar 2022 22:02:01 +0100
Subject: [PATCH] switchdev: fix FDB roaming
Try and solve the roaming issue by trying to replicate what NSS bridge
module is doing, but by utilizing switchdev FDB notifiers instead of
adding new notifiers to the bridge code.
We register a new non-blocking switchdev notifier and simply wait for
notification, and then process the SWITCHDEV_FDB_DEL_TO_DEVICE
notifications.
Those tell us that a certain FDB entry should be removed, then a VSI ID
is fetched for the physical PPE port and using that VSI ID and the
notification provided MAC adress existing FDB entry gets removed.
Signed-off-by: Robert Marko <robimarko@gmail.com>
---
nss_dp_switchdev.c | 61 ++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 61 insertions(+)
--- a/nss_dp_switchdev.c
+++ b/nss_dp_switchdev.c
@@ -24,6 +24,8 @@
#include "nss_dp_dev.h"
#include "fal/fal_stp.h"
#include "fal/fal_ctrlpkt.h"
+#include "fal/fal_fdb.h"
+#include "ref/ref_vsi.h"
#define NSS_DP_SWITCH_ID 0
#define NSS_DP_SW_ETHTYPE_PID 0 /* PPE ethtype profile ID for slow protocols */
@@ -348,10 +350,64 @@ static int nss_dp_switchdev_event(struct
return NOTIFY_DONE;
}
+static int nss_dp_switchdev_fdb_del_event(struct net_device *netdev,
+ struct switchdev_notifier_fdb_info *fdb_info)
+{
+ struct nss_dp_dev *dp_priv = (struct nss_dp_dev *)netdev_priv(netdev);
+ fal_fdb_entry_t entry;
+ a_uint32_t vsi_id;
+ sw_error_t rv;
+
+ netdev_dbg(netdev, "FDB DEL %pM port %d\n", fdb_info->addr, dp_priv->macid);
+
+ rv = ppe_port_vsi_get(NSS_DP_SWITCH_ID, dp_priv->macid, &vsi_id);
+ if (rv) {
+ netdev_err(netdev, "cannot get VSI ID for port %d\n", dp_priv->macid);
+ return notifier_from_errno(rv);
+ }
+
+ memset(&entry, 0, sizeof(entry));
+ memcpy(&entry.addr, fdb_info->addr, ETH_ALEN);
+ entry.fid = vsi_id;
+
+ rv = fal_fdb_entry_del_bymac(NSS_DP_SWITCH_ID, &entry);
+ if (rv) {
+ netdev_err(netdev, "FDB entry delete failed with MAC %pM and fid %d\n",
+ &entry.addr, entry.fid);
+ return notifier_from_errno(rv);
+ }
+
+ return notifier_from_errno(rv);
+}
+
+static int nss_dp_fdb_switchdev_event(struct notifier_block *nb,
+ unsigned long event, void *ptr)
+{
+ struct net_device *dev = switchdev_notifier_info_to_dev(ptr);
+
+ /*
+ * Handle switchdev event only for physical devices
+ */
+ if (!nss_dp_is_phy_dev(dev)) {
+ return NOTIFY_DONE;
+ }
+
+ switch (event) {
+ case SWITCHDEV_FDB_DEL_TO_DEVICE:
+ return nss_dp_switchdev_fdb_del_event(dev, ptr);
+ }
+
+ return NOTIFY_DONE;
+}
+
static struct notifier_block nss_dp_switchdev_notifier = {
.notifier_call = nss_dp_switchdev_event,
};
+static struct notifier_block nss_dp_switchdev_fdb_notifier = {
+ .notifier_call = nss_dp_fdb_switchdev_event,
+};
+
static bool switch_init_done;
/*
@@ -366,6 +422,11 @@ void nss_dp_switchdev_setup(struct net_d
return;
}
+ err = register_switchdev_notifier(&nss_dp_switchdev_fdb_notifier);
+ if (err) {
+ netdev_dbg(dev, "%px:Failed to register switchdev FDB notifier\n", dev);
+ }
+
err = register_switchdev_blocking_notifier(&nss_dp_switchdev_notifier);
if (err) {
netdev_dbg(dev, "%px:Failed to register switchdev notifier\n", dev);

View File

@ -0,0 +1,41 @@
From 7e4ae2d6285095794d73d2f2ce61404f61d4e633 Mon Sep 17 00:00:00 2001
From: Ansuel Smith <ansuelsmth@gmail.com>
Date: Tue, 17 May 2022 15:55:36 +0200
Subject: [PATCH 11/11] treewide: fix confusing printing of registered netdev
Net core implementation changed and now printing the netdev name cause
confusing printing if done before register_netdev. Move the old printing
to dbg and add an additional info log right after register_netdev to
give the user some info on correct nss-dp probe.
Signed-off-by: Ansuel Smith <ansuelsmth@gmail.com>
---
hal/dp_ops/edma_dp/edma_v1/edma_data_plane.c | 4 ++--
nss_dp_main.c | 3 +++
2 files changed, 5 insertions(+), 2 deletions(-)
--- a/hal/dp_ops/edma_dp/edma_v1/edma_data_plane.c
+++ b/hal/dp_ops/edma_dp/edma_v1/edma_data_plane.c
@@ -822,8 +822,8 @@ static int edma_register_netdevice(struc
return -EINVAL;
}
- netdev_info(netdev, "nss_dp_edma: Registering netdev %s(qcom-id:%d) with EDMA\n",
- netdev->name, macid);
+ netdev_dbg(netdev, "nss_dp_edma: Registering netdev %s(qcom-id:%d) with EDMA\n",
+ netdev->name, macid);
/*
* We expect 'macid' to correspond to ports numbers on
--- a/nss_dp_main.c
+++ b/nss_dp_main.c
@@ -875,6 +875,9 @@ static int32_t nss_dp_probe(struct platf
goto phy_setup_fail;
}
+ netdev_info(netdev, "Registered netdev %s(qcom-id:%d)\n",
+ netdev->name, port_id);
+
dp_global_ctx.nss_dp[dp_priv->macid - 1] = dp_priv;
dp_global_ctx.slowproto_acl_bm = 0;

View File

@ -0,0 +1,23 @@
From fee52ef165e9fab2fca15492677082fd8e9e891f Mon Sep 17 00:00:00 2001
From: Ansuel Smith <ansuelsmth@gmail.com>
Date: Thu, 19 May 2022 23:40:24 +0200
Subject: [PATCH 12/12] gmac: syn: xgmac: silence debug log on probe
Silence debug log set as info in xgmac port probe.
Signed-off-by: Ansuel Smith <ansuelsmth@gmail.com>
---
hal/gmac_ops/syn/xgmac/syn_if.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
--- a/hal/gmac_ops/syn/xgmac/syn_if.c
+++ b/hal/gmac_ops/syn/xgmac/syn_if.c
@@ -445,7 +445,7 @@ static void *syn_init(struct nss_gmac_ha
spin_lock_init(&shd->nghd.slock);
- netdev_info(ndev, "ioremap OK.Size 0x%x Ndev base 0x%lx macbase 0x%px\n",
+ netdev_dbg(ndev, "ioremap OK.Size 0x%x Ndev base 0x%lx macbase 0x%px\n",
gmacpdata->reg_len,
ndev->base_addr,
shd->nghd.mac_base);

View File

@ -0,0 +1,182 @@
From 8293a26ca56ee2e9a88e4efb5dcc7f647803cd8c Mon Sep 17 00:00:00 2001
From: Alexandru Gagniuc <mr.nuke.me@gmail.com>
Date: Sun, 5 Jun 2022 21:45:09 -0500
Subject: [PATCH] nss_dp_main: Use a 'phy-handle' property to connect to the
PHY
The original method of connecting a PHY to the ethernet controller
requires the "qcom,link-poll", and "qcom,phy-mdio-addr" devicetree
properties. This is redundant. The PHY node already contains the MDIO
address, and attaching a PHY implies "link-poll".
Allow using a "phy-handle" property. Remove the following properties,
as they are no longer used:
* "qcom,link-poll"
* "qcom,phy-mdio-addr"
* "mdio-bus"
* "qcom,forced-speed"
* "qcom,forced-duplex"
Signed-off-by: Alexandru Gagniuc <mr.nuke.me@gmail.com>
---
include/nss_dp_dev.h | 5 +--
nss_dp_main.c | 91 +++++---------------------------------------
2 files changed, 10 insertions(+), 86 deletions(-)
--- a/include/nss_dp_dev.h
+++ b/include/nss_dp_dev.h
@@ -100,13 +100,10 @@ struct nss_dp_dev {
unsigned long drv_flags; /* Driver specific feature flags */
/* Phy related stuff */
+ struct device_node *phy_node;
struct phy_device *phydev; /* Phy device */
struct mii_bus *miibus; /* MII bus */
phy_interface_t phy_mii_type; /* RGMII/SGMII/QSGMII */
- uint32_t phy_mdio_addr; /* Mdio address */
- bool link_poll; /* Link polling enable? */
- uint32_t forced_speed; /* Forced speed? */
- uint32_t forced_duplex; /* Forced duplex? */
uint32_t link_state; /* Current link state */
uint32_t pause; /* Current flow control settings */
--- a/nss_dp_main.c
+++ b/nss_dp_main.c
@@ -399,7 +399,7 @@ static int nss_dp_open(struct net_device
netif_start_queue(netdev);
- if (!dp_priv->link_poll) {
+ if (!dp_priv->phydev) {
/* Notify data plane link is up */
if (dp_priv->data_plane_ops->link_state(dp_priv->dpc, 1)) {
netdev_dbg(netdev, "Data plane set link failed\n");
@@ -576,6 +576,8 @@ static int32_t nss_dp_of_get_pdata(struc
return -EFAULT;
}
+ dp_priv->phy_node = of_parse_phandle(np, "phy-handle", 0);
+
if (of_property_read_u32(np, "qcom,mactype", &hal_pdata->mactype)) {
pr_err("%s: error reading mactype\n", np->name);
return -EFAULT;
@@ -594,16 +596,6 @@ static int32_t nss_dp_of_get_pdata(struc
#else
of_get_phy_mode(np, &dp_priv->phy_mii_type);
#endif
- dp_priv->link_poll = of_property_read_bool(np, "qcom,link-poll");
- if (of_property_read_u32(np, "qcom,phy-mdio-addr",
- &dp_priv->phy_mdio_addr) && dp_priv->link_poll) {
- pr_err("%s: mdio addr required if link polling is enabled\n",
- np->name);
- return -EFAULT;
- }
-
- of_property_read_u32(np, "qcom,forced-speed", &dp_priv->forced_speed);
- of_property_read_u32(np, "qcom,forced-duplex", &dp_priv->forced_duplex);
ret = of_get_mac_address(np, maddr);
if (!ret && is_valid_ether_addr(maddr)) {
@@ -636,50 +628,6 @@ static int32_t nss_dp_of_get_pdata(struc
return 0;
}
-/*
- * nss_dp_mdio_attach()
- */
-static struct mii_bus *nss_dp_mdio_attach(struct platform_device *pdev)
-{
- struct device_node *mdio_node;
- struct platform_device *mdio_plat;
- struct ipq40xx_mdio_data *mdio_data;
-
- /*
- * Find mii_bus using "mdio-bus" handle.
- */
- mdio_node = of_parse_phandle(pdev->dev.of_node, "mdio-bus", 0);
- if (mdio_node) {
- return of_mdio_find_bus(mdio_node);
- }
-
- mdio_node = of_find_compatible_node(NULL, NULL, "qcom,qca-mdio");
- if (!mdio_node) {
- mdio_node = of_find_compatible_node(NULL, NULL,
- "qcom,ipq40xx-mdio");
- if (!mdio_node) {
- dev_err(&pdev->dev, "cannot find mdio node by phandle\n");
- return NULL;
- }
- }
-
- mdio_plat = of_find_device_by_node(mdio_node);
- if (!mdio_plat) {
- dev_err(&pdev->dev, "cannot find platform device from mdio node\n");
- of_node_put(mdio_node);
- return NULL;
- }
-
- mdio_data = dev_get_drvdata(&mdio_plat->dev);
- if (!mdio_data) {
- dev_err(&pdev->dev, "cannot get mii bus reference from device data\n");
- of_node_put(mdio_node);
- return NULL;
- }
-
- return mdio_data->mii_bus;
-}
-
#ifdef CONFIG_NET_SWITCHDEV
/*
* nss_dp_is_phy_dev()
@@ -738,7 +686,6 @@ static int32_t nss_dp_probe(struct platf
struct device_node *np = pdev->dev.of_node;
struct nss_gmac_hal_platform_data gmac_hal_pdata;
int32_t ret = 0;
- uint8_t phy_id[MII_BUS_ID_SIZE + 3];
#if defined(NSS_DP_PPE_SUPPORT)
uint32_t vsi_id;
fal_port_t port_id;
@@ -813,37 +760,17 @@ static int32_t nss_dp_probe(struct platf
dp_priv->drv_flags |= NSS_DP_PRIV_FLAG(INIT_DONE);
- if (dp_priv->link_poll) {
- dp_priv->miibus = nss_dp_mdio_attach(pdev);
- if (!dp_priv->miibus) {
- netdev_dbg(netdev, "failed to find miibus\n");
- goto phy_setup_fail;
- }
- snprintf(phy_id, MII_BUS_ID_SIZE + 3, PHY_ID_FMT,
- dp_priv->miibus->id, dp_priv->phy_mdio_addr);
-
+ if (dp_priv->phy_node) {
SET_NETDEV_DEV(netdev, &pdev->dev);
-
- dp_priv->phydev = phy_connect(netdev, phy_id,
- &nss_dp_adjust_link,
- dp_priv->phy_mii_type);
+ dp_priv->phydev = of_phy_connect(netdev, dp_priv->phy_node,
+ &nss_dp_adjust_link, 0,
+ dp_priv->phy_mii_type);
if (IS_ERR(dp_priv->phydev)) {
- netdev_dbg(netdev, "failed to connect to phy device\n");
+ dev_err(&pdev->dev, "Could not attach to PHY\n");
goto phy_setup_fail;
}
-#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 5, 0))
- dp_priv->phydev->advertising |=
- (ADVERTISED_Pause | ADVERTISED_Asym_Pause);
- dp_priv->phydev->supported |=
- (SUPPORTED_Pause | SUPPORTED_Asym_Pause);
-#else
- linkmode_set_bit(ETHTOOL_LINK_MODE_Pause_BIT, dp_priv->phydev->advertising);
- linkmode_set_bit(ETHTOOL_LINK_MODE_Asym_Pause_BIT, dp_priv->phydev->advertising);
-
- linkmode_set_bit(ETHTOOL_LINK_MODE_Pause_BIT, dp_priv->phydev->supported);
- linkmode_set_bit(ETHTOOL_LINK_MODE_Asym_Pause_BIT, dp_priv->phydev->supported);
-#endif
+ phy_attached_info(dp_priv->phydev);
}
#if defined(NSS_DP_PPE_SUPPORT)

View File

@ -0,0 +1,63 @@
From ae4fe8fb79b68f4cf4a887434ab6a8a9a1c65bfc Mon Sep 17 00:00:00 2001
From: Robert Marko <robimarko@gmail.com>
Date: Thu, 23 Jun 2022 14:18:50 +0200
Subject: [PATCH] nss-dp: edma-v1: use NAPI GRO by default
Utilize napi_gro_receive instead of plain netif_receive_skb on EDMA v1.
Usually it provides quite a lot of RX speed improvements, however in some
cases it may lead to decreased performance as there is no checksum
offloading implemented.
In cases where reduced performance is experienced its possible to disable
GRO by using ethtool.
Signed-off-by: Robert Marko <robimarko@gmail.com>
---
hal/dp_ops/edma_dp/edma_v1/edma_data_plane.c | 10 ++++++----
hal/dp_ops/edma_dp/edma_v1/edma_tx_rx.c | 8 ++++++--
2 files changed, 12 insertions(+), 6 deletions(-)
diff --git a/hal/dp_ops/edma_dp/edma_v1/edma_data_plane.c b/hal/dp_ops/edma_dp/edma_v1/edma_data_plane.c
index 1d748db..e81c461 100644
--- a/hal/dp_ops/edma_dp/edma_v1/edma_data_plane.c
+++ b/hal/dp_ops/edma_dp/edma_v1/edma_data_plane.c
@@ -589,10 +589,12 @@ drop:
*/
static void edma_if_set_features(struct nss_dp_data_plane_ctx *dpc)
{
- /*
- * TODO - add flags to support HIGHMEM/cksum offload VLAN
- * the features are enabled.
- */
+ struct net_device *netdev = dpc->dev;
+
+ netdev->features |= NETIF_F_GRO;
+ netdev->hw_features |= NETIF_F_GRO;
+ netdev->vlan_features |= NETIF_F_GRO;
+ netdev->wanted_features |= NETIF_F_GRO;
}
/* TODO - check if this is needed */
diff --git a/hal/dp_ops/edma_dp/edma_v1/edma_tx_rx.c b/hal/dp_ops/edma_dp/edma_v1/edma_tx_rx.c
index 5780a30..a002a79 100644
--- a/hal/dp_ops/edma_dp/edma_v1/edma_tx_rx.c
+++ b/hal/dp_ops/edma_dp/edma_v1/edma_tx_rx.c
@@ -410,8 +410,12 @@ static uint32_t edma_clean_rx(struct edma_hw *ehw,
if (unlikely(EDMA_RXPH_SERVICE_CODE_GET(rxph) ==
NSS_PTP_EVENT_SERVICE_CODE))
nss_phy_tstamp_rx_buf(ndev, skb);
- else
- netif_receive_skb(skb);
+ else {
+ if (likely(ndev->features & NETIF_F_GRO))
+ napi_gro_receive(&ehw->napi, skb);
+ else
+ netif_receive_skb(skb);
+ }
next_rx_desc:
/*
--
2.38.1

View File

@ -0,0 +1,55 @@
From 358b93e40d0c6b6d381fe0e9d2a63c45a10321b3 Mon Sep 17 00:00:00 2001
From: Robert Marko <robimarko@gmail.com>
Date: Sun, 4 Dec 2022 18:41:36 +0100
Subject: [PATCH] nss-dp: allow setting netdev name from DTS
Allow reading the desired netdev name from DTS like DSA allows and then
set it as the netdev name during registration.
If label is not defined, simply fallback to kernel ethN enumeration.
Signed-off-by: Robert Marko <robimarko@gmail.com>
---
nss_dp_main.c | 17 ++++++++++++++---
1 file changed, 14 insertions(+), 3 deletions(-)
diff --git a/nss_dp_main.c b/nss_dp_main.c
index 18e1088..19e14fb 100644
--- a/nss_dp_main.c
+++ b/nss_dp_main.c
@@ -685,18 +685,29 @@ static int32_t nss_dp_probe(struct platform_device *pdev)
struct nss_dp_dev *dp_priv;
struct device_node *np = pdev->dev.of_node;
struct nss_gmac_hal_platform_data gmac_hal_pdata;
+ const char *name = of_get_property(np, "label", NULL);
int32_t ret = 0;
+ int assign_type;
#if defined(NSS_DP_PPE_SUPPORT)
uint32_t vsi_id;
fal_port_t port_id;
#endif
+ if (name) {
+ assign_type = NET_NAME_PREDICTABLE;
+ } else {
+ name = "eth%d";
+ assign_type = NET_NAME_ENUM;
+ }
+
/* TODO: See if we need to do some SoC level common init */
- netdev = alloc_etherdev_mqs(sizeof(struct nss_dp_dev),
- NSS_DP_NETDEV_TX_QUEUE_NUM, NSS_DP_NETDEV_RX_QUEUE_NUM);
+ netdev = alloc_netdev_mqs(sizeof(struct nss_dp_dev),
+ name, assign_type,
+ ether_setup,
+ NSS_DP_NETDEV_TX_QUEUE_NUM, NSS_DP_NETDEV_RX_QUEUE_NUM);
if (!netdev) {
- pr_info("alloc_etherdev() failed\n");
+ dev_err(&pdev->dev, "alloc_netdev_mqs() failed\n");
return -ENOMEM;
}
--
2.38.1

View File

@ -0,0 +1,82 @@
include $(TOPDIR)/rules.mk
PKG_NAME:=qca-ssdk
PKG_RELEASE:=1
PKG_SOURCE_URL:=https://git.codelinaro.org/clo/qsdk/oss/lklm/qca-ssdk.git
PKG_SOURCE_PROTO:=git
PKG_SOURCE_DATE:=2022-09-12
PKG_SOURCE_VERSION:=628b22bc3d5ee81414b75ab3de6a255c82754dec
PKG_MIRROR_HASH:=859344f79504b9953639dc5aa27042249f68e3a9a269e66d7f7a25e1ab38c110
PKG_FLAGS:=nonshared
include $(INCLUDE_DIR)/kernel.mk
include $(INCLUDE_DIR)/package.mk
define KernelPackage/qca-ssdk
SECTION:=kernel
CATEGORY:=Kernel modules
SUBMENU:=Network Devices
TITLE:=Qualcom SSDK switch driver
DEPENDS:=@(TARGET_ipq807x)
FILES:=$(PKG_BUILD_DIR)/build/bin/qca-ssdk.ko
AUTOLOAD:=$(call AutoLoad,30,qca-ssdk)
endef
define KernelPackage/qca-ssdk/Description
Driver for Qualcomm Atheros switches.
endef
GCC_VERSION=$(shell echo "$(CONFIG_GCC_VERSION)" | sed 's/[^0-9.]*\([0-9.]*\).*/\1/')
ifdef CONFIG_TOOLCHAIN_BIN_PATH
TOOLCHAIN_BIN_PATH=$(CONFIG_TOOLCHAIN_BIN_PATH)
else
TOOLCHAIN_BIN_PATH=$(TOOLCHAIN_DIR)/bin
endif
MAKE_FLAGS+= \
TARGET_NAME=$(CONFIG_TARGET_NAME) \
TOOL_PATH=$(TOOLCHAIN_BIN_PATH) \
SYS_PATH=$(LINUX_DIR) \
TOOLPREFIX=$(TARGET_CROSS) \
KVER=$(LINUX_VERSION) \
ARCH=$(LINUX_KARCH) \
TARGET_SUFFIX=$(CONFIG_TARGET_SUFFIX) \
GCC_VERSION=$(GCC_VERSION) \
EXTRA_CFLAGS=-fno-stack-protector -I$(STAGING_DIR)/usr/include \
$(KERNEL_MAKE_FLAGS)
ifeq ($(CONFIG_TARGET_BOARD), "ipq807x")
MAKE_FLAGS+= CHIP_TYPE=HPPE PTP_FEATURE=disable SWCONFIG_FEATURE=disable
endif
define Build/InstallDev
$(INSTALL_DIR) $(1)/usr/include/qca-ssdk
$(INSTALL_DIR) $(1)/usr/include/qca-ssdk/api
$(INSTALL_DIR) $(1)/usr/include/qca-ssdk/ref
$(INSTALL_DIR) $(1)/usr/include/qca-ssdk/fal
$(INSTALL_DIR) $(1)/usr/include/qca-ssdk/sal
$(INSTALL_DIR) $(1)/usr/include/qca-ssdk/init
$(CP) -rf $(PKG_BUILD_DIR)/include/api/sw_ioctl.h $(1)/usr/include/qca-ssdk/api
if [ -f $(PKG_BUILD_DIR)/include/ref/ref_vsi.h ]; then \
$(CP) -rf $(PKG_BUILD_DIR)/include/ref/ref_vsi.h $(1)/usr/include/qca-ssdk/ref/; \
fi
if [ -f $(PKG_BUILD_DIR)/include/ref/ref_fdb.h ]; then \
$(CP) -rf $(PKG_BUILD_DIR)/include/ref/ref_fdb.h $(1)/usr/include/qca-ssdk/ref/; \
fi
if [ -f $(PKG_BUILD_DIR)/include/ref/ref_port_ctrl.h ]; then \
$(CP) -rf $(PKG_BUILD_DIR)/include/ref/ref_port_ctrl.h $(1)/usr/include/qca-ssdk/ref/; \
fi
if [ -f $(PKG_BUILD_DIR)/include/init/ssdk_init.h ]; then \
$(CP) -rf $(PKG_BUILD_DIR)/include/init/ssdk_init.h $(1)/usr/include/qca-ssdk/init/; \
fi
$(CP) -rf $(PKG_BUILD_DIR)/include/fal $(1)/usr/include/qca-ssdk
$(CP) -rf $(PKG_BUILD_DIR)/include/common/*.h $(1)/usr/include/qca-ssdk
$(CP) -rf $(PKG_BUILD_DIR)/include/sal/os/linux/*.h $(1)/usr/include/qca-ssdk
$(CP) -rf $(PKG_BUILD_DIR)/include/sal/os/*.h $(1)/usr/include/qca-ssdk
endef
$(eval $(call KernelPackage,qca-ssdk))

View File

@ -0,0 +1,56 @@
From 6ee395e1cab32d1d4899d7846ea99e6e2dc0a9e4 Mon Sep 17 00:00:00 2001
From: Robert Marko <robimarko@gmail.com>
Date: Wed, 12 May 2021 13:41:12 +0200
Subject: [PATCH 01/11] SSDK: config: add kernel 5.10
This is purely to identify it and be able to set
flags correctly.
Signed-off-by: Robert Marko <robimarko@gmail.com>
---
config | 6 +++++-
make/linux_opt.mk | 4 ++--
2 files changed, 7 insertions(+), 3 deletions(-)
--- a/config
+++ b/config
@@ -24,6 +24,10 @@ ifeq ($(KVER),$(filter 5.4%,$(KVER)))
OS_VER=5_4
endif
+ifeq ($(KVER),$(filter 5.10%,$(KVER)))
+OS_VER=5_10
+endif
+
ifeq ($(KVER), 3.4.0)
OS_VER=3_4
endif
@@ -132,7 +136,7 @@ ifeq ($(ARCH), arm)
endif
ifeq ($(ARCH), arm64)
- ifeq ($(KVER),$(filter 4.1% 4.4% 4.9% 5.4%,$(KVER)))
+ ifeq ($(KVER),$(filter 4.1% 4.4% 4.9% 5.4% 5.10%,$(KVER)))
CPU_CFLAG= -DMODULE -Os -pipe -march=armv8-a -mcpu=cortex-a53+crypto -fno-caller-saves -fno-strict-aliasing -Werror -fno-common -Wno-format-security -Wno-pointer-sign -Wno-unused-but-set-variable -Wno-error=unused-result -mcmodel=large
endif
endif
--- a/make/linux_opt.mk
+++ b/make/linux_opt.mk
@@ -437,7 +437,7 @@ ifeq (KSLIB, $(MODULE_TYPE))
KASAN_SHADOW_SCALE_SHIFT := 3
endif
- ifeq (5_4, $(OS_VER))
+ ifeq ($(OS_VER),$(filter 5_4 5_10, $(OS_VER)))
ifeq ($(ARCH), arm64)
KASAN_OPTION += -DKASAN_SHADOW_SCALE_SHIFT=$(KASAN_SHADOW_SCALE_SHIFT)
endif
@@ -468,7 +468,7 @@ ifeq (KSLIB, $(MODULE_TYPE))
endif
- ifeq ($(OS_VER),$(filter 4_4 5_4, $(OS_VER)))
+ ifeq ($(OS_VER),$(filter 4_4 5_4 5_10, $(OS_VER)))
MODULE_CFLAG += -DKVER34
MODULE_CFLAG += -DKVER32
MODULE_CFLAG += -DLNX26_22

View File

@ -0,0 +1,102 @@
From 845a89b05aae807fb837f8e8f27f95c89de6023f Mon Sep 17 00:00:00 2001
From: Robert Marko <robimarko@gmail.com>
Date: Wed, 12 May 2021 13:45:45 +0200
Subject: [PATCH 02/11] SSDK: replace ioremap_nocache with ioremap
ioremap_nocache was dropped upstream, simply use the
generic variety.
Signed-off-by: Robert Marko <robimarko@gmail.com>
---
src/init/ssdk_clk.c | 10 +++++-----
src/init/ssdk_init.c | 2 +-
src/init/ssdk_plat.c | 6 +++---
3 files changed, 9 insertions(+), 9 deletions(-)
--- a/src/init/ssdk_clk.c
+++ b/src/init/ssdk_clk.c
@@ -721,7 +721,7 @@ ssdk_mp_tcsr_get(a_uint32_t tcsr_offset,
{
void __iomem *tcsr_base = NULL;
- tcsr_base = ioremap_nocache(TCSR_ETH_ADDR, TCSR_ETH_SIZE);
+ tcsr_base = ioremap(TCSR_ETH_ADDR, TCSR_ETH_SIZE);
if (!tcsr_base)
{
SSDK_ERROR("Failed to map tcsr eth address!\n");
@@ -738,7 +738,7 @@ ssdk_mp_tcsr_set(a_uint32_t tcsr_offset,
{
void __iomem *tcsr_base = NULL;
- tcsr_base = ioremap_nocache(TCSR_ETH_ADDR, TCSR_ETH_SIZE);
+ tcsr_base = ioremap(TCSR_ETH_ADDR, TCSR_ETH_SIZE);
if (!tcsr_base)
{
SSDK_ERROR("Failed to map tcsr eth address!\n");
@@ -786,7 +786,7 @@ ssdk_mp_cmnblk_stable_check(void)
a_uint32_t reg_val;
int i, loops = 20;
- pll_lock = ioremap_nocache(CMN_PLL_LOCKED_ADDR, CMN_PLL_LOCKED_SIZE);
+ pll_lock = ioremap(CMN_PLL_LOCKED_ADDR, CMN_PLL_LOCKED_SIZE);
if (!pll_lock) {
SSDK_ERROR("Failed to map CMN PLL LOCK register!\n");
return A_FALSE;
@@ -843,7 +843,7 @@ static void ssdk_cmnblk_pll_src_set(enum
void __iomem *cmn_pll_src_base = NULL;
a_uint32_t reg_val;
- cmn_pll_src_base = ioremap_nocache(CMN_BLK_PLL_SRC_ADDR, CMN_BLK_SIZE);
+ cmn_pll_src_base = ioremap(CMN_BLK_PLL_SRC_ADDR, CMN_BLK_SIZE);
if (!cmn_pll_src_base) {
SSDK_ERROR("Failed to map cmn pll source address!\n");
return;
@@ -869,7 +869,7 @@ static void ssdk_cmnblk_init(enum cmnblk
return;
}
- gcc_pll_base = ioremap_nocache(CMN_BLK_ADDR, CMN_BLK_SIZE);
+ gcc_pll_base = ioremap(CMN_BLK_ADDR, CMN_BLK_SIZE);
if (!gcc_pll_base) {
SSDK_ERROR("Failed to map gcc pll address!\n");
return;
--- a/src/init/ssdk_init.c
+++ b/src/init/ssdk_init.c
@@ -3134,7 +3134,7 @@ static int ssdk_dess_mac_mode_init(a_uin
(a_uint8_t *)&reg_value, 4);
mdelay(10);
/*softreset psgmii, fixme*/
- gcc_addr = ioremap_nocache(0x1812000, 0x200);
+ gcc_addr = ioremap(0x1812000, 0x200);
if (!gcc_addr) {
SSDK_ERROR("gcc map fail!\n");
return 0;
--- a/src/init/ssdk_plat.c
+++ b/src/init/ssdk_plat.c
@@ -1708,7 +1708,7 @@ ssdk_plat_init(ssdk_init_cfg *cfg, a_uin
reg_mode = ssdk_uniphy_reg_access_mode_get(dev_id);
if(reg_mode == HSL_REG_LOCAL_BUS) {
ssdk_uniphy_reg_map_info_get(dev_id, &map);
- qca_phy_priv_global[dev_id]->uniphy_hw_addr = ioremap_nocache(map.base_addr,
+ qca_phy_priv_global[dev_id]->uniphy_hw_addr = ioremap(map.base_addr,
map.size);
if (!qca_phy_priv_global[dev_id]->uniphy_hw_addr) {
SSDK_ERROR("%s ioremap fail.", __func__);
@@ -1723,7 +1723,7 @@ ssdk_plat_init(ssdk_init_cfg *cfg, a_uin
reg_mode = ssdk_switch_reg_access_mode_get(dev_id);
if (reg_mode == HSL_REG_LOCAL_BUS) {
ssdk_switch_reg_map_info_get(dev_id, &map);
- qca_phy_priv_global[dev_id]->hw_addr = ioremap_nocache(map.base_addr,
+ qca_phy_priv_global[dev_id]->hw_addr = ioremap(map.base_addr,
map.size);
if (!qca_phy_priv_global[dev_id]->hw_addr) {
SSDK_ERROR("%s ioremap fail.", __func__);
@@ -1764,7 +1764,7 @@ ssdk_plat_init(ssdk_init_cfg *cfg, a_uin
return -1;
}
- qca_phy_priv_global[dev_id]->psgmii_hw_addr = ioremap_nocache(map.base_addr,
+ qca_phy_priv_global[dev_id]->psgmii_hw_addr = ioremap(map.base_addr,
map.size);
if (!qca_phy_priv_global[dev_id]->psgmii_hw_addr) {
SSDK_ERROR("%s ioremap fail.", __func__);

View File

@ -0,0 +1,40 @@
From 85f988dbc15559a5a2fee606e6ef400aa39fe444 Mon Sep 17 00:00:00 2001
From: Robert Marko <robimarko@gmail.com>
Date: Wed, 12 May 2021 17:15:46 +0200
Subject: [PATCH 03/11] SSDK: platform: use of_mdio_find_bus() to get MDIO bus
Kernel has a generic of_mdio_find_bus() which can get the appropriate
MDIO bus based on the DT node.
So, drop the getting MDIO from platform data, which no longer works
in 5.4 and later and use of_mdio_find_bus().
Signed-off-by: Baruch Siach <baruch@tkos.co.il>
Signed-off-by: Robert Marko <robimarko@gmail.com>
---
src/init/ssdk_plat.c | 8 +-------
1 file changed, 1 insertion(+), 7 deletions(-)
--- a/src/init/ssdk_plat.c
+++ b/src/init/ssdk_plat.c
@@ -753,7 +753,6 @@ static int miibus_get(a_uint32_t dev_id)
struct device_node *mdio_node = NULL;
struct device_node *switch_node = NULL;
struct platform_device *mdio_plat = NULL;
- struct qca_mdio_data *mdio_data = NULL;
struct qca_phy_priv *priv;
hsl_reg_mode reg_mode = HSL_REG_LOCAL_BUS;
priv = qca_phy_priv_global[dev_id];
@@ -788,12 +787,7 @@ static int miibus_get(a_uint32_t dev_id)
if(reg_mode == HSL_REG_LOCAL_BUS)
{
- mdio_data = dev_get_drvdata(&mdio_plat->dev);
- if (!mdio_data) {
- SSDK_ERROR("cannot get mdio_data reference from device data\n");
- return 1;
- }
- priv->miibus = mdio_data->mii_bus;
+ priv->miibus = of_mdio_find_bus(mdio_node);
}
else
priv->miibus = dev_get_drvdata(&mdio_plat->dev);

View File

@ -0,0 +1,42 @@
From 079c20aa182c6b623d49e1f375e022dedac7373c Mon Sep 17 00:00:00 2001
From: Robert Marko <robimarko@gmail.com>
Date: Fri, 13 Aug 2021 20:03:21 +0200
Subject: [PATCH 04/11] SSDK: dts: fix of_get_mac_address()
Recently OpenWrt backported the updated of_get_mac_address()
function which returns and error code instead.
So, patch the SSDK to use it and fix the compilation error.
Signed-off-by: Robert Marko <robimarko@gmail.com>
---
src/init/ssdk_dts.c | 7 ++++---
1 file changed, 4 insertions(+), 3 deletions(-)
--- a/src/init/ssdk_dts.c
+++ b/src/init/ssdk_dts.c
@@ -921,8 +921,9 @@ static void ssdk_dt_parse_intf_mac(void)
{
struct device_node *dp_node = NULL;
a_uint32_t dp = 0;
- a_uint8_t *maddr = NULL;
+ u8 maddr[ETH_ALEN];
char dp_name[8] = {0};
+ int ret;
for (dp = 1; dp <= SSDK_MAX_NR_ETH; dp++) {
snprintf(dp_name, sizeof(dp_name), "dp%d", dp);
@@ -930,11 +931,11 @@ static void ssdk_dt_parse_intf_mac(void)
if (!dp_node) {
continue;
}
- maddr = (a_uint8_t *)of_get_mac_address(dp_node);
+ ret = of_get_mac_address(dp_node, maddr);
#if (LINUX_VERSION_CODE < KERNEL_VERSION(5, 0, 0))
if (maddr && is_valid_ether_addr(maddr)) {
#else
- if (!IS_ERR(maddr) && is_valid_ether_addr(maddr)) {
+ if (!ret && is_valid_ether_addr(maddr)) {
#endif
ssdk_dt_global.num_intf_mac++;
ether_addr_copy(ssdk_dt_global.intf_mac[dp-1].uc, maddr);

View File

@ -0,0 +1,56 @@
From 0c509f8d8e5a6a03933a112d4487fd1c005442d6 Mon Sep 17 00:00:00 2001
From: Robert Marko <robimarko@gmail.com>
Date: Fri, 24 Dec 2021 19:39:02 +0100
Subject: [PATCH 05/11] SSDK: config: add kernel 5.15
This is purely to identify it and be able to set
flags correctly.
Signed-off-by: Robert Marko <robimarko@gmail.com>
---
config | 6 +++++-
make/linux_opt.mk | 4 ++--
2 files changed, 7 insertions(+), 3 deletions(-)
--- a/config
+++ b/config
@@ -28,6 +28,10 @@ ifeq ($(KVER),$(filter 5.10%,$(KVER)))
OS_VER=5_10
endif
+ifeq ($(KVER),$(filter 5.15%,$(KVER)))
+OS_VER=5_15
+endif
+
ifeq ($(KVER), 3.4.0)
OS_VER=3_4
endif
@@ -136,7 +140,7 @@ ifeq ($(ARCH), arm)
endif
ifeq ($(ARCH), arm64)
- ifeq ($(KVER),$(filter 4.1% 4.4% 4.9% 5.4% 5.10%,$(KVER)))
+ ifeq ($(KVER),$(filter 4.1% 4.4% 4.9% 5.4% 5.10% 5.15%,$(KVER)))
CPU_CFLAG= -DMODULE -Os -pipe -march=armv8-a -mcpu=cortex-a53+crypto -fno-caller-saves -fno-strict-aliasing -Werror -fno-common -Wno-format-security -Wno-pointer-sign -Wno-unused-but-set-variable -Wno-error=unused-result -mcmodel=large
endif
endif
--- a/make/linux_opt.mk
+++ b/make/linux_opt.mk
@@ -437,7 +437,7 @@ ifeq (KSLIB, $(MODULE_TYPE))
KASAN_SHADOW_SCALE_SHIFT := 3
endif
- ifeq ($(OS_VER),$(filter 5_4 5_10, $(OS_VER)))
+ ifeq ($(OS_VER),$(filter 5_4 5_10 5_15, $(OS_VER)))
ifeq ($(ARCH), arm64)
KASAN_OPTION += -DKASAN_SHADOW_SCALE_SHIFT=$(KASAN_SHADOW_SCALE_SHIFT)
endif
@@ -468,7 +468,7 @@ ifeq (KSLIB, $(MODULE_TYPE))
endif
- ifeq ($(OS_VER),$(filter 4_4 5_4 5_10, $(OS_VER)))
+ ifeq ($(OS_VER),$(filter 4_4 5_4 5_10 5_15, $(OS_VER)))
MODULE_CFLAG += -DKVER34
MODULE_CFLAG += -DKVER32
MODULE_CFLAG += -DLNX26_22

View File

@ -0,0 +1,83 @@
From 9278b2794d984f5a8ec2350b9607a35aea2cc106 Mon Sep 17 00:00:00 2001
From: Robert Marko <robimarko@gmail.com>
Date: Fri, 24 Dec 2021 20:02:32 +0100
Subject: [PATCH 06/11] qca8081: convert to 5.11 IRQ model
Kernel 5.11 introduced new IRQ handling model for PHY-s,
so provide those if 5.11 or later is used.
Signed-off-by: Robert Marko <robimarko@gmail.com>
---
src/hsl/phy/qca808x.c | 46 +++++++++++++++++++++++++++++++++++++++++++
1 file changed, 46 insertions(+)
--- a/src/hsl/phy/qca808x.c
+++ b/src/hsl/phy/qca808x.c
@@ -247,6 +247,7 @@ static int qca808x_config_intr(struct ph
return err;
}
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(5, 11, 0))
static int qca808x_ack_interrupt(struct phy_device *phydev)
{
int err;
@@ -266,6 +267,47 @@ static int qca808x_ack_interrupt(struct
return (err < 0) ? err : 0;
}
+#endif
+
+#if (LINUX_VERSION_CODE > KERNEL_VERSION(5, 11, 0))
+static irqreturn_t qca808x_handle_interrupt(struct phy_device *phydev)
+{
+ a_uint16_t irq_status, int_enabled;
+ a_uint32_t dev_id = 0, phy_id = 0;
+ qca808x_priv *priv = phydev->priv;
+ const struct qca808x_phy_info *pdata = priv->phy_info;
+
+ if (!pdata) {
+ return SW_FAIL;
+ }
+
+ dev_id = pdata->dev_id;
+ phy_id = pdata->phy_addr;
+
+ irq_status = qca808x_phy_reg_read(dev_id, phy_id,
+ QCA808X_PHY_INTR_STATUS);
+ if (irq_status < 0) {
+ phy_error(phydev);
+ return IRQ_NONE;
+ }
+
+ /* Read the current enabled interrupts */
+ int_enabled = qca808x_phy_reg_read(dev_id, phy_id,
+ QCA808X_PHY_INTR_MASK);
+ if (int_enabled < 0) {
+ phy_error(phydev);
+ return IRQ_NONE;
+ }
+
+ /* See if this was one of our enabled interrupts */
+ if (!(irq_status & int_enabled))
+ return IRQ_NONE;
+
+ phy_trigger_machine(phydev);
+
+ return IRQ_HANDLED;
+}
+#endif
/* switch linux negtiation capability to fal avariable */
#if (LINUX_VERSION_CODE < KERNEL_VERSION(5, 0, 0))
@@ -638,7 +680,11 @@ struct phy_driver qca808x_phy_driver = {
.config_intr = qca808x_config_intr,
.config_aneg = qca808x_config_aneg,
.aneg_done = qca808x_aneg_done,
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(5, 11, 0))
.ack_interrupt = qca808x_ack_interrupt,
+#else
+ .handle_interrupt = qca808x_handle_interrupt,
+#endif
.read_status = qca808x_read_status,
.suspend = qca808x_suspend,
.resume = qca808x_resume,

View File

@ -0,0 +1,67 @@
From 20a7945b82a4aefcb9ca0a14978412e4ae0057c9 Mon Sep 17 00:00:00 2001
From: Robert Marko <robimarko@gmail.com>
Date: Tue, 11 Jan 2022 00:28:42 +0100
Subject: [PATCH 07/11] qca807x: add a LED quirk for Xiaomi AX9000
Xiaomi AX9000 has a single LED for each of 4 gigabit ethernet ports that
are connected to QCA8075, and that LED is connected to the 100M LED pin.
So, by default it will only work when in 10 or 100Mbit mode, this is quite
annoying and makes no sense(If they have connected it to the 1000Mbit LED
pin then it would have worked for 10/100 by default as well).
So, to solve this add a check for system compatible as we cant parse if
from DTS in any other way and set the 100M LED to blink on 1000Base-T
as well.
Signed-off-by: Robert Marko <robimarko@gmail.com>
---
include/hsl/phy/malibu_phy.h | 2 ++
src/hsl/phy/malibu_phy.c | 11 +++++++++++
2 files changed, 13 insertions(+)
--- a/include/hsl/phy/malibu_phy.h
+++ b/include/hsl/phy/malibu_phy.h
@@ -94,6 +94,7 @@ extern "C"
#define MALIBU_DAC_CTRL_MASK 0x380
#define MALIBU_DAC_CTRL_VALUE 0x280
#define MALIBU_LED_1000_CTRL1_100_10_MASK 0x30
+#define MALIBU_LED_100_CTRL1_1000_MASK 0x40
#define MALIBU_PHY_EEE_ADV_100M 0x0002
#define MALIBU_PHY_EEE_ADV_1000M 0x0004
@@ -118,6 +119,7 @@ extern "C"
#define MALIBU_PHY_MMD7_EGRESS_COUNTER_HIGH 0x802d
#define MALIBU_PHY_MMD7_EGRESS_COUNTER_LOW 0x802e
#define MALIBU_PHY_MMD7_EGRESS_ERROR_COUNTER 0x802f
+#define MALIBU_PHY_MMD7_LED_100_CTRL1 0x8074
#define MALIBU_PHY_MMD7_LED_1000_CTRL1 0x8076
--- a/src/hsl/phy/malibu_phy.c
+++ b/src/hsl/phy/malibu_phy.c
@@ -15,6 +15,8 @@
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
+#include <linux/of.h>
+
#include "sw.h"
#include "fal_port_ctrl.h"
#include "hsl_api.h"
@@ -2708,6 +2710,15 @@ malibu_phy_hw_init(a_uint32_t dev_id, a_
led_status |= MALIBU_LED_1000_CTRL1_100_10_MASK;
malibu_phy_mmd_write(dev_id, phy_addr, MALIBU_PHY_MMD7_NUM,
MALIBU_PHY_MMD7_LED_1000_CTRL1, led_status);
+ if (of_machine_is_compatible("xiaomi,ax9000")) {
+ /* add 1000M link LED behavior for Xiaomi AX9000 */
+ led_status = malibu_phy_mmd_read(dev_id, phy_addr, MALIBU_PHY_MMD7_NUM,
+ MALIBU_PHY_MMD7_LED_100_CTRL1);
+ led_status &= ~MALIBU_LED_100_CTRL1_1000_MASK;
+ led_status |= MALIBU_LED_100_CTRL1_1000_MASK;
+ malibu_phy_mmd_write(dev_id, phy_addr, MALIBU_PHY_MMD7_NUM,
+ MALIBU_PHY_MMD7_LED_100_CTRL1, led_status);
+ }
/*disable Extended next page*/
phy_data = malibu_phy_reg_read(dev_id, phy_addr, MALIBU_AUTONEG_ADVERT);
phy_data &= ~MALIBU_EXTENDED_NEXT_PAGE_EN;

View File

@ -0,0 +1,29 @@
From bad774f43ec253e7e743e23bde87444c9d9cefdc Mon Sep 17 00:00:00 2001
From: Robert Marko <robimarko@gmail.com>
Date: Wed, 26 Jan 2022 14:47:33 +0100
Subject: [PATCH 08/11] qca807x: add a LED quirk for Xiaomi AX3600
AX3600 requires the same LED quirk so that PHY LED-s will blink even
once Linux resets the PHY.
So, just check for its compatible.
Signed-off-by: Robert Marko <robimarko@gmail.com>
---
src/hsl/phy/malibu_phy.c | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
--- a/src/hsl/phy/malibu_phy.c
+++ b/src/hsl/phy/malibu_phy.c
@@ -2710,8 +2710,9 @@ malibu_phy_hw_init(a_uint32_t dev_id, a_
led_status |= MALIBU_LED_1000_CTRL1_100_10_MASK;
malibu_phy_mmd_write(dev_id, phy_addr, MALIBU_PHY_MMD7_NUM,
MALIBU_PHY_MMD7_LED_1000_CTRL1, led_status);
- if (of_machine_is_compatible("xiaomi,ax9000")) {
- /* add 1000M link LED behavior for Xiaomi AX9000 */
+ /* add 1000M link LED behavior for Xiaomi boards */
+ if (of_machine_is_compatible("xiaomi,ax9000") ||
+ of_machine_is_compatible("xiaomi,ax3600")) {
led_status = malibu_phy_mmd_read(dev_id, phy_addr, MALIBU_PHY_MMD7_NUM,
MALIBU_PHY_MMD7_LED_100_CTRL1);
led_status &= ~MALIBU_LED_100_CTRL1_1000_MASK;

View File

@ -0,0 +1,22 @@
From be352dd54d163c005611906ac6b87692c9b8a1e6 Mon Sep 17 00:00:00 2001
From: Ansuel Smith <ansuelsmth@gmail.com>
Date: Sat, 7 May 2022 19:03:55 +0200
Subject: [PATCH 09/11] include: fix compilation error for parse_uci_option
Fix missing include for parse_uci_option
Signed-off-by: Ansuel Smith <ansuelsmth@gmail.com>
---
include/ref/ref_uci.h | 1 +
1 file changed, 1 insertion(+)
--- a/include/ref/ref_uci.h
+++ b/include/ref/ref_uci.h
@@ -22,6 +22,7 @@
extern "C" {
#endif /* __cplusplus */
+#include <linux/switch.h>
#if defined(IN_SWCONFIG)
int

View File

@ -0,0 +1,30 @@
From ecd1e0c57fdf7f8916fa20f085e08bb4b6ba0396 Mon Sep 17 00:00:00 2001
From: Alexandru Gagniuc <mr.nuke.me@gmail.com>
Date: Fri, 23 Sep 2022 08:21:13 -0500
Subject: [PATCH 10/11] QSDK: config: Avoid -Werror heroics
Trying to compile the QSDK with warnings as errors is a very brave
endeavor. It's also stupid as it doesn't work on ipq60xx:
isisc_acl_prv.h:99: error: "FIELD_GET" redefined [-Werror]
99 | #define FIELD_GET(reg, field, val) \
|
Instead of dealing with the braindead code, just disable Werror.
Signed-off-by: Alexandru Gagniuc <mr.nuke.me@gmail.com>
---
config | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
--- a/config
+++ b/config
@@ -141,7 +141,7 @@ endif
ifeq ($(ARCH), arm64)
ifeq ($(KVER),$(filter 4.1% 4.4% 4.9% 5.4% 5.10% 5.15%,$(KVER)))
- CPU_CFLAG= -DMODULE -Os -pipe -march=armv8-a -mcpu=cortex-a53+crypto -fno-caller-saves -fno-strict-aliasing -Werror -fno-common -Wno-format-security -Wno-pointer-sign -Wno-unused-but-set-variable -Wno-error=unused-result -mcmodel=large
+ CPU_CFLAG= -DMODULE -Os -pipe -march=armv8-a -mcpu=cortex-a53+crypto -fno-caller-saves -fno-strict-aliasing -fno-common -Wno-format-security -Wno-pointer-sign -Wno-unused-but-set-variable -Wno-error=unused-result -mcmodel=large
endif
endif

View File

@ -0,0 +1,48 @@
From c06e6edfb740d0ba0b804fa16d6222e257349089 Mon Sep 17 00:00:00 2001
From: Alexandru Gagniuc <mr.nuke.me@gmail.com>
Date: Fri, 23 Sep 2022 08:30:03 -0500
Subject: [PATCH 11/11] Revert "qca-ssdk: remove bridge fdb entry for the
authentication failed mac"
This change causes an undefined reference to "br_fdb_delete_by_netdev".
This reverts commit 144f02b982c8c707aaf84b57d8c277d03d877236.
Signed-off-by: Alexandru Gagniuc <mr.nuke.me@gmail.com>
---
src/ref/ref_acl.c | 11 -----------
1 file changed, 11 deletions(-)
--- a/src/ref/ref_acl.c
+++ b/src/ref/ref_acl.c
@@ -23,7 +23,6 @@
#include "ssdk_init.h"
#include "ssdk_plat.h"
#include <linux/etherdevice.h>
-#include <linux/if_bridge.h>
/* entry 0-1 is for global deny all and accept eapol rule
entry 2-9 is for phy port1 specific mac accept rule
@@ -128,7 +127,6 @@ _ref_acl_mac_entry_create_rule(a_uint32_
{
sw_error_t rv = SW_OK;
fal_acl_rule_t rule = {0};
- struct net_device *eth_dev = NULL;
a_uint32_t port_id = ssdk_ifname_to_port(dev_id, entry->ifname);
SSDK_DEBUG("port_id %d entry_idx %d\n", port_id, entry_idx);
@@ -224,15 +222,6 @@ _ref_acl_mac_entry_create_rule(a_uint32_
ref_acl_mac_entry[dev_id][entry_idx].port_map = BIT(port_id);
ref_acl_mac_entry[dev_id][entry_idx].acl_policy = 1;
}
- else if (!is_deny_all_mac(entry->src_mac.uc) && !entry->acl_policy)
- {
- eth_dev = dev_get_by_name(&init_net, entry->ifname);
- if (eth_dev)
- {
- br_fdb_delete_by_netdev(eth_dev, entry->src_mac.uc, 0);
- dev_put(eth_dev);
- }
- }
return rv;
}

View File

@ -0,0 +1,92 @@
# Copyright (C) 2010 OpenWrt.org
# Copyright (C) 2015-2016 Lantiq Beteiligungs GmbH & Co KG.
#
# This is free software, licensed under the GNU General Public License v2.
# See /LICENSE for more information.
include $(TOPDIR)/rules.mk
include $(INCLUDE_DIR)/kernel.mk
PKG_NAME:=ltq-vdsl-vr11-app
PKG_VERSION:=4.23.1
PKG_RELEASE:=1
PKG_BASE_NAME:=dsl_cpe_control
UGW_VERSION=8.5.2.10
UGW_BASENAME=$(PKG_BASE_NAME)-ugw_$(UGW_VERSION)
PKG_SOURCE:=$(UGW_BASENAME).tar.bz2
PKG_SOURCE_URL:=https://gitlab.com/prpl-foundation/intel/$(PKG_BASE_NAME)/-/archive/ugw_$(UGW_VERSION)/
PKG_HASH:=d21ec74ca30f7f3893a8aa26d2b74ec319652f6b112832efab6f1274c7e5d1fc
PKG_BUILD_DIR:=$(BUILD_DIR)/$(UGW_BASENAME)
PKG_LICENSE:=BSD-2-Clause
PKG_LICENSE_FILES:=LICENSE
PKG_BUILD_DEPENDS:=ltq-vdsl-vr11
PKG_FLAGS:=nonshared
PKG_FIXUP:=autoreconf
include $(INCLUDE_DIR)/package.mk
define Package/ltq-vdsl-vr11-app
SECTION:=net
CATEGORY:=Network
TITLE:=Lantiq VDSL userland tool
URL:=http://www.lantiq.com/
DEPENDS:=@TARGET_ipq40xx +libpthread +librt +libubox +libubus +ltq-dsl-base +kmod-ltq-vdsl-vr11
PROVIDES:=ltq-dsl-app
endef
define Package/ltq-vdsl-vr11-app/description
Userland tool needed to control Lantiq VDSL CPE
endef
# ltq-vdsl-vr11-app uses a header provided by the MEI driver which has some
# conditionals.
#
# Define them here with the default values they would get in the MEI driver,
# have the same view on both sides.
#
# If you change them, you need to change them for the ltq-vdsl-vr11-app as well
VDSL_APP_CFLAGS = \
-DMAX_CLI_PIPES=1 \
-DMEI_SUPPORT_DEBUG_STREAMS=1 \
-DMEI_SUPPORT_OPTIMIZED_FW_DL=1
CONFIGURE_ARGS += \
--enable-debug-logger-support=no
CONFIGURE_ARGS += \
--enable-vrx \
--enable-vrx-device=vr11 \
--enable-driver-include="-I$(STAGING_DIR)/usr/include/drv_vdsl_cpe_api" \
--enable-device-driver-include="-I$(STAGING_DIR)/usr/include/vdsl/" \
--enable-ifxos \
--enable-ifxos-include="-I$(STAGING_DIR)/usr/include/ifxos" \
--enable-ifxos-library="-I$(STAGING_DIR)/usr/lib" \
--enable-add-appl-cflags="$(VDSL_APP_CFLAGS)" \
--enable-debug \
--disable-dti
CONFIGURE_ARGS += \
--enable-model=full \
--enable-dsl-ceoc=no
#CONFIGURE_ARGS += --enable-model=lite
#CONFIGURE_ARGS += --enable-model=footprint
#CONFIGURE_ARGS += --enable-model=typical
#CONFIGURE_ARGS += --enable-model=debug
define Build/Prepare
$(call Build/Prepare/Default)
$(CP) ../ltq-vdsl-vr9-app/src/src/dsl_cpe_ubus.c $(PKG_BUILD_DIR)/src/
endef
define Package/ltq-vdsl-vr11-app/install
$(INSTALL_DIR) $(1)/etc/init.d $(1)/sbin $(1)/etc/hotplug.d/dsl
$(INSTALL_BIN) ./files/dsl_control $(1)/etc/init.d/
$(INSTALL_BIN) $(PKG_BUILD_DIR)/src/dsl_cpe_control $(1)/sbin/vdsl_cpe_control
$(INSTALL_BIN) ./files/dsl_cpe_pipe.sh $(1)/sbin/
endef
$(eval $(call BuildPackage,ltq-vdsl-vr11-app))

View File

@ -0,0 +1,264 @@
#!/bin/sh /etc/rc.common
# Copyright (C) 2012 OpenWrt.org
START=97
USE_PROCD=1
dslstat() {
ubus call dsl metrics
}
extra_command "dslstat" "Get DSL status information"
#
# ITU-T G.997.1 (06/2012) - Section 7.3.1.1.1 (xTU transmission system enabling (XTSE))
# ITU-T G.997.1 Amendment 2 (04/2013) - Section 2.1 - (Vectoring mode enable (VECTORMODE_ENABLE))
#
# G.992.1 Annex A
# G.992.2 Annex A
# G.992.3 Annex A / L-US1 / L_US-2 / M
# G.992.5 Annex A / M
# G.993.2 Annex A/B/C
# G.993.5 Annex A/B/C
xtse_xdsl_a="05_01_04_00_4C_01_04_07"
# G.992.1 Annex B
# G.992.3 Annex B
# G.992.5 Annex B
# G.993.2 Annex A/B/C
# G.993.5 Annex A/B/C
xtse_xdsl_b="10_00_10_00_00_04_00_07"
# G.992.1 Annex B
# G.992.3 Annex B
# G.992.3 Annex J
# G.992.5 Annex B
# G.992.5 Annex J
# G.993.2 Annex A/B/C
# G.993.5 Annex A/B/C
xtse_xdsl_j="10_00_10_40_00_04_01_07"
# G.992.1 Annex B
xtse_xdsl_bdmt="10_00_00_00_00_00_00_00"
# G.992.3 Annex B
xtse_xdsl_b2="00_00_10_00_00_00_00_00"
# G.992.5 Annex B
xtse_xdsl_b2p="00_00_00_00_00_04_00_00"
# ANSI T1.413
xtse_xdsl_at1="01_00_00_00_00_00_00_00"
# G.992.2 Annex A
xtse_xdsl_alite="00_01_00_00_00_00_00_00"
# G.992.1 Annex A
xtse_xdsl_admt="04_00_00_00_00_00_00_00"
# G.992.3 Annex A
xtse_xdsl_a2="00_00_04_00_00_00_00_00"
# G.992.5 Annex A
xtse_xdsl_a2p="00_00_00_00_00_01_00_00"
# G.992.3 Annex L
xtse_xdsl_l="00_00_00_00_0C_00_00_00"
# G.992.3 Annex M
# G.992.5 Annex M
xtse_xdsl_m="00_00_00_00_40_00_04_00"
# G.992.3 Annex M
xtse_xdsl_m2="00_00_00_00_40_00_00_00"
# G.992.5 Annex M
xtse_xdsl_m2p="00_00_00_00_00_00_04_00"
#
# ITU-T G.994.1 (06/2012) - Table 2 (Mandatory carrier sets)
#
# A43
tone_adsl_a="0x142" # A43C + J43 + A43
tone_vdsl_a="0x142" # A43C + J43 + A43
# A43 + V43
tone_adsl_av="0x142" # A43C + J43 + A43
tone_vdsl_av="0x146" # A43C + J43 + A43 + V43
# B43
tone_adsl_b="0x81" # B43 + B43c
tone_vdsl_b="0x1" # B43
# B43 + V43
tone_adsl_bv="0x81" # B43 + B43c
tone_vdsl_bv="0x5" # B43 + V43
# create DSL autoboot script. Used for SNR margin tweak and to set MAC address for vectoring error reports
autoboot_script() {
echo "[WaitForConfiguration]={
locs nLine=0 0 $1
dsmmcs nLine=0 $2
}
[WaitForLinkActivate]={
}
[WaitForRestart]={
}
[Common]={
}" > /tmp/dsl.scr
}
lowlevel_cfg() {
echo "# VRX Low Level Configuration File
#
# Parameters must be separated by tabs or spaces.
# Empty lines and comments will be ignored.
#
# nFilter
#
# NA = -1
# OFF = 0
# ISDN = 1
# POTS = 2
# POTS_2 = 3
# POTS_3 = 4
#
# (dec)
-1
# nHsToneGroupMode nHsToneGroup_A nHsToneGroup_V nHsToneGroup_AV
#
# NA = -1 NA = -1 see see
# AUTO = 0 VDSL2_B43 = 0x0001 nHsToneGroup_A nHsToneGroup_A
# MANUAL = 1 VDSL2_A43 = 0x0002
# VDSL2_V43 = 0x0004
# VDSL1_V43P = 0x0008
# VDSL1_V43I = 0x0010
# ADSL1_C43 = 0x0020
# ADSL2_J43 = 0x0040
# ADSL2_B43C = 0x0080
# ADSL2_A43C = 0x0100
#
# (dec) (hex) (hex) (hex)
1 $1 $2 0x0
# nBaseAddr nIrqNum
#
# (hex) (dec)
0x1e116000 63
# nUtopiaPhyAdr nUtopiaBusWidth nPosPhyParity
# default(16b) = 0 NA = -1
# 8-bit = 1 ODD = 0
# 16-bit = 2
#
#
# (hex) (dec) (dec)
0xFF 0 0
# bNtrEnable
#
# (dec)
0" > /tmp/lowlevel.cfg
}
get_macaddr() {
local name
config_get name $1 name
[ "$name" = "dsl0" ] && config_get $2 $1 macaddr
}
service_triggers() {
procd_add_reload_trigger network
}
start_service() {
local annex
local firmware
local tone
local tone_adsl
local tone_vdsl
local xtse
local xfer_mode
local line_mode
local tc_layer
local mode
local lowlevel
local snr
local macaddr
config_load network
config_get tone dsl tone
config_get annex dsl annex
config_get firmware dsl firmware
config_get xfer_mode dsl xfer_mode
config_get line_mode dsl line_mode
config_get snr dsl ds_snr_offset
config_foreach get_macaddr device macaddr
eval "xtse=\"\${xtse_xdsl_$annex}\""
case "${xfer_mode}" in
atm)
tc_layer="-T1:0x1:0x1_1:0x1:0x1"
;;
ptm)
tc_layer="-T2:0x1:0x1_2:0x1:0x1"
;;
esac
case "${line_mode}" in
adsl)
mode="-M1"
# mask out VDSL bits when ADSL is requested
xtse="${xtse%_*}_00"
;;
vdsl)
mode="-M2"
# mask out ADSL bits when VDSL is requested
xtse="00_00_00_00_00_00_00_${xtse##*_}"
;;
esac
[ -z "${firmware}" ] && firmware=/lib/firmware/vdsl.bin
[ -f "${firmware}" ] || {
echo failed to find $firmware
return 1
}
eval "tone_adsl=\"\${tone_adsl_$tone}\""
eval "tone_vdsl=\"\${tone_vdsl_$tone}\""
[ -n "${tone_adsl}" ] && [ -n "${tone_vdsl}" ] && {
lowlevel_cfg "${tone_adsl}" "${tone_vdsl}"
lowlevel="-l /tmp/lowlevel.cfg"
}
[ -z "${snr}" ] && snr=0
[ -z "${macaddr}" ] && macaddr="00:00:00:00:00:00"
autoboot_script "$snr" "$macaddr"
autoboot="-a /tmp/dsl.scr -A /tmp/dsl.scr"
procd_open_instance
procd_set_param command /sbin/vdsl_cpe_control \
-i$xtse \
-n /sbin/dsl_notify.sh \
-f ${firmware} \
$lowlevel \
${mode} \
${tc_layer} \
$autoboot
procd_close_instance
}
stop_service() {
DSL_NOTIFICATION_TYPE="DSL_INTERFACE_STATUS" \
DSL_INTERFACE_STATUS="DOWN" \
/sbin/dsl_notify.sh
}

View File

@ -0,0 +1,18 @@
#!/bin/sh
pipe_no=0
# use specified pipe no
case "$1" in
0|1|2)
pipe_no=$1; shift; ;;
esac
#echo "Call dsl_pipe with $*"
lock /var/lock/dsl_pipe
echo $* > /tmp/pipe/dsl_cpe${pipe_no}_cmd
result=$(cat /tmp/pipe/dsl_cpe${pipe_no}_ack)
lock -u /var/lock/dsl_pipe
echo "$result"

View File

@ -0,0 +1,11 @@
--- a/src/dsl_cpe_init_cfg.c
+++ b/src/dsl_cpe_init_cfg.c
@@ -38,7 +38,7 @@ DSL_InitData_t gInitCfgData =
DSL_DEV_HS_TONE_GROUP_CLEANED, \
DSL_DEV_HS_TONE_GROUP_CLEANED, \
DSL_DEV_HS_TONE_GROUP_CLEANED, \
- 0x1E116000, 0x37, -1),
+ 0x1E116000, 0x3f, -1),
DSL_CPE_SIC_SET(DSL_TC_ATM, DSL_EMF_TC_CLEANED, DSL_EMF_TC_CLEANED, DSL_SYSTEMIF_MII, \
DSL_TC_EFM, DSL_EMF_TC_CLEANED, DSL_EMF_TC_CLEANED, DSL_SYSTEMIF_MII),
DSL_CPE_MAC_CFG_SET(DSL_EFM_SPEED_100, DSL_EFM_DUPLEX_FULL, DSL_EFM_FLOWCTRL_ON, DSL_EFM_AUTONEG_OFF, \

View File

@ -0,0 +1,87 @@
--- a/src/dsl_cpe_control.h
+++ b/src/dsl_cpe_control.h
@@ -13,6 +13,8 @@
#ifndef _DSL_CPE_CONTROL_H
#define _DSL_CPE_CONTROL_H
+#include <string.h>
+
/** \defgroup DSL_CPE_CONTROL Lantiq DSL CPE API Control Application
Lists the entire modules to the DSL CPE_API Control Application.
@{ */
--- a/src/dsl_cpe_safec_wrapper.h
+++ b/src/dsl_cpe_safec_wrapper.h
@@ -23,7 +23,7 @@
#define cpe_control_vsnprintf_s vsnprintf_s
/* snprintf_s symbol is not exported in SafeC lib */
-static int cpe_control_snprintf_s(char *dest,
+static inline int cpe_control_snprintf_s(char *dest,
size_t dmax,
const char *fmt,
...)
@@ -40,7 +40,7 @@ static int cpe_control_snprintf_s(char *
#else
-#warning "Safe C library is not available!"
+//#warning "Safe C library is not available!"
#include <stddef.h> /* size_t */
#include <stdarg.h> /* va_list */
@@ -55,7 +55,7 @@ static __inline__ size_t safec_wrapper_m
#define cpe_control_memset_s(dest, destsz, src, srcsz) memset(dest, src, safec_wrapper_min(destsz,srcsz))
#define cpe_control_strncpy_s(dest, destsz, src, srcsz) strncpy(dest, src, safec_wrapper_min(destsz,srcsz))
-static size_t cpe_control_strnlen_s(const char *str,
+static inline size_t cpe_control_strnlen_s(const char *str,
size_t smax)
{
/* preconditions */
@@ -74,7 +74,7 @@ static size_t cpe_control_strnlen_s(cons
return size;
}
-static char *cpe_control_strtok_s(char *dest,
+static inline char *cpe_control_strtok_s(char *dest,
size_t *dmax,
const char *delim,
char **ptr)
@@ -123,7 +123,7 @@ static char *cpe_control_strtok_s(char *
return pTmp;
}
-static int cpe_control_pipe_strcat_s(char *dest,
+static inline int cpe_control_pipe_strcat_s(char *dest,
size_t destsz,
char *src)
{
@@ -157,7 +157,7 @@ static int cpe_control_pipe_strcat_s(cha
return 0;
}
-static int cpe_control_snprintf_s(char *dest,
+static inline int cpe_control_snprintf_s(char *dest,
size_t dmax,
const char *fmt,
...)
@@ -181,7 +181,7 @@ static int cpe_control_snprintf_s(char *
return retVal;
}
-static int cpe_control_vsnprintf_s(char *dest,
+static inline int cpe_control_vsnprintf_s(char *dest,
size_t dmax,
const char *fmt,
va_list vlist)
--- a/tools/pipe/dsl_cpe_safec_wrapper.h
+++ b/tools/pipe/dsl_cpe_safec_wrapper.h
@@ -27,7 +27,7 @@
#else
-#warning "Safe C library is not available!"
+//#warning "Safe C library is not available!"
#include <stddef.h> /* size_t */
static __inline__ size_t safec_wrapper_min(size_t a, size_t b)

View File

@ -0,0 +1,85 @@
This enables automatic connection after the control daemon is started,
and also changes the way the connection is stopped on termination.
Using the autoboot restart command is necessary because the stop command
would stop the autoboot thread, and the driver offers no working way to
start it again later, short of unloading and reloading the module.
--- a/src/dsl_cpe_init_cfg.c
+++ b/src/dsl_cpe_init_cfg.c
@@ -27,7 +27,7 @@ DSL_InitData_t gInitCfgData =
DSL_CPE_FW2_SET(DSL_NULL, 0x0),
DSL_CPE_XTU_SET(0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x7),
DSL_CPE_LINE_INV_NE_SET(DSL_NULL),
- DSL_CPE_AUTOBOOT_CTRL_SET(DSL_AUTOBOOT_CTRL_STOP),
+ DSL_CPE_AUTOBOOT_CTRL_SET(DSL_AUTOBOOT_CTRL_START),
DSL_CPE_AUTOBOOT_CFG_SET(DSL_FALSE, DSL_FALSE, DSL_FALSE),
DSL_CPE_TEST_MODE_CTRL_SET(DSL_TESTMODE_DISABLE),
DSL_CPE_LINE_ACTIVATE_CTRL_SET(DSL_G997_INHIBIT_LDSF, DSL_G997_INHIBIT_ACSF, DSL_G997_NORMAL_STARTUP),
--- a/src/dsl_cpe_control.c
+++ b/src/dsl_cpe_control.c
@@ -7338,6 +7338,7 @@ DSL_CPE_STATIC DSL_void_t DSL_CPE_Termi
{
DSL_Error_t nRet = DSL_SUCCESS;
DSL_int_t nDevice = 0;
+ DSL_AutobootConfig_t sAutobootCfg;
DSL_AutobootControl_t sAutobootCtl;
DSL_CPE_Control_Context_t *pCtrlCtx = DSL_NULL;
@@ -7349,8 +7350,32 @@ DSL_CPE_STATIC DSL_void_t DSL_CPE_Termi
for (nDevice = 0; nDevice < DSL_CPE_DSL_ENTITIES; ++nDevice)
{
+ g_bWaitBeforeConfigWrite[nDevice] = DSL_TRUE;
+ g_bWaitBeforeLinkActivation[nDevice] = DSL_TRUE;
+ g_bWaitBeforeRestart[nDevice] = DSL_TRUE;
+
+ g_bAutoContinueWaitBeforeConfigWrite[nDevice] = DSL_FALSE;
+ g_bAutoContinueWaitBeforeLinkActivation[nDevice] = DSL_FALSE;
+ g_bAutoContinueWaitBeforeRestart[nDevice] = DSL_FALSE;
+
+ memset(&sAutobootCfg, 0x0, sizeof(DSL_AutobootConfig_t));
+ sAutobootCfg.data.nStateMachineOptions.bWaitBeforeConfigWrite = DSL_TRUE;
+ sAutobootCfg.data.nStateMachineOptions.bWaitBeforeLinkActivation = DSL_TRUE;
+ sAutobootCfg.data.nStateMachineOptions.bWaitBeforeRestart = DSL_TRUE;
+
+ nRet = (DSL_Error_t)DSL_CPE_Ioctl(
+ DSL_CPE_GetGlobalContext()->fd[nDevice],
+ DSL_FIO_AUTOBOOT_CONFIG_SET, (DSL_int_t)&sAutobootCfg);
+
+ if (nRet < DSL_SUCCESS)
+ {
+ DSL_CCA_DEBUG(DSL_CCA_DBG_ERR, (DSL_CPE_PREFIX
+ "Autoboot configuration for device (%d) failed!, nRet = %d!"
+ DSL_CPE_CRLF, nDevice, sAutobootCtl.accessCtl.nReturn));
+ }
+
memset(&sAutobootCtl, 0, sizeof(DSL_AutobootControl_t));
- sAutobootCtl.data.nCommand = DSL_AUTOBOOT_CTRL_STOP;
+ sAutobootCtl.data.nCommand = DSL_AUTOBOOT_CTRL_RESTART;
nRet = (DSL_Error_t)DSL_CPE_Ioctl(
DSL_CPE_GetGlobalContext()->fd[nDevice],
@@ -7359,13 +7384,13 @@ DSL_CPE_STATIC DSL_void_t DSL_CPE_Termi
if (nRet < DSL_SUCCESS)
{
DSL_CCA_DEBUG(DSL_CCA_DBG_ERR, (DSL_CPE_PREFIX
- "Autoboot stop for device (%d) failed!, nRet = %d!"
+ "Autoboot restart for device (%d) failed!, nRet = %d!"
DSL_CPE_CRLF, nDevice, sAutobootCtl.accessCtl.nReturn));
}
}
DSL_CCA_DEBUG(DSL_CCA_DBG_MSG, (DSL_CPE_PREFIX
- "Autoboot stop executed" DSL_CPE_CRLF));
+ "Autoboot restart executed" DSL_CPE_CRLF));
DSL_CPE_DaemonExit();
@@ -8798,4 +8823,4 @@ DSL_CPE_STATIC DSL_Error_t DSL_CPE_Firmw
pDecimal));
return nErrCode;
-}
\ No newline at end of file
+}

View File

@ -0,0 +1,50 @@
--- a/src/dsl_cpe_control.c
+++ b/src/dsl_cpe_control.c
@@ -221,6 +221,9 @@ extern DSL_Error_t DSL_CPE_Pipe_StaticRe
#endif /* INCLUDE_DSL_RESOURCE_STATISTICS*/
#endif
+extern void ubus_init();
+extern void ubus_deinit();
+
DSL_char_t *g_sFirmwareName1 = DSL_NULL;
DSL_FirmwareFeatures_t g_nFwFeatures1 = {DSL_FW_XDSLMODE_CLEANED, DSL_FW_XDSLFEATURE_CLEANED,
DSL_FW_XDSLFEATURE_CLEANED};
@@ -7831,6 +7834,8 @@ DSL_int_t dsl_cpe_daemon (
#endif /* defined(INCLUDE_DSL_JSON_PARSING) && (INCLUDE_DSL_JSON_PARSING == 1) */
#endif /* RTEMS*/
+ ubus_init();
+
/* Open DSL_CPE_MAX_DSL_ENTITIES devices*/
for (nDevice = 0; nDevice < DSL_CPE_DSL_ENTITIES; nDevice++)
{
@@ -8367,6 +8372,7 @@ DSL_int_t dsl_cpe_daemon (
#endif /* INCLUDE_DSL_CPE_CLI_SUPPORT */
DSL_CPE_CONTROL_EXIT:
+ ubus_deinit();
if (INCLUDE_DSL_BONDING)
{
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -17,7 +17,7 @@ else
dsl_cpe_control_common_ldflags =
endif
-dsl_cpe_control_LDADD = -lpthread -lrt
+dsl_cpe_control_LDADD = -lpthread -lrt -lubox -lubus
if INCLUDE_DSL_CPE_DTI_SUPPORT
dsl_cpe_control_LDADD += -ldti_agent
@@ -118,7 +118,8 @@ dsl_cpe_control_SOURCES = \
dsl_cpe_control.c \
dsl_cpe_init_cfg.c \
dsl_cpe_linux.c \
- dsl_cpe_debug.c
+ dsl_cpe_debug.c \
+ dsl_cpe_ubus.c
dsl_cpe_control_SOURCES += \
$(dsl_cpe_control_dti_sources)

View File

@ -17,7 +17,7 @@ define Package/ltq-dsl-base
CATEGORY:=Network
TITLE:=DSL related files for Intel/Lantiq DSL Chipsets
URL:=http://openwrt.org/
DEPENDS:=@TARGET_lantiq +jshn
DEPENDS:=@(TARGET_lantiq||TARGET_ipq40xx) +jshn
endef
define Package/ltq-dsl-base/description

View File

@ -8,13 +8,13 @@
include $(TOPDIR)/rules.mk
PKG_NAME:=procd
PKG_RELEASE:=$(AUTORELEASE)
PKG_RELEASE:=1
PKG_SOURCE_PROTO:=git
PKG_SOURCE_URL=$(PROJECT_GIT)/project/procd.git
PKG_MIRROR_HASH:=d60b4aa9d47d75e906dfd812528a1bc28e91f5af72a9d9275056b71b19d99f04
PKG_SOURCE_DATE:=2022-11-10
PKG_SOURCE_VERSION:=039b88f75367203e540009cc97603b1bce3fafa6
PKG_MIRROR_HASH:=75a92c01ef85f41dc7e0b77ac35f464fbe45942af02ca6847516c4ebf574c4a4
PKG_SOURCE_DATE:=2023-01-16
PKG_SOURCE_VERSION:=190f13a75e67e0bdb662188da79b8be31e0aae01
CMAKE_INSTALL:=1
PKG_LICENSE:=GPL-2.0

View File

@ -8,10 +8,10 @@ ARCH:=arc
CPU_TYPE:=archs
BOARD:=archs38
BOARDNAME:=Synopsys DesignWare ARC HS38
FEATURES:=source-only
SUBTARGETS:=generic
KERNEL_PATCHVER:=5.10
KERNEL_TESTING_PATCHVER:=5.15
KERNEL_PATCHVER:=5.15
DEVICE_TYPE:=basic

View File

@ -897,6 +897,7 @@ CONFIG_CC_OPTIMIZE_FOR_PERFORMANCE=y
# CONFIG_CHARGER_LTC4162L is not set
# CONFIG_CHARGER_MANAGER is not set
# CONFIG_CHARGER_MAX8903 is not set
# CONFIG_CHARGER_QCOM_SMBB is not set
# CONFIG_CHARGER_RT9455 is not set
# CONFIG_CHARGER_SBS is not set
# CONFIG_CHARGER_SMB347 is not set
@ -2726,6 +2727,8 @@ CONFIG_INPUT_MISC=y
# CONFIG_INPUT_PALMAS_PWRBUTTON is not set
# CONFIG_INPUT_PCF8574 is not set
# CONFIG_INPUT_PCSPKR is not set
# CONFIG_INPUT_PM8941_PWRKEY is not set
# CONFIG_INPUT_PM8XXX_VIBRATOR is not set
# CONFIG_INPUT_POLLDEV is not set
# CONFIG_INPUT_POWERMATE is not set
# CONFIG_INPUT_PWM_BEEPER is not set

Some files were not shown because too many files have changed in this diff Show More