mirror of
https://github.com/kernelkit/infix.git
synced 2026-08-06 15:43:02 +02:00
kernel: Bump to 6.5.11 + kkit-linux-6.5.y
6.5.11: Pull latest fixes from stable tree kkit-linux-6.5.y: LED support for 88X3310 PHY and 88E6393X switch.
This commit is contained in:
committed by
Joachim Wiberg
parent
55afbb2a94
commit
febb998702
@@ -22,7 +22,7 @@ BR2_ROOTFS_POST_BUILD_SCRIPT="${BR2_EXTERNAL_INFIX_PATH}/board/common/post-build
|
||||
BR2_ROOTFS_POST_IMAGE_SCRIPT="${BR2_EXTERNAL_INFIX_PATH}/board/common/post-image.sh"
|
||||
BR2_LINUX_KERNEL=y
|
||||
BR2_LINUX_KERNEL_CUSTOM_VERSION=y
|
||||
BR2_LINUX_KERNEL_CUSTOM_VERSION_VALUE="6.5.6"
|
||||
BR2_LINUX_KERNEL_CUSTOM_VERSION_VALUE="6.5.11"
|
||||
BR2_LINUX_KERNEL_USE_CUSTOM_CONFIG=y
|
||||
BR2_LINUX_KERNEL_CUSTOM_CONFIG_FILE="${BR2_EXTERNAL_INFIX_PATH}/board/aarch64/linux_defconfig"
|
||||
BR2_LINUX_KERNEL_DTS_SUPPORT=y
|
||||
|
||||
@@ -24,7 +24,7 @@ BR2_ROOTFS_POST_BUILD_SCRIPT="${BR2_EXTERNAL_INFIX_PATH}/board/common/post-build
|
||||
BR2_ROOTFS_POST_IMAGE_SCRIPT="${BR2_EXTERNAL_INFIX_PATH}/board/common/post-image.sh"
|
||||
BR2_LINUX_KERNEL=y
|
||||
BR2_LINUX_KERNEL_CUSTOM_VERSION=y
|
||||
BR2_LINUX_KERNEL_CUSTOM_VERSION_VALUE="6.5.6"
|
||||
BR2_LINUX_KERNEL_CUSTOM_VERSION_VALUE="6.5.11"
|
||||
BR2_LINUX_KERNEL_USE_CUSTOM_CONFIG=y
|
||||
BR2_LINUX_KERNEL_CUSTOM_CONFIG_FILE="${BR2_EXTERNAL_INFIX_PATH}/board/aarch64/linux_defconfig"
|
||||
BR2_LINUX_KERNEL_DTS_SUPPORT=y
|
||||
|
||||
@@ -21,7 +21,7 @@ BR2_ROOTFS_POST_BUILD_SCRIPT="board/qemu/x86_64/post-build.sh ${BR2_EXTERNAL_INF
|
||||
BR2_ROOTFS_POST_IMAGE_SCRIPT="${BR2_EXTERNAL_INFIX_PATH}/board/common/post-image.sh"
|
||||
BR2_LINUX_KERNEL=y
|
||||
BR2_LINUX_KERNEL_CUSTOM_VERSION=y
|
||||
BR2_LINUX_KERNEL_CUSTOM_VERSION_VALUE="6.5.6"
|
||||
BR2_LINUX_KERNEL_CUSTOM_VERSION_VALUE="6.5.11"
|
||||
BR2_LINUX_KERNEL_USE_CUSTOM_CONFIG=y
|
||||
BR2_LINUX_KERNEL_CUSTOM_CONFIG_FILE="${BR2_EXTERNAL_INFIX_PATH}/board/x86_64/linux_defconfig"
|
||||
BR2_LINUX_KERNEL_INSTALL_TARGET=y
|
||||
|
||||
@@ -23,7 +23,7 @@ BR2_ROOTFS_POST_BUILD_SCRIPT="board/qemu/x86_64/post-build.sh ${BR2_EXTERNAL_INF
|
||||
BR2_ROOTFS_POST_IMAGE_SCRIPT="${BR2_EXTERNAL_INFIX_PATH}/board/common/post-image.sh"
|
||||
BR2_LINUX_KERNEL=y
|
||||
BR2_LINUX_KERNEL_CUSTOM_VERSION=y
|
||||
BR2_LINUX_KERNEL_CUSTOM_VERSION_VALUE="6.5.6"
|
||||
BR2_LINUX_KERNEL_CUSTOM_VERSION_VALUE="6.5.11"
|
||||
BR2_LINUX_KERNEL_USE_CUSTOM_CONFIG=y
|
||||
BR2_LINUX_KERNEL_CUSTOM_CONFIG_FILE="${BR2_EXTERNAL_INFIX_PATH}/board/x86_64/linux_defconfig"
|
||||
BR2_LINUX_KERNEL_INSTALL_TARGET=y
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
From 99e3fc4a7c6d31f5d0fdc7bb5c409c776c19012c Mon Sep 17 00:00:00 2001
|
||||
From e1011848d2c9476e20e6a4053b8ab46ce2a1506f Mon Sep 17 00:00:00 2001
|
||||
From: Tobias Waldekranz <tobias@waldekranz.com>
|
||||
Date: Thu, 5 Oct 2023 16:09:25 +0200
|
||||
Subject: [PATCH 1/9] eth: fwnode: Fall back to NVMEM provided MAC address from
|
||||
OF
|
||||
Subject: [PATCH 01/15] eth: fwnode: Fall back to NVMEM provided MAC address
|
||||
from OF
|
||||
|
||||
In the cases where the fwnode is an OF node, make use of any NVMEM
|
||||
source of the interface's MAC address that might have been specified
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
From 5ddc784a4c8803aff2c3fa3c6595e9d32933d4aa Mon Sep 17 00:00:00 2001
|
||||
From 1d6f30fce9f4516730439f72ee2134301d37654d Mon Sep 17 00:00:00 2001
|
||||
From: Tobias Waldekranz <tobias@waldekranz.com>
|
||||
Date: Tue, 5 Sep 2023 13:08:29 +0200
|
||||
Subject: [PATCH 2/9] net: dsa: mv88e6xxx: Create API to read a single stat
|
||||
Subject: [PATCH 02/15] net: dsa: mv88e6xxx: Create API to read a single stat
|
||||
counter
|
||||
|
||||
This change contains no functional change. We simply push the hardware
|
||||
@@ -18,7 +18,7 @@ Signed-off-by: Tobias Waldekranz <tobias@waldekranz.com>
|
||||
2 files changed, 105 insertions(+), 82 deletions(-)
|
||||
|
||||
diff --git a/drivers/net/dsa/mv88e6xxx/chip.c b/drivers/net/dsa/mv88e6xxx/chip.c
|
||||
index 7af2f08a62f1..1e944cf08233 100644
|
||||
index 0d4b236d1e34..139f4d55a284 100644
|
||||
--- a/drivers/net/dsa/mv88e6xxx/chip.c
|
||||
+++ b/drivers/net/dsa/mv88e6xxx/chip.c
|
||||
@@ -1082,7 +1082,7 @@ static struct mv88e6xxx_hw_stat mv88e6xxx_hw_stats[] = {
|
||||
@@ -163,7 +163,7 @@ index 7af2f08a62f1..1e944cf08233 100644
|
||||
|
||||
mv88e6xxx_reg_lock(chip);
|
||||
if (chip->info->ops->serdes_get_stats) {
|
||||
@@ -4196,7 +4218,7 @@ static const struct mv88e6xxx_ops mv88e6085_ops = {
|
||||
@@ -4198,7 +4220,7 @@ static const struct mv88e6xxx_ops mv88e6085_ops = {
|
||||
.stats_set_histogram = mv88e6095_g1_stats_set_histogram,
|
||||
.stats_get_sset_count = mv88e6095_stats_get_sset_count,
|
||||
.stats_get_strings = mv88e6095_stats_get_strings,
|
||||
@@ -172,7 +172,7 @@ index 7af2f08a62f1..1e944cf08233 100644
|
||||
.set_cpu_port = mv88e6095_g1_set_cpu_port,
|
||||
.set_egress_port = mv88e6095_g1_set_egress_port,
|
||||
.watchdog_ops = &mv88e6097_watchdog_ops,
|
||||
@@ -4234,7 +4256,7 @@ static const struct mv88e6xxx_ops mv88e6095_ops = {
|
||||
@@ -4236,7 +4258,7 @@ static const struct mv88e6xxx_ops mv88e6095_ops = {
|
||||
.stats_set_histogram = mv88e6095_g1_stats_set_histogram,
|
||||
.stats_get_sset_count = mv88e6095_stats_get_sset_count,
|
||||
.stats_get_strings = mv88e6095_stats_get_strings,
|
||||
@@ -181,7 +181,7 @@ index 7af2f08a62f1..1e944cf08233 100644
|
||||
.mgmt_rsvd2cpu = mv88e6185_g2_mgmt_rsvd2cpu,
|
||||
.serdes_power = mv88e6185_serdes_power,
|
||||
.serdes_get_lane = mv88e6185_serdes_get_lane,
|
||||
@@ -4277,7 +4299,7 @@ static const struct mv88e6xxx_ops mv88e6097_ops = {
|
||||
@@ -4279,7 +4301,7 @@ static const struct mv88e6xxx_ops mv88e6097_ops = {
|
||||
.stats_set_histogram = mv88e6095_g1_stats_set_histogram,
|
||||
.stats_get_sset_count = mv88e6095_stats_get_sset_count,
|
||||
.stats_get_strings = mv88e6095_stats_get_strings,
|
||||
@@ -190,7 +190,7 @@ index 7af2f08a62f1..1e944cf08233 100644
|
||||
.set_cpu_port = mv88e6095_g1_set_cpu_port,
|
||||
.set_egress_port = mv88e6095_g1_set_egress_port,
|
||||
.watchdog_ops = &mv88e6097_watchdog_ops,
|
||||
@@ -4323,7 +4345,7 @@ static const struct mv88e6xxx_ops mv88e6123_ops = {
|
||||
@@ -4325,7 +4347,7 @@ static const struct mv88e6xxx_ops mv88e6123_ops = {
|
||||
.stats_set_histogram = mv88e6095_g1_stats_set_histogram,
|
||||
.stats_get_sset_count = mv88e6095_stats_get_sset_count,
|
||||
.stats_get_strings = mv88e6095_stats_get_strings,
|
||||
@@ -199,7 +199,7 @@ index 7af2f08a62f1..1e944cf08233 100644
|
||||
.set_cpu_port = mv88e6095_g1_set_cpu_port,
|
||||
.set_egress_port = mv88e6095_g1_set_egress_port,
|
||||
.watchdog_ops = &mv88e6097_watchdog_ops,
|
||||
@@ -4366,7 +4388,7 @@ static const struct mv88e6xxx_ops mv88e6131_ops = {
|
||||
@@ -4368,7 +4390,7 @@ static const struct mv88e6xxx_ops mv88e6131_ops = {
|
||||
.stats_set_histogram = mv88e6095_g1_stats_set_histogram,
|
||||
.stats_get_sset_count = mv88e6095_stats_get_sset_count,
|
||||
.stats_get_strings = mv88e6095_stats_get_strings,
|
||||
@@ -208,7 +208,7 @@ index 7af2f08a62f1..1e944cf08233 100644
|
||||
.set_cpu_port = mv88e6095_g1_set_cpu_port,
|
||||
.set_egress_port = mv88e6095_g1_set_egress_port,
|
||||
.watchdog_ops = &mv88e6097_watchdog_ops,
|
||||
@@ -4415,7 +4437,7 @@ static const struct mv88e6xxx_ops mv88e6141_ops = {
|
||||
@@ -4417,7 +4439,7 @@ static const struct mv88e6xxx_ops mv88e6141_ops = {
|
||||
.stats_set_histogram = mv88e6390_g1_stats_set_histogram,
|
||||
.stats_get_sset_count = mv88e6320_stats_get_sset_count,
|
||||
.stats_get_strings = mv88e6320_stats_get_strings,
|
||||
@@ -217,7 +217,7 @@ index 7af2f08a62f1..1e944cf08233 100644
|
||||
.set_cpu_port = mv88e6390_g1_set_cpu_port,
|
||||
.set_egress_port = mv88e6390_g1_set_egress_port,
|
||||
.watchdog_ops = &mv88e6390_watchdog_ops,
|
||||
@@ -4477,7 +4499,7 @@ static const struct mv88e6xxx_ops mv88e6161_ops = {
|
||||
@@ -4479,7 +4501,7 @@ static const struct mv88e6xxx_ops mv88e6161_ops = {
|
||||
.stats_set_histogram = mv88e6095_g1_stats_set_histogram,
|
||||
.stats_get_sset_count = mv88e6095_stats_get_sset_count,
|
||||
.stats_get_strings = mv88e6095_stats_get_strings,
|
||||
@@ -226,7 +226,7 @@ index 7af2f08a62f1..1e944cf08233 100644
|
||||
.set_cpu_port = mv88e6095_g1_set_cpu_port,
|
||||
.set_egress_port = mv88e6095_g1_set_egress_port,
|
||||
.watchdog_ops = &mv88e6097_watchdog_ops,
|
||||
@@ -4515,7 +4537,7 @@ static const struct mv88e6xxx_ops mv88e6165_ops = {
|
||||
@@ -4517,7 +4539,7 @@ static const struct mv88e6xxx_ops mv88e6165_ops = {
|
||||
.stats_set_histogram = mv88e6095_g1_stats_set_histogram,
|
||||
.stats_get_sset_count = mv88e6095_stats_get_sset_count,
|
||||
.stats_get_strings = mv88e6095_stats_get_strings,
|
||||
@@ -235,7 +235,7 @@ index 7af2f08a62f1..1e944cf08233 100644
|
||||
.set_cpu_port = mv88e6095_g1_set_cpu_port,
|
||||
.set_egress_port = mv88e6095_g1_set_egress_port,
|
||||
.watchdog_ops = &mv88e6097_watchdog_ops,
|
||||
@@ -4563,7 +4585,7 @@ static const struct mv88e6xxx_ops mv88e6171_ops = {
|
||||
@@ -4565,7 +4587,7 @@ static const struct mv88e6xxx_ops mv88e6171_ops = {
|
||||
.stats_set_histogram = mv88e6095_g1_stats_set_histogram,
|
||||
.stats_get_sset_count = mv88e6095_stats_get_sset_count,
|
||||
.stats_get_strings = mv88e6095_stats_get_strings,
|
||||
@@ -244,7 +244,7 @@ index 7af2f08a62f1..1e944cf08233 100644
|
||||
.set_cpu_port = mv88e6095_g1_set_cpu_port,
|
||||
.set_egress_port = mv88e6095_g1_set_egress_port,
|
||||
.watchdog_ops = &mv88e6097_watchdog_ops,
|
||||
@@ -4612,7 +4634,7 @@ static const struct mv88e6xxx_ops mv88e6172_ops = {
|
||||
@@ -4614,7 +4636,7 @@ static const struct mv88e6xxx_ops mv88e6172_ops = {
|
||||
.stats_set_histogram = mv88e6095_g1_stats_set_histogram,
|
||||
.stats_get_sset_count = mv88e6095_stats_get_sset_count,
|
||||
.stats_get_strings = mv88e6095_stats_get_strings,
|
||||
@@ -253,7 +253,7 @@ index 7af2f08a62f1..1e944cf08233 100644
|
||||
.set_cpu_port = mv88e6095_g1_set_cpu_port,
|
||||
.set_egress_port = mv88e6095_g1_set_egress_port,
|
||||
.watchdog_ops = &mv88e6097_watchdog_ops,
|
||||
@@ -4668,7 +4690,7 @@ static const struct mv88e6xxx_ops mv88e6175_ops = {
|
||||
@@ -4670,7 +4692,7 @@ static const struct mv88e6xxx_ops mv88e6175_ops = {
|
||||
.stats_set_histogram = mv88e6095_g1_stats_set_histogram,
|
||||
.stats_get_sset_count = mv88e6095_stats_get_sset_count,
|
||||
.stats_get_strings = mv88e6095_stats_get_strings,
|
||||
@@ -262,7 +262,7 @@ index 7af2f08a62f1..1e944cf08233 100644
|
||||
.set_cpu_port = mv88e6095_g1_set_cpu_port,
|
||||
.set_egress_port = mv88e6095_g1_set_egress_port,
|
||||
.watchdog_ops = &mv88e6097_watchdog_ops,
|
||||
@@ -4717,7 +4739,7 @@ static const struct mv88e6xxx_ops mv88e6176_ops = {
|
||||
@@ -4719,7 +4741,7 @@ static const struct mv88e6xxx_ops mv88e6176_ops = {
|
||||
.stats_set_histogram = mv88e6095_g1_stats_set_histogram,
|
||||
.stats_get_sset_count = mv88e6095_stats_get_sset_count,
|
||||
.stats_get_strings = mv88e6095_stats_get_strings,
|
||||
@@ -271,7 +271,7 @@ index 7af2f08a62f1..1e944cf08233 100644
|
||||
.set_cpu_port = mv88e6095_g1_set_cpu_port,
|
||||
.set_egress_port = mv88e6095_g1_set_egress_port,
|
||||
.watchdog_ops = &mv88e6097_watchdog_ops,
|
||||
@@ -4769,7 +4791,7 @@ static const struct mv88e6xxx_ops mv88e6185_ops = {
|
||||
@@ -4771,7 +4793,7 @@ static const struct mv88e6xxx_ops mv88e6185_ops = {
|
||||
.stats_set_histogram = mv88e6095_g1_stats_set_histogram,
|
||||
.stats_get_sset_count = mv88e6095_stats_get_sset_count,
|
||||
.stats_get_strings = mv88e6095_stats_get_strings,
|
||||
@@ -280,7 +280,7 @@ index 7af2f08a62f1..1e944cf08233 100644
|
||||
.set_cpu_port = mv88e6095_g1_set_cpu_port,
|
||||
.set_egress_port = mv88e6095_g1_set_egress_port,
|
||||
.watchdog_ops = &mv88e6097_watchdog_ops,
|
||||
@@ -4820,7 +4842,7 @@ static const struct mv88e6xxx_ops mv88e6190_ops = {
|
||||
@@ -4822,7 +4844,7 @@ static const struct mv88e6xxx_ops mv88e6190_ops = {
|
||||
.stats_set_histogram = mv88e6390_g1_stats_set_histogram,
|
||||
.stats_get_sset_count = mv88e6320_stats_get_sset_count,
|
||||
.stats_get_strings = mv88e6320_stats_get_strings,
|
||||
@@ -289,7 +289,7 @@ index 7af2f08a62f1..1e944cf08233 100644
|
||||
.set_cpu_port = mv88e6390_g1_set_cpu_port,
|
||||
.set_egress_port = mv88e6390_g1_set_egress_port,
|
||||
.watchdog_ops = &mv88e6390_watchdog_ops,
|
||||
@@ -4885,7 +4907,7 @@ static const struct mv88e6xxx_ops mv88e6190x_ops = {
|
||||
@@ -4887,7 +4909,7 @@ static const struct mv88e6xxx_ops mv88e6190x_ops = {
|
||||
.stats_set_histogram = mv88e6390_g1_stats_set_histogram,
|
||||
.stats_get_sset_count = mv88e6320_stats_get_sset_count,
|
||||
.stats_get_strings = mv88e6320_stats_get_strings,
|
||||
@@ -298,7 +298,7 @@ index 7af2f08a62f1..1e944cf08233 100644
|
||||
.set_cpu_port = mv88e6390_g1_set_cpu_port,
|
||||
.set_egress_port = mv88e6390_g1_set_egress_port,
|
||||
.watchdog_ops = &mv88e6390_watchdog_ops,
|
||||
@@ -4948,7 +4970,7 @@ static const struct mv88e6xxx_ops mv88e6191_ops = {
|
||||
@@ -4950,7 +4972,7 @@ static const struct mv88e6xxx_ops mv88e6191_ops = {
|
||||
.stats_set_histogram = mv88e6390_g1_stats_set_histogram,
|
||||
.stats_get_sset_count = mv88e6320_stats_get_sset_count,
|
||||
.stats_get_strings = mv88e6320_stats_get_strings,
|
||||
@@ -307,7 +307,7 @@ index 7af2f08a62f1..1e944cf08233 100644
|
||||
.set_cpu_port = mv88e6390_g1_set_cpu_port,
|
||||
.set_egress_port = mv88e6390_g1_set_egress_port,
|
||||
.watchdog_ops = &mv88e6390_watchdog_ops,
|
||||
@@ -5014,7 +5036,7 @@ static const struct mv88e6xxx_ops mv88e6240_ops = {
|
||||
@@ -5016,7 +5038,7 @@ static const struct mv88e6xxx_ops mv88e6240_ops = {
|
||||
.stats_set_histogram = mv88e6095_g1_stats_set_histogram,
|
||||
.stats_get_sset_count = mv88e6095_stats_get_sset_count,
|
||||
.stats_get_strings = mv88e6095_stats_get_strings,
|
||||
@@ -316,7 +316,7 @@ index 7af2f08a62f1..1e944cf08233 100644
|
||||
.set_cpu_port = mv88e6095_g1_set_cpu_port,
|
||||
.set_egress_port = mv88e6095_g1_set_egress_port,
|
||||
.watchdog_ops = &mv88e6097_watchdog_ops,
|
||||
@@ -5074,7 +5096,7 @@ static const struct mv88e6xxx_ops mv88e6250_ops = {
|
||||
@@ -5076,7 +5098,7 @@ static const struct mv88e6xxx_ops mv88e6250_ops = {
|
||||
.stats_set_histogram = mv88e6095_g1_stats_set_histogram,
|
||||
.stats_get_sset_count = mv88e6250_stats_get_sset_count,
|
||||
.stats_get_strings = mv88e6250_stats_get_strings,
|
||||
@@ -325,7 +325,7 @@ index 7af2f08a62f1..1e944cf08233 100644
|
||||
.set_cpu_port = mv88e6095_g1_set_cpu_port,
|
||||
.set_egress_port = mv88e6095_g1_set_egress_port,
|
||||
.watchdog_ops = &mv88e6250_watchdog_ops,
|
||||
@@ -5121,7 +5143,7 @@ static const struct mv88e6xxx_ops mv88e6290_ops = {
|
||||
@@ -5123,7 +5145,7 @@ static const struct mv88e6xxx_ops mv88e6290_ops = {
|
||||
.stats_set_histogram = mv88e6390_g1_stats_set_histogram,
|
||||
.stats_get_sset_count = mv88e6320_stats_get_sset_count,
|
||||
.stats_get_strings = mv88e6320_stats_get_strings,
|
||||
@@ -334,7 +334,7 @@ index 7af2f08a62f1..1e944cf08233 100644
|
||||
.set_cpu_port = mv88e6390_g1_set_cpu_port,
|
||||
.set_egress_port = mv88e6390_g1_set_egress_port,
|
||||
.watchdog_ops = &mv88e6390_watchdog_ops,
|
||||
@@ -5187,7 +5209,7 @@ static const struct mv88e6xxx_ops mv88e6320_ops = {
|
||||
@@ -5189,7 +5211,7 @@ static const struct mv88e6xxx_ops mv88e6320_ops = {
|
||||
.stats_set_histogram = mv88e6095_g1_stats_set_histogram,
|
||||
.stats_get_sset_count = mv88e6320_stats_get_sset_count,
|
||||
.stats_get_strings = mv88e6320_stats_get_strings,
|
||||
@@ -343,7 +343,7 @@ index 7af2f08a62f1..1e944cf08233 100644
|
||||
.set_cpu_port = mv88e6095_g1_set_cpu_port,
|
||||
.set_egress_port = mv88e6095_g1_set_egress_port,
|
||||
.watchdog_ops = &mv88e6390_watchdog_ops,
|
||||
@@ -5234,7 +5256,7 @@ static const struct mv88e6xxx_ops mv88e6321_ops = {
|
||||
@@ -5236,7 +5258,7 @@ static const struct mv88e6xxx_ops mv88e6321_ops = {
|
||||
.stats_set_histogram = mv88e6095_g1_stats_set_histogram,
|
||||
.stats_get_sset_count = mv88e6320_stats_get_sset_count,
|
||||
.stats_get_strings = mv88e6320_stats_get_strings,
|
||||
@@ -352,7 +352,7 @@ index 7af2f08a62f1..1e944cf08233 100644
|
||||
.set_cpu_port = mv88e6095_g1_set_cpu_port,
|
||||
.set_egress_port = mv88e6095_g1_set_egress_port,
|
||||
.watchdog_ops = &mv88e6390_watchdog_ops,
|
||||
@@ -5283,7 +5305,7 @@ static const struct mv88e6xxx_ops mv88e6341_ops = {
|
||||
@@ -5285,7 +5307,7 @@ static const struct mv88e6xxx_ops mv88e6341_ops = {
|
||||
.stats_set_histogram = mv88e6390_g1_stats_set_histogram,
|
||||
.stats_get_sset_count = mv88e6320_stats_get_sset_count,
|
||||
.stats_get_strings = mv88e6320_stats_get_strings,
|
||||
@@ -361,7 +361,7 @@ index 7af2f08a62f1..1e944cf08233 100644
|
||||
.set_cpu_port = mv88e6390_g1_set_cpu_port,
|
||||
.set_egress_port = mv88e6390_g1_set_egress_port,
|
||||
.watchdog_ops = &mv88e6390_watchdog_ops,
|
||||
@@ -5348,7 +5370,7 @@ static const struct mv88e6xxx_ops mv88e6350_ops = {
|
||||
@@ -5350,7 +5372,7 @@ static const struct mv88e6xxx_ops mv88e6350_ops = {
|
||||
.stats_set_histogram = mv88e6095_g1_stats_set_histogram,
|
||||
.stats_get_sset_count = mv88e6095_stats_get_sset_count,
|
||||
.stats_get_strings = mv88e6095_stats_get_strings,
|
||||
@@ -370,7 +370,7 @@ index 7af2f08a62f1..1e944cf08233 100644
|
||||
.set_cpu_port = mv88e6095_g1_set_cpu_port,
|
||||
.set_egress_port = mv88e6095_g1_set_egress_port,
|
||||
.watchdog_ops = &mv88e6097_watchdog_ops,
|
||||
@@ -5394,7 +5416,7 @@ static const struct mv88e6xxx_ops mv88e6351_ops = {
|
||||
@@ -5396,7 +5418,7 @@ static const struct mv88e6xxx_ops mv88e6351_ops = {
|
||||
.stats_set_histogram = mv88e6095_g1_stats_set_histogram,
|
||||
.stats_get_sset_count = mv88e6095_stats_get_sset_count,
|
||||
.stats_get_strings = mv88e6095_stats_get_strings,
|
||||
@@ -379,7 +379,7 @@ index 7af2f08a62f1..1e944cf08233 100644
|
||||
.set_cpu_port = mv88e6095_g1_set_cpu_port,
|
||||
.set_egress_port = mv88e6095_g1_set_egress_port,
|
||||
.watchdog_ops = &mv88e6097_watchdog_ops,
|
||||
@@ -5445,7 +5467,7 @@ static const struct mv88e6xxx_ops mv88e6352_ops = {
|
||||
@@ -5447,7 +5469,7 @@ static const struct mv88e6xxx_ops mv88e6352_ops = {
|
||||
.stats_set_histogram = mv88e6095_g1_stats_set_histogram,
|
||||
.stats_get_sset_count = mv88e6095_stats_get_sset_count,
|
||||
.stats_get_strings = mv88e6095_stats_get_strings,
|
||||
@@ -388,7 +388,7 @@ index 7af2f08a62f1..1e944cf08233 100644
|
||||
.set_cpu_port = mv88e6095_g1_set_cpu_port,
|
||||
.set_egress_port = mv88e6095_g1_set_egress_port,
|
||||
.watchdog_ops = &mv88e6097_watchdog_ops,
|
||||
@@ -5514,7 +5536,7 @@ static const struct mv88e6xxx_ops mv88e6390_ops = {
|
||||
@@ -5516,7 +5538,7 @@ static const struct mv88e6xxx_ops mv88e6390_ops = {
|
||||
.stats_set_histogram = mv88e6390_g1_stats_set_histogram,
|
||||
.stats_get_sset_count = mv88e6320_stats_get_sset_count,
|
||||
.stats_get_strings = mv88e6320_stats_get_strings,
|
||||
@@ -397,7 +397,7 @@ index 7af2f08a62f1..1e944cf08233 100644
|
||||
.set_cpu_port = mv88e6390_g1_set_cpu_port,
|
||||
.set_egress_port = mv88e6390_g1_set_egress_port,
|
||||
.watchdog_ops = &mv88e6390_watchdog_ops,
|
||||
@@ -5583,7 +5605,7 @@ static const struct mv88e6xxx_ops mv88e6390x_ops = {
|
||||
@@ -5585,7 +5607,7 @@ static const struct mv88e6xxx_ops mv88e6390x_ops = {
|
||||
.stats_set_histogram = mv88e6390_g1_stats_set_histogram,
|
||||
.stats_get_sset_count = mv88e6320_stats_get_sset_count,
|
||||
.stats_get_strings = mv88e6320_stats_get_strings,
|
||||
@@ -406,7 +406,7 @@ index 7af2f08a62f1..1e944cf08233 100644
|
||||
.set_cpu_port = mv88e6390_g1_set_cpu_port,
|
||||
.set_egress_port = mv88e6390_g1_set_egress_port,
|
||||
.watchdog_ops = &mv88e6390_watchdog_ops,
|
||||
@@ -5652,7 +5674,7 @@ static const struct mv88e6xxx_ops mv88e6393x_ops = {
|
||||
@@ -5654,7 +5676,7 @@ static const struct mv88e6xxx_ops mv88e6393x_ops = {
|
||||
.stats_set_histogram = mv88e6390_g1_stats_set_histogram,
|
||||
.stats_get_sset_count = mv88e6320_stats_get_sset_count,
|
||||
.stats_get_strings = mv88e6320_stats_get_strings,
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
From 63c14938bdaa1891386989aa46bee4571c1c0777 Mon Sep 17 00:00:00 2001
|
||||
From f960475a96d2852d06ee062c970e35074f87659c Mon Sep 17 00:00:00 2001
|
||||
From: Tobias Waldekranz <tobias@waldekranz.com>
|
||||
Date: Tue, 5 Sep 2023 21:10:15 +0200
|
||||
Subject: [PATCH 3/9] net: dsa: mv88e6xxx: Give each hw stat an ID
|
||||
Subject: [PATCH 03/15] net: dsa: mv88e6xxx: Give each hw stat an ID
|
||||
|
||||
With the upcoming standard counter group support, we are no longer
|
||||
reading out the whole set of counters, but rather mapping a subset to
|
||||
@@ -17,7 +17,7 @@ Signed-off-by: Tobias Waldekranz <tobias@waldekranz.com>
|
||||
1 file changed, 78 insertions(+), 63 deletions(-)
|
||||
|
||||
diff --git a/drivers/net/dsa/mv88e6xxx/chip.c b/drivers/net/dsa/mv88e6xxx/chip.c
|
||||
index 1e944cf08233..ea4fb0d3e628 100644
|
||||
index 139f4d55a284..4afe5c212a36 100644
|
||||
--- a/drivers/net/dsa/mv88e6xxx/chip.c
|
||||
+++ b/drivers/net/dsa/mv88e6xxx/chip.c
|
||||
@@ -1019,68 +1019,83 @@ static int mv88e6xxx_stats_snapshot(struct mv88e6xxx_chip *chip, int port)
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
From ffd5442fcbadcbd8733b9ac870d83d7561cca9fc Mon Sep 17 00:00:00 2001
|
||||
From 6a612f46152d8567a16b7b15fdcc3081cbdbb3fb Mon Sep 17 00:00:00 2001
|
||||
From: Tobias Waldekranz <tobias@waldekranz.com>
|
||||
Date: Tue, 5 Sep 2023 21:15:52 +0200
|
||||
Subject: [PATCH 4/9] net: dsa: mv88e6xxx: Add "eth-mac" counter group support
|
||||
Subject: [PATCH 04/15] net: dsa: mv88e6xxx: Add "eth-mac" counter group
|
||||
support
|
||||
|
||||
After this change, mv88e6xxx ports can report the applicable subset of
|
||||
their counters using ethtool's standardized "eth-mac" counter group.
|
||||
@@ -12,7 +13,7 @@ Signed-off-by: Tobias Waldekranz <tobias@waldekranz.com>
|
||||
1 file changed, 52 insertions(+)
|
||||
|
||||
diff --git a/drivers/net/dsa/mv88e6xxx/chip.c b/drivers/net/dsa/mv88e6xxx/chip.c
|
||||
index ea4fb0d3e628..ec3a4717bc44 100644
|
||||
index 4afe5c212a36..2cfc072b41b1 100644
|
||||
--- a/drivers/net/dsa/mv88e6xxx/chip.c
|
||||
+++ b/drivers/net/dsa/mv88e6xxx/chip.c
|
||||
@@ -1403,6 +1403,57 @@ static void mv88e6xxx_get_ethtool_stats(struct dsa_switch *ds, int port,
|
||||
@@ -73,7 +74,7 @@ index ea4fb0d3e628..ec3a4717bc44 100644
|
||||
static int mv88e6xxx_get_regs_len(struct dsa_switch *ds, int port)
|
||||
{
|
||||
struct mv88e6xxx_chip *chip = ds->priv;
|
||||
@@ -7160,6 +7211,7 @@ static const struct dsa_switch_ops mv88e6xxx_switch_ops = {
|
||||
@@ -7162,6 +7213,7 @@ static const struct dsa_switch_ops mv88e6xxx_switch_ops = {
|
||||
.phylink_mac_link_up = mv88e6xxx_mac_link_up,
|
||||
.get_strings = mv88e6xxx_get_strings,
|
||||
.get_ethtool_stats = mv88e6xxx_get_ethtool_stats,
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
From 2cfafa598282efc980baf00b312a61032b9f5aa9 Mon Sep 17 00:00:00 2001
|
||||
From a85c55f3232d402780a22d42859bdc81150469b4 Mon Sep 17 00:00:00 2001
|
||||
From: Tobias Waldekranz <tobias@waldekranz.com>
|
||||
Date: Wed, 6 Sep 2023 10:55:53 +0200
|
||||
Subject: [PATCH 5/9] net: dsa: mv88e6xxx: Add "rmon" counter group support
|
||||
Subject: [PATCH 05/15] net: dsa: mv88e6xxx: Add "rmon" counter group support
|
||||
|
||||
After this change, mv88e6xxx ports can report the applicable subset of
|
||||
their counters using ethtool's standardized "rmon" counter group.
|
||||
@@ -12,7 +12,7 @@ Signed-off-by: Tobias Waldekranz <tobias@waldekranz.com>
|
||||
1 file changed, 56 insertions(+)
|
||||
|
||||
diff --git a/drivers/net/dsa/mv88e6xxx/chip.c b/drivers/net/dsa/mv88e6xxx/chip.c
|
||||
index ec3a4717bc44..eb5990cfc7d4 100644
|
||||
index 2cfc072b41b1..90dcd6c3be31 100644
|
||||
--- a/drivers/net/dsa/mv88e6xxx/chip.c
|
||||
+++ b/drivers/net/dsa/mv88e6xxx/chip.c
|
||||
@@ -1454,6 +1454,61 @@ static void mv88e6xxx_get_eth_mac_stats(struct dsa_switch *ds, int port,
|
||||
@@ -77,7 +77,7 @@ index ec3a4717bc44..eb5990cfc7d4 100644
|
||||
static int mv88e6xxx_get_regs_len(struct dsa_switch *ds, int port)
|
||||
{
|
||||
struct mv88e6xxx_chip *chip = ds->priv;
|
||||
@@ -7212,6 +7267,7 @@ static const struct dsa_switch_ops mv88e6xxx_switch_ops = {
|
||||
@@ -7214,6 +7269,7 @@ static const struct dsa_switch_ops mv88e6xxx_switch_ops = {
|
||||
.get_strings = mv88e6xxx_get_strings,
|
||||
.get_ethtool_stats = mv88e6xxx_get_ethtool_stats,
|
||||
.get_eth_mac_stats = mv88e6xxx_get_eth_mac_stats,
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
From 7abdce276172fe74e24fd30d204a75e388bbab6c Mon Sep 17 00:00:00 2001
|
||||
From 6f684b1b9eb8a307b77aa4baa8531e2c423112af Mon Sep 17 00:00:00 2001
|
||||
From: Tobias Waldekranz <tobias@waldekranz.com>
|
||||
Date: Thu, 21 Sep 2023 11:10:26 +0200
|
||||
Subject: [PATCH 6/9] arm64: dts: marvell: cp11x: Provide clock names for MDIO
|
||||
controllers
|
||||
Subject: [PATCH 06/15] arm64: dts: marvell: cp11x: Provide clock names for
|
||||
MDIO controllers
|
||||
|
||||
This will let the driver figure out the rate of the core clk, such
|
||||
that custom MDC frequencies can be supported.
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
From 8dc464b6506fbc038ccdae0a88936989fdf32117 Mon Sep 17 00:00:00 2001
|
||||
From d5e03e7b44c8ac414927751097d8d65caffc33b4 Mon Sep 17 00:00:00 2001
|
||||
From: Tobias Waldekranz <tobias@waldekranz.com>
|
||||
Date: Tue, 19 Sep 2023 18:19:40 +0200
|
||||
Subject: [PATCH 7/9] net: mvmdio: Avoid excessive sleeps in polled mode
|
||||
Subject: [PATCH 07/15] net: mvmdio: Avoid excessive sleeps in polled mode
|
||||
|
||||
Before this change, when operating in polled mode, i.e. no IRQ is
|
||||
available, every individual C45 access would be hit with a 150us sleep
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
From 1956176490d4eec3a889a38626326b375782a55a Mon Sep 17 00:00:00 2001
|
||||
From d389cc01295ebd7be228c8240f0061134b27f215 Mon Sep 17 00:00:00 2001
|
||||
From: Tobias Waldekranz <tobias@waldekranz.com>
|
||||
Date: Thu, 21 Sep 2023 11:12:55 +0200
|
||||
Subject: [PATCH 8/9] net: mvmdio: Support setting the MDC frequency on XSMI
|
||||
Subject: [PATCH 08/15] net: mvmdio: Support setting the MDC frequency on XSMI
|
||||
controllers
|
||||
|
||||
Support the standard "clock-frequency" attribute to set the generated
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
From 0de9c5dfc6395eb2e3066488638ac86de58b8068 Mon Sep 17 00:00:00 2001
|
||||
From 46bbea6b9d692ac7460e4e278cedee9f88b6da0b Mon Sep 17 00:00:00 2001
|
||||
From: Tobias Waldekranz <tobias@waldekranz.com>
|
||||
Date: Tue, 19 Sep 2023 18:38:10 +0200
|
||||
Subject: [PATCH 9/9] net: phy: marvell10g: Support firmware loading on 88X3310
|
||||
Subject: [PATCH 09/15] net: phy: marvell10g: Support firmware loading on
|
||||
88X3310
|
||||
|
||||
If a device is found waiting for firmware to be loaded into its RAM,
|
||||
ask userspace for the binary and load it over XMDIO.
|
||||
|
||||
@@ -0,0 +1,63 @@
|
||||
From 312d3efde0fbe7cec3bf7ba1908c213c9cf69337 Mon Sep 17 00:00:00 2001
|
||||
From: Andrew Lunn <andrew@lunn.ch>
|
||||
Date: Tue, 8 Aug 2023 23:04:33 +0200
|
||||
Subject: [PATCH 10/15] led: trig: netdev: Fix requesting offload device
|
||||
|
||||
When the netdev trigger is activates, it tries to determine what
|
||||
device the LED blinks for, and what the current blink mode is.
|
||||
|
||||
The documentation for hw_control_get() says:
|
||||
|
||||
* Return 0 on success, a negative error number on failing parsing the
|
||||
* initial mode. Error from this function is NOT FATAL as the device
|
||||
* may be in a not supported initial state by the attached LED trigger.
|
||||
*/
|
||||
|
||||
For the Marvell PHY and the Armada 370-rd board, the initial LED blink
|
||||
mode is not supported by the trigger, so it returns an error. This
|
||||
resulted in not getting the device the LED is blinking for. As a
|
||||
result, the device is unknown and offloaded is never performed.
|
||||
|
||||
Change to condition to always get the device if offloading is
|
||||
supported, and reduce the scope of testing for an error from
|
||||
hw_control_get() to skip setting trigger internal state if there is an
|
||||
error.
|
||||
|
||||
Reviewed-by: Simon Horman <simon.horman@corigine.com>
|
||||
Signed-off-by: Andrew Lunn <andrew@lunn.ch>
|
||||
Tested-by: Daniel Golle <daniel@makrotopia.org>
|
||||
Link: https://lore.kernel.org/r/20230808210436.838995-2-andrew@lunn.ch
|
||||
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
|
||||
Signed-off-by: Tobias Waldekranz <tobias@waldekranz.com>
|
||||
---
|
||||
drivers/leds/trigger/ledtrig-netdev.c | 8 +++++---
|
||||
1 file changed, 5 insertions(+), 3 deletions(-)
|
||||
|
||||
diff --git a/drivers/leds/trigger/ledtrig-netdev.c b/drivers/leds/trigger/ledtrig-netdev.c
|
||||
index 03c58e50cc44..e9e4da217249 100644
|
||||
--- a/drivers/leds/trigger/ledtrig-netdev.c
|
||||
+++ b/drivers/leds/trigger/ledtrig-netdev.c
|
||||
@@ -564,15 +564,17 @@ static int netdev_trig_activate(struct led_classdev *led_cdev)
|
||||
/* Check if hw control is active by default on the LED.
|
||||
* Init already enabled mode in hw control.
|
||||
*/
|
||||
- if (supports_hw_control(led_cdev) &&
|
||||
- !led_cdev->hw_control_get(led_cdev, &mode)) {
|
||||
+ if (supports_hw_control(led_cdev)) {
|
||||
dev = led_cdev->hw_control_get_device(led_cdev);
|
||||
if (dev) {
|
||||
const char *name = dev_name(dev);
|
||||
|
||||
set_device_name(trigger_data, name, strlen(name));
|
||||
trigger_data->hw_control = true;
|
||||
- trigger_data->mode = mode;
|
||||
+
|
||||
+ rc = led_cdev->hw_control_get(led_cdev, &mode);
|
||||
+ if (!rc)
|
||||
+ trigger_data->mode = mode;
|
||||
}
|
||||
}
|
||||
|
||||
--
|
||||
2.34.1
|
||||
|
||||
@@ -0,0 +1,37 @@
|
||||
From 83322015e7960ba0f1f3698e36333cfb6aecb931 Mon Sep 17 00:00:00 2001
|
||||
From: Andrew Lunn <andrew@lunn.ch>
|
||||
Date: Tue, 8 Aug 2023 23:04:36 +0200
|
||||
Subject: [PATCH 11/15] leds: trig-netdev: Disable offload on deactivation of
|
||||
trigger
|
||||
|
||||
Ensure that the offloading of blinking is stopped when the trigger is
|
||||
deactivated. Calling led_set_brightness() is documented as stopping
|
||||
offload and setting the LED to a constant brightness.
|
||||
|
||||
Suggested-by: Daniel Golle <daniel@makrotopia.org>
|
||||
Signed-off-by: Andrew Lunn <andrew@lunn.ch>
|
||||
Reviewed-by: Simon Horman <simon.horman@corigine.com>
|
||||
Tested-by: Daniel Golle <daniel@makrotopia.org>
|
||||
Link: https://lore.kernel.org/r/20230808210436.838995-5-andrew@lunn.ch
|
||||
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
|
||||
Signed-off-by: Tobias Waldekranz <tobias@waldekranz.com>
|
||||
---
|
||||
drivers/leds/trigger/ledtrig-netdev.c | 2 ++
|
||||
1 file changed, 2 insertions(+)
|
||||
|
||||
diff --git a/drivers/leds/trigger/ledtrig-netdev.c b/drivers/leds/trigger/ledtrig-netdev.c
|
||||
index e9e4da217249..cc3261543a5e 100644
|
||||
--- a/drivers/leds/trigger/ledtrig-netdev.c
|
||||
+++ b/drivers/leds/trigger/ledtrig-netdev.c
|
||||
@@ -595,6 +595,8 @@ static void netdev_trig_deactivate(struct led_classdev *led_cdev)
|
||||
|
||||
cancel_delayed_work_sync(&trigger_data->work);
|
||||
|
||||
+ led_set_brightness(led_cdev, LED_OFF);
|
||||
+
|
||||
dev_put(trigger_data->net_dev);
|
||||
|
||||
kfree(trigger_data);
|
||||
--
|
||||
2.34.1
|
||||
|
||||
@@ -0,0 +1,157 @@
|
||||
From a4f09c743da21f09b0fcc6e5842d665490f9f70e Mon Sep 17 00:00:00 2001
|
||||
From: Andrew Lunn <andrew@lunn.ch>
|
||||
Date: Tue, 8 Aug 2023 23:04:34 +0200
|
||||
Subject: [PATCH 12/15] net: phy: phy_device: Call into the PHY driver to set
|
||||
LED offload
|
||||
|
||||
Linux LEDs can be requested to perform hardware accelerated blinking
|
||||
to indicate link, RX, TX etc. Pass the rules for blinking to the PHY
|
||||
driver, if it implements the ops needed to determine if a given
|
||||
pattern can be offloaded, to offload it, and what the current offload
|
||||
is. Additionally implement the op needed to get what device the LED is
|
||||
for.
|
||||
|
||||
Reviewed-by: Simon Horman <simon.horman@corigine.com>
|
||||
Signed-off-by: Andrew Lunn <andrew@lunn.ch>
|
||||
Tested-by: Daniel Golle <daniel@makrotopia.org>
|
||||
Link: https://lore.kernel.org/r/20230808210436.838995-3-andrew@lunn.ch
|
||||
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
|
||||
Signed-off-by: Tobias Waldekranz <tobias@waldekranz.com>
|
||||
---
|
||||
drivers/net/phy/phy_device.c | 68 ++++++++++++++++++++++++++++++++++++
|
||||
include/linux/phy.h | 33 +++++++++++++++++
|
||||
2 files changed, 101 insertions(+)
|
||||
|
||||
diff --git a/drivers/net/phy/phy_device.c b/drivers/net/phy/phy_device.c
|
||||
index c7cf61fe41cf..d096d9d63617 100644
|
||||
--- a/drivers/net/phy/phy_device.c
|
||||
+++ b/drivers/net/phy/phy_device.c
|
||||
@@ -3020,6 +3020,61 @@ static int phy_led_blink_set(struct led_classdev *led_cdev,
|
||||
return err;
|
||||
}
|
||||
|
||||
+static __maybe_unused struct device *
|
||||
+phy_led_hw_control_get_device(struct led_classdev *led_cdev)
|
||||
+{
|
||||
+ struct phy_led *phyled = to_phy_led(led_cdev);
|
||||
+ struct phy_device *phydev = phyled->phydev;
|
||||
+
|
||||
+ if (phydev->attached_dev)
|
||||
+ return &phydev->attached_dev->dev;
|
||||
+ return NULL;
|
||||
+}
|
||||
+
|
||||
+static int __maybe_unused
|
||||
+phy_led_hw_control_get(struct led_classdev *led_cdev,
|
||||
+ unsigned long *rules)
|
||||
+{
|
||||
+ struct phy_led *phyled = to_phy_led(led_cdev);
|
||||
+ struct phy_device *phydev = phyled->phydev;
|
||||
+ int err;
|
||||
+
|
||||
+ mutex_lock(&phydev->lock);
|
||||
+ err = phydev->drv->led_hw_control_get(phydev, phyled->index, rules);
|
||||
+ mutex_unlock(&phydev->lock);
|
||||
+
|
||||
+ return err;
|
||||
+}
|
||||
+
|
||||
+static int __maybe_unused
|
||||
+phy_led_hw_control_set(struct led_classdev *led_cdev,
|
||||
+ unsigned long rules)
|
||||
+{
|
||||
+ struct phy_led *phyled = to_phy_led(led_cdev);
|
||||
+ struct phy_device *phydev = phyled->phydev;
|
||||
+ int err;
|
||||
+
|
||||
+ mutex_lock(&phydev->lock);
|
||||
+ err = phydev->drv->led_hw_control_set(phydev, phyled->index, rules);
|
||||
+ mutex_unlock(&phydev->lock);
|
||||
+
|
||||
+ return err;
|
||||
+}
|
||||
+
|
||||
+static __maybe_unused int phy_led_hw_is_supported(struct led_classdev *led_cdev,
|
||||
+ unsigned long rules)
|
||||
+{
|
||||
+ struct phy_led *phyled = to_phy_led(led_cdev);
|
||||
+ struct phy_device *phydev = phyled->phydev;
|
||||
+ int err;
|
||||
+
|
||||
+ mutex_lock(&phydev->lock);
|
||||
+ err = phydev->drv->led_hw_is_supported(phydev, phyled->index, rules);
|
||||
+ mutex_unlock(&phydev->lock);
|
||||
+
|
||||
+ return err;
|
||||
+}
|
||||
+
|
||||
static void phy_leds_unregister(struct phy_device *phydev)
|
||||
{
|
||||
struct phy_led *phyled;
|
||||
@@ -3057,6 +3112,19 @@ static int of_phy_led(struct phy_device *phydev,
|
||||
cdev->brightness_set_blocking = phy_led_set_brightness;
|
||||
if (phydev->drv->led_blink_set)
|
||||
cdev->blink_set = phy_led_blink_set;
|
||||
+
|
||||
+#ifdef CONFIG_LEDS_TRIGGERS
|
||||
+ if (phydev->drv->led_hw_is_supported &&
|
||||
+ phydev->drv->led_hw_control_set &&
|
||||
+ phydev->drv->led_hw_control_get) {
|
||||
+ cdev->hw_control_is_supported = phy_led_hw_is_supported;
|
||||
+ cdev->hw_control_set = phy_led_hw_control_set;
|
||||
+ cdev->hw_control_get = phy_led_hw_control_get;
|
||||
+ cdev->hw_control_trigger = "netdev";
|
||||
+ }
|
||||
+
|
||||
+ cdev->hw_control_get_device = phy_led_hw_control_get_device;
|
||||
+#endif
|
||||
cdev->max_brightness = 1;
|
||||
init_data.devicename = dev_name(&phydev->mdio.dev);
|
||||
init_data.fwnode = of_fwnode_handle(led);
|
||||
diff --git a/include/linux/phy.h b/include/linux/phy.h
|
||||
index 11c1e91563d4..0f9e4598c596 100644
|
||||
--- a/include/linux/phy.h
|
||||
+++ b/include/linux/phy.h
|
||||
@@ -1104,6 +1104,39 @@ struct phy_driver {
|
||||
int (*led_blink_set)(struct phy_device *dev, u8 index,
|
||||
unsigned long *delay_on,
|
||||
unsigned long *delay_off);
|
||||
+ /**
|
||||
+ * @led_hw_is_supported: Can the HW support the given rules.
|
||||
+ * @dev: PHY device which has the LED
|
||||
+ * @index: Which LED of the PHY device
|
||||
+ * @rules The core is interested in these rules
|
||||
+ *
|
||||
+ * Return 0 if yes, -EOPNOTSUPP if not, or an error code.
|
||||
+ */
|
||||
+ int (*led_hw_is_supported)(struct phy_device *dev, u8 index,
|
||||
+ unsigned long rules);
|
||||
+ /**
|
||||
+ * @led_hw_control_set: Set the HW to control the LED
|
||||
+ * @dev: PHY device which has the LED
|
||||
+ * @index: Which LED of the PHY device
|
||||
+ * @rules The rules used to control the LED
|
||||
+ *
|
||||
+ * Returns 0, or a an error code.
|
||||
+ */
|
||||
+ int (*led_hw_control_set)(struct phy_device *dev, u8 index,
|
||||
+ unsigned long rules);
|
||||
+ /**
|
||||
+ * @led_hw_control_get: Get how the HW is controlling the LED
|
||||
+ * @dev: PHY device which has the LED
|
||||
+ * @index: Which LED of the PHY device
|
||||
+ * @rules Pointer to the rules used to control the LED
|
||||
+ *
|
||||
+ * Set *@rules to how the HW is currently blinking. Returns 0
|
||||
+ * on success, or a error code if the current blinking cannot
|
||||
+ * be represented in rules, or some other error happens.
|
||||
+ */
|
||||
+ int (*led_hw_control_get)(struct phy_device *dev, u8 index,
|
||||
+ unsigned long *rules);
|
||||
+
|
||||
};
|
||||
#define to_phy_driver(d) container_of(to_mdio_common_driver(d), \
|
||||
struct phy_driver, mdiodrv)
|
||||
--
|
||||
2.34.1
|
||||
|
||||
@@ -0,0 +1,535 @@
|
||||
From 5adf394404d4c8ac25fb1e36d7d3f23b699b3104 Mon Sep 17 00:00:00 2001
|
||||
From: Tobias Waldekranz <tobias@waldekranz.com>
|
||||
Date: Wed, 15 Nov 2023 20:58:42 +0100
|
||||
Subject: [PATCH 13/15] net: phy: marvell10g: Add LED support for 88X3310
|
||||
|
||||
Pickup the LEDs from the state in which the hardware reset or
|
||||
bootloader left them, but also support further configuration via
|
||||
device tree. This is primarily needed because the electrical polarity
|
||||
and drive behavior is software controlled and not possible to set via
|
||||
hardware strapping.
|
||||
|
||||
Trigger support:
|
||||
- "none"
|
||||
- "timer": Map 60-100 ms periods to the fast rate (81ms) and 1000-1600
|
||||
ms periods to the slow rate (1300ms). Defer everything else to
|
||||
software blinking
|
||||
- "netdev": Offload (per-medium) link or duplex information to the
|
||||
solid behavior; tx and/or rx activity to blink behavior.
|
||||
|
||||
Signed-off-by: Tobias Waldekranz <tobias@waldekranz.com>
|
||||
---
|
||||
drivers/net/phy/marvell10g.c | 455 +++++++++++++++++++++++++++++++++++
|
||||
1 file changed, 455 insertions(+)
|
||||
|
||||
diff --git a/drivers/net/phy/marvell10g.c b/drivers/net/phy/marvell10g.c
|
||||
index 155f439d9c1c..05ad7c769e24 100644
|
||||
--- a/drivers/net/phy/marvell10g.c
|
||||
+++ b/drivers/net/phy/marvell10g.c
|
||||
@@ -28,6 +28,7 @@
|
||||
#include <linux/firmware.h>
|
||||
#include <linux/hwmon.h>
|
||||
#include <linux/marvell_phy.h>
|
||||
+#include <linux/of.h>
|
||||
#include <linux/phy.h>
|
||||
#include <linux/sfp.h>
|
||||
#include <linux/netdevice.h>
|
||||
@@ -136,6 +137,14 @@ enum {
|
||||
MV_V2_33X0_PORT_CTRL_MACTYPE_10GBASER_NO_SGMII_AN = 0x5,
|
||||
MV_V2_33X0_PORT_CTRL_MACTYPE_10GBASER_RATE_MATCH = 0x6,
|
||||
MV_V2_33X0_PORT_CTRL_MACTYPE_USXGMII = 0x7,
|
||||
+ MV_V2_LED0_CONTROL = 0xf020,
|
||||
+ MV_V2_LED_CONTROL_POLARITY_MASK = 0x0003,
|
||||
+ MV_V2_LED_CONTROL_POLARITY_SHIFT = 0,
|
||||
+ MV_V2_LED_CONTROL_BLINK_RATE = BIT(2),
|
||||
+ MV_V2_LED_CONTROL_SOLID_FUNC_MASK = 0x00f8,
|
||||
+ MV_V2_LED_CONTROL_SOLID_FUNC_SHIFT = 3,
|
||||
+ MV_V2_LED_CONTROL_BLINK_FUNC_MASK = 0x1f00,
|
||||
+ MV_V2_LED_CONTROL_BLINK_FUNC_SHIFT = 8,
|
||||
MV_V2_PORT_INTR_STS = 0xf040,
|
||||
MV_V2_PORT_INTR_MASK = 0xf043,
|
||||
MV_V2_PORT_INTR_STS_WOL_EN = BIT(8),
|
||||
@@ -168,6 +177,16 @@ struct mv3310_chip {
|
||||
#endif
|
||||
};
|
||||
|
||||
+#define MV3310_N_LEDS 4
|
||||
+
|
||||
+struct mv3310_led {
|
||||
+ u8 index;
|
||||
+ u16 fw_ctrl;
|
||||
+
|
||||
+ unsigned copper:1;
|
||||
+ unsigned fiber:1;
|
||||
+};
|
||||
+
|
||||
struct mv3310_priv {
|
||||
DECLARE_BITMAP(supported_interfaces, PHY_INTERFACE_MODE_MAX);
|
||||
|
||||
@@ -178,6 +197,8 @@ struct mv3310_priv {
|
||||
|
||||
struct device *hwmon_dev;
|
||||
char *hwmon_name;
|
||||
+
|
||||
+ struct mv3310_led led[MV3310_N_LEDS];
|
||||
};
|
||||
|
||||
static const struct mv3310_chip *to_mv3310_chip(struct phy_device *phydev)
|
||||
@@ -185,6 +206,431 @@ static const struct mv3310_chip *to_mv3310_chip(struct phy_device *phydev)
|
||||
return phydev->drv->driver_data;
|
||||
}
|
||||
|
||||
+enum mv3310_led_func {
|
||||
+ MV3310_LED_FUNC_OFF = 0x00,
|
||||
+ MV3310_LED_FUNC_TX_RX = 0x01,
|
||||
+ MV3310_LED_FUNC_TX = 0x02,
|
||||
+ MV3310_LED_FUNC_RX = 0x03,
|
||||
+ MV3310_LED_FUNC_COLLISION = 0x04,
|
||||
+ MV3310_LED_FUNC_LINK_COPPER = 0x05,
|
||||
+ MV3310_LED_FUNC_LINK_FIBER = 0x06,
|
||||
+ MV3310_LED_FUNC_LINK = 0x07,
|
||||
+ MV3310_LED_FUNC_10M_LINK = 0x08,
|
||||
+ MV3310_LED_FUNC_100M_LINK = 0x09,
|
||||
+ MV3310_LED_FUNC_1G_LINK = 0x0a,
|
||||
+ MV3310_LED_FUNC_10G_LINK = 0x0b,
|
||||
+ MV3310_LED_FUNC_10M_100M_LINK = 0x0c,
|
||||
+ MV3310_LED_FUNC_10M_100M_1G_LINK = 0x0d,
|
||||
+ MV3310_LED_FUNC_100M_10G_LINK = 0x0e,
|
||||
+ MV3310_LED_FUNC_1G_10G_LINK = 0x0f,
|
||||
+ MV3310_LED_FUNC_1G_10G_SLAVE = 0x10,
|
||||
+ MV3310_LED_FUNC_1G_10G_MASTER = 0x11,
|
||||
+ MV3310_LED_FUNC_HALF_DUPLEX = 0x12,
|
||||
+ MV3310_LED_FUNC_FULL_DUPLEX = 0x13,
|
||||
+ MV3310_LED_FUNC_LINK_EEE = 0x14,
|
||||
+ MV3310_LED_FUNC_2G5_LINK = 0x15,
|
||||
+ MV3310_LED_FUNC_5G_LINK = 0x16,
|
||||
+ MV3310_LED_FUNC_ON = 0x17,
|
||||
+ MV3310_LED_FUNC_2G5_5G_SLAVE = 0x18,
|
||||
+ MV3310_LED_FUNC_2G5_5G_MASTER = 0x19,
|
||||
+
|
||||
+ MV3310_LED_FUNC_SPEED_BLINK = 0x1f
|
||||
+};
|
||||
+
|
||||
+static int mv3310_led_flags_from_funcs(struct mv3310_led *led,
|
||||
+ enum mv3310_led_func solid,
|
||||
+ enum mv3310_led_func blink,
|
||||
+ unsigned long *flagsp)
|
||||
+{
|
||||
+ unsigned long flags = 0;
|
||||
+
|
||||
+ switch (solid) {
|
||||
+ case MV3310_LED_FUNC_OFF:
|
||||
+ break;
|
||||
+ case MV3310_LED_FUNC_LINK_COPPER:
|
||||
+ case MV3310_LED_FUNC_LINK_FIBER:
|
||||
+ case MV3310_LED_FUNC_LINK:
|
||||
+ flags |= TRIGGER_NETDEV_LINK;
|
||||
+ break;
|
||||
+ case MV3310_LED_FUNC_HALF_DUPLEX:
|
||||
+ flags |= TRIGGER_NETDEV_HALF_DUPLEX;
|
||||
+ break;
|
||||
+ case MV3310_LED_FUNC_FULL_DUPLEX:
|
||||
+ flags |= TRIGGER_NETDEV_FULL_DUPLEX;
|
||||
+ break;
|
||||
+ default:
|
||||
+ return -EINVAL;
|
||||
+ }
|
||||
+
|
||||
+ switch (blink) {
|
||||
+ case MV3310_LED_FUNC_OFF:
|
||||
+ break;
|
||||
+ case MV3310_LED_FUNC_TX:
|
||||
+ flags |= TRIGGER_NETDEV_TX;
|
||||
+ break;
|
||||
+ case MV3310_LED_FUNC_RX:
|
||||
+ flags |= TRIGGER_NETDEV_RX;
|
||||
+ break;
|
||||
+ case MV3310_LED_FUNC_TX_RX:
|
||||
+ flags |= TRIGGER_NETDEV_TX | TRIGGER_NETDEV_RX;
|
||||
+ break;
|
||||
+ default:
|
||||
+ return -EINVAL;
|
||||
+
|
||||
+ }
|
||||
+
|
||||
+ *flagsp = flags;
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static int mv3310_led_funcs_from_flags(struct mv3310_led *led,
|
||||
+ unsigned long flags,
|
||||
+ enum mv3310_led_func *solid,
|
||||
+ enum mv3310_led_func *blink)
|
||||
+{
|
||||
+ unsigned long activity, duplex, link;
|
||||
+
|
||||
+ if (flags & ~(BIT(TRIGGER_NETDEV_LINK) |
|
||||
+ BIT(TRIGGER_NETDEV_HALF_DUPLEX) |
|
||||
+ BIT(TRIGGER_NETDEV_FULL_DUPLEX) |
|
||||
+ BIT(TRIGGER_NETDEV_TX) |
|
||||
+ BIT(TRIGGER_NETDEV_RX)))
|
||||
+ return -EINVAL;
|
||||
+
|
||||
+ link = flags & BIT(TRIGGER_NETDEV_LINK);
|
||||
+
|
||||
+ duplex = flags & (BIT(TRIGGER_NETDEV_HALF_DUPLEX) |
|
||||
+ BIT(TRIGGER_NETDEV_FULL_DUPLEX));
|
||||
+
|
||||
+ activity = flags & (BIT(TRIGGER_NETDEV_TX) |
|
||||
+ BIT(TRIGGER_NETDEV_RX));
|
||||
+
|
||||
+ if (link && duplex)
|
||||
+ return -EINVAL;
|
||||
+
|
||||
+ if (solid) {
|
||||
+ if (link) {
|
||||
+ if (led->copper)
|
||||
+ *solid = MV3310_LED_FUNC_LINK_COPPER;
|
||||
+ else if (led->fiber)
|
||||
+ *solid = MV3310_LED_FUNC_LINK_FIBER;
|
||||
+ else
|
||||
+ *solid = MV3310_LED_FUNC_LINK;
|
||||
+ } else if (duplex) {
|
||||
+ switch (duplex) {
|
||||
+ case BIT(TRIGGER_NETDEV_HALF_DUPLEX):
|
||||
+ *solid = MV3310_LED_FUNC_HALF_DUPLEX;
|
||||
+ break;
|
||||
+ case BIT(TRIGGER_NETDEV_FULL_DUPLEX):
|
||||
+ *solid = MV3310_LED_FUNC_FULL_DUPLEX;
|
||||
+ break;
|
||||
+ default:
|
||||
+ break;
|
||||
+ }
|
||||
+ } else {
|
||||
+ *solid = MV3310_LED_FUNC_OFF;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ if (blink) {
|
||||
+ switch (activity) {
|
||||
+ case 0:
|
||||
+ *blink = MV3310_LED_FUNC_OFF;
|
||||
+ break;
|
||||
+ case BIT(TRIGGER_NETDEV_TX):
|
||||
+ *blink = MV3310_LED_FUNC_TX;
|
||||
+ break;
|
||||
+ case BIT(TRIGGER_NETDEV_RX):
|
||||
+ *blink = MV3310_LED_FUNC_RX;
|
||||
+ break;
|
||||
+ default:
|
||||
+ *blink = MV3310_LED_FUNC_TX_RX;
|
||||
+ break;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static int mv3310_led_get(struct phy_device *phydev,
|
||||
+ struct mv3310_led *led,
|
||||
+ enum mv3310_led_func *solid,
|
||||
+ enum mv3310_led_func *blink,
|
||||
+ bool *slow_blink)
|
||||
+{
|
||||
+ int ctrl;
|
||||
+
|
||||
+ ctrl = phy_read_mmd(phydev, MDIO_MMD_VEND2,
|
||||
+ MV_V2_LED0_CONTROL + led->index);
|
||||
+ if (ctrl < 0)
|
||||
+ return ctrl;
|
||||
+
|
||||
+ *solid = (ctrl & MV_V2_LED_CONTROL_SOLID_FUNC_MASK) >>
|
||||
+ MV_V2_LED_CONTROL_SOLID_FUNC_SHIFT;
|
||||
+ *blink = (ctrl & MV_V2_LED_CONTROL_BLINK_FUNC_MASK) >>
|
||||
+ MV_V2_LED_CONTROL_BLINK_FUNC_SHIFT;
|
||||
+
|
||||
+ *slow_blink = !!(ctrl & MV_V2_LED_CONTROL_BLINK_RATE);
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static int mv3310_led_set(struct phy_device *phydev,
|
||||
+ struct mv3310_led *led,
|
||||
+ enum mv3310_led_func solid,
|
||||
+ enum mv3310_led_func blink,
|
||||
+ bool slow_blink)
|
||||
+{
|
||||
+ u16 ctrl = led->fw_ctrl;
|
||||
+
|
||||
+ ctrl &= ~MV_V2_LED_CONTROL_SOLID_FUNC_MASK;
|
||||
+ ctrl &= ~MV_V2_LED_CONTROL_BLINK_FUNC_MASK;
|
||||
+ ctrl &= ~MV_V2_LED_CONTROL_BLINK_RATE;
|
||||
+
|
||||
+ ctrl |= solid << MV_V2_LED_CONTROL_SOLID_FUNC_SHIFT;
|
||||
+ ctrl |= blink << MV_V2_LED_CONTROL_BLINK_FUNC_SHIFT;
|
||||
+
|
||||
+ if (slow_blink)
|
||||
+ ctrl |= MV_V2_LED_CONTROL_BLINK_RATE;
|
||||
+
|
||||
+ return phy_write_mmd(phydev, MDIO_MMD_VEND2,
|
||||
+ MV_V2_LED0_CONTROL + led->index, ctrl);
|
||||
+}
|
||||
+
|
||||
+
|
||||
+enum mv3310_led_polarity {
|
||||
+ MV3310_LED_POLARITY_ACTIVE_LOW = 0x0,
|
||||
+ MV3310_LED_POLARITY_ACTIVE_HIGH = 0x1,
|
||||
+ MV3310_LED_POLARITY_ACTIVE_LOW_TRISTATE = 0x2,
|
||||
+ MV3310_LED_POLARITY_ACTIVE_HIGH_TRISTATE = 0x3,
|
||||
+};
|
||||
+
|
||||
+static const char *mv3310_led_polarity_name[] = {
|
||||
+ [MV3310_LED_POLARITY_ACTIVE_LOW] = "active-low",
|
||||
+ [MV3310_LED_POLARITY_ACTIVE_HIGH] = "active-high",
|
||||
+ [MV3310_LED_POLARITY_ACTIVE_LOW_TRISTATE] = "active-low-tristate",
|
||||
+ [MV3310_LED_POLARITY_ACTIVE_HIGH_TRISTATE] = "active-high-tristate",
|
||||
+};
|
||||
+
|
||||
+static int mv3310_led_polarity_from_str(const char *str,
|
||||
+ enum mv3310_led_polarity *polarity)
|
||||
+{
|
||||
+ int i;
|
||||
+
|
||||
+ for (i = 0; i < ARRAY_SIZE(mv3310_led_polarity_name); i++) {
|
||||
+ if (!mv3310_led_polarity_name[i])
|
||||
+ continue;
|
||||
+
|
||||
+ if (!strcmp(mv3310_led_polarity_name[i], str)) {
|
||||
+ *polarity = i;
|
||||
+ return 0;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ return -ENOENT;
|
||||
+}
|
||||
+
|
||||
+static int mv3310_led_probe_of(struct phy_device *phydev,
|
||||
+ struct device_node *np)
|
||||
+{
|
||||
+ struct mv3310_priv *priv = dev_get_drvdata(&phydev->mdio.dev);
|
||||
+ enum mv3310_led_polarity polarity;
|
||||
+ struct mv3310_led *led;
|
||||
+ const char *str;
|
||||
+ u32 index;
|
||||
+ u16 ctrl;
|
||||
+ int err;
|
||||
+
|
||||
+ err = of_property_read_u32(np, "reg", &index);
|
||||
+ if (err)
|
||||
+ return err;
|
||||
+
|
||||
+ if (index >= MV3310_N_LEDS)
|
||||
+ return -EINVAL;
|
||||
+
|
||||
+ led = &priv->led[index];
|
||||
+ ctrl = led->fw_ctrl;
|
||||
+
|
||||
+ err = of_property_read_string(np, "marvell,media", &str);
|
||||
+ if (!err) {
|
||||
+ if (!strcmp(str, "copper"))
|
||||
+ led->copper = 1;
|
||||
+ else if (!strcmp(str, "fiber"))
|
||||
+ led->fiber = 1;
|
||||
+ }
|
||||
+
|
||||
+ err = of_property_read_string(np, "marvell,polarity", &str);
|
||||
+ err = err ? : mv3310_led_polarity_from_str(str, &polarity);
|
||||
+ if (!err) {
|
||||
+ ctrl &= ~MV_V2_LED_CONTROL_POLARITY_MASK;
|
||||
+ ctrl |= polarity << MV_V2_LED_CONTROL_POLARITY_SHIFT;
|
||||
+ }
|
||||
+
|
||||
+ if (ctrl != led->fw_ctrl) {
|
||||
+ led->fw_ctrl = ctrl;
|
||||
+
|
||||
+ return phy_write_mmd(phydev, MDIO_MMD_VEND2,
|
||||
+ MV_V2_LED0_CONTROL + index, ctrl);
|
||||
+ }
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static int mv3310_leds_probe(struct phy_device *phydev)
|
||||
+{
|
||||
+ struct mv3310_priv *priv = dev_get_drvdata(&phydev->mdio.dev);
|
||||
+ struct device_node *node = phydev->mdio.dev.of_node;
|
||||
+ struct device_node *pnp, *np;
|
||||
+ int err, val, index;
|
||||
+
|
||||
+ /* Save the state config left by HW reset or bootloader, this
|
||||
+ * may be further refined by configuration from DT, if
|
||||
+ * available.
|
||||
+ *
|
||||
+ * The resulting state is used as the fallback when no trigger
|
||||
+ * is active.
|
||||
+ */
|
||||
+ for (index = 0; index < MV3310_N_LEDS; index++) {
|
||||
+ val = phy_read_mmd(phydev, MDIO_MMD_VEND2,
|
||||
+ MV_V2_LED0_CONTROL + index);
|
||||
+ if (val < 0)
|
||||
+ return val;
|
||||
+
|
||||
+ priv->led[index] = (struct mv3310_led) {
|
||||
+ .index = index,
|
||||
+ .fw_ctrl = val,
|
||||
+ };
|
||||
+ }
|
||||
+
|
||||
+ if (!node)
|
||||
+ return 0;
|
||||
+
|
||||
+ pnp = of_get_child_by_name(node, "leds");
|
||||
+ if (!pnp)
|
||||
+ return 0;
|
||||
+
|
||||
+ for_each_available_child_of_node(pnp, np) {
|
||||
+ err = mv3310_led_probe_of(phydev, np);
|
||||
+ if (err)
|
||||
+ return err;
|
||||
+ }
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static int mv3310_led_brightness_set(struct phy_device *phydev,
|
||||
+ u8 index, enum led_brightness value)
|
||||
+{
|
||||
+ struct mv3310_priv *priv = dev_get_drvdata(&phydev->mdio.dev);
|
||||
+ enum mv3310_led_func solid;
|
||||
+ struct mv3310_led *led;
|
||||
+
|
||||
+ if (index >= MV3310_N_LEDS)
|
||||
+ return -ENODEV;
|
||||
+
|
||||
+ led = &priv->led[index];
|
||||
+
|
||||
+ if (value == LED_OFF)
|
||||
+ solid = MV3310_LED_FUNC_OFF;
|
||||
+ else
|
||||
+ solid = MV3310_LED_FUNC_ON;
|
||||
+
|
||||
+ return mv3310_led_set(phydev, led, solid, MV3310_LED_FUNC_OFF, false);
|
||||
+}
|
||||
+
|
||||
+static int mv3310_led_blink_set(struct phy_device *phydev, u8 index,
|
||||
+ unsigned long *delay_on,
|
||||
+ unsigned long *delay_off)
|
||||
+{
|
||||
+ struct mv3310_priv *priv = dev_get_drvdata(&phydev->mdio.dev);
|
||||
+ struct mv3310_led *led;
|
||||
+ bool slow_blink;
|
||||
+ int err;
|
||||
+
|
||||
+ if (index >= MV3310_N_LEDS)
|
||||
+ return -ENODEV;
|
||||
+
|
||||
+ led = &priv->led[index];
|
||||
+
|
||||
+ if (*delay_on != *delay_off)
|
||||
+ /* Defer anything other than 50% duty cycles to
|
||||
+ * software.
|
||||
+ */
|
||||
+ return -EINVAL;
|
||||
+
|
||||
+ /* Accept values within ~20% of our supported rates (80ms or
|
||||
+ * 1300ms periods).
|
||||
+ */
|
||||
+ if ((*delay_on >= 30) && (*delay_on <= 50))
|
||||
+ slow_blink = false;
|
||||
+ else if (((*delay_on >= 500) && (*delay_on <= 800)) || (*delay_on == 0))
|
||||
+ slow_blink = true;
|
||||
+ else
|
||||
+ return -EINVAL;
|
||||
+
|
||||
+ err = mv3310_led_set(phydev, led, MV3310_LED_FUNC_OFF,
|
||||
+ MV3310_LED_FUNC_ON, slow_blink);
|
||||
+ if (!err)
|
||||
+ *delay_on = *delay_off = slow_blink ? 650 : 40;
|
||||
+
|
||||
+ return err;
|
||||
+}
|
||||
+
|
||||
+static int mv3310_led_hw_is_supported(struct phy_device *phydev, u8 index,
|
||||
+ unsigned long flags)
|
||||
+{
|
||||
+ struct mv3310_priv *priv = dev_get_drvdata(&phydev->mdio.dev);
|
||||
+ struct mv3310_led *led;
|
||||
+
|
||||
+ if (index >= MV3310_N_LEDS)
|
||||
+ return -ENODEV;
|
||||
+
|
||||
+ led = &priv->led[index];
|
||||
+
|
||||
+ return mv3310_led_funcs_from_flags(led, flags, NULL, NULL);
|
||||
+}
|
||||
+
|
||||
+static int mv3310_led_hw_control_set(struct phy_device *phydev, u8 index,
|
||||
+ unsigned long flags)
|
||||
+{
|
||||
+ struct mv3310_priv *priv = dev_get_drvdata(&phydev->mdio.dev);
|
||||
+ enum mv3310_led_func solid, blink;
|
||||
+ struct mv3310_led *led;
|
||||
+ int err;
|
||||
+
|
||||
+ if (index >= MV3310_N_LEDS)
|
||||
+ return -ENODEV;
|
||||
+
|
||||
+ led = &priv->led[index];
|
||||
+
|
||||
+ err = mv3310_led_funcs_from_flags(led, flags, &solid, &blink);
|
||||
+ if (err)
|
||||
+ return err;
|
||||
+
|
||||
+ return mv3310_led_set(phydev, led, solid, blink, false);
|
||||
+}
|
||||
+
|
||||
+static int mv3310_led_hw_control_get(struct phy_device *phydev, u8 index,
|
||||
+ unsigned long *flags)
|
||||
+{
|
||||
+ struct mv3310_priv *priv = dev_get_drvdata(&phydev->mdio.dev);
|
||||
+ enum mv3310_led_func solid, blink;
|
||||
+ struct mv3310_led *led;
|
||||
+ bool slow_blink;
|
||||
+ int err;
|
||||
+
|
||||
+ if (index >= MV3310_N_LEDS)
|
||||
+ return -ENODEV;
|
||||
+
|
||||
+ led = &priv->led[index];
|
||||
+
|
||||
+ err = mv3310_led_get(phydev, led, &solid, &blink, &slow_blink);
|
||||
+ if (err)
|
||||
+ return err;
|
||||
+
|
||||
+ return mv3310_led_flags_from_funcs(led, solid, blink, flags);
|
||||
+}
|
||||
+
|
||||
+
|
||||
#ifdef CONFIG_HWMON
|
||||
static umode_t mv3310_hwmon_is_visible(const void *data,
|
||||
enum hwmon_sensor_types type,
|
||||
@@ -697,6 +1143,10 @@ static int mv3310_probe(struct phy_device *phydev)
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
+ ret = mv3310_leds_probe(phydev);
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+
|
||||
chip->init_supported_interfaces(priv->supported_interfaces);
|
||||
|
||||
return phy_sfp_probe(phydev, &mv3310_sfp_ops);
|
||||
@@ -1502,6 +1952,11 @@ static struct phy_driver mv3310_drivers[] = {
|
||||
.set_loopback = genphy_c45_loopback,
|
||||
.get_wol = mv3110_get_wol,
|
||||
.set_wol = mv3110_set_wol,
|
||||
+ .led_brightness_set = mv3310_led_brightness_set,
|
||||
+ .led_blink_set = mv3310_led_blink_set,
|
||||
+ .led_hw_is_supported = mv3310_led_hw_is_supported,
|
||||
+ .led_hw_control_set = mv3310_led_hw_control_set,
|
||||
+ .led_hw_control_get = mv3310_led_hw_control_get,
|
||||
},
|
||||
{
|
||||
.phy_id = MARVELL_PHY_ID_88X3310,
|
||||
--
|
||||
2.34.1
|
||||
|
||||
@@ -0,0 +1,321 @@
|
||||
From 913a57a304e8024f4cea872fa904cee867c469a2 Mon Sep 17 00:00:00 2001
|
||||
From: Tobias Waldekranz <tobias@waldekranz.com>
|
||||
Date: Thu, 16 Nov 2023 19:44:32 +0100
|
||||
Subject: [PATCH 14/15] net: dsa: mv88e6xxx: Add LED infrastructure
|
||||
|
||||
Parse DT for LEDs and register them for devices that support it,
|
||||
though no actual implementations exist yet.
|
||||
|
||||
Signed-off-by: Tobias Waldekranz <tobias@waldekranz.com>
|
||||
---
|
||||
drivers/net/dsa/mv88e6xxx/Makefile | 1 +
|
||||
drivers/net/dsa/mv88e6xxx/chip.c | 8 +-
|
||||
drivers/net/dsa/mv88e6xxx/chip.h | 17 +++
|
||||
drivers/net/dsa/mv88e6xxx/leds.c | 184 +++++++++++++++++++++++++++++
|
||||
drivers/net/dsa/mv88e6xxx/leds.h | 12 ++
|
||||
5 files changed, 221 insertions(+), 1 deletion(-)
|
||||
create mode 100644 drivers/net/dsa/mv88e6xxx/leds.c
|
||||
create mode 100644 drivers/net/dsa/mv88e6xxx/leds.h
|
||||
|
||||
diff --git a/drivers/net/dsa/mv88e6xxx/Makefile b/drivers/net/dsa/mv88e6xxx/Makefile
|
||||
index 1409e691ab77..ab07996aeb7f 100644
|
||||
--- a/drivers/net/dsa/mv88e6xxx/Makefile
|
||||
+++ b/drivers/net/dsa/mv88e6xxx/Makefile
|
||||
@@ -9,6 +9,7 @@ mv88e6xxx-objs += global2.o
|
||||
mv88e6xxx-objs += global2_avb.o
|
||||
mv88e6xxx-objs += global2_scratch.o
|
||||
mv88e6xxx-$(CONFIG_NET_DSA_MV88E6XXX_PTP) += hwtstamp.o
|
||||
+mv88e6xxx-objs += leds.o
|
||||
mv88e6xxx-objs += phy.o
|
||||
mv88e6xxx-objs += port.o
|
||||
mv88e6xxx-objs += port_hidden.o
|
||||
diff --git a/drivers/net/dsa/mv88e6xxx/chip.c b/drivers/net/dsa/mv88e6xxx/chip.c
|
||||
index 90dcd6c3be31..d343ea5cc4a1 100644
|
||||
--- a/drivers/net/dsa/mv88e6xxx/chip.c
|
||||
+++ b/drivers/net/dsa/mv88e6xxx/chip.c
|
||||
@@ -37,6 +37,7 @@
|
||||
#include "global1.h"
|
||||
#include "global2.h"
|
||||
#include "hwtstamp.h"
|
||||
+#include "leds.h"
|
||||
#include "phy.h"
|
||||
#include "port.h"
|
||||
#include "ptp.h"
|
||||
@@ -4259,11 +4260,16 @@ static int mv88e6xxx_setup(struct dsa_switch *ds)
|
||||
|
||||
static int mv88e6xxx_port_setup(struct dsa_switch *ds, int port)
|
||||
{
|
||||
- return mv88e6xxx_setup_devlink_regions_port(ds, port);
|
||||
+ int err = 0;
|
||||
+
|
||||
+ err = err ? : mv88e6xxx_setup_devlink_regions_port(ds, port);
|
||||
+ err = err ? : mv88e6xxx_port_setup_leds(ds, port);
|
||||
+ return err;
|
||||
}
|
||||
|
||||
static void mv88e6xxx_port_teardown(struct dsa_switch *ds, int port)
|
||||
{
|
||||
+ /* LED resources are devm_ managed */
|
||||
mv88e6xxx_teardown_devlink_regions_port(ds, port);
|
||||
}
|
||||
|
||||
diff --git a/drivers/net/dsa/mv88e6xxx/chip.h b/drivers/net/dsa/mv88e6xxx/chip.h
|
||||
index 268c97cde8d8..fb0d2584af1b 100644
|
||||
--- a/drivers/net/dsa/mv88e6xxx/chip.h
|
||||
+++ b/drivers/net/dsa/mv88e6xxx/chip.h
|
||||
@@ -205,6 +205,7 @@ struct mv88e6xxx_irq_ops;
|
||||
struct mv88e6xxx_gpio_ops;
|
||||
struct mv88e6xxx_avb_ops;
|
||||
struct mv88e6xxx_ptp_ops;
|
||||
+struct mv88e6xxx_led_ops;
|
||||
|
||||
struct mv88e6xxx_irq {
|
||||
u16 masked;
|
||||
@@ -329,6 +330,8 @@ struct mv88e6xxx_hw_stat {
|
||||
int type;
|
||||
};
|
||||
|
||||
+struct mv88e6xxx_led;
|
||||
+
|
||||
struct mv88e6xxx_chip {
|
||||
const struct mv88e6xxx_info *info;
|
||||
|
||||
@@ -672,6 +675,9 @@ struct mv88e6xxx_ops {
|
||||
/* Precision Time Protocol operations */
|
||||
const struct mv88e6xxx_ptp_ops *ptp_ops;
|
||||
|
||||
+ /* LED operations */
|
||||
+ const struct mv88e6xxx_led_ops *led_ops;
|
||||
+
|
||||
/* Phylink */
|
||||
void (*phylink_get_caps)(struct mv88e6xxx_chip *chip, int port,
|
||||
struct phylink_config *config);
|
||||
@@ -748,6 +754,17 @@ struct mv88e6xxx_ptp_ops {
|
||||
u32 cc_mult_dem;
|
||||
};
|
||||
|
||||
+struct mv88e6xxx_led_ops {
|
||||
+ int (*brightness_set)(struct mv88e6xxx_led *led,
|
||||
+ enum led_brightness brightness);
|
||||
+ int (*blink_set)(struct mv88e6xxx_led *led,
|
||||
+ unsigned long *delay_on, unsigned long *delay_off);
|
||||
+ int (*hw_control_is_supported)(struct mv88e6xxx_led *led,
|
||||
+ unsigned long flags);
|
||||
+ int (*hw_control_set)(struct mv88e6xxx_led *led, unsigned long flags);
|
||||
+ int (*hw_control_get)(struct mv88e6xxx_led *led, unsigned long *flags);
|
||||
+};
|
||||
+
|
||||
static inline bool mv88e6xxx_has_stu(struct mv88e6xxx_chip *chip)
|
||||
{
|
||||
return chip->info->max_sid > 0 &&
|
||||
diff --git a/drivers/net/dsa/mv88e6xxx/leds.c b/drivers/net/dsa/mv88e6xxx/leds.c
|
||||
new file mode 100644
|
||||
index 000000000000..42e1661e1f47
|
||||
--- /dev/null
|
||||
+++ b/drivers/net/dsa/mv88e6xxx/leds.c
|
||||
@@ -0,0 +1,184 @@
|
||||
+// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
+#include <net/dsa.h>
|
||||
+
|
||||
+#include "chip.h"
|
||||
+#include "port.h"
|
||||
+
|
||||
+struct mv88e6xxx_led {
|
||||
+ struct mv88e6xxx_chip *chip;
|
||||
+ int port;
|
||||
+ u8 index;
|
||||
+
|
||||
+ struct led_classdev ldev;
|
||||
+};
|
||||
+
|
||||
+static int mv88e6xxx_led_brightness_set(struct led_classdev *ldev,
|
||||
+ enum led_brightness brightness)
|
||||
+{
|
||||
+ const struct mv88e6xxx_led_ops *ops;
|
||||
+ struct mv88e6xxx_led *led;
|
||||
+
|
||||
+ led = container_of(ldev, struct mv88e6xxx_led, ldev);
|
||||
+ ops = led->chip->info->ops->led_ops;
|
||||
+
|
||||
+ if (!ops->brightness_set)
|
||||
+ return -EOPNOTSUPP;
|
||||
+
|
||||
+ return ops->brightness_set(led, brightness);
|
||||
+}
|
||||
+
|
||||
+static int mv88e6xxx_led_blink_set(struct led_classdev *ldev,
|
||||
+ unsigned long *delay_on,
|
||||
+ unsigned long *delay_off)
|
||||
+{
|
||||
+ const struct mv88e6xxx_led_ops *ops;
|
||||
+ struct mv88e6xxx_led *led;
|
||||
+
|
||||
+ led = container_of(ldev, struct mv88e6xxx_led, ldev);
|
||||
+ ops = led->chip->info->ops->led_ops;
|
||||
+
|
||||
+ if (!ops->blink_set)
|
||||
+ return -EOPNOTSUPP;
|
||||
+
|
||||
+ return ops->blink_set(led, delay_on, delay_off);
|
||||
+}
|
||||
+
|
||||
+static int mv88e6xxx_led_hw_control_is_supported(struct led_classdev *ldev,
|
||||
+ unsigned long flags)
|
||||
+{
|
||||
+ const struct mv88e6xxx_led_ops *ops;
|
||||
+ struct mv88e6xxx_led *led;
|
||||
+
|
||||
+ led = container_of(ldev, struct mv88e6xxx_led, ldev);
|
||||
+ ops = led->chip->info->ops->led_ops;
|
||||
+
|
||||
+ if (!ops->hw_control_is_supported)
|
||||
+ return -EOPNOTSUPP;
|
||||
+
|
||||
+ return ops->hw_control_is_supported(led, flags);
|
||||
+}
|
||||
+
|
||||
+static int mv88e6xxx_led_hw_control_set(struct led_classdev *ldev,
|
||||
+ unsigned long flags)
|
||||
+{
|
||||
+ const struct mv88e6xxx_led_ops *ops;
|
||||
+ struct mv88e6xxx_led *led;
|
||||
+
|
||||
+ led = container_of(ldev, struct mv88e6xxx_led, ldev);
|
||||
+ ops = led->chip->info->ops->led_ops;
|
||||
+
|
||||
+ if (!ops->hw_control_set)
|
||||
+ return -EOPNOTSUPP;
|
||||
+
|
||||
+ return ops->hw_control_set(led, flags);
|
||||
+}
|
||||
+
|
||||
+static int mv88e6xxx_led_hw_control_get(struct led_classdev *ldev,
|
||||
+ unsigned long *flags)
|
||||
+{
|
||||
+ const struct mv88e6xxx_led_ops *ops;
|
||||
+ struct mv88e6xxx_led *led;
|
||||
+
|
||||
+ led = container_of(ldev, struct mv88e6xxx_led, ldev);
|
||||
+ ops = led->chip->info->ops->led_ops;
|
||||
+
|
||||
+ if (!ops->hw_control_get)
|
||||
+ return -EOPNOTSUPP;
|
||||
+
|
||||
+ return ops->hw_control_get(led, flags);
|
||||
+}
|
||||
+
|
||||
+static struct device *mv88e6xxx_led_hw_control_get_device(struct led_classdev *ldev)
|
||||
+{
|
||||
+ struct mv88e6xxx_led *led;
|
||||
+ struct dsa_port *dp;
|
||||
+
|
||||
+ led = container_of(ldev, struct mv88e6xxx_led, ldev);
|
||||
+ dp = dsa_to_port(led->chip->ds, led->port);
|
||||
+
|
||||
+ if (dp && dp->slave)
|
||||
+ return &dp->slave->dev;
|
||||
+
|
||||
+ return NULL;
|
||||
+}
|
||||
+
|
||||
+static int mv88e6xxx_port_setup_led(struct mv88e6xxx_chip *chip, int port,
|
||||
+ struct device_node *np)
|
||||
+{
|
||||
+ struct led_init_data init_data = {};
|
||||
+ struct mv88e6xxx_led *led;
|
||||
+ char *devname;
|
||||
+ u32 index;
|
||||
+ int err;
|
||||
+
|
||||
+ err = of_property_read_u32(np, "reg", &index);
|
||||
+ if (err)
|
||||
+ return err;
|
||||
+
|
||||
+ if (index >= 2)
|
||||
+ return -EINVAL;
|
||||
+
|
||||
+ led = devm_kzalloc(chip->dev, sizeof(*led), GFP_KERNEL);
|
||||
+ if (!led)
|
||||
+ return -ENOMEM;
|
||||
+
|
||||
+ *led = (struct mv88e6xxx_led) {
|
||||
+ .chip = chip,
|
||||
+ .port = port,
|
||||
+ .index = index,
|
||||
+
|
||||
+ .ldev = {
|
||||
+ .max_brightness = 1,
|
||||
+ .brightness_set_blocking = mv88e6xxx_led_brightness_set,
|
||||
+ .blink_set = mv88e6xxx_led_blink_set,
|
||||
+
|
||||
+#ifdef CONFIG_LEDS_TRIGGERS
|
||||
+ .hw_control_trigger = "netdev",
|
||||
+ .hw_control_get_device = mv88e6xxx_led_hw_control_get_device,
|
||||
+
|
||||
+ .hw_control_is_supported = mv88e6xxx_led_hw_control_is_supported,
|
||||
+ .hw_control_set = mv88e6xxx_led_hw_control_set,
|
||||
+ .hw_control_get = mv88e6xxx_led_hw_control_get,
|
||||
+#endif
|
||||
+ },
|
||||
+ };
|
||||
+
|
||||
+ devname = devm_kasprintf(chip->dev, GFP_KERNEL, "%s.%d",
|
||||
+ dev_name(chip->dev), port);
|
||||
+ if (!devname)
|
||||
+ return -ENOMEM;
|
||||
+
|
||||
+ init_data = (struct led_init_data) {
|
||||
+ .fwnode = of_fwnode_handle(np),
|
||||
+ .devname_mandatory = true,
|
||||
+ .devicename = devname,
|
||||
+ };
|
||||
+
|
||||
+ return devm_led_classdev_register_ext(chip->dev, &led->ldev, &init_data);
|
||||
+}
|
||||
+
|
||||
+int mv88e6xxx_port_setup_leds(struct dsa_switch *ds, int port)
|
||||
+{
|
||||
+ struct dsa_port *dp = dsa_to_port(ds, port);
|
||||
+ struct mv88e6xxx_chip *chip = ds->priv;
|
||||
+ struct device_node *pnp, *np;
|
||||
+ int err;
|
||||
+
|
||||
+ if (!chip->info->ops->led_ops)
|
||||
+ return 0;
|
||||
+
|
||||
+ if (!dp->dn)
|
||||
+ return 0;
|
||||
+
|
||||
+ pnp = of_get_child_by_name(dp->dn, "leds");
|
||||
+ if (!pnp)
|
||||
+ return 0;
|
||||
+
|
||||
+ for_each_available_child_of_node(pnp, np) {
|
||||
+ err = mv88e6xxx_port_setup_led(chip, port, np);
|
||||
+ if (err)
|
||||
+ return err;
|
||||
+ }
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
diff --git a/drivers/net/dsa/mv88e6xxx/leds.h b/drivers/net/dsa/mv88e6xxx/leds.h
|
||||
new file mode 100644
|
||||
index 000000000000..8afa2a0c0527
|
||||
--- /dev/null
|
||||
+++ b/drivers/net/dsa/mv88e6xxx/leds.h
|
||||
@@ -0,0 +1,12 @@
|
||||
+/* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
+
|
||||
+/* Marvell 88E6xxx Switch leds support. */
|
||||
+
|
||||
+#ifndef _MV88E6XXX_LEDS_H
|
||||
+#define _MV88E6XXX_LEDS_H
|
||||
+
|
||||
+#include "chip.h"
|
||||
+
|
||||
+int mv88e6xxx_port_setup_leds(struct dsa_switch *ds, int port);
|
||||
+
|
||||
+#endif /* _MV88E6XXX_LEDS_H */
|
||||
--
|
||||
2.34.1
|
||||
|
||||
@@ -0,0 +1,353 @@
|
||||
From 09fca5d7f66b1bdc6a5f72eb3d36bfd8c88bebcc Mon Sep 17 00:00:00 2001
|
||||
From: Tobias Waldekranz <tobias@waldekranz.com>
|
||||
Date: Thu, 16 Nov 2023 21:59:35 +0100
|
||||
Subject: [PATCH 15/15] net: dsa: mv88e6xxx: Add LED support for 6393X
|
||||
|
||||
Trigger support:
|
||||
- "none"
|
||||
- "timer"
|
||||
- "netdev"
|
||||
|
||||
Signed-off-by: Tobias Waldekranz <tobias@waldekranz.com>
|
||||
---
|
||||
drivers/net/dsa/mv88e6xxx/chip.c | 1 +
|
||||
drivers/net/dsa/mv88e6xxx/leds.c | 219 +++++++++++++++++++++++++++++++
|
||||
drivers/net/dsa/mv88e6xxx/leds.h | 2 +
|
||||
drivers/net/dsa/mv88e6xxx/port.c | 33 +++++
|
||||
drivers/net/dsa/mv88e6xxx/port.h | 7 +
|
||||
5 files changed, 262 insertions(+)
|
||||
|
||||
diff --git a/drivers/net/dsa/mv88e6xxx/chip.c b/drivers/net/dsa/mv88e6xxx/chip.c
|
||||
index d343ea5cc4a1..7d6b2b85fc31 100644
|
||||
--- a/drivers/net/dsa/mv88e6xxx/chip.c
|
||||
+++ b/drivers/net/dsa/mv88e6xxx/chip.c
|
||||
@@ -5833,6 +5833,7 @@ static const struct mv88e6xxx_ops mv88e6393x_ops = {
|
||||
.gpio_ops = &mv88e6352_gpio_ops,
|
||||
.avb_ops = &mv88e6390_avb_ops,
|
||||
.ptp_ops = &mv88e6352_ptp_ops,
|
||||
+ .led_ops = &mv88e6393x_led_ops,
|
||||
.phylink_get_caps = mv88e6393x_phylink_get_caps,
|
||||
};
|
||||
|
||||
diff --git a/drivers/net/dsa/mv88e6xxx/leds.c b/drivers/net/dsa/mv88e6xxx/leds.c
|
||||
index 42e1661e1f47..02daf976100d 100644
|
||||
--- a/drivers/net/dsa/mv88e6xxx/leds.c
|
||||
+++ b/drivers/net/dsa/mv88e6xxx/leds.c
|
||||
@@ -4,6 +4,13 @@
|
||||
#include "chip.h"
|
||||
#include "port.h"
|
||||
|
||||
+#define FLAG_ACT (BIT(TRIGGER_NETDEV_RX) | BIT(TRIGGER_NETDEV_TX))
|
||||
+#define FLAG_LINK BIT(TRIGGER_NETDEV_LINK)
|
||||
+#define FLAG_LINK_10 BIT(TRIGGER_NETDEV_LINK_10)
|
||||
+#define FLAG_LINK_100 BIT(TRIGGER_NETDEV_LINK_100)
|
||||
+#define FLAG_LINK_1G BIT(TRIGGER_NETDEV_LINK_1000)
|
||||
+#define FLAG_FULL BIT(TRIGGER_NETDEV_FULL_DUPLEX)
|
||||
+
|
||||
struct mv88e6xxx_led {
|
||||
struct mv88e6xxx_chip *chip;
|
||||
int port;
|
||||
@@ -12,6 +19,218 @@ struct mv88e6xxx_led {
|
||||
struct led_classdev ldev;
|
||||
};
|
||||
|
||||
+enum mv88e6393x_led_mode {
|
||||
+ MV88E6393X_LED_MODE_BLINK = 0xd,
|
||||
+ MV88E6393X_LED_MODE_OFF = 0xe,
|
||||
+ MV88E6393X_LED_MODE_ON = 0xf,
|
||||
+
|
||||
+ MV88E6393X_LED_MODES = 0x10
|
||||
+};
|
||||
+
|
||||
+static const unsigned long mv88e6393x_led_map_p1_p8[2][MV88E6393X_LED_MODES] = {
|
||||
+ {
|
||||
+ [0x1] = FLAG_ACT | FLAG_LINK_100 | FLAG_LINK_1G,
|
||||
+ [0x2] = FLAG_ACT | FLAG_LINK_1G,
|
||||
+ [0x3] = FLAG_ACT | FLAG_LINK,
|
||||
+ [0x6] = FLAG_FULL,
|
||||
+ [0x7] = FLAG_ACT | FLAG_LINK_10 | FLAG_LINK_1G,
|
||||
+ [0x8] = FLAG_LINK,
|
||||
+ [0x9] = FLAG_LINK_10,
|
||||
+ [0xa] = FLAG_ACT | FLAG_LINK_10,
|
||||
+ [0xb] = FLAG_LINK_100 | FLAG_LINK_1G,
|
||||
+ },
|
||||
+ {
|
||||
+ [0x1] = FLAG_ACT,
|
||||
+ [0x2] = FLAG_ACT | FLAG_LINK_10 | FLAG_LINK_100,
|
||||
+ [0x3] = FLAG_LINK_1G,
|
||||
+ [0x5] = FLAG_ACT | FLAG_LINK,
|
||||
+ [0x6] = FLAG_ACT | FLAG_LINK_10 | FLAG_LINK_1G,
|
||||
+ [0x7] = FLAG_LINK_10 | FLAG_LINK_1G,
|
||||
+ [0x9] = FLAG_LINK_100,
|
||||
+ [0xa] = FLAG_ACT | FLAG_LINK_100,
|
||||
+ [0xb] = FLAG_LINK_10 | FLAG_LINK_100,
|
||||
+ }
|
||||
+};
|
||||
+
|
||||
+static const unsigned long mv88e6393x_led_map_p9_p10[2][MV88E6393X_LED_MODES] = {
|
||||
+ {
|
||||
+ [0x1] = FLAG_ACT | FLAG_LINK,
|
||||
+ },
|
||||
+ {
|
||||
+ [0x6] = FLAG_FULL,
|
||||
+ [0x7] = FLAG_ACT | FLAG_LINK,
|
||||
+ [0x8] = FLAG_LINK,
|
||||
+ }
|
||||
+};
|
||||
+
|
||||
+const unsigned long *mv88e6393x_led_map(struct mv88e6xxx_led *led)
|
||||
+{
|
||||
+ switch (led->port) {
|
||||
+ case 1:
|
||||
+ case 2:
|
||||
+ case 3:
|
||||
+ case 4:
|
||||
+ case 5:
|
||||
+ case 6:
|
||||
+ case 7:
|
||||
+ case 8:
|
||||
+ return mv88e6393x_led_map_p1_p8[led->index];
|
||||
+ case 9:
|
||||
+ case 10:
|
||||
+ return mv88e6393x_led_map_p9_p10[led->index];
|
||||
+ }
|
||||
+
|
||||
+ return NULL;
|
||||
+}
|
||||
+
|
||||
+static int mv88e6393x_led_flags_to_mode(struct mv88e6xxx_led *led, unsigned long flags)
|
||||
+{
|
||||
+ const unsigned long *map = mv88e6393x_led_map(led);
|
||||
+ int i;
|
||||
+
|
||||
+ if (!map)
|
||||
+ return -ENODEV;
|
||||
+
|
||||
+ if (!flags)
|
||||
+ return MV88E6393X_LED_MODE_OFF;
|
||||
+
|
||||
+ for (i = 0; i < MV88E6393X_LED_MODES; i++) {
|
||||
+ if (map[i] == flags)
|
||||
+ return i;
|
||||
+ }
|
||||
+
|
||||
+ return -EINVAL;
|
||||
+}
|
||||
+
|
||||
+static int mv88e6393x_led_mode_to_flags(struct mv88e6xxx_led *led, u8 mode,
|
||||
+ unsigned long *flags)
|
||||
+{
|
||||
+ const unsigned long *map = mv88e6393x_led_map(led);
|
||||
+
|
||||
+ if (!map)
|
||||
+ return -ENODEV;
|
||||
+
|
||||
+ if (mode == MV88E6393X_LED_MODE_OFF) {
|
||||
+ *flags = 0;
|
||||
+ return 0;
|
||||
+ }
|
||||
+
|
||||
+ if (map[mode]) {
|
||||
+ *flags = map[mode];
|
||||
+ return 0;
|
||||
+ }
|
||||
+
|
||||
+ return -EINVAL;
|
||||
+}
|
||||
+
|
||||
+static int mv88e6393x_led_set(struct mv88e6xxx_led *led, int mode)
|
||||
+{
|
||||
+ u16 ctrl;
|
||||
+ int err;
|
||||
+
|
||||
+ if (mode < 0)
|
||||
+ return mode;
|
||||
+
|
||||
+ err = mv88e6393x_port_led_read(led->chip, led->port, 0, &ctrl);
|
||||
+ if (err)
|
||||
+ return err;
|
||||
+
|
||||
+ switch (led->index) {
|
||||
+ case 0:
|
||||
+ ctrl &= ~0x0f;
|
||||
+ ctrl |= mode;
|
||||
+ break;
|
||||
+ case 1:
|
||||
+ ctrl &= ~0xf0;
|
||||
+ ctrl |= mode << 4;
|
||||
+ }
|
||||
+
|
||||
+ return mv88e6393x_port_led_write(led->chip, led->port, 0, ctrl);
|
||||
+}
|
||||
+
|
||||
+static int mv88e6393x_led_get(struct mv88e6xxx_led *led)
|
||||
+{
|
||||
+ u16 ctrl;
|
||||
+ int err;
|
||||
+
|
||||
+ err = mv88e6393x_port_led_read(led->chip, led->port, 0, &ctrl);
|
||||
+ if (err)
|
||||
+ return err;
|
||||
+
|
||||
+ switch (led->index) {
|
||||
+ case 0:
|
||||
+ return ctrl & 0xf;
|
||||
+ case 1:
|
||||
+ return (ctrl >> 4) & 0xf;
|
||||
+ }
|
||||
+
|
||||
+ return -EINVAL;
|
||||
+}
|
||||
+
|
||||
+static int mv88e6393x_led_brightness_set(struct mv88e6xxx_led *led,
|
||||
+ enum led_brightness brightness)
|
||||
+{
|
||||
+ if (brightness == LED_OFF)
|
||||
+ return mv88e6393x_led_set(led, MV88E6393X_LED_MODE_OFF);
|
||||
+
|
||||
+ return mv88e6393x_led_set(led, MV88E6393X_LED_MODE_ON);
|
||||
+}
|
||||
+static int mv88e6393x_led_blink_set(struct mv88e6xxx_led *led,
|
||||
+ unsigned long *delay_on,
|
||||
+ unsigned long *delay_off)
|
||||
+{
|
||||
+ int err;
|
||||
+
|
||||
+ /* Defer anything other than 50% duty cycles to software */
|
||||
+ if (*delay_on != *delay_off)
|
||||
+ return -EINVAL;
|
||||
+
|
||||
+ /* Reject values outside ~20% of our default rate (84ms) */
|
||||
+ if (*delay_on && ((*delay_on < 30) || (*delay_on > 50)))
|
||||
+ return -EINVAL;
|
||||
+
|
||||
+ err = mv88e6393x_led_set(led, MV88E6393X_LED_MODE_BLINK);
|
||||
+ if (!err)
|
||||
+ *delay_on = *delay_off = 42;
|
||||
+
|
||||
+ return err;
|
||||
+}
|
||||
+
|
||||
+static int mv88e6393x_led_hw_control_is_supported(struct mv88e6xxx_led *led,
|
||||
+ unsigned long flags)
|
||||
+{
|
||||
+ int mode = mv88e6393x_led_flags_to_mode(led, flags);
|
||||
+
|
||||
+ return (mode < 0) ? mode : 0;
|
||||
+}
|
||||
+
|
||||
+static int mv88e6393x_led_hw_control_set(struct mv88e6xxx_led *led,
|
||||
+ unsigned long flags)
|
||||
+{
|
||||
+ int mode = mv88e6393x_led_flags_to_mode(led, flags);
|
||||
+
|
||||
+ return mv88e6393x_led_set(led, mode);
|
||||
+}
|
||||
+
|
||||
+static int mv88e6393x_led_hw_control_get(struct mv88e6xxx_led *led,
|
||||
+ unsigned long *flags)
|
||||
+{
|
||||
+ int mode = mv88e6393x_led_get(led);
|
||||
+
|
||||
+ if (mode < 0)
|
||||
+ return mode;
|
||||
+
|
||||
+ return mv88e6393x_led_mode_to_flags(led, mode, flags);
|
||||
+}
|
||||
+
|
||||
+const struct mv88e6xxx_led_ops mv88e6393x_led_ops = {
|
||||
+ .brightness_set = mv88e6393x_led_brightness_set,
|
||||
+ .blink_set = mv88e6393x_led_blink_set,
|
||||
+ .hw_control_is_supported = mv88e6393x_led_hw_control_is_supported,
|
||||
+ .hw_control_set = mv88e6393x_led_hw_control_set,
|
||||
+ .hw_control_get = mv88e6393x_led_hw_control_get,
|
||||
+};
|
||||
+
|
||||
static int mv88e6xxx_led_brightness_set(struct led_classdev *ldev,
|
||||
enum led_brightness brightness)
|
||||
{
|
||||
diff --git a/drivers/net/dsa/mv88e6xxx/leds.h b/drivers/net/dsa/mv88e6xxx/leds.h
|
||||
index 8afa2a0c0527..542345d23dc5 100644
|
||||
--- a/drivers/net/dsa/mv88e6xxx/leds.h
|
||||
+++ b/drivers/net/dsa/mv88e6xxx/leds.h
|
||||
@@ -7,6 +7,8 @@
|
||||
|
||||
#include "chip.h"
|
||||
|
||||
+extern const struct mv88e6xxx_led_ops mv88e6393x_led_ops;
|
||||
+
|
||||
int mv88e6xxx_port_setup_leds(struct dsa_switch *ds, int port);
|
||||
|
||||
#endif /* _MV88E6XXX_LEDS_H */
|
||||
diff --git a/drivers/net/dsa/mv88e6xxx/port.c b/drivers/net/dsa/mv88e6xxx/port.c
|
||||
index dd66ec902d4c..e6733a3ab19f 100644
|
||||
--- a/drivers/net/dsa/mv88e6xxx/port.c
|
||||
+++ b/drivers/net/dsa/mv88e6xxx/port.c
|
||||
@@ -1569,6 +1569,39 @@ int mv88e6351_port_set_ether_type(struct mv88e6xxx_chip *chip, int port,
|
||||
return mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_ETH_TYPE, etype);
|
||||
}
|
||||
|
||||
+/* Offset 0x16: LED Control Register */
|
||||
+
|
||||
+int mv88e6393x_port_led_write(struct mv88e6xxx_chip *chip, int port,
|
||||
+ unsigned int pointer, u16 data)
|
||||
+{
|
||||
+ u16 cmd = BIT(15) | ((pointer & 0x7) << 12) | (data & 0x7ff);
|
||||
+ int err;
|
||||
+
|
||||
+ err = mv88e6xxx_port_write(chip, port, MV88E6393X_PORT_LED_CONTROL, cmd);
|
||||
+ if (err)
|
||||
+ return err;
|
||||
+
|
||||
+ return mv88e6xxx_port_wait_bit(chip, port, MV88E6393X_PORT_LED_CONTROL, 15, 0);
|
||||
+}
|
||||
+
|
||||
+int mv88e6393x_port_led_read(struct mv88e6xxx_chip *chip, int port,
|
||||
+ unsigned int pointer, u16 *data)
|
||||
+{
|
||||
+ u16 cmd = (pointer & 0x7) << 12;
|
||||
+ int err;
|
||||
+
|
||||
+ err = mv88e6xxx_port_write(chip, port, MV88E6393X_PORT_LED_CONTROL, cmd);
|
||||
+ if (err)
|
||||
+ return err;
|
||||
+
|
||||
+ err = mv88e6xxx_port_read(chip, port, MV88E6393X_PORT_LED_CONTROL, &cmd);
|
||||
+ if (err)
|
||||
+ return err;
|
||||
+
|
||||
+ *data = cmd & 0x7ff;
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
/* Offset 0x18: Port IEEE Priority Remapping Registers [0-3]
|
||||
* Offset 0x19: Port IEEE Priority Remapping Registers [4-7]
|
||||
*/
|
||||
diff --git a/drivers/net/dsa/mv88e6xxx/port.h b/drivers/net/dsa/mv88e6xxx/port.h
|
||||
index 86deeb347cbc..3605a59d1399 100644
|
||||
--- a/drivers/net/dsa/mv88e6xxx/port.h
|
||||
+++ b/drivers/net/dsa/mv88e6xxx/port.h
|
||||
@@ -294,6 +294,9 @@
|
||||
/* Offset 0x13: OutFiltered Counter */
|
||||
#define MV88E6XXX_PORT_OUT_FILTERED 0x13
|
||||
|
||||
+/* Offset 0x16: LED Control Register */
|
||||
+#define MV88E6393X_PORT_LED_CONTROL 0x16
|
||||
+
|
||||
/* Offset 0x18: IEEE Priority Mapping Table */
|
||||
#define MV88E6390_PORT_IEEE_PRIO_MAP_TABLE 0x18
|
||||
#define MV88E6390_PORT_IEEE_PRIO_MAP_TABLE_UPDATE 0x8000
|
||||
@@ -410,6 +413,10 @@ int mv88e6393x_port_set_policy(struct mv88e6xxx_chip *chip, int port,
|
||||
enum mv88e6xxx_policy_action action);
|
||||
int mv88e6351_port_set_ether_type(struct mv88e6xxx_chip *chip, int port,
|
||||
u16 etype);
|
||||
+int mv88e6393x_port_led_write(struct mv88e6xxx_chip *chip, int port,
|
||||
+ unsigned int pointer, u16 data);
|
||||
+int mv88e6393x_port_led_read(struct mv88e6xxx_chip *chip, int port,
|
||||
+ unsigned int pointer, u16 *data);
|
||||
int mv88e6393x_set_egress_port(struct mv88e6xxx_chip *chip,
|
||||
enum mv88e6xxx_egress_direction direction,
|
||||
int port);
|
||||
--
|
||||
2.34.1
|
||||
|
||||
Reference in New Issue
Block a user