Merge Official Source

Signed-off-by: Tianling Shen <cnsztl@immortalwrt.org>
This commit is contained in:
Tianling Shen 2023-04-30 09:39:22 +08:00
commit 509f51b342
No known key found for this signature in database
GPG Key ID: 6850B6345C862176
84 changed files with 874 additions and 4404 deletions

View File

@ -126,6 +126,13 @@ define Build/append-string
echo -n $(1) >> $@
endef
define Build/append-md5sum-ascii-salted
cp $@ $@.salted
echo -ne $(1) >> $@.salted
$(STAGING_DIR_HOST)/bin/mkhash md5 $@.salted | head -c32 >> $@
rm $@.salted
endef
define Build/append-ubi
sh $(TOPDIR)/scripts/ubinize-image.sh \
$(if $(UBOOTENV_IN_UBI),--uboot-env) \

View File

@ -1,2 +1,2 @@
LINUX_VERSION-5.10 = .178
LINUX_KERNEL_HASH-5.10.178 = 1acfade3715e560f00fb30615d5471e24b3940b549381558787aee9734e7a8af
LINUX_VERSION-5.10 = .179
LINUX_KERNEL_HASH-5.10.179 = 1bbd445c154b053eea46acc883be548a98179988a9ed3a0b81bddfbf30a37e29

View File

@ -1,2 +1,2 @@
LINUX_VERSION-5.15 = .108
LINUX_KERNEL_HASH-5.15.108 = 8beb69ada46f1cbca2f4cf901ec078846035c1cd925d9471422f65aff74243ba
LINUX_VERSION-5.15 = .109
LINUX_KERNEL_HASH-5.15.109 = 066c4bbcbe3c480068a2e302f52b1708f340ecaaf633ec43d7f791bbeac5771a

View File

@ -62,7 +62,8 @@ h3c,tx1801-plus|\
h3c,tx1806|\
jcg,q20|\
linksys,e7350|\
netgear,wax202)
netgear,wax202|\
zyxel,wsm20)
ubootenv_add_uci_config "/dev/mtd1" "0x0" "0x20000" "0x20000"
;;
haier,har-20s2u1|\

View File

@ -827,7 +827,9 @@ $(eval $(call KernelPackage,crypto-rmd160))
define KernelPackage/crypto-rng
TITLE:=CryptoAPI random number generation
DEPENDS:=+kmod-crypto-hash +kmod-crypto-hmac +kmod-crypto-sha256
DEPENDS:=+kmod-crypto-hash +kmod-crypto-hmac \
+LINUX_5_10:kmod-crypto-sha256 \
+LINUX_5_15:kmod-crypto-sha512
KCONFIG:= \
CONFIG_CRYPTO_DRBG \
CONFIG_CRYPTO_DRBG_HMAC=y \

View File

@ -9,7 +9,7 @@ include $(TOPDIR)/rules.mk
PKG_NAME:=openssl
PKG_VERSION:=3.0.8
PKG_RELEASE:=8
PKG_RELEASE:=9
PKG_BUILD_FLAGS:=no-mips16 gc-sections
PKG_BUILD_PARALLEL:=1

View File

@ -0,0 +1,39 @@
From 02ac9c9420275868472f33b01def01218742b8bb Mon Sep 17 00:00:00 2001
From: Tomas Mraz <tomas@openssl.org>
Date: Mon, 17 Apr 2023 16:51:20 +0200
Subject: [PATCH] aesv8-armx.pl: Avoid buffer overrread in AES-XTS decryption
Original author: Nevine Ebeid (Amazon)
Fixes: CVE-2023-1255
The buffer overread happens on decrypts of 4 mod 5 sizes.
Unless the memory just after the buffer is unmapped this is harmless.
Reviewed-by: Paul Dale <pauli@openssl.org>
Reviewed-by: Tom Cosgrove <tom.cosgrove@arm.com>
(Merged from https://github.com/openssl/openssl/pull/20759)
(cherry picked from commit 72dfe46550ee1f1bbfacd49f071419365bc23304)
diff --git a/crypto/aes/asm/aesv8-armx.pl b/crypto/aes/asm/aesv8-armx.pl
index 6a7bf05d1b..bd583e2c89 100755
--- a/crypto/aes/asm/aesv8-armx.pl
+++ b/crypto/aes/asm/aesv8-armx.pl
@@ -3353,7 +3353,7 @@ $code.=<<___ if ($flavour =~ /64/);
.align 4
.Lxts_dec_tail4x:
add $inp,$inp,#16
- vld1.32 {$dat0},[$inp],#16
+ tst $tailcnt,#0xf
veor $tmp1,$dat1,$tmp0
vst1.8 {$tmp1},[$out],#16
veor $tmp2,$dat2,$tmp2
@@ -3362,6 +3362,8 @@ $code.=<<___ if ($flavour =~ /64/);
veor $tmp4,$dat4,$tmp4
vst1.8 {$tmp3-$tmp4},[$out],#32
+ b.eq .Lxts_dec_abort
+ vld1.32 {$dat0},[$inp],#16
b .Lxts_done
.align 4
.Lxts_outer_dec_tail:

View File

@ -19,16 +19,37 @@ proto_mbim_init_config() {
proto_config_add_string auth
proto_config_add_string username
proto_config_add_string password
[ -e /proc/sys/net/ipv6 ] && proto_config_add_string ipv6
proto_config_add_boolean dhcp
proto_config_add_boolean dhcpv6
proto_config_add_string pdptype
proto_config_add_int mtu
proto_config_add_defaults
}
_proto_mbim_get_field() {
local field="$1"
shift
local mbimconfig="$@"
echo "$mbimconfig" | while read -r line; do
variable=${line%%:*}
[ "$variable" = "$field" ] || continue;
value=${line##* }
echo -n "$value "
done
}
_proto_mbim_setup() {
local interface="$1"
local tid=2
local ret
local device apn pincode delay allow_roaming allow_partner $PROTO_DEFAULT_OPTIONS
json_get_vars device apn pincode delay auth username password allow_roaming allow_partner $PROTO_DEFAULT_OPTIONS
local device apn pincode delay auth username password allow_roaming allow_partner
local dhcp dhcpv6 pdptype ip4table ip6table mtu $PROTO_DEFAULT_OPTIONS
json_get_vars device apn pincode delay auth username password allow_roaming allow_partner
json_get_vars dhcp dhcpv6 pdptype ip4table ip6table mtu $PROTO_DEFAULT_OPTIONS
[ ! -e /proc/sys/net/ipv6 ] && ipv6=0 || json_get_var ipv6 ipv6
[ -n "$ctl_device" ] && device=$ctl_device
@ -146,35 +167,133 @@ _proto_mbim_setup() {
}
tid=$((tid + 1))
pdptype=$(echo "$pdptype" | awk '{print tolower($0)}')
[ "$ipv6" = 0 ] && pdptype="ipv4"
local req_pdptype="" # Pass "default" PDP type to umbim if unconfigured
[ "$pdptype" = "ipv4" -o "$pdptype" = "ipv6" -o "$pdptype" = "ipv4v6" ] && req_pdptype="$pdptype:"
local connect_state
echo "mbim[$$]" "Connect to network"
while ! umbim $DBG -n -t $tid -d $device connect "$apn" "$auth" "$username" "$password"; do
connect_state=$(umbim $DBG -n -t $tid -d $device connect "$req_pdptype$apn" "$auth" "$username" "$password") || {
echo "mbim[$$]" "Failed to connect bearer"
tid=$((tid + 1))
sleep 1;
done
umbim $DBG -t $tid -d "$device" disconnect
proto_notify_error "$interface" CONNECT_FAILED
return 1
}
tid=$((tid + 1))
uci_set_state network $interface tid "$tid"
echo "$connect_state"
local iptype="$(echo "$connect_state" | grep iptype: | awk '{print $4}')"
echo "mbim[$$]" "Connected"
local zone="$(fw3 -q network "$interface" 2>/dev/null)"
echo "mbim[$$]" "Setting up $ifname"
local mbimconfig="$(umbim $DBG -n -t $tid -d $device config)"
echo "$mbimconfig"
tid=$((tid + 1))
echo "mbim[$$]" "Connected, starting DHCP"
proto_init_update "$ifname" 1
proto_send_update "$interface"
json_init
json_add_string name "${interface}_4"
json_add_string ifname "@$interface"
json_add_string proto "dhcp"
proto_add_dynamic_defaults
json_close_object
ubus call network add_dynamic "$(json_dump)"
[ -z "$dhcp" ] && dhcp=1
[ -z "$dhcpv6" ] && dhcpv6=1
json_init
json_add_string name "${interface}_6"
json_add_string ifname "@$interface"
json_add_string proto "dhcpv6"
json_add_string extendprefix 1
proto_add_dynamic_defaults
json_close_object
ubus call network add_dynamic "$(json_dump)"
[ "$iptype" != "ipv6" ] && {
json_init
json_add_string name "${interface}_4"
json_add_string ifname "@$interface"
ipv4address=$(_proto_mbim_get_field ipv4address "$mbimconfig")
if [ -n "$ipv4address" ]; then
json_add_string proto "static"
json_add_array ipaddr
for address in $ipv4address; do
json_add_string "" "$address"
done
json_close_array
json_add_string gateway $(_proto_mbim_get_field ipv4gateway "$mbimconfig")
elif [ "$dhcp" != 0 ]; then
echo "mbim[$$]" "Starting DHCP on $ifname"
json_add_string proto "dhcp"
fi
[ "$peerdns" = 0 ] || {
json_add_array dns
for server in $(_proto_mbim_get_field ipv4dnsserver "$mbimconfig"); do
json_add_string "" "$server"
done
json_close_array
}
proto_add_dynamic_defaults
[ -n "$zone" ] && json_add_string zone "$zone"
[ -n "$ip4table" ] && json_add_string ip4table "$ip4table"
json_close_object
ubus call network add_dynamic "$(json_dump)"
}
[ "$iptype" != "ipv4" ] && {
json_init
json_add_string name "${interface}_6"
json_add_string ifname "@$interface"
ipv6address=$(_proto_mbim_get_field ipv6address "$mbimconfig")
if [ -n "$ipv6address" ]; then
json_add_string proto "static"
json_add_array ip6addr
for address in $ipv6address; do
json_add_string "" "$address"
done
json_close_array
json_add_array ip6prefix
for address in $ipv6address; do
json_add_string "" "$address"
done
json_close_array
json_add_string ip6gw $(_proto_mbim_get_field ipv6gateway "$mbimconfig")
elif [ "$dhcpv6" != 0 ]; then
echo "mbim[$$]" "Starting DHCPv6 on $ifname"
json_add_string proto "dhcpv6"
json_add_string extendprefix 1
fi
[ "$peerdns" = 0 ] || {
json_add_array dns
for server in $(_proto_mbim_get_field ipv6dnsserver "$mbimconfig"); do
json_add_string "" "$server"
done
json_close_array
}
proto_add_dynamic_defaults
[ -n "$zone" ] && json_add_string zone "$zone"
[ -n "$ip6table" ] && json_add_string ip6table "$ip6table"
json_close_object
ubus call network add_dynamic "$(json_dump)"
}
[ -z "$mtu" ] && {
local ipv4mtu=$(_proto_mbim_get_field ipv4mtu "$mbimconfig")
ipv4mtu="${ipv4mtu:-0}"
local ipv6mtu=$(_proto_mbim_get_field ipv6mtu "$mbimconfig")
ipv6mtu="${ipv6mtu:-0}"
mtu=$((ipv6mtu > ipv4mtu ? ipv6mtu : ipv4mtu))
}
[ -n "$mtu" -a "$mtu" != 0 ] && {
echo Setting MTU of $ifname to $mtu
/sbin/ip link set dev $ifname mtu $mtu
}
uci_set_state network $interface tid "$tid"
}
proto_mbim_setup() {

View File

@ -110,7 +110,6 @@ CONFIG_GPIO_GENERIC=y
CONFIG_GPIO_SNPS_CREG=y
CONFIG_GRACE_PERIOD=y
CONFIG_HANDLE_DOMAIN_IRQ=y
# CONFIG_HARDENED_USERCOPY is not set
CONFIG_HAS_DMA=y
CONFIG_HAS_IOMEM=y
CONFIG_HZ_PERIODIC=y

View File

@ -16,7 +16,7 @@ Submitted-by: Adrian Schmutzler <freifunk@adrianschmutzler.de>
--- a/drivers/net/phy/at803x.c
+++ b/drivers/net/phy/at803x.c
@@ -830,6 +830,13 @@ static int at803x_aneg_done(struct phy_d
@@ -959,6 +959,13 @@ static int at803x_aneg_done(struct phy_d
if (!(phy_read(phydev, AT803X_PSSR) & AT803X_PSSR_MR_AN_COMPLETE)) {
phydev_warn(phydev, "803x_aneg_done: SGMII link is not ok\n");
aneg_done = 0;

View File

@ -256,7 +256,6 @@ CONFIG_NO_HZ=y
CONFIG_NO_HZ_COMMON=y
CONFIG_NO_HZ_IDLE=y
CONFIG_NVMEM=y
CONFIG_OABI_COMPAT=y
CONFIG_OF=y
CONFIG_OF_ADDRESS=y
CONFIG_OF_CONFIGFS=y

View File

@ -320,7 +320,6 @@ CONFIG_NO_HZ_COMMON=y
CONFIG_NO_HZ_IDLE=y
CONFIG_NR_CPUS=4
CONFIG_NVMEM=y
CONFIG_OABI_COMPAT=y
CONFIG_OF=y
CONFIG_OF_ADDRESS=y
CONFIG_OF_CONFIGFS=y

View File

@ -5,7 +5,7 @@ This prevents the options from being delete with make kernel_oldconfig.
--- a/drivers/bcma/Kconfig
+++ b/drivers/bcma/Kconfig
@@ -32,6 +32,7 @@ config BCMA_HOST_PCI
@@ -36,6 +36,7 @@ config BCMA_HOST_PCI
config BCMA_HOST_SOC
bool "Support for BCMA in a SoC"
depends on HAS_IOMEM
@ -15,7 +15,7 @@ This prevents the options from being delete with make kernel_oldconfig.
the memory. This only works with the Broadcom SoCs from the
--- a/drivers/ssb/Kconfig
+++ b/drivers/ssb/Kconfig
@@ -136,6 +136,7 @@ config SSB_SFLASH
@@ -141,6 +141,7 @@ config SSB_SFLASH
config SSB_EMBEDDED
bool
depends on SSB_DRIVER_MIPS && SSB_PCICORE_HOSTMODE

View File

@ -17,7 +17,7 @@ Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
--- a/drivers/bcma/sprom.c
+++ b/drivers/bcma/sprom.c
@@ -165,7 +165,7 @@ static int bcma_sprom_valid(struct bcma_
@@ -170,7 +170,7 @@ static int bcma_sprom_valid(struct bcma_
return err;
revision = sprom[words - 1] & SSB_SPROM_REVISION_REV;

View File

@ -677,7 +677,7 @@
#if IS_ENABLED(CONFIG_NF_CONNTRACK)
#include <linux/netfilter/nf_conntrack_common.h>
#endif
@@ -786,7 +787,8 @@ struct sk_buff {
@@ -787,7 +788,8 @@ struct sk_buff {
fclone:2,
peeked:1,
head_frag:1,
@ -687,7 +687,7 @@
#ifdef CONFIG_SKB_EXTENSIONS
__u8 active_extensions;
#endif
@@ -3029,9 +3031,15 @@ static inline void skb_frag_ref(struct s
@@ -3030,9 +3032,15 @@ static inline void skb_frag_ref(struct s
*
* Releases a reference on the paged fragment @frag.
*/
@ -705,7 +705,7 @@
}
/**
@@ -3043,7 +3051,7 @@ static inline void __skb_frag_unref(skb_
@@ -3044,7 +3052,7 @@ static inline void __skb_frag_unref(skb_
*/
static inline void skb_frag_unref(struct sk_buff *skb, int f)
{
@ -714,7 +714,7 @@
}
/**
@@ -4642,5 +4650,12 @@ static inline u64 skb_get_kcov_handle(st
@@ -4643,5 +4651,12 @@ static inline u64 skb_get_kcov_handle(st
#endif
}

View File

@ -24,8 +24,8 @@ Signed-off-by: David S. Miller <davem@davemloft.net>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/io.h>
@@ -228,11 +229,65 @@ static const struct b53_io_ops b53_mmap_
.write64 = b53_mmap_write64,
@@ -242,11 +243,65 @@ static const struct b53_io_ops b53_mmap_
.phy_write16 = b53_mmap_phy_write16,
};
+static int b53_mmap_probe_of(struct platform_device *pdev,

View File

@ -354,7 +354,7 @@ Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
static void mem_cgroup_css_free(struct cgroup_subsys_state *css)
--- a/mm/page_alloc.c
+++ b/mm/page_alloc.c
@@ -7645,6 +7645,7 @@ static void __init free_area_init_node(i
@@ -7661,6 +7661,7 @@ static void __init free_area_init_node(i
pgdat_set_deferred_range(pgdat);
free_area_init_core(pgdat);

View File

@ -21,7 +21,7 @@ Signed-off-by: Alexei Starovoitov <ast@kernel.org>
--- a/include/linux/skbuff.h
+++ b/include/linux/skbuff.h
@@ -567,6 +567,7 @@ struct skb_shared_info {
@@ -568,6 +568,7 @@ struct skb_shared_info {
* Warning : all fields before dataref are cleared in __alloc_skb()
*/
atomic_t dataref;

View File

@ -1,49 +0,0 @@
From 45977e58ce65ed0459edc9a0466d9dfea09463f5 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=C3=81lvaro=20Fern=C3=A1ndez=20Rojas?= <noltari@gmail.com>
Date: Thu, 23 Mar 2023 20:48:41 +0100
Subject: [PATCH] net: dsa: b53: mmap: add phy ops
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Implement phy_read16() and phy_write16() ops for B53 MMAP to avoid accessing
B53_PORT_MII_PAGE registers which hangs the device.
This access should be done through the MDIO Mux bus controller.
Signed-off-by: Álvaro Fernández Rojas <noltari@gmail.com>
Acked-by: Florian Fainelli <f.fainelli@gmail.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
---
drivers/net/dsa/b53/b53_mmap.c | 14 ++++++++++++++
1 file changed, 14 insertions(+)
--- a/drivers/net/dsa/b53/b53_mmap.c
+++ b/drivers/net/dsa/b53/b53_mmap.c
@@ -216,6 +216,18 @@ static int b53_mmap_write64(struct b53_d
return 0;
}
+static int b53_mmap_phy_read16(struct b53_device *dev, int addr, int reg,
+ u16 *value)
+{
+ return -EIO;
+}
+
+static int b53_mmap_phy_write16(struct b53_device *dev, int addr, int reg,
+ u16 value)
+{
+ return -EIO;
+}
+
static const struct b53_io_ops b53_mmap_ops = {
.read8 = b53_mmap_read8,
.read16 = b53_mmap_read16,
@@ -227,6 +239,8 @@ static const struct b53_io_ops b53_mmap_
.write32 = b53_mmap_write32,
.write48 = b53_mmap_write48,
.write64 = b53_mmap_write64,
+ .phy_read16 = b53_mmap_phy_read16,
+ .phy_write16 = b53_mmap_phy_write16,
};
static int b53_mmap_probe_of(struct platform_device *pdev,

View File

@ -4721,8 +4721,8 @@ CONFIG_PWRSEQ_SIMPLE=y
# CONFIG_RALINK is not set
# CONFIG_RANDOM32_SELFTEST is not set
# CONFIG_RANDOMIZE_BASE is not set
# CONFIG_RANDOM_TRUST_BOOTLOADER is not set
# CONFIG_RANDOM_TRUST_CPU is not set
CONFIG_RANDOM_TRUST_BOOTLOADER=y
CONFIG_RANDOM_TRUST_CPU=y
# CONFIG_RAPIDIO is not set
# CONFIG_RAS is not set
# CONFIG_RAW_DRIVER is not set
@ -5034,7 +5034,7 @@ CONFIG_SCHED_HRTICK=y
# CONFIG_SCHED_MC is not set
CONFIG_SCHED_OMIT_FRAME_POINTER=y
# CONFIG_SCHED_SMT is not set
# CONFIG_SCHED_STACK_END_CHECK is not set
CONFIG_SCHED_STACK_END_CHECK=y
# CONFIG_SCHED_TRACER is not set
# CONFIG_SCR24X is not set
# CONFIG_SCSI is not set
@ -5480,7 +5480,7 @@ CONFIG_SIGNALFD=y
# CONFIG_SKY2_DEBUG is not set
# CONFIG_SLAB is not set
CONFIG_SLABINFO=y
# CONFIG_SLAB_FREELIST_HARDENED is not set
CONFIG_SLAB_FREELIST_HARDENED=y
# CONFIG_SLAB_FREELIST_RANDOM is not set
CONFIG_SLAB_MERGE_DEFAULT=y
# CONFIG_SLHC is not set

View File

@ -4962,8 +4962,8 @@ CONFIG_PWRSEQ_SIMPLE=y
# CONFIG_RANDOM32_SELFTEST is not set
# CONFIG_RANDOMIZE_BASE is not set
# CONFIG_RANDOMIZE_KSTACK_OFFSET_DEFAULT is not set
# CONFIG_RANDOM_TRUST_BOOTLOADER is not set
# CONFIG_RANDOM_TRUST_CPU is not set
CONFIG_RANDOM_TRUST_BOOTLOADER=y
CONFIG_RANDOM_TRUST_CPU=y
# CONFIG_RAPIDIO is not set
# CONFIG_RAS is not set
# CONFIG_RAW_DRIVER is not set
@ -5290,7 +5290,7 @@ CONFIG_SCHED_HRTICK=y
# CONFIG_SCHED_MC is not set
CONFIG_SCHED_OMIT_FRAME_POINTER=y
# CONFIG_SCHED_SMT is not set
# CONFIG_SCHED_STACK_END_CHECK is not set
CONFIG_SCHED_STACK_END_CHECK=y
# CONFIG_SCHED_TRACER is not set
# CONFIG_SCR24X is not set
# CONFIG_SCSI is not set
@ -5769,7 +5769,7 @@ CONFIG_SIGNALFD=y
# CONFIG_SKY2_DEBUG is not set
# CONFIG_SLAB is not set
CONFIG_SLABINFO=y
# CONFIG_SLAB_FREELIST_HARDENED is not set
CONFIG_SLAB_FREELIST_HARDENED=y
# CONFIG_SLAB_FREELIST_RANDOM is not set
CONFIG_SLAB_MERGE_DEFAULT=y
# CONFIG_SLHC is not set

View File

@ -191,36 +191,6 @@ static u16 get_bmt_index(struct bbmt *bmt)
return 0;
}
static int
read_bmt(u16 block, unsigned char *dat, unsigned char *fdm, int fdm_len)
{
u32 len = bmtd.bmt_pgs << bmtd.pg_shift;
return bbt_nand_read(blk_pg(block), dat, len, fdm, fdm_len);
}
static struct bbbt *scan_bmt(u16 block)
{
u8 fdm[4];
if (block < bmtd.pool_lba)
return NULL;
if (read_bmt(block, bmtd.bbt_buf, fdm, sizeof(fdm)))
return scan_bmt(block - 1);
if (is_valid_bmt(bmtd.bbt_buf, fdm)) {
bmtd.bmt_blk_idx = get_bmt_index(bmt_tbl((struct bbbt *)bmtd.bbt_buf));
if (bmtd.bmt_blk_idx == 0) {
pr_info("[BBT] FATAL ERR: bmt block index is wrong!\n");
return NULL;
}
pr_info("[BBT] BMT.v2 is found at 0x%x\n", block);
return (struct bbbt *)bmtd.bbt_buf;
} else
return scan_bmt(block - 1);
}
/* Write the Burner Bad Block Table to Nand Flash
* n - write BMT to bmt_tbl[n]
*/
@ -472,7 +442,30 @@ static int mtk_bmt_init_v2(struct device_node *np)
/* Scanning start from the first page of the last block
* of whole flash
*/
bmtd.bbt = scan_bmt(bmtd.total_blks - 1);
bmtd.bbt = NULL;
for (u16 block = bmtd.total_blks - 1; !bmtd.bbt && block >= bmtd.pool_lba; block--) {
u8 fdm[4];
if (bbt_nand_read(blk_pg(block), bmtd.bbt_buf, bufsz, fdm, sizeof(fdm))) {
/* Read failed, try the previous block */
continue;
}
if (!is_valid_bmt(bmtd.bbt_buf, fdm)) {
/* No valid BMT found, try the previous block */
continue;
}
bmtd.bmt_blk_idx = get_bmt_index(bmt_tbl((struct bbbt *)bmtd.bbt_buf));
if (bmtd.bmt_blk_idx == 0) {
pr_info("[BBT] FATAL ERR: bmt block index is wrong!\n");
break;
}
pr_info("[BBT] BMT.v2 is found at 0x%x\n", block);
bmtd.bbt = (struct bbbt *)bmtd.bbt_buf;
}
if (!bmtd.bbt) {
/* BMT not found */
if (bmtd.total_blks > BB_TABLE_MAX + BMT_TABLE_MAX) {

View File

@ -60,7 +60,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
*/
--- a/include/linux/skbuff.h
+++ b/include/linux/skbuff.h
@@ -2727,6 +2727,10 @@ static inline int pskb_trim(struct sk_bu
@@ -2728,6 +2728,10 @@ static inline int pskb_trim(struct sk_bu
return (len < skb->len) ? __pskb_trim(skb, len) : 0;
}
@ -71,7 +71,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
/**
* pskb_trim_unique - remove end from a paged unique (not cloned) buffer
* @skb: buffer to alter
@@ -2858,16 +2862,6 @@ static inline struct sk_buff *dev_alloc_
@@ -2859,16 +2863,6 @@ static inline struct sk_buff *dev_alloc_
}

View File

@ -71,7 +71,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
*/
--- a/include/linux/skbuff.h
+++ b/include/linux/skbuff.h
@@ -2854,6 +2854,10 @@ static inline int pskb_trim(struct sk_bu
@@ -2855,6 +2855,10 @@ static inline int pskb_trim(struct sk_bu
return (len < skb->len) ? __pskb_trim(skb, len) : 0;
}
@ -82,7 +82,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
/**
* pskb_trim_unique - remove end from a paged unique (not cloned) buffer
* @skb: buffer to alter
@@ -3004,16 +3008,6 @@ static inline struct sk_buff *dev_alloc_
@@ -3005,16 +3009,6 @@ static inline struct sk_buff *dev_alloc_
}

View File

@ -9,7 +9,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
--- a/include/linux/skbuff.h
+++ b/include/linux/skbuff.h
@@ -2693,7 +2693,7 @@ static inline int pskb_network_may_pull(
@@ -2694,7 +2694,7 @@ static inline int pskb_network_may_pull(
* NET_IP_ALIGN(2) + ethernet_header(14) + IP_header(20/40) + ports(8)
*/
#ifndef NET_SKB_PAD

View File

@ -22,7 +22,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
#endif
--- a/include/linux/skbuff.h
+++ b/include/linux/skbuff.h
@@ -863,6 +863,7 @@ struct sk_buff {
@@ -864,6 +864,7 @@ struct sk_buff {
__u8 decrypted:1;
#endif
__u8 scm_io_uring:1;

View File

@ -71,7 +71,7 @@ Signed-off-by: Tobias Wolf <dev-NTEO@vplace.de>
--- a/mm/page_alloc.c
+++ b/mm/page_alloc.c
@@ -7604,7 +7604,7 @@ static void __init alloc_node_mem_map(st
@@ -7620,7 +7620,7 @@ static void __init alloc_node_mem_map(st
if (pgdat == NODE_DATA(0)) {
mem_map = NODE_DATA(0)->node_mem_map;
if (page_to_pfn(mem_map) != pgdat->node_start_pfn)

View File

@ -9,7 +9,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
--- a/include/linux/skbuff.h
+++ b/include/linux/skbuff.h
@@ -2820,7 +2820,7 @@ static inline int pskb_network_may_pull(
@@ -2821,7 +2821,7 @@ static inline int pskb_network_may_pull(
* NET_IP_ALIGN(2) + ethernet_header(14) + IP_header(20/40) + ports(8)
*/
#ifndef NET_SKB_PAD

View File

@ -22,7 +22,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
#endif
--- a/include/linux/skbuff.h
+++ b/include/linux/skbuff.h
@@ -892,6 +892,7 @@ struct sk_buff {
@@ -893,6 +893,7 @@ struct sk_buff {
#ifdef CONFIG_IPV6_NDISC_NODETYPE
__u8 ndisc_nodetype:2;
#endif

View File

@ -31,7 +31,7 @@ Signed-off-by: Gabor Juhos <j4g8y7@gmail.com>
--- a/include/linux/skbuff.h
+++ b/include/linux/skbuff.h
@@ -563,6 +563,9 @@ struct skb_shared_info {
@@ -564,6 +564,9 @@ struct skb_shared_info {
unsigned int gso_type;
u32 tskey;

View File

@ -32,7 +32,7 @@ Link: https://lore.kernel.org/r/20220506152107.1527552-9-dmitry.baryshkov@linaro
+ perst-gpios = <&tlmm 58 0x1>;
};
&pcie_phy0 {
&pcie_qmp0 {
--- a/arch/arm64/boot/dts/qcom/ipq8074-hk10.dtsi
+++ b/arch/arm64/boot/dts/qcom/ipq8074-hk10.dtsi
@@ -39,12 +39,12 @@

View File

@ -39,4 +39,4 @@ Link: https://lore.kernel.org/r/20221107092930.33325-3-robimarko@gmail.com
+ perst-gpios = <&tlmm 58 GPIO_ACTIVE_LOW>;
};
&pcie_phy0 {
&pcie_qmp0 {

View File

@ -1,3 +0,0 @@
config MT753X_GSW
tristate "Driver for the MediaTek MT753x switch"

View File

@ -1,11 +0,0 @@
#
# Makefile for MediaTek MT753x gigabit switch
#
obj-$(CONFIG_MT753X_GSW) += mt753x.o
mt753x-$(CONFIG_SWCONFIG) += mt753x_swconfig.o
mt753x-y += mt753x_mdio.o mt7530.o mt7531.o \
mt753x_common.o mt753x_vlan.o \
mt753x_nl.o

View File

@ -1,631 +0,0 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
* Copyright (c) 2018 MediaTek Inc.
* Author: Weijie Gao <weijie.gao@mediatek.com>
*/
#include <linux/kernel.h>
#include <linux/delay.h>
#include "mt753x.h"
#include "mt753x_regs.h"
/* MT7530 registers */
/* Unique fields of PMCR for MT7530 */
#define FORCE_MODE BIT(15)
/* Unique fields of GMACCR for MT7530 */
#define VLAN_SUPT_NO_S 14
#define VLAN_SUPT_NO_M 0x1c000
#define LATE_COL_DROP BIT(13)
/* Unique fields of (M)HWSTRAP for MT7530 */
#define BOND_OPTION BIT(24)
#define P5_PHY0_SEL BIT(20)
#define CHG_TRAP BIT(16)
#define LOOPDET_DIS BIT(14)
#define P5_INTF_SEL_GMAC5 BIT(13)
#define SMI_ADDR_S 11
#define SMI_ADDR_M 0x1800
#define XTAL_FSEL_S 9
#define XTAL_FSEL_M 0x600
#define P6_INTF_DIS BIT(8)
#define P5_INTF_MODE_RGMII BIT(7)
#define P5_INTF_DIS_S BIT(6)
#define C_MDIO_BPS_S BIT(5)
#define EEPROM_EN_S BIT(4)
/* PHY EEE Register bitmap of define */
#define PHY_DEV07 0x07
#define PHY_DEV07_REG_03C 0x3c
/* PHY Extend Register 0x14 bitmap of define */
#define PHY_EXT_REG_14 0x14
/* Fields of PHY_EXT_REG_14 */
#define PHY_EN_DOWN_SHFIT BIT(4)
/* PHY Token Ring Register 0x10 bitmap of define */
#define PHY_TR_REG_10 0x10
/* PHY Token Ring Register 0x12 bitmap of define */
#define PHY_TR_REG_12 0x12
/* PHY LPI PCS/DSP Control Register bitmap of define */
#define PHY_LPI_REG_11 0x11
/* PHY DEV 0x1e Register bitmap of define */
#define PHY_DEV1E 0x1e
#define PHY_DEV1E_REG_123 0x123
#define PHY_DEV1E_REG_A6 0xa6
/* Values of XTAL_FSEL */
#define XTAL_20MHZ 1
#define XTAL_40MHZ 2
#define XTAL_25MHZ 3
#define P6ECR 0x7830
#define P6_INTF_MODE_TRGMII BIT(0)
#define TRGMII_TXCTRL 0x7a40
#define TRAIN_TXEN BIT(31)
#define TXC_INV BIT(30)
#define TX_DOEO BIT(29)
#define TX_RST BIT(28)
#define TRGMII_TD0_CTRL 0x7a50
#define TRGMII_TD1_CTRL 0x7a58
#define TRGMII_TD2_CTRL 0x7a60
#define TRGMII_TD3_CTRL 0x7a68
#define TRGMII_TXCTL_CTRL 0x7a70
#define TRGMII_TCK_CTRL 0x7a78
#define TRGMII_TD_CTRL(n) (0x7a50 + (n) * 8)
#define NUM_TRGMII_CTRL 6
#define TX_DMPEDRV BIT(31)
#define TX_DM_SR BIT(15)
#define TX_DMERODT BIT(14)
#define TX_DMOECTL BIT(13)
#define TX_TAP_S 8
#define TX_TAP_M 0xf00
#define TX_TRAIN_WD_S 0
#define TX_TRAIN_WD_M 0xff
#define TRGMII_TD0_ODT 0x7a54
#define TRGMII_TD1_ODT 0x7a5c
#define TRGMII_TD2_ODT 0x7a64
#define TRGMII_TD3_ODT 0x7a6c
#define TRGMII_TXCTL_ODT 0x7574
#define TRGMII_TCK_ODT 0x757c
#define TRGMII_TD_ODT(n) (0x7a54 + (n) * 8)
#define NUM_TRGMII_ODT 6
#define TX_DM_DRVN_PRE_S 30
#define TX_DM_DRVN_PRE_M 0xc0000000
#define TX_DM_DRVP_PRE_S 28
#define TX_DM_DRVP_PRE_M 0x30000000
#define TX_DM_TDSEL_S 24
#define TX_DM_TDSEL_M 0xf000000
#define TX_ODTEN BIT(23)
#define TX_DME_PRE BIT(20)
#define TX_DM_DRVNT0 BIT(19)
#define TX_DM_DRVPT0 BIT(18)
#define TX_DM_DRVNTE BIT(17)
#define TX_DM_DRVPTE BIT(16)
#define TX_DM_ODTN_S 12
#define TX_DM_ODTN_M 0x7000
#define TX_DM_ODTP_S 8
#define TX_DM_ODTP_M 0x700
#define TX_DM_DRVN_S 4
#define TX_DM_DRVN_M 0xf0
#define TX_DM_DRVP_S 0
#define TX_DM_DRVP_M 0x0f
#define P5RGMIIRXCR 0x7b00
#define CSR_RGMII_RCTL_CFG_S 24
#define CSR_RGMII_RCTL_CFG_M 0x7000000
#define CSR_RGMII_RXD_CFG_S 16
#define CSR_RGMII_RXD_CFG_M 0x70000
#define CSR_RGMII_EDGE_ALIGN BIT(8)
#define CSR_RGMII_RXC_90DEG_CFG_S 4
#define CSR_RGMII_RXC_90DEG_CFG_M 0xf0
#define CSR_RGMII_RXC_0DEG_CFG_S 0
#define CSR_RGMII_RXC_0DEG_CFG_M 0x0f
#define P5RGMIITXCR 0x7b04
#define CSR_RGMII_TXEN_CFG_S 16
#define CSR_RGMII_TXEN_CFG_M 0x70000
#define CSR_RGMII_TXD_CFG_S 8
#define CSR_RGMII_TXD_CFG_M 0x700
#define CSR_RGMII_TXC_CFG_S 0
#define CSR_RGMII_TXC_CFG_M 0x1f
#define CHIP_REV 0x7ffc
#define CHIP_NAME_S 16
#define CHIP_NAME_M 0xffff0000
#define CHIP_REV_S 0
#define CHIP_REV_M 0x0f
/* MMD registers */
#define CORE_PLL_GROUP2 0x401
#define RG_SYSPLL_EN_NORMAL BIT(15)
#define RG_SYSPLL_VODEN BIT(14)
#define RG_SYSPLL_POSDIV_S 5
#define RG_SYSPLL_POSDIV_M 0x60
#define CORE_PLL_GROUP4 0x403
#define RG_SYSPLL_DDSFBK_EN BIT(12)
#define RG_SYSPLL_BIAS_EN BIT(11)
#define RG_SYSPLL_BIAS_LPF_EN BIT(10)
#define CORE_PLL_GROUP5 0x404
#define RG_LCDDS_PCW_NCPO1_S 0
#define RG_LCDDS_PCW_NCPO1_M 0xffff
#define CORE_PLL_GROUP6 0x405
#define RG_LCDDS_PCW_NCPO0_S 0
#define RG_LCDDS_PCW_NCPO0_M 0xffff
#define CORE_PLL_GROUP7 0x406
#define RG_LCDDS_PWDB BIT(15)
#define RG_LCDDS_ISO_EN BIT(13)
#define RG_LCCDS_C_S 4
#define RG_LCCDS_C_M 0x70
#define RG_LCDDS_PCW_NCPO_CHG BIT(3)
#define CORE_PLL_GROUP10 0x409
#define RG_LCDDS_SSC_DELTA_S 0
#define RG_LCDDS_SSC_DELTA_M 0xfff
#define CORE_PLL_GROUP11 0x40a
#define RG_LCDDS_SSC_DELTA1_S 0
#define RG_LCDDS_SSC_DELTA1_M 0xfff
#define CORE_GSWPLL_GCR_1 0x040d
#define GSWPLL_PREDIV_S 14
#define GSWPLL_PREDIV_M 0xc000
#define GSWPLL_POSTDIV_200M_S 12
#define GSWPLL_POSTDIV_200M_M 0x3000
#define GSWPLL_EN_PRE BIT(11)
#define GSWPLL_FBKSEL BIT(10)
#define GSWPLL_BP BIT(9)
#define GSWPLL_BR BIT(8)
#define GSWPLL_FBKDIV_200M_S 0
#define GSWPLL_FBKDIV_200M_M 0xff
#define CORE_GSWPLL_GCR_2 0x040e
#define GSWPLL_POSTDIV_500M_S 8
#define GSWPLL_POSTDIV_500M_M 0x300
#define GSWPLL_FBKDIV_500M_S 0
#define GSWPLL_FBKDIV_500M_M 0xff
#define TRGMII_GSW_CLK_CG 0x0410
#define TRGMIICK_EN BIT(1)
#define GSWCK_EN BIT(0)
static int mt7530_mii_read(struct gsw_mt753x *gsw, int phy, int reg)
{
if (phy < MT753X_NUM_PHYS)
phy = (gsw->phy_base + phy) & MT753X_SMI_ADDR_MASK;
return mdiobus_read(gsw->host_bus, phy, reg);
}
static void mt7530_mii_write(struct gsw_mt753x *gsw, int phy, int reg, u16 val)
{
if (phy < MT753X_NUM_PHYS)
phy = (gsw->phy_base + phy) & MT753X_SMI_ADDR_MASK;
mdiobus_write(gsw->host_bus, phy, reg, val);
}
static int mt7530_mmd_read(struct gsw_mt753x *gsw, int addr, int devad, u16 reg)
{
u16 val;
if (addr < MT753X_NUM_PHYS)
addr = (gsw->phy_base + addr) & MT753X_SMI_ADDR_MASK;
mutex_lock(&gsw->host_bus->mdio_lock);
gsw->host_bus->write(gsw->host_bus, addr, MII_MMD_ACC_CTL_REG,
(MMD_ADDR << MMD_CMD_S) |
((devad << MMD_DEVAD_S) & MMD_DEVAD_M));
gsw->host_bus->write(gsw->host_bus, addr, MII_MMD_ADDR_DATA_REG, reg);
gsw->host_bus->write(gsw->host_bus, addr, MII_MMD_ACC_CTL_REG,
(MMD_DATA << MMD_CMD_S) |
((devad << MMD_DEVAD_S) & MMD_DEVAD_M));
val = gsw->host_bus->read(gsw->host_bus, addr, MII_MMD_ADDR_DATA_REG);
mutex_unlock(&gsw->host_bus->mdio_lock);
return val;
}
static void mt7530_mmd_write(struct gsw_mt753x *gsw, int addr, int devad,
u16 reg, u16 val)
{
if (addr < MT753X_NUM_PHYS)
addr = (gsw->phy_base + addr) & MT753X_SMI_ADDR_MASK;
mutex_lock(&gsw->host_bus->mdio_lock);
gsw->host_bus->write(gsw->host_bus, addr, MII_MMD_ACC_CTL_REG,
(MMD_ADDR << MMD_CMD_S) |
((devad << MMD_DEVAD_S) & MMD_DEVAD_M));
gsw->host_bus->write(gsw->host_bus, addr, MII_MMD_ADDR_DATA_REG, reg);
gsw->host_bus->write(gsw->host_bus, addr, MII_MMD_ACC_CTL_REG,
(MMD_DATA << MMD_CMD_S) |
((devad << MMD_DEVAD_S) & MMD_DEVAD_M));
gsw->host_bus->write(gsw->host_bus, addr, MII_MMD_ADDR_DATA_REG, val);
mutex_unlock(&gsw->host_bus->mdio_lock);
}
static void mt7530_core_reg_write(struct gsw_mt753x *gsw, u32 reg, u32 val)
{
gsw->mmd_write(gsw, 0, 0x1f, reg, val);
}
static void mt7530_trgmii_setting(struct gsw_mt753x *gsw)
{
u16 i;
mt7530_core_reg_write(gsw, CORE_PLL_GROUP5, 0x0780);
mdelay(1);
mt7530_core_reg_write(gsw, CORE_PLL_GROUP6, 0);
mt7530_core_reg_write(gsw, CORE_PLL_GROUP10, 0x87);
mdelay(1);
mt7530_core_reg_write(gsw, CORE_PLL_GROUP11, 0x87);
/* PLL BIAS enable */
mt7530_core_reg_write(gsw, CORE_PLL_GROUP4,
RG_SYSPLL_DDSFBK_EN | RG_SYSPLL_BIAS_EN);
mdelay(1);
/* PLL LPF enable */
mt7530_core_reg_write(gsw, CORE_PLL_GROUP4,
RG_SYSPLL_DDSFBK_EN |
RG_SYSPLL_BIAS_EN | RG_SYSPLL_BIAS_LPF_EN);
/* sys PLL enable */
mt7530_core_reg_write(gsw, CORE_PLL_GROUP2,
RG_SYSPLL_EN_NORMAL | RG_SYSPLL_VODEN |
(1 << RG_SYSPLL_POSDIV_S));
/* LCDDDS PWDS */
mt7530_core_reg_write(gsw, CORE_PLL_GROUP7,
(3 << RG_LCCDS_C_S) |
RG_LCDDS_PWDB | RG_LCDDS_ISO_EN);
mdelay(1);
/* Enable MT7530 TRGMII clock */
mt7530_core_reg_write(gsw, TRGMII_GSW_CLK_CG, GSWCK_EN | TRGMIICK_EN);
/* lower Tx Driving */
for (i = 0 ; i < NUM_TRGMII_ODT; i++)
mt753x_reg_write(gsw, TRGMII_TD_ODT(i),
(4 << TX_DM_DRVP_S) | (4 << TX_DM_DRVN_S));
}
static void mt7530_rgmii_setting(struct gsw_mt753x *gsw)
{
u32 val;
mt7530_core_reg_write(gsw, CORE_PLL_GROUP5, 0x0c80);
mdelay(1);
mt7530_core_reg_write(gsw, CORE_PLL_GROUP6, 0);
mt7530_core_reg_write(gsw, CORE_PLL_GROUP10, 0x87);
mdelay(1);
mt7530_core_reg_write(gsw, CORE_PLL_GROUP11, 0x87);
val = mt753x_reg_read(gsw, TRGMII_TXCTRL);
val &= ~TXC_INV;
mt753x_reg_write(gsw, TRGMII_TXCTRL, val);
mt753x_reg_write(gsw, TRGMII_TCK_CTRL,
(8 << TX_TAP_S) | (0x55 << TX_TRAIN_WD_S));
}
static int mt7530_mac_port_setup(struct gsw_mt753x *gsw)
{
u32 hwstrap, p6ecr = 0, p5mcr, p6mcr, phyad;
hwstrap = mt753x_reg_read(gsw, MHWSTRAP);
hwstrap &= ~(P6_INTF_DIS | P5_INTF_MODE_RGMII | P5_INTF_DIS_S);
hwstrap |= P5_INTF_SEL_GMAC5;
if (!gsw->port5_cfg.enabled) {
p5mcr = FORCE_MODE;
hwstrap |= P5_INTF_DIS_S;
} else {
p5mcr = (IPG_96BIT_WITH_SHORT_IPG << IPG_CFG_S) |
MAC_MODE | MAC_TX_EN | MAC_RX_EN |
BKOFF_EN | BACKPR_EN;
if (gsw->port5_cfg.force_link) {
p5mcr |= FORCE_MODE | FORCE_LINK | FORCE_RX_FC |
FORCE_TX_FC;
p5mcr |= gsw->port5_cfg.speed << FORCE_SPD_S;
if (gsw->port5_cfg.duplex)
p5mcr |= FORCE_DPX;
}
switch (gsw->port5_cfg.phy_mode) {
case PHY_INTERFACE_MODE_MII:
case PHY_INTERFACE_MODE_GMII:
break;
case PHY_INTERFACE_MODE_RGMII:
hwstrap |= P5_INTF_MODE_RGMII;
break;
default:
dev_info(gsw->dev, "%s is not supported by port5\n",
phy_modes(gsw->port5_cfg.phy_mode));
p5mcr = FORCE_MODE;
hwstrap |= P5_INTF_DIS_S;
}
/* Port5 to PHY direct mode */
if (of_property_read_u32(gsw->port5_cfg.np, "phy-address",
&phyad))
goto parse_p6;
if (phyad != 0 && phyad != 4) {
dev_info(gsw->dev,
"Only PHY 0/4 can be connected to Port 5\n");
goto parse_p6;
}
hwstrap &= ~P5_INTF_SEL_GMAC5;
if (phyad == 0)
hwstrap |= P5_PHY0_SEL;
else
hwstrap &= ~P5_PHY0_SEL;
}
parse_p6:
if (!gsw->port6_cfg.enabled) {
p6mcr = FORCE_MODE;
hwstrap |= P6_INTF_DIS;
} else {
p6mcr = (IPG_96BIT_WITH_SHORT_IPG << IPG_CFG_S) |
MAC_MODE | MAC_TX_EN | MAC_RX_EN |
BKOFF_EN | BACKPR_EN;
if (gsw->port6_cfg.force_link) {
p6mcr |= FORCE_MODE | FORCE_LINK | FORCE_RX_FC |
FORCE_TX_FC;
p6mcr |= gsw->port6_cfg.speed << FORCE_SPD_S;
if (gsw->port6_cfg.duplex)
p6mcr |= FORCE_DPX;
}
switch (gsw->port6_cfg.phy_mode) {
case PHY_INTERFACE_MODE_RGMII:
p6ecr = BIT(1);
break;
case PHY_INTERFACE_MODE_TRGMII:
/* set MT7530 central align */
p6ecr = BIT(0);
break;
default:
dev_info(gsw->dev, "%s is not supported by port6\n",
phy_modes(gsw->port6_cfg.phy_mode));
p6mcr = FORCE_MODE;
hwstrap |= P6_INTF_DIS;
}
}
mt753x_reg_write(gsw, MHWSTRAP, hwstrap);
mt753x_reg_write(gsw, P6ECR, p6ecr);
mt753x_reg_write(gsw, PMCR(5), p5mcr);
mt753x_reg_write(gsw, PMCR(6), p6mcr);
return 0;
}
static void mt7530_core_pll_setup(struct gsw_mt753x *gsw)
{
u32 hwstrap;
hwstrap = mt753x_reg_read(gsw, HWSTRAP);
switch ((hwstrap & XTAL_FSEL_M) >> XTAL_FSEL_S) {
case XTAL_40MHZ:
/* Disable MT7530 core clock */
mt7530_core_reg_write(gsw, TRGMII_GSW_CLK_CG, 0);
/* disable MT7530 PLL */
mt7530_core_reg_write(gsw, CORE_GSWPLL_GCR_1,
(2 << GSWPLL_POSTDIV_200M_S) |
(32 << GSWPLL_FBKDIV_200M_S));
/* For MT7530 core clock = 500Mhz */
mt7530_core_reg_write(gsw, CORE_GSWPLL_GCR_2,
(1 << GSWPLL_POSTDIV_500M_S) |
(25 << GSWPLL_FBKDIV_500M_S));
/* Enable MT7530 PLL */
mt7530_core_reg_write(gsw, CORE_GSWPLL_GCR_1,
(2 << GSWPLL_POSTDIV_200M_S) |
(32 << GSWPLL_FBKDIV_200M_S) |
GSWPLL_EN_PRE);
usleep_range(20, 40);
/* Enable MT7530 core clock */
mt7530_core_reg_write(gsw, TRGMII_GSW_CLK_CG, GSWCK_EN);
break;
default:
/* TODO: PLL settings for 20/25MHz */
break;
}
hwstrap = mt753x_reg_read(gsw, HWSTRAP);
hwstrap |= CHG_TRAP;
if (gsw->direct_phy_access)
hwstrap &= ~C_MDIO_BPS_S;
else
hwstrap |= C_MDIO_BPS_S;
mt753x_reg_write(gsw, MHWSTRAP, hwstrap);
if (gsw->port6_cfg.enabled &&
gsw->port6_cfg.phy_mode == PHY_INTERFACE_MODE_TRGMII) {
mt7530_trgmii_setting(gsw);
} else {
/* RGMII */
mt7530_rgmii_setting(gsw);
}
/* delay setting for 10/1000M */
mt753x_reg_write(gsw, P5RGMIIRXCR,
CSR_RGMII_EDGE_ALIGN |
(2 << CSR_RGMII_RXC_0DEG_CFG_S));
mt753x_reg_write(gsw, P5RGMIITXCR, 0x14 << CSR_RGMII_TXC_CFG_S);
}
static int mt7530_sw_detect(struct gsw_mt753x *gsw, struct chip_rev *crev)
{
u32 rev;
rev = mt753x_reg_read(gsw, CHIP_REV);
if (((rev & CHIP_NAME_M) >> CHIP_NAME_S) == MT7530) {
if (crev) {
crev->rev = rev & CHIP_REV_M;
crev->name = "MT7530";
}
return 0;
}
return -ENODEV;
}
static void mt7530_phy_setting(struct gsw_mt753x *gsw)
{
int i;
u32 val;
for (i = 0; i < MT753X_NUM_PHYS; i++) {
/* Disable EEE */
gsw->mmd_write(gsw, i, PHY_DEV07, PHY_DEV07_REG_03C, 0);
/* Enable HW auto downshift */
gsw->mii_write(gsw, i, 0x1f, 0x1);
val = gsw->mii_read(gsw, i, PHY_EXT_REG_14);
val |= PHY_EN_DOWN_SHFIT;
gsw->mii_write(gsw, i, PHY_EXT_REG_14, val);
/* Increase SlvDPSready time */
gsw->mii_write(gsw, i, 0x1f, 0x52b5);
gsw->mii_write(gsw, i, PHY_TR_REG_10, 0xafae);
gsw->mii_write(gsw, i, PHY_TR_REG_12, 0x2f);
gsw->mii_write(gsw, i, PHY_TR_REG_10, 0x8fae);
/* Increase post_update_timer */
gsw->mii_write(gsw, i, 0x1f, 0x3);
gsw->mii_write(gsw, i, PHY_LPI_REG_11, 0x4b);
gsw->mii_write(gsw, i, 0x1f, 0);
/* Adjust 100_mse_threshold */
gsw->mmd_write(gsw, i, PHY_DEV1E, PHY_DEV1E_REG_123, 0xffff);
/* Disable mcc */
gsw->mmd_write(gsw, i, PHY_DEV1E, PHY_DEV1E_REG_A6, 0x300);
}
}
static inline bool get_phy_access_mode(const struct device_node *np)
{
return of_property_read_bool(np, "mt7530,direct-phy-access");
}
static int mt7530_sw_init(struct gsw_mt753x *gsw)
{
int i;
u32 val;
gsw->direct_phy_access = get_phy_access_mode(gsw->dev->of_node);
/* Force MT7530 to use (in)direct PHY access */
val = mt753x_reg_read(gsw, HWSTRAP);
val |= CHG_TRAP;
if (gsw->direct_phy_access)
val &= ~C_MDIO_BPS_S;
else
val |= C_MDIO_BPS_S;
mt753x_reg_write(gsw, MHWSTRAP, val);
/* Read PHY address base from HWSTRAP */
gsw->phy_base = (((val & SMI_ADDR_M) >> SMI_ADDR_S) << 3) + 8;
gsw->phy_base &= MT753X_SMI_ADDR_MASK;
if (gsw->direct_phy_access) {
gsw->mii_read = mt7530_mii_read;
gsw->mii_write = mt7530_mii_write;
gsw->mmd_read = mt7530_mmd_read;
gsw->mmd_write = mt7530_mmd_write;
} else {
gsw->mii_read = mt753x_mii_read;
gsw->mii_write = mt753x_mii_write;
gsw->mmd_read = mt753x_mmd_ind_read;
gsw->mmd_write = mt753x_mmd_ind_write;
}
for (i = 0; i < MT753X_NUM_PHYS; i++) {
val = gsw->mii_read(gsw, i, MII_BMCR);
val |= BMCR_PDOWN;
gsw->mii_write(gsw, i, MII_BMCR, val);
}
/* Force MAC link down before reset */
mt753x_reg_write(gsw, PMCR(5), FORCE_MODE);
mt753x_reg_write(gsw, PMCR(6), FORCE_MODE);
/* Switch soft reset */
/* BUG: sw reset causes gsw int flooding */
mt753x_reg_write(gsw, SYS_CTRL, SW_PHY_RST | SW_SYS_RST | SW_REG_RST);
usleep_range(10, 20);
/* global mac control settings configuration */
mt753x_reg_write(gsw, GMACCR,
LATE_COL_DROP | (15 << MTCC_LMT_S) |
(2 << MAX_RX_JUMBO_S) | RX_PKT_LEN_MAX_JUMBO);
mt7530_core_pll_setup(gsw);
mt7530_mac_port_setup(gsw);
return 0;
}
static int mt7530_sw_post_init(struct gsw_mt753x *gsw)
{
int i;
u32 val;
mt7530_phy_setting(gsw);
for (i = 0; i < MT753X_NUM_PHYS; i++) {
val = gsw->mii_read(gsw, i, MII_BMCR);
val &= ~BMCR_PDOWN;
gsw->mii_write(gsw, i, MII_BMCR, val);
}
return 0;
}
struct mt753x_sw_id mt7530_id = {
.model = MT7530,
.detect = mt7530_sw_detect,
.init = mt7530_sw_init,
.post_init = mt7530_sw_post_init
};

View File

@ -1,13 +0,0 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Copyright (c) 2018 MediaTek Inc.
*/
#ifndef _MT7530_H_
#define _MT7530_H_
#include "mt753x.h"
extern struct mt753x_sw_id mt7530_id;
#endif /* _MT7530_H_ */

View File

@ -1,918 +0,0 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
* Copyright (c) 2018 MediaTek Inc.
* Author: Zhanguo Ju <zhanguo.ju@mediatek.com>
*/
#include <linux/kernel.h>
#include <linux/delay.h>
#include <linux/hrtimer.h>
#include "mt753x.h"
#include "mt753x_regs.h"
/* MT7531 registers */
#define SGMII_REG_BASE 0x5000
#define SGMII_REG_PORT_BASE 0x1000
#define SGMII_REG(p, r) (SGMII_REG_BASE + \
(p) * SGMII_REG_PORT_BASE + (r))
#define PCS_CONTROL_1(p) SGMII_REG(p, 0x00)
#define SGMII_MODE(p) SGMII_REG(p, 0x20)
#define QPHY_PWR_STATE_CTRL(p) SGMII_REG(p, 0xe8)
#define PHYA_CTRL_SIGNAL3(p) SGMII_REG(p, 0x128)
/* Fields of PCS_CONTROL_1 */
#define SGMII_LINK_STATUS BIT(18)
#define SGMII_AN_ENABLE BIT(12)
#define SGMII_AN_RESTART BIT(9)
/* Fields of SGMII_MODE */
#define SGMII_REMOTE_FAULT_DIS BIT(8)
#define SGMII_IF_MODE_FORCE_DUPLEX BIT(4)
#define SGMII_IF_MODE_FORCE_SPEED_S 0x2
#define SGMII_IF_MODE_FORCE_SPEED_M 0x0c
#define SGMII_IF_MODE_ADVERT_AN BIT(1)
/* Values of SGMII_IF_MODE_FORCE_SPEED */
#define SGMII_IF_MODE_FORCE_SPEED_10 0
#define SGMII_IF_MODE_FORCE_SPEED_100 1
#define SGMII_IF_MODE_FORCE_SPEED_1000 2
/* Fields of QPHY_PWR_STATE_CTRL */
#define PHYA_PWD BIT(4)
/* Fields of PHYA_CTRL_SIGNAL3 */
#define RG_TPHY_SPEED_S 2
#define RG_TPHY_SPEED_M 0x0c
/* Values of RG_TPHY_SPEED */
#define RG_TPHY_SPEED_1000 0
#define RG_TPHY_SPEED_2500 1
/* Unique fields of (M)HWSTRAP for MT7531 */
#define XTAL_FSEL_S 7
#define XTAL_FSEL_M BIT(7)
#define PHY_EN BIT(6)
#define CHG_STRAP BIT(8)
/* Efuse Register Define */
#define GBE_EFUSE 0x7bc8
#define GBE_SEL_EFUSE_EN BIT(0)
/* PHY ENABLE Register bitmap define */
#define PHY_DEV1F 0x1f
#define PHY_DEV1F_REG_44 0x44
#define PHY_DEV1F_REG_104 0x104
#define PHY_DEV1F_REG_10A 0x10a
#define PHY_DEV1F_REG_10B 0x10b
#define PHY_DEV1F_REG_10C 0x10c
#define PHY_DEV1F_REG_10D 0x10d
#define PHY_DEV1F_REG_268 0x268
#define PHY_DEV1F_REG_269 0x269
#define PHY_DEV1F_REG_403 0x403
/* Fields of PHY_DEV1F_REG_403 */
#define GBE_EFUSE_SETTING BIT(3)
#define PHY_EN_BYPASS_MODE BIT(4)
#define POWER_ON_OFF BIT(5)
#define PHY_PLL_M GENMASK(9, 8)
#define PHY_PLL_SEL(x) (((x) << 8) & GENMASK(9, 8))
/* PHY EEE Register bitmap of define */
#define PHY_DEV07 0x07
#define PHY_DEV07_REG_03C 0x3c
/* PHY Extend Register 0x14 bitmap of define */
#define PHY_EXT_REG_14 0x14
/* Fields of PHY_EXT_REG_14 */
#define PHY_EN_DOWN_SHFIT BIT(4)
/* PHY Extend Register 0x17 bitmap of define */
#define PHY_EXT_REG_17 0x17
/* Fields of PHY_EXT_REG_17 */
#define PHY_LINKDOWN_POWER_SAVING_EN BIT(4)
/* PHY Token Ring Register 0x10 bitmap of define */
#define PHY_TR_REG_10 0x10
/* PHY Token Ring Register 0x12 bitmap of define */
#define PHY_TR_REG_12 0x12
/* PHY DEV 0x1e Register bitmap of define */
#define PHY_DEV1E 0x1e
#define PHY_DEV1E_REG_13 0x13
#define PHY_DEV1E_REG_14 0x14
#define PHY_DEV1E_REG_41 0x41
#define PHY_DEV1E_REG_A6 0xa6
#define PHY_DEV1E_REG_0C6 0x0c6
#define PHY_DEV1E_REG_0FE 0x0fe
#define PHY_DEV1E_REG_123 0x123
#define PHY_DEV1E_REG_189 0x189
/* Fields of PHY_DEV1E_REG_0C6 */
#define PHY_POWER_SAVING_S 8
#define PHY_POWER_SAVING_M 0x300
#define PHY_POWER_SAVING_TX 0x0
/* Fields of PHY_DEV1E_REG_189 */
#define DESCRAMBLER_CLEAR_EN 0x1
/* Values of XTAL_FSEL_S */
#define XTAL_40MHZ 0
#define XTAL_25MHZ 1
#define PLLGP_EN 0x7820
#define EN_COREPLL BIT(2)
#define SW_CLKSW BIT(1)
#define SW_PLLGP BIT(0)
#define PLLGP_CR0 0x78a8
#define RG_COREPLL_EN BIT(22)
#define RG_COREPLL_POSDIV_S 23
#define RG_COREPLL_POSDIV_M 0x3800000
#define RG_COREPLL_SDM_PCW_S 1
#define RG_COREPLL_SDM_PCW_M 0x3ffffe
#define RG_COREPLL_SDM_PCW_CHG BIT(0)
/* TOP Signals Status Register */
#define TOP_SIG_SR 0x780c
#define PAD_DUAL_SGMII_EN BIT(1)
/* RGMII and SGMII PLL clock */
#define ANA_PLLGP_CR2 0x78b0
#define ANA_PLLGP_CR5 0x78bc
/* GPIO mode define */
#define GPIO_MODE_REGS(x) (0x7c0c + (((x) / 8) * 4))
#define GPIO_MODE_S 4
/* GPIO GROUP IOLB SMT0 Control */
#define SMT0_IOLB 0x7f04
#define SMT_IOLB_5_SMI_MDC_EN BIT(5)
/* Unique fields of PMCR for MT7531 */
#define FORCE_MODE_EEE1G BIT(25)
#define FORCE_MODE_EEE100 BIT(26)
#define FORCE_MODE_TX_FC BIT(27)
#define FORCE_MODE_RX_FC BIT(28)
#define FORCE_MODE_DPX BIT(29)
#define FORCE_MODE_SPD BIT(30)
#define FORCE_MODE_LNK BIT(31)
#define FORCE_MODE BIT(15)
#define CHIP_REV 0x781C
#define CHIP_NAME_S 16
#define CHIP_NAME_M 0xffff0000
#define CHIP_REV_S 0
#define CHIP_REV_M 0x0f
#define CHIP_REV_E1 0x0
#define CLKGEN_CTRL 0x7500
#define CLK_SKEW_OUT_S 8
#define CLK_SKEW_OUT_M 0x300
#define CLK_SKEW_IN_S 6
#define CLK_SKEW_IN_M 0xc0
#define RXCLK_NO_DELAY BIT(5)
#define TXCLK_NO_REVERSE BIT(4)
#define GP_MODE_S 1
#define GP_MODE_M 0x06
#define GP_CLK_EN BIT(0)
/* Values of GP_MODE */
#define GP_MODE_RGMII 0
#define GP_MODE_MII 1
#define GP_MODE_REV_MII 2
/* Values of CLK_SKEW_IN */
#define CLK_SKEW_IN_NO_CHANGE 0
#define CLK_SKEW_IN_DELAY_100PPS 1
#define CLK_SKEW_IN_DELAY_200PPS 2
#define CLK_SKEW_IN_REVERSE 3
/* Values of CLK_SKEW_OUT */
#define CLK_SKEW_OUT_NO_CHANGE 0
#define CLK_SKEW_OUT_DELAY_100PPS 1
#define CLK_SKEW_OUT_DELAY_200PPS 2
#define CLK_SKEW_OUT_REVERSE 3
/* Proprietory Control Register of Internal Phy device 0x1e */
#define RXADC_CONTROL_3 0xc2
#define RXADC_LDO_CONTROL_2 0xd3
/* Proprietory Control Register of Internal Phy device 0x1f */
#define TXVLD_DA_271 0x271
#define TXVLD_DA_272 0x272
#define TXVLD_DA_273 0x273
/* DSP Channel and NOD_ADDR*/
#define DSP_CH 0x2
#define DSP_NOD_ADDR 0xD
/* gpio pinmux pins and functions define */
static int gpio_int_pins[] = {0};
static int gpio_int_funcs[] = {1};
static int gpio_mdc_pins[] = {11, 20};
static int gpio_mdc_funcs[] = {2, 2};
static int gpio_mdio_pins[] = {12, 21};
static int gpio_mdio_funcs[] = {2, 2};
static int mt7531_set_port_sgmii_force_mode(struct gsw_mt753x *gsw, u32 port,
struct mt753x_port_cfg *port_cfg)
{
u32 speed, port_base, val;
ktime_t timeout;
u32 timeout_us;
if (port < 5 || port >= MT753X_NUM_PORTS) {
dev_info(gsw->dev, "port %d is not a SGMII port\n", port);
return -EINVAL;
}
port_base = port - 5;
switch (port_cfg->speed) {
case MAC_SPD_1000:
speed = RG_TPHY_SPEED_1000;
break;
case MAC_SPD_2500:
speed = RG_TPHY_SPEED_2500;
break;
default:
dev_info(gsw->dev, "invalid SGMII speed idx %d for port %d\n",
port_cfg->speed, port);
speed = RG_TPHY_SPEED_1000;
}
/* Step 1: Speed select register setting */
val = mt753x_reg_read(gsw, PHYA_CTRL_SIGNAL3(port_base));
val &= ~RG_TPHY_SPEED_M;
val |= speed << RG_TPHY_SPEED_S;
mt753x_reg_write(gsw, PHYA_CTRL_SIGNAL3(port_base), val);
/* Step 2 : Disable AN */
val = mt753x_reg_read(gsw, PCS_CONTROL_1(port_base));
val &= ~SGMII_AN_ENABLE;
mt753x_reg_write(gsw, PCS_CONTROL_1(port_base), val);
/* Step 3: SGMII force mode setting */
val = mt753x_reg_read(gsw, SGMII_MODE(port_base));
val &= ~SGMII_IF_MODE_ADVERT_AN;
val &= ~SGMII_IF_MODE_FORCE_SPEED_M;
val |= SGMII_IF_MODE_FORCE_SPEED_1000 << SGMII_IF_MODE_FORCE_SPEED_S;
val |= SGMII_IF_MODE_FORCE_DUPLEX;
/* For sgmii force mode, 0 is full duplex and 1 is half duplex */
if (port_cfg->duplex)
val &= ~SGMII_IF_MODE_FORCE_DUPLEX;
mt753x_reg_write(gsw, SGMII_MODE(port_base), val);
/* Step 4: XXX: Disable Link partner's AN and set force mode */
/* Step 5: XXX: Special setting for PHYA ==> reserved for flexible */
/* Step 6 : Release PHYA power down state */
val = mt753x_reg_read(gsw, QPHY_PWR_STATE_CTRL(port_base));
val &= ~PHYA_PWD;
mt753x_reg_write(gsw, QPHY_PWR_STATE_CTRL(port_base), val);
/* Step 7 : Polling SGMII_LINK_STATUS */
timeout_us = 2000000;
timeout = ktime_add_us(ktime_get(), timeout_us);
while (1) {
val = mt753x_reg_read(gsw, PCS_CONTROL_1(port_base));
val &= SGMII_LINK_STATUS;
if (val)
break;
if (ktime_compare(ktime_get(), timeout) > 0)
return -ETIMEDOUT;
}
return 0;
}
static int mt7531_set_port_sgmii_an_mode(struct gsw_mt753x *gsw, u32 port,
struct mt753x_port_cfg *port_cfg)
{
u32 speed, port_base, val;
ktime_t timeout;
u32 timeout_us;
if (port < 5 || port >= MT753X_NUM_PORTS) {
dev_info(gsw->dev, "port %d is not a SGMII port\n", port);
return -EINVAL;
}
port_base = port - 5;
switch (port_cfg->speed) {
case MAC_SPD_1000:
speed = RG_TPHY_SPEED_1000;
break;
case MAC_SPD_2500:
speed = RG_TPHY_SPEED_2500;
break;
default:
dev_info(gsw->dev, "invalid SGMII speed idx %d for port %d\n",
port_cfg->speed, port);
speed = RG_TPHY_SPEED_1000;
}
/* Step 1: Speed select register setting */
val = mt753x_reg_read(gsw, PHYA_CTRL_SIGNAL3(port_base));
val &= ~RG_TPHY_SPEED_M;
val |= speed << RG_TPHY_SPEED_S;
mt753x_reg_write(gsw, PHYA_CTRL_SIGNAL3(port_base), val);
/* Step 2: Remote fault disable */
val = mt753x_reg_read(gsw, SGMII_MODE(port));
val |= SGMII_REMOTE_FAULT_DIS;
mt753x_reg_write(gsw, SGMII_MODE(port), val);
/* Step 3: Setting Link partner's AN enable = 1 */
/* Step 4: Setting Link partner's device ability for speed/duplex */
/* Step 5: AN re-start */
val = mt753x_reg_read(gsw, PCS_CONTROL_1(port));
val |= SGMII_AN_RESTART;
mt753x_reg_write(gsw, PCS_CONTROL_1(port), val);
/* Step 6: Special setting for PHYA ==> reserved for flexible */
/* Step 7 : Polling SGMII_LINK_STATUS */
timeout_us = 2000000;
timeout = ktime_add_us(ktime_get(), timeout_us);
while (1) {
val = mt753x_reg_read(gsw, PCS_CONTROL_1(port_base));
val &= SGMII_LINK_STATUS;
if (val)
break;
if (ktime_compare(ktime_get(), timeout) > 0)
return -ETIMEDOUT;
}
return 0;
}
static int mt7531_set_port_rgmii(struct gsw_mt753x *gsw, u32 port)
{
u32 val;
if (port != 5) {
dev_info(gsw->dev, "RGMII mode is not available for port %d\n",
port);
return -EINVAL;
}
val = mt753x_reg_read(gsw, CLKGEN_CTRL);
val |= GP_CLK_EN;
val &= ~GP_MODE_M;
val |= GP_MODE_RGMII << GP_MODE_S;
val |= TXCLK_NO_REVERSE;
val |= RXCLK_NO_DELAY;
val &= ~CLK_SKEW_IN_M;
val |= CLK_SKEW_IN_NO_CHANGE << CLK_SKEW_IN_S;
val &= ~CLK_SKEW_OUT_M;
val |= CLK_SKEW_OUT_NO_CHANGE << CLK_SKEW_OUT_S;
mt753x_reg_write(gsw, CLKGEN_CTRL, val);
return 0;
}
static int mt7531_mac_port_setup(struct gsw_mt753x *gsw, u32 port,
struct mt753x_port_cfg *port_cfg)
{
u32 pmcr;
u32 speed;
if (port < 5 || port >= MT753X_NUM_PORTS) {
dev_info(gsw->dev, "port %d is not a MAC port\n", port);
return -EINVAL;
}
if (port_cfg->enabled) {
pmcr = (IPG_96BIT_WITH_SHORT_IPG << IPG_CFG_S) |
MAC_MODE | MAC_TX_EN | MAC_RX_EN |
BKOFF_EN | BACKPR_EN;
if (port_cfg->force_link) {
/* PMCR's speed field 0x11 is reserved,
* sw should set 0x10
*/
speed = port_cfg->speed;
if (port_cfg->speed == MAC_SPD_2500)
speed = MAC_SPD_1000;
pmcr |= FORCE_MODE_LNK | FORCE_LINK |
FORCE_MODE_SPD | FORCE_MODE_DPX |
FORCE_MODE_RX_FC | FORCE_MODE_TX_FC |
FORCE_RX_FC | FORCE_TX_FC |
(speed << FORCE_SPD_S);
if (port_cfg->duplex)
pmcr |= FORCE_DPX;
}
} else {
pmcr = FORCE_MODE_LNK;
}
switch (port_cfg->phy_mode) {
case PHY_INTERFACE_MODE_RGMII:
mt7531_set_port_rgmii(gsw, port);
break;
case PHY_INTERFACE_MODE_SGMII:
if (port_cfg->force_link)
mt7531_set_port_sgmii_force_mode(gsw, port, port_cfg);
else
mt7531_set_port_sgmii_an_mode(gsw, port, port_cfg);
break;
default:
if (port_cfg->enabled)
dev_info(gsw->dev, "%s is not supported by port %d\n",
phy_modes(port_cfg->phy_mode), port);
pmcr = FORCE_MODE_LNK;
}
mt753x_reg_write(gsw, PMCR(port), pmcr);
return 0;
}
static void mt7531_core_pll_setup(struct gsw_mt753x *gsw)
{
u32 hwstrap;
u32 val;
val = mt753x_reg_read(gsw, TOP_SIG_SR);
if (val & PAD_DUAL_SGMII_EN)
return;
hwstrap = mt753x_reg_read(gsw, HWSTRAP);
switch ((hwstrap & XTAL_FSEL_M) >> XTAL_FSEL_S) {
case XTAL_25MHZ:
/* Step 1 : Disable MT7531 COREPLL */
val = mt753x_reg_read(gsw, PLLGP_EN);
val &= ~EN_COREPLL;
mt753x_reg_write(gsw, PLLGP_EN, val);
/* Step 2: switch to XTAL output */
val = mt753x_reg_read(gsw, PLLGP_EN);
val |= SW_CLKSW;
mt753x_reg_write(gsw, PLLGP_EN, val);
val = mt753x_reg_read(gsw, PLLGP_CR0);
val &= ~RG_COREPLL_EN;
mt753x_reg_write(gsw, PLLGP_CR0, val);
/* Step 3: disable PLLGP and enable program PLLGP */
val = mt753x_reg_read(gsw, PLLGP_EN);
val |= SW_PLLGP;
mt753x_reg_write(gsw, PLLGP_EN, val);
/* Step 4: program COREPLL output frequency to 500MHz */
val = mt753x_reg_read(gsw, PLLGP_CR0);
val &= ~RG_COREPLL_POSDIV_M;
val |= 2 << RG_COREPLL_POSDIV_S;
mt753x_reg_write(gsw, PLLGP_CR0, val);
usleep_range(25, 35);
val = mt753x_reg_read(gsw, PLLGP_CR0);
val &= ~RG_COREPLL_SDM_PCW_M;
val |= 0x140000 << RG_COREPLL_SDM_PCW_S;
mt753x_reg_write(gsw, PLLGP_CR0, val);
/* Set feedback divide ratio update signal to high */
val = mt753x_reg_read(gsw, PLLGP_CR0);
val |= RG_COREPLL_SDM_PCW_CHG;
mt753x_reg_write(gsw, PLLGP_CR0, val);
/* Wait for at least 16 XTAL clocks */
usleep_range(10, 20);
/* Step 5: set feedback divide ratio update signal to low */
val = mt753x_reg_read(gsw, PLLGP_CR0);
val &= ~RG_COREPLL_SDM_PCW_CHG;
mt753x_reg_write(gsw, PLLGP_CR0, val);
/* Enable 325M clock for SGMII */
mt753x_reg_write(gsw, ANA_PLLGP_CR5, 0xad0000);
/* Enable 250SSC clock for RGMII */
mt753x_reg_write(gsw, ANA_PLLGP_CR2, 0x4f40000);
/* Step 6: Enable MT7531 PLL */
val = mt753x_reg_read(gsw, PLLGP_CR0);
val |= RG_COREPLL_EN;
mt753x_reg_write(gsw, PLLGP_CR0, val);
val = mt753x_reg_read(gsw, PLLGP_EN);
val |= EN_COREPLL;
mt753x_reg_write(gsw, PLLGP_EN, val);
usleep_range(25, 35);
break;
case XTAL_40MHZ:
/* Step 1 : Disable MT7531 COREPLL */
val = mt753x_reg_read(gsw, PLLGP_EN);
val &= ~EN_COREPLL;
mt753x_reg_write(gsw, PLLGP_EN, val);
/* Step 2: switch to XTAL output */
val = mt753x_reg_read(gsw, PLLGP_EN);
val |= SW_CLKSW;
mt753x_reg_write(gsw, PLLGP_EN, val);
val = mt753x_reg_read(gsw, PLLGP_CR0);
val &= ~RG_COREPLL_EN;
mt753x_reg_write(gsw, PLLGP_CR0, val);
/* Step 3: disable PLLGP and enable program PLLGP */
val = mt753x_reg_read(gsw, PLLGP_EN);
val |= SW_PLLGP;
mt753x_reg_write(gsw, PLLGP_EN, val);
/* Step 4: program COREPLL output frequency to 500MHz */
val = mt753x_reg_read(gsw, PLLGP_CR0);
val &= ~RG_COREPLL_POSDIV_M;
val |= 2 << RG_COREPLL_POSDIV_S;
mt753x_reg_write(gsw, PLLGP_CR0, val);
usleep_range(25, 35);
val = mt753x_reg_read(gsw, PLLGP_CR0);
val &= ~RG_COREPLL_SDM_PCW_M;
val |= 0x190000 << RG_COREPLL_SDM_PCW_S;
mt753x_reg_write(gsw, PLLGP_CR0, val);
/* Set feedback divide ratio update signal to high */
val = mt753x_reg_read(gsw, PLLGP_CR0);
val |= RG_COREPLL_SDM_PCW_CHG;
mt753x_reg_write(gsw, PLLGP_CR0, val);
/* Wait for at least 16 XTAL clocks */
usleep_range(10, 20);
/* Step 5: set feedback divide ratio update signal to low */
val = mt753x_reg_read(gsw, PLLGP_CR0);
val &= ~RG_COREPLL_SDM_PCW_CHG;
mt753x_reg_write(gsw, PLLGP_CR0, val);
/* Enable 325M clock for SGMII */
mt753x_reg_write(gsw, ANA_PLLGP_CR5, 0xad0000);
/* Enable 250SSC clock for RGMII */
mt753x_reg_write(gsw, ANA_PLLGP_CR2, 0x4f40000);
/* Step 6: Enable MT7531 PLL */
val = mt753x_reg_read(gsw, PLLGP_CR0);
val |= RG_COREPLL_EN;
mt753x_reg_write(gsw, PLLGP_CR0, val);
val = mt753x_reg_read(gsw, PLLGP_EN);
val |= EN_COREPLL;
mt753x_reg_write(gsw, PLLGP_EN, val);
usleep_range(25, 35);
break;
}
}
static int mt7531_internal_phy_calibration(struct gsw_mt753x *gsw)
{
return 0;
}
static int mt7531_sw_detect(struct gsw_mt753x *gsw, struct chip_rev *crev)
{
u32 rev, topsig;
rev = mt753x_reg_read(gsw, CHIP_REV);
if (((rev & CHIP_NAME_M) >> CHIP_NAME_S) == MT7531) {
if (crev) {
topsig = mt753x_reg_read(gsw, TOP_SIG_SR);
crev->rev = rev & CHIP_REV_M;
crev->name = topsig & PAD_DUAL_SGMII_EN ?
"MT7531AE" : "MT7531BE";
}
return 0;
}
return -ENODEV;
}
static void pinmux_set_mux_7531(struct gsw_mt753x *gsw, u32 pin, u32 mode)
{
u32 val;
val = mt753x_reg_read(gsw, GPIO_MODE_REGS(pin));
val &= ~(0xf << (pin & 7) * GPIO_MODE_S);
val |= mode << (pin & 7) * GPIO_MODE_S;
mt753x_reg_write(gsw, GPIO_MODE_REGS(pin), val);
}
static int mt7531_set_gpio_pinmux(struct gsw_mt753x *gsw)
{
u32 group = 0;
struct device_node *np = gsw->dev->of_node;
/* Set GPIO 0 interrupt mode */
pinmux_set_mux_7531(gsw, gpio_int_pins[0], gpio_int_funcs[0]);
of_property_read_u32(np, "mediatek,mdio_master_pinmux", &group);
/* group = 0: do nothing, 1: 1st group (AE), 2: 2nd group (BE) */
if (group > 0 && group <= 2) {
group--;
pinmux_set_mux_7531(gsw, gpio_mdc_pins[group],
gpio_mdc_funcs[group]);
pinmux_set_mux_7531(gsw, gpio_mdio_pins[group],
gpio_mdio_funcs[group]);
}
return 0;
}
static void mt7531_phy_pll_setup(struct gsw_mt753x *gsw)
{
u32 hwstrap;
u32 val;
hwstrap = mt753x_reg_read(gsw, HWSTRAP);
switch ((hwstrap & XTAL_FSEL_M) >> XTAL_FSEL_S) {
case XTAL_25MHZ:
/* disable pll auto calibration */
gsw->mmd_write(gsw, 0, PHY_DEV1F, PHY_DEV1F_REG_104, 0x608);
/* change pll sel */
val = gsw->mmd_read(gsw, 0, PHY_DEV1F,
PHY_DEV1F_REG_403);
val &= ~(PHY_PLL_M);
val |= PHY_PLL_SEL(3);
gsw->mmd_write(gsw, 0, PHY_DEV1F, PHY_DEV1F_REG_403, val);
/* set divider ratio */
gsw->mmd_write(gsw, 0, PHY_DEV1F,
PHY_DEV1F_REG_10A, 0x1009);
/* set divider ratio */
gsw->mmd_write(gsw, 0, PHY_DEV1F, PHY_DEV1F_REG_10B, 0x7c6);
/* capacitance and resistance adjustment */
gsw->mmd_write(gsw, 0, PHY_DEV1F,
PHY_DEV1F_REG_10C, 0xa8be);
break;
case XTAL_40MHZ:
/* disable pll auto calibration */
gsw->mmd_write(gsw, 0, PHY_DEV1F, PHY_DEV1F_REG_104, 0x608);
/* change pll sel */
val = gsw->mmd_read(gsw, 0, PHY_DEV1F,
PHY_DEV1F_REG_403);
val &= ~(PHY_PLL_M);
val |= PHY_PLL_SEL(3);
gsw->mmd_write(gsw, 0, PHY_DEV1F, PHY_DEV1F_REG_403, val);
/* set divider ratio */
gsw->mmd_write(gsw, 0, PHY_DEV1F,
PHY_DEV1F_REG_10A, 0x1018);
/* set divider ratio */
gsw->mmd_write(gsw, 0, PHY_DEV1F, PHY_DEV1F_REG_10B, 0xc676);
/* capacitance and resistance adjustment */
gsw->mmd_write(gsw, 0, PHY_DEV1F,
PHY_DEV1F_REG_10C, 0xd8be);
break;
}
/* power down pll. additional delay is not required via mdio access */
gsw->mmd_write(gsw, 0, PHY_DEV1F, PHY_DEV1F_REG_10D, 0x10);
/* power up pll */
gsw->mmd_write(gsw, 0, PHY_DEV1F, PHY_DEV1F_REG_10D, 0x14);
}
static void mt7531_phy_setting(struct gsw_mt753x *gsw)
{
int i;
u32 val;
/* Adjust DAC TX Delay */
gsw->mmd_write(gsw, 0, PHY_DEV1F, PHY_DEV1F_REG_44, 0xc0);
for (i = 0; i < MT753X_NUM_PHYS; i++) {
/* Disable EEE */
gsw->mmd_write(gsw, i, PHY_DEV07, PHY_DEV07_REG_03C, 0);
/* Enable HW auto downshift */
gsw->mii_write(gsw, i, 0x1f, 0x1);
val = gsw->mii_read(gsw, i, PHY_EXT_REG_14);
val |= PHY_EN_DOWN_SHFIT;
gsw->mii_write(gsw, i, PHY_EXT_REG_14, val);
/* Increase SlvDPSready time */
gsw->mii_write(gsw, i, 0x1f, 0x52b5);
gsw->mii_write(gsw, i, PHY_TR_REG_10, 0xafae);
gsw->mii_write(gsw, i, PHY_TR_REG_12, 0x2f);
gsw->mii_write(gsw, i, PHY_TR_REG_10, 0x8fae);
gsw->mii_write(gsw, i, 0x1f, 0);
/* Adjust 100_mse_threshold */
gsw->mmd_write(gsw, i, PHY_DEV1E, PHY_DEV1E_REG_123, 0xffff);
/* Disable mcc */
gsw->mmd_write(gsw, i, PHY_DEV1E, PHY_DEV1E_REG_A6, 0x300);
/* PHY link down power saving enable */
val = gsw->mii_read(gsw, i, PHY_EXT_REG_17);
val |= PHY_LINKDOWN_POWER_SAVING_EN;
gsw->mii_write(gsw, i, PHY_EXT_REG_17, val);
val = gsw->mmd_read(gsw, i, PHY_DEV1E, PHY_DEV1E_REG_0C6);
val &= ~PHY_POWER_SAVING_M;
val |= PHY_POWER_SAVING_TX << PHY_POWER_SAVING_S;
gsw->mmd_write(gsw, i, PHY_DEV1E, PHY_DEV1E_REG_0C6, val);
/* Set TX Pair delay selection */
gsw->mmd_write(gsw, i, PHY_DEV1E, PHY_DEV1E_REG_13, 0x404);
gsw->mmd_write(gsw, i, PHY_DEV1E, PHY_DEV1E_REG_14, 0x404);
}
}
static void mt7531_adjust_line_driving(struct gsw_mt753x *gsw, u32 port)
{
/* For ADC timing margin window for LDO calibration */
gsw->mmd_write(gsw, port, PHY_DEV1E, RXADC_LDO_CONTROL_2, 0x2222);
/* Adjust AD sample timing */
gsw->mmd_write(gsw, port, PHY_DEV1E, RXADC_CONTROL_3, 0x4444);
/* Adjust Line driver current for different mode */
gsw->mmd_write(gsw, port, PHY_DEV1F, TXVLD_DA_271, 0x2ca5);
/* Adjust Line driver current for different mode */
gsw->mmd_write(gsw, port, PHY_DEV1F, TXVLD_DA_272, 0xc6b);
/* Adjust Line driver amplitude for 10BT */
gsw->mmd_write(gsw, port, PHY_DEV1F, TXVLD_DA_273, 0x3000);
/* Adjust RX Echo path filter */
gsw->mmd_write(gsw, port, PHY_DEV1E, PHY_DEV1E_REG_0FE, 0x2);
/* Adjust RX HVGA bias current */
gsw->mmd_write(gsw, port, PHY_DEV1E, PHY_DEV1E_REG_41, 0x3333);
/* Adjust TX class AB driver 1 */
gsw->mmd_write(gsw, port, PHY_DEV1F, PHY_DEV1F_REG_268, 0x388);
/* Adjust TX class AB driver 2 */
gsw->mmd_write(gsw, port, PHY_DEV1F, PHY_DEV1F_REG_269, 0x4448);
}
static void mt7531_eee_setting(struct gsw_mt753x *gsw, u32 port)
{
u32 tr_reg_control;
u32 val;
/* Disable generate signal to clear the scramble_lock when lpi mode */
val = gsw->mmd_read(gsw, port, PHY_DEV1E, PHY_DEV1E_REG_189);
val &= ~DESCRAMBLER_CLEAR_EN;
gsw->mmd_write(gsw, port, PHY_DEV1E, PHY_DEV1E_REG_189, val);
/* roll back CR*/
gsw->mii_write(gsw, port, 0x1f, 0x52b5);
gsw->mmd_write(gsw, port, 0x1e, 0x2d1, 0);
tr_reg_control = (1 << 15) | (0 << 13) | (DSP_CH << 11) |
(DSP_NOD_ADDR << 7) | (0x8 << 1);
gsw->mii_write(gsw, port, 17, 0x1b);
gsw->mii_write(gsw, port, 18, 0);
gsw->mii_write(gsw, port, 16, tr_reg_control);
tr_reg_control = (1 << 15) | (0 << 13) | (DSP_CH << 11) |
(DSP_NOD_ADDR << 7) | (0xf << 1);
gsw->mii_write(gsw, port, 17, 0);
gsw->mii_write(gsw, port, 18, 0);
gsw->mii_write(gsw, port, 16, tr_reg_control);
tr_reg_control = (1 << 15) | (0 << 13) | (DSP_CH << 11) |
(DSP_NOD_ADDR << 7) | (0x10 << 1);
gsw->mii_write(gsw, port, 17, 0x500);
gsw->mii_write(gsw, port, 18, 0);
gsw->mii_write(gsw, port, 16, tr_reg_control);
gsw->mii_write(gsw, port, 0x1f, 0);
}
static int mt7531_sw_init(struct gsw_mt753x *gsw)
{
int i;
u32 val;
gsw->phy_base = (gsw->smi_addr + 1) & MT753X_SMI_ADDR_MASK;
gsw->mii_read = mt753x_mii_read;
gsw->mii_write = mt753x_mii_write;
gsw->mmd_read = mt753x_mmd_read;
gsw->mmd_write = mt753x_mmd_write;
for (i = 0; i < MT753X_NUM_PHYS; i++) {
val = gsw->mii_read(gsw, i, MII_BMCR);
val |= BMCR_ISOLATE;
gsw->mii_write(gsw, i, MII_BMCR, val);
}
/* Force MAC link down before reset */
mt753x_reg_write(gsw, PMCR(5), FORCE_MODE_LNK);
mt753x_reg_write(gsw, PMCR(6), FORCE_MODE_LNK);
/* Switch soft reset */
mt753x_reg_write(gsw, SYS_CTRL, SW_SYS_RST | SW_REG_RST);
usleep_range(10, 20);
/* Enable MDC input Schmitt Trigger */
val = mt753x_reg_read(gsw, SMT0_IOLB);
mt753x_reg_write(gsw, SMT0_IOLB, val | SMT_IOLB_5_SMI_MDC_EN);
/* Set 7531 gpio pinmux */
mt7531_set_gpio_pinmux(gsw);
/* Global mac control settings */
mt753x_reg_write(gsw, GMACCR,
(15 << MTCC_LMT_S) | (11 << MAX_RX_JUMBO_S) |
RX_PKT_LEN_MAX_JUMBO);
mt7531_core_pll_setup(gsw);
mt7531_mac_port_setup(gsw, 5, &gsw->port5_cfg);
mt7531_mac_port_setup(gsw, 6, &gsw->port6_cfg);
return 0;
}
static int mt7531_sw_post_init(struct gsw_mt753x *gsw)
{
int i;
u32 val;
mt7531_phy_pll_setup(gsw);
/* Internal PHYs are disabled by default. SW should enable them.
* Note that this may already be enabled in bootloader stage.
*/
val = gsw->mmd_read(gsw, 0, PHY_DEV1F, PHY_DEV1F_REG_403);
val |= PHY_EN_BYPASS_MODE;
val &= ~POWER_ON_OFF;
gsw->mmd_write(gsw, 0, PHY_DEV1F, PHY_DEV1F_REG_403, val);
mt7531_phy_setting(gsw);
for (i = 0; i < MT753X_NUM_PHYS; i++) {
val = gsw->mii_read(gsw, i, MII_BMCR);
val &= ~BMCR_ISOLATE;
gsw->mii_write(gsw, i, MII_BMCR, val);
}
for (i = 0; i < MT753X_NUM_PHYS; i++)
mt7531_adjust_line_driving(gsw, i);
for (i = 0; i < MT753X_NUM_PHYS; i++)
mt7531_eee_setting(gsw, i);
val = mt753x_reg_read(gsw, CHIP_REV);
val &= CHIP_REV_M;
if (val == CHIP_REV_E1) {
mt7531_internal_phy_calibration(gsw);
} else {
val = mt753x_reg_read(gsw, GBE_EFUSE);
if (val & GBE_SEL_EFUSE_EN) {
val = gsw->mmd_read(gsw, 0, PHY_DEV1F,
PHY_DEV1F_REG_403);
val &= ~GBE_EFUSE_SETTING;
gsw->mmd_write(gsw, 0, PHY_DEV1F, PHY_DEV1F_REG_403,
val);
} else {
mt7531_internal_phy_calibration(gsw);
}
}
return 0;
}
struct mt753x_sw_id mt7531_id = {
.model = MT7531,
.detect = mt7531_sw_detect,
.init = mt7531_sw_init,
.post_init = mt7531_sw_post_init
};
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Zhanguo Ju <zhanguo.ju@mediatek.com>");
MODULE_DESCRIPTION("Driver for MediaTek MT753x Gigabit Switch");

View File

@ -1,13 +0,0 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Copyright (c) 2018 MediaTek Inc.
*/
#ifndef _MT7531_H_
#define _MT7531_H_
#include "mt753x.h"
extern struct mt753x_sw_id mt7531_id;
#endif /* _MT7531_H_ */

View File

@ -1,213 +0,0 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Copyright (c) 2018 MediaTek Inc.
* Author: Weijie Gao <weijie.gao@mediatek.com>
*/
#ifndef _MT753X_H_
#define _MT753X_H_
#include <linux/list.h>
#include <linux/mutex.h>
#include <linux/netdevice.h>
#include <linux/of_mdio.h>
#include <linux/workqueue.h>
#include <linux/gpio/consumer.h>
#ifdef CONFIG_SWCONFIG
#include <linux/switch.h>
#endif
#include "mt753x_vlan.h"
#define MT753X_DFL_CPU_PORT 6
#define MT753X_NUM_PHYS 5
#define MT753X_DFL_SMI_ADDR 0x1f
#define MT753X_SMI_ADDR_MASK 0x1f
struct gsw_mt753x;
enum mt753x_model {
MT7530 = 0x7530,
MT7531 = 0x7531
};
struct mt753x_port_cfg {
struct device_node *np;
phy_interface_t phy_mode;
u32 enabled: 1;
u32 force_link: 1;
u32 speed: 2;
u32 duplex: 1;
};
struct mt753x_phy {
struct gsw_mt753x *gsw;
struct net_device netdev;
struct phy_device *phydev;
};
struct gsw_mt753x {
u32 id;
struct device *dev;
struct mii_bus *host_bus;
struct mii_bus *gphy_bus;
struct mutex mii_lock; /* MII access lock */
u32 smi_addr;
u32 phy_base;
int direct_phy_access;
enum mt753x_model model;
const char *name;
struct mt753x_port_cfg port5_cfg;
struct mt753x_port_cfg port6_cfg;
int phy_status_poll;
struct mt753x_phy phys[MT753X_NUM_PHYS];
int phy_link_sts;
int irq;
int reset_pin;
struct work_struct irq_worker;
#ifdef CONFIG_SWCONFIG
struct switch_dev swdev;
u32 cpu_port;
#endif
int global_vlan_enable;
struct mt753x_vlan_entry vlan_entries[MT753X_NUM_VLANS];
struct mt753x_port_entry port_entries[MT753X_NUM_PORTS];
int (*mii_read)(struct gsw_mt753x *gsw, int phy, int reg);
void (*mii_write)(struct gsw_mt753x *gsw, int phy, int reg, u16 val);
int (*mmd_read)(struct gsw_mt753x *gsw, int addr, int devad, u16 reg);
void (*mmd_write)(struct gsw_mt753x *gsw, int addr, int devad, u16 reg,
u16 val);
struct list_head list;
};
struct chip_rev {
const char *name;
u32 rev;
};
struct mt753x_sw_id {
enum mt753x_model model;
int (*detect)(struct gsw_mt753x *gsw, struct chip_rev *crev);
int (*init)(struct gsw_mt753x *gsw);
int (*post_init)(struct gsw_mt753x *gsw);
};
extern struct list_head mt753x_devs;
struct gsw_mt753x *mt753x_get_gsw(u32 id);
struct gsw_mt753x *mt753x_get_first_gsw(void);
void mt753x_put_gsw(void);
void mt753x_lock_gsw(void);
u32 mt753x_reg_read(struct gsw_mt753x *gsw, u32 reg);
void mt753x_reg_write(struct gsw_mt753x *gsw, u32 reg, u32 val);
int mt753x_mii_read(struct gsw_mt753x *gsw, int phy, int reg);
void mt753x_mii_write(struct gsw_mt753x *gsw, int phy, int reg, u16 val);
int mt753x_mmd_read(struct gsw_mt753x *gsw, int addr, int devad, u16 reg);
void mt753x_mmd_write(struct gsw_mt753x *gsw, int addr, int devad, u16 reg,
u16 val);
int mt753x_mmd_ind_read(struct gsw_mt753x *gsw, int addr, int devad, u16 reg);
void mt753x_mmd_ind_write(struct gsw_mt753x *gsw, int addr, int devad, u16 reg,
u16 val);
void mt753x_irq_worker(struct work_struct *work);
void mt753x_irq_enable(struct gsw_mt753x *gsw);
/* MDIO Indirect Access Registers */
#define MII_MMD_ACC_CTL_REG 0x0d
#define MMD_CMD_S 14
#define MMD_CMD_M 0xc000
#define MMD_DEVAD_S 0
#define MMD_DEVAD_M 0x1f
/* MMD_CMD: MMD commands */
#define MMD_ADDR 0
#define MMD_DATA 1
#define MII_MMD_ADDR_DATA_REG 0x0e
/* Procedure of MT753x Internal Register Access
*
* 1. Internal Register Address
*
* The MT753x has a 16-bit register address and each register is 32-bit.
* This means the lowest two bits are not used as the register address is
* 4-byte aligned.
*
* Rest of the valid bits are divided into two parts:
* Bit 15..6 is the Page address
* Bit 5..2 is the low address
*
* -------------------------------------------------------------------
* | 15 14 13 12 11 10 9 8 7 6 | 5 4 3 2 | 1 0 |
* |----------------------------------------|---------------|--------|
* | Page Address | Address | Unused |
* -------------------------------------------------------------------
*
* 2. MDIO access timing
*
* The MT753x uses the following MDIO timing for a single register read
*
* Phase 1: Write Page Address
* -------------------------------------------------------------------
* | ST | OP | PHY_ADDR | TYPE | RSVD | TA | RSVD | PAGE_ADDR |
* -------------------------------------------------------------------
* | 01 | 01 | 11111 | 1 | 1111 | xx | 00000 | REG_ADDR[15..6] |
* -------------------------------------------------------------------
*
* Phase 2: Write low Address & Read low word
* -------------------------------------------------------------------
* | ST | OP | PHY_ADDR | TYPE | LOW_ADDR | TA | DATA |
* -------------------------------------------------------------------
* | 01 | 10 | 11111 | 0 | REG_ADDR[5..2] | xx | DATA[15..0] |
* -------------------------------------------------------------------
*
* Phase 3: Read high word
* -------------------------------------------------------------------
* | ST | OP | PHY_ADDR | TYPE | RSVD | TA | DATA |
* -------------------------------------------------------------------
* | 01 | 10 | 11111 | 1 | 0000 | xx | DATA[31..16] |
* -------------------------------------------------------------------
*
* The MT753x uses the following MDIO timing for a single register write
*
* Phase 1: Write Page Address (The same as read)
*
* Phase 2: Write low Address and low word
* -------------------------------------------------------------------
* | ST | OP | PHY_ADDR | TYPE | LOW_ADDR | TA | DATA |
* -------------------------------------------------------------------
* | 01 | 01 | 11111 | 0 | REG_ADDR[5..2] | xx | DATA[15..0] |
* -------------------------------------------------------------------
*
* Phase 3: write high word
* -------------------------------------------------------------------
* | ST | OP | PHY_ADDR | TYPE | RSVD | TA | DATA |
* -------------------------------------------------------------------
* | 01 | 01 | 11111 | 1 | 0000 | xx | DATA[31..16] |
* -------------------------------------------------------------------
*
*/
/* Internal Register Address fields */
#define MT753X_REG_PAGE_ADDR_S 6
#define MT753X_REG_PAGE_ADDR_M 0xffc0
#define MT753X_REG_ADDR_S 2
#define MT753X_REG_ADDR_M 0x3c
#endif /* _MT753X_H_ */

View File

@ -1,90 +0,0 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
* Copyright (c) 2018 MediaTek Inc.
* Author: Weijie Gao <weijie.gao@mediatek.com>
*/
#include <linux/kernel.h>
#include <linux/delay.h>
#include "mt753x.h"
#include "mt753x_regs.h"
void mt753x_irq_enable(struct gsw_mt753x *gsw)
{
u32 val;
int i;
/* Record initial PHY link status */
for (i = 0; i < MT753X_NUM_PHYS; i++) {
val = gsw->mii_read(gsw, i, MII_BMSR);
if (val & BMSR_LSTATUS)
gsw->phy_link_sts |= BIT(i);
}
val = BIT(MT753X_NUM_PHYS) - 1;
mt753x_reg_write(gsw, SYS_INT_EN, val);
}
static void display_port_link_status(struct gsw_mt753x *gsw, u32 port)
{
u32 pmsr, speed_bits;
const char *speed;
pmsr = mt753x_reg_read(gsw, PMSR(port));
speed_bits = (pmsr & MAC_SPD_STS_M) >> MAC_SPD_STS_S;
switch (speed_bits) {
case MAC_SPD_10:
speed = "10Mbps";
break;
case MAC_SPD_100:
speed = "100Mbps";
break;
case MAC_SPD_1000:
speed = "1Gbps";
break;
case MAC_SPD_2500:
speed = "2.5Gbps";
break;
}
if (pmsr & MAC_LNK_STS) {
dev_info(gsw->dev, "Port %d Link is Up - %s/%s\n",
port, speed, (pmsr & MAC_DPX_STS) ? "Full" : "Half");
} else {
dev_info(gsw->dev, "Port %d Link is Down\n", port);
}
}
void mt753x_irq_worker(struct work_struct *work)
{
struct gsw_mt753x *gsw;
u32 sts, physts, laststs;
int i;
gsw = container_of(work, struct gsw_mt753x, irq_worker);
sts = mt753x_reg_read(gsw, SYS_INT_STS);
/* Check for changed PHY link status */
for (i = 0; i < MT753X_NUM_PHYS; i++) {
if (!(sts & PHY_LC_INT(i)))
continue;
laststs = gsw->phy_link_sts & BIT(i);
physts = !!(gsw->mii_read(gsw, i, MII_BMSR) & BMSR_LSTATUS);
physts <<= i;
if (physts ^ laststs) {
gsw->phy_link_sts ^= BIT(i);
display_port_link_status(gsw, i);
}
}
mt753x_reg_write(gsw, SYS_INT_STS, sts);
enable_irq(gsw->irq);
}

View File

@ -1,597 +0,0 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
* Copyright (c) 2018 MediaTek Inc.
* Author: Weijie Gao <weijie.gao@mediatek.com>
*/
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/device.h>
#include <linux/delay.h>
#include <linux/reset.h>
#include <linux/hrtimer.h>
#include <linux/mii.h>
#include <linux/of_mdio.h>
#include <linux/of_platform.h>
#include <linux/of_gpio.h>
#include <linux/of_net.h>
#include <linux/of_irq.h>
#include <linux/phy.h>
#include "mt753x.h"
#include "mt753x_swconfig.h"
#include "mt753x_regs.h"
#include "mt753x_nl.h"
#include "mt7530.h"
#include "mt7531.h"
static u32 mt753x_id;
struct list_head mt753x_devs;
static DEFINE_MUTEX(mt753x_devs_lock);
static struct mt753x_sw_id *mt753x_sw_ids[] = {
&mt7530_id,
&mt7531_id,
};
u32 mt753x_reg_read(struct gsw_mt753x *gsw, u32 reg)
{
u32 high, low;
mutex_lock(&gsw->host_bus->mdio_lock);
gsw->host_bus->write(gsw->host_bus, gsw->smi_addr, 0x1f,
(reg & MT753X_REG_PAGE_ADDR_M) >> MT753X_REG_PAGE_ADDR_S);
low = gsw->host_bus->read(gsw->host_bus, gsw->smi_addr,
(reg & MT753X_REG_ADDR_M) >> MT753X_REG_ADDR_S);
high = gsw->host_bus->read(gsw->host_bus, gsw->smi_addr, 0x10);
mutex_unlock(&gsw->host_bus->mdio_lock);
return (high << 16) | (low & 0xffff);
}
void mt753x_reg_write(struct gsw_mt753x *gsw, u32 reg, u32 val)
{
mutex_lock(&gsw->host_bus->mdio_lock);
gsw->host_bus->write(gsw->host_bus, gsw->smi_addr, 0x1f,
(reg & MT753X_REG_PAGE_ADDR_M) >> MT753X_REG_PAGE_ADDR_S);
gsw->host_bus->write(gsw->host_bus, gsw->smi_addr,
(reg & MT753X_REG_ADDR_M) >> MT753X_REG_ADDR_S, val & 0xffff);
gsw->host_bus->write(gsw->host_bus, gsw->smi_addr, 0x10, val >> 16);
mutex_unlock(&gsw->host_bus->mdio_lock);
}
/* Indirect MDIO clause 22/45 access */
static int mt753x_mii_rw(struct gsw_mt753x *gsw, int phy, int reg, u16 data,
u32 cmd, u32 st)
{
ktime_t timeout;
u32 val, timeout_us;
int ret = 0;
timeout_us = 100000;
timeout = ktime_add_us(ktime_get(), timeout_us);
while (1) {
val = mt753x_reg_read(gsw, PHY_IAC);
if ((val & PHY_ACS_ST) == 0)
break;
if (ktime_compare(ktime_get(), timeout) > 0)
return -ETIMEDOUT;
}
val = (st << MDIO_ST_S) |
((cmd << MDIO_CMD_S) & MDIO_CMD_M) |
((phy << MDIO_PHY_ADDR_S) & MDIO_PHY_ADDR_M) |
((reg << MDIO_REG_ADDR_S) & MDIO_REG_ADDR_M);
if (cmd == MDIO_CMD_WRITE || cmd == MDIO_CMD_ADDR)
val |= data & MDIO_RW_DATA_M;
mt753x_reg_write(gsw, PHY_IAC, val | PHY_ACS_ST);
timeout_us = 100000;
timeout = ktime_add_us(ktime_get(), timeout_us);
while (1) {
val = mt753x_reg_read(gsw, PHY_IAC);
if ((val & PHY_ACS_ST) == 0)
break;
if (ktime_compare(ktime_get(), timeout) > 0)
return -ETIMEDOUT;
}
if (cmd == MDIO_CMD_READ || cmd == MDIO_CMD_READ_C45) {
val = mt753x_reg_read(gsw, PHY_IAC);
ret = val & MDIO_RW_DATA_M;
}
return ret;
}
int mt753x_mii_read(struct gsw_mt753x *gsw, int phy, int reg)
{
int val;
if (phy < MT753X_NUM_PHYS)
phy = (gsw->phy_base + phy) & MT753X_SMI_ADDR_MASK;
mutex_lock(&gsw->mii_lock);
val = mt753x_mii_rw(gsw, phy, reg, 0, MDIO_CMD_READ, MDIO_ST_C22);
mutex_unlock(&gsw->mii_lock);
return val;
}
void mt753x_mii_write(struct gsw_mt753x *gsw, int phy, int reg, u16 val)
{
if (phy < MT753X_NUM_PHYS)
phy = (gsw->phy_base + phy) & MT753X_SMI_ADDR_MASK;
mutex_lock(&gsw->mii_lock);
mt753x_mii_rw(gsw, phy, reg, val, MDIO_CMD_WRITE, MDIO_ST_C22);
mutex_unlock(&gsw->mii_lock);
}
int mt753x_mmd_read(struct gsw_mt753x *gsw, int addr, int devad, u16 reg)
{
int val;
if (addr < MT753X_NUM_PHYS)
addr = (gsw->phy_base + addr) & MT753X_SMI_ADDR_MASK;
mutex_lock(&gsw->mii_lock);
mt753x_mii_rw(gsw, addr, devad, reg, MDIO_CMD_ADDR, MDIO_ST_C45);
val = mt753x_mii_rw(gsw, addr, devad, 0, MDIO_CMD_READ_C45,
MDIO_ST_C45);
mutex_unlock(&gsw->mii_lock);
return val;
}
void mt753x_mmd_write(struct gsw_mt753x *gsw, int addr, int devad, u16 reg,
u16 val)
{
if (addr < MT753X_NUM_PHYS)
addr = (gsw->phy_base + addr) & MT753X_SMI_ADDR_MASK;
mutex_lock(&gsw->mii_lock);
mt753x_mii_rw(gsw, addr, devad, reg, MDIO_CMD_ADDR, MDIO_ST_C45);
mt753x_mii_rw(gsw, addr, devad, val, MDIO_CMD_WRITE, MDIO_ST_C45);
mutex_unlock(&gsw->mii_lock);
}
int mt753x_mmd_ind_read(struct gsw_mt753x *gsw, int addr, int devad, u16 reg)
{
u16 val;
if (addr < MT753X_NUM_PHYS)
addr = (gsw->phy_base + addr) & MT753X_SMI_ADDR_MASK;
mutex_lock(&gsw->mii_lock);
mt753x_mii_rw(gsw, addr, MII_MMD_ACC_CTL_REG,
(MMD_ADDR << MMD_CMD_S) |
((devad << MMD_DEVAD_S) & MMD_DEVAD_M),
MDIO_CMD_WRITE, MDIO_ST_C22);
mt753x_mii_rw(gsw, addr, MII_MMD_ADDR_DATA_REG, reg,
MDIO_CMD_WRITE, MDIO_ST_C22);
mt753x_mii_rw(gsw, addr, MII_MMD_ACC_CTL_REG,
(MMD_DATA << MMD_CMD_S) |
((devad << MMD_DEVAD_S) & MMD_DEVAD_M),
MDIO_CMD_WRITE, MDIO_ST_C22);
val = mt753x_mii_rw(gsw, addr, MII_MMD_ADDR_DATA_REG, 0,
MDIO_CMD_READ, MDIO_ST_C22);
mutex_unlock(&gsw->mii_lock);
return val;
}
void mt753x_mmd_ind_write(struct gsw_mt753x *gsw, int addr, int devad, u16 reg,
u16 val)
{
if (addr < MT753X_NUM_PHYS)
addr = (gsw->phy_base + addr) & MT753X_SMI_ADDR_MASK;
mutex_lock(&gsw->mii_lock);
mt753x_mii_rw(gsw, addr, MII_MMD_ACC_CTL_REG,
(MMD_ADDR << MMD_CMD_S) |
((devad << MMD_DEVAD_S) & MMD_DEVAD_M),
MDIO_CMD_WRITE, MDIO_ST_C22);
mt753x_mii_rw(gsw, addr, MII_MMD_ADDR_DATA_REG, reg,
MDIO_CMD_WRITE, MDIO_ST_C22);
mt753x_mii_rw(gsw, addr, MII_MMD_ACC_CTL_REG,
(MMD_DATA << MMD_CMD_S) |
((devad << MMD_DEVAD_S) & MMD_DEVAD_M),
MDIO_CMD_WRITE, MDIO_ST_C22);
mt753x_mii_rw(gsw, addr, MII_MMD_ADDR_DATA_REG, val,
MDIO_CMD_WRITE, MDIO_ST_C22);
mutex_unlock(&gsw->mii_lock);
}
static inline int mt753x_get_duplex(const struct device_node *np)
{
return of_property_read_bool(np, "full-duplex");
}
static void mt753x_load_port_cfg(struct gsw_mt753x *gsw)
{
struct device_node *port_np;
struct device_node *fixed_link_node;
struct mt753x_port_cfg *port_cfg;
u32 port;
for_each_child_of_node(gsw->dev->of_node, port_np) {
if (!of_device_is_compatible(port_np, "mediatek,mt753x-port"))
continue;
if (!of_device_is_available(port_np))
continue;
if (of_property_read_u32(port_np, "reg", &port))
continue;
switch (port) {
case 5:
port_cfg = &gsw->port5_cfg;
break;
case 6:
port_cfg = &gsw->port6_cfg;
break;
default:
continue;
}
if (port_cfg->enabled) {
dev_info(gsw->dev, "duplicated node for port%d\n",
port_cfg->phy_mode);
continue;
}
port_cfg->np = port_np;
if (of_get_phy_mode(port_np, &port_cfg->phy_mode) < 0) {
dev_info(gsw->dev, "incorrect phy-mode %d\n", port);
continue;
}
fixed_link_node = of_get_child_by_name(port_np, "fixed-link");
if (fixed_link_node) {
u32 speed;
port_cfg->force_link = 1;
port_cfg->duplex = mt753x_get_duplex(fixed_link_node);
if (of_property_read_u32(fixed_link_node, "speed",
&speed)) {
speed = 0;
continue;
}
of_node_put(fixed_link_node);
switch (speed) {
case 10:
port_cfg->speed = MAC_SPD_10;
break;
case 100:
port_cfg->speed = MAC_SPD_100;
break;
case 1000:
port_cfg->speed = MAC_SPD_1000;
break;
case 2500:
port_cfg->speed = MAC_SPD_2500;
break;
default:
dev_info(gsw->dev, "incorrect speed %d\n",
speed);
continue;
}
}
port_cfg->enabled = 1;
}
}
static void mt753x_add_gsw(struct gsw_mt753x *gsw)
{
mutex_lock(&mt753x_devs_lock);
gsw->id = mt753x_id++;
INIT_LIST_HEAD(&gsw->list);
list_add_tail(&gsw->list, &mt753x_devs);
mutex_unlock(&mt753x_devs_lock);
}
static void mt753x_remove_gsw(struct gsw_mt753x *gsw)
{
mutex_lock(&mt753x_devs_lock);
list_del(&gsw->list);
mutex_unlock(&mt753x_devs_lock);
}
struct gsw_mt753x *mt753x_get_gsw(u32 id)
{
struct gsw_mt753x *dev;
mutex_lock(&mt753x_devs_lock);
list_for_each_entry(dev, &mt753x_devs, list) {
if (dev->id == id)
return dev;
}
mutex_unlock(&mt753x_devs_lock);
return NULL;
}
struct gsw_mt753x *mt753x_get_first_gsw(void)
{
struct gsw_mt753x *dev;
mutex_lock(&mt753x_devs_lock);
list_for_each_entry(dev, &mt753x_devs, list)
return dev;
mutex_unlock(&mt753x_devs_lock);
return NULL;
}
void mt753x_put_gsw(void)
{
mutex_unlock(&mt753x_devs_lock);
}
void mt753x_lock_gsw(void)
{
mutex_lock(&mt753x_devs_lock);
}
static int mt753x_hw_reset(struct gsw_mt753x *gsw)
{
struct device_node *np = gsw->dev->of_node;
struct reset_control *rstc;
int mcm;
int ret = -EINVAL;
mcm = of_property_read_bool(np, "mediatek,mcm");
if (mcm) {
rstc = devm_reset_control_get(gsw->dev, "mcm");
ret = IS_ERR(rstc);
if (IS_ERR(rstc)) {
dev_err(gsw->dev, "Missing reset ctrl of switch\n");
return ret;
}
reset_control_assert(rstc);
msleep(30);
reset_control_deassert(rstc);
gsw->reset_pin = -1;
return 0;
}
gsw->reset_pin = of_get_named_gpio(np, "reset-gpios", 0);
if (gsw->reset_pin < 0) {
dev_err(gsw->dev, "Missing reset pin of switch\n");
return ret;
}
ret = devm_gpio_request(gsw->dev, gsw->reset_pin, "mt753x-reset");
if (ret) {
dev_info(gsw->dev, "Failed to request gpio %d\n",
gsw->reset_pin);
return ret;
}
gpio_direction_output(gsw->reset_pin, 0);
msleep(30);
gpio_set_value(gsw->reset_pin, 1);
msleep(500);
return 0;
}
static irqreturn_t mt753x_irq_handler(int irq, void *dev)
{
struct gsw_mt753x *gsw = dev;
disable_irq_nosync(gsw->irq);
schedule_work(&gsw->irq_worker);
return IRQ_HANDLED;
}
static int mt753x_probe(struct platform_device *pdev)
{
struct gsw_mt753x *gsw;
struct mt753x_sw_id *sw;
struct device_node *np = pdev->dev.of_node;
struct device_node *mdio;
struct mii_bus *mdio_bus;
int ret = -EINVAL;
struct chip_rev rev;
struct mt753x_mapping *map;
int i;
mdio = of_parse_phandle(np, "mediatek,mdio", 0);
if (!mdio)
return -EINVAL;
mdio_bus = of_mdio_find_bus(mdio);
if (!mdio_bus)
return -EPROBE_DEFER;
gsw = devm_kzalloc(&pdev->dev, sizeof(struct gsw_mt753x), GFP_KERNEL);
if (!gsw)
return -ENOMEM;
gsw->host_bus = mdio_bus;
gsw->dev = &pdev->dev;
mutex_init(&gsw->mii_lock);
/* Switch hard reset */
if (mt753x_hw_reset(gsw))
goto fail;
/* Fetch the SMI address dirst */
if (of_property_read_u32(np, "mediatek,smi-addr", &gsw->smi_addr))
gsw->smi_addr = MT753X_DFL_SMI_ADDR;
/* Get LAN/WAN port mapping */
map = mt753x_find_mapping(np);
if (map) {
mt753x_apply_mapping(gsw, map);
gsw->global_vlan_enable = 1;
dev_info(gsw->dev, "LAN/WAN VLAN setting=%s\n", map->name);
}
/* Load MAC port configurations */
mt753x_load_port_cfg(gsw);
/* Check for valid switch and then initialize */
for (i = 0; i < ARRAY_SIZE(mt753x_sw_ids); i++) {
if (!mt753x_sw_ids[i]->detect(gsw, &rev)) {
sw = mt753x_sw_ids[i];
gsw->name = rev.name;
gsw->model = sw->model;
dev_info(gsw->dev, "Switch is MediaTek %s rev %d",
gsw->name, rev.rev);
/* Initialize the switch */
ret = sw->init(gsw);
if (ret)
goto fail;
break;
}
}
if (i >= ARRAY_SIZE(mt753x_sw_ids)) {
dev_err(gsw->dev, "No mt753x switch found\n");
goto fail;
}
gsw->irq = platform_get_irq(pdev, 0);
if (gsw->irq >= 0) {
ret = devm_request_irq(gsw->dev, gsw->irq, mt753x_irq_handler,
0, dev_name(gsw->dev), gsw);
if (ret) {
dev_err(gsw->dev, "Failed to request irq %d\n",
gsw->irq);
goto fail;
}
INIT_WORK(&gsw->irq_worker, mt753x_irq_worker);
}
platform_set_drvdata(pdev, gsw);
gsw->phy_status_poll = of_property_read_bool(gsw->dev->of_node,
"mediatek,phy-poll");
mt753x_add_gsw(gsw);
mt753x_swconfig_init(gsw);
if (sw->post_init)
sw->post_init(gsw);
if (gsw->irq >= 0)
mt753x_irq_enable(gsw);
return 0;
fail:
devm_kfree(&pdev->dev, gsw);
return ret;
}
static int mt753x_remove(struct platform_device *pdev)
{
struct gsw_mt753x *gsw = platform_get_drvdata(pdev);
if (gsw->irq >= 0)
cancel_work_sync(&gsw->irq_worker);
if (gsw->reset_pin >= 0)
devm_gpio_free(&pdev->dev, gsw->reset_pin);
#ifdef CONFIG_SWCONFIG
mt753x_swconfig_destroy(gsw);
#endif
mt753x_remove_gsw(gsw);
platform_set_drvdata(pdev, NULL);
return 0;
}
static const struct of_device_id mt753x_ids[] = {
{ .compatible = "mediatek,mt753x" },
{ },
};
MODULE_DEVICE_TABLE(of, mt753x_ids);
static struct platform_driver mt753x_driver = {
.probe = mt753x_probe,
.remove = mt753x_remove,
.driver = {
.name = "mt753x",
.of_match_table = mt753x_ids,
},
};
static int __init mt753x_init(void)
{
int ret;
INIT_LIST_HEAD(&mt753x_devs);
ret = platform_driver_register(&mt753x_driver);
mt753x_nl_init();
return ret;
}
module_init(mt753x_init);
static void __exit mt753x_exit(void)
{
mt753x_nl_exit();
platform_driver_unregister(&mt753x_driver);
}
module_exit(mt753x_exit);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Weijie Gao <weijie.gao@mediatek.com>");
MODULE_DESCRIPTION("Driver for MediaTek MT753x Gigabit Switch");

View File

@ -1,382 +0,0 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
* Copyright (c) 2018 MediaTek Inc.
* Author: Sirui Zhao <Sirui.Zhao@mediatek.com>
*/
#include <linux/types.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/init.h>
#include <net/genetlink.h>
#include "mt753x.h"
#include "mt753x_nl.h"
struct mt753x_nl_cmd_item {
enum mt753x_cmd cmd;
bool require_dev;
int (*process)(struct genl_info *info, struct gsw_mt753x *gsw);
u32 nr_required_attrs;
const enum mt753x_attr *required_attrs;
};
static int mt753x_nl_response(struct sk_buff *skb, struct genl_info *info);
/*
static const struct nla_policy mt753x_nl_cmd_policy[] = {
[MT753X_ATTR_TYPE_MESG] = { .type = NLA_STRING },
[MT753X_ATTR_TYPE_PHY] = { .type = NLA_S32 },
[MT753X_ATTR_TYPE_REG] = { .type = NLA_S32 },
[MT753X_ATTR_TYPE_VAL] = { .type = NLA_S32 },
[MT753X_ATTR_TYPE_DEV_NAME] = { .type = NLA_S32 },
[MT753X_ATTR_TYPE_DEV_ID] = { .type = NLA_S32 },
[MT753X_ATTR_TYPE_DEVAD] = { .type = NLA_S32 },
};
*/
static const struct genl_ops mt753x_nl_ops[] = {
{
.cmd = MT753X_CMD_REQUEST,
.doit = mt753x_nl_response,
// .policy = mt753x_nl_cmd_policy,
.flags = GENL_ADMIN_PERM,
}, {
.cmd = MT753X_CMD_READ,
.doit = mt753x_nl_response,
// .policy = mt753x_nl_cmd_policy,
.flags = GENL_ADMIN_PERM,
}, {
.cmd = MT753X_CMD_WRITE,
.doit = mt753x_nl_response,
// .policy = mt753x_nl_cmd_policy,
.flags = GENL_ADMIN_PERM,
},
};
static struct genl_family mt753x_nl_family = {
.name = MT753X_GENL_NAME,
.version = MT753X_GENL_VERSION,
.maxattr = MT753X_NR_ATTR_TYPE,
.ops = mt753x_nl_ops,
.n_ops = ARRAY_SIZE(mt753x_nl_ops),
};
static int mt753x_nl_list_devs(char *buff, int size)
{
struct gsw_mt753x *gsw;
int len, total = 0;
char buf[80];
memset(buff, 0, size);
mt753x_lock_gsw();
list_for_each_entry(gsw, &mt753x_devs, list) {
len = snprintf(buf, sizeof(buf),
"id: %d, model: %s, node: %s\n",
gsw->id, gsw->name, gsw->dev->of_node->name);
strncat(buff, buf, size - total);
total += len;
}
mt753x_put_gsw();
return total;
}
static int mt753x_nl_prepare_reply(struct genl_info *info, u8 cmd,
struct sk_buff **skbp)
{
struct sk_buff *msg;
void *reply;
if (!info)
return -EINVAL;
msg = genlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL);
if (!msg)
return -ENOMEM;
/* Construct send-back message header */
reply = genlmsg_put(msg, info->snd_portid, info->snd_seq,
&mt753x_nl_family, 0, cmd);
if (!reply) {
nlmsg_free(msg);
return -EINVAL;
}
*skbp = msg;
return 0;
}
static int mt753x_nl_send_reply(struct sk_buff *skb, struct genl_info *info)
{
struct genlmsghdr *genlhdr = nlmsg_data(nlmsg_hdr(skb));
void *reply = genlmsg_data(genlhdr);
/* Finalize a generic netlink message (update message header) */
genlmsg_end(skb, reply);
/* reply to a request */
return genlmsg_reply(skb, info);
}
static s32 mt753x_nl_get_s32(struct genl_info *info, enum mt753x_attr attr,
s32 defval)
{
struct nlattr *na;
na = info->attrs[attr];
if (na)
return nla_get_s32(na);
return defval;
}
static int mt753x_nl_get_u32(struct genl_info *info, enum mt753x_attr attr,
u32 *val)
{
struct nlattr *na;
na = info->attrs[attr];
if (na) {
*val = nla_get_u32(na);
return 0;
}
return -1;
}
static struct gsw_mt753x *mt753x_nl_parse_find_gsw(struct genl_info *info)
{
struct gsw_mt753x *gsw;
struct nlattr *na;
int gsw_id;
na = info->attrs[MT753X_ATTR_TYPE_DEV_ID];
if (na) {
gsw_id = nla_get_s32(na);
if (gsw_id >= 0)
gsw = mt753x_get_gsw(gsw_id);
else
gsw = mt753x_get_first_gsw();
} else {
gsw = mt753x_get_first_gsw();
}
return gsw;
}
static int mt753x_nl_get_swdevs(struct genl_info *info, struct gsw_mt753x *gsw)
{
struct sk_buff *rep_skb = NULL;
char dev_info[512];
int ret;
ret = mt753x_nl_list_devs(dev_info, sizeof(dev_info));
if (!ret) {
pr_info("No switch registered\n");
return -EINVAL;
}
ret = mt753x_nl_prepare_reply(info, MT753X_CMD_REPLY, &rep_skb);
if (ret < 0)
goto err;
ret = nla_put_string(rep_skb, MT753X_ATTR_TYPE_MESG, dev_info);
if (ret < 0)
goto err;
return mt753x_nl_send_reply(rep_skb, info);
err:
if (rep_skb)
nlmsg_free(rep_skb);
return ret;
}
static int mt753x_nl_reply_read(struct genl_info *info, struct gsw_mt753x *gsw)
{
struct sk_buff *rep_skb = NULL;
s32 phy, devad, reg;
int value;
int ret = 0;
phy = mt753x_nl_get_s32(info, MT753X_ATTR_TYPE_PHY, -1);
devad = mt753x_nl_get_s32(info, MT753X_ATTR_TYPE_DEVAD, -1);
reg = mt753x_nl_get_s32(info, MT753X_ATTR_TYPE_REG, -1);
if (reg < 0)
goto err;
ret = mt753x_nl_prepare_reply(info, MT753X_CMD_READ, &rep_skb);
if (ret < 0)
goto err;
if (phy >= 0) {
if (devad < 0)
value = gsw->mii_read(gsw, phy, reg);
else
value = gsw->mmd_read(gsw, phy, devad, reg);
} else {
value = mt753x_reg_read(gsw, reg);
}
ret = nla_put_s32(rep_skb, MT753X_ATTR_TYPE_REG, reg);
if (ret < 0)
goto err;
ret = nla_put_s32(rep_skb, MT753X_ATTR_TYPE_VAL, value);
if (ret < 0)
goto err;
return mt753x_nl_send_reply(rep_skb, info);
err:
if (rep_skb)
nlmsg_free(rep_skb);
return ret;
}
static int mt753x_nl_reply_write(struct genl_info *info, struct gsw_mt753x *gsw)
{
struct sk_buff *rep_skb = NULL;
s32 phy, devad, reg;
u32 value;
int ret = 0;
phy = mt753x_nl_get_s32(info, MT753X_ATTR_TYPE_PHY, -1);
devad = mt753x_nl_get_s32(info, MT753X_ATTR_TYPE_DEVAD, -1);
reg = mt753x_nl_get_s32(info, MT753X_ATTR_TYPE_REG, -1);
if (mt753x_nl_get_u32(info, MT753X_ATTR_TYPE_VAL, &value))
goto err;
if (reg < 0)
goto err;
ret = mt753x_nl_prepare_reply(info, MT753X_CMD_WRITE, &rep_skb);
if (ret < 0)
goto err;
if (phy >= 0) {
if (devad < 0)
gsw->mii_write(gsw, phy, reg, value);
else
gsw->mmd_write(gsw, phy, devad, reg, value);
} else {
mt753x_reg_write(gsw, reg, value);
}
ret = nla_put_s32(rep_skb, MT753X_ATTR_TYPE_REG, reg);
if (ret < 0)
goto err;
ret = nla_put_s32(rep_skb, MT753X_ATTR_TYPE_VAL, value);
if (ret < 0)
goto err;
return mt753x_nl_send_reply(rep_skb, info);
err:
if (rep_skb)
nlmsg_free(rep_skb);
return ret;
}
static const enum mt753x_attr mt753x_nl_cmd_read_attrs[] = {
MT753X_ATTR_TYPE_REG
};
static const enum mt753x_attr mt753x_nl_cmd_write_attrs[] = {
MT753X_ATTR_TYPE_REG,
MT753X_ATTR_TYPE_VAL
};
static const struct mt753x_nl_cmd_item mt753x_nl_cmds[] = {
{
.cmd = MT753X_CMD_REQUEST,
.require_dev = false,
.process = mt753x_nl_get_swdevs
}, {
.cmd = MT753X_CMD_READ,
.require_dev = true,
.process = mt753x_nl_reply_read,
.required_attrs = mt753x_nl_cmd_read_attrs,
.nr_required_attrs = ARRAY_SIZE(mt753x_nl_cmd_read_attrs),
}, {
.cmd = MT753X_CMD_WRITE,
.require_dev = true,
.process = mt753x_nl_reply_write,
.required_attrs = mt753x_nl_cmd_write_attrs,
.nr_required_attrs = ARRAY_SIZE(mt753x_nl_cmd_write_attrs),
}
};
static int mt753x_nl_response(struct sk_buff *skb, struct genl_info *info)
{
struct genlmsghdr *hdr = nlmsg_data(info->nlhdr);
const struct mt753x_nl_cmd_item *cmditem = NULL;
struct gsw_mt753x *gsw = NULL;
u32 sat_req_attrs = 0;
int i, ret;
for (i = 0; i < ARRAY_SIZE(mt753x_nl_cmds); i++) {
if (hdr->cmd == mt753x_nl_cmds[i].cmd) {
cmditem = &mt753x_nl_cmds[i];
break;
}
}
if (!cmditem) {
pr_info("mt753x-nl: unknown cmd %u\n", hdr->cmd);
return -EINVAL;
}
for (i = 0; i < cmditem->nr_required_attrs; i++) {
if (info->attrs[cmditem->required_attrs[i]])
sat_req_attrs++;
}
if (sat_req_attrs != cmditem->nr_required_attrs) {
pr_info("mt753x-nl: missing required attr(s) for cmd %u\n",
hdr->cmd);
return -EINVAL;
}
if (cmditem->require_dev) {
gsw = mt753x_nl_parse_find_gsw(info);
if (!gsw) {
pr_info("mt753x-nl: failed to find switch dev\n");
return -EINVAL;
}
}
ret = cmditem->process(info, gsw);
mt753x_put_gsw();
return ret;
}
int __init mt753x_nl_init(void)
{
int ret;
ret = genl_register_family(&mt753x_nl_family);
if (ret) {
pr_info("mt753x-nl: genl_register_family_with_ops failed\n");
return ret;
}
return 0;
}
void __exit mt753x_nl_exit(void)
{
genl_unregister_family(&mt753x_nl_family);
}

View File

@ -1,43 +0,0 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Copyright (c) 2018 MediaTek Inc.
* Author: Sirui Zhao <Sirui.Zhao@mediatek.com>
*/
#ifndef _MT753X_NL_H_
#define _MT753X_NL_H_
#define MT753X_GENL_NAME "mt753x"
#define MT753X_GENL_VERSION 0x1
enum mt753x_cmd {
MT753X_CMD_UNSPEC = 0,
MT753X_CMD_REQUEST,
MT753X_CMD_REPLY,
MT753X_CMD_READ,
MT753X_CMD_WRITE,
__MT753X_CMD_MAX,
};
enum mt753x_attr {
MT753X_ATTR_TYPE_UNSPEC = 0,
MT753X_ATTR_TYPE_MESG,
MT753X_ATTR_TYPE_PHY,
MT753X_ATTR_TYPE_DEVAD,
MT753X_ATTR_TYPE_REG,
MT753X_ATTR_TYPE_VAL,
MT753X_ATTR_TYPE_DEV_NAME,
MT753X_ATTR_TYPE_DEV_ID,
__MT753X_ATTR_TYPE_MAX,
};
#define MT753X_NR_ATTR_TYPE (__MT753X_ATTR_TYPE_MAX - 1)
#ifdef __KERNEL__
int __init mt753x_nl_init(void);
void __exit mt753x_nl_exit(void);
#endif /* __KERNEL__ */
#endif /* _MT753X_NL_H_ */

View File

@ -1,294 +0,0 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Copyright (c) 2018 MediaTek Inc.
* Author: Weijie Gao <weijie.gao@mediatek.com>
*/
#ifndef _MT753X_REGS_H_
#define _MT753X_REGS_H_
#include <linux/bitops.h>
/* Values of Egress TAG Control */
#define ETAG_CTRL_UNTAG 0
#define ETAG_CTRL_TAG 2
#define ETAG_CTRL_SWAP 1
#define ETAG_CTRL_STACK 3
#define VTCR 0x90
#define VAWD1 0x94
#define VAWD2 0x98
/* Fields of VTCR */
#define VTCR_BUSY BIT(31)
#define IDX_INVLD BIT(16)
#define VTCR_FUNC_S 12
#define VTCR_FUNC_M 0xf000
#define VTCR_VID_S 0
#define VTCR_VID_M 0xfff
/* Values of VTCR_FUNC */
#define VTCR_READ_VLAN_ENTRY 0
#define VTCR_WRITE_VLAN_ENTRY 1
#define VTCR_INVD_VLAN_ENTRY 2
#define VTCR_ENABLE_VLAN_ENTRY 3
#define VTCR_READ_ACL_ENTRY 4
#define VTCR_WRITE_ACL_ENTRY 5
#define VTCR_READ_TRTCM_TABLE 6
#define VTCR_WRITE_TRTCM_TABLE 7
#define VTCR_READ_ACL_MASK_ENTRY 8
#define VTCR_WRITE_ACL_MASK_ENTRY 9
#define VTCR_READ_ACL_RULE_ENTRY 10
#define VTCR_WRITE_ACL_RULE_ENTRY 11
#define VTCR_READ_ACL_RATE_ENTRY 12
#define VTCR_WRITE_ACL_RATE_ENTRY 13
/* VLAN entry fields */
/* VAWD1 */
#define PORT_STAG BIT(31)
#define IVL_MAC BIT(30)
#define EG_CON BIT(29)
#define VTAG_EN BIT(28)
#define COPY_PRI BIT(27)
#define USER_PRI_S 24
#define USER_PRI_M 0x7000000
#define PORT_MEM_S 16
#define PORT_MEM_M 0xff0000
#define S_TAG1_S 4
#define S_TAG1_M 0xfff0
#define FID_S 1
#define FID_M 0x0e
#define VENTRY_VALID BIT(0)
/* VAWD2 */
#define S_TAG2_S 16
#define S_TAG2_M 0xffff0000
#define PORT_ETAG_S(p) ((p) * 2)
#define PORT_ETAG_M 0x03
#define PORT_CTRL_BASE 0x2000
#define PORT_CTRL_PORT_OFFSET 0x100
#define PORT_CTRL_REG(p, r) (PORT_CTRL_BASE + \
(p) * PORT_CTRL_PORT_OFFSET + (r))
#define CKGCR(p) PORT_CTRL_REG(p, 0x00)
#define PCR(p) PORT_CTRL_REG(p, 0x04)
#define PIC(p) PORT_CTRL_REG(p, 0x08)
#define PSC(p) PORT_CTRL_REG(p, 0x0c)
#define PVC(p) PORT_CTRL_REG(p, 0x10)
#define PPBV1(p) PORT_CTRL_REG(p, 0x14)
#define PPBV2(p) PORT_CTRL_REG(p, 0x18)
#define BSR(p) PORT_CTRL_REG(p, 0x1c)
#define STAG01 PORT_CTRL_REG(p, 0x20)
#define STAG23 PORT_CTRL_REG(p, 0x24)
#define STAG45 PORT_CTRL_REG(p, 0x28)
#define STAG67 PORT_CTRL_REG(p, 0x2c)
#define PPBV(p, g) (PPBV1(p) + ((g) / 2) * 4)
/* Fields of PCR */
#define MLDV2_EN BIT(30)
#define EG_TAG_S 28
#define EG_TAG_M 0x30000000
#define PORT_PRI_S 24
#define PORT_PRI_M 0x7000000
#define PORT_MATRIX_S 16
#define PORT_MATRIX_M 0xff0000
#define UP2DSCP_EN BIT(12)
#define UP2TAG_EN BIT(11)
#define ACL_EN BIT(10)
#define PORT_TX_MIR BIT(9)
#define PORT_RX_MIR BIT(8)
#define ACL_MIR BIT(7)
#define MIS_PORT_FW_S 4
#define MIS_PORT_FW_M 0x70
#define VLAN_MIS BIT(2)
#define PORT_VLAN_S 0
#define PORT_VLAN_M 0x03
/* Values of PORT_VLAN */
#define PORT_MATRIX_MODE 0
#define FALLBACK_MODE 1
#define CHECK_MODE 2
#define SECURITY_MODE 3
/* Fields of PVC */
#define STAG_VPID_S 16
#define STAG_VPID_M 0xffff0000
#define DIS_PVID BIT(15)
#define FORCE_PVID BIT(14)
#define PT_VPM BIT(12)
#define PT_OPTION BIT(11)
#define PVC_EG_TAG_S 8
#define PVC_EG_TAG_M 0x700
#define VLAN_ATTR_S 6
#define VLAN_ATTR_M 0xc0
#define PVC_PORT_STAG BIT(5)
#define BC_LKYV_EN BIT(4)
#define MC_LKYV_EN BIT(3)
#define UC_LKYV_EN BIT(2)
#define ACC_FRM_S 0
#define ACC_FRM_M 0x03
/* Values of VLAN_ATTR */
#define VA_USER_PORT 0
#define VA_STACK_PORT 1
#define VA_TRANSLATION_PORT 2
#define VA_TRANSPARENT_PORT 3
/* Fields of PPBV */
#define GRP_PORT_PRI_S(g) (((g) % 2) * 16 + 13)
#define GRP_PORT_PRI_M 0x07
#define GRP_PORT_VID_S(g) (((g) % 2) * 16)
#define GRP_PORT_VID_M 0xfff
#define PORT_MAC_CTRL_BASE 0x3000
#define PORT_MAC_CTRL_PORT_OFFSET 0x100
#define PORT_MAC_CTRL_REG(p, r) (PORT_MAC_CTRL_BASE + \
(p) * PORT_MAC_CTRL_PORT_OFFSET + (r))
#define PMCR(p) PORT_MAC_CTRL_REG(p, 0x00)
#define PMEEECR(p) PORT_MAC_CTRL_REG(p, 0x04)
#define PMSR(p) PORT_MAC_CTRL_REG(p, 0x08)
#define PINT_EN(p) PORT_MAC_CTRL_REG(p, 0x10)
#define PINT_STS(p) PORT_MAC_CTRL_REG(p, 0x14)
#define GMACCR (PORT_MAC_CTRL_BASE + 0xe0)
#define TXCRC_EN BIT(19)
#define RXCRC_EN BIT(18)
#define PRMBL_LMT_EN BIT(17)
#define MTCC_LMT_S 9
#define MTCC_LMT_M 0x1e00
#define MAX_RX_JUMBO_S 2
#define MAX_RX_JUMBO_M 0x3c
#define MAX_RX_PKT_LEN_S 0
#define MAX_RX_PKT_LEN_M 0x3
/* Values of MAX_RX_PKT_LEN */
#define RX_PKT_LEN_1518 0
#define RX_PKT_LEN_1536 1
#define RX_PKT_LEN_1522 2
#define RX_PKT_LEN_MAX_JUMBO 3
/* Fields of PMCR */
#define IPG_CFG_S 18
#define IPG_CFG_M 0xc0000
#define EXT_PHY BIT(17)
#define MAC_MODE BIT(16)
#define MAC_TX_EN BIT(14)
#define MAC_RX_EN BIT(13)
#define MAC_PRE BIT(11)
#define BKOFF_EN BIT(9)
#define BACKPR_EN BIT(8)
#define FORCE_EEE1G BIT(7)
#define FORCE_EEE1000 BIT(6)
#define FORCE_RX_FC BIT(5)
#define FORCE_TX_FC BIT(4)
#define FORCE_SPD_S 2
#define FORCE_SPD_M 0x0c
#define FORCE_DPX BIT(1)
#define FORCE_LINK BIT(0)
/* Fields of PMSR */
#define EEE1G_STS BIT(7)
#define EEE100_STS BIT(6)
#define RX_FC_STS BIT(5)
#define TX_FC_STS BIT(4)
#define MAC_SPD_STS_S 2
#define MAC_SPD_STS_M 0x0c
#define MAC_DPX_STS BIT(1)
#define MAC_LNK_STS BIT(0)
/* Values of MAC_SPD_STS */
#define MAC_SPD_10 0
#define MAC_SPD_100 1
#define MAC_SPD_1000 2
#define MAC_SPD_2500 3
/* Values of IPG_CFG */
#define IPG_96BIT 0
#define IPG_96BIT_WITH_SHORT_IPG 1
#define IPG_64BIT 2
#define MIB_COUNTER_BASE 0x4000
#define MIB_COUNTER_PORT_OFFSET 0x100
#define MIB_COUNTER_REG(p, r) (MIB_COUNTER_BASE + \
(p) * MIB_COUNTER_PORT_OFFSET + (r))
#define STATS_TDPC 0x00
#define STATS_TCRC 0x04
#define STATS_TUPC 0x08
#define STATS_TMPC 0x0C
#define STATS_TBPC 0x10
#define STATS_TCEC 0x14
#define STATS_TSCEC 0x18
#define STATS_TMCEC 0x1C
#define STATS_TDEC 0x20
#define STATS_TLCEC 0x24
#define STATS_TXCEC 0x28
#define STATS_TPPC 0x2C
#define STATS_TL64PC 0x30
#define STATS_TL65PC 0x34
#define STATS_TL128PC 0x38
#define STATS_TL256PC 0x3C
#define STATS_TL512PC 0x40
#define STATS_TL1024PC 0x44
#define STATS_TOC 0x48
#define STATS_RDPC 0x60
#define STATS_RFPC 0x64
#define STATS_RUPC 0x68
#define STATS_RMPC 0x6C
#define STATS_RBPC 0x70
#define STATS_RAEPC 0x74
#define STATS_RCEPC 0x78
#define STATS_RUSPC 0x7C
#define STATS_RFEPC 0x80
#define STATS_ROSPC 0x84
#define STATS_RJEPC 0x88
#define STATS_RPPC 0x8C
#define STATS_RL64PC 0x90
#define STATS_RL65PC 0x94
#define STATS_RL128PC 0x98
#define STATS_RL256PC 0x9C
#define STATS_RL512PC 0xA0
#define STATS_RL1024PC 0xA4
#define STATS_ROC 0xA8
#define STATS_RDPC_CTRL 0xB0
#define STATS_RDPC_ING 0xB4
#define STATS_RDPC_ARL 0xB8
#define SYS_CTRL 0x7000
#define SW_PHY_RST BIT(2)
#define SW_SYS_RST BIT(1)
#define SW_REG_RST BIT(0)
#define SYS_INT_EN 0x7008
#define SYS_INT_STS 0x700c
#define MAC_PC_INT BIT(16)
#define PHY_INT(p) BIT((p) + 8)
#define PHY_LC_INT(p) BIT(p)
#define PHY_IAC 0x701c
#define PHY_ACS_ST BIT(31)
#define MDIO_REG_ADDR_S 25
#define MDIO_REG_ADDR_M 0x3e000000
#define MDIO_PHY_ADDR_S 20
#define MDIO_PHY_ADDR_M 0x1f00000
#define MDIO_CMD_S 18
#define MDIO_CMD_M 0xc0000
#define MDIO_ST_S 16
#define MDIO_ST_M 0x30000
#define MDIO_RW_DATA_S 0
#define MDIO_RW_DATA_M 0xffff
/* MDIO_CMD: MDIO commands */
#define MDIO_CMD_ADDR 0
#define MDIO_CMD_WRITE 1
#define MDIO_CMD_READ 2
#define MDIO_CMD_READ_C45 3
/* MDIO_ST: MDIO start field */
#define MDIO_ST_C45 0
#define MDIO_ST_C22 1
#define HWSTRAP 0x7800
#define MHWSTRAP 0x7804
#endif /* _MT753X_REGS_H_ */

View File

@ -1,510 +0,0 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
* Copyright (c) 2018 MediaTek Inc.
* Author: Weijie Gao <weijie.gao@mediatek.com>
*/
#include <linux/if.h>
#include <linux/list.h>
#include <linux/if_ether.h>
#include <linux/skbuff.h>
#include <linux/netdevice.h>
#include <linux/netlink.h>
#include <linux/bitops.h>
#include <net/genetlink.h>
#include <linux/delay.h>
#include <linux/phy.h>
#include <linux/netdevice.h>
#include <linux/etherdevice.h>
#include <linux/lockdep.h>
#include <linux/workqueue.h>
#include <linux/of_device.h>
#include "mt753x.h"
#include "mt753x_swconfig.h"
#include "mt753x_regs.h"
#define MT753X_PORT_MIB_TXB_ID 18 /* TxByte */
#define MT753X_PORT_MIB_RXB_ID 37 /* RxByte */
#define MIB_DESC(_s, _o, _n) \
{ \
.size = (_s), \
.offset = (_o), \
.name = (_n), \
}
struct mt753x_mib_desc {
unsigned int size;
unsigned int offset;
const char *name;
};
static const struct mt753x_mib_desc mt753x_mibs[] = {
MIB_DESC(1, STATS_TDPC, "TxDrop"),
MIB_DESC(1, STATS_TCRC, "TxCRC"),
MIB_DESC(1, STATS_TUPC, "TxUni"),
MIB_DESC(1, STATS_TMPC, "TxMulti"),
MIB_DESC(1, STATS_TBPC, "TxBroad"),
MIB_DESC(1, STATS_TCEC, "TxCollision"),
MIB_DESC(1, STATS_TSCEC, "TxSingleCol"),
MIB_DESC(1, STATS_TMCEC, "TxMultiCol"),
MIB_DESC(1, STATS_TDEC, "TxDefer"),
MIB_DESC(1, STATS_TLCEC, "TxLateCol"),
MIB_DESC(1, STATS_TXCEC, "TxExcCol"),
MIB_DESC(1, STATS_TPPC, "TxPause"),
MIB_DESC(1, STATS_TL64PC, "Tx64Byte"),
MIB_DESC(1, STATS_TL65PC, "Tx65Byte"),
MIB_DESC(1, STATS_TL128PC, "Tx128Byte"),
MIB_DESC(1, STATS_TL256PC, "Tx256Byte"),
MIB_DESC(1, STATS_TL512PC, "Tx512Byte"),
MIB_DESC(1, STATS_TL1024PC, "Tx1024Byte"),
MIB_DESC(2, STATS_TOC, "TxByte"),
MIB_DESC(1, STATS_RDPC, "RxDrop"),
MIB_DESC(1, STATS_RFPC, "RxFiltered"),
MIB_DESC(1, STATS_RUPC, "RxUni"),
MIB_DESC(1, STATS_RMPC, "RxMulti"),
MIB_DESC(1, STATS_RBPC, "RxBroad"),
MIB_DESC(1, STATS_RAEPC, "RxAlignErr"),
MIB_DESC(1, STATS_RCEPC, "RxCRC"),
MIB_DESC(1, STATS_RUSPC, "RxUnderSize"),
MIB_DESC(1, STATS_RFEPC, "RxFragment"),
MIB_DESC(1, STATS_ROSPC, "RxOverSize"),
MIB_DESC(1, STATS_RJEPC, "RxJabber"),
MIB_DESC(1, STATS_RPPC, "RxPause"),
MIB_DESC(1, STATS_RL64PC, "Rx64Byte"),
MIB_DESC(1, STATS_RL65PC, "Rx65Byte"),
MIB_DESC(1, STATS_RL128PC, "Rx128Byte"),
MIB_DESC(1, STATS_RL256PC, "Rx256Byte"),
MIB_DESC(1, STATS_RL512PC, "Rx512Byte"),
MIB_DESC(1, STATS_RL1024PC, "Rx1024Byte"),
MIB_DESC(2, STATS_ROC, "RxByte"),
MIB_DESC(1, STATS_RDPC_CTRL, "RxCtrlDrop"),
MIB_DESC(1, STATS_RDPC_ING, "RxIngDrop"),
MIB_DESC(1, STATS_RDPC_ARL, "RxARLDrop")
};
enum {
/* Global attributes. */
MT753X_ATTR_ENABLE_VLAN,
};
static int mt753x_get_vlan_enable(struct switch_dev *dev,
const struct switch_attr *attr,
struct switch_val *val)
{
struct gsw_mt753x *gsw = container_of(dev, struct gsw_mt753x, swdev);
val->value.i = gsw->global_vlan_enable;
return 0;
}
static int mt753x_set_vlan_enable(struct switch_dev *dev,
const struct switch_attr *attr,
struct switch_val *val)
{
struct gsw_mt753x *gsw = container_of(dev, struct gsw_mt753x, swdev);
gsw->global_vlan_enable = val->value.i != 0;
return 0;
}
static int mt753x_get_port_pvid(struct switch_dev *dev, int port, int *val)
{
struct gsw_mt753x *gsw = container_of(dev, struct gsw_mt753x, swdev);
if (port >= MT753X_NUM_PORTS)
return -EINVAL;
*val = mt753x_reg_read(gsw, PPBV1(port));
*val &= GRP_PORT_VID_M;
return 0;
}
static int mt753x_set_port_pvid(struct switch_dev *dev, int port, int pvid)
{
struct gsw_mt753x *gsw = container_of(dev, struct gsw_mt753x, swdev);
if (port >= MT753X_NUM_PORTS)
return -EINVAL;
if (pvid < MT753X_MIN_VID || pvid > MT753X_MAX_VID)
return -EINVAL;
gsw->port_entries[port].pvid = pvid;
return 0;
}
static int mt753x_get_vlan_ports(struct switch_dev *dev, struct switch_val *val)
{
struct gsw_mt753x *gsw = container_of(dev, struct gsw_mt753x, swdev);
u32 member;
u32 etags;
int i;
val->len = 0;
if (val->port_vlan < 0 || val->port_vlan >= MT753X_NUM_VLANS)
return -EINVAL;
mt753x_vlan_ctrl(gsw, VTCR_READ_VLAN_ENTRY, val->port_vlan);
member = mt753x_reg_read(gsw, VAWD1);
member &= PORT_MEM_M;
member >>= PORT_MEM_S;
etags = mt753x_reg_read(gsw, VAWD2);
for (i = 0; i < MT753X_NUM_PORTS; i++) {
struct switch_port *p;
int etag;
if (!(member & BIT(i)))
continue;
p = &val->value.ports[val->len++];
p->id = i;
etag = (etags >> PORT_ETAG_S(i)) & PORT_ETAG_M;
if (etag == ETAG_CTRL_TAG)
p->flags |= BIT(SWITCH_PORT_FLAG_TAGGED);
else if (etag != ETAG_CTRL_UNTAG)
dev_info(gsw->dev,
"vlan egress tag control neither untag nor tag.\n");
}
return 0;
}
static int mt753x_set_vlan_ports(struct switch_dev *dev, struct switch_val *val)
{
struct gsw_mt753x *gsw = container_of(dev, struct gsw_mt753x, swdev);
u8 member = 0;
u8 etags = 0;
int i;
if (val->port_vlan < 0 || val->port_vlan >= MT753X_NUM_VLANS ||
val->len > MT753X_NUM_PORTS)
return -EINVAL;
for (i = 0; i < val->len; i++) {
struct switch_port *p = &val->value.ports[i];
if (p->id >= MT753X_NUM_PORTS)
return -EINVAL;
member |= BIT(p->id);
if (p->flags & BIT(SWITCH_PORT_FLAG_TAGGED))
etags |= BIT(p->id);
}
gsw->vlan_entries[val->port_vlan].member = member;
gsw->vlan_entries[val->port_vlan].etags = etags;
return 0;
}
static int mt753x_set_vid(struct switch_dev *dev,
const struct switch_attr *attr,
struct switch_val *val)
{
struct gsw_mt753x *gsw = container_of(dev, struct gsw_mt753x, swdev);
int vlan;
u16 vid;
vlan = val->port_vlan;
vid = (u16)val->value.i;
if (vlan < 0 || vlan >= MT753X_NUM_VLANS)
return -EINVAL;
if (vid < MT753X_MIN_VID || vid > MT753X_MAX_VID)
return -EINVAL;
gsw->vlan_entries[vlan].vid = vid;
return 0;
}
static int mt753x_get_vid(struct switch_dev *dev,
const struct switch_attr *attr,
struct switch_val *val)
{
val->value.i = val->port_vlan;
return 0;
}
static int mt753x_get_port_link(struct switch_dev *dev, int port,
struct switch_port_link *link)
{
struct gsw_mt753x *gsw = container_of(dev, struct gsw_mt753x, swdev);
u32 speed, pmsr;
if (port < 0 || port >= MT753X_NUM_PORTS)
return -EINVAL;
pmsr = mt753x_reg_read(gsw, PMSR(port));
link->link = pmsr & MAC_LNK_STS;
link->duplex = pmsr & MAC_DPX_STS;
speed = (pmsr & MAC_SPD_STS_M) >> MAC_SPD_STS_S;
switch (speed) {
case MAC_SPD_10:
link->speed = SWITCH_PORT_SPEED_10;
break;
case MAC_SPD_100:
link->speed = SWITCH_PORT_SPEED_100;
break;
case MAC_SPD_1000:
link->speed = SWITCH_PORT_SPEED_1000;
break;
case MAC_SPD_2500:
/* TODO: swconfig has no support for 2500 now */
link->speed = SWITCH_PORT_SPEED_UNKNOWN;
break;
}
return 0;
}
static int mt753x_set_port_link(struct switch_dev *dev, int port,
struct switch_port_link *link)
{
#ifndef MODULE
if (port >= MT753X_NUM_PHYS)
return -EINVAL;
return switch_generic_set_link(dev, port, link);
#else
return -ENOTSUPP;
#endif
}
static u64 get_mib_counter(struct gsw_mt753x *gsw, int i, int port)
{
unsigned int offset;
u64 lo, hi, hi2;
offset = mt753x_mibs[i].offset;
if (mt753x_mibs[i].size == 1)
return mt753x_reg_read(gsw, MIB_COUNTER_REG(port, offset));
do {
hi = mt753x_reg_read(gsw, MIB_COUNTER_REG(port, offset + 4));
lo = mt753x_reg_read(gsw, MIB_COUNTER_REG(port, offset));
hi2 = mt753x_reg_read(gsw, MIB_COUNTER_REG(port, offset + 4));
} while (hi2 != hi);
return (hi << 32) | lo;
}
static int mt753x_get_port_mib(struct switch_dev *dev,
const struct switch_attr *attr,
struct switch_val *val)
{
static char buf[4096];
struct gsw_mt753x *gsw = container_of(dev, struct gsw_mt753x, swdev);
int i, len = 0;
if (val->port_vlan >= MT753X_NUM_PORTS)
return -EINVAL;
len += snprintf(buf + len, sizeof(buf) - len,
"Port %d MIB counters\n", val->port_vlan);
for (i = 0; i < ARRAY_SIZE(mt753x_mibs); ++i) {
u64 counter;
len += snprintf(buf + len, sizeof(buf) - len,
"%-11s: ", mt753x_mibs[i].name);
counter = get_mib_counter(gsw, i, val->port_vlan);
len += snprintf(buf + len, sizeof(buf) - len, "%llu\n",
counter);
}
val->value.s = buf;
val->len = len;
return 0;
}
static int mt753x_get_port_stats(struct switch_dev *dev, int port,
struct switch_port_stats *stats)
{
struct gsw_mt753x *gsw = container_of(dev, struct gsw_mt753x, swdev);
if (port < 0 || port >= MT753X_NUM_PORTS)
return -EINVAL;
stats->tx_bytes = get_mib_counter(gsw, MT753X_PORT_MIB_TXB_ID, port);
stats->rx_bytes = get_mib_counter(gsw, MT753X_PORT_MIB_RXB_ID, port);
return 0;
}
static void mt753x_port_isolation(struct gsw_mt753x *gsw)
{
int i;
for (i = 0; i < MT753X_NUM_PORTS; i++)
mt753x_reg_write(gsw, PCR(i),
BIT(gsw->cpu_port) << PORT_MATRIX_S);
mt753x_reg_write(gsw, PCR(gsw->cpu_port), PORT_MATRIX_M);
for (i = 0; i < MT753X_NUM_PORTS; i++)
mt753x_reg_write(gsw, PVC(i),
(0x8100 << STAG_VPID_S) |
(VA_TRANSPARENT_PORT << VLAN_ATTR_S));
}
static int mt753x_apply_config(struct switch_dev *dev)
{
struct gsw_mt753x *gsw = container_of(dev, struct gsw_mt753x, swdev);
if (!gsw->global_vlan_enable) {
mt753x_port_isolation(gsw);
return 0;
}
mt753x_apply_vlan_config(gsw);
return 0;
}
static int mt753x_reset_switch(struct switch_dev *dev)
{
struct gsw_mt753x *gsw = container_of(dev, struct gsw_mt753x, swdev);
int i;
memset(gsw->port_entries, 0, sizeof(gsw->port_entries));
memset(gsw->vlan_entries, 0, sizeof(gsw->vlan_entries));
/* set default vid of each vlan to the same number of vlan, so the vid
* won't need be set explicitly.
*/
for (i = 0; i < MT753X_NUM_VLANS; i++)
gsw->vlan_entries[i].vid = i;
return 0;
}
static int mt753x_phy_read16(struct switch_dev *dev, int addr, u8 reg,
u16 *value)
{
struct gsw_mt753x *gsw = container_of(dev, struct gsw_mt753x, swdev);
*value = gsw->mii_read(gsw, addr, reg);
return 0;
}
static int mt753x_phy_write16(struct switch_dev *dev, int addr, u8 reg,
u16 value)
{
struct gsw_mt753x *gsw = container_of(dev, struct gsw_mt753x, swdev);
gsw->mii_write(gsw, addr, reg, value);
return 0;
}
static const struct switch_attr mt753x_global[] = {
{
.type = SWITCH_TYPE_INT,
.name = "enable_vlan",
.description = "VLAN mode (1:enabled)",
.max = 1,
.id = MT753X_ATTR_ENABLE_VLAN,
.get = mt753x_get_vlan_enable,
.set = mt753x_set_vlan_enable,
}
};
static const struct switch_attr mt753x_port[] = {
{
.type = SWITCH_TYPE_STRING,
.name = "mib",
.description = "Get MIB counters for port",
.get = mt753x_get_port_mib,
.set = NULL,
},
};
static const struct switch_attr mt753x_vlan[] = {
{
.type = SWITCH_TYPE_INT,
.name = "vid",
.description = "VLAN ID (0-4094)",
.set = mt753x_set_vid,
.get = mt753x_get_vid,
.max = 4094,
},
};
static const struct switch_dev_ops mt753x_swdev_ops = {
.attr_global = {
.attr = mt753x_global,
.n_attr = ARRAY_SIZE(mt753x_global),
},
.attr_port = {
.attr = mt753x_port,
.n_attr = ARRAY_SIZE(mt753x_port),
},
.attr_vlan = {
.attr = mt753x_vlan,
.n_attr = ARRAY_SIZE(mt753x_vlan),
},
.get_vlan_ports = mt753x_get_vlan_ports,
.set_vlan_ports = mt753x_set_vlan_ports,
.get_port_pvid = mt753x_get_port_pvid,
.set_port_pvid = mt753x_set_port_pvid,
.get_port_link = mt753x_get_port_link,
.set_port_link = mt753x_set_port_link,
.get_port_stats = mt753x_get_port_stats,
.apply_config = mt753x_apply_config,
.reset_switch = mt753x_reset_switch,
.phy_read16 = mt753x_phy_read16,
.phy_write16 = mt753x_phy_write16,
};
int mt753x_swconfig_init(struct gsw_mt753x *gsw)
{
struct device_node *np = gsw->dev->of_node;
struct switch_dev *swdev;
int ret;
if (of_property_read_u32(np, "mediatek,cpuport", &gsw->cpu_port))
gsw->cpu_port = MT753X_DFL_CPU_PORT;
swdev = &gsw->swdev;
swdev->name = gsw->name;
swdev->alias = gsw->name;
swdev->cpu_port = gsw->cpu_port;
swdev->ports = MT753X_NUM_PORTS;
swdev->vlans = MT753X_NUM_VLANS;
swdev->ops = &mt753x_swdev_ops;
ret = register_switch(swdev, NULL);
if (ret) {
dev_notice(gsw->dev, "Failed to register switch %s\n",
swdev->name);
return ret;
}
mt753x_apply_config(swdev);
return 0;
}
void mt753x_swconfig_destroy(struct gsw_mt753x *gsw)
{
unregister_switch(&gsw->swdev);
}

View File

@ -1,29 +0,0 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Copyright (c) 2018 MediaTek Inc.
* Author: Weijie Gao <weijie.gao@mediatek.com>
*/
#ifndef _MT753X_SWCONFIG_H_
#define _MT753X_SWCONFIG_H_
#ifdef CONFIG_SWCONFIG
#include <linux/switch.h>
#include "mt753x.h"
int mt753x_swconfig_init(struct gsw_mt753x *gsw);
void mt753x_swconfig_destroy(struct gsw_mt753x *gsw);
#else
static inline int mt753x_swconfig_init(struct gsw_mt753x *gsw)
{
mt753x_apply_vlan_config(gsw);
return 0;
}
static inline void mt753x_swconfig_destroy(struct gsw_mt753x *gsw)
{
}
#endif
#endif /* _MT753X_SWCONFIG_H_ */

View File

@ -1,183 +0,0 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
* Copyright (c) 2018 MediaTek Inc.
*/
#include "mt753x.h"
#include "mt753x_regs.h"
struct mt753x_mapping mt753x_def_mapping[] = {
{
.name = "llllw",
.pvids = { 1, 1, 1, 1, 2, 2, 1 },
.members = { 0, 0x4f, 0x30 },
.etags = { 0, 0, 0 },
.vids = { 0, 1, 2 },
}, {
.name = "wllll",
.pvids = { 2, 1, 1, 1, 1, 2, 1 },
.members = { 0, 0x5e, 0x21 },
.etags = { 0, 0, 0 },
.vids = { 0, 1, 2 },
}, {
.name = "lwlll",
.pvids = { 1, 2, 1, 1, 1, 2, 1 },
.members = { 0, 0x5d, 0x22 },
.etags = { 0, 0, 0 },
.vids = { 0, 1, 2 },
},
};
void mt753x_vlan_ctrl(struct gsw_mt753x *gsw, u32 cmd, u32 val)
{
int i;
mt753x_reg_write(gsw, VTCR,
VTCR_BUSY | ((cmd << VTCR_FUNC_S) & VTCR_FUNC_M) |
(val & VTCR_VID_M));
for (i = 0; i < 300; i++) {
u32 val = mt753x_reg_read(gsw, VTCR);
if ((val & VTCR_BUSY) == 0)
break;
usleep_range(1000, 1100);
}
if (i == 300)
dev_info(gsw->dev, "vtcr timeout\n");
}
static void mt753x_write_vlan_entry(struct gsw_mt753x *gsw, int vlan, u16 vid,
u8 ports, u8 etags)
{
int port;
u32 val;
/* vlan port membership */
if (ports)
mt753x_reg_write(gsw, VAWD1,
IVL_MAC | VTAG_EN | VENTRY_VALID |
((ports << PORT_MEM_S) & PORT_MEM_M));
else
mt753x_reg_write(gsw, VAWD1, 0);
/* egress mode */
val = 0;
for (port = 0; port < MT753X_NUM_PORTS; port++) {
if (etags & BIT(port))
val |= ETAG_CTRL_TAG << PORT_ETAG_S(port);
else
val |= ETAG_CTRL_UNTAG << PORT_ETAG_S(port);
}
mt753x_reg_write(gsw, VAWD2, val);
/* write to vlan table */
mt753x_vlan_ctrl(gsw, VTCR_WRITE_VLAN_ENTRY, vid);
}
void mt753x_apply_vlan_config(struct gsw_mt753x *gsw)
{
int i, j;
u8 tag_ports;
u8 untag_ports;
/* set all ports as security mode */
for (i = 0; i < MT753X_NUM_PORTS; i++)
mt753x_reg_write(gsw, PCR(i),
PORT_MATRIX_M | SECURITY_MODE);
/* check if a port is used in tag/untag vlan egress mode */
tag_ports = 0;
untag_ports = 0;
for (i = 0; i < MT753X_NUM_VLANS; i++) {
u8 member = gsw->vlan_entries[i].member;
u8 etags = gsw->vlan_entries[i].etags;
if (!member)
continue;
for (j = 0; j < MT753X_NUM_PORTS; j++) {
if (!(member & BIT(j)))
continue;
if (etags & BIT(j))
tag_ports |= 1u << j;
else
untag_ports |= 1u << j;
}
}
/* set all untag-only ports as transparent and the rest as user port */
for (i = 0; i < MT753X_NUM_PORTS; i++) {
u32 pvc_mode = 0x8100 << STAG_VPID_S;
if (untag_ports & BIT(i) && !(tag_ports & BIT(i)))
pvc_mode = (0x8100 << STAG_VPID_S) |
(VA_TRANSPARENT_PORT << VLAN_ATTR_S);
mt753x_reg_write(gsw, PVC(i), pvc_mode);
}
/* first clear the switch vlan table */
for (i = 0; i < MT753X_NUM_VLANS; i++)
mt753x_write_vlan_entry(gsw, i, i, 0, 0);
/* now program only vlans with members to avoid
* clobbering remapped entries in later iterations
*/
for (i = 0; i < MT753X_NUM_VLANS; i++) {
u16 vid = gsw->vlan_entries[i].vid;
u8 member = gsw->vlan_entries[i].member;
u8 etags = gsw->vlan_entries[i].etags;
if (member)
mt753x_write_vlan_entry(gsw, i, vid, member, etags);
}
/* Port Default PVID */
for (i = 0; i < MT753X_NUM_PORTS; i++) {
int vlan = gsw->port_entries[i].pvid;
u16 pvid = 0;
u32 val;
if (vlan < MT753X_NUM_VLANS && gsw->vlan_entries[vlan].member)
pvid = gsw->vlan_entries[vlan].vid;
val = mt753x_reg_read(gsw, PPBV1(i));
val &= ~GRP_PORT_VID_M;
val |= pvid;
mt753x_reg_write(gsw, PPBV1(i), val);
}
}
struct mt753x_mapping *mt753x_find_mapping(struct device_node *np)
{
const char *map;
int i;
if (of_property_read_string(np, "mediatek,portmap", &map))
return NULL;
for (i = 0; i < ARRAY_SIZE(mt753x_def_mapping); i++)
if (!strcmp(map, mt753x_def_mapping[i].name))
return &mt753x_def_mapping[i];
return NULL;
}
void mt753x_apply_mapping(struct gsw_mt753x *gsw, struct mt753x_mapping *map)
{
int i = 0;
for (i = 0; i < MT753X_NUM_PORTS; i++)
gsw->port_entries[i].pvid = map->pvids[i];
for (i = 0; i < MT753X_NUM_VLANS; i++) {
gsw->vlan_entries[i].member = map->members[i];
gsw->vlan_entries[i].etags = map->etags[i];
gsw->vlan_entries[i].vid = map->vids[i];
}
}

View File

@ -1,40 +0,0 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Copyright (c) 2018 MediaTek Inc.
*/
#ifndef _MT753X_VLAN_H_
#define _MT753X_VLAN_H_
#define MT753X_NUM_PORTS 7
#define MT753X_NUM_VLANS 4095
#define MT753X_MAX_VID 4095
#define MT753X_MIN_VID 0
struct gsw_mt753x;
struct mt753x_port_entry {
u16 pvid;
};
struct mt753x_vlan_entry {
u16 vid;
u8 member;
u8 etags;
};
struct mt753x_mapping {
char *name;
u16 pvids[MT753X_NUM_PORTS];
u8 members[MT753X_NUM_VLANS];
u8 etags[MT753X_NUM_VLANS];
u16 vids[MT753X_NUM_VLANS];
};
extern struct mt753x_mapping mt753x_defaults[];
void mt753x_vlan_ctrl(struct gsw_mt753x *gsw, u32 cmd, u32 val);
void mt753x_apply_vlan_config(struct gsw_mt753x *gsw);
struct mt753x_mapping *mt753x_find_mapping(struct device_node *np);
void mt753x_apply_mapping(struct gsw_mt753x *gsw, struct mt753x_mapping *map);
#endif /* _MT753X_VLAN_H_ */

View File

@ -24,7 +24,6 @@ CONFIG_ARM64_MODULE_PLTS=y
CONFIG_ARM64_PAGE_SHIFT=12
CONFIG_ARM64_PA_BITS=48
CONFIG_ARM64_PA_BITS_48=y
# CONFIG_ARM64_SW_TTBR0_PAN is not set
CONFIG_ARM64_TAGGED_ADDR_ABI=y
CONFIG_ARM64_VA_BITS=39
CONFIG_ARM64_VA_BITS_39=y

View File

@ -26,7 +26,6 @@ CONFIG_ARM64_MODULE_PLTS=y
CONFIG_ARM64_PAGE_SHIFT=12
CONFIG_ARM64_PA_BITS=48
CONFIG_ARM64_PA_BITS_48=y
# CONFIG_ARM64_SW_TTBR0_PAN is not set
CONFIG_ARM64_TAGGED_ADDR_ABI=y
CONFIG_ARM64_VA_BITS=39
CONFIG_ARM64_VA_BITS_39=y
@ -88,11 +87,7 @@ CONFIG_COMMON_CLK_MT7622_HIFSYS=y
# CONFIG_COMMON_CLK_MT8183_VENCSYS is not set
# CONFIG_COMMON_CLK_MT8516 is not set
# CONFIG_COMMON_CLK_MT8516_AUDSYS is not set
CONFIG_COMPAT=y
CONFIG_COMPAT_32BIT_TIME=y
CONFIG_COMPAT_BINFMT_ELF=y
CONFIG_COMPAT_NETLINK_MESSAGES=y
CONFIG_COMPAT_OLD_SIGACTION=y
CONFIG_CONFIGFS_FS=y
CONFIG_CONSOLE_LOGLEVEL_DEFAULT=15
# CONFIG_CPUFREQ_DT is not set

View File

@ -131,7 +131,6 @@ CONFIG_GENERIC_TIME_VSYSCALL=y
CONFIG_GENERIC_VDSO_32=y
CONFIG_GPIO_CDEV=y
CONFIG_HANDLE_DOMAIN_IRQ=y
# CONFIG_HARDENED_USERCOPY is not set
CONFIG_HARDEN_BRANCH_PREDICTOR=y
CONFIG_HARDIRQS_SW_RESEND=y
CONFIG_HAS_DMA=y

View File

@ -112,8 +112,6 @@ CONFIG_IRQ_WORK=y
CONFIG_ISA_DMA_API=y
CONFIG_KERNEL_START=0xc0000000
# CONFIG_KSI8560 is not set
CONFIG_LEGACY_PTYS=y
CONFIG_LEGACY_PTY_COUNT=256
CONFIG_LIBFDT=y
CONFIG_LOCK_DEBUGGING_SUPPORT=y
CONFIG_LOWMEM_CAM_NUM=3

View File

@ -112,8 +112,6 @@ CONFIG_IRQ_WORK=y
CONFIG_ISA_DMA_API=y
CONFIG_KERNEL_START=0xc0000000
# CONFIG_KSI8560 is not set
CONFIG_LEGACY_PTYS=y
CONFIG_LEGACY_PTY_COUNT=256
CONFIG_LIBFDT=y
CONFIG_LOCK_DEBUGGING_SUPPORT=y
CONFIG_LOWMEM_CAM_NUM=3

View File

@ -0,0 +1,158 @@
// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
#include "mt7621.dtsi"
#include <dt-bindings/gpio/gpio.h>
#include <dt-bindings/input/input.h>
/ {
compatible = "dlink,dap-1620-b1", "mediatek,mt7621-soc";
model = "D-Link DAP-1620 B1";
aliases {
label-mac-device = &gmac0;
led-boot = &led_status_red;
led-failsafe = &led_status_green;
led-running = &led_status_green;
led-upgrade = &led_status_red;
};
keys {
compatible = "gpio-keys";
reset {
label = "reset";
gpios = <&gpio 7 GPIO_ACTIVE_LOW>;
linux,code = <KEY_RESTART>;
debounce-interval = <60>;
};
wps {
label = "wps";
gpios = <&gpio 18 GPIO_ACTIVE_LOW>;
linux,code = <KEY_WPS_BUTTON>;
};
};
leds {
compatible = "gpio-leds";
led_status_red: status_red {
label = "red:status";
gpios = <&gpio 16 GPIO_ACTIVE_LOW>;
};
led_status_green: status_green {
label = "green:status";
gpios = <&gpio 13 GPIO_ACTIVE_LOW>;
};
rssi_low_red {
label = "red:rssilow";
gpios = <&gpio 25 GPIO_ACTIVE_LOW>;
};
rssi_low_green {
label = "green:rssilow";
gpios = <&gpio 24 GPIO_ACTIVE_LOW>;
};
rssi_med_green {
label = "green:rssimed";
gpios = <&gpio 23 GPIO_ACTIVE_LOW>;
};
rssi_high_green {
label = "green:rssihigh";
gpios = <&gpio 22 GPIO_ACTIVE_LOW>;
};
};
};
&spi0 {
status = "okay";
flash@0 {
compatible = "jedec,spi-nor";
reg = <0>;
spi-max-frequency = <50000000>;
partitions {
compatible = "fixed-partitions";
#address-cells = <1>;
#size-cells = <1>;
partition@0 {
label = "u-boot";
reg = <0x0 0x30000>;
read-only;
};
partition@30000 {
label = "u-boot-env";
reg = <0x30000 0x10000>;
read-only;
};
factory: partition@40000 {
label = "factory";
reg = <0x40000 0x10000>;
read-only;
compatible = "nvmem-cells";
#address-cells = <1>;
#size-cells = <1>;
macaddr_factory_e000: macaddr@e000 {
reg = <0xe000 0x6>;
};
};
partition@50000 {
compatible = "denx,uimage";
label = "firmware";
reg = <0x50000 0xfb0000>;
};
};
};
};
&pcie {
status = "okay";
};
&pcie0 {
wifi@0,0 {
compatible = "mediatek,mt76";
reg = <0x0000 0 0 0 0>;
mediatek,mtd-eeprom = <&factory 0x0>;
/* The correct MAC addresses are set in 10_fix_wifi_mac. */
};
};
&gmac0 {
nvmem-cells = <&macaddr_factory_e000>;
nvmem-cell-names = "mac-address";
};
&switch0 {
ports {
port@0 {
status = "okay";
label = "lan";
};
};
};
&ethernet {
pinctrl-0 = <&mdio_pins>, <&rgmii1_pins>;
};
&state_default {
gpio {
groups = "uart3", "jtag", "wdt";
function = "gpio";
};
};

View File

@ -11,6 +11,8 @@
model = "TP-Link EC330-G5u v1";
aliases {
label-mac-device = &gmac0;
led-boot = &led_power;
led-failsafe = &led_power;
led-running = &led_power;
@ -226,6 +228,14 @@
label = "factory";
reg = <0x7800000 0x400000>;
read-only;
compatible = "nvmem-cells";
#address-cells = <1>;
#size-cells = <1>;
macaddr_factory_165: macaddr@165 {
reg = <0x165 0x11>;
};
};
partition@0_wholeflash {
@ -246,6 +256,9 @@
reg = <0x0000 0 0 0 0>;
mediatek,mtd-eeprom = <&factory 0x8000>;
ieee80211-freq-limit = <2400000 2500000>;
nvmem-cells = <&macaddr_factory_165>;
nvmem-cell-names = "mac-address-ascii";
};
};
@ -255,13 +268,26 @@
reg = <0x0000 0 0 0 0>;
mediatek,mtd-eeprom = <&factory 0x14000>;
ieee80211-freq-limit = <5000000 6000000>;
nvmem-cells = <&macaddr_factory_165>;
nvmem-cell-names = "mac-address-ascii";
mac-address-increment = <(2)>;
};
};
&gmac0 {
nvmem-cells = <&macaddr_factory_165>;
nvmem-cell-names = "mac-address-ascii";
};
&gmac1 {
status = "okay";
label = "wan";
phy-handle = <&ethphy0>;
nvmem-cells = <&macaddr_factory_165>;
nvmem-cell-names = "mac-address-ascii";
mac-address-increment = <(1)>;
};
&mdio {

View File

@ -0,0 +1,233 @@
// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
#include "mt7621.dtsi"
#include <dt-bindings/gpio/gpio.h>
#include <dt-bindings/input/input.h>
/ {
compatible = "zyxel,wsm20", "mediatek,mt7621-soc";
model = "ZyXEL WSM20";
aliases {
led-boot = &led_system_white;
led-failsafe = &led_system_red;
led-running = &led_system_white;
led-upgrade = &led_system_red;
label-mac-device = &gmac0;
};
chosen {
bootargs-override = "console=ttyS0,115200n1";
};
leds {
compatible = "gpio-leds";
led_system_white: led-0 {
gpios = <&gpio 3 GPIO_ACTIVE_LOW>;
label = "white:system";
};
led_system_red: led-1 {
gpios = <&gpio 4 GPIO_ACTIVE_LOW>;
label = "red:system";
};
led-2 {
gpios = <&gpio 8 GPIO_ACTIVE_LOW>;
label = "green:led1";
};
led-3 {
gpios = <&gpio 0 GPIO_ACTIVE_LOW>;
label = "white:led2";
};
led-4 {
gpios = <&gpio 13 GPIO_ACTIVE_LOW>;
label = "green:led3";
};
led-5 {
gpios = <&gpio 17 GPIO_ACTIVE_HIGH>;
label = "red:led4";
};
led-6 {
gpios = <&gpio 5 GPIO_ACTIVE_HIGH>;
label = "white:led5";
};
};
keys {
compatible = "gpio-keys";
led {
label = "led";
gpios = <&gpio 16 GPIO_ACTIVE_LOW>;
linux,code = <BTN_0>;
};
reset {
label = "reset";
gpios = <&gpio 6 GPIO_ACTIVE_LOW>;
linux,code = <KEY_RESTART>;
};
wps {
label = "wps";
gpios = <&gpio 18 GPIO_ACTIVE_LOW>;
linux,code = <KEY_WLAN>;
};
};
};
&nand {
status = "okay";
partitions {
compatible = "fixed-partitions";
#address-cells = <1>;
#size-cells = <1>;
partition@0 {
reg = <0x0 0x100000>;
label = "Bootloader";
read-only;
};
partition@100000 {
reg = <0x100000 0x100000>;
label = "Config";
};
factory: partition@200000 {
reg = <0x200000 0x1c0000>;
label = "Factory";
read-only;
};
partition@3c0000 {
reg = <0x3c0000 0x2800000>;
label = "firmware";
compatible = "fixed-partitions";
#address-cells = <1>;
#size-cells = <1>;
partition@0 {
label = "kernel";
reg = <0x0 0x800000>;
};
partition@800000 {
label = "ubi";
reg = <0x800000 0x2000000>;
};
};
partition@2bc0000 {
reg = <0x2bc0000 0x2800000>;
label = "Kernel2";
};
partition@53c0000 {
reg = <0x53c0000 0x100000>;
label = "persist";
};
partition@54c0000 {
reg = <0x54c0000 0x400000>;
label = "rootfs_data";
read-only;
};
partition@58C0000 {
reg = <0x58c0000 0x25c0000>;
label = "app";
read-only;
};
partition@7e80000 {
reg = <0x7e80000 0x100000>;
label = "crt";
read-only;
};
};
};
&gmac0 {
nvmem-cells = <&macaddr_factory_1fdfa>;
nvmem-cell-names = "mac-address";
};
&gmac1 {
status = "okay";
label = "wan";
phy-handle = <&ethphy0>;
nvmem-cells = <&macaddr_factory_1fdf4>;
nvmem-cell-names = "mac-address";
};
&mdio {
ethphy0: ethernet-phy@0 {
reg = <0>;
};
};
&pcie {
status = "okay";
};
&pcie1 {
wifi@0,0 {
compatible = "mediatek,mt76";
reg = <0x0000 0 0 0 0>;
mediatek,mtd-eeprom = <&factory 0x0>;
mediatek,disable-radar-background;
};
};
&pcie2 {
status = "disabled";
};
&switch0 {
ports {
port@1 {
status = "okay";
label = "lan3";
};
port@2 {
status = "okay";
label = "lan2";
};
port@3 {
status = "okay";
label = "lan1";
};
};
};
&state_default {
gpio {
groups = "i2c", "uart3", "jtag", "wdt";
function = "gpio";
};
};
&factory {
compatible = "nvmem-cells";
#address-cells = <1>;
#size-cells = <1>;
macaddr_factory_1fdfa: macaddr@1fdfa {
reg = <0x1fdfa 0x6>;
};
macaddr_factory_1fdf4: macaddr@1fdf4 {
reg = <0x1fdf4 0x6>;
};
};

View File

@ -43,6 +43,7 @@ define Build/loader-common
BOARD="$(BOARDNAME)" PLATFORM="$(LOADER_PLATFORM)" \
LZMA_TEXT_START=$(LZMA_TEXT_START) \
LOADADDR=$(LOADADDR) \
SUBTARGET=$(SUBTARGET) \
$(1) compile loader.$(LOADER_TYPE)
mv "$@.$(LOADER_TYPE)" "$@"
rm -rf $@.src

View File

@ -18,6 +18,8 @@ FLASH_OFFS :=
FLASH_MAX :=
BOARD :=
PLATFORM :=
SUBTARGET :=
CACHE_FLAGS := -DCONFIG_CACHELINE_SIZE=32
ifeq ($(TARGET_DIR),)
TARGET_DIR := $(KDIR)
@ -46,6 +48,8 @@ loader-compile: $(PKG_BUILD_DIR)/.prepared
FLASH_MAX=$(FLASH_MAX) \
BOARD="$(BOARD)" \
PLATFORM="$(PLATFORM)" \
SUBTARGET="$(SUBTARGET)" \
CACHE_FLAGS="$(CACHE_FLAGS)" \
clean all
loader.gz: $(PKG_BUILD_DIR)/loader.bin

View File

@ -23,6 +23,7 @@ FLASH_START :=
FLASH_OFFS :=
FLASH_MAX :=
PLATFORM :=
SUBTARGET :=
CACHE_FLAGS :=
CC := $(CROSS_COMPILE)gcc
@ -31,8 +32,6 @@ OBJCOPY := $(CROSS_COMPILE)objcopy
OBJDUMP := $(CROSS_COMPILE)objdump
include $(PLATFORM).mk
BIN_FLAGS := -O binary -R .reginfo -R .note -R .comment -R .mdebug \
-R .MIPS.abiflags -S
@ -54,7 +53,27 @@ LDFLAGS += -flto -fwhole-program -Wl,-z,max-page-size=4096
O_FORMAT = $(shell $(OBJDUMP) -i | head -2 | grep elf32)
OBJECTS := head.o loader.o cache.o board-$(PLATFORM).o printf.o LzmaDecode.o
OBJECTS := head.o loader.o cache.o board.o printf.o LzmaDecode.o
ifeq ($(strip $(SUBTARGET)),)
$(error "Please specify a SUBTARGET!")
endif
ifeq ($(strip $(SUBTARGET)),mt7620)
CFLAGS += -DSOC_MT7620
endif
ifeq ($(strip $(SUBTARGET)),mt7621)
CFLAGS += -DSOC_MT7621
endif
ifeq ($(strip $(SUBTARGET)),rt305x)
CFLAGS += -DSOC_RT305X
endif
ifeq ($(strip $(SUBTARGET)),rt3883)
CFLAGS += -DSOC_RT3883
endif
ifneq ($(strip $(LOADER_DATA)),)
OBJECTS += data.o

View File

@ -1,39 +0,0 @@
/*
* Arch specific code for mt7621 based boards, based on code for Ralink boards
*
* Copyright (C) 2018 Tobias Schramm <tobleminer@gmail.com>
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 as published
* by the Free Software Foundation.
*/
#include <stddef.h>
#include <stdint.h>
#include "config.h"
#define READREG(r) *(volatile uint32_t *)(r)
#define WRITEREG(r,v) *(volatile uint32_t *)(r) = v
#define KSEG1ADDR(_x) (((_x) & 0x1fffffff) | 0xa0000000)
#define UART_BASE 0xBE000C00
#define UART_TBR_OFFSET 0x00
#define UART_LSR_OFFSET 0x14
#define UART_LSR_TEMT (1 << 6)
#define UART_READ(r) READREG(UART_BASE + (r))
#define UART_WRITE(r,v) WRITEREG(UART_BASE + (r), (v))
void board_putc(int ch)
{
while (((UART_READ(UART_LSR_OFFSET)) & UART_LSR_TEMT) == 0);
UART_WRITE(UART_TBR_OFFSET, ch);
while (((UART_READ(UART_LSR_OFFSET)) & UART_LSR_TEMT) == 0);
}
void board_init(void)
{
}

View File

@ -1,42 +0,0 @@
/*
* Arch specific code for Ralink based boards
*
* Copyright (C) 2013 John Crispin <blogic@openwrt.org>
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 as published
* by the Free Software Foundation.
*/
#include <stddef.h>
#include "config.h"
#define READREG(r) *(volatile unsigned int *)(r)
#define WRITEREG(r,v) *(volatile unsigned int *)(r) = v
#define KSEG1ADDR(_x) (((_x) & 0x1fffffff) | 0xa0000000)
#ifdef CONFIG_SOC_RT288X
#define UART_BASE 0xb0300c00
#else
#define UART_BASE 0xb0000c00
#endif
#define UART_TX 1
#define UART_LSR 7
#define UART_LSR_THRE 0x20
#define UART_READ(r) READREG(UART_BASE + 4 * (r))
#define UART_WRITE(r,v) WRITEREG(UART_BASE + 4 * (r), (v))
void board_putc(int ch)
{
while (((UART_READ(UART_LSR)) & UART_LSR_THRE) == 0);
UART_WRITE(UART_TX, ch);
while (((UART_READ(UART_LSR)) & UART_LSR_THRE) == 0);
}
void board_init(void)
{
}

View File

@ -0,0 +1,48 @@
/*
* Arch specific code for ramips based boards
*
* Copyright (C) 2013 John Crispin <blogic@openwrt.org>
* Copyright (C) 2018 Tobias Schramm <tobleminer@gmail.com>
* Copyright (C) 2023 Antonio Vázquez <antoniovazquezblanco@gmail.com>
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 as published
* by the Free Software Foundation.
*/
#include <stdint.h>
#if defined(SOC_MT7620) || defined(SOC_RT3883)
#define UART_BASE 0xb0000c00
#define UART_THR (UART_BASE + 0x04)
#define UART_LSR (UART_BASE + 0x1c)
#define UART_LSR_THRE_MASK 0x40
#elif defined(SOC_MT7621)
#define UART_BASE 0xbe000c00
#define UART_THR (UART_BASE + 0x00)
#define UART_LSR (UART_BASE + 0x14)
#define UART_LSR_THRE_MASK 0x20
#elif defined(SOC_RT305X)
#define UART_BASE 0x10000500
#define UART_THR (UART_BASE + 0x04)
#define UART_LSR (UART_BASE + 0x1c)
#define UART_LSR_THRE_MASK 0x20
#else
#error "Unsupported SOC..."
#endif
// Helper functions
#define READREG(r) (*(volatile uint32_t *)(r))
#define WRITEREG(r,v) (*(volatile uint32_t *)(r)) = v
void board_init(void)
{
}
void board_putc(int ch)
{
while ((READREG(UART_LSR) & UART_LSR_THRE_MASK) == 0);
WRITEREG(UART_THR, ch);
while ((READREG(UART_LSR) & UART_LSR_THRE_MASK) == 0);
}

View File

@ -1 +0,0 @@
CACHE_FLAGS+=-DCONFIG_ICACHE_SIZE="(32 * 1024)" -DCONFIG_DCACHE_SIZE="(32 * 1024)" -DCONFIG_CACHELINE_SIZE=32

View File

@ -1 +0,0 @@
CACHE_FLAGS+=-DCONFIG_ICACHE_SIZE="(32 * 1024)" -DCONFIG_DCACHE_SIZE="(16 * 1024)" -DCONFIG_CACHELINE_SIZE=32

View File

@ -1 +0,0 @@
CACHE_FLAGS+=-DCONFIG_ICACHE_SIZE="(32 * 1024)" -DCONFIG_DCACHE_SIZE="(16 * 1024)" -DCONFIG_CACHELINE_SIZE=32

View File

@ -7,7 +7,7 @@ include ./common-tp-link.mk
DEFAULT_SOC := mt7621
DEVICE_VARS += ELECOM_HWNAME LINKSYS_HWNAME
DEVICE_VARS += ELECOM_HWNAME LINKSYS_HWNAME DLINK_HWID
ifdef CONFIG_LINUX_5_10
DTS_CPPFLAGS += -DDTS_LEGACY
@ -62,6 +62,29 @@ define Build/iodata-mstc-header
)
endef
define Build/znet-header
$(eval version=$(word 1,$(1)))
( \
data_size_crc="$$(dd if=$@ 2>/dev/null | gzip -c | \
tail -c 8 | od -An -N4 -tx4 --endian big | tr -d ' \n')"; \
payload_len="$$(dd if=$@ bs=4 count=1 skip=1 2>/dev/null | od -An -tdI --endian big | tr -d ' \n')"; \
payload_size_crc="$$(dd if=$@ ibs=1 count=$$payload_len 2>/dev/null | gzip -c | \
tail -c 8 | od -An -N4 -tx4 --endian big | tr -d ' \n')"; \
echo -ne "\x5A\x4E\x45\x54" | dd bs=4 count=1 conv=sync 2>/dev/null; \
echo -ne "$$(printf '%08x' $$(stat -c%s $@) | fold -s2 | xargs -I {} echo \\x{} | tac | tr -d '\n')" | \
dd bs=4 count=1 conv=sync 2>/dev/null; \
echo -ne "$$(echo $$data_size_crc | sed 's/../\\x&/g')" | \
dd bs=4 count=1 conv=sync 2>/dev/null; \
echo -ne "$$(echo $$payload_size_crc | sed 's/../\\x&/g')" | \
dd bs=4 count=1 conv=sync 2>/dev/null; \
echo -ne "\x12\x34\x56\x78" | dd bs=4 count=1 conv=sync 2>/dev/null; \
echo -ne "$(version)" | dd bs=28 count=1 conv=sync 2>/dev/null; \
dd if=/dev/zero bs=262096 count=1 conv=sync 2>/dev/null | tr "\000" "\377"; \
cat $@; \
) > $@.new
mv $@.new $@
endef
define Build/belkin-header
$(eval magic=$(word 1,$(1)))
$(eval hw_ver=$(word 2,$(1)))
@ -532,6 +555,22 @@ define Device/cudy_x6
endef
TARGET_DEVICES += cudy_x6
define Device/dlink_dap-1620-b1
DEVICE_VENDOR := D-Link
DEVICE_MODEL := DAP-1620
DEVICE_VARIANT := B1
DEVICE_PACKAGES := kmod-mt7615-firmware rssileds
DLINK_HWID := MT76XMT7621-RP-PR2475-NA
IMAGE_SIZE := 16064k
IMAGES += factory.bin
IMAGE/factory.bin := $$(sysupgrade_bin) | \
check-size 11009992 | pad-to 11009992 | \
append-md5sum-ascii-salted ffff | \
append-string $$(DLINK_HWID) | \
check-size
endef
TARGET_DEVICES += dlink_dap-1620-b1
define Device/dlink_dap-x1860-a1
$(Device/dsa-migration)
IMAGE_SIZE := 53248k
@ -2188,6 +2227,9 @@ define Device/tplink_ec330-g5u-v1
uImage-tplink-c9 firmware 'OS IMAGE ($(VERSION_DIST))'
KERNEL_INITRAMFS := kernel-bin | append-dtb | lzma | loader-kernel | \
uImage none
IMAGES += factory.bin
IMAGE/factory.bin := append-kernel | pad-to $$(KERNEL_SIZE) | \
append-ubi | check-size
IMAGE/sysupgrade.bin := sysupgrade-tar | append-metadata | check-size
endef
TARGET_DEVICES += tplink_ec330-g5u-v1
@ -2907,3 +2949,19 @@ define Device/zyxel_wap6805
IMAGE/sysupgrade.bin := sysupgrade-tar | append-metadata
endef
TARGET_DEVICES += zyxel_wap6805
define Device/zyxel_wsm20
$(Device/dsa-migration)
BLOCKSIZE := 128k
PAGESIZE := 2048
KERNEL_SIZE := 8192k
IMAGE_SIZE := 41943040
UBINIZE_OPTS := -E 5
DEVICE_VENDOR := ZyXEL
DEVICE_MODEL := WSM20
DEVICE_PACKAGES := kmod-mt7915-firmware
KERNEL := kernel-bin | lzma | fit lzma $$(KDIR)/image-$$(firstword $$(DEVICE_DTS)).dtb | znet-header V1.00(ABZF.0)C0
KERNEL_INITRAMFS := kernel-bin | lzma | fit lzma $$(KDIR)/image-$$(firstword $$(DEVICE_DTS)).dtb | znet-header V1.00(ABZF.0)C0
IMAGE/sysupgrade.bin := sysupgrade-tar | append-metadata
endef
TARGET_DEVICES += zyxel_wsm20

View File

@ -60,6 +60,13 @@ jcg,y2|\
xzwifi,creativebox-v1)
ucidef_set_led_netdev "internet" "internet" "blue:internet" "wan"
;;
dlink,dap-1620-b1)
ucidef_set_rssimon "wlan1" "200000" "1"
ucidef_set_led_rssi "rssilow" "RSSILOW" "red:rssilow" "wlan1" "1" "40"
ucidef_set_led_rssi "rssimediumlow" "RSSIMEDIUMLOW" "green:rssilow" "wlan1" "21" "100"
ucidef_set_led_rssi "rssimediumhigh" "RSSIMEDIUMHIGH" "green:rssimed" "wlan1" "61" "100"
ucidef_set_led_rssi "rssihigh" "RSSIHIGH" "green:rssihigh" "wlan1" "81" "100"
;;
dlink,dap-x1860-a1)
ucidef_set_rssimon "wlan1" "200000" "1"
ucidef_set_led_rssi "rssilow" "RSSILOW" "orange:rssilow" "wlan1" "1" "25"

View File

@ -14,6 +14,7 @@ ramips_setup_interfaces()
ampedwireless,ally-00x19k|\
asus,rp-ac56|\
asus,rp-ac87|\
dlink,dap-1620-b1|\
dlink,dap-x1860-a1|\
edimax,re23s|\
mikrotik,ltap-2hnd|\
@ -49,7 +50,8 @@ ramips_setup_interfaces()
xiaomi,mi-router-cr6606|\
xiaomi,mi-router-cr6608|\
xiaomi,mi-router-cr6609|\
xiaomi,redmi-router-ac2100)
xiaomi,redmi-router-ac2100|\
zyxel,wsm20)
ucidef_set_interfaces_lan_wan "lan1 lan2 lan3" "wan"
;;
asiarf,ap7621-001|\
@ -244,11 +246,6 @@ ramips_setup_macs()
label_mac=$(cat "/sys/firmware/mikrotik/hard_config/mac_base")
lan_mac=$label_mac
;;
tplink,ec330-g5u-v1)
label_mac="$(mtd_get_mac_text factory 0x165)"
lan_mac=$label_mac
wan_mac=$(macaddr_add $label_mac 1)
;;
tplink,er605-v2)
CI_UBIPART="firmware"
label_mac=$(mtd_get_mac_uci_config_ubi "tddp")

View File

@ -32,13 +32,7 @@ case "$board" in
[ "$PHYNBR" = "1" ] && \
macaddr_setbit_la "$(macaddr_add $hw_mac_addr 0x100000)" > /sys${DEVPATH}/macaddress
;;
dlink,dap-x1860-a1)
hw_mac_addr="$(mtd_get_mac_binary factory 0x4)"
[ "$PHYNBR" = "0" ] && \
macaddr_add $hw_mac_addr 1 > /sys${DEVPATH}/macaddress
[ "$PHYNBR" = "1" ] && \
macaddr_add $hw_mac_addr 4 > /sys${DEVPATH}/macaddress
;;
dlink,dap-1620-b1|\
dlink,dir-853-a1)
lan_mac_addr="$(mtd_get_mac_binary factory 0xe000)"
[ "$PHYNBR" = "0" ] && \
@ -46,6 +40,13 @@ case "$board" in
[ "$PHYNBR" = "1" ] && \
macaddr_add $lan_mac_addr 2 > /sys${DEVPATH}/macaddress
;;
dlink,dap-x1860-a1)
hw_mac_addr="$(mtd_get_mac_binary factory 0x4)"
[ "$PHYNBR" = "0" ] && \
macaddr_add $hw_mac_addr 1 > /sys${DEVPATH}/macaddress
[ "$PHYNBR" = "1" ] && \
macaddr_add $hw_mac_addr 4 > /sys${DEVPATH}/macaddress
;;
dlink,dir-853-a3)
[ "$PHYNBR" = "0" ] && \
macaddr_setbit_la "$(mtd_get_mac_binary factory 0xe000)" \
@ -160,11 +161,6 @@ case "$board" in
hw_mac_addr="$(mtd_get_mac_binary product-info 0x8)"
macaddr_add "$hw_mac_addr" "$PHYNBR" > "/sys${DEVPATH}/macaddress"
;;
tplink,ec330-g5u-v1)
hw_mac_addr="$(mtd_get_mac_text factory 0x165)"
[ "$PHYNBR" = "0" ] && echo -n $hw_mac_addr > /sys${DEVPATH}/macaddress
[ "$PHYNBR" = "1" ] && macaddr_add $hw_mac_addr 2 > /sys${DEVPATH}/macaddress
;;
yuncore,ax820)
[ "$PHYNBR" = "1" ] && \
macaddr_setbit_la "$(mtd_get_mac_binary Factory 0xe000)" > /sys${DEVPATH}/macaddress
@ -181,4 +177,9 @@ case "$board" in
[ "$PHYNBR" = "0" ] && macaddr_add $hw_mac_addr 1 > /sys${DEVPATH}/macaddress
[ "$PHYNBR" = "1" ] && macaddr_add $hw_mac_addr 2 > /sys${DEVPATH}/macaddress
;;
zyxel,wsm20)
hw_mac_addr="$(mtd_get_mac_binary Factory 0x1fdfa)"
[ "$PHYNBR" = "0" ] && macaddr_add $hw_mac_addr 1 > /sys${DEVPATH}/macaddress
[ "$PHYNBR" = "1" ] && macaddr_add $hw_mac_addr 2 > /sys${DEVPATH}/macaddress
;;
esac

View File

@ -155,6 +155,10 @@ platform_do_upgrade() {
CI_KERNPART="Kernel"
nand_do_upgrade "$1"
;;
zyxel,wsm20)
zyxel_mstc_upgrade_prepare
nand_do_upgrade "$1"
;;
*)
default_do_upgrade "$1"
;;

View File

@ -0,0 +1,39 @@
#
# Copyright (C) 2023 OpenWrt.org
#
. /lib/functions.sh
zyxel_mstc_prepare_fail() {
echo "failed to check and prepare the environment, rebooting..."
umount -a
reboot -f
}
zyxel_mstc_upgrade_prepare() {
local persist_mtd="$(find_mtd_part persist)"
local firmware_mtd="$(find_mtd_part firmware)"
if [ -z "$persist_mtd" ] || [ -z "$firmware_mtd" ]; then
echo 'cannot find mtd partition(s) "persist" or "firmware"'
zyxel_mstc_prepare_fail
fi
local bootnum=$(hexdump -s 4 -n 1 -e '"%x"' ${persist_mtd})
if [ "$bootnum" != "1" ] && [ "$bootnum" != "2" ]; then
echo "failed to get bootnum, please check the value at 0x4 in ${persist_mtd}"
zyxel_mstc_prepare_fail
fi
echo "current: bootnum => ${bootnum}"
[ "$(fw_printenv -n bootmenu_delay)" = "3" ] || fw_setenv bootmenu_delay 3
if [ "$bootnum" = "2" ]; then
if ! ( echo -ne "\x01" | dd of=${persist_mtd} count=1 bs=1 seek=4 conv=notrunc 2>/dev/null ); then
echo "failed to set new boot partition"
zyxel_mstc_prepare_fail
fi
echo "### switch to 1st os-image on next boot ###"
fi
}

View File

@ -116,8 +116,6 @@ CONFIG_IRQ_MIPS_CPU=y
CONFIG_IRQ_WORK=y
CONFIG_JFFS2_ZLIB=y
CONFIG_LEDS_GPIO=y
CONFIG_LEGACY_PTYS=y
CONFIG_LEGACY_PTY_COUNT=256
CONFIG_LIBFDT=y
CONFIG_LOCK_DEBUGGING_SUPPORT=y
CONFIG_MARVELL_PHY=y

View File

@ -114,8 +114,6 @@ CONFIG_IRQ_MIPS_CPU=y
CONFIG_IRQ_WORK=y
CONFIG_JFFS2_ZLIB=y
CONFIG_LEDS_GPIO=y
CONFIG_LEGACY_PTYS=y
CONFIG_LEGACY_PTY_COUNT=256
CONFIG_LIBFDT=y
CONFIG_LOCK_DEBUGGING_SUPPORT=y
CONFIG_MARVELL_PHY=y

View File

@ -109,8 +109,6 @@ CONFIG_IRQ_MIPS_CPU=y
CONFIG_IRQ_WORK=y
CONFIG_JFFS2_ZLIB=y
CONFIG_LEDS_GPIO=y
CONFIG_LEGACY_PTYS=y
CONFIG_LEGACY_PTY_COUNT=256
CONFIG_LIBFDT=y
CONFIG_LLD_VERSION=0
CONFIG_LOCK_DEBUGGING_SUPPORT=y

View File

@ -111,8 +111,6 @@ CONFIG_IRQ_MIPS_CPU=y
CONFIG_IRQ_WORK=y
CONFIG_JFFS2_ZLIB=y
CONFIG_LEDS_GPIO=y
CONFIG_LEGACY_PTYS=y
CONFIG_LEGACY_PTY_COUNT=256
CONFIG_LIBFDT=y
CONFIG_LOCK_DEBUGGING_SUPPORT=y
CONFIG_MARVELL_PHY=y

View File

@ -100,8 +100,6 @@ CONFIG_IRQ_MIPS_CPU=y
CONFIG_IRQ_WORK=y
CONFIG_JFFS2_ZLIB=y
CONFIG_LEDS_GPIO=y
CONFIG_LEGACY_PTYS=y
CONFIG_LEGACY_PTY_COUNT=256
CONFIG_LIBFDT=y
CONFIG_LLD_VERSION=0
CONFIG_LOCK_DEBUGGING_SUPPORT=y

View File

@ -95,8 +95,6 @@ CONFIG_IRQ_MIPS_CPU=y
CONFIG_IRQ_WORK=y
CONFIG_JFFS2_ZLIB=y
CONFIG_LEDS_GPIO=y
CONFIG_LEGACY_PTYS=y
CONFIG_LEGACY_PTY_COUNT=256
CONFIG_LIBFDT=y
CONFIG_LOCK_DEBUGGING_SUPPORT=y
CONFIG_MARVELL_PHY=y

View File

@ -101,8 +101,6 @@ CONFIG_IRQ_MIPS_CPU=y
CONFIG_IRQ_WORK=y
CONFIG_JFFS2_ZLIB=y
CONFIG_LEDS_GPIO=y
CONFIG_LEGACY_PTYS=y
CONFIG_LEGACY_PTY_COUNT=256
CONFIG_LIBFDT=y
CONFIG_LLD_VERSION=0
CONFIG_LOCK_DEBUGGING_SUPPORT=y

View File

@ -103,8 +103,6 @@ CONFIG_IRQ_WORK=y
CONFIG_JFFS2_ZLIB=y
CONFIG_KMAP_LOCAL=y
CONFIG_LEDS_GPIO=y
CONFIG_LEGACY_PTYS=y
CONFIG_LEGACY_PTY_COUNT=256
CONFIG_LIBFDT=y
CONFIG_LOCK_DEBUGGING_SUPPORT=y
CONFIG_MARVELL_PHY=y

View File

@ -41,7 +41,6 @@ CONFIG_ARM64_PTR_AUTH=y
# CONFIG_ARM64_PTR_AUTH_KERNEL is not set
CONFIG_ARM64_RAS_EXTN=y
CONFIG_ARM64_SVE=y
# CONFIG_ARM64_SW_TTBR0_PAN is not set
CONFIG_ARM64_TAGGED_ADDR_ABI=y
CONFIG_ARM64_VA_BITS=48
# CONFIG_ARM64_VA_BITS_39 is not set
@ -127,10 +126,7 @@ CONFIG_COMMON_CLK_RK808=y
CONFIG_COMMON_CLK_ROCKCHIP=y
CONFIG_COMMON_CLK_SCMI=y
CONFIG_COMMON_CLK_SCPI=y
CONFIG_COMPAT=y
CONFIG_COMPAT_32BIT_TIME=y
CONFIG_COMPAT_BINFMT_ELF=y
CONFIG_COMPAT_OLD_SIGACTION=y
CONFIG_CONFIGFS_FS=y
CONFIG_CONSOLE_TRANSLATIONS=y
CONFIG_CONTIG_ALLOC=y
@ -268,7 +264,6 @@ CONFIG_GPIO_GENERIC_PLATFORM=y
CONFIG_GPIO_ROCKCHIP=y
CONFIG_GPIO_SYSCON=y
CONFIG_HANDLE_DOMAIN_IRQ=y
# CONFIG_HARDENED_USERCOPY is not set
CONFIG_HARDIRQS_SW_RESEND=y
CONFIG_HAS_DMA=y
CONFIG_HAS_IOMEM=y
@ -336,8 +331,6 @@ CONFIG_LEDS_PWM=y
CONFIG_LEDS_SYSCON=y
CONFIG_LEDS_TRIGGER_CPU=y
CONFIG_LEDS_TRIGGER_PANIC=y
CONFIG_LEGACY_PTYS=y
CONFIG_LEGACY_PTY_COUNT=16
CONFIG_LIBCRC32C=y
CONFIG_LIBFDT=y
CONFIG_LOCALVERSION_AUTO=y

View File

@ -8,11 +8,11 @@ include $(TOPDIR)/rules.mk
PKG_NAME:=coreutils
PKG_CPE_ID:=cpe:/a:gnu:coreutils
PKG_VERSION:=9.2
PKG_VERSION:=9.3
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.xz
PKG_SOURCE_URL:=@GNU/coreutils
PKG_HASH:=6885ff47b9cdb211de47d368c17853f406daaf98b148aaecdf10de29cc04b0b3
PKG_HASH:=adbcfcfe899235b71e8768dcf07cd532520b7f54f9a8064843f8d199a904bbaa
HOST_BUILD_PARALLEL := 1

View File

@ -1,126 +0,0 @@
From 093a8b4bfaba60005f14493ce7ef11ed665a0176 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?P=C3=A1draig=20Brady?= <P@draigBrady.com>
Date: Thu, 23 Mar 2023 13:19:04 +0000
Subject: [PATCH] copy: fix --reflink=auto to fallback in more cases
On restricted systems like android or some containers,
FICLONE could return EPERM, EACCES, or ENOTTY,
which would have induced the command to fail to copy
rather than falling back to a more standard copy.
* src/copy.c (is_terminal_failure): A new function refactored
from handle_clone_fail().
(is_CLONENOTSUP): Merge in the handling of EACCES, ENOTTY, EPERM
as they also pertain to determination of whether cloning is supported
if we ever use this function in that context.
(handle_clone_fail): Use is_terminal_failure() in all cases,
so that we assume a terminal failure in less errno cases.
* NEWS: Mention the bug fix.
Addresses https://bugs.gnu.org/62404
---
--- a/src/copy.c
+++ b/src/copy.c
@@ -278,15 +278,27 @@ create_hole (int fd, char const *name, b
}
-/* Whether the errno from FICLONE, or copy_file_range
- indicates operation is not supported for this file or file system. */
+/* Whether the errno indicates the operation is a transient failure.
+ I.e., a failure that would indicate the operation _is_ supported,
+ but has failed in a terminal way. */
+
+static bool
+is_terminal_error (int err)
+{
+ return err == EIO || err == ENOMEM || err == ENOSPC || err == EDQUOT;
+}
+
+
+/* Whether the errno from FICLONE, or copy_file_range indicates
+ the operation is not supported/allowed for this file or process. */
static bool
is_CLONENOTSUP (int err)
{
- return err == ENOSYS || is_ENOTSUP (err)
+ return err == ENOSYS || err == ENOTTY || is_ENOTSUP (err)
|| err == EINVAL || err == EBADF
- || err == EXDEV || err == ETXTBSY;
+ || err == EXDEV || err == ETXTBSY
+ || err == EPERM || err == EACCES;
}
@@ -339,20 +351,18 @@ sparse_copy (int src_fd, int dest_fd, ch
{
copy_debug.offload = COPY_DEBUG_UNSUPPORTED;
- if (is_CLONENOTSUP (errno))
- break;
-
- /* copy_file_range might not be enabled in seccomp filters,
- so retry with a standard copy. EPERM can also occur
- for immutable files, but that would only be in the edge case
- where the file is made immutable after creating/truncating,
+ /* Consider operation unsupported only if no data copied.
+ For example, EPERM could occur if copy_file_range not enabled
+ in seccomp filters, so retry with a standard copy. EPERM can
+ also occur for immutable files, but that would only be in the
+ edge case where the file is made immutable after creating,
in which case the (more accurate) error is still shown. */
- if (errno == EPERM && *total_n_read == 0)
+ if (*total_n_read == 0 && is_CLONENOTSUP (errno))
break;
/* ENOENT was seen sometimes across CIFS shares, resulting in
no data being copied, but subsequent standard copies succeed. */
- if (errno == ENOENT && *total_n_read == 0)
+ if (*total_n_read == 0 && errno == ENOENT)
break;
if (errno == EINTR)
@@ -1172,17 +1182,15 @@ handle_clone_fail (int dst_dirfd, char c
char const* src_name, char const* dst_name,
int dest_desc, bool new_dst, enum Reflink_type reflink_mode)
{
- /* If the clone operation is creating the destination,
- then don't try and cater for all non transient file system errors,
- and instead only cater for specific transient errors. */
- bool transient_failure;
- if (dest_desc < 0) /* currently for fclonefileat(). */
- transient_failure = errno == EIO || errno == ENOMEM
- || errno == ENOSPC || errno == EDQUOT;
- else /* currently for FICLONE. */
- transient_failure = ! is_CLONENOTSUP (errno);
+ /* When the clone operation fails, report failure only with errno values
+ known to mean trouble when the clone is supported and called properly.
+ Do not report failure merely because !is_CLONENOTSUP (errno),
+ as systems may yield oddball errno values here with FICLONE.
+ Also is_CLONENOTSUP() is not appropriate for the range of errnos
+ possible from fclonefileat(), so it's more consistent to avoid. */
+ bool report_failure = is_terminal_error (errno);
- if (reflink_mode == REFLINK_ALWAYS || transient_failure)
+ if (reflink_mode == REFLINK_ALWAYS || report_failure)
error (0, errno, _("failed to clone %s from %s"),
quoteaf_n (0, dst_name), quoteaf_n (1, src_name));
@@ -1190,14 +1198,14 @@ handle_clone_fail (int dst_dirfd, char c
but cloned no data. */
if (new_dst /* currently not for fclonefileat(). */
&& reflink_mode == REFLINK_ALWAYS
- && ((! transient_failure) || lseek (dest_desc, 0, SEEK_END) == 0)
+ && ((! report_failure) || lseek (dest_desc, 0, SEEK_END) == 0)
&& unlinkat (dst_dirfd, dst_relname, 0) != 0 && errno != ENOENT)
error (0, errno, _("cannot remove %s"), quoteaf (dst_name));
- if (! transient_failure)
+ if (! report_failure)
copy_debug.reflink = COPY_DEBUG_UNSUPPORTED;
- if (reflink_mode == REFLINK_ALWAYS || transient_failure)
+ if (reflink_mode == REFLINK_ALWAYS || report_failure)
return false;
return true;

View File

@ -1,20 +0,0 @@
From 9c5e542fd190a14431092e3b6cb45d18fe95f26f Mon Sep 17 00:00:00 2001
From: Paul Eggert <eggert@cs.ucla.edu>
Date: Tue, 28 Mar 2023 01:52:43 -0700
Subject: [PATCH] date: diagnose -f read errors
* src/date.c (batch_convert): Diagnose read errors, fixing Bug#62497.
---
--- a/src/date.c
+++ b/src/date.c
@@ -368,7 +368,9 @@ batch_convert (char const *input_filenam
ssize_t line_length = getline (&line, &buflen, in_stream);
if (line_length < 0)
{
- /* FIXME: detect/handle error here. */
+ if (ferror (in_stream))
+ die (EXIT_FAILURE, errno, _("%s: read error"),
+ quotef (input_filename));
break;
}

View File

@ -7,11 +7,11 @@
include $(TOPDIR)/rules.mk
PKG_NAME:=patchelf
PKG_VERSION:=0.17.2
PKG_VERSION:=0.18.0
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.bz2
PKG_SOURCE_URL:=https://github.com/NixOS/patchelf/releases/download/$(PKG_VERSION)
PKG_HASH:=bae2ea376072e422c196218dd9bdef0548ccc08da4de9f36b4672df84ea2d8e2
PKG_HASH:=1952b2a782ba576279c211ee942e341748fdb44997f704dd53def46cd055470b
HOST_BUILD_PARALLEL:=1
HOST_FIXUP:=autoreconf