mirror of
https://github.com/kernelkit/infix.git
synced 2026-07-22 01:13:00 +02:00
542 lines
16 KiB
Diff
542 lines
16 KiB
Diff
From d42f3887e25aa770c0dd7d722f0410a926a943ae Mon Sep 17 00:00:00 2001
|
|
From: Mattias Walström <lazzer@gmail.com>
|
|
Date: Wed, 14 Jan 2026 18:22:41 +0100
|
|
Subject: [PATCH 28/50] net: dsa: mv88e6xxx: Add LED support for 6393X
|
|
|
|
Original commit:
|
|
commit 462277b926140ee2d231317e92afb6cabf640268
|
|
Author: Tobias Waldekranz <tobias@waldekranz.com>
|
|
Date: Thu Nov 16 21:59:35 2023 +0100
|
|
|
|
net: dsa: mv88e6xxx: Add LED support for 6393X
|
|
|
|
Trigger support:
|
|
- "none"
|
|
- "timer"
|
|
- "netdev"
|
|
---
|
|
drivers/net/dsa/mv88e6xxx/chip.c | 1 +
|
|
drivers/net/dsa/mv88e6xxx/leds.c | 403 +++++++++++++++++++++++++++++++
|
|
drivers/net/dsa/mv88e6xxx/port.c | 33 +++
|
|
drivers/net/dsa/mv88e6xxx/port.h | 13 +
|
|
4 files changed, 450 insertions(+)
|
|
|
|
diff --git a/drivers/net/dsa/mv88e6xxx/chip.c b/drivers/net/dsa/mv88e6xxx/chip.c
|
|
index d379799c0a16..7bc3169839d3 100644
|
|
--- a/drivers/net/dsa/mv88e6xxx/chip.c
|
|
+++ b/drivers/net/dsa/mv88e6xxx/chip.c
|
|
@@ -5658,6 +5658,7 @@ static const struct mv88e6xxx_ops mv88e6393x_ops = {
|
|
.port_disable_pri_override = mv88e6xxx_port_disable_pri_override,
|
|
.port_get_cmode = mv88e6352_port_get_cmode,
|
|
.port_set_cmode = mv88e6393x_port_set_cmode,
|
|
+ .port_setup_leds = mv88e6393x_port_setup_leds,
|
|
.port_setup_message_port = mv88e6xxx_setup_message_port,
|
|
.port_set_upstream_port = mv88e6393x_port_set_upstream_port,
|
|
.stats_snapshot = mv88e6390_g1_stats_snapshot,
|
|
diff --git a/drivers/net/dsa/mv88e6xxx/leds.c b/drivers/net/dsa/mv88e6xxx/leds.c
|
|
index ab3bc645da56..aa539df21f8d 100644
|
|
--- a/drivers/net/dsa/mv88e6xxx/leds.c
|
|
+++ b/drivers/net/dsa/mv88e6xxx/leds.c
|
|
@@ -102,6 +102,58 @@ struct mv88e6xxx_led_hwconfig {
|
|
u16 selector;
|
|
};
|
|
|
|
+/* 6393X LED mode flags */
|
|
+#define MV88E6393X_FLAG_ACT (BIT(TRIGGER_NETDEV_RX) | BIT(TRIGGER_NETDEV_TX))
|
|
+#define MV88E6393X_FLAG_LINK BIT(TRIGGER_NETDEV_LINK)
|
|
+#define MV88E6393X_FLAG_LINK_10 BIT(TRIGGER_NETDEV_LINK_10)
|
|
+#define MV88E6393X_FLAG_LINK_100 BIT(TRIGGER_NETDEV_LINK_100)
|
|
+#define MV88E6393X_FLAG_LINK_1G BIT(TRIGGER_NETDEV_LINK_1000)
|
|
+#define MV88E6393X_FLAG_FULL BIT(TRIGGER_NETDEV_FULL_DUPLEX)
|
|
+
|
|
+/* 6393X LED modes */
|
|
+#define MV88E6393X_LED_MODE_BLINK 0xd
|
|
+#define MV88E6393X_LED_MODE_OFF 0xe
|
|
+#define MV88E6393X_LED_MODE_ON 0xf
|
|
+#define MV88E6393X_LED_MODES 0x10
|
|
+
|
|
+/* 6393X LED mode to flags mapping for ports 1-8 */
|
|
+static const unsigned long mv88e6393x_led_map_p1_p8[2][MV88E6393X_LED_MODES] = {
|
|
+ [0] = {
|
|
+ [0x1] = MV88E6393X_FLAG_ACT | MV88E6393X_FLAG_LINK_100 | MV88E6393X_FLAG_LINK_1G,
|
|
+ [0x2] = MV88E6393X_FLAG_ACT | MV88E6393X_FLAG_LINK_1G,
|
|
+ [0x3] = MV88E6393X_FLAG_ACT | MV88E6393X_FLAG_LINK,
|
|
+ [0x6] = MV88E6393X_FLAG_FULL,
|
|
+ [0x7] = MV88E6393X_FLAG_ACT | MV88E6393X_FLAG_LINK_10 | MV88E6393X_FLAG_LINK_1G,
|
|
+ [0x8] = MV88E6393X_FLAG_LINK,
|
|
+ [0x9] = MV88E6393X_FLAG_LINK_10,
|
|
+ [0xa] = MV88E6393X_FLAG_ACT | MV88E6393X_FLAG_LINK_10,
|
|
+ [0xb] = MV88E6393X_FLAG_LINK_100 | MV88E6393X_FLAG_LINK_1G,
|
|
+ },
|
|
+ [1] = {
|
|
+ [0x1] = MV88E6393X_FLAG_ACT,
|
|
+ [0x2] = MV88E6393X_FLAG_ACT | MV88E6393X_FLAG_LINK_10 | MV88E6393X_FLAG_LINK_100,
|
|
+ [0x3] = MV88E6393X_FLAG_LINK_1G,
|
|
+ [0x5] = MV88E6393X_FLAG_ACT | MV88E6393X_FLAG_LINK,
|
|
+ [0x6] = MV88E6393X_FLAG_ACT | MV88E6393X_FLAG_LINK_10 | MV88E6393X_FLAG_LINK_1G,
|
|
+ [0x7] = MV88E6393X_FLAG_LINK_10 | MV88E6393X_FLAG_LINK_1G,
|
|
+ [0x9] = MV88E6393X_FLAG_LINK_100,
|
|
+ [0xa] = MV88E6393X_FLAG_ACT | MV88E6393X_FLAG_LINK_100,
|
|
+ [0xb] = MV88E6393X_FLAG_LINK_10 | MV88E6393X_FLAG_LINK_100,
|
|
+ }
|
|
+};
|
|
+
|
|
+/* 6393X LED mode to flags mapping for ports 9-10 */
|
|
+static const unsigned long mv88e6393x_led_map_p9_p10[2][MV88E6393X_LED_MODES] = {
|
|
+ [0] = {
|
|
+ [0x1] = MV88E6393X_FLAG_ACT | MV88E6393X_FLAG_LINK,
|
|
+ },
|
|
+ [1] = {
|
|
+ [0x6] = MV88E6393X_FLAG_FULL,
|
|
+ [0x7] = MV88E6393X_FLAG_ACT | MV88E6393X_FLAG_LINK,
|
|
+ [0x8] = MV88E6393X_FLAG_LINK,
|
|
+ }
|
|
+};
|
|
+
|
|
/* The following is a lookup table to check what rules we can support on a
|
|
* certain LED given restrictions such as that some rules only work with fiber
|
|
* (SFP) connections and some blink on activity by default.
|
|
@@ -846,3 +898,354 @@ int mv88e6xxx_port_setup_leds(struct mv88e6xxx_chip *chip, int port)
|
|
fwnode_handle_put(leds);
|
|
return ret;
|
|
}
|
|
+
|
|
+/* 6393X LED support */
|
|
+
|
|
+static const unsigned long *mv88e6393x_led_map(int port, int led)
|
|
+{
|
|
+ if (port >= 1 && port <= 8)
|
|
+ return mv88e6393x_led_map_p1_p8[led];
|
|
+ if (port >= 9 && port <= 10)
|
|
+ return mv88e6393x_led_map_p9_p10[led];
|
|
+ return NULL;
|
|
+}
|
|
+
|
|
+static int mv88e6393x_led_flags_to_mode(int port, int led, unsigned long flags)
|
|
+{
|
|
+ const unsigned long *map = mv88e6393x_led_map(port, 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 -EOPNOTSUPP;
|
|
+}
|
|
+
|
|
+static int mv88e6393x_led_mode_to_flags(int port, int led, u8 mode,
|
|
+ unsigned long *flags)
|
|
+{
|
|
+ const unsigned long *map = mv88e6393x_led_map(port, led);
|
|
+
|
|
+ if (!map)
|
|
+ return -ENODEV;
|
|
+
|
|
+ if (mode == MV88E6393X_LED_MODE_OFF) {
|
|
+ *flags = 0;
|
|
+ return 0;
|
|
+ }
|
|
+
|
|
+ if (mode < MV88E6393X_LED_MODES && map[mode]) {
|
|
+ *flags = map[mode];
|
|
+ return 0;
|
|
+ }
|
|
+
|
|
+ return -EINVAL;
|
|
+}
|
|
+
|
|
+static int mv88e6393x_led_set_mode(struct mv88e6xxx_port *p, int led, int mode)
|
|
+{
|
|
+ u16 ctrl;
|
|
+ int err;
|
|
+
|
|
+ if (mode < 0)
|
|
+ return mode;
|
|
+
|
|
+ err = mv88e6393x_port_led_read(p->chip, p->port, 0, &ctrl);
|
|
+ if (err)
|
|
+ return err;
|
|
+
|
|
+ if (led == 0) {
|
|
+ ctrl &= ~0x0f;
|
|
+ ctrl |= mode;
|
|
+ } else {
|
|
+ ctrl &= ~0xf0;
|
|
+ ctrl |= mode << 4;
|
|
+ }
|
|
+
|
|
+ return mv88e6393x_port_led_write(p->chip, p->port, 0, ctrl);
|
|
+}
|
|
+
|
|
+static int mv88e6393x_led_get_mode(struct mv88e6xxx_port *p, int led)
|
|
+{
|
|
+ u16 ctrl;
|
|
+ int err;
|
|
+
|
|
+ err = mv88e6393x_port_led_read(p->chip, p->port, 0, &ctrl);
|
|
+ if (err)
|
|
+ return err;
|
|
+
|
|
+ if (led == 0)
|
|
+ return ctrl & 0xf;
|
|
+ else
|
|
+ return (ctrl >> 4) & 0xf;
|
|
+}
|
|
+
|
|
+static int mv88e6393x_led_brightness_set(struct mv88e6xxx_port *p, int led,
|
|
+ int brightness)
|
|
+{
|
|
+ if (brightness == LED_OFF)
|
|
+ return mv88e6393x_led_set_mode(p, led, MV88E6393X_LED_MODE_OFF);
|
|
+
|
|
+ return mv88e6393x_led_set_mode(p, led, MV88E6393X_LED_MODE_ON);
|
|
+}
|
|
+
|
|
+static int mv88e6393x_led0_brightness_set_blocking(struct led_classdev *ldev,
|
|
+ enum led_brightness brightness)
|
|
+{
|
|
+ struct mv88e6xxx_port *p = container_of(ldev, struct mv88e6xxx_port, led0);
|
|
+ int err;
|
|
+
|
|
+ mv88e6xxx_reg_lock(p->chip);
|
|
+ err = mv88e6393x_led_brightness_set(p, 0, brightness);
|
|
+ mv88e6xxx_reg_unlock(p->chip);
|
|
+
|
|
+ return err;
|
|
+}
|
|
+
|
|
+static int mv88e6393x_led1_brightness_set_blocking(struct led_classdev *ldev,
|
|
+ enum led_brightness brightness)
|
|
+{
|
|
+ struct mv88e6xxx_port *p = container_of(ldev, struct mv88e6xxx_port, led1);
|
|
+ int err;
|
|
+
|
|
+ mv88e6xxx_reg_lock(p->chip);
|
|
+ err = mv88e6393x_led_brightness_set(p, 1, brightness);
|
|
+ mv88e6xxx_reg_unlock(p->chip);
|
|
+
|
|
+ return err;
|
|
+}
|
|
+
|
|
+static int mv88e6393x_led_blink_set(struct mv88e6xxx_port *p, int 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;
|
|
+
|
|
+ mv88e6xxx_reg_lock(p->chip);
|
|
+ err = mv88e6393x_led_set_mode(p, led, MV88E6393X_LED_MODE_BLINK);
|
|
+ mv88e6xxx_reg_unlock(p->chip);
|
|
+ if (!err)
|
|
+ *delay_on = *delay_off = 42;
|
|
+
|
|
+ return err;
|
|
+}
|
|
+
|
|
+static int mv88e6393x_led0_blink_set(struct led_classdev *ldev,
|
|
+ unsigned long *delay_on,
|
|
+ unsigned long *delay_off)
|
|
+{
|
|
+ struct mv88e6xxx_port *p = container_of(ldev, struct mv88e6xxx_port, led0);
|
|
+
|
|
+ return mv88e6393x_led_blink_set(p, 0, delay_on, delay_off);
|
|
+}
|
|
+
|
|
+static int mv88e6393x_led1_blink_set(struct led_classdev *ldev,
|
|
+ unsigned long *delay_on,
|
|
+ unsigned long *delay_off)
|
|
+{
|
|
+ struct mv88e6xxx_port *p = container_of(ldev, struct mv88e6xxx_port, led1);
|
|
+
|
|
+ return mv88e6393x_led_blink_set(p, 1, delay_on, delay_off);
|
|
+}
|
|
+
|
|
+static int
|
|
+mv88e6393x_led0_hw_control_is_supported(struct led_classdev *ldev, unsigned long rules)
|
|
+{
|
|
+ struct mv88e6xxx_port *p = container_of(ldev, struct mv88e6xxx_port, led0);
|
|
+ int mode = mv88e6393x_led_flags_to_mode(p->port, 0, rules);
|
|
+
|
|
+ return (mode < 0) ? mode : 0;
|
|
+}
|
|
+
|
|
+static int
|
|
+mv88e6393x_led1_hw_control_is_supported(struct led_classdev *ldev, unsigned long rules)
|
|
+{
|
|
+ struct mv88e6xxx_port *p = container_of(ldev, struct mv88e6xxx_port, led1);
|
|
+ int mode = mv88e6393x_led_flags_to_mode(p->port, 1, rules);
|
|
+
|
|
+ return (mode < 0) ? mode : 0;
|
|
+}
|
|
+
|
|
+static int mv88e6393x_led_hw_control_set(struct mv88e6xxx_port *p,
|
|
+ int led, unsigned long rules)
|
|
+{
|
|
+ int mode = mv88e6393x_led_flags_to_mode(p->port, led, rules);
|
|
+
|
|
+ if (mode < 0)
|
|
+ return mode;
|
|
+
|
|
+ return mv88e6393x_led_set_mode(p, led, mode);
|
|
+}
|
|
+
|
|
+static int
|
|
+mv88e6393x_led0_hw_control_set(struct led_classdev *ldev, unsigned long rules)
|
|
+{
|
|
+ struct mv88e6xxx_port *p = container_of(ldev, struct mv88e6xxx_port, led0);
|
|
+ int err;
|
|
+
|
|
+ mv88e6xxx_reg_lock(p->chip);
|
|
+ err = mv88e6393x_led_hw_control_set(p, 0, rules);
|
|
+ mv88e6xxx_reg_unlock(p->chip);
|
|
+
|
|
+ return err;
|
|
+}
|
|
+
|
|
+static int
|
|
+mv88e6393x_led1_hw_control_set(struct led_classdev *ldev, unsigned long rules)
|
|
+{
|
|
+ struct mv88e6xxx_port *p = container_of(ldev, struct mv88e6xxx_port, led1);
|
|
+ int err;
|
|
+
|
|
+ mv88e6xxx_reg_lock(p->chip);
|
|
+ err = mv88e6393x_led_hw_control_set(p, 1, rules);
|
|
+ mv88e6xxx_reg_unlock(p->chip);
|
|
+
|
|
+ return err;
|
|
+}
|
|
+
|
|
+static int
|
|
+mv88e6393x_led_hw_control_get(struct mv88e6xxx_port *p, int led, unsigned long *rules)
|
|
+{
|
|
+ int mode;
|
|
+
|
|
+ mv88e6xxx_reg_lock(p->chip);
|
|
+ mode = mv88e6393x_led_get_mode(p, led);
|
|
+ mv88e6xxx_reg_unlock(p->chip);
|
|
+ if (mode < 0)
|
|
+ return mode;
|
|
+
|
|
+ return mv88e6393x_led_mode_to_flags(p->port, led, mode, rules);
|
|
+}
|
|
+
|
|
+static int
|
|
+mv88e6393x_led0_hw_control_get(struct led_classdev *ldev, unsigned long *rules)
|
|
+{
|
|
+ struct mv88e6xxx_port *p = container_of(ldev, struct mv88e6xxx_port, led0);
|
|
+
|
|
+ return mv88e6393x_led_hw_control_get(p, 0, rules);
|
|
+}
|
|
+
|
|
+static int
|
|
+mv88e6393x_led1_hw_control_get(struct led_classdev *ldev, unsigned long *rules)
|
|
+{
|
|
+ struct mv88e6xxx_port *p = container_of(ldev, struct mv88e6xxx_port, led1);
|
|
+
|
|
+ return mv88e6393x_led_hw_control_get(p, 1, rules);
|
|
+}
|
|
+
|
|
+int mv88e6393x_port_setup_leds(struct mv88e6xxx_chip *chip, int port)
|
|
+{
|
|
+ struct fwnode_handle *led = NULL, *leds = NULL;
|
|
+ struct led_init_data init_data = { };
|
|
+ enum led_default_state state;
|
|
+ struct mv88e6xxx_port *p;
|
|
+ struct led_classdev *l;
|
|
+ struct device *dev;
|
|
+ u32 led_num;
|
|
+ int ret;
|
|
+
|
|
+ /* 6393X has LEDs on ports 1-10 */
|
|
+ if (port < 1 || port > 10)
|
|
+ return -EOPNOTSUPP;
|
|
+
|
|
+ p = &chip->ports[port];
|
|
+ if (!p->fwnode)
|
|
+ return 0;
|
|
+
|
|
+ dev = chip->dev;
|
|
+
|
|
+ leds = fwnode_get_named_child_node(p->fwnode, "leds");
|
|
+ if (!leds) {
|
|
+ dev_dbg(dev, "No Leds node specified in device tree for port %d!\n",
|
|
+ port);
|
|
+ return 0;
|
|
+ }
|
|
+
|
|
+ fwnode_for_each_child_node(leds, led) {
|
|
+ if (fwnode_property_read_u32(led, "reg", &led_num))
|
|
+ continue;
|
|
+ if (led_num > 1) {
|
|
+ dev_err(dev, "invalid LED specified port %d\n", port);
|
|
+ ret = -EINVAL;
|
|
+ goto err_put_led;
|
|
+ }
|
|
+
|
|
+ if (led_num == 0)
|
|
+ l = &p->led0;
|
|
+ else
|
|
+ l = &p->led1;
|
|
+
|
|
+ state = led_init_default_state_get(led);
|
|
+ switch (state) {
|
|
+ case LEDS_DEFSTATE_ON:
|
|
+ l->brightness = 1;
|
|
+ mv88e6393x_led_brightness_set(p, led_num, 1);
|
|
+ break;
|
|
+ case LEDS_DEFSTATE_KEEP:
|
|
+ break;
|
|
+ default:
|
|
+ l->brightness = 0;
|
|
+ mv88e6393x_led_brightness_set(p, led_num, 0);
|
|
+ }
|
|
+
|
|
+ l->max_brightness = 1;
|
|
+ if (led_num == 0) {
|
|
+ l->brightness_set_blocking = mv88e6393x_led0_brightness_set_blocking;
|
|
+ l->blink_set = mv88e6393x_led0_blink_set;
|
|
+ l->hw_control_is_supported = mv88e6393x_led0_hw_control_is_supported;
|
|
+ l->hw_control_set = mv88e6393x_led0_hw_control_set;
|
|
+ l->hw_control_get = mv88e6393x_led0_hw_control_get;
|
|
+ l->hw_control_get_device = mv88e6xxx_led0_hw_control_get_device;
|
|
+ } else {
|
|
+ l->brightness_set_blocking = mv88e6393x_led1_brightness_set_blocking;
|
|
+ l->blink_set = mv88e6393x_led1_blink_set;
|
|
+ l->hw_control_is_supported = mv88e6393x_led1_hw_control_is_supported;
|
|
+ l->hw_control_set = mv88e6393x_led1_hw_control_set;
|
|
+ l->hw_control_get = mv88e6393x_led1_hw_control_get;
|
|
+ l->hw_control_get_device = mv88e6xxx_led1_hw_control_get_device;
|
|
+ }
|
|
+ l->hw_control_trigger = "netdev";
|
|
+
|
|
+ init_data.default_label = ":port";
|
|
+ init_data.fwnode = led;
|
|
+ init_data.devname_mandatory = true;
|
|
+ init_data.devicename = kasprintf(GFP_KERNEL, "%s:0%d:0%d", chip->info->name,
|
|
+ port, led_num);
|
|
+ if (!init_data.devicename) {
|
|
+ ret = -ENOMEM;
|
|
+ goto err_put_led;
|
|
+ }
|
|
+
|
|
+ ret = devm_led_classdev_register_ext(dev, l, &init_data);
|
|
+ kfree(init_data.devicename);
|
|
+
|
|
+ if (ret) {
|
|
+ dev_err(dev, "Failed to init LED %d for port %d", led_num, port);
|
|
+ goto err_put_led;
|
|
+ }
|
|
+ }
|
|
+
|
|
+ fwnode_handle_put(leds);
|
|
+ return 0;
|
|
+
|
|
+err_put_led:
|
|
+ fwnode_handle_put(led);
|
|
+ fwnode_handle_put(leds);
|
|
+ return ret;
|
|
+}
|
|
diff --git a/drivers/net/dsa/mv88e6xxx/port.c b/drivers/net/dsa/mv88e6xxx/port.c
|
|
index e28fdd21de38..1985b8553611 100644
|
|
--- a/drivers/net/dsa/mv88e6xxx/port.c
|
|
+++ b/drivers/net/dsa/mv88e6xxx/port.c
|
|
@@ -1604,6 +1604,39 @@ int mv88e6xxx_port_relinquish_ether_type(struct mv88e6xxx_chip *chip, int port)
|
|
return err;
|
|
}
|
|
|
|
+/* Offset 0x16: LED Control (6393X family) */
|
|
+
|
|
+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 d2ba9ed1f23e..f4a56671fc4c 100644
|
|
--- a/drivers/net/dsa/mv88e6xxx/port.h
|
|
+++ b/drivers/net/dsa/mv88e6xxx/port.h
|
|
@@ -444,6 +444,9 @@
|
|
/* Control for Special LED (Index 0x7 of LED Control on Port 2) */
|
|
#define MV88E6XXX_PORT_LED_CONTROL_0x07_P2_PTP_ACT 0 /* bits 6:0 PTP Activity */
|
|
|
|
+/* Offset 0x16: LED Control (6393X family) */
|
|
+#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
|
|
@@ -565,6 +568,10 @@ int mv88e6351_port_set_ether_type(struct mv88e6xxx_chip *chip, int port,
|
|
int mv88e6xxx_port_claim_ether_type(struct mv88e6xxx_chip *chip, int port,
|
|
u16 etype);
|
|
int mv88e6xxx_port_relinquish_ether_type(struct mv88e6xxx_chip *chip, int port);
|
|
+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);
|
|
@@ -597,12 +604,18 @@ int mv88e6185_port_get_cmode(struct mv88e6xxx_chip *chip, int port, u8 *cmode);
|
|
int mv88e6352_port_get_cmode(struct mv88e6xxx_chip *chip, int port, u8 *cmode);
|
|
#ifdef CONFIG_NET_DSA_MV88E6XXX_LEDS
|
|
int mv88e6xxx_port_setup_leds(struct mv88e6xxx_chip *chip, int port);
|
|
+int mv88e6393x_port_setup_leds(struct mv88e6xxx_chip *chip, int port);
|
|
#else
|
|
static inline int mv88e6xxx_port_setup_leds(struct mv88e6xxx_chip *chip,
|
|
int port)
|
|
{
|
|
return 0;
|
|
}
|
|
+static inline int mv88e6393x_port_setup_leds(struct mv88e6xxx_chip *chip,
|
|
+ int port)
|
|
+{
|
|
+ return 0;
|
|
+}
|
|
#endif
|
|
int mv88e6xxx_port_drop_untagged(struct mv88e6xxx_chip *chip, int port,
|
|
bool drop_untagged);
|