Print this page
9724 qede needs updates for newer GCC
Split |
Close |
Expand all |
Collapse all |
--- old/usr/src/uts/common/io/qede/579xx/drivers/ecore/ecore_phy.c
+++ new/usr/src/uts/common/io/qede/579xx/drivers/ecore/ecore_phy.c
1 1 /*
2 2 * CDDL HEADER START
3 3 *
4 4 * The contents of this file are subject to the terms of the
5 5 * Common Development and Distribution License, v.1, (the "License").
6 6 * You may not use this file except in compliance with the License.
7 7 *
8 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 9 * or http://opensource.org/licenses/CDDL-1.0.
10 10 * See the License for the specific language governing permissions
11 11 * and limitations under the License.
12 12 *
13 13 * When distributing Covered Code, include this CDDL HEADER in each
14 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 15 * If applicable, add the following below this CDDL HEADER, with the
16 16 * fields enclosed by brackets "[]" replaced with your own identifying
17 17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 18 *
19 19 * CDDL HEADER END
20 20 */
21 21
22 22 /*
23 23 * Copyright 2014-2017 Cavium, Inc.
24 24 * The contents of this file are subject to the terms of the Common Development
25 25 * and Distribution License, v.1, (the "License").
↓ open down ↓ |
25 lines elided |
↑ open up ↑ |
26 26
27 27 * You may not use this file except in compliance with the License.
28 28
29 29 * You can obtain a copy of the License at available
30 30 * at http://opensource.org/licenses/CDDL-1.0
31 31
32 32 * See the License for the specific language governing permissions and
33 33 * limitations under the License.
34 34 */
35 35
36 +/*
37 + * Copyright 2018 Joyent, Inc.
38 + */
39 +
36 40 #include "bcm_osal.h"
37 41 #include "ecore.h"
38 42 #include "reg_addr.h"
39 43 #include "ecore_hw.h"
40 44 #include "ecore_hsi_common.h"
41 45 #include "ecore_mcp.h"
42 46 #include "nvm_cfg.h"
43 47 #include "ecore_phy_api.h"
44 48
45 49 #define SERDESID 0x900e
46 50
47 51
48 52 enum _ecore_status_t ecore_phy_read(struct ecore_hwfn *p_hwfn,
49 53 struct ecore_ptt *p_ptt, u32 port, u32 lane,
50 54 u32 addr, u32 cmd, u8 *buf)
51 55 {
52 56 return ecore_mcp_phy_read(p_hwfn->p_dev, cmd,
53 57 addr | (lane << 16) | (1<<29) | (port << 30), buf, 8);
54 58 }
55 59
56 60 enum _ecore_status_t ecore_phy_write(struct ecore_hwfn *p_hwfn,
57 61 struct ecore_ptt *p_ptt, u32 port,
58 62 u32 lane, u32 addr, u32 data_lo,
59 63 u32 data_hi, u32 cmd)
60 64 {
61 65 u8 buf64[8] = {0};
62 66
63 67 OSAL_MEMCPY(buf64, &data_lo, 4);
64 68 OSAL_MEMCPY(buf64 + 4, &data_hi, 4);
65 69
66 70 return ecore_mcp_phy_write(p_hwfn->p_dev, cmd,
67 71 addr | (lane << 16) | (1<<29) | (port << 30),
68 72 buf64, 8);
69 73 }
70 74
71 75 /* phy core write */
72 76 int ecore_phy_core_write(struct ecore_hwfn *p_hwfn, struct ecore_ptt *p_ptt,
73 77 u32 port, u32 addr, u32 data_lo, u32 data_hi,
74 78 char *p_phy_result_buf)
75 79 {
76 80 enum _ecore_status_t rc = ECORE_INVAL;
77 81
78 82 if (port > 3) {
79 83 OSAL_SPRINTF(p_phy_result_buf,
80 84 "ERROR! Port must be in range of 0..3\n");
81 85 return rc;
82 86 }
83 87
84 88 /* write to address */
85 89 rc = ecore_phy_write(p_hwfn, p_ptt, port, 0 /* lane */, addr, data_lo,
86 90 data_hi, ECORE_PHY_CORE_WRITE);
87 91 if (rc == ECORE_SUCCESS)
88 92 OSAL_SPRINTF(p_phy_result_buf, "0\n");
89 93 else
90 94 OSAL_SPRINTF(p_phy_result_buf,
91 95 "Failed placing phy_core command\n");
92 96
93 97 return rc;
94 98 }
95 99
96 100 /* phy core read */
97 101 int ecore_phy_core_read(struct ecore_hwfn *p_hwfn, struct ecore_ptt *p_ptt,
98 102 u32 port, u32 addr, char *p_phy_result_buf)
99 103 {
100 104 enum _ecore_status_t rc = ECORE_INVAL;
101 105 u8 buf64[8] = {0};
102 106 u8 data_hi[4];
103 107 u8 data_lo[4];
104 108
105 109 if (port > 3) {
106 110 OSAL_SPRINTF(p_phy_result_buf,
107 111 "ERROR! Port must be in range of 0..3\n");
108 112 return rc;
109 113 }
110 114
111 115 /* read from address */
112 116 rc = ecore_phy_read(p_hwfn, p_ptt, port, 0 /* lane */ , addr,
113 117 ECORE_PHY_CORE_READ, buf64);
114 118 if (rc == ECORE_SUCCESS) {
115 119 OSAL_MEMCPY(data_lo, buf64, 4);
116 120 OSAL_MEMCPY(data_hi, (buf64 + 4), 4);
117 121 OSAL_SPRINTF(p_phy_result_buf, "0x%08x%08x\n",
118 122 *(u32 *)data_hi, *(u32 *)data_lo);
119 123 }
120 124 else
121 125 OSAL_SPRINTF(p_phy_result_buf, "Failed placing phy_core command\n");
122 126
123 127 return rc;
124 128 }
125 129
126 130 /* phy raw write */
127 131 int ecore_phy_raw_write(struct ecore_hwfn *p_hwfn, struct ecore_ptt *p_ptt,
128 132 u32 port, u32 lane, u32 addr, u32 data_lo,
129 133 u32 data_hi, char *p_phy_result_buf)
130 134 {
131 135 enum _ecore_status_t rc = ECORE_INVAL;
132 136
133 137 /* check if the enterd port is in the range */
134 138 if (port > 3) {
135 139 OSAL_SPRINTF(p_phy_result_buf,
136 140 "Port must be in range of 0..3\n");
137 141 return rc;
138 142 }
139 143
140 144 /* check if the enterd lane is in the range */
141 145 if (lane > 6) {
142 146 OSAL_SPRINTF(p_phy_result_buf,
143 147 "Lane must be in range of 0..6\n");
144 148 return rc;
145 149 }
146 150
147 151 /* write to address*/
148 152 rc = ecore_phy_write(p_hwfn,p_ptt, port, lane, addr, data_lo,
149 153 data_hi, ECORE_PHY_RAW_WRITE);
150 154 if (rc == ECORE_SUCCESS)
151 155 OSAL_SPRINTF(p_phy_result_buf, "0\n");
152 156 else
153 157 OSAL_SPRINTF(p_phy_result_buf,
154 158 "Failed placing phy_core command\n");
155 159
156 160 return rc;
157 161 }
158 162
159 163 /* phy raw read */
160 164 int ecore_phy_raw_read(struct ecore_hwfn *p_hwfn, struct ecore_ptt *p_ptt,
161 165 u32 port, u32 lane, u32 addr, char *p_phy_result_buf)
162 166 {
163 167 enum _ecore_status_t rc = ECORE_INVAL;
164 168 u8 buf64[8] = {0};
165 169 u8 data_hi[4];
166 170 u8 data_lo[4];
167 171
168 172 /* check if the enterd port is in the range */
169 173 if (port > 3) {
170 174 OSAL_SPRINTF(p_phy_result_buf,
171 175 "Port must be in range of 0..3\n");
172 176 return rc;
173 177 }
174 178
175 179 /* check if the enterd lane is in the range */
176 180 if (lane > 6) {
177 181 OSAL_SPRINTF(p_phy_result_buf,
178 182 "Lane must be in range of 0..6\n");
179 183 return rc;
180 184 }
181 185
182 186 /* read from address */
183 187 rc = ecore_phy_read(p_hwfn,p_ptt, port, lane, addr, ECORE_PHY_RAW_READ,
184 188 buf64);
185 189 if (rc == ECORE_SUCCESS) {
186 190 OSAL_MEMCPY(data_lo, buf64, 4);
187 191 OSAL_MEMCPY(data_hi, (buf64 + 4), 4);
188 192 OSAL_SPRINTF(p_phy_result_buf, "0x%08x%08x\n",
189 193 *(u32 *)data_hi, *(u32 *)data_lo);
190 194 } else {
191 195 OSAL_SPRINTF(p_phy_result_buf,
192 196 "Failed placing phy_core command\n");
193 197 }
194 198
195 199 return rc;
196 200 }
197 201
198 202 static u32 ecore_phy_get_nvm_cfg1_addr(struct ecore_hwfn *p_hwfn,
199 203 struct ecore_ptt *p_ptt)
200 204 {
201 205 u32 nvm_cfg_addr, nvm_cfg1_offset;
202 206
203 207 nvm_cfg_addr = ecore_rd(p_hwfn, p_ptt, MISC_REG_GEN_PURP_CR0);
204 208 nvm_cfg1_offset = ecore_rd(p_hwfn, p_ptt, nvm_cfg_addr +
205 209 offsetof(struct nvm_cfg,
206 210 sections_offset[NVM_CFG_SECTION_NVM_CFG1]));
207 211 return MCP_REG_SCRATCH + nvm_cfg1_offset;
208 212 }
209 213
210 214 /* get phy info */
211 215 int ecore_phy_info(struct ecore_hwfn *p_hwfn, struct ecore_ptt *p_ptt,
212 216 char *p_phy_result_buf)
213 217 {
214 218 u32 nvm_cfg1_addr = ecore_phy_get_nvm_cfg1_addr(p_hwfn, p_ptt);
215 219 u32 port_mode, port, max_ports, core_cfg, length = 0;
216 220 enum _ecore_status_t rc = ECORE_INVAL;
217 221 u8 buf64[8] = {0};
218 222 u8 data_hi[4];
219 223 u8 data_lo[4];
220 224
221 225 u8 is_bb = ((ecore_rd(p_hwfn, p_ptt, MISCS_REG_CHIP_NUM) & 0x8070)
222 226 != 0x8070);
223 227
224 228 if (is_bb)
225 229 length += OSAL_SPRINTF(&p_phy_result_buf[length],
226 230 "Device: BB ");
227 231 else
228 232 length += OSAL_SPRINTF(&p_phy_result_buf[length],
229 233 "Device: AH ");
230 234
231 235 core_cfg = ecore_rd(p_hwfn, p_ptt, nvm_cfg1_addr +
232 236 offsetof(struct nvm_cfg1, glob.core_cfg));
233 237 port_mode = (core_cfg & NVM_CFG1_GLOB_NETWORK_PORT_MODE_MASK) >>
234 238 NVM_CFG1_GLOB_NETWORK_PORT_MODE_OFFSET;
235 239 switch (port_mode) {
236 240 case NVM_CFG1_GLOB_NETWORK_PORT_MODE_BB_1X100G:
237 241 length += OSAL_SPRINTF(&p_phy_result_buf[length], "1x100G\n");
238 242 max_ports = 1;
239 243 break;
240 244 case NVM_CFG1_GLOB_NETWORK_PORT_MODE_1X40G:
241 245 length += OSAL_SPRINTF(&p_phy_result_buf[length], "1x40G\n");
242 246 max_ports = 1;
243 247 break;
244 248 case NVM_CFG1_GLOB_NETWORK_PORT_MODE_1X25G:
245 249 length += OSAL_SPRINTF(&p_phy_result_buf[length], "1x25G\n");
246 250 max_ports = 1;
247 251 break;
248 252 case NVM_CFG1_GLOB_NETWORK_PORT_MODE_BB_2X40G:
249 253 length += OSAL_SPRINTF(&p_phy_result_buf[length], "2x40G\n");
250 254 max_ports = 2;
251 255 break;
252 256 case NVM_CFG1_GLOB_NETWORK_PORT_MODE_2X50G:
253 257 length += OSAL_SPRINTF(&p_phy_result_buf[length], "2x50G\n");
254 258 max_ports = 2;
255 259 break;
256 260 case NVM_CFG1_GLOB_NETWORK_PORT_MODE_2X25G:
257 261 length += OSAL_SPRINTF(&p_phy_result_buf[length], "2x25G\n");
258 262 max_ports = 2;
259 263 break;
260 264 case NVM_CFG1_GLOB_NETWORK_PORT_MODE_2X10G:
261 265 length += OSAL_SPRINTF(&p_phy_result_buf[length], "2x10G\n");
262 266 max_ports = 2;
263 267 break;
264 268 case NVM_CFG1_GLOB_NETWORK_PORT_MODE_4X10G_F:
265 269 length += OSAL_SPRINTF(&p_phy_result_buf[length], "4x10G\n");
266 270 max_ports = 4;
267 271 break;
268 272 case NVM_CFG1_GLOB_NETWORK_PORT_MODE_BB_4X10G_E:
269 273 length += OSAL_SPRINTF(&p_phy_result_buf[length], "4x10G\n");
270 274 max_ports = 4;
271 275 break;
272 276 case NVM_CFG1_GLOB_NETWORK_PORT_MODE_BB_4X20G:
273 277 length += OSAL_SPRINTF(&p_phy_result_buf[length], "4x20G\n");
274 278 max_ports = 4;
275 279 break;
276 280 case NVM_CFG1_GLOB_NETWORK_PORT_MODE_4X25G:
277 281 length += OSAL_SPRINTF(&p_phy_result_buf[length], "4x25G\n");
278 282 max_ports = 4;
279 283 break;
280 284 default:
281 285 length += OSAL_SPRINTF(&p_phy_result_buf[length],
282 286 "Wrong port mode\n");
283 287 return rc;
284 288 }
285 289
286 290 if (is_bb) {
287 291 for (port = 0; port < max_ports; port++) {
288 292 rc = ecore_phy_read(p_hwfn, p_ptt, port, 0, SERDESID,
289 293 DRV_MSG_CODE_PHY_RAW_READ, buf64);
290 294 if (rc == ECORE_SUCCESS) {
291 295 length += OSAL_SPRINTF(
292 296 &p_phy_result_buf[length],
293 297 "Port %d is in ", port);
294 298 OSAL_MEMCPY(data_lo, buf64, 4);
295 299 OSAL_MEMCPY(data_hi, (buf64 + 4), 4);
296 300 if ((data_lo[0] & 0x3f) == 0x14)
297 301 length += OSAL_SPRINTF(
298 302 &p_phy_result_buf[length],
299 303 "Falcon\n");
300 304 else
301 305 length += OSAL_SPRINTF(
302 306 &p_phy_result_buf[length],
303 307 "Eagle\n");
304 308 }
305 309 }
306 310 } else {
307 311 /* @@@TMP until ecore_phy_read() on AH is supported */
308 312 for (port = 0; port < max_ports; port++)
309 313 length += OSAL_SPRINTF(&p_phy_result_buf[length],
310 314 "Port %d is in MPS25\n", port);
311 315 rc = ECORE_SUCCESS;
312 316 }
313 317
314 318 return rc;
315 319 }
316 320
317 321 struct tsc_stat {
318 322 u32 reg;
319 323 char *name;
320 324 char *desc;
321 325 };
322 326
323 327 static struct tsc_stat ah_stat_regs[] = {
324 328 {0x000100, "ETHERSTATSOCTETS ", "total, good and bad"},
325 329 /* {0x000104, "ETHERSTATSOCTETS_H ", "total, good and bad"},*/
326 330 {0x000108, "OCTETSOK ", "total, good"},
327 331 /* {0x00010c, "OCTETSOK_H ", "total, good"}, */
328 332 {0x000110, "AALIGNMENTERRORS ", "Wrong SFD detected"},
329 333 /* {0x000114, "AALIGNMENTERRORS_H ", "Wrong SFD detected"}, */
330 334 {0x000118, "APAUSEMACCTRLFRAMES ", "Good Pause frames received"},
331 335 /* {0x00011c, "APAUSEMACCTRLFRAMES_H ", "Good Pause frames received"}, */
332 336 {0x000120, "FRAMESOK ", "Good frames received"},
333 337 /* {0x000124, "FRAMESOK_H ", "Good frames received"}, */
334 338 {0x000128, "CRCERRORS ", "wrong CRC and good length received"},
335 339 /* {0x00012c, "CRCERRORS_H ", "wrong CRC and good length received"}, */
336 340 {0x000130, "VLANOK ", "Good Frames with VLAN tag received"},
337 341 /* {0x000134, "VLANOK_H ", "Good Frames with VLAN tag received"}, */
338 342 {0x000138, "IFINERRORS ", "Errored frames received"},
339 343 /* {0x00013c, "IFINERRORS_H ", "Errored frames received"}, */
340 344 {0x000140, "IFINUCASTPKTS ", "Good Unicast received"},
341 345 /* {0x000144, "IFINUCASTPKTS_H ", "Good Unicast received"}, */
342 346 {0x000148, "IFINMCASTPKTS ", "Good Multicast received"},
343 347 /* {0x00014c, "IFINMCASTPKTS_H ", "Good Multicast received"}, */
344 348 {0x000150, "IFINBCASTPKTS ", "Good Broadcast received"},
345 349 /* {0x000154, "IFINBCASTPKTS_H ", "Good Broadcast received"}, */
346 350 {0x000158, "ETHERSTATSDROPEVENTS ", "Dropped frames"},
347 351 /* {0x00015c, "ETHERSTATSDROPEVENTS_H ", "Dropped frames"}, */
348 352 {0x000160, "ETHERSTATSPKTS ", "Frames received, good and bad"},
349 353 /* {0x000164, "ETHERSTATSPKTS_H ", "Frames received, good and bad"}, */
350 354 {0x000168, "ETHERSTATSUNDERSIZEPKTS ", "Frames received less 64 with good crc"},
351 355 /* {0x00016c, "ETHERSTATSUNDERSIZEPKTS_H ", "Frames received less 64 with good crc"}, */
352 356 {0x000170, "ETHERSTATSPKTS64 ", "Frames of 64 octets received"},
353 357 /* {0x000174, "ETHERSTATSPKTS64_H ", "Frames of 64 octets received"}, */
354 358 {0x000178, "ETHERSTATSPKTS65TO127 ", "Frames of 65 to 127 octets received"},
355 359 /* {0x00017c, "ETHERSTATSPKTS65TO127_H ", "Frames of 65 to 127 octets received"}, */
356 360 {0x000180, "ETHERSTATSPKTS128TO255 ", "Frames of 128 to 255 octets received"},
357 361 /* {0x000184, "ETHERSTATSPKTS128TO255_H ", "Frames of 128 to 255 octets received"}, */
358 362 {0x000188, "ETHERSTATSPKTS256TO511 ", "Frames of 256 to 511 octets received"},
359 363 /* {0x00018c, "ETHERSTATSPKTS256TO511_H ", "Frames of 256 to 511 octets received"},*/
360 364 {0x000190, "ETHERSTATSPKTS512TO1023 ", "Frames of 512 to 1023 octets received"},
361 365 /* {0x000194, "ETHERSTATSPKTS512TO1023_H ", "Frames of 512 to 1023 octets received"},*/
362 366 {0x000198, "ETHERSTATSPKTS1024TO1518 ", "Frames of 1024 to 1518 octets received"},
363 367 /* {0x00019c, "ETHERSTATSPKTS1024TO1518_H ", "Frames of 1024 to 1518 octets received"},*/
364 368 {0x0001a0, "ETHERSTATSPKTS1519TOMAX ", "Frames of 1519 to FRM_LENGTH octets received"},
365 369 /* {0x0001a4, "ETHERSTATSPKTS1519TOMAX_H ", "Frames of 1519 to FRM_LENGTH octets received"},*/
366 370 {0x0001a8, "ETHERSTATSPKTSOVERSIZE ", "Frames greater FRM_LENGTH and good CRC received"},
367 371 /* {0x0001ac, "ETHERSTATSPKTSOVERSIZE_H ", "Frames greater FRM_LENGTH and good CRC received"},*/
368 372 {0x0001b0, "ETHERSTATSJABBERS ", "Frames greater FRM_LENGTH and bad CRC received"},
369 373 /* {0x0001b4, "ETHERSTATSJABBERS_H ", "Frames greater FRM_LENGTH and bad CRC received"},*/
370 374 {0x0001b8, "ETHERSTATSFRAGMENTS ", "Frames less 64 and bad CRC received"},
371 375 /* {0x0001bc, "ETHERSTATSFRAGMENTS_H ", "Frames less 64 and bad CRC received"},*/
372 376 {0x0001c0, "AMACCONTROLFRAMES ", "Good frames received of type 0x8808 but not Pause"},
373 377 /* {0x0001c4, "AMACCONTROLFRAMES_H ", "Good frames received of type 0x8808 but not Pause"},*/
374 378 {0x0001c8, "AFRAMETOOLONG ", "Good and bad frames exceeding FRM_LENGTH received"},
375 379 /* {0x0001cc, "AFRAMETOOLONG_H ", "Good and bad frames exceeding FRM_LENGTH received"},*/
376 380 {0x0001d0, "AINRANGELENGTHERROR ", "Good frames with invalid length field (not supported)"},
377 381 /* {0x0001d4, "AINRANGELENGTHERROR_H ", "Good frames with invalid length field (not supported)"},*/
378 382 {0x000200, "TXETHERSTATSOCTETS ", "total, good and bad"},
379 383 /* {0x000204, "TXETHERSTATSOCTETS_H ", "total, good and bad"},*/
380 384 {0x000208, "TXOCTETSOK ", "total, good"},
381 385 /* {0x00020c, "TXOCTETSOK_H ", "total, good"},*/
382 386 {0x000218, "TXAPAUSEMACCTRLFRAMES ", "Good Pause frames transmitted"},
383 387 /* {0x00021c, "TXAPAUSEMACCTRLFRAMES_H ", "Good Pause frames transmitted"},*/
384 388 {0x000220, "TXFRAMESOK ", "Good frames transmitted"},
385 389 /* {0x000224, "TXFRAMESOK_H ", "Good frames transmitted"},*/
386 390 {0x000228, "TXCRCERRORS ", "wrong CRC transmitted"},
387 391 /* {0x00022c, "TXCRCERRORS_H ", "wrong CRC transmitted"},*/
388 392 {0x000230, "TXVLANOK ", "Good Frames with VLAN tag transmitted"},
389 393 /* {0x000234, "TXVLANOK_H ", "Good Frames with VLAN tag transmitted"},*/
390 394 {0x000238, "IFOUTERRORS ", "Errored frames transmitted"},
391 395 /* {0x00023c, "IFOUTERRORS_H ", "Errored frames transmitted"},*/
392 396 {0x000240, "IFOUTUCASTPKTS ", "Good Unicast transmitted"},
393 397 /* {0x000244, "IFOUTUCASTPKTS_H ", "Good Unicast transmitted"},*/
394 398 {0x000248, "IFOUTMCASTPKTS ", "Good Multicast transmitted"},
395 399 /* {0x00024c, "IFOUTMCASTPKTS_H ", "Good Multicast transmitted"},*/
396 400 {0x000250, "IFOUTBCASTPKTS ", "Good Broadcast transmitted"},
397 401 /* {0x000254, "IFOUTBCASTPKTS_H ", "Good Broadcast transmitted"},*/
398 402 {0x000258, "TXETHERSTATSDROPEVENTS ", "Dropped frames (unused, reserved)"},
399 403 /* {0x00025c, "TXETHERSTATSDROPEVENTS_H ", "Dropped frames (unused, reserved)"},*/
400 404 {0x000260, "TXETHERSTATSPKTS ", "Frames transmitted, good and bad"},
401 405 /* {0x000264, "TXETHERSTATSPKTS_H ", "Frames transmitted, good and bad"},*/
402 406 {0x000268, "TXETHERSTATSUNDERSIZEPKTS ", "Frames transmitted less 64"},
403 407 /* {0x00026c, "TXETHERSTATSUNDERSIZEPKTS_H ", "Frames transmitted less 64"},*/
404 408 {0x000270, "TXETHERSTATSPKTS64 ", "Frames of 64 octets transmitted"},
405 409 /* {0x000274, "TXETHERSTATSPKTS64_H ", "Frames of 64 octets transmitted"},*/
406 410 {0x000278, "TXETHERSTATSPKTS65TO127 ", "Frames of 65 to 127 octets transmitted"},
407 411 /* {0x00027c, "TXETHERSTATSPKTS65TO127_H ", "Frames of 65 to 127 octets transmitted"},*/
408 412 {0x000280, "TXETHERSTATSPKTS128TO255 ", "Frames of 128 to 255 octets transmitted"},
409 413 /* {0x000284, "TXETHERSTATSPKTS128TO255_H ", "Frames of 128 to 255 octets transmitted"},*/
410 414 {0x000288, "TXETHERSTATSPKTS256TO511 ", "Frames of 256 to 511 octets transmitted"},
411 415 /* {0x00028c, "TXETHERSTATSPKTS256TO511_H ", "Frames of 256 to 511 octets transmitted"},*/
412 416 {0x000290, "TXETHERSTATSPKTS512TO1023 ", "Frames of 512 to 1023 octets transmitted"},
413 417 /* {0x000294, "TXETHERSTATSPKTS512TO1023_H ", "Frames of 512 to 1023 octets transmitted"},*/
414 418 {0x000298, "TXETHERSTATSPKTS1024TO1518 ", "Frames of 1024 to 1518 octets transmitted"},
415 419 /* {0x00029c, "TXETHERSTATSPKTS1024TO1518_H ", "Frames of 1024 to 1518 octets transmitted"},*/
416 420 {0x0002a0, "TXETHERSTATSPKTS1519TOTX_MTU ", "Frames of 1519 to FRM_LENGTH.TX_MTU octets transmitted"},
417 421 /* {0x0002a4, "TXETHERSTATSPKTS1519TOTX_MTU_H ", "Frames of 1519 to FRM_LENGTH.TX_MTU octets transmitted"},*/
418 422 {0x0002c0, "TXAMACCONTROLFRAMES ", "Good frames transmitted of type 0x8808 but not Pause"},
419 423 /* {0x0002c4, "TXAMACCONTROLFRAMES_H ", "Good frames transmitted of type 0x8808 but not Pause"},*/
420 424 {0x000380, "ACBFCPAUSEFRAMESRECEIVED_0 ", "Set of 8 objects recording the number of CBFC (Class Based Flow Control) pause frames received for each class."},
421 425 /* {0x000384, "ACBFCPAUSEFRAMESRECEIVED_0_H ", "Upper 32bit of 64bit counter."},*/
422 426 {0x000388, "ACBFCPAUSEFRAMESRECEIVED_1 ", "Set of 8 objects recording the number of CBFC (Class Based Flow Control) pause frames received for each class."},
423 427 /* {0x00038c, "ACBFCPAUSEFRAMESRECEIVED_1_H ", "Upper 32bit of 64bit counter."},*/
424 428 {0x000390, "ACBFCPAUSEFRAMESRECEIVED_2 ", "Set of 8 objects recording the number of CBFC (Class Based Flow Control) pause frames received for each class."},
425 429 /* {0x000394, "ACBFCPAUSEFRAMESRECEIVED_2_H ", "Upper 32bit of 64bit counter."},*/
426 430 {0x000398, "ACBFCPAUSEFRAMESRECEIVED_3 ", "Set of 8 objects recording the number of CBFC (Class Based Flow Control) pause frames received for each class."},
427 431 /* {0x00039c, "ACBFCPAUSEFRAMESRECEIVED_3_H ", "Upper 32bit of 64bit counter."},*/
428 432 {0x0003a0, "ACBFCPAUSEFRAMESRECEIVED_4 ", "Set of 8 objects recording the number of CBFC (Class Based Flow Control) pause frames received for each class."},
429 433 /* {0x0003a4, "ACBFCPAUSEFRAMESRECEIVED_4_H ", "Upper 32bit of 64bit counter."},*/
430 434 {0x0003a8, "ACBFCPAUSEFRAMESRECEIVED_5 ", "Set of 8 objects recording the number of CBFC (Class Based Flow Control) pause frames received for each class."},
431 435 /* {0x0003ac, "ACBFCPAUSEFRAMESRECEIVED_5_H ", "Upper 32bit of 64bit counter."},*/
432 436 {0x0003b0, "ACBFCPAUSEFRAMESRECEIVED_6 ", "Set of 8 objects recording the number of CBFC (Class Based Flow Control) pause frames received for each class."},
433 437 /* {0x0003b4, "ACBFCPAUSEFRAMESRECEIVED_6_H ", "Upper 32bit of 64bit counter."},*/
434 438 {0x0003b8, "ACBFCPAUSEFRAMESRECEIVED_7 ", "Set of 8 objects recording the number of CBFC (Class Based Flow Control) pause frames received for each class."},
435 439 /* {0x0003bc, "ACBFCPAUSEFRAMESRECEIVED_7_H ", "Upper 32bit of 64bit counter."},*/
436 440 {0x0003c0, "ACBFCPAUSEFRAMESTRANSMITTED_0 ", "Set of 8 objects recording the number of CBFC (Class Based Flow Control) pause frames transmitted for each class."},
437 441 /* {0x0003c4, "ACBFCPAUSEFRAMESTRANSMITTED_0_H", "Upper 32bit of 64bit counter."},*/
438 442 {0x0003c8, "ACBFCPAUSEFRAMESTRANSMITTED_1 ", "Set of 8 objects recording the number of CBFC (Class Based Flow Control) pause frames transmitted for each class."},
439 443 /* {0x0003cc, "ACBFCPAUSEFRAMESTRANSMITTED_1_H", "Upper 32bit of 64bit counter."},*/
440 444 {0x0003d0, "ACBFCPAUSEFRAMESTRANSMITTED_2 ", "Set of 8 objects recording the number of CBFC (Class Based Flow Control) pause frames transmitted for each class."},
441 445 /* {0x0003d4, "ACBFCPAUSEFRAMESTRANSMITTED_2_H", "Upper 32bit of 64bit counter."},*/
442 446 {0x0003d8, "ACBFCPAUSEFRAMESTRANSMITTED_3 ", "Set of 8 objects recording the number of CBFC (Class Based Flow Control) pause frames transmitted for each class."},
443 447 /* {0x0003dc, "ACBFCPAUSEFRAMESTRANSMITTED_3_H", "Upper 32bit of 64bit counter."},*/
444 448 {0x0003e0, "ACBFCPAUSEFRAMESTRANSMITTED_4 ", "Set of 8 objects recording the number of CBFC (Class Based Flow Control) pause frames transmitted for each class."},
445 449 /* {0x0003e4, "ACBFCPAUSEFRAMESTRANSMITTED_4_H", "Upper 32bit of 64bit counter."},*/
446 450 {0x0003e8, "ACBFCPAUSEFRAMESTRANSMITTED_5 ", "Set of 8 objects recording the number of CBFC (Class Based Flow Control) pause frames transmitted for each class."},
447 451 /* {0x0003ec, "ACBFCPAUSEFRAMESTRANSMITTED_5_H", "Upper 32bit of 64bit counter."},*/
448 452 {0x0003f0, "ACBFCPAUSEFRAMESTRANSMITTED_6 ", "Set of 8 objects recording the number of CBFC (Class Based Flow Control) pause frames transmitted for each class."},
449 453 /* {0x0003f4, "ACBFCPAUSEFRAMESTRANSMITTED_6_H", "Upper 32bit of 64bit counter."},*/
450 454 {0x0003f8, "ACBFCPAUSEFRAMESTRANSMITTED_7 ", "Set of 8 objects recording the number of CBFC (Class Based Flow Control) pause frames transmitted for each class."},
451 455 /* {0x0003fc, "ACBFCPAUSEFRAMESTRANSMITTED_7_H", "Upper 32bit of 64bit counter."}*/
452 456 };
453 457 static struct tsc_stat bb_stat_regs[] = {
454 458 {0x00000000, "GRX64","RX 64-byte frame counter" },
455 459 {0x00000001, "GRX127","RX 65 to 127 byte frame counter" },
456 460 {0x00000002, "GRX255","RX 128 to 255 byte frame counter" },
457 461 {0x00000003, "GRX511","RX 256 to 511 byte frame counter" },
458 462 {0x00000004, "GRX1023","RX 512 to 1023 byte frame counter" },
459 463 {0x00000005, "GRX1518","RX 1024 to 1518 byte frame counter" },
460 464 {0x00000006, "GRX1522","RX 1519 to 1522 byte VLAN-tagged frame counter" },
461 465 {0x00000007, "GRX2047","RX 1519 to 2047 byte frame counter" },
462 466 {0x00000008, "GRX4095","RX 2048 to 4095 byte frame counter" },
463 467 {0x00000009, "GRX9216","RX 4096 to 9216 byte frame counter" },
464 468 {0x0000000a, "GRX16383","RX 9217 to 16383 byte frame counter" },
465 469 {0x0000000b, "GRXPKT","RX frame counter (all packets)" },
466 470 {0x0000000c, "GRXUCA","RX UC frame counter" },
467 471 {0x0000000d, "GRXMCA","RX MC frame counter" },
468 472 {0x0000000e, "GRXBCA","RX BC frame counter" },
469 473 {0x0000000f, "GRXFCS","RX FCS error frame counter" },
470 474 {0x00000010, "GRXCF","RX control frame counter" },
471 475 {0x00000011, "GRXPF","RX pause frame counter" },
472 476 {0x00000012, "GRXPP","RX PFC frame counter" },
473 477 {0x00000013, "GRXUO","RX unsupported opcode frame counter" },
474 478 {0x00000014, "GRXUDA","RX unsupported DA for pause/PFC frame counter" },
475 479 {0x00000015, "GRXWSA","RX incorrect SA counter" },
476 480 {0x00000016, "GRXALN","RX alignment error counter" },
477 481 {0x00000017, "GRXFLR","RX out-of-range length frame counter" },
478 482 {0x00000018, "GRXFRERR","RX code error frame counter" },
479 483 {0x00000019, "GRXFCR","RX false carrier counter" },
480 484 {0x0000001a, "GRXOVR","RX oversized frame counter" },
481 485 {0x0000001b, "GRXJBR","RX jabber frame counter" },
482 486 {0x0000001c, "GRXMTUE","RX MTU check error frame counter" },
483 487 {0x0000001d, "GRXMCRC",
484 488 "RX packet with 4-Byte CRC matching MACSEC_PROG_TX_CRC." },
485 489 {0x0000001e, "GRXPRM","RX promiscuous packet counter" },
486 490 {0x0000001f, "GRXVLN","RX single and double VLAN tagged frame counter" },
487 491 {0x00000020, "GRXDVLN","RX double VLANG tagged frame counter" },
488 492 {0x00000021, "GRXTRFU","RX truncated frame (due to RX FIFO full) counter" },
489 493 {0x00000022, "GRXPOK","RX good frame (good CRC, not oversized, no ERROR)" },
490 494 {0x00000023, "GRXPFCOFF0",
491 495 "RX PFC frame transition XON to XOFF for Priority0" },
492 496 {0x00000024, "GRXPFCOFF1",
493 497 "RX PFC frame transition XON to XOFF for Priority1" },
494 498 {0x00000025, "GRXPFCOFF2",
495 499 "RX PFC frame transition XON to XOFF for Priority2" },
496 500 {0x00000026, "GRXPFCOFF3",
497 501 "RX PFC frame transition XON to XOFF for Priority3" },
498 502 {0x00000027, "GRXPFCOFF4",
499 503 "RX PFC frame transition XON to XOFF for Priority4" },
500 504 {0x00000028, "GRXPFCOFF5",
501 505 "RX PFC frame transition XON to XOFF for Priority5" },
502 506 {0x00000029, "GRXPFCOFF6",
503 507 "RX PFC frame transition XON to XOFF for Priority6" },
504 508 {0x0000002a, "GRXPFCOFF7",
505 509 "RX PFC frame transition XON to XOFF for Priority7" },
506 510 {0x0000002b, "GRXPFCP0","RX PFC frame with enable bit set for Priority0" },
507 511 {0x0000002c, "GRXPFCP1","RX PFC frame with enable bit set for Priority1" },
508 512 {0x0000002d, "GRXPFCP2","RX PFC frame with enable bit set for Priority2" },
509 513 {0x0000002e, "GRXPFCP3","RX PFC frame with enable bit set for Priority3" },
510 514 {0x0000002f, "GRXPFCP4","RX PFC frame with enable bit set for Priority4" },
511 515 {0x00000030, "GRXPFCP5","RX PFC frame with enable bit set for Priority5" },
512 516 {0x00000031, "GRXPFCP6","RX PFC frame with enable bit set for Priority6" },
513 517 {0x00000032, "GRXPFCP7","RX PFC frame with enable bit set for Priority7" },
514 518 {0x00000033, "GRXSCHCRC","RX frame with SCH CRC error. For LH mode only" },
515 519 {0x00000034, "GRXUND","RX undersized frame counter" },
516 520 {0x00000035, "GRXFRG","RX fragment counter" },
517 521 {0x00000036, "RXEEELPI", "RX EEE LPI counter"},
518 522 {0x00000037, "RXEEELPIDU", "RX EEE LPI duration counter"},
519 523 {0x00000038, "RXLLFCPHY", "RX LLFC PHY COUNTER"},
520 524 {0x00000039, "RXLLFCLOG", "RX LLFC LOG COUNTER"},
521 525 {0x0000003a, "RXLLFCCRC", "RX LLFC CRC COUNTER"},
522 526 {0x0000003b, "RXHCFC", "RX HCFC COUNTER"},
523 527 {0x0000003c, "RXHCFCCRC", "RX HCFC CRC COUNTER"},
524 528 {0x0000003d, "GRXBYT", "RX byte counter"},
525 529 {0x0000003e, "GRXRBYT", "RX runt byte counter"},
526 530 {0x0000003f, "GRXRPKT", "RX packet counter"},
527 531 {0x00000040, "GTX64", "TX 64-byte frame counter"},
528 532 {0x00000041, "GTX127", "TX 65 to 127 byte frame counter"},
529 533 {0x00000042, "GTX255", "TX 128 to 255 byte frame counter"},
530 534 {0x00000043, "GTX511", "TX 256 to 511 byte frame counter"},
531 535 {0x00000044, "GTX1023", "TX 512 to 1023 byte frame counter"},
532 536 {0x00000045, "GTX1518", "TX 1024 to 1518 byte frame counter"},
533 537 {0x00000046, "GTX1522", "TX 1519 to 1522 byte VLAN-tagged frame counter"},
534 538 {0x00000047, "GTX2047", "TX 1519 to 2047 byte frame counter"},
535 539 {0x00000048, "GTX4095", "TX 2048 to 4095 byte frame counte"},
536 540 {0x00000049, "GTX9216", "TX 4096 to 9216 byte frame counter"},
537 541 {0x0000004a, "GTX16383", "TX 9217 to 16383 byte frame counter"},
538 542 {0x0000004b, "GTXPOK", "TX good frame counter"},
539 543 {0x0000004c, "GTXPKT", "TX frame counter (all packets"},
540 544 {0x0000004d, "GTXUCA", "TX UC frame counter"},
541 545 {0x0000004e, "GTXMCA", "TX MC frame counter"},
542 546 {0x0000004f, "GTXBCA", "TX BC frame counter"},
543 547 {0x00000050, "GTXPF", "TX pause frame counter"},
544 548 {0x00000051, "GTXPP", "TX PFC frame counter"},
545 549 {0x00000052, "GTXJBR", "TX jabber counter"},
546 550 {0x00000053, "GTXFCS", "TX FCS error counter"},
547 551 {0x00000054, "GTXCF", "TX control frame counter"},
548 552 {0x00000055, "GTXOVR", "TX oversize packet counter"},
549 553 {0x00000056, "GTXDFR", "TX Single Deferral Frame Counter"},
550 554 {0x00000057, "GTXEDF", "TX Multiple Deferral Frame Counter"},
551 555 {0x00000058, "GTXSCL", "TX Single Collision Frame Counter"},
552 556 {0x00000059, "GTXMCL", "TX Multiple Collision Frame Counter"},
553 557 {0x0000005a, "GTXLCL", "TX Late Collision Frame Counter"},
554 558 {0x0000005b, "GTXXCL", "TX Excessive Collision Frame Counter"},
555 559 {0x0000005c, "GTXFRG", "TX fragment counter"},
556 560 {0x0000005d, "GTXERR", "TX error (set by system) frame counter"},
557 561 {0x0000005e, "GTXVLN", "TX VLAN Tag Frame Counter"},
558 562 {0x0000005f, "GTXDVLN", "TX Double VLAN Tag Frame Counter"},
559 563 {0x00000060, "GTXRPKT", "TX RUNT Frame Counter"},
560 564 {0x00000061, "GTXUFL", "TX FIFO Underrun Counter"},
561 565 {0x00000062, "GTXPFCP0", "TX PFC frame with enable bit set for Priority0"},
562 566 {0x00000063, "GTXPFCP1", "TX PFC frame with enable bit set for Priority1"},
563 567 {0x00000064, "GTXPFCP2", "TX PFC frame with enable bit set for Priority2"},
564 568 {0x00000065, "GTXPFCP3", "TX PFC frame with enable bit set for Priority3"},
565 569 {0x00000066, "GTXPFCP4", "TX PFC frame with enable bit set for Priority4"},
566 570 {0x00000067, "GTXPFCP5", "TX PFC frame with enable bit set for Priority5"},
567 571 {0x00000068, "GTXPFCP6", "TX PFC frame with enable bit set for Priority6"},
568 572 {0x00000069, "GTXPFCP7", "TX PFC frame with enable bit set for Priority7"},
569 573 {0x0000006a, "TXEEELPI", "TX EEE LPI Event Counter"},
570 574 {0x0000006b, "TXEEELPIDU", "TX EEE LPI Duration Counter"},
571 575 {0x0000006c, "TXLLFCLOG", "Transmit Logical Type LLFC message counter"},
572 576 {0x0000006d, "TXHCFC", "Transmit Logical Type LLFC message counter"},
573 577 {0x0000006e, "GTXNCL", "Transmit Total Collision Counter"},
574 578 {0x0000006f, "GTXBYT", "TX byte counter"}
575 579 };
576 580
577 581 /* get mac status */
578 582 static int ecore_bb_phy_mac_stat(struct ecore_hwfn *p_hwfn,
579 583 struct ecore_ptt *p_ptt,
580 584 u32 port, char *p_phy_result_buf)
581 585 {
582 586 u8 buf64[8] = {0}, data_hi[4], data_lo[4];
583 587 bool b_false_alarm = false;
584 588 u32 length, reg_id, addr;
585 589 enum _ecore_status_t rc = ECORE_INVAL;
586 590
587 591 length = OSAL_SPRINTF(p_phy_result_buf,
588 592 "MAC stats for port %d (only non-zero)\n", port);
589 593
590 594 for (reg_id = 0; reg_id < OSAL_ARRAY_SIZE(bb_stat_regs); reg_id++) {
591 595 addr = bb_stat_regs[reg_id].reg;
592 596 rc = ecore_phy_read(p_hwfn, p_ptt, port, 0 /*lane*/, addr,
593 597 ECORE_PHY_CORE_READ, buf64);
594 598
595 599 OSAL_MEMCPY(data_lo, buf64, 4);
596 600 OSAL_MEMCPY(data_hi, (buf64 + 4), 4);
597 601
598 602 if (rc == ECORE_SUCCESS) {
599 603 if (*(u32 *)data_lo != 0) { /* Only non-zero */
600 604 length += OSAL_SPRINTF(&p_phy_result_buf[length],
601 605 "%-10s: 0x%08x (%s)\n",
602 606 bb_stat_regs[reg_id].name,
603 607 *(u32 *)data_lo,
604 608 bb_stat_regs[reg_id].desc);
605 609 if ((bb_stat_regs[reg_id].reg == 0x0000000f) ||
606 610 (bb_stat_regs[reg_id].reg == 0x00000018) ||
607 611 (bb_stat_regs[reg_id].reg == 0x00000035))
608 612 b_false_alarm = true;
609 613 }
610 614 } else {
611 615 OSAL_SPRINTF(p_phy_result_buf, "Failed reading stat 0x%x\n\n",
612 616 addr);
613 617 }
614 618 }
615 619
616 620 if (b_false_alarm)
617 621 length += OSAL_SPRINTF(&p_phy_result_buf[length],
618 622 "Note: GRXFCS/GRXFRERR/GRXFRG may "
↓ open down ↓ |
573 lines elided |
↑ open up ↑ |
619 623 "increment when the port shuts down\n");
620 624
621 625 return rc;
622 626 }
623 627
624 628 /* get mac status */
625 629 static int ecore_ah_e5_phy_mac_stat(struct ecore_hwfn *p_hwfn,
626 630 struct ecore_ptt *p_ptt, u32 port,
627 631 char *p_phy_result_buf)
628 632 {
629 - u32 length, reg_id, addr, data_hi, data_lo;
633 + u32 length, reg_id, addr, data_hi __unused, data_lo;
630 634
631 635 length = OSAL_SPRINTF(p_phy_result_buf,
632 636 "MAC stats for port %d (only non-zero)\n", port);
633 637
634 638 for (reg_id = 0; reg_id < OSAL_ARRAY_SIZE(ah_stat_regs); reg_id++) {
635 639 addr = ah_stat_regs[reg_id].reg;
636 640 data_lo = ecore_rd(p_hwfn, p_ptt,
637 641 NWM_REG_MAC0_K2_E5 +
638 642 NWM_REG_MAC0_SIZE * 4 * port +
639 643 addr);
640 644 data_hi = ecore_rd(p_hwfn, p_ptt,
641 645 NWM_REG_MAC0_K2_E5 +
642 646 NWM_REG_MAC0_SIZE * 4 * port +
643 647 addr + 4);
644 648
645 649 if (data_lo) { /* Only non-zero */
646 650 length += OSAL_SPRINTF(&p_phy_result_buf[length],
647 651 "%-10s: 0x%08x (%s)\n",
648 652 ah_stat_regs[reg_id].name,
649 653 data_lo,
650 654 ah_stat_regs[reg_id].desc);
651 655 }
652 656 }
653 657
654 658 return ECORE_SUCCESS;
655 659 }
656 660
657 661 int ecore_phy_mac_stat(struct ecore_hwfn *p_hwfn, struct ecore_ptt *p_ptt,
658 662 u32 port, char *p_phy_result_buf)
659 663 {
660 664 int num_ports = ecore_device_num_ports(p_hwfn->p_dev);
661 665
662 666 if (port >= (u32)num_ports) {
663 667 OSAL_SPRINTF(p_phy_result_buf,
664 668 "Port must be in range of 0..%d\n", num_ports);
665 669 return ECORE_INVAL;
666 670 }
667 671
668 672 if (ECORE_IS_BB(p_hwfn->p_dev))
669 673 return ecore_bb_phy_mac_stat(p_hwfn, p_ptt, port,
670 674 p_phy_result_buf);
671 675 else
672 676 return ecore_ah_e5_phy_mac_stat(p_hwfn, p_ptt, port,
673 677 p_phy_result_buf);
674 678 }
675 679
676 680 #define SFP_RX_LOS_OFFSET 110
677 681 #define SFP_TX_DISABLE_OFFSET 110
678 682 #define SFP_TX_FAULT_OFFSET 110
679 683
680 684 #define QSFP_RX_LOS_OFFSET 3
681 685 #define QSFP_TX_DISABLE_OFFSET 86
682 686 #define QSFP_TX_FAULT_OFFSET 4
683 687
684 688 /* Set SFP error string */
685 689 static int ecore_sfp_set_error(enum _ecore_status_t rc, u32 offset,
686 690 char *p_phy_result_buf, char *p_err_str)
687 691 {
688 692 if (rc != ECORE_SUCCESS) {
689 693 if (rc == ECORE_NODEV)
690 694 OSAL_SPRINTF((char *)&p_phy_result_buf[offset],
691 695 "Transceiver is unplugged.\n");
692 696 else
693 697 OSAL_SPRINTF((char *)&p_phy_result_buf[offset], "%s",
694 698 p_err_str);
695 699
696 700 return ECORE_UNKNOWN_ERROR;
697 701 }
698 702
699 703 return rc;
700 704 }
701 705
702 706 /* Validate SFP port */
703 707 static int ecore_validate_sfp_port(struct ecore_hwfn *p_hwfn,
704 708 struct ecore_ptt *p_ptt,
705 709 u32 port, char *p_phy_result_buf)
706 710 {
707 711 /* Verify <port> field is between 0 and number of ports */
708 712 u32 num_ports = ecore_device_num_ports(p_hwfn->p_dev);
709 713
710 714 if (port >= num_ports) {
711 715 if (num_ports == 1)
712 716 OSAL_SPRINTF(p_phy_result_buf,
713 717 "Bad port number, must be 0.\n");
714 718 else
715 719 OSAL_SPRINTF(p_phy_result_buf,
716 720 "Bad port number, must be between 0 and %d.\n",
717 721 num_ports-1);
718 722
719 723 return ECORE_INVAL;
720 724 }
721 725
722 726 return ECORE_SUCCESS;
723 727 }
724 728
725 729 /* Validate SFP parameters */
726 730 static int ecore_validate_sfp_parameters(struct ecore_hwfn *p_hwfn,
727 731 struct ecore_ptt *p_ptt,
728 732 u32 port, u32 addr, u32 offset,
729 733 u32 size, char *p_phy_result_buf)
730 734 {
731 735 enum _ecore_status_t rc;
732 736
733 737 /* Verify <port> field is between 0 and number of ports */
734 738 rc = ecore_validate_sfp_port(p_hwfn, p_ptt, port, p_phy_result_buf);
735 739 if (rc != ECORE_SUCCESS)
736 740 return rc;
737 741
738 742 /* Verify <I2C> field is 0xA0 or 0xA2 */
739 743 if ((addr != 0xA0) && (addr != 0xA2)) {
740 744 OSAL_SPRINTF(p_phy_result_buf,
741 745 "Bad I2C address, must be 0xA0 or 0xA2.\n");
742 746 return ECORE_INVAL;
743 747 }
744 748
745 749 /* Verify <size> field is 1 - MAX_I2C_TRANSCEIVER_PAGE_SIZE */
746 750 if ((size == 0) || (size > MAX_I2C_TRANSCEIVER_PAGE_SIZE)) {
747 751 OSAL_SPRINTF(p_phy_result_buf,
748 752 "Bad size, must be between 1 and %d.\n",
749 753 MAX_I2C_TRANSCEIVER_PAGE_SIZE);
750 754 return ECORE_INVAL;
751 755 }
752 756
753 757 /* Verify <offset> + <size> <= MAX_I2C_TRANSCEIVER_PAGE_SIZE */
754 758 if (offset + size > MAX_I2C_TRANSCEIVER_PAGE_SIZE) {
755 759 OSAL_SPRINTF(p_phy_result_buf,
756 760 "Bad offset and size, must not exceed %d.\n",
757 761 MAX_I2C_TRANSCEIVER_PAGE_SIZE);
758 762 return ECORE_INVAL;
759 763 }
760 764
761 765 return rc;
762 766 }
763 767
764 768 /* Write to SFP */
765 769 int ecore_phy_sfp_write(struct ecore_hwfn *p_hwfn, struct ecore_ptt *p_ptt,
766 770 u32 port, u32 addr, u32 offset, u32 size,
767 771 u32 val, char *p_phy_result_buf)
768 772 {
769 773 enum _ecore_status_t rc;
770 774
771 775 rc = ecore_validate_sfp_parameters(p_hwfn, p_ptt, port, addr,
772 776 offset, size, p_phy_result_buf);
773 777 if (rc == ECORE_SUCCESS)
774 778 {
775 779 rc = ecore_mcp_phy_sfp_write(p_hwfn, p_ptt, port, addr,
776 780 offset, size, (u8 *)&val);
777 781
778 782 if (rc != ECORE_SUCCESS)
779 783 return ecore_sfp_set_error(rc, 0, p_phy_result_buf,
780 784 "Error writing to transceiver.\n");
781 785
782 786 OSAL_SPRINTF(p_phy_result_buf,
783 787 "Written successfully to transceiver.\n");
784 788 }
785 789
786 790 return rc;
787 791 }
788 792
789 793 /* Read from SFP */
790 794 int ecore_phy_sfp_read(struct ecore_hwfn *p_hwfn, struct ecore_ptt *p_ptt,
791 795 u32 port, u32 addr, u32 offset,
792 796 u32 size, char *p_phy_result_buf)
793 797 {
794 798 enum _ecore_status_t rc;
795 799 u32 i;
796 800
797 801 rc = ecore_validate_sfp_parameters(p_hwfn, p_ptt, port, addr,
798 802 offset, size, p_phy_result_buf);
799 803 if (rc == ECORE_SUCCESS)
800 804 {
801 805 int length = 0;
802 806 u8 buf[MAX_I2C_TRANSCEIVER_PAGE_SIZE];
803 807
804 808 rc = ecore_mcp_phy_sfp_read(p_hwfn, p_ptt, port, addr,
805 809 offset, size, buf);
806 810 if (rc != ECORE_SUCCESS)
807 811 return ecore_sfp_set_error(rc, 0, p_phy_result_buf,
808 812 "Error reading from transceiver.\n");
809 813 for (i = 0; i < size; i++)
810 814 length += OSAL_SPRINTF(
811 815 (char *)&p_phy_result_buf[length],
812 816 "%02x ", buf[i]);
813 817 }
814 818
815 819 return rc;
816 820 }
817 821
818 822 static enum _ecore_status_t ecore_decode_sfp_info(struct ecore_hwfn *p_hwfn,
819 823 struct ecore_ptt *p_ptt,
820 824 u32 port, u32 length,
821 825 char *p_phy_result_buf)
822 826 {
823 827 /* SFP EEPROM contents are described in SFF-8024 and SFF-8472 */
824 828 /***********************************************/
825 829 /* SFP DATA and locations */
826 830 /* get specification complianace bytes 3-10 */
827 831 /* get signal rate byte 12 */
828 832 /* get extended compliance code byte 36 */
829 833 /* get vendor length bytes 14-19 */
830 834 /* get vendor name bytes bytes 20-35 */
831 835 /* get vendor OUI bytes 37-39 */
832 836 /* get vendor PN bytes 40-55 */
833 837 /* get vendor REV bytes 56-59 */
834 838 /* validated */
835 839 /***********************************************/
836 840 enum _ecore_status_t rc;
837 841 u8 buf[32];
838 842
839 843 /* Read byte 12 - signal rate, and if nothing matches */
840 844 /* check byte 8 for 10G copper */
841 845 rc = ecore_mcp_phy_sfp_read(p_hwfn, p_ptt, port, I2C_TRANSCEIVER_ADDR,
842 846 12, 1, buf);
843 847 if (rc != ECORE_SUCCESS)
844 848 return ecore_sfp_set_error(rc, length, p_phy_result_buf,
845 849 "Error reading specification compliance field.\n");
846 850
847 851 length += OSAL_SPRINTF(&p_phy_result_buf[length],
848 852 "BYTE 12 signal rate: %d\n", buf[0]);
849 853
850 854 if (buf[0] >= 250) {
851 855 length += OSAL_SPRINTF(&p_phy_result_buf[length],
852 856 "25G signal rate: %d\n", buf[0]);
853 857 /* 25G - This should be copper - could double check */
854 858 /* Read byte 3 - optics, and if nothing matches */
855 859 /* check byte 8 for 10G copper */
856 860 rc = ecore_mcp_phy_sfp_read(p_hwfn, p_ptt, port,
857 861 I2C_TRANSCEIVER_ADDR, 3, 1, buf);
858 862 if (rc != ECORE_SUCCESS)
859 863 return ecore_sfp_set_error(rc, length,
860 864 p_phy_result_buf,
861 865 "Error reading optics field.\n");
862 866
863 867 switch (buf[0]) {
864 868 case 1:
865 869 length += OSAL_SPRINTF(&p_phy_result_buf[length],
866 870 "25G Passive copper detected\n");
867 871 break;
868 872 case 2:
869 873 length += OSAL_SPRINTF(&p_phy_result_buf[length],
870 874 "25G Active copper detected\n");
871 875 break;
872 876 default:
873 877 length += OSAL_SPRINTF(&p_phy_result_buf[length],
874 878 "UNKNOWN 25G cable detected: %x\n",
875 879 buf[0]);
876 880 break;
877 881 }
878 882
879 883 } else if (buf[3] >= 100) {
880 884 length += OSAL_SPRINTF(&p_phy_result_buf[length],
881 885 "10G signal rate: %d\n", buf[0]);
882 886 /* 10G - Read byte 3 for optics and byte 8 for copper, and */
883 887 /* byte 2 for AOC */
884 888 /* Read byte 3 - optics, and if nothing matches check byte */
885 889 /* 8 for 10G copper */
886 890 rc = ecore_mcp_phy_sfp_read(p_hwfn, p_ptt, port,
887 891 I2C_TRANSCEIVER_ADDR, 3, 1, buf);
888 892 if (rc != ECORE_SUCCESS)
889 893 return ecore_sfp_set_error(rc, length,
890 894 p_phy_result_buf,
891 895 "Error reading optics field.\n");
892 896
893 897 switch (buf[0]) {
894 898 case 0x10:
895 899 /* 10G SR */
896 900 length += OSAL_SPRINTF(&p_phy_result_buf[length],
897 901 "10G SR detected\n");
898 902 break;
899 903 case 0x20:
900 904 /* 10G LR */
901 905 length += OSAL_SPRINTF(&p_phy_result_buf[length],
902 906 "10G LR detected\n");
903 907 break;
904 908 case 0x40:
905 909 /* 10G LRM */
906 910 length += OSAL_SPRINTF(&p_phy_result_buf[length],
907 911 "10G LRM detected\n");
908 912 break;
909 913 case 0x80:
910 914 length += OSAL_SPRINTF(&p_phy_result_buf[length],
911 915 "10G ER detected\n");
912 916 break;
913 917 default:
914 918 length += OSAL_SPRINTF(&p_phy_result_buf[length],
915 919 "SFP/SFP+/SFP-28 transceiver type 0x%x not known... Check for 10G copper.\n",
916 920 buf[0]);
917 921 /* Read 3, check 8 too */
918 922 rc = ecore_mcp_phy_sfp_read(p_hwfn, p_ptt, port,
919 923 I2C_TRANSCEIVER_ADDR,
920 924 8, 1, buf);
921 925 if (rc != ECORE_SUCCESS)
922 926 return ecore_sfp_set_error(rc, length,
923 927 p_phy_result_buf,
924 928 "Error reading 10G copper field.\n");
925 929
926 930 switch (buf[0]) {
927 931 case 0x04:
928 932 case 0x84:
929 933 length += OSAL_SPRINTF(
930 934 &p_phy_result_buf[length],
931 935 "10G Passive copper detected\n");
932 936 break;
933 937 case 0x08:
934 938 case 0x88:
935 939 length += OSAL_SPRINTF(
936 940 &p_phy_result_buf[length],
937 941 "10G Active copper detected\n");
938 942 break;
939 943 default:
940 944 length += OSAL_SPRINTF(
941 945 &p_phy_result_buf[length],
942 946 "Unexpected SFP/SFP+/SFP-28 transceiver type 0x%x\n",
943 947 buf[3]);
944 948 break;
945 949 } /* switch byte 8 */
946 950
947 951 } /* switch byte 3 */
948 952
949 953 } else if (buf[0] >= 10) {
950 954 length += OSAL_SPRINTF(&p_phy_result_buf[length],
951 955 "1G signal rate: %d\n", buf[3]);
952 956 /* 1G - Read byte 6 for optics and byte 8 for copper */
953 957 rc = ecore_mcp_phy_sfp_read(p_hwfn, p_ptt, port,
954 958 I2C_TRANSCEIVER_ADDR, 6, 1, buf);
955 959 if (rc != ECORE_SUCCESS)
956 960 return ecore_sfp_set_error(rc, length,
957 961 p_phy_result_buf,
958 962 "Error reading optics field.\n");
959 963
960 964 switch (buf[0]) {
961 965 case 1:
962 966 length += OSAL_SPRINTF(&p_phy_result_buf[length],
963 967 "1G SX detected\n");
964 968 break;
965 969 case 2:
966 970 length += OSAL_SPRINTF(&p_phy_result_buf[length],
967 971 "1G LX detected\n");
968 972 break;
969 973 default:
970 974 length += OSAL_SPRINTF(&p_phy_result_buf[length],
971 975 "Assume 1G Passive copper detected\n");
972 976 break;
973 977 }
974 978 }
975 979
976 980 /* get vendor length bytes 14-19 */
977 981 rc = ecore_mcp_phy_sfp_read(p_hwfn, p_ptt, port, I2C_TRANSCEIVER_ADDR,
978 982 14, 6, buf);
979 983 if (rc != ECORE_SUCCESS)
980 984 return ecore_sfp_set_error(rc, length, p_phy_result_buf,
981 985 "Error reading vendor length bytes.\n");
982 986
983 987 length += OSAL_SPRINTF(&p_phy_result_buf[length],
984 988 "Length (SMF, km) 0x%x\n", buf[0]);
985 989 length += OSAL_SPRINTF(&p_phy_result_buf[length],
986 990 "Length (SMF) 0x%x\n", buf[1]);
987 991 length += OSAL_SPRINTF(&p_phy_result_buf[length],
988 992 "Length (50 um) 0x%x\n", buf[2]);
989 993 length += OSAL_SPRINTF(&p_phy_result_buf[length],
990 994 "Length (62.5 um) 0x%x\n", buf[3]);
991 995 length += OSAL_SPRINTF(&p_phy_result_buf[length],
992 996 "Length (OM4 or copper cable) 0x%x\n", buf[4]);
993 997 length += OSAL_SPRINTF(&p_phy_result_buf[length],
994 998 "Length (OM3) 0x%x\n", buf[5]);
995 999
996 1000 /* get vendor name bytes bytes 20-35 */
997 1001 rc = ecore_mcp_phy_sfp_read(p_hwfn, p_ptt, port, I2C_TRANSCEIVER_ADDR,
998 1002 20, 16, buf);
999 1003 if (rc != ECORE_SUCCESS)
1000 1004 return ecore_sfp_set_error(rc, length, p_phy_result_buf,
1001 1005 "Error reading vendor name.\n");
1002 1006
1003 1007 buf[16] = 0;
1004 1008 length += OSAL_SPRINTF(&p_phy_result_buf[length],
1005 1009 "Vendor name: %s\n", buf);
1006 1010
1007 1011 /* get vendor OUI bytes 37-39 */
1008 1012 rc = ecore_mcp_phy_sfp_read(p_hwfn, p_ptt, port, I2C_TRANSCEIVER_ADDR,
1009 1013 37, 3, buf);
1010 1014 if (rc != ECORE_SUCCESS)
1011 1015 return ecore_sfp_set_error(rc, length, p_phy_result_buf,
1012 1016 "Error reading vendor OUI.\n");
1013 1017
1014 1018 length += OSAL_SPRINTF(&p_phy_result_buf[length],
1015 1019 "Vendor OUI: %02x%02x%02x\n",
1016 1020 buf[0], buf[1], buf[2]);
1017 1021
1018 1022 /* get vendor PN bytes 40-55 */
1019 1023 rc = ecore_mcp_phy_sfp_read(p_hwfn, p_ptt, port, I2C_TRANSCEIVER_ADDR,
1020 1024 40, 16, buf);
1021 1025 if (rc != ECORE_SUCCESS)
1022 1026 return ecore_sfp_set_error(rc, length, p_phy_result_buf,
1023 1027 "Error reading vendor PN.\n");
1024 1028
1025 1029 buf[16] = 0;
1026 1030 length += OSAL_SPRINTF(&p_phy_result_buf[length],
1027 1031 "Vendor PN: %s\n", buf);
1028 1032
1029 1033 /* get vendor REV bytes 56-59 */
1030 1034 rc = ecore_mcp_phy_sfp_read(p_hwfn, p_ptt, port, I2C_TRANSCEIVER_ADDR,
1031 1035 56, 4, buf);
1032 1036 if (rc != ECORE_SUCCESS)
1033 1037 return ecore_sfp_set_error(rc, length, p_phy_result_buf,
1034 1038 "Error reading vendor rev.\n");
1035 1039
1036 1040 buf[4] = 0;
1037 1041 length += OSAL_SPRINTF(&p_phy_result_buf[length],
1038 1042 "Vendor rev: %s\n", buf);
1039 1043
1040 1044 return rc;
1041 1045 }
1042 1046
1043 1047 static enum _ecore_status_t ecore_decode_qsfp_info(struct ecore_hwfn *p_hwfn,
1044 1048 struct ecore_ptt *p_ptt,
1045 1049 u32 port, u32 length,
1046 1050 char *p_phy_result_buf)
1047 1051 {
1048 1052 /* QSFP EEPROM contents are described in SFF-8024 and SFF-8636 */
1049 1053 /***********************************************/
1050 1054 /* QSFP DATA and locations */
1051 1055 /* get specification complianace bytes 131-138 */
1052 1056 /* get extended rate select bytes 141 */
1053 1057 /* get vendor length bytes 142-146 */
1054 1058 /* get device technology byte 147 */
1055 1059 /* get vendor name bytes bytes 148-163 */
1056 1060 /* get vendor OUI bytes 165-167 */
1057 1061 /* get vendor PN bytes 168-183 */
1058 1062 /* get vendor REV bytes 184-185 */
1059 1063 /* validated */
1060 1064 /***********************************************/
1061 1065 enum _ecore_status_t rc;
1062 1066 u8 buf[32];
1063 1067
1064 1068 rc = ecore_mcp_phy_sfp_read(p_hwfn, p_ptt, port, I2C_TRANSCEIVER_ADDR,
1065 1069 131, 1, buf);
1066 1070 if (rc != ECORE_SUCCESS)
1067 1071 return ecore_sfp_set_error(rc, length, p_phy_result_buf,
1068 1072 "Error reading transceiver compliance code.\n");
1069 1073
1070 1074 length += OSAL_SPRINTF(&p_phy_result_buf[length],
1071 1075 "Transceiver compliance code 0x%x\n", buf[0]);
1072 1076
1073 1077 switch (buf[0]) {
1074 1078 case 0x1:
1075 1079 /* 40G Active (XLPPI) */
1076 1080 length += OSAL_SPRINTF(&p_phy_result_buf[length],
1077 1081 "40G Active (XLPPI) detected.\n");
1078 1082 break;
1079 1083 case 0x2:
1080 1084 /* 40G LR-4 */
1081 1085 length += OSAL_SPRINTF(&p_phy_result_buf[length],
1082 1086 "40G LR-4 detected.\n");
1083 1087 break;
1084 1088 case 0x4:
1085 1089 /* 40G SR-4 */
1086 1090 length += OSAL_SPRINTF(&p_phy_result_buf[length],
1087 1091 "40G SR-4 detected.\n");
1088 1092 break;
1089 1093 case 0x8:
1090 1094 /* 40G CR-4 */
1091 1095 length += OSAL_SPRINTF(&p_phy_result_buf[length],
1092 1096 "40G CR-4 detected.\n");
1093 1097 break;
1094 1098 case 0x10:
1095 1099 /* 10G SR */
1096 1100 length += OSAL_SPRINTF(&p_phy_result_buf[length],
1097 1101 "10G SR detected.\n");
1098 1102 break;
1099 1103 case 0x20:
1100 1104 /* 10G LR */
1101 1105 length += OSAL_SPRINTF(&p_phy_result_buf[length],
1102 1106 "10G LR detected.\n");
1103 1107 break;
1104 1108 case 0x40:
1105 1109 /* 10G LRM */
1106 1110 length += OSAL_SPRINTF(&p_phy_result_buf[length],
1107 1111 "10G LRM detected.\n");
1108 1112 break;
1109 1113 case 0x88: /* Could be 40G/100G CR4 cable, check 192 for 100G CR4 */
1110 1114 length += OSAL_SPRINTF(&p_phy_result_buf[length],
1111 1115 "Multi-rate transceiver: 40G CR-4 detected...\n");
1112 1116 break;
1113 1117 case 0x80:
1114 1118 /* Use extended technology field */
1115 1119 length += OSAL_SPRINTF(&p_phy_result_buf[length],
1116 1120 "Use extended technology field\n");
1117 1121 /* Byte 93 & 129 is supposed to have power info. During */
1118 1122 /* testing all reads 0. Ignore for now */
1119 1123 /* 0-127 is in the first page this in high region - */
1120 1124 /* see what page it is. */
1121 1125 /* buf[3] = 0; */
1122 1126 /* ret_val = read_transceiver_data(g_port, i2c_addr, 129, */
1123 1127 /* buf, 1); */
1124 1128 /* length += OSAL_SPRINTF(&p_phy_result_buf[length], */
1125 1129 /* "Read transceiver power data. Value read: 0x%hx\n\n", */
1126 1130 /* buf[3]); */
1127 1131
1128 1132 rc = ecore_mcp_phy_sfp_read(p_hwfn, p_ptt, port,
1129 1133 I2C_TRANSCEIVER_ADDR, 192, 1, buf);
1130 1134 if (rc != ECORE_SUCCESS)
1131 1135 return ecore_sfp_set_error(rc, length, p_phy_result_buf,
1132 1136 "Error reading technology compliance field.\n");
1133 1137
1134 1138 switch (buf[0]) {
1135 1139 case 0:
1136 1140 /* Unspecified */
1137 1141 length += OSAL_SPRINTF(&p_phy_result_buf[length],
1138 1142 "Unspecified detected.\n");
1139 1143 break;
1140 1144 case 0x1:
1141 1145 /* 100G AOC (active optical cable) */
1142 1146 length += OSAL_SPRINTF(&p_phy_result_buf[length],
1143 1147 "100G AOC (active optical cable) detected\n");
1144 1148 break;
1145 1149 case 0x2:
1146 1150 /* 100G SR-4 */
1147 1151 length += OSAL_SPRINTF(&p_phy_result_buf[length],
1148 1152 "100G SR-4 detected\n");
1149 1153 break;
1150 1154 case 0x3:
1151 1155 /* 100G LR-4 */
1152 1156 length += OSAL_SPRINTF(&p_phy_result_buf[length],
1153 1157 "100G LR-4 detected\n");
1154 1158 break;
1155 1159 case 0x4:
1156 1160 /* 100G ER-4 */
1157 1161 length += OSAL_SPRINTF(&p_phy_result_buf[length],
1158 1162 "100G ER-4 detected\n");
1159 1163 break;
1160 1164 case 0x8:
1161 1165 /* 100G ACC (active copper cable) */
1162 1166 length += OSAL_SPRINTF(&p_phy_result_buf[length],
1163 1167 "100G ACC (active copper cable detected\n");
1164 1168 break;
1165 1169 case 0xb:
1166 1170 /* 100G CR-4 */
1167 1171 length += OSAL_SPRINTF(&p_phy_result_buf[length],
1168 1172 "100G CR-4 detected\n");
1169 1173 break;
1170 1174 case 0x11:
1171 1175 /* 4x10G SR */
1172 1176 length += OSAL_SPRINTF(&p_phy_result_buf[length],
1173 1177 "4x10G SR detected\n");
1174 1178 break;
1175 1179 default:
1176 1180 length += OSAL_SPRINTF(&p_phy_result_buf[length],
1177 1181 "Unexpected technology. NEW COMPLIANCE CODE TO SUPPORT 0x%x\n",
1178 1182 buf[0]);
1179 1183 break;
1180 1184 }
1181 1185 break;
1182 1186 default:
1183 1187 /* Unexpected technology compliance field */
1184 1188 length += OSAL_SPRINTF(&p_phy_result_buf[length],
1185 1189 "WARNING: Unexpected technology compliance field detected 0x%x\n",
1186 1190 buf[0]);
1187 1191 length += OSAL_SPRINTF(&p_phy_result_buf[length],
1188 1192 "Assume SR-4 detected\n");
1189 1193 break;
1190 1194 }
1191 1195
1192 1196 /* get extended rate select bytes 141 */
1193 1197 /* get vendor length bytes 142-146 */
1194 1198 /* get device technology byte 147 */
1195 1199 rc = ecore_mcp_phy_sfp_read(p_hwfn, p_ptt, port, I2C_TRANSCEIVER_ADDR,
1196 1200 141, 7, buf);
1197 1201 if (rc != ECORE_SUCCESS)
1198 1202 return ecore_sfp_set_error(rc, length, p_phy_result_buf,
1199 1203 "Error reading extended rate select bytes.\n");
1200 1204
1201 1205 length += OSAL_SPRINTF(&p_phy_result_buf[length],
1202 1206 "Extended rate select bytes 0x%x\n", buf[0]);
1203 1207 length += OSAL_SPRINTF(&p_phy_result_buf[length],
1204 1208 "Length (SMF) 0x%x\n", buf[1]);
1205 1209 length += OSAL_SPRINTF(&p_phy_result_buf[length],
1206 1210 "Length (OM3 50 um) 0x%x\n", buf[2]);
1207 1211 length += OSAL_SPRINTF(&p_phy_result_buf[length],
1208 1212 "Length (OM2 50 um) 0x%x\n", buf[3]);
1209 1213 length += OSAL_SPRINTF(&p_phy_result_buf[length],
1210 1214 "Length (OM1 62.5 um) 0x%x\n", buf[4]);
1211 1215 length += OSAL_SPRINTF(&p_phy_result_buf[length],
1212 1216 "Length (Passive or active) 0x%x\n", buf[5]);
1213 1217 length += OSAL_SPRINTF(&p_phy_result_buf[length],
1214 1218 "Device technology byte 0x%x\n", buf[6]);
1215 1219
1216 1220 /* get vendor name bytes bytes 148-163 */
1217 1221 rc = ecore_mcp_phy_sfp_read(p_hwfn, p_ptt, port, I2C_TRANSCEIVER_ADDR,
1218 1222 148, 16, buf);
1219 1223 if (rc != ECORE_SUCCESS)
1220 1224 return ecore_sfp_set_error(rc, length, p_phy_result_buf,
1221 1225 "Error reading vendor name.\n");
1222 1226
1223 1227 buf[16] = 0;
1224 1228 length += OSAL_SPRINTF(&p_phy_result_buf[length],
1225 1229 "Vendor name: %s\n", buf);
1226 1230
1227 1231 /* get vendor OUI bytes 165-167 */
1228 1232 rc = ecore_mcp_phy_sfp_read(p_hwfn, p_ptt, port, I2C_TRANSCEIVER_ADDR,
1229 1233 165, 3, buf);
1230 1234 if (rc != ECORE_SUCCESS)
1231 1235 return ecore_sfp_set_error(rc, length, p_phy_result_buf,
1232 1236 "Error reading vendor OUI.\n");
1233 1237
1234 1238 length += OSAL_SPRINTF(&p_phy_result_buf[length],
1235 1239 "Vendor OUI: %02x%02x%02x\n",
1236 1240 buf[0], buf[1], buf[2]);
1237 1241
1238 1242 /* get vendor PN bytes 168-183 */
1239 1243 rc = ecore_mcp_phy_sfp_read(p_hwfn, p_ptt, port, I2C_TRANSCEIVER_ADDR,
1240 1244 168, 16, buf);
1241 1245 if (rc != ECORE_SUCCESS)
1242 1246 return ecore_sfp_set_error(rc, length, p_phy_result_buf,
1243 1247 "Error reading vendor PN.\n");
1244 1248
1245 1249 buf[16] = 0;
1246 1250 length += OSAL_SPRINTF(&p_phy_result_buf[length],
1247 1251 "Vendor PN: %s\n", buf);
1248 1252
1249 1253 /* get vendor REV bytes 184-185 */
1250 1254 rc = ecore_mcp_phy_sfp_read(p_hwfn, p_ptt, port, I2C_TRANSCEIVER_ADDR,
1251 1255 184, 2, buf);
1252 1256 if (rc != ECORE_SUCCESS)
1253 1257 return ecore_sfp_set_error(rc, length, p_phy_result_buf,
1254 1258 "Error reading vendor rev.\n");
1255 1259
1256 1260 buf[2] = 0;
1257 1261 length += OSAL_SPRINTF(&p_phy_result_buf[length],
1258 1262 "Vendor rev: %s\n", buf);
1259 1263
1260 1264 return rc;
1261 1265 }
1262 1266
1263 1267 /* Decode SFP information */
1264 1268 int ecore_phy_sfp_decode(struct ecore_hwfn *p_hwfn, struct ecore_ptt *p_ptt,
1265 1269 u32 port, char *p_phy_result_buf)
1266 1270 {
1267 1271 enum _ecore_status_t rc;
1268 1272 u32 length = 0;
1269 1273 u8 buf[4];
1270 1274
1271 1275 /* Verify <port> field is between 0 and number of ports */
1272 1276 rc = ecore_validate_sfp_port(p_hwfn, p_ptt, port, p_phy_result_buf);
1273 1277 if (rc != ECORE_SUCCESS)
1274 1278 return rc;
1275 1279
1276 1280 rc = ecore_mcp_phy_sfp_read(p_hwfn, p_ptt, port, I2C_TRANSCEIVER_ADDR,
1277 1281 0, 1, buf);
1278 1282 if (rc != ECORE_SUCCESS)
1279 1283 return ecore_sfp_set_error(rc, length, p_phy_result_buf,
1280 1284 "Error reading transceiver identification field.\n");
1281 1285
1282 1286 switch (buf[0]) {
1283 1287 case 0x3: /* SFP, SFP+, SFP-28 */
1284 1288 length += OSAL_SPRINTF(&p_phy_result_buf[length],
1285 1289 "SFP, SFP+ or SFP-28 inserted.\n");
1286 1290 rc = ecore_decode_sfp_info(p_hwfn, p_ptt, port,
1287 1291 length, p_phy_result_buf);
1288 1292 break;
1289 1293 case 0xc: /* QSFP */
1290 1294 length += OSAL_SPRINTF(&p_phy_result_buf[length],
1291 1295 "QSFP inserted.\n");
1292 1296 rc = ecore_decode_qsfp_info(p_hwfn, p_ptt, port,
1293 1297 length, p_phy_result_buf);
1294 1298 break;
1295 1299 case 0xd: /* QSFP+ */
1296 1300 length += OSAL_SPRINTF(&p_phy_result_buf[length],
1297 1301 "QSFP+ inserted.\n");
1298 1302 rc = ecore_decode_qsfp_info(p_hwfn, p_ptt, port,
1299 1303 length, p_phy_result_buf);
1300 1304 break;
1301 1305 case 0x11: /* QSFP-28 */
1302 1306 length += OSAL_SPRINTF(&p_phy_result_buf[length],
1303 1307 "QSFP-28 inserted.\n");
1304 1308 rc = ecore_decode_qsfp_info(p_hwfn, p_ptt, port,
1305 1309 length, p_phy_result_buf);
1306 1310 break;
1307 1311 case 0x12: /* CXP2 (CXP-28) */
1308 1312 OSAL_SPRINTF(p_phy_result_buf,
1309 1313 "CXP2 (CXP-28) inserted.\n");
1310 1314 rc = ECORE_UNKNOWN_ERROR;
1311 1315 break;
1312 1316 default:
1313 1317 OSAL_SPRINTF(p_phy_result_buf,
1314 1318 "Unknown transceiver type inserted.\n");
1315 1319 rc = ECORE_UNKNOWN_ERROR;
1316 1320 break;
1317 1321 }
1318 1322
1319 1323 return rc;
1320 1324 }
1321 1325
1322 1326 /* Get SFP inserted status */
1323 1327 int ecore_phy_sfp_get_inserted(struct ecore_hwfn *p_hwfn,
1324 1328 struct ecore_ptt *p_ptt,
1325 1329 u32 port, char *p_phy_result_buf)
1326 1330 {
1327 1331 u32 transceiver_state;
1328 1332 u32 addr = SECTION_OFFSIZE_ADDR(p_hwfn->mcp_info->public_base,
1329 1333 PUBLIC_PORT);
1330 1334 u32 mfw_mb_offsize = ecore_rd(p_hwfn, p_ptt, addr);
1331 1335 u32 port_addr = SECTION_ADDR(mfw_mb_offsize, port);
1332 1336
1333 1337 transceiver_state = ecore_rd(p_hwfn, p_ptt,
1334 1338 port_addr +
1335 1339 OFFSETOF(struct public_port,
1336 1340 transceiver_data));
1337 1341
1338 1342 transceiver_state = GET_FIELD(transceiver_state, ETH_TRANSCEIVER_STATE);
1339 1343
1340 1344 OSAL_SPRINTF(p_phy_result_buf, "%d",
1341 1345 (transceiver_state == ETH_TRANSCEIVER_STATE_PRESENT));
1342 1346
1343 1347 return ECORE_SUCCESS;
1344 1348 }
1345 1349
1346 1350 /* Get SFP TX disable status */
1347 1351 int ecore_phy_sfp_get_txdisable(struct ecore_hwfn *p_hwfn,
1348 1352 struct ecore_ptt *p_ptt,
1349 1353 u32 port, char *p_phy_result_buf)
1350 1354 {
1351 1355 enum _ecore_status_t rc;
1352 1356 u32 length = 0;
1353 1357 u8 buf[4];
1354 1358
1355 1359 /* Verify <port> field is between 0 and number of ports */
1356 1360 rc = ecore_validate_sfp_port(p_hwfn, p_ptt, port, p_phy_result_buf);
1357 1361 if (rc != ECORE_SUCCESS)
1358 1362 return rc;
1359 1363
1360 1364 rc = ecore_mcp_phy_sfp_read(p_hwfn, p_ptt, port, I2C_TRANSCEIVER_ADDR,
1361 1365 0, 1, buf);
1362 1366 if (rc != ECORE_SUCCESS)
1363 1367 return ecore_sfp_set_error(rc, length, p_phy_result_buf,
1364 1368 "Error reading transceiver identification field.\n");
1365 1369
1366 1370 switch (buf[0]) {
1367 1371 case 0x3: /* SFP, SFP+, SFP-28 */
1368 1372 rc = ecore_mcp_phy_sfp_read(p_hwfn, p_ptt, port,
1369 1373 I2C_TRANSCEIVER_ADDR, 110, 1, buf);
1370 1374 if (rc != ECORE_SUCCESS)
1371 1375 return ecore_sfp_set_error(rc, length, p_phy_result_buf,
1372 1376 "Error reading transceiver tx disable status field.\n");
1373 1377 OSAL_SPRINTF(p_phy_result_buf, "%d",
1374 1378 ((buf[0] & 0xC0) ? 1 : 0));
1375 1379 break;
1376 1380 case 0xc: /* QSFP */
1377 1381 case 0xd: /* QSFP+ */
1378 1382 case 0x11: /* QSFP-28 */
1379 1383 rc = ecore_mcp_phy_sfp_read(p_hwfn, p_ptt, port,
1380 1384 I2C_TRANSCEIVER_ADDR, 86, 1, buf);
1381 1385 if (rc != ECORE_SUCCESS)
1382 1386 return ecore_sfp_set_error(rc, length, p_phy_result_buf,
1383 1387 "Error reading transceiver tx disable status field.\n");
1384 1388 OSAL_SPRINTF(p_phy_result_buf, "%d",
1385 1389 ((buf[0] & ((1 << port))) ? 1 : 0));
1386 1390 break;
1387 1391 default:
1388 1392 OSAL_SPRINTF(p_phy_result_buf,
1389 1393 "Unknown transceiver type inserted.\n");
1390 1394 rc = ECORE_UNKNOWN_ERROR;
1391 1395 break;
1392 1396 }
1393 1397
1394 1398 return rc;
1395 1399 }
1396 1400
1397 1401 /* Set SFP TX disable */
1398 1402 int ecore_phy_sfp_set_txdisable(struct ecore_hwfn *p_hwfn,
1399 1403 struct ecore_ptt *p_ptt,
1400 1404 u32 port, u8 txdisable,
1401 1405 char *p_phy_result_buf)
1402 1406 {
1403 1407 enum _ecore_status_t rc;
1404 1408 u32 length = 0;
1405 1409 u8 buf[4];
1406 1410
1407 1411 /* Verify <txdisable> field is between 0 and 1 */
1408 1412 if (txdisable > 1) {
1409 1413 OSAL_SPRINTF(p_phy_result_buf,
1410 1414 "Bad tx disable value, must be 0 or 1.\n");
1411 1415 return ECORE_INVAL;
1412 1416 }
1413 1417
1414 1418 /* Verify <port> field is between 0 and number of ports */
1415 1419 rc = ecore_validate_sfp_port(p_hwfn, p_ptt, port,
1416 1420 p_phy_result_buf);
1417 1421 if (rc != ECORE_SUCCESS)
1418 1422 return rc;
1419 1423
1420 1424 rc = ecore_mcp_phy_sfp_read(p_hwfn, p_ptt, port, I2C_TRANSCEIVER_ADDR,
1421 1425 0, 1, buf);
1422 1426 if (rc != ECORE_SUCCESS)
1423 1427 return ecore_sfp_set_error(rc, length, p_phy_result_buf,
1424 1428 "Error reading transceiver identification field.\n");
1425 1429
1426 1430 switch (buf[0]) {
1427 1431 case 0x3: /* SFP, SFP+, SFP-28 */
1428 1432 rc = ecore_mcp_phy_sfp_read(p_hwfn, p_ptt, port,
1429 1433 I2C_TRANSCEIVER_ADDR,
1430 1434 SFP_TX_DISABLE_OFFSET, 1, buf);
1431 1435 if (rc != ECORE_SUCCESS)
1432 1436 return ecore_sfp_set_error(rc, length, p_phy_result_buf,
1433 1437 "Error reading transceiver tx disable status field.\n");
1434 1438
1435 1439 if (((buf[0] & 0x40) >> 6) != txdisable) {
1436 1440 buf[0] ^= 0x40;
1437 1441 rc = ecore_mcp_phy_sfp_write(p_hwfn, p_ptt, port,
1438 1442 I2C_TRANSCEIVER_ADDR,
1439 1443 SFP_TX_DISABLE_OFFSET,
1440 1444 1, buf);
1441 1445 if (rc != ECORE_SUCCESS)
1442 1446 OSAL_SPRINTF(&p_phy_result_buf[length],
1443 1447 "Error setting transceiver tx disable status field.\n");
1444 1448 }
1445 1449
1446 1450 if (((buf[0] & 0x80) >> 7) != txdisable) {
1447 1451 u32 nvm_cfg_addr, nvm_cfg1_offset, port_cfg_addr;
1448 1452 u16 gpio;
1449 1453
1450 1454 nvm_cfg_addr = ecore_rd(p_hwfn, p_ptt,
1451 1455 MISC_REG_GEN_PURP_CR0);
1452 1456 nvm_cfg1_offset = ecore_rd(p_hwfn, p_ptt,
1453 1457 nvm_cfg_addr + 4);
1454 1458 port_cfg_addr = MCP_REG_SCRATCH + nvm_cfg1_offset +
1455 1459 OFFSETOF(struct nvm_cfg1, port[port]);
1456 1460 gpio = (u16)ecore_rd(p_hwfn, p_ptt,
1457 1461 port_cfg_addr +
1458 1462 OFFSETOF(struct nvm_cfg1_port,
1459 1463 transceiver_00));
1460 1464 gpio &= NVM_CFG1_PORT_TRANS_MODULE_ABS_MASK;
1461 1465 rc = ecore_phy_gpio_write(p_hwfn, p_ptt, gpio,
1462 1466 txdisable,
1463 1467 p_phy_result_buf);
1464 1468 if (rc != ECORE_SUCCESS)
1465 1469 OSAL_SPRINTF(&p_phy_result_buf[length],
1466 1470 "Error setting transceiver tx disable status field.\n");
1467 1471 }
1468 1472 break;
1469 1473 case 0xc: /* QSFP */
1470 1474 case 0xd: /* QSFP+ */
1471 1475 case 0x11: /* QSFP-28 */
1472 1476 rc = ecore_mcp_phy_sfp_read(p_hwfn, p_ptt, port,
1473 1477 I2C_TRANSCEIVER_ADDR,
1474 1478 QSFP_TX_DISABLE_OFFSET, 1, buf);
1475 1479 if (rc != ECORE_SUCCESS)
1476 1480 return ecore_sfp_set_error(rc, length,
1477 1481 p_phy_result_buf,
1478 1482 "Error reading transceiver tx disable status field.\n");
1479 1483 if (((buf[0] & (1 << port)) >> port) != txdisable) {
1480 1484 buf[0] ^= (1 << port);
1481 1485 rc = ecore_mcp_phy_sfp_write(p_hwfn, p_ptt, port,
1482 1486 I2C_TRANSCEIVER_ADDR,
1483 1487 QSFP_TX_DISABLE_OFFSET,
1484 1488 1, buf);
1485 1489 if (rc != ECORE_SUCCESS)
1486 1490 OSAL_SPRINTF(&p_phy_result_buf[length],
1487 1491 "Error setting transceiver tx disable status field.\n");
1488 1492 }
1489 1493 break;
1490 1494 default:
1491 1495 OSAL_SPRINTF(p_phy_result_buf,
1492 1496 "Unknown transceiver type inserted.\n");
1493 1497 rc = ECORE_UNKNOWN_ERROR;
1494 1498 break;
1495 1499 }
1496 1500
1497 1501 return rc;
1498 1502 }
1499 1503
1500 1504 /* Get SFP TX fault status */
1501 1505 int ecore_phy_sfp_get_txreset(struct ecore_hwfn *p_hwfn,
1502 1506 struct ecore_ptt *p_ptt,
1503 1507 u32 port, char *p_phy_result_buf)
1504 1508 {
1505 1509 enum _ecore_status_t rc;
1506 1510 u32 length = 0;
1507 1511 u8 buf[4];
1508 1512
1509 1513 /* Verify <port> field is between 0 and number of ports */
1510 1514 rc = ecore_validate_sfp_port(p_hwfn, p_ptt, port, p_phy_result_buf);
1511 1515 if (rc != ECORE_SUCCESS)
1512 1516 return rc;
1513 1517
1514 1518 rc = ecore_mcp_phy_sfp_read(p_hwfn, p_ptt, port, I2C_TRANSCEIVER_ADDR,
1515 1519 0, 1, buf);
1516 1520 if (rc != ECORE_SUCCESS)
1517 1521 return ecore_sfp_set_error(rc, length, p_phy_result_buf,
1518 1522 "Error reading transceiver identification field.\n");
1519 1523
1520 1524 switch (buf[0]) {
1521 1525 case 0x3: /* SFP, SFP+, SFP-28 */
1522 1526 rc = ecore_mcp_phy_sfp_read(p_hwfn, p_ptt, port,
1523 1527 I2C_TRANSCEIVER_ADDR,
1524 1528 SFP_TX_FAULT_OFFSET, 1, buf);
1525 1529 if (rc != ECORE_SUCCESS)
1526 1530 return ecore_sfp_set_error(rc, length, p_phy_result_buf,
1527 1531 "Error reading transceiver tx fault status field.\n");
1528 1532 OSAL_SPRINTF(p_phy_result_buf, "%d",
1529 1533 ((buf[0] & 0x02) ? 1 : 0));
1530 1534 break;
1531 1535 case 0xc: /* QSFP */
1532 1536 case 0xd: /* QSFP+ */
1533 1537 case 0x11: /* QSFP-28 */
1534 1538 rc = ecore_mcp_phy_sfp_read(p_hwfn, p_ptt, port,
1535 1539 I2C_TRANSCEIVER_ADDR,
1536 1540 QSFP_TX_FAULT_OFFSET, 1, buf);
1537 1541 if (rc != ECORE_SUCCESS)
1538 1542 return ecore_sfp_set_error(rc, length, p_phy_result_buf,
1539 1543 "Error reading transceiver tx fault status field.\n");
1540 1544 OSAL_SPRINTF(p_phy_result_buf, "%d",
1541 1545 ((buf[0] & (1 << port)) ? 1 : 0));
1542 1546 break;
1543 1547 default:
1544 1548 OSAL_SPRINTF(p_phy_result_buf,
1545 1549 "Unknown transceiver type inserted.\n");
1546 1550 rc = ECORE_UNKNOWN_ERROR;
1547 1551 break;
1548 1552 }
1549 1553
1550 1554 return rc;
1551 1555 }
1552 1556
1553 1557 /* Get SFP RX los status */
1554 1558 int ecore_phy_sfp_get_rxlos(struct ecore_hwfn *p_hwfn,
1555 1559 struct ecore_ptt *p_ptt,
1556 1560 u32 port, char *p_phy_result_buf)
1557 1561 {
1558 1562 enum _ecore_status_t rc;
1559 1563 u32 length = 0;
1560 1564 u8 buf[4];
1561 1565
1562 1566 /* Verify <port> field is between 0 and number of ports */
1563 1567 rc = ecore_validate_sfp_port(p_hwfn, p_ptt, port, p_phy_result_buf);
1564 1568 if (rc != ECORE_SUCCESS)
1565 1569 return rc;
1566 1570
1567 1571 rc = ecore_mcp_phy_sfp_read(p_hwfn, p_ptt, port, I2C_TRANSCEIVER_ADDR,
1568 1572 0, 1, buf);
1569 1573 if (rc != ECORE_SUCCESS)
1570 1574 return ecore_sfp_set_error(rc, length, p_phy_result_buf,
1571 1575 "Error reading transceiver identification field.\n");
1572 1576
1573 1577 switch (buf[0]) {
1574 1578 case 0x3: /* SFP, SFP+, SFP-28 */
1575 1579 rc = ecore_mcp_phy_sfp_read(p_hwfn, p_ptt, port,
1576 1580 I2C_TRANSCEIVER_ADDR,
1577 1581 SFP_RX_LOS_OFFSET, 1, buf);
1578 1582 if (rc != ECORE_SUCCESS)
1579 1583 return ecore_sfp_set_error(rc, length, p_phy_result_buf,
1580 1584 "Error reading transceiver rx los status field.\n");
1581 1585 OSAL_SPRINTF(p_phy_result_buf, "%d",
1582 1586 ((buf[0] & 0x01) ? 1 : 0));
1583 1587 break;
1584 1588 case 0xc: /* QSFP */
1585 1589 case 0xd: /* QSFP+ */
1586 1590 case 0x11: /* QSFP-28 */
1587 1591 rc = ecore_mcp_phy_sfp_read(p_hwfn, p_ptt, port,
1588 1592 I2C_TRANSCEIVER_ADDR,
1589 1593 QSFP_RX_LOS_OFFSET, 1, buf);
1590 1594 if (rc != ECORE_SUCCESS)
1591 1595 return ecore_sfp_set_error(rc, length, p_phy_result_buf,
1592 1596 "Error reading transceiver rx los status field.\n");
1593 1597 OSAL_SPRINTF(p_phy_result_buf, "%d",
1594 1598 ((buf[0] & (1 << port)) ? 1 : 0));
1595 1599 break;
1596 1600 default:
1597 1601 OSAL_SPRINTF(p_phy_result_buf,
1598 1602 "Unknown transceiver type inserted.\n");
1599 1603 rc = ECORE_UNKNOWN_ERROR;
1600 1604 break;
1601 1605 }
1602 1606
1603 1607 return rc;
1604 1608 }
1605 1609
1606 1610 /* Get SFP EEPROM memory dump */
1607 1611 int ecore_phy_sfp_get_eeprom(struct ecore_hwfn *p_hwfn,
1608 1612 struct ecore_ptt *p_ptt,
1609 1613 u32 port, char *p_phy_result_buf)
1610 1614 {
1611 1615 enum _ecore_status_t rc;
1612 1616 u8 buf[4];
1613 1617
1614 1618 /* Verify <port> field is between 0 and number of ports */
1615 1619 rc = ecore_validate_sfp_port(p_hwfn, p_ptt, port, p_phy_result_buf);
1616 1620 if (rc != ECORE_SUCCESS)
1617 1621 return rc;
1618 1622
1619 1623 rc = ecore_mcp_phy_sfp_read(p_hwfn, p_ptt, port, I2C_TRANSCEIVER_ADDR,
1620 1624 0, 1, buf);
1621 1625 if (rc != ECORE_SUCCESS)
1622 1626 return ecore_sfp_set_error(rc, 0, p_phy_result_buf,
1623 1627 "Error reading transceiver identification field.\n");
1624 1628
1625 1629 switch (buf[0]) {
1626 1630 case 0x3: /* SFP, SFP+, SFP-28 */
1627 1631 case 0xc: /* QSFP */
1628 1632 case 0xd: /* QSFP+ */
1629 1633 case 0x11: /* QSFP-28 */
1630 1634 rc = ecore_phy_sfp_read(p_hwfn, p_ptt, port,
1631 1635 I2C_TRANSCEIVER_ADDR, 0,
1632 1636 MAX_I2C_TRANSCEIVER_PAGE_SIZE,
1633 1637 p_phy_result_buf);
1634 1638 break;
1635 1639 default:
1636 1640 OSAL_SPRINTF(p_phy_result_buf,
1637 1641 "Unknown transceiver type inserted.\n");
1638 1642 rc = ECORE_UNKNOWN_ERROR;
1639 1643 break;
1640 1644 }
1641 1645
1642 1646 return rc;
1643 1647 }
1644 1648
1645 1649 /* Write to gpio */
1646 1650 int ecore_phy_gpio_write(struct ecore_hwfn *p_hwfn, struct ecore_ptt *p_ptt,
1647 1651 u16 gpio, u16 gpio_val, char *p_phy_result_buf)
1648 1652 {
1649 1653 enum _ecore_status_t rc;
1650 1654
1651 1655 rc = ecore_mcp_gpio_write(p_hwfn, p_ptt, gpio, gpio_val);
1652 1656
1653 1657 if (rc == ECORE_SUCCESS)
1654 1658 OSAL_SPRINTF(p_phy_result_buf,
1655 1659 "Written successfully to gpio number %d.\n",
1656 1660 gpio);
1657 1661 else
1658 1662 OSAL_SPRINTF(p_phy_result_buf,
1659 1663 "Can't write to gpio %d\n", gpio);
1660 1664
1661 1665 return rc;
1662 1666 }
1663 1667
1664 1668 /* Read from gpio */
1665 1669 int ecore_phy_gpio_read(struct ecore_hwfn *p_hwfn, struct ecore_ptt *p_ptt,
1666 1670 u16 gpio, char *p_phy_result_buf)
1667 1671 {
1668 1672 enum _ecore_status_t rc;
1669 1673 u32 param;
1670 1674
1671 1675 rc = ecore_mcp_gpio_read(p_hwfn, p_ptt, gpio, ¶m);
1672 1676
1673 1677 if (rc == ECORE_SUCCESS)
1674 1678 OSAL_SPRINTF(p_phy_result_buf, "%x", param);
1675 1679 else
1676 1680 OSAL_SPRINTF(p_phy_result_buf,
1677 1681 "Can't read from gpio %d\n", gpio);
1678 1682
1679 1683 return rc;
1680 1684 }
1681 1685
1682 1686 /* Get information from gpio */
1683 1687 int ecore_phy_gpio_info(struct ecore_hwfn *p_hwfn, struct ecore_ptt *p_ptt,
1684 1688 u16 gpio, char *p_phy_result_buf)
1685 1689 {
1686 1690 u32 direction, ctrl, length = 0;
1687 1691 enum _ecore_status_t rc;
1688 1692
1689 1693 rc = ecore_mcp_gpio_info(p_hwfn, p_ptt, gpio, &direction, &ctrl);
1690 1694
1691 1695 if (rc != ECORE_SUCCESS) {
1692 1696 OSAL_SPRINTF(p_phy_result_buf,
1693 1697 "Can't get information for gpio %d\n", gpio);
1694 1698 return rc;
1695 1699 }
1696 1700
1697 1701 length = OSAL_SPRINTF(p_phy_result_buf, "Gpio %d is %s - ",
1698 1702 gpio,
1699 1703 ((direction == 0) ? "output" : "input"));
1700 1704 switch (ctrl) {
1701 1705 case 0:
1702 1706 OSAL_SPRINTF(&p_phy_result_buf[length],
1703 1707 "control is uninitialized\n");
1704 1708 break;
1705 1709 case 1:
1706 1710 OSAL_SPRINTF(&p_phy_result_buf[length],
1707 1711 "control is path 0\n");
1708 1712 break;
1709 1713 case 2:
1710 1714 OSAL_SPRINTF(&p_phy_result_buf[length],
1711 1715 "control is path 1\n");
1712 1716 break;
1713 1717 case 3:
1714 1718 OSAL_SPRINTF(&p_phy_result_buf[length],
1715 1719 "control is shared\n");
1716 1720 break;
1717 1721 default:
1718 1722 OSAL_SPRINTF(&p_phy_result_buf[length],
1719 1723 "\nError - control is invalid\n");
1720 1724 break;
1721 1725 }
1722 1726
1723 1727 return ECORE_SUCCESS;
1724 1728 }
1725 1729
1726 1730 /* Get information from gpio */
1727 1731 int ecore_phy_extphy_read(struct ecore_hwfn *p_hwfn, struct ecore_ptt *p_ptt,
1728 1732 u16 port, u16 devad, u16 reg, char *p_phy_result_buf)
1729 1733 {
1730 1734 enum _ecore_status_t rc;
1731 1735 u32 resp_cmd;
1732 1736 u32 val;
1733 1737
1734 1738 rc = ecore_mcp_cmd(p_hwfn, p_ptt, DRV_MSG_CODE_EXT_PHY_READ,
1735 1739 ((port << DRV_MB_PARAM_PORT_SHIFT) |
1736 1740 (devad << DRV_MB_PARAM_DEVAD_SHIFT) |
1737 1741 (reg << DRV_MB_PARAM_ADDR_SHIFT)),
1738 1742 &resp_cmd,
1739 1743 &val);
1740 1744
1741 1745 if ((rc != ECORE_SUCCESS) || (resp_cmd != FW_MSG_CODE_PHY_OK)) {
1742 1746 OSAL_SPRINTF(p_phy_result_buf,
1743 1747 "Failed reading external PHY\n");
1744 1748 return rc;
1745 1749 }
1746 1750 OSAL_SPRINTF(p_phy_result_buf, "0x%04x\n", val);
1747 1751 return ECORE_SUCCESS;
1748 1752 }
1749 1753
1750 1754 /* Get information from gpio */
1751 1755 int ecore_phy_extphy_write(struct ecore_hwfn *p_hwfn, struct ecore_ptt *p_ptt,
1752 1756 u16 port, u16 devad, u16 reg, u16 val,
1753 1757 char *p_phy_result_buf)
1754 1758 {
1755 1759 enum _ecore_status_t rc;
1756 1760 u32 resp_cmd;
1757 1761 u32 fw_param;
1758 1762
1759 1763 rc = ecore_mcp_nvm_wr_cmd(p_hwfn, p_ptt, DRV_MSG_CODE_EXT_PHY_WRITE,
1760 1764 ((port << DRV_MB_PARAM_PORT_SHIFT) |
1761 1765 (devad << DRV_MB_PARAM_DEVAD_SHIFT) |
1762 1766 (reg << DRV_MB_PARAM_ADDR_SHIFT)),
1763 1767 &resp_cmd,
1764 1768 &fw_param,
1765 1769 sizeof(u32),
1766 1770 (u32 *)&val);
1767 1771
1768 1772 if ((rc != ECORE_SUCCESS) || (resp_cmd != FW_MSG_CODE_PHY_OK)) {
1769 1773 OSAL_SPRINTF(p_phy_result_buf,
1770 1774 "Failed writing external PHY\n");
1771 1775 return rc;
1772 1776 }
1773 1777 OSAL_SPRINTF(p_phy_result_buf, "0\n");
1774 1778 return ECORE_SUCCESS;
1775 1779 }
↓ open down ↓ |
1136 lines elided |
↑ open up ↑ |
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX