mirror of
				git://git.openwrt.org/openwrt/openwrt.git
				synced 2025-11-03 22:44:27 -05:00 
			
		
		
		
	Backport qca8k fixes for big endian system (to make them working again) and a patch fixing MDIO conflicts if other PHY are connected and mgmt eth is used to control the switch. Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
		
			
				
	
	
		
			436 lines
		
	
	
		
			13 KiB
		
	
	
	
		
			Diff
		
	
	
	
	
	
			
		
		
	
	
			436 lines
		
	
	
		
			13 KiB
		
	
	
	
		
			Diff
		
	
	
	
	
	
From 1e264f9d2918b5737023c44a23ae04def1095210 Mon Sep 17 00:00:00 2001
 | 
						|
From: Christian Marangi <ansuelsmth@gmail.com>
 | 
						|
Date: Mon, 17 Apr 2023 17:17:24 +0200
 | 
						|
Subject: [PATCH 2/9] net: dsa: qca8k: add LEDs basic support
 | 
						|
 | 
						|
Add LEDs basic support for qca8k Switch Family by adding basic
 | 
						|
brightness_set() support.
 | 
						|
 | 
						|
Since these LEDs refelect port status, the default label is set to
 | 
						|
":port". DT binding should describe the color and function of the
 | 
						|
LEDs using standard LEDs api.
 | 
						|
Each LED always have the device name as prefix. The device name is
 | 
						|
composed from the mii bus id and the PHY addr resulting in example
 | 
						|
names like:
 | 
						|
- qca8k-0.0:00:amber:lan
 | 
						|
- qca8k-0.0:00:white:lan
 | 
						|
- qca8k-0.0:01:amber:lan
 | 
						|
- qca8k-0.0:01:white:lan
 | 
						|
 | 
						|
These LEDs supports only blocking variant of the brightness_set()
 | 
						|
function since they can sleep during access of the switch leds to set
 | 
						|
the brightness.
 | 
						|
 | 
						|
While at it add to the qca8k header file each mode defined by the Switch
 | 
						|
Documentation for future use.
 | 
						|
 | 
						|
Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
 | 
						|
Reviewed-by: Florian Fainelli <f.fainelli@gmail.com>
 | 
						|
Signed-off-by: David S. Miller <davem@davemloft.net>
 | 
						|
---
 | 
						|
 drivers/net/dsa/qca/Kconfig      |   8 ++
 | 
						|
 drivers/net/dsa/qca/Makefile     |   3 +
 | 
						|
 drivers/net/dsa/qca/qca8k-8xxx.c |   5 +
 | 
						|
 drivers/net/dsa/qca/qca8k-leds.c | 239 +++++++++++++++++++++++++++++++
 | 
						|
 drivers/net/dsa/qca/qca8k.h      |  60 ++++++++
 | 
						|
 drivers/net/dsa/qca/qca8k_leds.h |  16 +++
 | 
						|
 6 files changed, 331 insertions(+)
 | 
						|
 create mode 100644 drivers/net/dsa/qca/qca8k-leds.c
 | 
						|
 create mode 100644 drivers/net/dsa/qca/qca8k_leds.h
 | 
						|
 | 
						|
--- a/drivers/net/dsa/qca/Kconfig
 | 
						|
+++ b/drivers/net/dsa/qca/Kconfig
 | 
						|
@@ -15,3 +15,11 @@ config NET_DSA_QCA8K
 | 
						|
 	help
 | 
						|
 	  This enables support for the Qualcomm Atheros QCA8K Ethernet
 | 
						|
 	  switch chips.
 | 
						|
+
 | 
						|
+config NET_DSA_QCA8K_LEDS_SUPPORT
 | 
						|
+	bool "Qualcomm Atheros QCA8K Ethernet switch family LEDs support"
 | 
						|
+	depends on NET_DSA_QCA8K
 | 
						|
+	depends on LEDS_CLASS
 | 
						|
+	help
 | 
						|
+	  This enabled support for LEDs present on the Qualcomm Atheros
 | 
						|
+	  QCA8K Ethernet switch chips.
 | 
						|
--- a/drivers/net/dsa/qca/Makefile
 | 
						|
+++ b/drivers/net/dsa/qca/Makefile
 | 
						|
@@ -2,3 +2,6 @@
 | 
						|
 obj-$(CONFIG_NET_DSA_AR9331)	+= ar9331.o
 | 
						|
 obj-$(CONFIG_NET_DSA_QCA8K)	+= qca8k.o
 | 
						|
 qca8k-y 			+= qca8k-common.o qca8k-8xxx.o
 | 
						|
+ifdef CONFIG_NET_DSA_QCA8K_LEDS_SUPPORT
 | 
						|
+qca8k-y				+= qca8k-leds.o
 | 
						|
+endif
 | 
						|
--- a/drivers/net/dsa/qca/qca8k-8xxx.c
 | 
						|
+++ b/drivers/net/dsa/qca/qca8k-8xxx.c
 | 
						|
@@ -22,6 +22,7 @@
 | 
						|
 #include <linux/dsa/tag_qca.h>
 | 
						|
 
 | 
						|
 #include "qca8k.h"
 | 
						|
+#include "qca8k_leds.h"
 | 
						|
 
 | 
						|
 static void
 | 
						|
 qca8k_split_addr(u32 regaddr, u16 *r1, u16 *r2, u16 *page)
 | 
						|
@@ -1840,6 +1841,10 @@ qca8k_setup(struct dsa_switch *ds)
 | 
						|
 	if (ret)
 | 
						|
 		return ret;
 | 
						|
 
 | 
						|
+	ret = qca8k_setup_led_ctrl(priv);
 | 
						|
+	if (ret)
 | 
						|
+		return ret;
 | 
						|
+
 | 
						|
 	qca8k_setup_pcs(priv, &priv->pcs_port_0, 0);
 | 
						|
 	qca8k_setup_pcs(priv, &priv->pcs_port_6, 6);
 | 
						|
 
 | 
						|
--- /dev/null
 | 
						|
+++ b/drivers/net/dsa/qca/qca8k-leds.c
 | 
						|
@@ -0,0 +1,239 @@
 | 
						|
+// SPDX-License-Identifier: GPL-2.0
 | 
						|
+#include <linux/regmap.h>
 | 
						|
+#include <net/dsa.h>
 | 
						|
+
 | 
						|
+#include "qca8k.h"
 | 
						|
+#include "qca8k_leds.h"
 | 
						|
+
 | 
						|
+static int
 | 
						|
+qca8k_get_enable_led_reg(int port_num, int led_num, struct qca8k_led_pattern_en *reg_info)
 | 
						|
+{
 | 
						|
+	switch (port_num) {
 | 
						|
+	case 0:
 | 
						|
+		reg_info->reg = QCA8K_LED_CTRL_REG(led_num);
 | 
						|
+		reg_info->shift = QCA8K_LED_PHY0123_CONTROL_RULE_SHIFT;
 | 
						|
+		break;
 | 
						|
+	case 1:
 | 
						|
+	case 2:
 | 
						|
+	case 3:
 | 
						|
+		/* Port 123 are controlled on a different reg */
 | 
						|
+		reg_info->reg = QCA8K_LED_CTRL3_REG;
 | 
						|
+		reg_info->shift = QCA8K_LED_PHY123_PATTERN_EN_SHIFT(port_num, led_num);
 | 
						|
+		break;
 | 
						|
+	case 4:
 | 
						|
+		reg_info->reg = QCA8K_LED_CTRL_REG(led_num);
 | 
						|
+		reg_info->shift = QCA8K_LED_PHY4_CONTROL_RULE_SHIFT;
 | 
						|
+		break;
 | 
						|
+	default:
 | 
						|
+		return -EINVAL;
 | 
						|
+	}
 | 
						|
+
 | 
						|
+	return 0;
 | 
						|
+}
 | 
						|
+
 | 
						|
+static int
 | 
						|
+qca8k_led_brightness_set(struct qca8k_led *led,
 | 
						|
+			 enum led_brightness brightness)
 | 
						|
+{
 | 
						|
+	struct qca8k_led_pattern_en reg_info;
 | 
						|
+	struct qca8k_priv *priv = led->priv;
 | 
						|
+	u32 mask, val;
 | 
						|
+
 | 
						|
+	qca8k_get_enable_led_reg(led->port_num, led->led_num, ®_info);
 | 
						|
+
 | 
						|
+	val = QCA8K_LED_ALWAYS_OFF;
 | 
						|
+	if (brightness)
 | 
						|
+		val = QCA8K_LED_ALWAYS_ON;
 | 
						|
+
 | 
						|
+	/* HW regs to control brightness is special and port 1-2-3
 | 
						|
+	 * are placed in a different reg.
 | 
						|
+	 *
 | 
						|
+	 * To control port 0 brightness:
 | 
						|
+	 * - the 2 bit (15, 14) of:
 | 
						|
+	 *   - QCA8K_LED_CTRL0_REG for led1
 | 
						|
+	 *   - QCA8K_LED_CTRL1_REG for led2
 | 
						|
+	 *   - QCA8K_LED_CTRL2_REG for led3
 | 
						|
+	 *
 | 
						|
+	 * To control port 4:
 | 
						|
+	 * - the 2 bit (31, 30) of:
 | 
						|
+	 *   - QCA8K_LED_CTRL0_REG for led1
 | 
						|
+	 *   - QCA8K_LED_CTRL1_REG for led2
 | 
						|
+	 *   - QCA8K_LED_CTRL2_REG for led3
 | 
						|
+	 *
 | 
						|
+	 * To control port 1:
 | 
						|
+	 *   - the 2 bit at (9, 8) of QCA8K_LED_CTRL3_REG are used for led1
 | 
						|
+	 *   - the 2 bit at (11, 10) of QCA8K_LED_CTRL3_REG are used for led2
 | 
						|
+	 *   - the 2 bit at (13, 12) of QCA8K_LED_CTRL3_REG are used for led3
 | 
						|
+	 *
 | 
						|
+	 * To control port 2:
 | 
						|
+	 *   - the 2 bit at (15, 14) of QCA8K_LED_CTRL3_REG are used for led1
 | 
						|
+	 *   - the 2 bit at (17, 16) of QCA8K_LED_CTRL3_REG are used for led2
 | 
						|
+	 *   - the 2 bit at (19, 18) of QCA8K_LED_CTRL3_REG are used for led3
 | 
						|
+	 *
 | 
						|
+	 * To control port 3:
 | 
						|
+	 *   - the 2 bit at (21, 20) of QCA8K_LED_CTRL3_REG are used for led1
 | 
						|
+	 *   - the 2 bit at (23, 22) of QCA8K_LED_CTRL3_REG are used for led2
 | 
						|
+	 *   - the 2 bit at (25, 24) of QCA8K_LED_CTRL3_REG are used for led3
 | 
						|
+	 *
 | 
						|
+	 * To abstract this and have less code, we use the port and led numm
 | 
						|
+	 * to calculate the shift and the correct reg due to this problem of
 | 
						|
+	 * not having a 1:1 map of LED with the regs.
 | 
						|
+	 */
 | 
						|
+	if (led->port_num == 0 || led->port_num == 4) {
 | 
						|
+		mask = QCA8K_LED_PATTERN_EN_MASK;
 | 
						|
+		val <<= QCA8K_LED_PATTERN_EN_SHIFT;
 | 
						|
+	} else {
 | 
						|
+		mask = QCA8K_LED_PHY123_PATTERN_EN_MASK;
 | 
						|
+	}
 | 
						|
+
 | 
						|
+	return regmap_update_bits(priv->regmap, reg_info.reg,
 | 
						|
+				  mask << reg_info.shift,
 | 
						|
+				  val << reg_info.shift);
 | 
						|
+}
 | 
						|
+
 | 
						|
+static int
 | 
						|
+qca8k_cled_brightness_set_blocking(struct led_classdev *ldev,
 | 
						|
+				   enum led_brightness brightness)
 | 
						|
+{
 | 
						|
+	struct qca8k_led *led = container_of(ldev, struct qca8k_led, cdev);
 | 
						|
+
 | 
						|
+	return qca8k_led_brightness_set(led, brightness);
 | 
						|
+}
 | 
						|
+
 | 
						|
+static enum led_brightness
 | 
						|
+qca8k_led_brightness_get(struct qca8k_led *led)
 | 
						|
+{
 | 
						|
+	struct qca8k_led_pattern_en reg_info;
 | 
						|
+	struct qca8k_priv *priv = led->priv;
 | 
						|
+	u32 val;
 | 
						|
+	int ret;
 | 
						|
+
 | 
						|
+	qca8k_get_enable_led_reg(led->port_num, led->led_num, ®_info);
 | 
						|
+
 | 
						|
+	ret = regmap_read(priv->regmap, reg_info.reg, &val);
 | 
						|
+	if (ret)
 | 
						|
+		return 0;
 | 
						|
+
 | 
						|
+	val >>= reg_info.shift;
 | 
						|
+
 | 
						|
+	if (led->port_num == 0 || led->port_num == 4) {
 | 
						|
+		val &= QCA8K_LED_PATTERN_EN_MASK;
 | 
						|
+		val >>= QCA8K_LED_PATTERN_EN_SHIFT;
 | 
						|
+	} else {
 | 
						|
+		val &= QCA8K_LED_PHY123_PATTERN_EN_MASK;
 | 
						|
+	}
 | 
						|
+
 | 
						|
+	/* Assume brightness ON only when the LED is set to always ON */
 | 
						|
+	return val == QCA8K_LED_ALWAYS_ON;
 | 
						|
+}
 | 
						|
+
 | 
						|
+static int
 | 
						|
+qca8k_parse_port_leds(struct qca8k_priv *priv, struct fwnode_handle *port, int port_num)
 | 
						|
+{
 | 
						|
+	struct fwnode_handle *led = NULL, *leds = NULL;
 | 
						|
+	struct led_init_data init_data = { };
 | 
						|
+	struct dsa_switch *ds = priv->ds;
 | 
						|
+	enum led_default_state state;
 | 
						|
+	struct qca8k_led *port_led;
 | 
						|
+	int led_num, led_index;
 | 
						|
+	int ret;
 | 
						|
+
 | 
						|
+	leds = fwnode_get_named_child_node(port, "leds");
 | 
						|
+	if (!leds) {
 | 
						|
+		dev_dbg(priv->dev, "No Leds node specified in device tree for port %d!\n",
 | 
						|
+			port_num);
 | 
						|
+		return 0;
 | 
						|
+	}
 | 
						|
+
 | 
						|
+	fwnode_for_each_child_node(leds, led) {
 | 
						|
+		/* Reg represent the led number of the port.
 | 
						|
+		 * Each port can have at most 3 leds attached
 | 
						|
+		 * Commonly:
 | 
						|
+		 * 1. is gigabit led
 | 
						|
+		 * 2. is mbit led
 | 
						|
+		 * 3. additional status led
 | 
						|
+		 */
 | 
						|
+		if (fwnode_property_read_u32(led, "reg", &led_num))
 | 
						|
+			continue;
 | 
						|
+
 | 
						|
+		if (led_num >= QCA8K_LED_PORT_COUNT) {
 | 
						|
+			dev_warn(priv->dev, "Invalid LED reg %d defined for port %d",
 | 
						|
+				 led_num, port_num);
 | 
						|
+			continue;
 | 
						|
+		}
 | 
						|
+
 | 
						|
+		led_index = QCA8K_LED_PORT_INDEX(port_num, led_num);
 | 
						|
+
 | 
						|
+		port_led = &priv->ports_led[led_index];
 | 
						|
+		port_led->port_num = port_num;
 | 
						|
+		port_led->led_num = led_num;
 | 
						|
+		port_led->priv = priv;
 | 
						|
+
 | 
						|
+		state = led_init_default_state_get(led);
 | 
						|
+		switch (state) {
 | 
						|
+		case LEDS_DEFSTATE_ON:
 | 
						|
+			port_led->cdev.brightness = 1;
 | 
						|
+			qca8k_led_brightness_set(port_led, 1);
 | 
						|
+			break;
 | 
						|
+		case LEDS_DEFSTATE_KEEP:
 | 
						|
+			port_led->cdev.brightness =
 | 
						|
+					qca8k_led_brightness_get(port_led);
 | 
						|
+			break;
 | 
						|
+		default:
 | 
						|
+			port_led->cdev.brightness = 0;
 | 
						|
+			qca8k_led_brightness_set(port_led, 0);
 | 
						|
+		}
 | 
						|
+
 | 
						|
+		port_led->cdev.max_brightness = 1;
 | 
						|
+		port_led->cdev.brightness_set_blocking = qca8k_cled_brightness_set_blocking;
 | 
						|
+		init_data.default_label = ":port";
 | 
						|
+		init_data.fwnode = led;
 | 
						|
+		init_data.devname_mandatory = true;
 | 
						|
+		init_data.devicename = kasprintf(GFP_KERNEL, "%s:0%d", ds->slave_mii_bus->id,
 | 
						|
+						 port_num);
 | 
						|
+		if (!init_data.devicename)
 | 
						|
+			return -ENOMEM;
 | 
						|
+
 | 
						|
+		ret = devm_led_classdev_register_ext(priv->dev, &port_led->cdev, &init_data);
 | 
						|
+		if (ret)
 | 
						|
+			dev_warn(priv->dev, "Failed to init LED %d for port %d", led_num, port_num);
 | 
						|
+
 | 
						|
+		kfree(init_data.devicename);
 | 
						|
+	}
 | 
						|
+
 | 
						|
+	return 0;
 | 
						|
+}
 | 
						|
+
 | 
						|
+int
 | 
						|
+qca8k_setup_led_ctrl(struct qca8k_priv *priv)
 | 
						|
+{
 | 
						|
+	struct fwnode_handle *ports, *port;
 | 
						|
+	int port_num;
 | 
						|
+	int ret;
 | 
						|
+
 | 
						|
+	ports = device_get_named_child_node(priv->dev, "ports");
 | 
						|
+	if (!ports) {
 | 
						|
+		dev_info(priv->dev, "No ports node specified in device tree!");
 | 
						|
+		return 0;
 | 
						|
+	}
 | 
						|
+
 | 
						|
+	fwnode_for_each_child_node(ports, port) {
 | 
						|
+		if (fwnode_property_read_u32(port, "reg", &port_num))
 | 
						|
+			continue;
 | 
						|
+
 | 
						|
+		/* Skip checking for CPU port 0 and CPU port 6 as not supported */
 | 
						|
+		if (port_num == 0 || port_num == 6)
 | 
						|
+			continue;
 | 
						|
+
 | 
						|
+		/* Each port can have at most 3 different leds attached.
 | 
						|
+		 * Switch port starts from 0 to 6, but port 0 and 6 are CPU
 | 
						|
+		 * port. The port index needs to be decreased by one to identify
 | 
						|
+		 * the correct port for LED setup.
 | 
						|
+		 */
 | 
						|
+		ret = qca8k_parse_port_leds(priv, port, qca8k_port_to_phy(port_num));
 | 
						|
+		if (ret)
 | 
						|
+			return ret;
 | 
						|
+	}
 | 
						|
+
 | 
						|
+	return 0;
 | 
						|
+}
 | 
						|
--- a/drivers/net/dsa/qca/qca8k.h
 | 
						|
+++ b/drivers/net/dsa/qca/qca8k.h
 | 
						|
@@ -11,6 +11,7 @@
 | 
						|
 #include <linux/delay.h>
 | 
						|
 #include <linux/regmap.h>
 | 
						|
 #include <linux/gpio.h>
 | 
						|
+#include <linux/leds.h>
 | 
						|
 #include <linux/dsa/tag_qca.h>
 | 
						|
 
 | 
						|
 #define QCA8K_ETHERNET_MDIO_PRIORITY			7
 | 
						|
@@ -85,6 +86,51 @@
 | 
						|
 #define   QCA8K_MDIO_MASTER_DATA(x)			FIELD_PREP(QCA8K_MDIO_MASTER_DATA_MASK, x)
 | 
						|
 #define   QCA8K_MDIO_MASTER_MAX_PORTS			5
 | 
						|
 #define   QCA8K_MDIO_MASTER_MAX_REG			32
 | 
						|
+
 | 
						|
+/* LED control register */
 | 
						|
+#define QCA8K_LED_PORT_COUNT				3
 | 
						|
+#define QCA8K_LED_COUNT					((QCA8K_NUM_PORTS - QCA8K_NUM_CPU_PORTS) * QCA8K_LED_PORT_COUNT)
 | 
						|
+#define QCA8K_LED_RULE_COUNT				6
 | 
						|
+#define QCA8K_LED_RULE_MAX				11
 | 
						|
+#define QCA8K_LED_PORT_INDEX(_phy, _led)		(((_phy) * QCA8K_LED_PORT_COUNT) + (_led))
 | 
						|
+
 | 
						|
+#define QCA8K_LED_PHY123_PATTERN_EN_SHIFT(_phy, _led)	((((_phy) - 1) * 6) + 8 + (2 * (_led)))
 | 
						|
+#define QCA8K_LED_PHY123_PATTERN_EN_MASK		GENMASK(1, 0)
 | 
						|
+
 | 
						|
+#define QCA8K_LED_PHY0123_CONTROL_RULE_SHIFT		0
 | 
						|
+#define QCA8K_LED_PHY4_CONTROL_RULE_SHIFT		16
 | 
						|
+
 | 
						|
+#define QCA8K_LED_CTRL_REG(_i)				(0x050 + (_i) * 4)
 | 
						|
+#define QCA8K_LED_CTRL0_REG				0x50
 | 
						|
+#define QCA8K_LED_CTRL1_REG				0x54
 | 
						|
+#define QCA8K_LED_CTRL2_REG				0x58
 | 
						|
+#define QCA8K_LED_CTRL3_REG				0x5C
 | 
						|
+#define   QCA8K_LED_CTRL_SHIFT(_i)			(((_i) % 2) * 16)
 | 
						|
+#define   QCA8K_LED_CTRL_MASK				GENMASK(15, 0)
 | 
						|
+#define QCA8K_LED_RULE_MASK				GENMASK(13, 0)
 | 
						|
+#define QCA8K_LED_BLINK_FREQ_MASK			GENMASK(1, 0)
 | 
						|
+#define QCA8K_LED_BLINK_FREQ_SHITF			0
 | 
						|
+#define   QCA8K_LED_BLINK_2HZ				0
 | 
						|
+#define   QCA8K_LED_BLINK_4HZ				1
 | 
						|
+#define   QCA8K_LED_BLINK_8HZ				2
 | 
						|
+#define   QCA8K_LED_BLINK_AUTO				3
 | 
						|
+#define QCA8K_LED_LINKUP_OVER_MASK			BIT(2)
 | 
						|
+#define QCA8K_LED_TX_BLINK_MASK				BIT(4)
 | 
						|
+#define QCA8K_LED_RX_BLINK_MASK				BIT(5)
 | 
						|
+#define QCA8K_LED_COL_BLINK_MASK			BIT(7)
 | 
						|
+#define QCA8K_LED_LINK_10M_EN_MASK			BIT(8)
 | 
						|
+#define QCA8K_LED_LINK_100M_EN_MASK			BIT(9)
 | 
						|
+#define QCA8K_LED_LINK_1000M_EN_MASK			BIT(10)
 | 
						|
+#define QCA8K_LED_POWER_ON_LIGHT_MASK			BIT(11)
 | 
						|
+#define QCA8K_LED_HALF_DUPLEX_MASK			BIT(12)
 | 
						|
+#define QCA8K_LED_FULL_DUPLEX_MASK			BIT(13)
 | 
						|
+#define QCA8K_LED_PATTERN_EN_MASK			GENMASK(15, 14)
 | 
						|
+#define QCA8K_LED_PATTERN_EN_SHIFT			14
 | 
						|
+#define   QCA8K_LED_ALWAYS_OFF				0
 | 
						|
+#define   QCA8K_LED_ALWAYS_BLINK_4HZ			1
 | 
						|
+#define   QCA8K_LED_ALWAYS_ON				2
 | 
						|
+#define   QCA8K_LED_RULE_CONTROLLED			3
 | 
						|
+
 | 
						|
 #define QCA8K_GOL_MAC_ADDR0				0x60
 | 
						|
 #define QCA8K_GOL_MAC_ADDR1				0x64
 | 
						|
 #define QCA8K_MAX_FRAME_SIZE				0x78
 | 
						|
@@ -382,6 +428,19 @@ struct qca8k_pcs {
 | 
						|
 	int port;
 | 
						|
 };
 | 
						|
 
 | 
						|
+struct qca8k_led_pattern_en {
 | 
						|
+	u32 reg;
 | 
						|
+	u8 shift;
 | 
						|
+};
 | 
						|
+
 | 
						|
+struct qca8k_led {
 | 
						|
+	u8 port_num;
 | 
						|
+	u8 led_num;
 | 
						|
+	u16 old_rule;
 | 
						|
+	struct qca8k_priv *priv;
 | 
						|
+	struct led_classdev cdev;
 | 
						|
+};
 | 
						|
+
 | 
						|
 struct qca8k_priv {
 | 
						|
 	u8 switch_id;
 | 
						|
 	u8 switch_revision;
 | 
						|
@@ -406,6 +465,7 @@ struct qca8k_priv {
 | 
						|
 	struct qca8k_pcs pcs_port_0;
 | 
						|
 	struct qca8k_pcs pcs_port_6;
 | 
						|
 	const struct qca8k_match_data *info;
 | 
						|
+	struct qca8k_led ports_led[QCA8K_LED_COUNT];
 | 
						|
 };
 | 
						|
 
 | 
						|
 struct qca8k_mib_desc {
 | 
						|
--- /dev/null
 | 
						|
+++ b/drivers/net/dsa/qca/qca8k_leds.h
 | 
						|
@@ -0,0 +1,16 @@
 | 
						|
+/* SPDX-License-Identifier: GPL-2.0-only */
 | 
						|
+
 | 
						|
+#ifndef __QCA8K_LEDS_H
 | 
						|
+#define __QCA8K_LEDS_H
 | 
						|
+
 | 
						|
+/* Leds Support function */
 | 
						|
+#ifdef CONFIG_NET_DSA_QCA8K_LEDS_SUPPORT
 | 
						|
+int qca8k_setup_led_ctrl(struct qca8k_priv *priv);
 | 
						|
+#else
 | 
						|
+static inline int qca8k_setup_led_ctrl(struct qca8k_priv *priv)
 | 
						|
+{
 | 
						|
+	return 0;
 | 
						|
+}
 | 
						|
+#endif
 | 
						|
+
 | 
						|
+#endif /* __QCA8K_LEDS_H */
 |