1 diff --git a/openwrt/target/linux/ramips/files-4.14/drivers/net/ethernet/mediatek/gsw_mt7620.h b/target/linux/ramips/files-4.14/drivers/net/ethernet/mediatek/gsw_mt7620.h
2 index ae0b6de024..0eb8597b73 100644
3 --- a/openwrt/target/linux/ramips/files-4.14/drivers/net/ethernet/mediatek/gsw_mt7620.h
4 +++ b/openwrt/target/linux/ramips/files-4.14/drivers/net/ethernet/mediatek/gsw_mt7620.h
6 #define PHY_PRE_EN BIT(30)
7 #define PMY_MDC_CONF(_x) ((_x & 0x3f) << 24)
9 +/* Register for hw trap modification */
10 +#define MT7530_MHWTRAP 0x7804
11 +#define MHWTRAP_PHY0_SEL BIT(20)
12 +#define MHWTRAP_MANUAL BIT(16)
13 +#define MHWTRAP_P5_MAC_SEL BIT(13)
14 +#define MHWTRAP_P6_DIS BIT(8)
15 +#define MHWTRAP_P5_RGMII_MODE BIT(7)
16 +#define MHWTRAP_P5_DIS BIT(6)
17 +#define MHWTRAP_PHY_ACCESS BIT(5)
19 +#define MT7530_IO_DRV_CR 0x7810
20 +#define P5_IO_CLK_DRV(x) ((x) & 0x3)
21 +#define P5_IO_DATA_DRV(x) (((x) & 0x3) << 4)
23 +#define MT7530_P5RGMIIRXCR 0x7b00
24 +#define CSR_RGMII_EDGE_ALIGN BIT(8)
25 +#define CSR_RGMII_RXC_0DEG_CFG(x) ((x) & 0xf)
27 +#define MT7530_P5RGMIITXCR 0x7b04
28 +#define CSR_RGMII_TXC_CFG(x) ((x) & 0x1f)
31 /* Global attributes. */
32 @@ -96,6 +116,29 @@ enum {
36 +/* Port 5 interface select definitions */
37 +enum p5_interface_select {
44 +static const char *p5_intf_modes(unsigned int p5_interface)
46 + switch (p5_interface) {
49 + case P5_INTF_SEL_PHY_P0:
51 + case P5_INTF_SEL_PHY_P4:
53 + case P5_INTF_SEL_GMAC5:
62 @@ -103,6 +146,8 @@ struct mt7620_gsw {
65 unsigned long int autopoll;
66 + phy_interface_t p5_interface;
67 + unsigned int p5_intf_sel;
70 void mtk_switch_w32(struct mt7620_gsw *gsw, u32 val, unsigned reg);
71 diff --git a/openwrt/target/linux/ramips/files-4.14/drivers/net/ethernet/mediatek/gsw_mt7621.c b/target/linux/ramips/files-4.14/drivers/net/ethernet/mediatek/gsw_mt7621.c
72 index 89be239007..1fc63590fd 100644
73 --- a/openwrt/target/linux/ramips/files-4.14/drivers/net/ethernet/mediatek/gsw_mt7621.c
74 +++ b/openwrt/target/linux/ramips/files-4.14/drivers/net/ethernet/mediatek/gsw_mt7621.c
76 #include <linux/kernel.h>
77 #include <linux/types.h>
78 #include <linux/platform_device.h>
79 +#include <linux/of_mdio.h>
80 +#include <linux/of_net.h>
81 #include <linux/of_device.h>
82 #include <linux/of_irq.h>
84 @@ -43,7 +45,11 @@ static irqreturn_t gsw_interrupt_mt7621(int irq, void *_priv)
85 reg = mt7530_mdio_r32(gsw, 0x700c);
86 mt7530_mdio_w32(gsw, 0x700c, reg);
88 - for (i = 0; i < 5; i++)
89 + for (i = 0; i < 6; i++) {
90 + if (i == 5 && gsw->p5_intf_sel != P5_INTF_SEL_GMAC5)
97 @@ -60,12 +66,152 @@ static irqreturn_t gsw_interrupt_mt7621(int irq, void *_priv)
98 "port %d link down\n", i);
103 mt7620_handle_carrier(priv);
108 +static void mt7530_parse_ports(struct mt7620_gsw *gsw, struct device_node *np)
110 + struct device_node *phy_node, *ports, *port;
114 + gsw->p5_interface = PHY_INTERFACE_MODE_NA;
115 + gsw->p5_intf_sel = P5_DISABLED;
117 + ports = of_get_child_by_name(np, "ports");
121 + for_each_available_child_of_node(ports, port) {
122 + err = of_property_read_u32(port, "reg", ®);
129 + phy_node = of_parse_phandle(port, "phy-handle", 0);
131 + gsw->p5_interface = of_get_phy_mode(port);
132 + gsw->p5_intf_sel = P5_INTF_SEL_GMAC5;
134 + id = of_mdio_parse_addr(gsw->dev, phy_node);
136 + gsw->p5_intf_sel = P5_INTF_SEL_PHY_P0;
138 + gsw->p5_intf_sel = P5_INTF_SEL_PHY_P4;
140 + of_node_put(phy_node);
145 +static void mt7530_setup_port5(struct mt7620_gsw *gsw, struct device_node *np)
150 + mt7530_parse_ports(gsw, np);
152 + val = mt7530_mdio_r32(gsw, MT7530_MHWTRAP);
154 + val |= MHWTRAP_MANUAL | MHWTRAP_P5_MAC_SEL | MHWTRAP_P5_DIS;
155 + val &= ~MHWTRAP_P5_RGMII_MODE & ~MHWTRAP_PHY0_SEL;
157 + switch (gsw->p5_intf_sel) {
158 + case P5_INTF_SEL_PHY_P0:
159 + /* MT7530_P5_MODE_GPHY_P0: 2nd GMAC -> P5 -> P0 */
160 + val |= MHWTRAP_PHY0_SEL;
162 + case P5_INTF_SEL_PHY_P4:
163 + /* MT7530_P5_MODE_GPHY_P4: 2nd GMAC -> P5 -> P4 */
164 + val &= ~MHWTRAP_P5_MAC_SEL & ~MHWTRAP_P5_DIS;
166 + /* Setup the MAC by default for the cpu port */
167 + mt7530_mdio_w32(gsw, GSW_REG_PORT_PMCR(5), 0x56300);
169 + case P5_INTF_SEL_GMAC5:
170 + /* MT7530_P5_MODE_GMAC: P5 -> External phy or 2nd GMAC */
171 + val &= ~MHWTRAP_P5_DIS;
172 + mt7530_mdio_w32(gsw, GSW_REG_PORT_PMCR(5), 0x56300);
175 + gsw->p5_interface = PHY_INTERFACE_MODE_NA;
178 + dev_err(gsw->dev, "Unsupported p5_intf_sel %d\n",
183 + /* Setup RGMII settings */
184 + if (phy_interface_mode_is_rgmii(gsw->p5_interface)) {
185 + val |= MHWTRAP_P5_RGMII_MODE;
187 + /* P5 RGMII RX Clock Control: delay setting for 1000M */
188 + mt7530_mdio_w32(gsw, MT7530_P5RGMIIRXCR, CSR_RGMII_EDGE_ALIGN);
190 + /* Don't set delay in DSA mode */
191 + if ((gsw->p5_intf_sel == P5_INTF_SEL_PHY_P0 ||
192 + gsw->p5_intf_sel == P5_INTF_SEL_PHY_P4) &&
193 + (gsw->p5_interface == PHY_INTERFACE_MODE_RGMII_TXID ||
194 + gsw->p5_interface == PHY_INTERFACE_MODE_RGMII_ID))
195 + tx_delay = 4; /* n * 0.5 ns */
197 + /* P5 RGMII TX Clock Control: delay x */
198 + mt7530_mdio_w32(gsw, MT7530_P5RGMIITXCR,
199 + CSR_RGMII_TXC_CFG(0x10 + tx_delay));
201 + /* reduce P5 RGMII Tx driving, 8mA */
202 + mt7530_mdio_w32(gsw, MT7530_IO_DRV_CR,
203 + P5_IO_CLK_DRV(1) | P5_IO_DATA_DRV(1));
206 + mt7530_mdio_w32(gsw, MT7530_MHWTRAP, val);
208 + dev_info(gsw->dev, "Setup P5, HWTRAP=0x%x, intf_sel=%s, phy-mode=%s\n",
209 + val, p5_intf_modes(gsw->p5_intf_sel), phy_modes(gsw->p5_interface));
216 +/* HACK: detect at803x and force at8033 at 1gbit full-duplex */
217 +static void mt7530_detect_at8033(struct mt7620_gsw *gsw)
221 + if (gsw->p5_intf_sel == P5_INTF_SEL_GMAC5) {
222 + /* read phy identifier 1 */
223 + reg = _mt7620_mii_read(gsw, 7, 0x02);
224 + if (reg < 0 || reg != 0x004d)
227 + /* read phy identifier 2 */
228 + reg = _mt7620_mii_read(gsw, 7, 0x03);
229 + if (reg < 0 || reg != 0xd074)
232 + /* read chip configure register */
233 + reg = _mt7620_mii_read(gsw, 7, 0x1f);
234 + if ((reg & 0x000f) == 0x0002)
235 + dev_info(gsw->dev,"phy 7 at803x mode BX1000, 1Gbit\n");
238 + "phy 7 at803x mode unknown: 0x1F=0x%x\n", reg);
240 + /* force PHY and port 5 MAC 1gbit, full-duplex */
241 + _mt7620_mii_write(gsw, 7, 0x00, 0x0140);
242 + mt7530_mdio_w32(gsw, 0x3500, 0x7e33b);
247 static void mt7621_hw_init(struct mt7620_gsw *gsw, struct device_node *np)
250 @@ -174,10 +320,6 @@ static void mt7621_hw_init(struct mt7620_gsw *gsw, struct device_node *np)
251 mt7530_mdio_w32(gsw, 0x7a40, val);
252 mt7530_mdio_w32(gsw, 0x7a78, 0x855);
254 - /* delay setting for 10/1000M */
255 - mt7530_mdio_w32(gsw, 0x7b00, 0x102);
256 - mt7530_mdio_w32(gsw, 0x7b04, 0x14);
258 /* lower Tx Driving*/
259 mt7530_mdio_w32(gsw, 0x7a54, 0x44);
260 mt7530_mdio_w32(gsw, 0x7a5c, 0x44);
261 @@ -186,6 +328,12 @@ static void mt7621_hw_init(struct mt7620_gsw *gsw, struct device_node *np)
262 mt7530_mdio_w32(gsw, 0x7a74, 0x44);
263 mt7530_mdio_w32(gsw, 0x7a7c, 0x44);
266 + mt7530_setup_port5(gsw, np);
268 + /* HACK: Detect at8033 phy on ubnt erx-sfp */
269 + mt7530_detect_at8033(gsw);
271 /* turn on all PHYs */
272 for (i = 0; i <= 4; i++) {
273 val = _mt7620_mii_read(gsw, i, 0);
274 diff --git a/openwrt/target/linux/ramips/dts/mt7621.dtsi b/target/linux/ramips/dts/mt7621.dtsi
275 index 4f69e0902e..0fab3fbca8 100644
276 --- a/openwrt/target/linux/ramips/dts/mt7621.dtsi
277 +++ b/openwrt/target/linux/ramips/dts/mt7621.dtsi
280 mediatek,switch = <&gsw>;
284 #address-cells = <1>;
287 diff --git a/openwrt/target/linux/ramips/base-files/etc/board.d/02_network b/target/linux/ramips/base-files/etc/board.d/02_network
288 index 0ffd5d6560..e3c0d1067d 100755
289 --- a/openwrt/target/linux/ramips/base-files/etc/board.d/02_network
290 +++ b/openwrt/target/linux/ramips/base-files/etc/board.d/02_network
299 @@ -261,6 +261,10 @@ ramips_setup_interfaces()
300 ucidef_add_switch "switch0" \
301 "1:lan" "2:lan" "3:lan" "4:lan" "0:wan" "6@eth0"
304 + ucidef_add_switch "switch0" \
305 + "0:lan" "1:lan" "2:lan" "3:lan" "4:lan" "5:wan" "6@eth0"
308 ucidef_add_switch "switch0" \
309 "1:lan" "2:lan" "0:wan" "6@eth0"
310 diff --git a/openwrt/target/linux/ramips/dts/UBNT-ERX-SFP.dts b/target/linux/ramips/dts/UBNT-ERX-SFP.dts
311 index 7de37804a5..a208f62794 100644
312 --- a/openwrt/target/linux/ramips/dts/UBNT-ERX-SFP.dts
313 +++ b/openwrt/target/linux/ramips/dts/UBNT-ERX-SFP.dts
320 + compatible = "gpio-leds";
322 + /* Fixme: Currently a hack to enable SFP clk gate. */
325 + gpios = <&gpio0 7 GPIO_ACTIVE_LOW>;
326 + default-state = "off";
327 + linux,default-trigger = "default-on";
333 + ephy5: ethernet-phy@7 {
343 + phy-handle = <&ephy5>;
344 + phy-mode = "rgmii-rxid";
348 diff --git a/openwrt/package/network/utils/phytool/Makefile b/openwrt/package/network/utils/phytool/Makefile
350 index 00000000..e385d5eb
352 +++ b/openwrt/package/network/utils/phytool/Makefile
354 +include $(TOPDIR)/rules.mk
359 +PKG_RELEASE=$(PKG_SOURCE_VERSION)
361 +PKG_SOURCE_PROTO:=git
362 +PKG_SOURCE_URL:=https://github.com/wkz/phytool.git
363 +PKG_SOURCE_DATE:=2017-09-12
364 +PKG_SOURCE_VERSION:=8882328c08ba2efb13c049812098f1d0cb8adf0c
365 +PKG_MIRROR_HASH:=11d406bfe5e4e8372e7e7fed05440e28d6567918910e8cc3671ff3c51dbd165f
367 +PKG_LICENSE:=GPL-2.0
368 +PKG_LICENSE_FILES:=COPYING
370 +PKG_MAINTAINER:=Christian Lamparter <chunkeey@googlemail.com>
372 +include $(INCLUDE_DIR)/package.mk
374 +define Package/phytool
377 + TITLE:=phytool Linux MDIO register access
378 + URL:=https://github.com/wkz/phytool.git
381 +define Package/phytool/description
382 + Linux MDIO register access
385 +define Build/Configure
388 +define Build/Compile
389 + $(MAKE) -C $(PKG_BUILD_DIR) \
390 + CC="$(TARGET_CC)" \
391 + CFLAGS="$(TARGET_CFLAGS) -Wall" \
392 + LDFLAGS="$(TARGET_LDFLAGS)"
395 +define Package/phytool/install
396 + $(INSTALL_DIR) $(1)/usr/bin
397 + $(INSTALL_BIN) $(PKG_BUILD_DIR)/phytool $(1)/usr/bin/
400 +$(eval $(call BuildPackage,phytool))