Skip to content

Commit

Permalink
Merge Official Source
Browse files Browse the repository at this point in the history
Signed-off-by: Tianling Shen <[email protected]>
  • Loading branch information
1715173329 committed Jan 8, 2025
2 parents 482b69f + 3deeb78 commit 8607c28
Show file tree
Hide file tree
Showing 13 changed files with 1,729 additions and 46 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -844,13 +844,19 @@ mac80211_setup_adhoc() {

mac80211_setup_mesh() {
json_get_vars ssid mesh_id mcast_rate
json_get_values iface_basic_rate_list basic_rate

mcval=
[ -n "$mcast_rate" ] && wpa_supplicant_add_rate mcval "$mcast_rate"
[ -n "$mesh_id" ] && ssid="$mesh_id"

br_list="$basic_rate_list"
if [ -n "$iface_basic_rate_list" ]; then
br_list="$iface_basic_rate_list"
fi

brstr=
for br in $basic_rate_list; do
for br in $br_list; do
wpa_supplicant_add_rate brstr "$br"
done

Expand Down
25 changes: 21 additions & 4 deletions target/linux/realtek/dts/rtl8380_zyxel_gs1900.dtsi
Original file line number Diff line number Diff line change
Expand Up @@ -40,18 +40,35 @@
gpios = <&gpio0 0 GPIO_ACTIVE_HIGH>;
};
};
};

&mdio_aux {
status = "okay";

// Reset GPIO is <&gpio0 1 GPIO_ACTIVE_LOW>
// Don't specify the reset info so the mdio subsystem doesn't reset the bus
//reset-gpios = <&gpio0 1 GPIO_ACTIVE_LOW>;
//reset-delay-us = <1000>;
//reset-post-delay-us = <10000>;

gpio1: expander@0 {
compatible = "realtek,rtl8231";
reg = <0x0>;

gpio1: rtl8231-gpio {
compatible = "realtek,rtl8231-gpio";
#gpio-cells = <2>;
gpio-controller;
indirect-access-bus-id = <0>;
#gpio-cells = <2>;
gpio-ranges = <&gpio1 0 0 37>;

poe_enable {
gpio-hog;
gpios = <13 GPIO_ACTIVE_HIGH>;
output-high;
};

led-controller {
compatible = "realtek,rtl8231-leds";
status = "disabled";
};
};
};

Expand Down
56 changes: 56 additions & 0 deletions target/linux/realtek/dts/rtl838x.dtsi
Original file line number Diff line number Diff line change
Expand Up @@ -232,6 +232,42 @@
};
};

switchcore@1b000000 {
compatible = "syscon", "simple-mfd";
reg = <0x1b000000 0x20000>;

mdio_aux: mdio-aux {
compatible = "realtek,rtl8380-aux-mdio";
#address-cells = <1>;
#size-cells = <0>;

status = "disabled";

pinctrl-names = "default";
pinctrl-0 = <&mdio_aux_mdx>, <&aux_mode_mdio>;
};
};

pinmux@1b000144 {
compatible = "pinctrl-single";
reg = <0x1b000144 0x4>;

pinctrl-single,bit-per-mux;
pinctrl-single,register-width = <32>;
pinctrl-single,function-mask = <0x1>;
#pinctrl-cells = <2>;

/* I2C mode */
aux_mode_i2c: i2c-pins {
pinctrl-single,bits = <0x0 0x0 0x1>;
};

/* MDIO mode */
aux_mode_mdio: mdx-pins {
pinctrl-single,bits = <0x0 0x1 0x1>;
};
};

pinmux: pinmux@1b001000 {
compatible = "pinctrl-single";
reg = <0x1b001000 0x4>;
Expand Down Expand Up @@ -262,6 +298,26 @@
};
};

pinmux@1b00a0e0 {
compatible = "pinctrl-single";
reg = <0x1b00a0e0 0x4>;

pinctrl-single,bit-per-mux;
pinctrl-single,register-width = <32>;
pinctrl-single,function-mask = <0x1>;
#pinctrl-cells = <2>;

/* Use SoC GPIO 2/3 as GPIO */
mdio_aux_gpio: gpio-pins {
pinctrl-single,bits = <0x0 0x0 0x1>;
};

/* Use SoC GPIO 2/3 as MDC/MDIO */
mdio_aux_mdx: mdx-pins {
pinctrl-single,bits = <0x0 0x1 0x1>;
};
};

ethernet0: ethernet@1b00a300 {
compatible = "realtek,rtl838x-eth";
reg = <0x1b00a300 0x100>;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,193 @@
From c7ddb74c981c1a29bad82d555d08724aca93b687 Mon Sep 17 00:00:00 2001
From: Sander Vanheule <[email protected]>
Date: Fri, 27 Dec 2024 14:55:31 +0100
Subject: [PATCH] net: mdio: Add Realtek Otto auxiliary controller

SoCs in Realtek's Otto platform such as the RTL8380 and RTL8391 have a
simple auxiliary MDIO controller that is commonly used to manage RTL8231
GPIO expanders on switch devices.

Add a new MDIO controller driver supporting the RTL838x (maple) and
RTL839x (cypress) SoCs.

Signed-off-by: Sander Vanheule <[email protected]>
---
drivers/net/mdio/Kconfig | 10 ++
drivers/net/mdio/Makefile | 1 +
drivers/net/mdio/mdio-realtek-otto-aux.c | 129 +++++++++++++++++++++++
3 files changed, 140 insertions(+)
create mode 100644 drivers/net/mdio/mdio-realtek-otto-aux.c

--- a/drivers/net/mdio/Kconfig
+++ b/drivers/net/mdio/Kconfig
@@ -207,6 +207,16 @@ config MDIO_REGMAP
regmap. Users willing to use this driver must explicitly select
REGMAP.

+config MDIO_REALTEK_OTTO_AUX
+ tristate "Realtek Otto auxiliary MDIO interface support"
+ default MACH_REALTEK_RTL
+ depends on MACH_REALTEK_RTL
+ depends on MFD_SYSCON
+ select MDIO_DEVRES
+ help
+ This driver supports the auxilairy MDIO bus on RTL838x SoCs. This bus
+ is typically used to attach RTL8231 GPIO extenders.
+
config MDIO_THUNDER
tristate "ThunderX SOCs MDIO buses"
depends on 64BIT
--- a/drivers/net/mdio/Makefile
+++ b/drivers/net/mdio/Makefile
@@ -20,6 +20,7 @@ obj-$(CONFIG_MDIO_MSCC_MIIM) += mdio-ms
obj-$(CONFIG_MDIO_MVUSB) += mdio-mvusb.o
obj-$(CONFIG_MDIO_OCTEON) += mdio-octeon.o
obj-$(CONFIG_MDIO_REGMAP) += mdio-regmap.o
+obj-$(CONFIG_MDIO_REALTEK_OTTO_AUX) += mdio-realtek-otto-aux.o
obj-$(CONFIG_MDIO_SMBUS) += mdio-smbus.o
obj-$(CONFIG_MDIO_SUN4I) += mdio-sun4i.o
obj-$(CONFIG_MDIO_THUNDER) += mdio-thunder.o
--- /dev/null
+++ b/drivers/net/mdio/mdio-realtek-otto-aux.c
@@ -0,0 +1,141 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+
+#include <linux/mfd/core.h>
+#include <linux/mfd/syscon.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/of_mdio.h>
+#include <linux/of_platform.h>
+#include <linux/phy.h>
+#include <linux/platform_device.h>
+#include <linux/regmap.h>
+
+#define RTL8380_EXT_GPIO_INDIRECT_ACCESS 0xA09C
+#define RTL8390_EXT_GPIO_INDIRECT_ACCESS 0x0224
+
+#define RTL83XX_AUX_MDIO_DATA GENMASK(31, 16)
+#define RTL83XX_AUX_MDIO_REG GENMASK(11, 7)
+#define RTL83XX_AUX_MDIO_PHY_ADDR GENMASK(6, 2)
+#define RTL83XX_AUX_MDIO_WRITE BIT(1)
+#define RTL83XX_AUX_MDIO_READ 0
+#define RTL83XX_AUX_MDIO_EXEC BIT(0)
+
+struct realtek_aux_mdio_ctrl {
+ struct device *dev;
+ struct regmap *map;
+ unsigned int cmd_reg;
+};
+
+#define mii_bus_to_ctrl(bus) ((struct realtek_aux_mdio_ctrl *) bus->priv)
+
+static int rtl83xx_aux_mdio_cmd(struct realtek_aux_mdio_ctrl *ctrl, int addr, int regnum,
+ u32 rw_bit, u16 *data)
+{
+ unsigned int mask_volatile;
+ unsigned int cmd;
+ unsigned int run;
+ int err;
+
+ cmd = rw_bit | RTL83XX_AUX_MDIO_EXEC;
+ cmd |= FIELD_PREP(RTL83XX_AUX_MDIO_PHY_ADDR, addr);
+ cmd |= FIELD_PREP(RTL83XX_AUX_MDIO_REG, regnum);
+
+ mask_volatile = RTL83XX_AUX_MDIO_EXEC;
+
+ if (rw_bit == RTL83XX_AUX_MDIO_WRITE)
+ cmd |= FIELD_PREP(RTL83XX_AUX_MDIO_DATA, *data);
+ else
+ mask_volatile |= RTL83XX_AUX_MDIO_DATA;
+
+ err = regmap_write(ctrl->map, ctrl->cmd_reg, cmd);
+ if (err)
+ return err;
+
+ err = regmap_read_poll_timeout(ctrl->map, ctrl->cmd_reg, run, (run != cmd), 3, 100);
+
+ if ((run & ~mask_volatile) != (cmd & ~mask_volatile)) {
+ dev_err(ctrl->dev, "Command modified. Is offloading still active?");
+ return -EIO;
+ }
+
+ if (!err && (rw_bit == RTL83XX_AUX_MDIO_READ))
+ *data = FIELD_GET(RTL83XX_AUX_MDIO_DATA, run);
+
+ return err;
+}
+
+static int rtl83xx_aux_mdio_read(struct mii_bus *bus, int addr, int regnum)
+{
+ struct realtek_aux_mdio_ctrl *ctrl = mii_bus_to_ctrl(bus);
+ u16 data;
+ int err;
+
+ err = rtl83xx_aux_mdio_cmd(ctrl, addr, regnum, RTL83XX_AUX_MDIO_READ, &data);
+
+ if (err)
+ return err;
+ else
+ return data;
+}
+
+static int rtl83xx_aux_mdio_write(struct mii_bus *bus, int addr, int regnum, u16 val)
+{
+ struct realtek_aux_mdio_ctrl *ctrl = mii_bus_to_ctrl(bus);
+
+ return rtl83xx_aux_mdio_cmd(ctrl, addr, regnum, RTL83XX_AUX_MDIO_WRITE, &val);
+}
+
+static int realtek_aux_mdio_probe(struct platform_device *pdev)
+{
+ struct device_node *np = pdev->dev.of_node;
+ struct realtek_aux_mdio_ctrl *ctrl;
+ struct mii_bus *bus;
+
+ bus = devm_mdiobus_alloc_size(&pdev->dev, sizeof(*ctrl));
+ if (!bus)
+ return -ENOMEM;
+
+ ctrl = bus->priv;
+ ctrl->dev = &pdev->dev;
+ ctrl->cmd_reg = (unsigned int) device_get_match_data(ctrl->dev);
+ ctrl->map = syscon_node_to_regmap(np->parent);
+ if (IS_ERR(ctrl->map))
+ return PTR_ERR(ctrl->map);
+
+ bus->name = "RTL83xx auxiliary MDIO bus";
+ snprintf(bus->id, MII_BUS_ID_SIZE, "rtl83xx-aux-mdio") ;
+ bus->parent = ctrl->dev;
+ bus->read = rtl83xx_aux_mdio_read;
+ bus->write = rtl83xx_aux_mdio_write;
+ /* Don't have interrupts */
+ for (unsigned int i = 0; i < PHY_MAX_ADDR; i++)
+ bus->irq[i] = PHY_POLL;
+
+ return devm_of_mdiobus_register(ctrl->dev, bus, np);
+}
+
+static const struct of_device_id realtek_aux_mdio_of_match[] = {
+ {
+ .compatible = "realtek,rtl8380-aux-mdio",
+ .data = (void *) RTL8380_EXT_GPIO_INDIRECT_ACCESS,
+ },
+ {
+ .compatible = "realtek,rtl8390-aux-mdio",
+ .data = (void *) RTL8390_EXT_GPIO_INDIRECT_ACCESS,
+ },
+ { /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(of, realtek_aux_mdio_of_match);
+
+static struct platform_driver realtek_aux_mdio_driver = {
+ .driver = {
+ .name = "realtek-otto-aux-mdio",
+ .of_match_table = realtek_aux_mdio_of_match
+ },
+ .probe = realtek_aux_mdio_probe,
+};
+module_platform_driver(realtek_aux_mdio_driver);
+
+MODULE_AUTHOR("Sander Vanheule <[email protected]>");
+MODULE_DESCRIPTION("Realtek RTL83xx auxiliary MDIO bus");
+MODULE_LICENSE("GPL v2");
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
From b3f79468c90d8770f007d628a1e32b2d5d44a5c2 Mon Sep 17 00:00:00 2001
From: Sander Vanheule <[email protected]>
Date: Sat, 15 May 2021 11:57:32 +0200
Subject: [PATCH] gpio: regmap: Bypass cache for shadowed outputs

Some chips have the read-only input and write-only output data registers
aliased to the same offset, but do not perform direction multiplexing on
writes. Upon writing the register, this then always updates the output
value, even when the pin is configured as input. As a result it is not
safe to perform read-modify-writes on output pins, when other pins are
still configured as input.

For example, on a bit-banged I2C bus, where the lines are switched
between out-low and in (with external pull-up)

OUT(L) IN OUT(H)
SCK ....../''''''|''''''

SDA '''''''''\..........
^ ^- SCK switches to direction to OUT, but now has a high
| value, breaking the clock.
|
\- Perform RMW to update SDA. This reads the current input
value for SCK, updates the SDA value and writes back a 1
for SCK as well.

If a register is used for both the data input and data output (and is
not marked as volatile) the driver should ensure the cache is not
updated on register reads. This ensures proper functioning of writing
the output register with regmap_update_bits(), which will then use and
update the cache only on register writes.

Signed-off-by: Sander Vanheule <[email protected]>
---
drivers/gpio/gpio-regmap.c | 10 +++++++++-
1 file changed, 9 insertions(+), 1 deletion(-)

--- a/drivers/gpio/gpio-regmap.c
+++ b/drivers/gpio/gpio-regmap.c
@@ -74,7 +74,15 @@ static int gpio_regmap_get(struct gpio_c
if (ret)
return ret;

- ret = regmap_read(gpio->regmap, reg, &val);
+ /*
+ * Ensure we don't spoil the register cache with pin input values and
+ * perform a bypassed read. This way the cache (if any) is only used and
+ * updated on register writes.
+ */
+ if (gpio->reg_dat_base == gpio->reg_set_base)
+ ret = regmap_read_bypassed(gpio->regmap, reg, &val);
+ else
+ ret = regmap_read(gpio->regmap, reg, &val);
if (ret)
return ret;

Loading

0 comments on commit 8607c28

Please sign in to comment.