Commit f15176b8 authored by Linus Walleij's avatar Linus Walleij Committed by David S. Miller
Browse files

net: dsa: rtl8366rb: Fix compilation problem



When the kernel is compiled without LED framework support the
rtl8366rb fails to build like this:

rtl8366rb.o: in function `rtl8366rb_setup_led':
rtl8366rb.c:953:(.text.unlikely.rtl8366rb_setup_led+0xe8):
  undefined reference to `led_init_default_state_get'
rtl8366rb.c:980:(.text.unlikely.rtl8366rb_setup_led+0x240):
  undefined reference to `devm_led_classdev_register_ext'

As this is constantly coming up in different randconfig builds,
bite the bullet and create a separate file for the offending
code, split out a header with all stuff needed both in the
core driver and the leds code.

Add a new bool Kconfig option for the LED compile target, such
that it depends on LEDS_CLASS=y || LEDS_CLASS=RTL8366RB
which make LED support always available when LEDS_CLASS is
compiled into the kernel and enforce that if the LEDS_CLASS
is a module, then the RTL8366RB driver needs to be a module
as well so that modprobe can resolve the dependencies.

Fixes: 32d61700 ("net: dsa: realtek: add LED drivers for rtl8366rb")
Reported-by: default avatarkernel test robot <lkp@intel.com>
Closes: https://lore.kernel.org/oe-kbuild-all/202502070525.xMUImayb-lkp@intel.com/


Signed-off-by: default avatarLinus Walleij <linus.walleij@linaro.org>
Reviewed-by: default avatarVladimir Oltean <olteanv@gmail.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 28b04731
Loading
Loading
Loading
Loading
+6 −0
Original line number Diff line number Diff line
@@ -43,4 +43,10 @@ config NET_DSA_REALTEK_RTL8366RB
	help
	  Select to enable support for Realtek RTL8366RB.

config NET_DSA_REALTEK_RTL8366RB_LEDS
	bool "Support RTL8366RB LED control"
	depends on (LEDS_CLASS=y || LEDS_CLASS=NET_DSA_REALTEK_RTL8366RB)
	depends on NET_DSA_REALTEK_RTL8366RB
	default NET_DSA_REALTEK_RTL8366RB

endif
+3 −0
Original line number Diff line number Diff line
@@ -12,4 +12,7 @@ endif

obj-$(CONFIG_NET_DSA_REALTEK_RTL8366RB) += rtl8366.o
rtl8366-objs 				:= rtl8366-core.o rtl8366rb.o
ifdef CONFIG_NET_DSA_REALTEK_RTL8366RB_LEDS
rtl8366-objs 				+= rtl8366rb-leds.o
endif
obj-$(CONFIG_NET_DSA_REALTEK_RTL8365MB) += rtl8365mb.o
+177 −0
Original line number Diff line number Diff line
// SPDX-License-Identifier: GPL-2.0

#include <linux/bitops.h>
#include <linux/regmap.h>
#include <net/dsa.h>
#include "rtl83xx.h"
#include "rtl8366rb.h"

static inline u32 rtl8366rb_led_group_port_mask(u8 led_group, u8 port)
{
	switch (led_group) {
	case 0:
		return FIELD_PREP(RTL8366RB_LED_0_X_CTRL_MASK, BIT(port));
	case 1:
		return FIELD_PREP(RTL8366RB_LED_0_X_CTRL_MASK, BIT(port));
	case 2:
		return FIELD_PREP(RTL8366RB_LED_0_X_CTRL_MASK, BIT(port));
	case 3:
		return FIELD_PREP(RTL8366RB_LED_0_X_CTRL_MASK, BIT(port));
	default:
		return 0;
	}
}

static int rb8366rb_get_port_led(struct rtl8366rb_led *led)
{
	struct realtek_priv *priv = led->priv;
	u8 led_group = led->led_group;
	u8 port_num = led->port_num;
	int ret;
	u32 val;

	ret = regmap_read(priv->map, RTL8366RB_LED_X_X_CTRL_REG(led_group),
			  &val);
	if (ret) {
		dev_err(priv->dev, "error reading LED on port %d group %d\n",
			led_group, port_num);
		return ret;
	}

	return !!(val & rtl8366rb_led_group_port_mask(led_group, port_num));
}

static int rb8366rb_set_port_led(struct rtl8366rb_led *led, bool enable)
{
	struct realtek_priv *priv = led->priv;
	u8 led_group = led->led_group;
	u8 port_num = led->port_num;
	int ret;

	ret = regmap_update_bits(priv->map,
				 RTL8366RB_LED_X_X_CTRL_REG(led_group),
				 rtl8366rb_led_group_port_mask(led_group,
							       port_num),
				 enable ? 0xffff : 0);
	if (ret) {
		dev_err(priv->dev, "error updating LED on port %d group %d\n",
			led_group, port_num);
		return ret;
	}

	/* Change the LED group to manual controlled LEDs if required */
	ret = rb8366rb_set_ledgroup_mode(priv, led_group,
					 RTL8366RB_LEDGROUP_FORCE);

	if (ret) {
		dev_err(priv->dev, "error updating LED GROUP group %d\n",
			led_group);
		return ret;
	}

	return 0;
}

static int
rtl8366rb_cled_brightness_set_blocking(struct led_classdev *ldev,
				       enum led_brightness brightness)
{
	struct rtl8366rb_led *led = container_of(ldev, struct rtl8366rb_led,
						 cdev);

	return rb8366rb_set_port_led(led, brightness == LED_ON);
}

static int rtl8366rb_setup_led(struct realtek_priv *priv, struct dsa_port *dp,
			       struct fwnode_handle *led_fwnode)
{
	struct rtl8366rb *rb = priv->chip_data;
	struct led_init_data init_data = { };
	enum led_default_state state;
	struct rtl8366rb_led *led;
	u32 led_group;
	int ret;

	ret = fwnode_property_read_u32(led_fwnode, "reg", &led_group);
	if (ret)
		return ret;

	if (led_group >= RTL8366RB_NUM_LEDGROUPS) {
		dev_warn(priv->dev, "Invalid LED reg %d defined for port %d",
			 led_group, dp->index);
		return -EINVAL;
	}

	led = &rb->leds[dp->index][led_group];
	led->port_num = dp->index;
	led->led_group = led_group;
	led->priv = priv;

	state = led_init_default_state_get(led_fwnode);
	switch (state) {
	case LEDS_DEFSTATE_ON:
		led->cdev.brightness = 1;
		rb8366rb_set_port_led(led, 1);
		break;
	case LEDS_DEFSTATE_KEEP:
		led->cdev.brightness =
			rb8366rb_get_port_led(led);
		break;
	case LEDS_DEFSTATE_OFF:
	default:
		led->cdev.brightness = 0;
		rb8366rb_set_port_led(led, 0);
	}

	led->cdev.max_brightness = 1;
	led->cdev.brightness_set_blocking =
		rtl8366rb_cled_brightness_set_blocking;
	init_data.fwnode = led_fwnode;
	init_data.devname_mandatory = true;

	init_data.devicename = kasprintf(GFP_KERNEL, "Realtek-%d:0%d:%d",
					 dp->ds->index, dp->index, led_group);
	if (!init_data.devicename)
		return -ENOMEM;

	ret = devm_led_classdev_register_ext(priv->dev, &led->cdev, &init_data);
	if (ret) {
		dev_warn(priv->dev, "Failed to init LED %d for port %d",
			 led_group, dp->index);
		return ret;
	}

	return 0;
}

int rtl8366rb_setup_leds(struct realtek_priv *priv)
{
	struct dsa_switch *ds = &priv->ds;
	struct device_node *leds_np;
	struct dsa_port *dp;
	int ret = 0;

	dsa_switch_for_each_port(dp, ds) {
		if (!dp->dn)
			continue;

		leds_np = of_get_child_by_name(dp->dn, "leds");
		if (!leds_np) {
			dev_dbg(priv->dev, "No leds defined for port %d",
				dp->index);
			continue;
		}

		for_each_child_of_node_scoped(leds_np, led_np) {
			ret = rtl8366rb_setup_led(priv, dp,
						  of_fwnode_handle(led_np));
			if (ret)
				break;
		}

		of_node_put(leds_np);
		if (ret)
			return ret;
	}
	return 0;
}
+6 −252
Original line number Diff line number Diff line
@@ -27,11 +27,7 @@
#include "realtek-smi.h"
#include "realtek-mdio.h"
#include "rtl83xx.h"

#define RTL8366RB_PORT_NUM_CPU		5
#define RTL8366RB_NUM_PORTS		6
#define RTL8366RB_PHY_NO_MAX		4
#define RTL8366RB_PHY_ADDR_MAX		31
#include "rtl8366rb.h"

/* Switch Global Configuration register */
#define RTL8366RB_SGCR				0x0000
@@ -176,39 +172,6 @@
 */
#define RTL8366RB_VLAN_INGRESS_CTRL2_REG	0x037f

/* LED control registers */
/* The LED blink rate is global; it is used by all triggers in all groups. */
#define RTL8366RB_LED_BLINKRATE_REG		0x0430
#define RTL8366RB_LED_BLINKRATE_MASK		0x0007
#define RTL8366RB_LED_BLINKRATE_28MS		0x0000
#define RTL8366RB_LED_BLINKRATE_56MS		0x0001
#define RTL8366RB_LED_BLINKRATE_84MS		0x0002
#define RTL8366RB_LED_BLINKRATE_111MS		0x0003
#define RTL8366RB_LED_BLINKRATE_222MS		0x0004
#define RTL8366RB_LED_BLINKRATE_446MS		0x0005

/* LED trigger event for each group */
#define RTL8366RB_LED_CTRL_REG			0x0431
#define RTL8366RB_LED_CTRL_OFFSET(led_group)	\
	(4 * (led_group))
#define RTL8366RB_LED_CTRL_MASK(led_group)	\
	(0xf << RTL8366RB_LED_CTRL_OFFSET(led_group))

/* The RTL8366RB_LED_X_X registers are used to manually set the LED state only
 * when the corresponding LED group in RTL8366RB_LED_CTRL_REG is
 * RTL8366RB_LEDGROUP_FORCE. Otherwise, it is ignored.
 */
#define RTL8366RB_LED_0_1_CTRL_REG		0x0432
#define RTL8366RB_LED_2_3_CTRL_REG		0x0433
#define RTL8366RB_LED_X_X_CTRL_REG(led_group)	\
	((led_group) <= 1 ? \
		RTL8366RB_LED_0_1_CTRL_REG : \
		RTL8366RB_LED_2_3_CTRL_REG)
#define RTL8366RB_LED_0_X_CTRL_MASK		GENMASK(5, 0)
#define RTL8366RB_LED_X_1_CTRL_MASK		GENMASK(11, 6)
#define RTL8366RB_LED_2_X_CTRL_MASK		GENMASK(5, 0)
#define RTL8366RB_LED_X_3_CTRL_MASK		GENMASK(11, 6)

#define RTL8366RB_MIB_COUNT			33
#define RTL8366RB_GLOBAL_MIB_COUNT		1
#define RTL8366RB_MIB_COUNTER_PORT_OFFSET	0x0050
@@ -244,7 +207,6 @@
#define RTL8366RB_PORT_STATUS_AN_MASK		0x0080

#define RTL8366RB_NUM_VLANS		16
#define RTL8366RB_NUM_LEDGROUPS		4
#define RTL8366RB_NUM_VIDS		4096
#define RTL8366RB_PRIORITYMAX		7
#define RTL8366RB_NUM_FIDS		8
@@ -351,46 +313,6 @@
#define RTL8366RB_GREEN_FEATURE_TX	BIT(0)
#define RTL8366RB_GREEN_FEATURE_RX	BIT(2)

enum rtl8366_ledgroup_mode {
	RTL8366RB_LEDGROUP_OFF			= 0x0,
	RTL8366RB_LEDGROUP_DUP_COL		= 0x1,
	RTL8366RB_LEDGROUP_LINK_ACT		= 0x2,
	RTL8366RB_LEDGROUP_SPD1000		= 0x3,
	RTL8366RB_LEDGROUP_SPD100		= 0x4,
	RTL8366RB_LEDGROUP_SPD10		= 0x5,
	RTL8366RB_LEDGROUP_SPD1000_ACT		= 0x6,
	RTL8366RB_LEDGROUP_SPD100_ACT		= 0x7,
	RTL8366RB_LEDGROUP_SPD10_ACT		= 0x8,
	RTL8366RB_LEDGROUP_SPD100_10_ACT	= 0x9,
	RTL8366RB_LEDGROUP_FIBER		= 0xa,
	RTL8366RB_LEDGROUP_AN_FAULT		= 0xb,
	RTL8366RB_LEDGROUP_LINK_RX		= 0xc,
	RTL8366RB_LEDGROUP_LINK_TX		= 0xd,
	RTL8366RB_LEDGROUP_MASTER		= 0xe,
	RTL8366RB_LEDGROUP_FORCE		= 0xf,

	__RTL8366RB_LEDGROUP_MODE_MAX
};

struct rtl8366rb_led {
	u8 port_num;
	u8 led_group;
	struct realtek_priv *priv;
	struct led_classdev cdev;
};

/**
 * struct rtl8366rb - RTL8366RB-specific data
 * @max_mtu: per-port max MTU setting
 * @pvid_enabled: if PVID is set for respective port
 * @leds: per-port and per-ledgroup led info
 */
struct rtl8366rb {
	unsigned int max_mtu[RTL8366RB_NUM_PORTS];
	bool pvid_enabled[RTL8366RB_NUM_PORTS];
	struct rtl8366rb_led leds[RTL8366RB_NUM_PORTS][RTL8366RB_NUM_LEDGROUPS];
};

static struct rtl8366_mib_counter rtl8366rb_mib_counters[] = {
	{ 0,  0, 4, "IfInOctets"				},
	{ 0,  4, 4, "EtherStatsOctets"				},
@@ -831,7 +753,8 @@ static int rtl8366rb_jam_table(const struct rtl8366rb_jam_tbl_entry *jam_table,
	return 0;
}

static int rb8366rb_set_ledgroup_mode(struct realtek_priv *priv,
/* This code is used also with LEDs disabled */
int rb8366rb_set_ledgroup_mode(struct realtek_priv *priv,
			       u8 led_group,
			       enum rtl8366_ledgroup_mode mode)
{
@@ -850,144 +773,7 @@ static int rb8366rb_set_ledgroup_mode(struct realtek_priv *priv,
	return 0;
}

static inline u32 rtl8366rb_led_group_port_mask(u8 led_group, u8 port)
{
	switch (led_group) {
	case 0:
		return FIELD_PREP(RTL8366RB_LED_0_X_CTRL_MASK, BIT(port));
	case 1:
		return FIELD_PREP(RTL8366RB_LED_0_X_CTRL_MASK, BIT(port));
	case 2:
		return FIELD_PREP(RTL8366RB_LED_0_X_CTRL_MASK, BIT(port));
	case 3:
		return FIELD_PREP(RTL8366RB_LED_0_X_CTRL_MASK, BIT(port));
	default:
		return 0;
	}
}

static int rb8366rb_get_port_led(struct rtl8366rb_led *led)
{
	struct realtek_priv *priv = led->priv;
	u8 led_group = led->led_group;
	u8 port_num = led->port_num;
	int ret;
	u32 val;

	ret = regmap_read(priv->map, RTL8366RB_LED_X_X_CTRL_REG(led_group),
			  &val);
	if (ret) {
		dev_err(priv->dev, "error reading LED on port %d group %d\n",
			led_group, port_num);
		return ret;
	}

	return !!(val & rtl8366rb_led_group_port_mask(led_group, port_num));
}

static int rb8366rb_set_port_led(struct rtl8366rb_led *led, bool enable)
{
	struct realtek_priv *priv = led->priv;
	u8 led_group = led->led_group;
	u8 port_num = led->port_num;
	int ret;

	ret = regmap_update_bits(priv->map,
				 RTL8366RB_LED_X_X_CTRL_REG(led_group),
				 rtl8366rb_led_group_port_mask(led_group,
							       port_num),
				 enable ? 0xffff : 0);
	if (ret) {
		dev_err(priv->dev, "error updating LED on port %d group %d\n",
			led_group, port_num);
		return ret;
	}

	/* Change the LED group to manual controlled LEDs if required */
	ret = rb8366rb_set_ledgroup_mode(priv, led_group,
					 RTL8366RB_LEDGROUP_FORCE);

	if (ret) {
		dev_err(priv->dev, "error updating LED GROUP group %d\n",
			led_group);
		return ret;
	}

	return 0;
}

static int
rtl8366rb_cled_brightness_set_blocking(struct led_classdev *ldev,
				       enum led_brightness brightness)
{
	struct rtl8366rb_led *led = container_of(ldev, struct rtl8366rb_led,
						 cdev);

	return rb8366rb_set_port_led(led, brightness == LED_ON);
}

static int rtl8366rb_setup_led(struct realtek_priv *priv, struct dsa_port *dp,
			       struct fwnode_handle *led_fwnode)
{
	struct rtl8366rb *rb = priv->chip_data;
	struct led_init_data init_data = { };
	enum led_default_state state;
	struct rtl8366rb_led *led;
	u32 led_group;
	int ret;

	ret = fwnode_property_read_u32(led_fwnode, "reg", &led_group);
	if (ret)
		return ret;

	if (led_group >= RTL8366RB_NUM_LEDGROUPS) {
		dev_warn(priv->dev, "Invalid LED reg %d defined for port %d",
			 led_group, dp->index);
		return -EINVAL;
	}

	led = &rb->leds[dp->index][led_group];
	led->port_num = dp->index;
	led->led_group = led_group;
	led->priv = priv;

	state = led_init_default_state_get(led_fwnode);
	switch (state) {
	case LEDS_DEFSTATE_ON:
		led->cdev.brightness = 1;
		rb8366rb_set_port_led(led, 1);
		break;
	case LEDS_DEFSTATE_KEEP:
		led->cdev.brightness =
			rb8366rb_get_port_led(led);
		break;
	case LEDS_DEFSTATE_OFF:
	default:
		led->cdev.brightness = 0;
		rb8366rb_set_port_led(led, 0);
	}

	led->cdev.max_brightness = 1;
	led->cdev.brightness_set_blocking =
		rtl8366rb_cled_brightness_set_blocking;
	init_data.fwnode = led_fwnode;
	init_data.devname_mandatory = true;

	init_data.devicename = kasprintf(GFP_KERNEL, "Realtek-%d:0%d:%d",
					 dp->ds->index, dp->index, led_group);
	if (!init_data.devicename)
		return -ENOMEM;

	ret = devm_led_classdev_register_ext(priv->dev, &led->cdev, &init_data);
	if (ret) {
		dev_warn(priv->dev, "Failed to init LED %d for port %d",
			 led_group, dp->index);
		return ret;
	}

	return 0;
}

/* This code is used also with LEDs disabled */
static int rtl8366rb_setup_all_leds_off(struct realtek_priv *priv)
{
	int ret = 0;
@@ -1008,38 +794,6 @@ static int rtl8366rb_setup_all_leds_off(struct realtek_priv *priv)
	return ret;
}

static int rtl8366rb_setup_leds(struct realtek_priv *priv)
{
	struct dsa_switch *ds = &priv->ds;
	struct device_node *leds_np;
	struct dsa_port *dp;
	int ret = 0;

	dsa_switch_for_each_port(dp, ds) {
		if (!dp->dn)
			continue;

		leds_np = of_get_child_by_name(dp->dn, "leds");
		if (!leds_np) {
			dev_dbg(priv->dev, "No leds defined for port %d",
				dp->index);
			continue;
		}

		for_each_child_of_node_scoped(leds_np, led_np) {
			ret = rtl8366rb_setup_led(priv, dp,
						  of_fwnode_handle(led_np));
			if (ret)
				break;
		}

		of_node_put(leds_np);
		if (ret)
			return ret;
	}
	return 0;
}

static int rtl8366rb_setup(struct dsa_switch *ds)
{
	struct realtek_priv *priv = ds->priv;
+107 −0
Original line number Diff line number Diff line
/* SPDX-License-Identifier: GPL-2.0+ */

#ifndef _RTL8366RB_H
#define _RTL8366RB_H

#include "realtek.h"

#define RTL8366RB_PORT_NUM_CPU		5
#define RTL8366RB_NUM_PORTS		6
#define RTL8366RB_PHY_NO_MAX		4
#define RTL8366RB_NUM_LEDGROUPS		4
#define RTL8366RB_PHY_ADDR_MAX		31

/* LED control registers */
/* The LED blink rate is global; it is used by all triggers in all groups. */
#define RTL8366RB_LED_BLINKRATE_REG		0x0430
#define RTL8366RB_LED_BLINKRATE_MASK		0x0007
#define RTL8366RB_LED_BLINKRATE_28MS		0x0000
#define RTL8366RB_LED_BLINKRATE_56MS		0x0001
#define RTL8366RB_LED_BLINKRATE_84MS		0x0002
#define RTL8366RB_LED_BLINKRATE_111MS		0x0003
#define RTL8366RB_LED_BLINKRATE_222MS		0x0004
#define RTL8366RB_LED_BLINKRATE_446MS		0x0005

/* LED trigger event for each group */
#define RTL8366RB_LED_CTRL_REG			0x0431
#define RTL8366RB_LED_CTRL_OFFSET(led_group)	\
	(4 * (led_group))
#define RTL8366RB_LED_CTRL_MASK(led_group)	\
	(0xf << RTL8366RB_LED_CTRL_OFFSET(led_group))

/* The RTL8366RB_LED_X_X registers are used to manually set the LED state only
 * when the corresponding LED group in RTL8366RB_LED_CTRL_REG is
 * RTL8366RB_LEDGROUP_FORCE. Otherwise, it is ignored.
 */
#define RTL8366RB_LED_0_1_CTRL_REG		0x0432
#define RTL8366RB_LED_2_3_CTRL_REG		0x0433
#define RTL8366RB_LED_X_X_CTRL_REG(led_group)	\
	((led_group) <= 1 ? \
		RTL8366RB_LED_0_1_CTRL_REG : \
		RTL8366RB_LED_2_3_CTRL_REG)
#define RTL8366RB_LED_0_X_CTRL_MASK		GENMASK(5, 0)
#define RTL8366RB_LED_X_1_CTRL_MASK		GENMASK(11, 6)
#define RTL8366RB_LED_2_X_CTRL_MASK		GENMASK(5, 0)
#define RTL8366RB_LED_X_3_CTRL_MASK		GENMASK(11, 6)

enum rtl8366_ledgroup_mode {
	RTL8366RB_LEDGROUP_OFF			= 0x0,
	RTL8366RB_LEDGROUP_DUP_COL		= 0x1,
	RTL8366RB_LEDGROUP_LINK_ACT		= 0x2,
	RTL8366RB_LEDGROUP_SPD1000		= 0x3,
	RTL8366RB_LEDGROUP_SPD100		= 0x4,
	RTL8366RB_LEDGROUP_SPD10		= 0x5,
	RTL8366RB_LEDGROUP_SPD1000_ACT		= 0x6,
	RTL8366RB_LEDGROUP_SPD100_ACT		= 0x7,
	RTL8366RB_LEDGROUP_SPD10_ACT		= 0x8,
	RTL8366RB_LEDGROUP_SPD100_10_ACT	= 0x9,
	RTL8366RB_LEDGROUP_FIBER		= 0xa,
	RTL8366RB_LEDGROUP_AN_FAULT		= 0xb,
	RTL8366RB_LEDGROUP_LINK_RX		= 0xc,
	RTL8366RB_LEDGROUP_LINK_TX		= 0xd,
	RTL8366RB_LEDGROUP_MASTER		= 0xe,
	RTL8366RB_LEDGROUP_FORCE		= 0xf,

	__RTL8366RB_LEDGROUP_MODE_MAX
};

#if IS_ENABLED(CONFIG_NET_DSA_REALTEK_RTL8366RB_LEDS)

struct rtl8366rb_led {
	u8 port_num;
	u8 led_group;
	struct realtek_priv *priv;
	struct led_classdev cdev;
};

int rtl8366rb_setup_leds(struct realtek_priv *priv);

#else

static inline int rtl8366rb_setup_leds(struct realtek_priv *priv)
{
	return 0;
}

#endif /* IS_ENABLED(CONFIG_LEDS_CLASS) */

/**
 * struct rtl8366rb - RTL8366RB-specific data
 * @max_mtu: per-port max MTU setting
 * @pvid_enabled: if PVID is set for respective port
 * @leds: per-port and per-ledgroup led info
 */
struct rtl8366rb {
	unsigned int max_mtu[RTL8366RB_NUM_PORTS];
	bool pvid_enabled[RTL8366RB_NUM_PORTS];
#if IS_ENABLED(CONFIG_NET_DSA_REALTEK_RTL8366RB_LEDS)
	struct rtl8366rb_led leds[RTL8366RB_NUM_PORTS][RTL8366RB_NUM_LEDGROUPS];
#endif
};

/* This code is used also with LEDs disabled */
int rb8366rb_set_ledgroup_mode(struct realtek_priv *priv,
			       u8 led_group,
			       enum rtl8366_ledgroup_mode mode);

#endif /* _RTL8366RB_H */