1 /***********************license start***********************************
2 * Copyright (c) 2003-2017 Cavium Inc. ([email protected]). All rights
3 * reserved.
4 *
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions are
8 * met:
9 *
10 * * Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 *
13 * * Redistributions in binary form must reproduce the above
14 * copyright notice, this list of conditions and the following
15 * disclaimer in the documentation and/or other materials provided
16 * with the distribution.
17 *
18 * * Neither the name of Cavium Inc. nor the names of
19 * its contributors may be used to endorse or promote products
20 * derived from this software without specific prior written
21 * permission.
22 *
23 * This Software, including technical data, may be subject to U.S. export
24 * control laws, including the U.S. Export Administration Act and its
25 * associated regulations, and may be subject to export or import
26 * regulations in other countries.
27 *
28 * TO THE MAXIMUM EXTENT PERMITTED BY LAW, THE SOFTWARE IS PROVIDED "AS IS"
29 * AND WITH ALL FAULTS AND CAVIUM INC. MAKES NO PROMISES, REPRESENTATIONS OR
30 * WARRANTIES, EITHER EXPRESS, IMPLIED, STATUTORY, OR OTHERWISE, WITH RESPECT
31 * TO THE SOFTWARE, INCLUDING ITS CONDITION, ITS CONFORMITY TO ANY
32 * REPRESENTATION OR DESCRIPTION, OR THE EXISTENCE OF ANY LATENT OR PATENT
33 * DEFECTS, AND CAVIUM SPECIFICALLY DISCLAIMS ALL IMPLIED (IF ANY) WARRANTIES
34 * OF TITLE, MERCHANTABILITY, NONINFRINGEMENT, FITNESS FOR A PARTICULAR
35 * PURPOSE, LACK OF VIRUSES, ACCURACY OR COMPLETENESS, QUIET ENJOYMENT,
36 * QUIET POSSESSION OR CORRESPONDENCE TO DESCRIPTION. THE ENTIRE RISK
37 * ARISING OUT OF USE OR PERFORMANCE OF THE SOFTWARE LIES WITH YOU.
38 ***********************license end**************************************/
39 #include <bdk.h>
40 #include <libbdk-hal/if/bdk-if.h>
41 #include <libbdk-hal/bdk-mdio.h>
42 #include <libbdk-hal/bdk-qlm.h>
43
44 static bool LOOP_INTERNAL = false;
45 static bool LOOP_EXTERNAL = false;
46
47 static uint8_t patch_arr[] = {
48 0x44, 0x83, 0x02, 0x42, 0x12, 0x02, 0x44, 0x93, 0x02, 0x44,
49 0xca, 0x02, 0x44, 0x4d, 0x02, 0x43, 0xef, 0xed, 0xff, 0xe5,
50 0xfc, 0x54, 0x38, 0x64, 0x20, 0x70, 0x08, 0x65, 0xff, 0x70,
51 0x04, 0xed, 0x44, 0x80, 0xff, 0x22, 0x8f, 0x19, 0x7b, 0xbb,
52 0x7d, 0x0e, 0x7f, 0x04, 0x12, 0x3d, 0xd7, 0xef, 0x4e, 0x60,
53 0x03, 0x02, 0x41, 0xf9, 0xe4, 0xf5, 0x1a, 0x74, 0x01, 0x7e,
54 0x00, 0xa8, 0x1a, 0x08, 0x80, 0x05, 0xc3, 0x33, 0xce, 0x33,
55 0xce, 0xd8, 0xf9, 0xff, 0xef, 0x55, 0x19, 0x70, 0x03, 0x02,
56 0x41, 0xed, 0x85, 0x1a, 0xfb, 0x7b, 0xbb, 0xe4, 0xfd, 0xff,
57 0x12, 0x3d, 0xd7, 0xef, 0x4e, 0x60, 0x03, 0x02, 0x41, 0xed,
58 0xe5, 0x1a, 0x54, 0x02, 0x75, 0x1d, 0x00, 0x25, 0xe0, 0x25,
59 0xe0, 0xf5, 0x1c, 0xe4, 0x78, 0xc5, 0xf6, 0xd2, 0x02, 0x12,
60 0x41, 0xfa, 0x7b, 0xff, 0x7d, 0x12, 0x7f, 0x07, 0x12, 0x3d,
61 0xd7, 0xef, 0x4e, 0x60, 0x03, 0x02, 0x41, 0xe7, 0xc2, 0x02,
62 0x74, 0xc7, 0x25, 0x1a, 0xf9, 0x74, 0xe7, 0x25, 0x1a, 0xf8,
63 0xe6, 0x27, 0xf5, 0x1b, 0xe5, 0x1d, 0x24, 0x5b, 0x12, 0x44,
64 0x2a, 0x12, 0x3e, 0xda, 0x7b, 0xfc, 0x7d, 0x11, 0x7f, 0x07,
65 0x12, 0x3d, 0xd7, 0x78, 0xcc, 0xef, 0xf6, 0x78, 0xc1, 0xe6,
66 0xfe, 0xef, 0xd3, 0x9e, 0x40, 0x06, 0x78, 0xcc, 0xe6, 0x78,
67 0xc1, 0xf6, 0x12, 0x41, 0xfa, 0x7b, 0xec, 0x7d, 0x12, 0x7f,
68 0x07, 0x12, 0x3d, 0xd7, 0x78, 0xcb, 0xef, 0xf6, 0xbf, 0x07,
69 0x06, 0x78, 0xc3, 0x76, 0x1a, 0x80, 0x1f, 0x78, 0xc5, 0xe6,
70 0xff, 0x60, 0x0f, 0xc3, 0xe5, 0x1b, 0x9f, 0xff, 0x78, 0xcb,
71 0xe6, 0x85, 0x1b, 0xf0, 0xa4, 0x2f, 0x80, 0x07, 0x78, 0xcb,
72 0xe6, 0x85, 0x1b, 0xf0, 0xa4, 0x78, 0xc3, 0xf6, 0xe4, 0x78,
73 0xc2, 0xf6, 0x78, 0xc2, 0xe6, 0xff, 0xc3, 0x08, 0x96, 0x40,
74 0x03, 0x02, 0x41, 0xd1, 0xef, 0x54, 0x03, 0x60, 0x33, 0x14,
75 0x60, 0x46, 0x24, 0xfe, 0x60, 0x42, 0x04, 0x70, 0x4b, 0xef,
76 0x24, 0x02, 0xff, 0xe4, 0x33, 0xfe, 0xef, 0x78, 0x02, 0xce,
77 0xa2, 0xe7, 0x13, 0xce, 0x13, 0xd8, 0xf8, 0xff, 0xe5, 0x1d,
78 0x24, 0x5c, 0xcd, 0xe5, 0x1c, 0x34, 0xf0, 0xcd, 0x2f, 0xff,
79 0xed, 0x3e, 0xfe, 0x12, 0x44, 0x6a, 0x7d, 0x11, 0x80, 0x0b,
80 0x78, 0xc2, 0xe6, 0x70, 0x04, 0x7d, 0x11, 0x80, 0x02, 0x7d,
81 0x12, 0x7f, 0x07, 0x12, 0x3e, 0x9a, 0x8e, 0x1e, 0x8f, 0x1f,
82 0x80, 0x03, 0xe5, 0x1e, 0xff, 0x78, 0xc5, 0xe6, 0x06, 0x24,
83 0xcd, 0xf8, 0xa6, 0x07, 0x78, 0xc2, 0x06, 0xe6, 0xb4, 0x1a,
84 0x0a, 0xe5, 0x1d, 0x24, 0x5c, 0x12, 0x44, 0x2a, 0x12, 0x3e,
85 0xda, 0x78, 0xc5, 0xe6, 0x65, 0x1b, 0x70, 0x82, 0x75, 0xdb,
86 0x20, 0x75, 0xdb, 0x28, 0x12, 0x44, 0x42, 0x12, 0x44, 0x42,
87 0xe5, 0x1a, 0x12, 0x44, 0x35, 0xe5, 0x1a, 0xc3, 0x13, 0x12,
88 0x44, 0x35, 0x78, 0xc5, 0x16, 0xe6, 0x24, 0xcd, 0xf8, 0xe6,
89 0xff, 0x7e, 0x08, 0x1e, 0xef, 0xa8, 0x06, 0x08, 0x80, 0x02,
90 0xc3, 0x13, 0xd8, 0xfc, 0xfd, 0xc4, 0x33, 0x54, 0xe0, 0xf5,
91 0xdb, 0xef, 0xa8, 0x06, 0x08, 0x80, 0x02, 0xc3, 0x13, 0xd8,
92 0xfc, 0xfd, 0xc4, 0x33, 0x54, 0xe0, 0x44, 0x08, 0xf5, 0xdb,
93 0xee, 0x70, 0xd8, 0x78, 0xc5, 0xe6, 0x70, 0xc8, 0x75, 0xdb,
94 0x10, 0x02, 0x40, 0xfd, 0x78, 0xc2, 0xe6, 0xc3, 0x94, 0x17,
95 0x50, 0x0e, 0xe5, 0x1d, 0x24, 0x62, 0x12, 0x42, 0x08, 0xe5,
96 0x1d, 0x24, 0x5c, 0x12, 0x42, 0x08, 0x20, 0x02, 0x03, 0x02,
97 0x40, 0x76, 0x05, 0x1a, 0xe5, 0x1a, 0xc3, 0x94, 0x04, 0x50,
98 0x03, 0x02, 0x40, 0x3a, 0x22, 0xe5, 0x1d, 0x24, 0x5c, 0xff,
99 0xe5, 0x1c, 0x34, 0xf0, 0xfe, 0x12, 0x44, 0x6a, 0x22, 0xff,
100 0xe5, 0x1c, 0x34, 0xf0, 0xfe, 0x12, 0x44, 0x6a, 0x22, 0xd2,
101 0x00, 0x75, 0xfb, 0x03, 0xab, 0x7e, 0xaa, 0x7d, 0x7d, 0x19,
102 0x7f, 0x03, 0x12, 0x3e, 0xda, 0xe5, 0x7e, 0x54, 0x0f, 0x24,
103 0xf3, 0x60, 0x03, 0x02, 0x42, 0xb9, 0x12, 0x44, 0xa3, 0x12,
104 0x44, 0xaa, 0xd8, 0xfb, 0xff, 0x20, 0xe2, 0x2a, 0x13, 0x92,
105 0x04, 0xef, 0xa2, 0xe1, 0x92, 0x03, 0x30, 0x04, 0x1f, 0xe4,
106 0xf5, 0x10, 0xe5, 0x10, 0x24, 0x17, 0xfd, 0x7b, 0x54, 0x7f,
107 0x04, 0x12, 0x3d, 0xd7, 0x74, 0x25, 0x25, 0x10, 0xf8, 0xa6,
108 0x07, 0x05, 0x10, 0xe5, 0x10, 0xc3, 0x94, 0x02, 0x40, 0xe4,
109 0x12, 0x44, 0xa3, 0x12, 0x44, 0xaa, 0xd8, 0xfb, 0x54, 0x05,
110 0x64, 0x04, 0x70, 0x27, 0x78, 0xc4, 0xe6, 0x78, 0xc6, 0xf6,
111 0xe5, 0x7d, 0xff, 0x33, 0x95, 0xe0, 0xef, 0x54, 0x0f, 0x78,
112 0xc4, 0xf6, 0x12, 0x42, 0xcf, 0x20, 0x04, 0x0c, 0x12, 0x44,
113 0xa3, 0x12, 0x44, 0xaa, 0xd8, 0xfb, 0x13, 0x92, 0x05, 0x22,
114 0xc2, 0x05, 0x22, 0x12, 0x44, 0xa3, 0x12, 0x44, 0xaa, 0xd8,
115 0xfb, 0x54, 0x05, 0x64, 0x05, 0x70, 0x1e, 0x78, 0xc4, 0x7d,
116 0xb8, 0x12, 0x42, 0xc5, 0x78, 0xc1, 0x7d, 0x74, 0x12, 0x42,
117 0xc5, 0xe4, 0x78, 0xc1, 0xf6, 0x22, 0x7b, 0x01, 0x7a, 0x00,
118 0x7d, 0xee, 0x7f, 0x92, 0x12, 0x38, 0xbd, 0x22, 0xe6, 0xfb,
119 0x7a, 0x00, 0x7f, 0x92, 0x12, 0x38, 0xbd, 0x22, 0x78, 0xc1,
120 0xe6, 0xfb, 0x7a, 0x00, 0x7d, 0x74, 0x7f, 0x92, 0x12, 0x38,
121 0xbd, 0xe4, 0x78, 0xc1, 0xf6, 0xf5, 0x11, 0x74, 0x01, 0x7e,
122 0x00, 0xa8, 0x11, 0x08, 0x80, 0x05, 0xc3, 0x33, 0xce, 0x33,
123 0xce, 0xd8, 0xf9, 0xff, 0x78, 0xc4, 0xe6, 0xfd, 0xef, 0x5d,
124 0x60, 0x44, 0x85, 0x11, 0xfb, 0xe5, 0x11, 0x54, 0x02, 0x25,
125 0xe0, 0x25, 0xe0, 0xfe, 0xe4, 0x24, 0x5b, 0xfb, 0xee, 0x12,
126 0x44, 0x2d, 0x12, 0x3e, 0xda, 0x7b, 0x40, 0x7d, 0x11, 0x7f,
127 0x07, 0x12, 0x3d, 0xd7, 0x74, 0xc7, 0x25, 0x11, 0xf8, 0xa6,
128 0x07, 0x7b, 0x11, 0x7d, 0x12, 0x7f, 0x07, 0x12, 0x3d, 0xd7,
129 0xef, 0x4e, 0x60, 0x09, 0x74, 0xe7, 0x25, 0x11, 0xf8, 0x76,
130 0x04, 0x80, 0x07, 0x74, 0xe7, 0x25, 0x11, 0xf8, 0x76, 0x0a,
131 0x05, 0x11, 0xe5, 0x11, 0xc3, 0x94, 0x04, 0x40, 0x9a, 0x78,
132 0xc6, 0xe6, 0x70, 0x15, 0x78, 0xc4, 0xe6, 0x60, 0x10, 0x75,
133 0xd9, 0x38, 0x75, 0xdb, 0x10, 0x7d, 0xfe, 0x12, 0x43, 0x7d,
134 0x7d, 0x76, 0x12, 0x43, 0x7d, 0x79, 0xc6, 0xe7, 0x78, 0xc4,
135 0x66, 0xff, 0x60, 0x03, 0x12, 0x40, 0x25, 0x78, 0xc4, 0xe6,
136 0x70, 0x09, 0xfb, 0xfa, 0x7d, 0xfe, 0x7f, 0x8e, 0x12, 0x38,
137 0xbd, 0x22, 0x7b, 0x01, 0x7a, 0x00, 0x7f, 0x8e, 0x12, 0x38,
138 0xbd, 0x22, 0xe4, 0xf5, 0x19, 0x74, 0x25, 0x25, 0x19, 0xf8,
139 0xe6, 0x64, 0x03, 0x60, 0x51, 0xe5, 0x19, 0x24, 0x17, 0xfd,
140 0x7b, 0xeb, 0x7f, 0x04, 0x12, 0x3d, 0xd7, 0x8f, 0xfb, 0x7b,
141 0x22, 0x7d, 0x18, 0x7f, 0x06, 0x12, 0x3d, 0xd7, 0xef, 0x64,
142 0x01, 0x4e, 0x60, 0x1c, 0x7d, 0x1c, 0xe4, 0xff, 0x12, 0x3e,
143 0x9a, 0xef, 0x54, 0x1b, 0x64, 0x0a, 0x70, 0x15, 0x7b, 0xcc,
144 0x7d, 0x10, 0xff, 0x12, 0x3d, 0xd7, 0xef, 0x64, 0x01, 0x4e,
145 0x70, 0x07, 0x12, 0x44, 0xb1, 0x7b, 0x03, 0x80, 0x0a, 0x12,
146 0x44, 0xb1, 0x74, 0x25, 0x25, 0x19, 0xf8, 0xe6, 0xfb, 0x7a,
147 0x00, 0x7d, 0x54, 0x12, 0x38, 0xbd, 0x05, 0x19, 0xe5, 0x19,
148 0xc3, 0x94, 0x02, 0x40, 0x9c, 0x22, 0xe5, 0x7e, 0x30, 0xe5,
149 0x35, 0x30, 0xe4, 0x0b, 0x7b, 0x02, 0x7d, 0x33, 0x7f, 0x35,
150 0x12, 0x36, 0x29, 0x80, 0x10, 0x7b, 0x01, 0x7d, 0x33, 0x7f,
151 0x35, 0x12, 0x36, 0x29, 0x90, 0x47, 0xd2, 0xe0, 0x44, 0x04,
152 0xf0, 0x90, 0x47, 0xd2, 0xe0, 0x54, 0xf7, 0xf0, 0x90, 0x47,
153 0xd1, 0xe0, 0x44, 0x10, 0xf0, 0x7b, 0x05, 0x7d, 0x84, 0x7f,
154 0x86, 0x12, 0x36, 0x29, 0x22, 0xfb, 0xe5, 0x1c, 0x34, 0xf0,
155 0xfa, 0x7d, 0x10, 0x7f, 0x07, 0x22, 0x54, 0x01, 0xc4, 0x33,
156 0x54, 0xe0, 0xf5, 0xdb, 0x44, 0x08, 0xf5, 0xdb, 0x22, 0xf5,
157 0xdb, 0x75, 0xdb, 0x08, 0xf5, 0xdb, 0x75, 0xdb, 0x08, 0x22,
158 0xe5, 0x7e, 0x54, 0x0f, 0x64, 0x01, 0x70, 0x0d, 0xe5, 0x7e,
159 0x30, 0xe4, 0x08, 0x90, 0x47, 0xd0, 0xe0, 0x44, 0x02, 0xf0,
160 0x22, 0x90, 0x47, 0xd0, 0xe0, 0x54, 0xfd, 0xf0, 0x22, 0xab,
161 0x07, 0xaa, 0x06, 0x7d, 0x10, 0x7f, 0x07, 0x12, 0x3e, 0xda,
162 0x7b, 0xff, 0x7d, 0x10, 0x7f, 0x07, 0x12, 0x3d, 0xd7, 0xef,
163 0x4e, 0x60, 0xf3, 0x22, 0x12, 0x44, 0xc5, 0x12, 0x44, 0xbb,
164 0x90, 0x47, 0xfa, 0xe0, 0x54, 0xf8, 0x44, 0x02, 0xf0, 0x22,
165 0x30, 0x04, 0x03, 0x12, 0x43, 0x87, 0x78, 0xc4, 0xe6, 0xff,
166 0x60, 0x03, 0x12, 0x40, 0x25, 0x22, 0xe5, 0x7e, 0xae, 0x7d,
167 0x78, 0x04, 0x22, 0xce, 0xa2, 0xe7, 0x13, 0xce, 0x13, 0x22,
168 0xe5, 0x19, 0x24, 0x17, 0x54, 0x1f, 0x44, 0x80, 0xff, 0x22,
169 0xe4, 0x78, 0xc4, 0xf6, 0xc2, 0x05, 0x78, 0xc1, 0xf6, 0x22,
170 0xc2, 0x04, 0xc2, 0x03, 0x22, 0x22
171 };
172
173 /**
174 * Setup Vitesse PHYs
175 * This function sets up one port in a Vitesse VSC8574 for
176 * either SGMII or QSGMII
177 */
setup_vitesse_phy(bdk_node_t node,int mdio_bus,int phy_addr,bool qsgmii)178 static void setup_vitesse_phy(bdk_node_t node, int mdio_bus, int phy_addr, bool qsgmii)
179 {
180 // Select "G" registers
181 bdk_mdio_write(node, mdio_bus, phy_addr, 31, 0x10);
182 // Reg 19G, bit 15:14
183 // 0 = SGMII
184 // 1 = QSGMII
185 int reg19 = bdk_mdio_read(node, mdio_bus, phy_addr, 19);
186 int reg18;
187 if (qsgmii)
188 {
189 // QSGMII
190 reg19 = (reg19 & ~(3 << 14)) | (1 << 14);
191 reg18 = 0x80e0;
192 }
193 else
194 {
195 // SGMII
196 reg19 = (reg19 & ~(3 << 14)) | (0 << 14);
197 reg18 = 0x80f0;
198 }
199 bdk_mdio_write(node, mdio_bus, phy_addr, 19, reg19);
200 // Write 18G, change all 4 ports
201 bdk_mdio_write(node, mdio_bus, phy_addr, 18, reg18);
202 // Select main registers
203 bdk_mdio_write(node, mdio_bus, phy_addr, 31, 0);
204 // Reg23, 10:8 Select copper
205 int reg23 = bdk_mdio_read(node, mdio_bus, phy_addr, 23);
206 reg23 = (reg23 & ~(7 << 8)) | (0 << 8);
207 bdk_mdio_write(node, mdio_bus, phy_addr, 23, reg23);
208 // Reg0, Reset
209 int reg0 = bdk_mdio_read(node, mdio_bus, phy_addr, 0);
210 reg0 |= (1 << 15);
211 bdk_mdio_write(node, mdio_bus, phy_addr, 0, reg0);
212 // Reg 16E3, bit 7 auto negotiation
213 bdk_mdio_write(node, mdio_bus, phy_addr, 31, 3);
214 bdk_mdio_write(node, mdio_bus, phy_addr, 16, 0x80);
215 // Select main registers
216 bdk_mdio_write(node, mdio_bus, phy_addr, 31, 0);
217 // Near end loopback (Thunder side)
218 if (LOOP_INTERNAL)
219 {
220 reg0 = bdk_mdio_read(node, mdio_bus, phy_addr, 0);
221 reg0 |= (1 << 14);
222 bdk_mdio_write(node, mdio_bus, phy_addr, 0, reg0);
223 }
224
225 // Far end loopback (External side)
226 if (LOOP_EXTERNAL)
227 {
228 reg23 = bdk_mdio_read(node, mdio_bus, phy_addr, 23);
229 reg23 |= (1 << 3);
230 bdk_mdio_write(node, mdio_bus, phy_addr, 23, reg23);
231 }
232 }
233
wr_masked(bdk_node_t node,int mdio_bus,int phy_addr,int reg,int value,int mask)234 static void wr_masked(bdk_node_t node, int mdio_bus, int phy_addr, int reg, int value, int mask)
235 {
236 int nmask = ~mask;
237 int old = bdk_mdio_read(node, mdio_bus, phy_addr, reg);
238 int vmask = value & mask;
239 int newv = old & nmask;
240 newv = newv | vmask;
241 bdk_mdio_write(node, mdio_bus, phy_addr, reg, newv);
242 }
243
vitesse_program(bdk_node_t node,int mdio_bus,int phy_addr)244 static void vitesse_program(bdk_node_t node, int mdio_bus, int phy_addr)
245 {
246 printf("Programming Vitesse PHY at address %d\n", phy_addr);
247 bdk_mdio_write(node, mdio_bus, phy_addr, 31, 0x0010);
248 bdk_mdio_write(node, mdio_bus, phy_addr, 18, 0x800f);
249 bdk_mdio_write(node, mdio_bus, phy_addr, 31, 0x0010);
250
251 int reg18g = bdk_mdio_read(node, mdio_bus, phy_addr, 18);
252 int timeout = 10;
253 while ((reg18g & (1<<15)) && (timeout > 0))
254 {
255 bdk_wait_usec(100000);
256 reg18g = bdk_mdio_read(node, mdio_bus, phy_addr, 18);
257 timeout = timeout - 1;
258 }
259 if (timeout == 0)
260 bdk_error("Vetesse: Timeout waiting for complete\n");
261
262 bdk_mdio_write(node, mdio_bus, phy_addr, 31, 0x0000);
263 bdk_mdio_write(node, mdio_bus, phy_addr, 31, 0x0010);
264 wr_masked(node, mdio_bus, phy_addr, 12, 0x0000, 0x0800);
265 bdk_mdio_write(node, mdio_bus, phy_addr, 9, 0x005b);
266 bdk_mdio_write(node, mdio_bus, phy_addr, 10, 0x005b);
267 wr_masked(node, mdio_bus, phy_addr, 12, 0x0800, 0x0800);
268 bdk_mdio_write(node, mdio_bus, phy_addr, 18, 0x800f);
269 wr_masked(node, mdio_bus, phy_addr, 0, 0x0000, 0x8000);
270 bdk_mdio_write(node, mdio_bus, phy_addr, 18, 0x0000);
271 wr_masked(node, mdio_bus, phy_addr, 12, 0x0000, 0x0800);
272 bdk_mdio_write(node, mdio_bus, phy_addr, 31, 0x10);
273 bdk_mdio_write(node, mdio_bus, phy_addr, 0, 0x7009);
274 bdk_mdio_write(node, mdio_bus, phy_addr, 12, 0x5002);
275 bdk_mdio_write(node, mdio_bus, phy_addr, 11, 0x0000);
276
277 for (unsigned int i=0; i<sizeof(patch_arr); i++)
278 {
279 int d = 0x5000 | patch_arr[i];
280 bdk_mdio_write(node, mdio_bus, phy_addr, 12, d);
281 }
282 bdk_mdio_write(node, mdio_bus, phy_addr, 12, 0x0000);
283
284 bdk_mdio_write(node, mdio_bus, phy_addr, 3, 0x3eb7);
285 bdk_mdio_write(node, mdio_bus, phy_addr, 4, 0x4012);
286 bdk_mdio_write(node, mdio_bus, phy_addr, 12, 0x0100);
287 bdk_mdio_write(node, mdio_bus, phy_addr, 0, 0x4018);
288 bdk_mdio_write(node, mdio_bus, phy_addr, 0, 0xc018);
289
290 // below verifies CRC is correct in 8051 RAM. CRC is 16-bit.
291 bdk_mdio_write(node, mdio_bus, phy_addr, 31, 0x0001);
292 bdk_mdio_write(node, mdio_bus, phy_addr, 25, 0x4000);
293 bdk_mdio_write(node, mdio_bus, phy_addr, 26, sizeof(patch_arr) + 1);
294 bdk_mdio_write(node, mdio_bus, phy_addr, 31, 0x0010);
295 bdk_mdio_write(node, mdio_bus, phy_addr, 18, 0x8008);
296
297 reg18g = bdk_mdio_read(node, mdio_bus, phy_addr, 18);
298 timeout = 10;
299 while ((reg18g & (1<<15)) && (timeout > 0))
300 {
301 bdk_wait_usec(100000);
302 reg18g = bdk_mdio_read(node, mdio_bus, phy_addr, 18);
303 timeout = timeout - 1;
304 }
305 if (timeout == 0)
306 bdk_error("Vetesse: Timeout waiting for complete\n");
307
308 bdk_mdio_write(node, mdio_bus, phy_addr, 31, 0x0001);
309
310 int crc_calculated = bdk_mdio_read(node, mdio_bus, phy_addr, 25);
311 if (crc_calculated != 0xB7C2)
312 printf("8051 crc_calculated = 0x%x, expected_crc = 0x%x\n", crc_calculated, 0xB7C2);
313
314 bdk_mdio_write(node, mdio_bus, phy_addr, 31, 0x0000);
315 }
316
317 //static void vetesse_setup(bdk_node_t node, int qlm, int mdio_bus, int phy_addr)
bdk_if_phy_vetesse_setup(bdk_node_t node,int qlm,int mdio_bus,int phy_addr)318 int bdk_if_phy_vetesse_setup(bdk_node_t node, int qlm, int mdio_bus, int phy_addr)
319 {
320 /* Check if the PHY is Vetesse PHY we expect */
321 int phy_status = bdk_mdio_read(node, mdio_bus, phy_addr, BDK_MDIO_PHY_REG_ID1);
322 if (phy_status != 0x0007)
323 return 0;
324
325 /* Check that the GSER mode is SGMII or QSGMII */
326 bdk_qlm_modes_t qlm_mode = bdk_qlm_get_mode(node, qlm);
327 if ((qlm_mode != BDK_QLM_MODE_SGMII_1X1) &&
328 (qlm_mode != BDK_QLM_MODE_SGMII_2X1) &&
329 (qlm_mode != BDK_QLM_MODE_SGMII_4X1) &&
330 (qlm_mode != BDK_QLM_MODE_QSGMII_4X1))
331 return 0;
332
333 /* Program the Vetesse PHY */
334 vitesse_program(node, mdio_bus, phy_addr);
335
336 /* Switch the Vitesse PHY to the correct mode */
337 bool is_qsgmii = (qlm_mode == BDK_QLM_MODE_QSGMII_4X1);
338 if (is_qsgmii)
339 {
340 for (int port = 0; port < 4; port++)
341 setup_vitesse_phy(node, mdio_bus, phy_addr + port, true);
342 }
343 else
344 setup_vitesse_phy(node, mdio_bus, phy_addr, false);
345 return 0;
346 }
347
348 #if 0
349 int bdk_if_phy_vetesse_setup(bdk_node_t node)
350 {
351 for (int bgx = 0; bgx < 4; bgx++)
352 {
353 int port = 0;
354 int phy_addr = bdk_config_get_int(BDK_CONFIG_PHY_ADDRESS, node, bgx, port);
355 if (phy_addr != -1)
356 {
357 int node = (phy_addr >> 24) & 0xff;
358 int mdio_bus = (phy_addr >> 8) & 0xff;
359 int mdio_addr = phy_addr & 0xff;
360 if (node == 0xff)
361 node = bdk_numa_local();
362 if ((phy_addr & BDK_IF_PHY_TYPE_MASK) == BDK_IF_PHY_MDIO)
363 {
364 int qlm = bdk_qlm_get(node, BDK_IF_BGX, bgx, port);
365 if (qlm != -1)
366 vetesse_setup(node, qlm, mdio_bus, mdio_addr);
367 }
368 }
369 }
370 return 0;
371 }
372 #endif
373