blob: ad822bb55879e103f1a5541d53650b03e60fcc18 [file] [log] [blame]
developerfd40db22021-04-29 10:08:25 +08001/* Copyright 2016 MediaTek Inc.
2 * Author: Nelson Chang <nelson.chang@mediatek.com>
3 * Author: Carlos Huang <carlos.huang@mediatek.com>
4 * Author: Harry Huang <harry.huang@mediatek.com>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 */
15#include "raether.h"
16
17void enable_auto_negotiate(struct END_DEVICE *ei_local)
18{
19 u32 reg_value;
20 pr_info("=================================\n");
21 pr_info("enable_auto_negotiate\n");
22
23 /* FIXME: we don't know how to deal with PHY end addr */
24 reg_value = sys_reg_read(ESW_PHY_POLLING);
25 reg_value |= (1 << 31);
26 reg_value &= ~(0x1f);
27 reg_value &= ~(0x1f << 8);
28
29 if (ei_local->architecture & (GE2_RGMII_AN | GE2_SGMII_AN)) {
30 /* setup PHY address for auto polling (Start Addr). */
31 /*avoid end phy address = 0 */
32 reg_value |= ((mac_to_gigaphy_mode_addr2 - 1) & 0x1f);
33 /* setup PHY address for auto polling (End Addr). */
34 reg_value |= (mac_to_gigaphy_mode_addr2 << 8);
35 } else if (ei_local->architecture & (GE1_RGMII_AN | GE1_SGMII_AN | LEOPARD_EPHY)) {
36 /* setup PHY address for auto polling (Start Addr). */
37 reg_value |= (mac_to_gigaphy_mode_addr << 0);
38 /* setup PHY address for auto polling (End Addr). */
39 reg_value |= ((mac_to_gigaphy_mode_addr + 1) << 8);
40 }
41
42 sys_reg_write(ESW_PHY_POLLING, reg_value);
43}
44
45void ra2880stop(struct END_DEVICE *ei_local)
46{
47 unsigned int reg_value;
48
49 pr_info("ra2880stop()...");
50
51 reg_value = sys_reg_read(DMA_GLO_CFG);
52 reg_value &= ~(TX_WB_DDONE | RX_DMA_EN | TX_DMA_EN);
53 sys_reg_write(DMA_GLO_CFG, reg_value);
54
55 pr_info("Done\n");
56}
57
58void set_mac_address(unsigned char p[6])
59{
60 unsigned long reg_value;
61
62 reg_value = (p[0] << 8) | (p[1]);
63 sys_reg_write(GDMA1_MAC_ADRH, reg_value);
64
65 reg_value = (unsigned long)((p[2] << 24) | (p[3] << 16) | (p[4] << 8) | p[5]);
66 sys_reg_write(GDMA1_MAC_ADRL, reg_value);
67}
68
69void set_mac2_address(unsigned char p[6])
70{
71 unsigned long reg_value;
72
73 reg_value = (p[0] << 8) | (p[1]);
74 sys_reg_write(GDMA2_MAC_ADRH, reg_value);
75
76 reg_value = (unsigned long)((p[2] << 24) | (p[3] << 16) | (p[4] << 8) | p[5]);
77 sys_reg_write(GDMA2_MAC_ADRL, reg_value);
78}
79
80static int getnext(const char *src, int separator, char *dest)
81{
82 char *c;
83 int len;
84
85 if (!src || !dest)
86 return -1;
87
88 c = strchr(src, separator);
89 if (!c) {
90 strcpy(dest, src);
91 return -1;
92 }
93 len = c - src;
94 strncpy(dest, src, len);
95 dest[len] = '\0';
96 return len + 1;
97}
98
99int str_to_ip(unsigned int *ip, const char *str)
100{
101 int len;
102 const char *ptr = str;
103 char buf[128];
104 unsigned char c[4];
105 int i;
106 int ret;
107
108 for (i = 0; i < 3; ++i) {
109 len = getnext(ptr, '.', buf);
110 if (len == -1)
111 return 1; /* parse error */
112
113 ret = kstrtoul(buf, 10, (unsigned long *)&c[i]);
114 if (ret)
115 return ret;
116
117 ptr += len;
118 }
119 ret = kstrtoul(ptr, 0, (unsigned long *)&c[3]);
120 if (ret)
121 return ret;
122
123 *ip = (c[0] << 24) + (c[1] << 16) + (c[2] << 8) + c[3];
124
125 return 0;
126}
127
128void set_ge1_force_1000(void)
129{
130 sys_reg_write(ETHDMASYS_ETH_MAC_BASE + 0x100, 0x2105e33b);
131}
132
133void set_ge2_force_1000(void)
134{
135 sys_reg_write(ETHDMASYS_ETH_MAC_BASE + 0x200, 0x2105e33b);
136}
137
138void set_ge1_an(void)
139{
140 sys_reg_write(ETHDMASYS_ETH_MAC_BASE + 0x100, 0x21056300);
141}
142
143void set_ge2_an(void)
144{
145 sys_reg_write(ETHDMASYS_ETH_MAC_BASE + 0x200, 0x21056300);
146}
147
148void set_ge2_gmii(void)
149{
150 void __iomem *virt_addr;
151 unsigned int reg_value;
152
153 virt_addr = ioremap(ETHSYS_BASE, 0x20);
154 reg_value = sys_reg_read(virt_addr + 0x14);
155 /*[15:14] =0 RGMII, [8] = 0 SGMII disable*/
156 reg_value = reg_value & (~0xc100);
157 reg_value = reg_value | 0x4000;
158 sys_reg_write(virt_addr + 0x14, reg_value);
159 iounmap(virt_addr);
160}
161
162void set_ge0_gmii(void)
163{
164 void __iomem *virt_addr;
165 unsigned int reg_value;
166
167 virt_addr = ioremap(ETHSYS_BASE, 0x20);
168 reg_value = sys_reg_read(virt_addr + 0x14);
169 /*[15:14] =0 RGMII, [8] = 0 SGMII disable*/
170 reg_value = reg_value & (~0xc000);
171 reg_value = reg_value | 0x400;
172 sys_reg_write(virt_addr + 0x14, reg_value);
173 iounmap(virt_addr);
174}
175
176void set_ge2_force_link_down(void)
177{
178 sys_reg_write(ETHDMASYS_ETH_MAC_BASE + 0x200, 0x2105e300);
179}