xref: /aosp_15_r20/external/coreboot/src/vendorcode/cavium/bdk/libbdk-hal/if/bdk-if-phy-vetesse.c (revision b9411a12aaaa7e1e6a6fb7c5e057f44ee179a49c)
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