Current version of rtl8366-smi module support Realtek switch
managment via two gpio lines only. This patch add Realtek switch
management via mii_bus. For my board Tp-link Archer C2 v1 (Mediatek
SoC mt7620a based) dts-file configuration looks like:
rtl8367rb {
compatible = "realtek,rtl8367b", "rtl8367b";
realtek,extif1 = <1 0 1 1 1 1 1 1 2>;
mii-bus = <>;
};
{
status = "okay";
mtd-mac-address = < 0xf100>;
pinctrl-names = "default";
pinctrl-0 = <_pins _pins _pins>;
port@5 {
status = "okay";
mediatek,fixed-link = <1000 1 1 1>;
phy-mode = "rgmii";
};
mdio0: mdio-bus {
status = "okay";
};
};
Realtek rtl8367rb switch is ok.
Other Realtek switches and archs are untested but must work too.
Version 2: add mii_bus mutex_lock
Signed-off-by: Serge Vasilugin
--
diff --git a/target/linux/generic/files/drivers/net/phy/rtl8366_smi.c
b/target/linux/generic/files/drivers/net/phy/rtl8366_smi.c
index ae04597..c190ebc 100644
--- a/target/linux/generic/files/drivers/net/phy/rtl8366_smi.c
+++ b/target/linux/generic/files/drivers/net/phy/rtl8366_smi.c
@@ -18,6 +18,7 @@
#include
#include
#include
+#include
#include
#include
@@ -198,7 +199,7 @@ static int rtl8366_smi_read_byte1(struct rtl8366_smi *smi,
u8 *data)
return 0;
}
-int rtl8366_smi_read_reg(struct rtl8366_smi *smi, u32 addr, u32 *data)
+static int __rtl8366_smi_read_reg(struct rtl8366_smi *smi, u32 addr, u32 *data)
{
unsigned long flags;
u8 lo = 0;
@@ -239,6 +240,101 @@ int rtl8366_smi_read_reg(struct rtl8366_smi *smi, u32
addr, u32 *data)
return ret;
}
+/* Read/write via mdiobus */
+#define MDC_MDIO_CTRL0_REG 31
+#define MDC_MDIO_START_REG 29
+#define MDC_MDIO_CTRL1_REG 21
+#define MDC_MDIO_ADDRESS_REG 23
+#define MDC_MDIO_DATA_WRITE_REG24
+#define MDC_MDIO_DATA_READ_REG 25
+
+#define MDC_MDIO_START_OP 0x
+#define MDC_MDIO_ADDR_OP 0x000E
+#define MDC_MDIO_READ_OP 0x0001
+#define MDC_MDIO_WRITE_OP 0x0003
+#define MDC_REALTEK_PHY_ADDR 0x0
+
+int __rtl8366_mdio_read_reg(struct rtl8366_smi *smi, u32 addr, u32 *data)
+{
+ u32 phy_id = MDC_REALTEK_PHY_ADDR;
+ struct mii_bus *mbus = smi->ext_mbus;
+
+ BUG_ON(in_interrupt());
+
+ mutex_lock(>mdio_lock);
+ /* Write Start command to register 29 */
+ mbus->write(mbus, phy_id, MDC_MDIO_START_REG, MDC_MDIO_START_OP);
+
+ /* Write address control code to register 31 */
+ mbus->write(mbus, phy_id, MDC_MDIO_CTRL0_REG, MDC_MDIO_ADDR_OP);
+
+ /* Write Start command to register 29 */
+ mbus->write(mbus, phy_id, MDC_MDIO_START_REG, MDC_MDIO_START_OP);
+
+ /* Write address to register 23 */
+ mbus->write(mbus, phy_id, MDC_MDIO_ADDRESS_REG, addr);
+
+ /* Write Start command to register 29 */
+ mbus->write(mbus, phy_id, MDC_MDIO_START_REG, MDC_MDIO_START_OP);
+
+ /* Write read control code to register 21 */
+ mbus->write(mbus, phy_id, MDC_MDIO_CTRL1_REG, MDC_MDIO_READ_OP);
+
+ /* Write Start command to register 29 */
+ mbus->write(smi->ext_mbus, phy_id, MDC_MDIO_START_REG,
MDC_MDIO_START_OP);
+
+ /* Read data from register 25 */
+ *data = mbus->read(mbus, phy_id, MDC_MDIO_DATA_READ_REG);
+
+ mutex_unlock(>mdio_lock);
+
+ return 0;
+}
+
+static int __rtl8366_mdio_write_reg(struct rtl8366_smi *smi, u32 addr, u32
data)
+{
+ u32 phy_id = MDC_REALTEK_PHY_ADDR;
+ struct mii_bus *mbus = smi->ext_mbus;
+
+ BUG_ON(in_interrupt());
+
+ mutex_lock(>mdio_lock);
+
+ /* Write Start command to register 29 */
+ mbus->write(mbus, phy_id, MDC_MDIO_START_REG, MDC_MDIO_START_OP);
+
+ /* Write address control code to register 31 */
+ mbus->write(mbus, phy_id, MDC_MDIO_CTRL0_REG, MDC_MDIO_ADDR_OP);
+
+ /* Write Start command to register 29 */
+ mbus->write(mbus, phy_id, MDC_MDIO_START_REG, MDC_MDIO_START_OP);
+
+ /* Write address to register 23 */
+ mbus->write(mbus, phy_id, MDC_MDIO_ADDRESS_REG, addr);
+
+ /* Write Start command to register 29 */
+ mbus->write(mbus, phy_id, MDC_MDIO_START_REG, MDC_MDIO_START_OP);
+
+ /* Write data to register 24 */
+ mbus->write(mbus, phy_id, MDC_MDIO_DATA_WRITE_REG, data);
+
+ /* Write Start command to register 29 */
+ mbus->write(mbus, phy_id, MDC_MDIO_START_REG, MDC_MDIO_START_OP);
+
+ /* Write data control code to register 21 */
+ mbus->write(mbus, phy_id, MDC_MDIO_CTRL1_REG, MDC_MDIO_WRITE_OP);
+
+ mutex_unlock(>mdio_lock);
+ return 0;
+}
+
+int rtl8366_smi_read_reg(struct rtl8366_smi *smi, u32 addr, u32 *data)
+{
+if(smi->ext_mbus)
+ return