Opennet Firmware
hardware_ubnt_erx_sfp.patch
gehe zur Dokumentation dieser Datei
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
5 @@ -84,6 +84,26 @@
6  #define PHY_PRE_EN BIT(30)
7  #define PMY_MDC_CONF(_x) ((_x & 0x3f) << 24)
8 
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)
18 +
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)
22 +
23 +#define MT7530_P5RGMIIRXCR 0x7b00
24 +#define CSR_RGMII_EDGE_ALIGN BIT(8)
25 +#define CSR_RGMII_RXC_0DEG_CFG(x) ((x) & 0xf)
26 +
27 +#define MT7530_P5RGMIITXCR 0x7b04
28 +#define CSR_RGMII_TXC_CFG(x) ((x) & 0x1f)
29 
30  enum {
31  /* Global attributes. */
32 @@ -96,6 +116,29 @@ enum {
33  PORT4_EPHY = 0,
34  PORT4_EXT,
35  };
36 +/* Port 5 interface select definitions */
37 +enum p5_interface_select {
38 + P5_DISABLED = 0,
39 + P5_INTF_SEL_PHY_P0,
40 + P5_INTF_SEL_PHY_P4,
41 + P5_INTF_SEL_GMAC5,
42 +};
43 +
44 +static const char *p5_intf_modes(unsigned int p5_interface)
45 +{
46 + switch (p5_interface) {
47 + case P5_DISABLED:
48 + return "DISABLED";
49 + case P5_INTF_SEL_PHY_P0:
50 + return "PHY P0";
51 + case P5_INTF_SEL_PHY_P4:
52 + return "PHY P4";
53 + case P5_INTF_SEL_GMAC5:
54 + return "GMAC5";
55 + default:
56 + return "unknown";
57 + }
58 +}
59 
60  struct mt7620_gsw {
61  struct device *dev;
62 @@ -103,6 +146,8 @@ struct mt7620_gsw {
63  int irq;
64  int port4;
65  unsigned long int autopoll;
66 + phy_interface_t p5_interface;
67 + unsigned int p5_intf_sel;
68  };
69 
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
75 @@ -16,6 +16,8 @@
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>
83 
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);
87 
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)
91 + continue;
92 +
93 +
94  if (reg & BIT(i)) {
95  unsigned int link;
96 
97 @@ -60,12 +66,152 @@ static irqreturn_t gsw_interrupt_mt7621(int irq, void *_priv)
98  "port %d link down\n", i);
99  }
100  }
101 + }
102 
103  mt7620_handle_carrier(priv);
104 
105  return IRQ_HANDLED;
106  }
107 
108 +static void mt7530_parse_ports(struct mt7620_gsw *gsw, struct device_node *np)
109 +{
110 + struct device_node *phy_node, *ports, *port;
111 + u32 reg, id;
112 + int err;
113 +
114 + gsw->p5_interface = PHY_INTERFACE_MODE_NA;
115 + gsw->p5_intf_sel = P5_DISABLED;
116 +
117 + ports = of_get_child_by_name(np, "ports");
118 + if (!ports)
119 + return;
120 +
121 + for_each_available_child_of_node(ports, port) {
122 + err = of_property_read_u32(port, "reg", &reg);
123 + if (err)
124 + continue;
125 +
126 + if (reg != 5)
127 + break;
128 +
129 + phy_node = of_parse_phandle(port, "phy-handle", 0);
130 + if (phy_node) {
131 + gsw->p5_interface = of_get_phy_mode(port);
132 + gsw->p5_intf_sel = P5_INTF_SEL_GMAC5;
133 +
134 + id = of_mdio_parse_addr(gsw->dev, phy_node);
135 + if (id == 0)
136 + gsw->p5_intf_sel = P5_INTF_SEL_PHY_P0;
137 + if (id == 4)
138 + gsw->p5_intf_sel = P5_INTF_SEL_PHY_P4;
139 + }
140 + of_node_put(phy_node);
141 + break;
142 + }
143 +}
144 +
145 +static void mt7530_setup_port5(struct mt7620_gsw *gsw, struct device_node *np)
146 +{
147 + u8 tx_delay = 0;
148 + int val;
149 +
150 + mt7530_parse_ports(gsw, np);
151 +
152 + val = mt7530_mdio_r32(gsw, MT7530_MHWTRAP);
153 +
154 + val |= MHWTRAP_MANUAL | MHWTRAP_P5_MAC_SEL | MHWTRAP_P5_DIS;
155 + val &= ~MHWTRAP_P5_RGMII_MODE & ~MHWTRAP_PHY0_SEL;
156 +
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;
161 + /* fall through */
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;
165 +
166 + /* Setup the MAC by default for the cpu port */
167 + mt7530_mdio_w32(gsw, GSW_REG_PORT_PMCR(5), 0x56300);
168 + break;
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);
173 + break;
174 + case P5_DISABLED:
175 + gsw->p5_interface = PHY_INTERFACE_MODE_NA;
176 + break;
177 + default:
178 + dev_err(gsw->dev, "Unsupported p5_intf_sel %d\n",
179 + gsw->p5_intf_sel);
180 + goto unlock_exit;
181 + }
182 +
183 + /* Setup RGMII settings */
184 + if (phy_interface_mode_is_rgmii(gsw->p5_interface)) {
185 + val |= MHWTRAP_P5_RGMII_MODE;
186 +
187 + /* P5 RGMII RX Clock Control: delay setting for 1000M */
188 + mt7530_mdio_w32(gsw, MT7530_P5RGMIIRXCR, CSR_RGMII_EDGE_ALIGN);
189 +
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 */
196 +
197 + /* P5 RGMII TX Clock Control: delay x */
198 + mt7530_mdio_w32(gsw, MT7530_P5RGMIITXCR,
199 + CSR_RGMII_TXC_CFG(0x10 + tx_delay));
200 +
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));
204 + }
205 +
206 + mt7530_mdio_w32(gsw, MT7530_MHWTRAP, val);
207 +
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));
210 +
211 +unlock_exit:
212 + return;
213 +}
214 +
215 +
216 +/* HACK: detect at803x and force at8033 at 1gbit full-duplex */
217 +static void mt7530_detect_at8033(struct mt7620_gsw *gsw)
218 +{
219 + u32 reg;
220 +
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)
225 + return;
226 +
227 + /* read phy identifier 2 */
228 + reg = _mt7620_mii_read(gsw, 7, 0x03);
229 + if (reg < 0 || reg != 0xd074)
230 + return;
231 +
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");
236 + else
237 + dev_info(gsw->dev,
238 + "phy 7 at803x mode unknown: 0x1F=0x%x\n", reg);
239 +
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);
243 + }
244 +}
245 +
246 +
247  static void mt7621_hw_init(struct mt7620_gsw *gsw, struct device_node *np)
248  {
249  u32 i;
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);
253 
254 - /* delay setting for 10/1000M */
255 - mt7530_mdio_w32(gsw, 0x7b00, 0x102);
256 - mt7530_mdio_w32(gsw, 0x7b04, 0x14);
257 -
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);
264 
265 + /* Setup port 5 */
266 + mt7530_setup_port5(gsw, np);
267 +
268 + /* HACK: Detect at8033 phy on ubnt erx-sfp */
269 + mt7530_detect_at8033(gsw);
270 +
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
278 @@ -460,7 +460,7 @@
279 
280  mediatek,switch = <&gsw>;
281 
282 - mdio-bus {
283 + mdio: mdio-bus {
284  #address-cells = <1>;
285  #size-cells = <0>;
286 
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
291 @@ -250,7 +250,6 @@
292  tl-wr841n-v13|\
293  u7628-01-128M-16M|\
294  ubnt-erx|\
295 - ubnt-erx-sfp|\
296  ur-326n4g|\
297  wrtnode|\
298  wrtnode2p | \
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"
302  ;;
303 + ubnt-erx-sfp)
304 + ucidef_add_switch "switch0" \
305 + "0:lan" "1:lan" "2:lan" "3:lan" "4:lan" "5:wan" "6@eth0"
306 + ;;
307  mikrotik,rbm33g)
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
314 @@ -21,4 +21,33 @@
315  reg = <0x25>;
316  };
317  };
318 +
319 + leds {
320 + compatible = "gpio-leds";
321 +
322 + /* Fixme: Currently a hack to enable SFP clk gate. */
323 + sfp {
324 + label = "sfp:i2c";
325 + gpios = <&gpio0 7 GPIO_ACTIVE_LOW>;
326 + default-state = "off";
327 + linux,default-trigger = "default-on";
328 + };
329 + };
330 +};
331 +
332 +&mdio {
333 + ephy5: ethernet-phy@7 {
334 + reg = <7>;
335 + };
336 +};
337 +
338 +&gsw {
339 + ports {
340 + lan5: port@5 {
341 + reg = <5>;
342 + label = "lan5";
343 + phy-handle = <&ephy5>;
344 + phy-mode = "rgmii-rxid";
345 + };
346 + };
347  };
348 diff --git a/openwrt/package/network/utils/phytool/Makefile b/openwrt/package/network/utils/phytool/Makefile
349 new file mode 100644
350 index 00000000..e385d5eb
351 --- /dev/null
352 +++ b/openwrt/package/network/utils/phytool/Makefile
353 @@ -0,0 +1,47 @@
354 +include $(TOPDIR)/rules.mk
355 +
356 +PKG_NAME:=phytool
357 +PKG_RELEASE:=1
358 +
359 +PKG_RELEASE=$(PKG_SOURCE_VERSION)
360 +
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
366 +
367 +PKG_LICENSE:=GPL-2.0
368 +PKG_LICENSE_FILES:=COPYING
369 +
370 +PKG_MAINTAINER:=Christian Lamparter <chunkeey@googlemail.com>
371 +
372 +include $(INCLUDE_DIR)/package.mk
373 +
374 +define Package/phytool
375 + SECTION:=net
376 + CATEGORY:=Network
377 + TITLE:=phytool Linux MDIO register access
378 + URL:=https://github.com/wkz/phytool.git
379 +endef
380 +
381 +define Package/phytool/description
382 + Linux MDIO register access
383 +endef
384 +
385 +define Build/Configure
386 +endef
387 +
388 +define Build/Compile
389 + $(MAKE) -C $(PKG_BUILD_DIR) \
390 + CC="$(TARGET_CC)" \
391 + CFLAGS="$(TARGET_CFLAGS) -Wall" \
392 + LDFLAGS="$(TARGET_LDFLAGS)"
393 +endef
394 +
395 +define Package/phytool/install
396 + $(INSTALL_DIR) $(1)/usr/bin
397 + $(INSTALL_BIN) $(PKG_BUILD_DIR)/phytool $(1)/usr/bin/
398 +endef
399 +
400 +$(eval $(call BuildPackage,phytool))