4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License, v.1, (the "License").
6 * You may not use this file except in compliance with the License.
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://opensource.org/licenses/CDDL-1.0.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
23 * Copyright 2014-2017 Cavium, Inc.
24 * The contents of this file are subject to the terms of the Common Development
25 * and Distribution License, v.1, (the "License").
27 * You may not use this file except in compliance with the License.
29 * You can obtain a copy of the License at available
30 * at http://opensource.org/licenses/CDDL-1.0
32 * See the License for the specific language governing permissions and
33 * limitations under the License.
40 #include "ecore_hsi_common.h"
41 #include "ecore_mcp.h"
43 #include "ecore_phy_api.h"
45 #define SERDESID 0x900e
48 enum _ecore_status_t
ecore_phy_read(struct ecore_hwfn
*p_hwfn
,
49 struct ecore_ptt
*p_ptt
, u32 port
, u32 lane
,
50 u32 addr
, u32 cmd
, u8
*buf
)
52 return ecore_mcp_phy_read(p_hwfn
->p_dev
, cmd
,
53 addr
| (lane
<< 16) | (1<<29) | (port
<< 30), buf
, 8);
56 enum _ecore_status_t
ecore_phy_write(struct ecore_hwfn
*p_hwfn
,
57 struct ecore_ptt
*p_ptt
, u32 port
,
58 u32 lane
, u32 addr
, u32 data_lo
,
63 OSAL_MEMCPY(buf64
, &data_lo
, 4);
64 OSAL_MEMCPY(buf64
+ 4, &data_hi
, 4);
66 return ecore_mcp_phy_write(p_hwfn
->p_dev
, cmd
,
67 addr
| (lane
<< 16) | (1<<29) | (port
<< 30),
72 int ecore_phy_core_write(struct ecore_hwfn
*p_hwfn
, struct ecore_ptt
*p_ptt
,
73 u32 port
, u32 addr
, u32 data_lo
, u32 data_hi
,
74 char *p_phy_result_buf
)
76 enum _ecore_status_t rc
= ECORE_INVAL
;
79 OSAL_SPRINTF(p_phy_result_buf
,
80 "ERROR! Port must be in range of 0..3\n");
84 /* write to address */
85 rc
= ecore_phy_write(p_hwfn
, p_ptt
, port
, 0 /* lane */, addr
, data_lo
,
86 data_hi
, ECORE_PHY_CORE_WRITE
);
87 if (rc
== ECORE_SUCCESS
)
88 OSAL_SPRINTF(p_phy_result_buf
, "0\n");
90 OSAL_SPRINTF(p_phy_result_buf
,
91 "Failed placing phy_core command\n");
97 int ecore_phy_core_read(struct ecore_hwfn
*p_hwfn
, struct ecore_ptt
*p_ptt
,
98 u32 port
, u32 addr
, char *p_phy_result_buf
)
100 enum _ecore_status_t rc
= ECORE_INVAL
;
106 OSAL_SPRINTF(p_phy_result_buf
,
107 "ERROR! Port must be in range of 0..3\n");
111 /* read from address */
112 rc
= ecore_phy_read(p_hwfn
, p_ptt
, port
, 0 /* lane */ , addr
,
113 ECORE_PHY_CORE_READ
, buf64
);
114 if (rc
== ECORE_SUCCESS
) {
115 OSAL_MEMCPY(data_lo
, buf64
, 4);
116 OSAL_MEMCPY(data_hi
, (buf64
+ 4), 4);
117 OSAL_SPRINTF(p_phy_result_buf
, "0x%08x%08x\n",
118 *(u32
*)data_hi
, *(u32
*)data_lo
);
121 OSAL_SPRINTF(p_phy_result_buf
, "Failed placing phy_core command\n");
127 int ecore_phy_raw_write(struct ecore_hwfn
*p_hwfn
, struct ecore_ptt
*p_ptt
,
128 u32 port
, u32 lane
, u32 addr
, u32 data_lo
,
129 u32 data_hi
, char *p_phy_result_buf
)
131 enum _ecore_status_t rc
= ECORE_INVAL
;
133 /* check if the enterd port is in the range */
135 OSAL_SPRINTF(p_phy_result_buf
,
136 "Port must be in range of 0..3\n");
140 /* check if the enterd lane is in the range */
142 OSAL_SPRINTF(p_phy_result_buf
,
143 "Lane must be in range of 0..6\n");
147 /* write to address*/
148 rc
= ecore_phy_write(p_hwfn
,p_ptt
, port
, lane
, addr
, data_lo
,
149 data_hi
, ECORE_PHY_RAW_WRITE
);
150 if (rc
== ECORE_SUCCESS
)
151 OSAL_SPRINTF(p_phy_result_buf
, "0\n");
153 OSAL_SPRINTF(p_phy_result_buf
,
154 "Failed placing phy_core command\n");
160 int ecore_phy_raw_read(struct ecore_hwfn
*p_hwfn
, struct ecore_ptt
*p_ptt
,
161 u32 port
, u32 lane
, u32 addr
, char *p_phy_result_buf
)
163 enum _ecore_status_t rc
= ECORE_INVAL
;
168 /* check if the enterd port is in the range */
170 OSAL_SPRINTF(p_phy_result_buf
,
171 "Port must be in range of 0..3\n");
175 /* check if the enterd lane is in the range */
177 OSAL_SPRINTF(p_phy_result_buf
,
178 "Lane must be in range of 0..6\n");
182 /* read from address */
183 rc
= ecore_phy_read(p_hwfn
,p_ptt
, port
, lane
, addr
, ECORE_PHY_RAW_READ
,
185 if (rc
== ECORE_SUCCESS
) {
186 OSAL_MEMCPY(data_lo
, buf64
, 4);
187 OSAL_MEMCPY(data_hi
, (buf64
+ 4), 4);
188 OSAL_SPRINTF(p_phy_result_buf
, "0x%08x%08x\n",
189 *(u32
*)data_hi
, *(u32
*)data_lo
);
191 OSAL_SPRINTF(p_phy_result_buf
,
192 "Failed placing phy_core command\n");
198 static u32
ecore_phy_get_nvm_cfg1_addr(struct ecore_hwfn
*p_hwfn
,
199 struct ecore_ptt
*p_ptt
)
201 u32 nvm_cfg_addr
, nvm_cfg1_offset
;
203 nvm_cfg_addr
= ecore_rd(p_hwfn
, p_ptt
, MISC_REG_GEN_PURP_CR0
);
204 nvm_cfg1_offset
= ecore_rd(p_hwfn
, p_ptt
, nvm_cfg_addr
+
205 offsetof(struct nvm_cfg
,
206 sections_offset
[NVM_CFG_SECTION_NVM_CFG1
]));
207 return MCP_REG_SCRATCH
+ nvm_cfg1_offset
;
211 int ecore_phy_info(struct ecore_hwfn
*p_hwfn
, struct ecore_ptt
*p_ptt
,
212 char *p_phy_result_buf
)
214 u32 nvm_cfg1_addr
= ecore_phy_get_nvm_cfg1_addr(p_hwfn
, p_ptt
);
215 u32 port_mode
, port
, max_ports
, core_cfg
, length
= 0;
216 enum _ecore_status_t rc
= ECORE_INVAL
;
221 u8 is_bb
= ((ecore_rd(p_hwfn
, p_ptt
, MISCS_REG_CHIP_NUM
) & 0x8070)
225 length
+= OSAL_SPRINTF(&p_phy_result_buf
[length
],
228 length
+= OSAL_SPRINTF(&p_phy_result_buf
[length
],
231 core_cfg
= ecore_rd(p_hwfn
, p_ptt
, nvm_cfg1_addr
+
232 offsetof(struct nvm_cfg1
, glob
.core_cfg
));
233 port_mode
= (core_cfg
& NVM_CFG1_GLOB_NETWORK_PORT_MODE_MASK
) >>
234 NVM_CFG1_GLOB_NETWORK_PORT_MODE_OFFSET
;
236 case NVM_CFG1_GLOB_NETWORK_PORT_MODE_BB_1X100G
:
237 length
+= OSAL_SPRINTF(&p_phy_result_buf
[length
], "1x100G\n");
240 case NVM_CFG1_GLOB_NETWORK_PORT_MODE_1X40G
:
241 length
+= OSAL_SPRINTF(&p_phy_result_buf
[length
], "1x40G\n");
244 case NVM_CFG1_GLOB_NETWORK_PORT_MODE_1X25G
:
245 length
+= OSAL_SPRINTF(&p_phy_result_buf
[length
], "1x25G\n");
248 case NVM_CFG1_GLOB_NETWORK_PORT_MODE_BB_2X40G
:
249 length
+= OSAL_SPRINTF(&p_phy_result_buf
[length
], "2x40G\n");
252 case NVM_CFG1_GLOB_NETWORK_PORT_MODE_2X50G
:
253 length
+= OSAL_SPRINTF(&p_phy_result_buf
[length
], "2x50G\n");
256 case NVM_CFG1_GLOB_NETWORK_PORT_MODE_2X25G
:
257 length
+= OSAL_SPRINTF(&p_phy_result_buf
[length
], "2x25G\n");
260 case NVM_CFG1_GLOB_NETWORK_PORT_MODE_2X10G
:
261 length
+= OSAL_SPRINTF(&p_phy_result_buf
[length
], "2x10G\n");
264 case NVM_CFG1_GLOB_NETWORK_PORT_MODE_4X10G_F
:
265 length
+= OSAL_SPRINTF(&p_phy_result_buf
[length
], "4x10G\n");
268 case NVM_CFG1_GLOB_NETWORK_PORT_MODE_BB_4X10G_E
:
269 length
+= OSAL_SPRINTF(&p_phy_result_buf
[length
], "4x10G\n");
272 case NVM_CFG1_GLOB_NETWORK_PORT_MODE_BB_4X20G
:
273 length
+= OSAL_SPRINTF(&p_phy_result_buf
[length
], "4x20G\n");
276 case NVM_CFG1_GLOB_NETWORK_PORT_MODE_4X25G
:
277 length
+= OSAL_SPRINTF(&p_phy_result_buf
[length
], "4x25G\n");
281 length
+= OSAL_SPRINTF(&p_phy_result_buf
[length
],
282 "Wrong port mode\n");
287 for (port
= 0; port
< max_ports
; port
++) {
288 rc
= ecore_phy_read(p_hwfn
, p_ptt
, port
, 0, SERDESID
,
289 DRV_MSG_CODE_PHY_RAW_READ
, buf64
);
290 if (rc
== ECORE_SUCCESS
) {
291 length
+= OSAL_SPRINTF(
292 &p_phy_result_buf
[length
],
293 "Port %d is in ", port
);
294 OSAL_MEMCPY(data_lo
, buf64
, 4);
295 OSAL_MEMCPY(data_hi
, (buf64
+ 4), 4);
296 if ((data_lo
[0] & 0x3f) == 0x14)
297 length
+= OSAL_SPRINTF(
298 &p_phy_result_buf
[length
],
301 length
+= OSAL_SPRINTF(
302 &p_phy_result_buf
[length
],
307 /* @@@TMP until ecore_phy_read() on AH is supported */
308 for (port
= 0; port
< max_ports
; port
++)
309 length
+= OSAL_SPRINTF(&p_phy_result_buf
[length
],
310 "Port %d is in MPS25\n", port
);
323 static struct tsc_stat ah_stat_regs
[] = {
324 {0x000100, "ETHERSTATSOCTETS ", "total, good and bad"},
325 /* {0x000104, "ETHERSTATSOCTETS_H ", "total, good and bad"},*/
326 {0x000108, "OCTETSOK ", "total, good"},
327 /* {0x00010c, "OCTETSOK_H ", "total, good"}, */
328 {0x000110, "AALIGNMENTERRORS ", "Wrong SFD detected"},
329 /* {0x000114, "AALIGNMENTERRORS_H ", "Wrong SFD detected"}, */
330 {0x000118, "APAUSEMACCTRLFRAMES ", "Good Pause frames received"},
331 /* {0x00011c, "APAUSEMACCTRLFRAMES_H ", "Good Pause frames received"}, */
332 {0x000120, "FRAMESOK ", "Good frames received"},
333 /* {0x000124, "FRAMESOK_H ", "Good frames received"}, */
334 {0x000128, "CRCERRORS ", "wrong CRC and good length received"},
335 /* {0x00012c, "CRCERRORS_H ", "wrong CRC and good length received"}, */
336 {0x000130, "VLANOK ", "Good Frames with VLAN tag received"},
337 /* {0x000134, "VLANOK_H ", "Good Frames with VLAN tag received"}, */
338 {0x000138, "IFINERRORS ", "Errored frames received"},
339 /* {0x00013c, "IFINERRORS_H ", "Errored frames received"}, */
340 {0x000140, "IFINUCASTPKTS ", "Good Unicast received"},
341 /* {0x000144, "IFINUCASTPKTS_H ", "Good Unicast received"}, */
342 {0x000148, "IFINMCASTPKTS ", "Good Multicast received"},
343 /* {0x00014c, "IFINMCASTPKTS_H ", "Good Multicast received"}, */
344 {0x000150, "IFINBCASTPKTS ", "Good Broadcast received"},
345 /* {0x000154, "IFINBCASTPKTS_H ", "Good Broadcast received"}, */
346 {0x000158, "ETHERSTATSDROPEVENTS ", "Dropped frames"},
347 /* {0x00015c, "ETHERSTATSDROPEVENTS_H ", "Dropped frames"}, */
348 {0x000160, "ETHERSTATSPKTS ", "Frames received, good and bad"},
349 /* {0x000164, "ETHERSTATSPKTS_H ", "Frames received, good and bad"}, */
350 {0x000168, "ETHERSTATSUNDERSIZEPKTS ", "Frames received less 64 with good crc"},
351 /* {0x00016c, "ETHERSTATSUNDERSIZEPKTS_H ", "Frames received less 64 with good crc"}, */
352 {0x000170, "ETHERSTATSPKTS64 ", "Frames of 64 octets received"},
353 /* {0x000174, "ETHERSTATSPKTS64_H ", "Frames of 64 octets received"}, */
354 {0x000178, "ETHERSTATSPKTS65TO127 ", "Frames of 65 to 127 octets received"},
355 /* {0x00017c, "ETHERSTATSPKTS65TO127_H ", "Frames of 65 to 127 octets received"}, */
356 {0x000180, "ETHERSTATSPKTS128TO255 ", "Frames of 128 to 255 octets received"},
357 /* {0x000184, "ETHERSTATSPKTS128TO255_H ", "Frames of 128 to 255 octets received"}, */
358 {0x000188, "ETHERSTATSPKTS256TO511 ", "Frames of 256 to 511 octets received"},
359 /* {0x00018c, "ETHERSTATSPKTS256TO511_H ", "Frames of 256 to 511 octets received"},*/
360 {0x000190, "ETHERSTATSPKTS512TO1023 ", "Frames of 512 to 1023 octets received"},
361 /* {0x000194, "ETHERSTATSPKTS512TO1023_H ", "Frames of 512 to 1023 octets received"},*/
362 {0x000198, "ETHERSTATSPKTS1024TO1518 ", "Frames of 1024 to 1518 octets received"},
363 /* {0x00019c, "ETHERSTATSPKTS1024TO1518_H ", "Frames of 1024 to 1518 octets received"},*/
364 {0x0001a0, "ETHERSTATSPKTS1519TOMAX ", "Frames of 1519 to FRM_LENGTH octets received"},
365 /* {0x0001a4, "ETHERSTATSPKTS1519TOMAX_H ", "Frames of 1519 to FRM_LENGTH octets received"},*/
366 {0x0001a8, "ETHERSTATSPKTSOVERSIZE ", "Frames greater FRM_LENGTH and good CRC received"},
367 /* {0x0001ac, "ETHERSTATSPKTSOVERSIZE_H ", "Frames greater FRM_LENGTH and good CRC received"},*/
368 {0x0001b0, "ETHERSTATSJABBERS ", "Frames greater FRM_LENGTH and bad CRC received"},
369 /* {0x0001b4, "ETHERSTATSJABBERS_H ", "Frames greater FRM_LENGTH and bad CRC received"},*/
370 {0x0001b8, "ETHERSTATSFRAGMENTS ", "Frames less 64 and bad CRC received"},
371 /* {0x0001bc, "ETHERSTATSFRAGMENTS_H ", "Frames less 64 and bad CRC received"},*/
372 {0x0001c0, "AMACCONTROLFRAMES ", "Good frames received of type 0x8808 but not Pause"},
373 /* {0x0001c4, "AMACCONTROLFRAMES_H ", "Good frames received of type 0x8808 but not Pause"},*/
374 {0x0001c8, "AFRAMETOOLONG ", "Good and bad frames exceeding FRM_LENGTH received"},
375 /* {0x0001cc, "AFRAMETOOLONG_H ", "Good and bad frames exceeding FRM_LENGTH received"},*/
376 {0x0001d0, "AINRANGELENGTHERROR ", "Good frames with invalid length field (not supported)"},
377 /* {0x0001d4, "AINRANGELENGTHERROR_H ", "Good frames with invalid length field (not supported)"},*/
378 {0x000200, "TXETHERSTATSOCTETS ", "total, good and bad"},
379 /* {0x000204, "TXETHERSTATSOCTETS_H ", "total, good and bad"},*/
380 {0x000208, "TXOCTETSOK ", "total, good"},
381 /* {0x00020c, "TXOCTETSOK_H ", "total, good"},*/
382 {0x000218, "TXAPAUSEMACCTRLFRAMES ", "Good Pause frames transmitted"},
383 /* {0x00021c, "TXAPAUSEMACCTRLFRAMES_H ", "Good Pause frames transmitted"},*/
384 {0x000220, "TXFRAMESOK ", "Good frames transmitted"},
385 /* {0x000224, "TXFRAMESOK_H ", "Good frames transmitted"},*/
386 {0x000228, "TXCRCERRORS ", "wrong CRC transmitted"},
387 /* {0x00022c, "TXCRCERRORS_H ", "wrong CRC transmitted"},*/
388 {0x000230, "TXVLANOK ", "Good Frames with VLAN tag transmitted"},
389 /* {0x000234, "TXVLANOK_H ", "Good Frames with VLAN tag transmitted"},*/
390 {0x000238, "IFOUTERRORS ", "Errored frames transmitted"},
391 /* {0x00023c, "IFOUTERRORS_H ", "Errored frames transmitted"},*/
392 {0x000240, "IFOUTUCASTPKTS ", "Good Unicast transmitted"},
393 /* {0x000244, "IFOUTUCASTPKTS_H ", "Good Unicast transmitted"},*/
394 {0x000248, "IFOUTMCASTPKTS ", "Good Multicast transmitted"},
395 /* {0x00024c, "IFOUTMCASTPKTS_H ", "Good Multicast transmitted"},*/
396 {0x000250, "IFOUTBCASTPKTS ", "Good Broadcast transmitted"},
397 /* {0x000254, "IFOUTBCASTPKTS_H ", "Good Broadcast transmitted"},*/
398 {0x000258, "TXETHERSTATSDROPEVENTS ", "Dropped frames (unused, reserved)"},
399 /* {0x00025c, "TXETHERSTATSDROPEVENTS_H ", "Dropped frames (unused, reserved)"},*/
400 {0x000260, "TXETHERSTATSPKTS ", "Frames transmitted, good and bad"},
401 /* {0x000264, "TXETHERSTATSPKTS_H ", "Frames transmitted, good and bad"},*/
402 {0x000268, "TXETHERSTATSUNDERSIZEPKTS ", "Frames transmitted less 64"},
403 /* {0x00026c, "TXETHERSTATSUNDERSIZEPKTS_H ", "Frames transmitted less 64"},*/
404 {0x000270, "TXETHERSTATSPKTS64 ", "Frames of 64 octets transmitted"},
405 /* {0x000274, "TXETHERSTATSPKTS64_H ", "Frames of 64 octets transmitted"},*/
406 {0x000278, "TXETHERSTATSPKTS65TO127 ", "Frames of 65 to 127 octets transmitted"},
407 /* {0x00027c, "TXETHERSTATSPKTS65TO127_H ", "Frames of 65 to 127 octets transmitted"},*/
408 {0x000280, "TXETHERSTATSPKTS128TO255 ", "Frames of 128 to 255 octets transmitted"},
409 /* {0x000284, "TXETHERSTATSPKTS128TO255_H ", "Frames of 128 to 255 octets transmitted"},*/
410 {0x000288, "TXETHERSTATSPKTS256TO511 ", "Frames of 256 to 511 octets transmitted"},
411 /* {0x00028c, "TXETHERSTATSPKTS256TO511_H ", "Frames of 256 to 511 octets transmitted"},*/
412 {0x000290, "TXETHERSTATSPKTS512TO1023 ", "Frames of 512 to 1023 octets transmitted"},
413 /* {0x000294, "TXETHERSTATSPKTS512TO1023_H ", "Frames of 512 to 1023 octets transmitted"},*/
414 {0x000298, "TXETHERSTATSPKTS1024TO1518 ", "Frames of 1024 to 1518 octets transmitted"},
415 /* {0x00029c, "TXETHERSTATSPKTS1024TO1518_H ", "Frames of 1024 to 1518 octets transmitted"},*/
416 {0x0002a0, "TXETHERSTATSPKTS1519TOTX_MTU ", "Frames of 1519 to FRM_LENGTH.TX_MTU octets transmitted"},
417 /* {0x0002a4, "TXETHERSTATSPKTS1519TOTX_MTU_H ", "Frames of 1519 to FRM_LENGTH.TX_MTU octets transmitted"},*/
418 {0x0002c0, "TXAMACCONTROLFRAMES ", "Good frames transmitted of type 0x8808 but not Pause"},
419 /* {0x0002c4, "TXAMACCONTROLFRAMES_H ", "Good frames transmitted of type 0x8808 but not Pause"},*/
420 {0x000380, "ACBFCPAUSEFRAMESRECEIVED_0 ", "Set of 8 objects recording the number of CBFC (Class Based Flow Control) pause frames received for each class."},
421 /* {0x000384, "ACBFCPAUSEFRAMESRECEIVED_0_H ", "Upper 32bit of 64bit counter."},*/
422 {0x000388, "ACBFCPAUSEFRAMESRECEIVED_1 ", "Set of 8 objects recording the number of CBFC (Class Based Flow Control) pause frames received for each class."},
423 /* {0x00038c, "ACBFCPAUSEFRAMESRECEIVED_1_H ", "Upper 32bit of 64bit counter."},*/
424 {0x000390, "ACBFCPAUSEFRAMESRECEIVED_2 ", "Set of 8 objects recording the number of CBFC (Class Based Flow Control) pause frames received for each class."},
425 /* {0x000394, "ACBFCPAUSEFRAMESRECEIVED_2_H ", "Upper 32bit of 64bit counter."},*/
426 {0x000398, "ACBFCPAUSEFRAMESRECEIVED_3 ", "Set of 8 objects recording the number of CBFC (Class Based Flow Control) pause frames received for each class."},
427 /* {0x00039c, "ACBFCPAUSEFRAMESRECEIVED_3_H ", "Upper 32bit of 64bit counter."},*/
428 {0x0003a0, "ACBFCPAUSEFRAMESRECEIVED_4 ", "Set of 8 objects recording the number of CBFC (Class Based Flow Control) pause frames received for each class."},
429 /* {0x0003a4, "ACBFCPAUSEFRAMESRECEIVED_4_H ", "Upper 32bit of 64bit counter."},*/
430 {0x0003a8, "ACBFCPAUSEFRAMESRECEIVED_5 ", "Set of 8 objects recording the number of CBFC (Class Based Flow Control) pause frames received for each class."},
431 /* {0x0003ac, "ACBFCPAUSEFRAMESRECEIVED_5_H ", "Upper 32bit of 64bit counter."},*/
432 {0x0003b0, "ACBFCPAUSEFRAMESRECEIVED_6 ", "Set of 8 objects recording the number of CBFC (Class Based Flow Control) pause frames received for each class."},
433 /* {0x0003b4, "ACBFCPAUSEFRAMESRECEIVED_6_H ", "Upper 32bit of 64bit counter."},*/
434 {0x0003b8, "ACBFCPAUSEFRAMESRECEIVED_7 ", "Set of 8 objects recording the number of CBFC (Class Based Flow Control) pause frames received for each class."},
435 /* {0x0003bc, "ACBFCPAUSEFRAMESRECEIVED_7_H ", "Upper 32bit of 64bit counter."},*/
436 {0x0003c0, "ACBFCPAUSEFRAMESTRANSMITTED_0 ", "Set of 8 objects recording the number of CBFC (Class Based Flow Control) pause frames transmitted for each class."},
437 /* {0x0003c4, "ACBFCPAUSEFRAMESTRANSMITTED_0_H", "Upper 32bit of 64bit counter."},*/
438 {0x0003c8, "ACBFCPAUSEFRAMESTRANSMITTED_1 ", "Set of 8 objects recording the number of CBFC (Class Based Flow Control) pause frames transmitted for each class."},
439 /* {0x0003cc, "ACBFCPAUSEFRAMESTRANSMITTED_1_H", "Upper 32bit of 64bit counter."},*/
440 {0x0003d0, "ACBFCPAUSEFRAMESTRANSMITTED_2 ", "Set of 8 objects recording the number of CBFC (Class Based Flow Control) pause frames transmitted for each class."},
441 /* {0x0003d4, "ACBFCPAUSEFRAMESTRANSMITTED_2_H", "Upper 32bit of 64bit counter."},*/
442 {0x0003d8, "ACBFCPAUSEFRAMESTRANSMITTED_3 ", "Set of 8 objects recording the number of CBFC (Class Based Flow Control) pause frames transmitted for each class."},
443 /* {0x0003dc, "ACBFCPAUSEFRAMESTRANSMITTED_3_H", "Upper 32bit of 64bit counter."},*/
444 {0x0003e0, "ACBFCPAUSEFRAMESTRANSMITTED_4 ", "Set of 8 objects recording the number of CBFC (Class Based Flow Control) pause frames transmitted for each class."},
445 /* {0x0003e4, "ACBFCPAUSEFRAMESTRANSMITTED_4_H", "Upper 32bit of 64bit counter."},*/
446 {0x0003e8, "ACBFCPAUSEFRAMESTRANSMITTED_5 ", "Set of 8 objects recording the number of CBFC (Class Based Flow Control) pause frames transmitted for each class."},
447 /* {0x0003ec, "ACBFCPAUSEFRAMESTRANSMITTED_5_H", "Upper 32bit of 64bit counter."},*/
448 {0x0003f0, "ACBFCPAUSEFRAMESTRANSMITTED_6 ", "Set of 8 objects recording the number of CBFC (Class Based Flow Control) pause frames transmitted for each class."},
449 /* {0x0003f4, "ACBFCPAUSEFRAMESTRANSMITTED_6_H", "Upper 32bit of 64bit counter."},*/
450 {0x0003f8, "ACBFCPAUSEFRAMESTRANSMITTED_7 ", "Set of 8 objects recording the number of CBFC (Class Based Flow Control) pause frames transmitted for each class."},
451 /* {0x0003fc, "ACBFCPAUSEFRAMESTRANSMITTED_7_H", "Upper 32bit of 64bit counter."}*/
453 static struct tsc_stat bb_stat_regs
[] = {
454 {0x00000000, "GRX64","RX 64-byte frame counter" },
455 {0x00000001, "GRX127","RX 65 to 127 byte frame counter" },
456 {0x00000002, "GRX255","RX 128 to 255 byte frame counter" },
457 {0x00000003, "GRX511","RX 256 to 511 byte frame counter" },
458 {0x00000004, "GRX1023","RX 512 to 1023 byte frame counter" },
459 {0x00000005, "GRX1518","RX 1024 to 1518 byte frame counter" },
460 {0x00000006, "GRX1522","RX 1519 to 1522 byte VLAN-tagged frame counter" },
461 {0x00000007, "GRX2047","RX 1519 to 2047 byte frame counter" },
462 {0x00000008, "GRX4095","RX 2048 to 4095 byte frame counter" },
463 {0x00000009, "GRX9216","RX 4096 to 9216 byte frame counter" },
464 {0x0000000a, "GRX16383","RX 9217 to 16383 byte frame counter" },
465 {0x0000000b, "GRXPKT","RX frame counter (all packets)" },
466 {0x0000000c, "GRXUCA","RX UC frame counter" },
467 {0x0000000d, "GRXMCA","RX MC frame counter" },
468 {0x0000000e, "GRXBCA","RX BC frame counter" },
469 {0x0000000f, "GRXFCS","RX FCS error frame counter" },
470 {0x00000010, "GRXCF","RX control frame counter" },
471 {0x00000011, "GRXPF","RX pause frame counter" },
472 {0x00000012, "GRXPP","RX PFC frame counter" },
473 {0x00000013, "GRXUO","RX unsupported opcode frame counter" },
474 {0x00000014, "GRXUDA","RX unsupported DA for pause/PFC frame counter" },
475 {0x00000015, "GRXWSA","RX incorrect SA counter" },
476 {0x00000016, "GRXALN","RX alignment error counter" },
477 {0x00000017, "GRXFLR","RX out-of-range length frame counter" },
478 {0x00000018, "GRXFRERR","RX code error frame counter" },
479 {0x00000019, "GRXFCR","RX false carrier counter" },
480 {0x0000001a, "GRXOVR","RX oversized frame counter" },
481 {0x0000001b, "GRXJBR","RX jabber frame counter" },
482 {0x0000001c, "GRXMTUE","RX MTU check error frame counter" },
483 {0x0000001d, "GRXMCRC",
484 "RX packet with 4-Byte CRC matching MACSEC_PROG_TX_CRC." },
485 {0x0000001e, "GRXPRM","RX promiscuous packet counter" },
486 {0x0000001f, "GRXVLN","RX single and double VLAN tagged frame counter" },
487 {0x00000020, "GRXDVLN","RX double VLANG tagged frame counter" },
488 {0x00000021, "GRXTRFU","RX truncated frame (due to RX FIFO full) counter" },
489 {0x00000022, "GRXPOK","RX good frame (good CRC, not oversized, no ERROR)" },
490 {0x00000023, "GRXPFCOFF0",
491 "RX PFC frame transition XON to XOFF for Priority0" },
492 {0x00000024, "GRXPFCOFF1",
493 "RX PFC frame transition XON to XOFF for Priority1" },
494 {0x00000025, "GRXPFCOFF2",
495 "RX PFC frame transition XON to XOFF for Priority2" },
496 {0x00000026, "GRXPFCOFF3",
497 "RX PFC frame transition XON to XOFF for Priority3" },
498 {0x00000027, "GRXPFCOFF4",
499 "RX PFC frame transition XON to XOFF for Priority4" },
500 {0x00000028, "GRXPFCOFF5",
501 "RX PFC frame transition XON to XOFF for Priority5" },
502 {0x00000029, "GRXPFCOFF6",
503 "RX PFC frame transition XON to XOFF for Priority6" },
504 {0x0000002a, "GRXPFCOFF7",
505 "RX PFC frame transition XON to XOFF for Priority7" },
506 {0x0000002b, "GRXPFCP0","RX PFC frame with enable bit set for Priority0" },
507 {0x0000002c, "GRXPFCP1","RX PFC frame with enable bit set for Priority1" },
508 {0x0000002d, "GRXPFCP2","RX PFC frame with enable bit set for Priority2" },
509 {0x0000002e, "GRXPFCP3","RX PFC frame with enable bit set for Priority3" },
510 {0x0000002f, "GRXPFCP4","RX PFC frame with enable bit set for Priority4" },
511 {0x00000030, "GRXPFCP5","RX PFC frame with enable bit set for Priority5" },
512 {0x00000031, "GRXPFCP6","RX PFC frame with enable bit set for Priority6" },
513 {0x00000032, "GRXPFCP7","RX PFC frame with enable bit set for Priority7" },
514 {0x00000033, "GRXSCHCRC","RX frame with SCH CRC error. For LH mode only" },
515 {0x00000034, "GRXUND","RX undersized frame counter" },
516 {0x00000035, "GRXFRG","RX fragment counter" },
517 {0x00000036, "RXEEELPI", "RX EEE LPI counter"},
518 {0x00000037, "RXEEELPIDU", "RX EEE LPI duration counter"},
519 {0x00000038, "RXLLFCPHY", "RX LLFC PHY COUNTER"},
520 {0x00000039, "RXLLFCLOG", "RX LLFC LOG COUNTER"},
521 {0x0000003a, "RXLLFCCRC", "RX LLFC CRC COUNTER"},
522 {0x0000003b, "RXHCFC", "RX HCFC COUNTER"},
523 {0x0000003c, "RXHCFCCRC", "RX HCFC CRC COUNTER"},
524 {0x0000003d, "GRXBYT", "RX byte counter"},
525 {0x0000003e, "GRXRBYT", "RX runt byte counter"},
526 {0x0000003f, "GRXRPKT", "RX packet counter"},
527 {0x00000040, "GTX64", "TX 64-byte frame counter"},
528 {0x00000041, "GTX127", "TX 65 to 127 byte frame counter"},
529 {0x00000042, "GTX255", "TX 128 to 255 byte frame counter"},
530 {0x00000043, "GTX511", "TX 256 to 511 byte frame counter"},
531 {0x00000044, "GTX1023", "TX 512 to 1023 byte frame counter"},
532 {0x00000045, "GTX1518", "TX 1024 to 1518 byte frame counter"},
533 {0x00000046, "GTX1522", "TX 1519 to 1522 byte VLAN-tagged frame counter"},
534 {0x00000047, "GTX2047", "TX 1519 to 2047 byte frame counter"},
535 {0x00000048, "GTX4095", "TX 2048 to 4095 byte frame counte"},
536 {0x00000049, "GTX9216", "TX 4096 to 9216 byte frame counter"},
537 {0x0000004a, "GTX16383", "TX 9217 to 16383 byte frame counter"},
538 {0x0000004b, "GTXPOK", "TX good frame counter"},
539 {0x0000004c, "GTXPKT", "TX frame counter (all packets"},
540 {0x0000004d, "GTXUCA", "TX UC frame counter"},
541 {0x0000004e, "GTXMCA", "TX MC frame counter"},
542 {0x0000004f, "GTXBCA", "TX BC frame counter"},
543 {0x00000050, "GTXPF", "TX pause frame counter"},
544 {0x00000051, "GTXPP", "TX PFC frame counter"},
545 {0x00000052, "GTXJBR", "TX jabber counter"},
546 {0x00000053, "GTXFCS", "TX FCS error counter"},
547 {0x00000054, "GTXCF", "TX control frame counter"},
548 {0x00000055, "GTXOVR", "TX oversize packet counter"},
549 {0x00000056, "GTXDFR", "TX Single Deferral Frame Counter"},
550 {0x00000057, "GTXEDF", "TX Multiple Deferral Frame Counter"},
551 {0x00000058, "GTXSCL", "TX Single Collision Frame Counter"},
552 {0x00000059, "GTXMCL", "TX Multiple Collision Frame Counter"},
553 {0x0000005a, "GTXLCL", "TX Late Collision Frame Counter"},
554 {0x0000005b, "GTXXCL", "TX Excessive Collision Frame Counter"},
555 {0x0000005c, "GTXFRG", "TX fragment counter"},
556 {0x0000005d, "GTXERR", "TX error (set by system) frame counter"},
557 {0x0000005e, "GTXVLN", "TX VLAN Tag Frame Counter"},
558 {0x0000005f, "GTXDVLN", "TX Double VLAN Tag Frame Counter"},
559 {0x00000060, "GTXRPKT", "TX RUNT Frame Counter"},
560 {0x00000061, "GTXUFL", "TX FIFO Underrun Counter"},
561 {0x00000062, "GTXPFCP0", "TX PFC frame with enable bit set for Priority0"},
562 {0x00000063, "GTXPFCP1", "TX PFC frame with enable bit set for Priority1"},
563 {0x00000064, "GTXPFCP2", "TX PFC frame with enable bit set for Priority2"},
564 {0x00000065, "GTXPFCP3", "TX PFC frame with enable bit set for Priority3"},
565 {0x00000066, "GTXPFCP4", "TX PFC frame with enable bit set for Priority4"},
566 {0x00000067, "GTXPFCP5", "TX PFC frame with enable bit set for Priority5"},
567 {0x00000068, "GTXPFCP6", "TX PFC frame with enable bit set for Priority6"},
568 {0x00000069, "GTXPFCP7", "TX PFC frame with enable bit set for Priority7"},
569 {0x0000006a, "TXEEELPI", "TX EEE LPI Event Counter"},
570 {0x0000006b, "TXEEELPIDU", "TX EEE LPI Duration Counter"},
571 {0x0000006c, "TXLLFCLOG", "Transmit Logical Type LLFC message counter"},
572 {0x0000006d, "TXHCFC", "Transmit Logical Type LLFC message counter"},
573 {0x0000006e, "GTXNCL", "Transmit Total Collision Counter"},
574 {0x0000006f, "GTXBYT", "TX byte counter"}
578 static int ecore_bb_phy_mac_stat(struct ecore_hwfn
*p_hwfn
,
579 struct ecore_ptt
*p_ptt
,
580 u32 port
, char *p_phy_result_buf
)
582 u8 buf64
[8] = {0}, data_hi
[4], data_lo
[4];
583 bool b_false_alarm
= false;
584 u32 length
, reg_id
, addr
;
585 enum _ecore_status_t rc
= ECORE_INVAL
;
587 length
= OSAL_SPRINTF(p_phy_result_buf
,
588 "MAC stats for port %d (only non-zero)\n", port
);
590 for (reg_id
= 0; reg_id
< OSAL_ARRAY_SIZE(bb_stat_regs
); reg_id
++) {
591 addr
= bb_stat_regs
[reg_id
].reg
;
592 rc
= ecore_phy_read(p_hwfn
, p_ptt
, port
, 0 /*lane*/, addr
,
593 ECORE_PHY_CORE_READ
, buf64
);
595 OSAL_MEMCPY(data_lo
, buf64
, 4);
596 OSAL_MEMCPY(data_hi
, (buf64
+ 4), 4);
598 if (rc
== ECORE_SUCCESS
) {
599 if (*(u32
*)data_lo
!= 0) { /* Only non-zero */
600 length
+= OSAL_SPRINTF(&p_phy_result_buf
[length
],
601 "%-10s: 0x%08x (%s)\n",
602 bb_stat_regs
[reg_id
].name
,
604 bb_stat_regs
[reg_id
].desc
);
605 if ((bb_stat_regs
[reg_id
].reg
== 0x0000000f) ||
606 (bb_stat_regs
[reg_id
].reg
== 0x00000018) ||
607 (bb_stat_regs
[reg_id
].reg
== 0x00000035))
608 b_false_alarm
= true;
611 OSAL_SPRINTF(p_phy_result_buf
, "Failed reading stat 0x%x\n\n",
617 length
+= OSAL_SPRINTF(&p_phy_result_buf
[length
],
618 "Note: GRXFCS/GRXFRERR/GRXFRG may "
619 "increment when the port shuts down\n");
625 static int ecore_ah_e5_phy_mac_stat(struct ecore_hwfn
*p_hwfn
,
626 struct ecore_ptt
*p_ptt
, u32 port
,
627 char *p_phy_result_buf
)
629 u32 length
, reg_id
, addr
, data_hi
, data_lo
;
631 length
= OSAL_SPRINTF(p_phy_result_buf
,
632 "MAC stats for port %d (only non-zero)\n", port
);
634 for (reg_id
= 0; reg_id
< OSAL_ARRAY_SIZE(ah_stat_regs
); reg_id
++) {
635 addr
= ah_stat_regs
[reg_id
].reg
;
636 data_lo
= ecore_rd(p_hwfn
, p_ptt
,
638 NWM_REG_MAC0_SIZE
* 4 * port
+
640 data_hi
= ecore_rd(p_hwfn
, p_ptt
,
642 NWM_REG_MAC0_SIZE
* 4 * port
+
645 if (data_lo
) { /* Only non-zero */
646 length
+= OSAL_SPRINTF(&p_phy_result_buf
[length
],
647 "%-10s: 0x%08x (%s)\n",
648 ah_stat_regs
[reg_id
].name
,
650 ah_stat_regs
[reg_id
].desc
);
654 return ECORE_SUCCESS
;
657 int ecore_phy_mac_stat(struct ecore_hwfn
*p_hwfn
, struct ecore_ptt
*p_ptt
,
658 u32 port
, char *p_phy_result_buf
)
660 int num_ports
= ecore_device_num_ports(p_hwfn
->p_dev
);
662 if (port
>= (u32
)num_ports
) {
663 OSAL_SPRINTF(p_phy_result_buf
,
664 "Port must be in range of 0..%d\n", num_ports
);
668 if (ECORE_IS_BB(p_hwfn
->p_dev
))
669 return ecore_bb_phy_mac_stat(p_hwfn
, p_ptt
, port
,
672 return ecore_ah_e5_phy_mac_stat(p_hwfn
, p_ptt
, port
,
676 #define SFP_RX_LOS_OFFSET 110
677 #define SFP_TX_DISABLE_OFFSET 110
678 #define SFP_TX_FAULT_OFFSET 110
680 #define QSFP_RX_LOS_OFFSET 3
681 #define QSFP_TX_DISABLE_OFFSET 86
682 #define QSFP_TX_FAULT_OFFSET 4
684 /* Set SFP error string */
685 static int ecore_sfp_set_error(enum _ecore_status_t rc
, u32 offset
,
686 char *p_phy_result_buf
, char *p_err_str
)
688 if (rc
!= ECORE_SUCCESS
) {
689 if (rc
== ECORE_NODEV
)
690 OSAL_SPRINTF((char *)&p_phy_result_buf
[offset
],
691 "Transceiver is unplugged.\n");
693 OSAL_SPRINTF((char *)&p_phy_result_buf
[offset
], "%s",
696 return ECORE_UNKNOWN_ERROR
;
702 /* Validate SFP port */
703 static int ecore_validate_sfp_port(struct ecore_hwfn
*p_hwfn
,
704 struct ecore_ptt
*p_ptt
,
705 u32 port
, char *p_phy_result_buf
)
707 /* Verify <port> field is between 0 and number of ports */
708 u32 num_ports
= ecore_device_num_ports(p_hwfn
->p_dev
);
710 if (port
>= num_ports
) {
712 OSAL_SPRINTF(p_phy_result_buf
,
713 "Bad port number, must be 0.\n");
715 OSAL_SPRINTF(p_phy_result_buf
,
716 "Bad port number, must be between 0 and %d.\n",
722 return ECORE_SUCCESS
;
725 /* Validate SFP parameters */
726 static int ecore_validate_sfp_parameters(struct ecore_hwfn
*p_hwfn
,
727 struct ecore_ptt
*p_ptt
,
728 u32 port
, u32 addr
, u32 offset
,
729 u32 size
, char *p_phy_result_buf
)
731 enum _ecore_status_t rc
;
733 /* Verify <port> field is between 0 and number of ports */
734 rc
= ecore_validate_sfp_port(p_hwfn
, p_ptt
, port
, p_phy_result_buf
);
735 if (rc
!= ECORE_SUCCESS
)
738 /* Verify <I2C> field is 0xA0 or 0xA2 */
739 if ((addr
!= 0xA0) && (addr
!= 0xA2)) {
740 OSAL_SPRINTF(p_phy_result_buf
,
741 "Bad I2C address, must be 0xA0 or 0xA2.\n");
745 /* Verify <size> field is 1 - MAX_I2C_TRANSCEIVER_PAGE_SIZE */
746 if ((size
== 0) || (size
> MAX_I2C_TRANSCEIVER_PAGE_SIZE
)) {
747 OSAL_SPRINTF(p_phy_result_buf
,
748 "Bad size, must be between 1 and %d.\n",
749 MAX_I2C_TRANSCEIVER_PAGE_SIZE
);
753 /* Verify <offset> + <size> <= MAX_I2C_TRANSCEIVER_PAGE_SIZE */
754 if (offset
+ size
> MAX_I2C_TRANSCEIVER_PAGE_SIZE
) {
755 OSAL_SPRINTF(p_phy_result_buf
,
756 "Bad offset and size, must not exceed %d.\n",
757 MAX_I2C_TRANSCEIVER_PAGE_SIZE
);
765 int ecore_phy_sfp_write(struct ecore_hwfn
*p_hwfn
, struct ecore_ptt
*p_ptt
,
766 u32 port
, u32 addr
, u32 offset
, u32 size
,
767 u32 val
, char *p_phy_result_buf
)
769 enum _ecore_status_t rc
;
771 rc
= ecore_validate_sfp_parameters(p_hwfn
, p_ptt
, port
, addr
,
772 offset
, size
, p_phy_result_buf
);
773 if (rc
== ECORE_SUCCESS
)
775 rc
= ecore_mcp_phy_sfp_write(p_hwfn
, p_ptt
, port
, addr
,
776 offset
, size
, (u8
*)&val
);
778 if (rc
!= ECORE_SUCCESS
)
779 return ecore_sfp_set_error(rc
, 0, p_phy_result_buf
,
780 "Error writing to transceiver.\n");
782 OSAL_SPRINTF(p_phy_result_buf
,
783 "Written successfully to transceiver.\n");
790 int ecore_phy_sfp_read(struct ecore_hwfn
*p_hwfn
, struct ecore_ptt
*p_ptt
,
791 u32 port
, u32 addr
, u32 offset
,
792 u32 size
, char *p_phy_result_buf
)
794 enum _ecore_status_t rc
;
797 rc
= ecore_validate_sfp_parameters(p_hwfn
, p_ptt
, port
, addr
,
798 offset
, size
, p_phy_result_buf
);
799 if (rc
== ECORE_SUCCESS
)
802 u8 buf
[MAX_I2C_TRANSCEIVER_PAGE_SIZE
];
804 rc
= ecore_mcp_phy_sfp_read(p_hwfn
, p_ptt
, port
, addr
,
806 if (rc
!= ECORE_SUCCESS
)
807 return ecore_sfp_set_error(rc
, 0, p_phy_result_buf
,
808 "Error reading from transceiver.\n");
809 for (i
= 0; i
< size
; i
++)
810 length
+= OSAL_SPRINTF(
811 (char *)&p_phy_result_buf
[length
],
818 static enum _ecore_status_t
ecore_decode_sfp_info(struct ecore_hwfn
*p_hwfn
,
819 struct ecore_ptt
*p_ptt
,
820 u32 port
, u32 length
,
821 char *p_phy_result_buf
)
823 /* SFP EEPROM contents are described in SFF-8024 and SFF-8472 */
824 /***********************************************/
825 /* SFP DATA and locations */
826 /* get specification complianace bytes 3-10 */
827 /* get signal rate byte 12 */
828 /* get extended compliance code byte 36 */
829 /* get vendor length bytes 14-19 */
830 /* get vendor name bytes bytes 20-35 */
831 /* get vendor OUI bytes 37-39 */
832 /* get vendor PN bytes 40-55 */
833 /* get vendor REV bytes 56-59 */
835 /***********************************************/
836 enum _ecore_status_t rc
;
839 /* Read byte 12 - signal rate, and if nothing matches */
840 /* check byte 8 for 10G copper */
841 rc
= ecore_mcp_phy_sfp_read(p_hwfn
, p_ptt
, port
, I2C_TRANSCEIVER_ADDR
,
843 if (rc
!= ECORE_SUCCESS
)
844 return ecore_sfp_set_error(rc
, length
, p_phy_result_buf
,
845 "Error reading specification compliance field.\n");
847 length
+= OSAL_SPRINTF(&p_phy_result_buf
[length
],
848 "BYTE 12 signal rate: %d\n", buf
[0]);
851 length
+= OSAL_SPRINTF(&p_phy_result_buf
[length
],
852 "25G signal rate: %d\n", buf
[0]);
853 /* 25G - This should be copper - could double check */
854 /* Read byte 3 - optics, and if nothing matches */
855 /* check byte 8 for 10G copper */
856 rc
= ecore_mcp_phy_sfp_read(p_hwfn
, p_ptt
, port
,
857 I2C_TRANSCEIVER_ADDR
, 3, 1, buf
);
858 if (rc
!= ECORE_SUCCESS
)
859 return ecore_sfp_set_error(rc
, length
,
861 "Error reading optics field.\n");
865 length
+= OSAL_SPRINTF(&p_phy_result_buf
[length
],
866 "25G Passive copper detected\n");
869 length
+= OSAL_SPRINTF(&p_phy_result_buf
[length
],
870 "25G Active copper detected\n");
873 length
+= OSAL_SPRINTF(&p_phy_result_buf
[length
],
874 "UNKNOWN 25G cable detected: %x\n",
879 } else if (buf
[3] >= 100) {
880 length
+= OSAL_SPRINTF(&p_phy_result_buf
[length
],
881 "10G signal rate: %d\n", buf
[0]);
882 /* 10G - Read byte 3 for optics and byte 8 for copper, and */
884 /* Read byte 3 - optics, and if nothing matches check byte */
885 /* 8 for 10G copper */
886 rc
= ecore_mcp_phy_sfp_read(p_hwfn
, p_ptt
, port
,
887 I2C_TRANSCEIVER_ADDR
, 3, 1, buf
);
888 if (rc
!= ECORE_SUCCESS
)
889 return ecore_sfp_set_error(rc
, length
,
891 "Error reading optics field.\n");
896 length
+= OSAL_SPRINTF(&p_phy_result_buf
[length
],
897 "10G SR detected\n");
901 length
+= OSAL_SPRINTF(&p_phy_result_buf
[length
],
902 "10G LR detected\n");
906 length
+= OSAL_SPRINTF(&p_phy_result_buf
[length
],
907 "10G LRM detected\n");
910 length
+= OSAL_SPRINTF(&p_phy_result_buf
[length
],
911 "10G ER detected\n");
914 length
+= OSAL_SPRINTF(&p_phy_result_buf
[length
],
915 "SFP/SFP+/SFP-28 transceiver type 0x%x not known... Check for 10G copper.\n",
917 /* Read 3, check 8 too */
918 rc
= ecore_mcp_phy_sfp_read(p_hwfn
, p_ptt
, port
,
919 I2C_TRANSCEIVER_ADDR
,
921 if (rc
!= ECORE_SUCCESS
)
922 return ecore_sfp_set_error(rc
, length
,
924 "Error reading 10G copper field.\n");
929 length
+= OSAL_SPRINTF(
930 &p_phy_result_buf
[length
],
931 "10G Passive copper detected\n");
935 length
+= OSAL_SPRINTF(
936 &p_phy_result_buf
[length
],
937 "10G Active copper detected\n");
940 length
+= OSAL_SPRINTF(
941 &p_phy_result_buf
[length
],
942 "Unexpected SFP/SFP+/SFP-28 transceiver type 0x%x\n",
945 } /* switch byte 8 */
947 } /* switch byte 3 */
949 } else if (buf
[0] >= 10) {
950 length
+= OSAL_SPRINTF(&p_phy_result_buf
[length
],
951 "1G signal rate: %d\n", buf
[3]);
952 /* 1G - Read byte 6 for optics and byte 8 for copper */
953 rc
= ecore_mcp_phy_sfp_read(p_hwfn
, p_ptt
, port
,
954 I2C_TRANSCEIVER_ADDR
, 6, 1, buf
);
955 if (rc
!= ECORE_SUCCESS
)
956 return ecore_sfp_set_error(rc
, length
,
958 "Error reading optics field.\n");
962 length
+= OSAL_SPRINTF(&p_phy_result_buf
[length
],
966 length
+= OSAL_SPRINTF(&p_phy_result_buf
[length
],
970 length
+= OSAL_SPRINTF(&p_phy_result_buf
[length
],
971 "Assume 1G Passive copper detected\n");
976 /* get vendor length bytes 14-19 */
977 rc
= ecore_mcp_phy_sfp_read(p_hwfn
, p_ptt
, port
, I2C_TRANSCEIVER_ADDR
,
979 if (rc
!= ECORE_SUCCESS
)
980 return ecore_sfp_set_error(rc
, length
, p_phy_result_buf
,
981 "Error reading vendor length bytes.\n");
983 length
+= OSAL_SPRINTF(&p_phy_result_buf
[length
],
984 "Length (SMF, km) 0x%x\n", buf
[0]);
985 length
+= OSAL_SPRINTF(&p_phy_result_buf
[length
],
986 "Length (SMF) 0x%x\n", buf
[1]);
987 length
+= OSAL_SPRINTF(&p_phy_result_buf
[length
],
988 "Length (50 um) 0x%x\n", buf
[2]);
989 length
+= OSAL_SPRINTF(&p_phy_result_buf
[length
],
990 "Length (62.5 um) 0x%x\n", buf
[3]);
991 length
+= OSAL_SPRINTF(&p_phy_result_buf
[length
],
992 "Length (OM4 or copper cable) 0x%x\n", buf
[4]);
993 length
+= OSAL_SPRINTF(&p_phy_result_buf
[length
],
994 "Length (OM3) 0x%x\n", buf
[5]);
996 /* get vendor name bytes bytes 20-35 */
997 rc
= ecore_mcp_phy_sfp_read(p_hwfn
, p_ptt
, port
, I2C_TRANSCEIVER_ADDR
,
999 if (rc
!= ECORE_SUCCESS
)
1000 return ecore_sfp_set_error(rc
, length
, p_phy_result_buf
,
1001 "Error reading vendor name.\n");
1004 length
+= OSAL_SPRINTF(&p_phy_result_buf
[length
],
1005 "Vendor name: %s\n", buf
);
1007 /* get vendor OUI bytes 37-39 */
1008 rc
= ecore_mcp_phy_sfp_read(p_hwfn
, p_ptt
, port
, I2C_TRANSCEIVER_ADDR
,
1010 if (rc
!= ECORE_SUCCESS
)
1011 return ecore_sfp_set_error(rc
, length
, p_phy_result_buf
,
1012 "Error reading vendor OUI.\n");
1014 length
+= OSAL_SPRINTF(&p_phy_result_buf
[length
],
1015 "Vendor OUI: %02x%02x%02x\n",
1016 buf
[0], buf
[1], buf
[2]);
1018 /* get vendor PN bytes 40-55 */
1019 rc
= ecore_mcp_phy_sfp_read(p_hwfn
, p_ptt
, port
, I2C_TRANSCEIVER_ADDR
,
1021 if (rc
!= ECORE_SUCCESS
)
1022 return ecore_sfp_set_error(rc
, length
, p_phy_result_buf
,
1023 "Error reading vendor PN.\n");
1026 length
+= OSAL_SPRINTF(&p_phy_result_buf
[length
],
1027 "Vendor PN: %s\n", buf
);
1029 /* get vendor REV bytes 56-59 */
1030 rc
= ecore_mcp_phy_sfp_read(p_hwfn
, p_ptt
, port
, I2C_TRANSCEIVER_ADDR
,
1032 if (rc
!= ECORE_SUCCESS
)
1033 return ecore_sfp_set_error(rc
, length
, p_phy_result_buf
,
1034 "Error reading vendor rev.\n");
1037 length
+= OSAL_SPRINTF(&p_phy_result_buf
[length
],
1038 "Vendor rev: %s\n", buf
);
1043 static enum _ecore_status_t
ecore_decode_qsfp_info(struct ecore_hwfn
*p_hwfn
,
1044 struct ecore_ptt
*p_ptt
,
1045 u32 port
, u32 length
,
1046 char *p_phy_result_buf
)
1048 /* QSFP EEPROM contents are described in SFF-8024 and SFF-8636 */
1049 /***********************************************/
1050 /* QSFP DATA and locations */
1051 /* get specification complianace bytes 131-138 */
1052 /* get extended rate select bytes 141 */
1053 /* get vendor length bytes 142-146 */
1054 /* get device technology byte 147 */
1055 /* get vendor name bytes bytes 148-163 */
1056 /* get vendor OUI bytes 165-167 */
1057 /* get vendor PN bytes 168-183 */
1058 /* get vendor REV bytes 184-185 */
1060 /***********************************************/
1061 enum _ecore_status_t rc
;
1064 rc
= ecore_mcp_phy_sfp_read(p_hwfn
, p_ptt
, port
, I2C_TRANSCEIVER_ADDR
,
1066 if (rc
!= ECORE_SUCCESS
)
1067 return ecore_sfp_set_error(rc
, length
, p_phy_result_buf
,
1068 "Error reading transceiver compliance code.\n");
1070 length
+= OSAL_SPRINTF(&p_phy_result_buf
[length
],
1071 "Transceiver compliance code 0x%x\n", buf
[0]);
1075 /* 40G Active (XLPPI) */
1076 length
+= OSAL_SPRINTF(&p_phy_result_buf
[length
],
1077 "40G Active (XLPPI) detected.\n");
1081 length
+= OSAL_SPRINTF(&p_phy_result_buf
[length
],
1082 "40G LR-4 detected.\n");
1086 length
+= OSAL_SPRINTF(&p_phy_result_buf
[length
],
1087 "40G SR-4 detected.\n");
1091 length
+= OSAL_SPRINTF(&p_phy_result_buf
[length
],
1092 "40G CR-4 detected.\n");
1096 length
+= OSAL_SPRINTF(&p_phy_result_buf
[length
],
1097 "10G SR detected.\n");
1101 length
+= OSAL_SPRINTF(&p_phy_result_buf
[length
],
1102 "10G LR detected.\n");
1106 length
+= OSAL_SPRINTF(&p_phy_result_buf
[length
],
1107 "10G LRM detected.\n");
1109 case 0x88: /* Could be 40G/100G CR4 cable, check 192 for 100G CR4 */
1110 length
+= OSAL_SPRINTF(&p_phy_result_buf
[length
],
1111 "Multi-rate transceiver: 40G CR-4 detected...\n");
1114 /* Use extended technology field */
1115 length
+= OSAL_SPRINTF(&p_phy_result_buf
[length
],
1116 "Use extended technology field\n");
1117 /* Byte 93 & 129 is supposed to have power info. During */
1118 /* testing all reads 0. Ignore for now */
1119 /* 0-127 is in the first page this in high region - */
1120 /* see what page it is. */
1122 /* ret_val = read_transceiver_data(g_port, i2c_addr, 129, */
1124 /* length += OSAL_SPRINTF(&p_phy_result_buf[length], */
1125 /* "Read transceiver power data. Value read: 0x%hx\n\n", */
1128 rc
= ecore_mcp_phy_sfp_read(p_hwfn
, p_ptt
, port
,
1129 I2C_TRANSCEIVER_ADDR
, 192, 1, buf
);
1130 if (rc
!= ECORE_SUCCESS
)
1131 return ecore_sfp_set_error(rc
, length
, p_phy_result_buf
,
1132 "Error reading technology compliance field.\n");
1137 length
+= OSAL_SPRINTF(&p_phy_result_buf
[length
],
1138 "Unspecified detected.\n");
1141 /* 100G AOC (active optical cable) */
1142 length
+= OSAL_SPRINTF(&p_phy_result_buf
[length
],
1143 "100G AOC (active optical cable) detected\n");
1147 length
+= OSAL_SPRINTF(&p_phy_result_buf
[length
],
1148 "100G SR-4 detected\n");
1152 length
+= OSAL_SPRINTF(&p_phy_result_buf
[length
],
1153 "100G LR-4 detected\n");
1157 length
+= OSAL_SPRINTF(&p_phy_result_buf
[length
],
1158 "100G ER-4 detected\n");
1161 /* 100G ACC (active copper cable) */
1162 length
+= OSAL_SPRINTF(&p_phy_result_buf
[length
],
1163 "100G ACC (active copper cable detected\n");
1167 length
+= OSAL_SPRINTF(&p_phy_result_buf
[length
],
1168 "100G CR-4 detected\n");
1172 length
+= OSAL_SPRINTF(&p_phy_result_buf
[length
],
1173 "4x10G SR detected\n");
1176 length
+= OSAL_SPRINTF(&p_phy_result_buf
[length
],
1177 "Unexpected technology. NEW COMPLIANCE CODE TO SUPPORT 0x%x\n",
1183 /* Unexpected technology compliance field */
1184 length
+= OSAL_SPRINTF(&p_phy_result_buf
[length
],
1185 "WARNING: Unexpected technology compliance field detected 0x%x\n",
1187 length
+= OSAL_SPRINTF(&p_phy_result_buf
[length
],
1188 "Assume SR-4 detected\n");
1192 /* get extended rate select bytes 141 */
1193 /* get vendor length bytes 142-146 */
1194 /* get device technology byte 147 */
1195 rc
= ecore_mcp_phy_sfp_read(p_hwfn
, p_ptt
, port
, I2C_TRANSCEIVER_ADDR
,
1197 if (rc
!= ECORE_SUCCESS
)
1198 return ecore_sfp_set_error(rc
, length
, p_phy_result_buf
,
1199 "Error reading extended rate select bytes.\n");
1201 length
+= OSAL_SPRINTF(&p_phy_result_buf
[length
],
1202 "Extended rate select bytes 0x%x\n", buf
[0]);
1203 length
+= OSAL_SPRINTF(&p_phy_result_buf
[length
],
1204 "Length (SMF) 0x%x\n", buf
[1]);
1205 length
+= OSAL_SPRINTF(&p_phy_result_buf
[length
],
1206 "Length (OM3 50 um) 0x%x\n", buf
[2]);
1207 length
+= OSAL_SPRINTF(&p_phy_result_buf
[length
],
1208 "Length (OM2 50 um) 0x%x\n", buf
[3]);
1209 length
+= OSAL_SPRINTF(&p_phy_result_buf
[length
],
1210 "Length (OM1 62.5 um) 0x%x\n", buf
[4]);
1211 length
+= OSAL_SPRINTF(&p_phy_result_buf
[length
],
1212 "Length (Passive or active) 0x%x\n", buf
[5]);
1213 length
+= OSAL_SPRINTF(&p_phy_result_buf
[length
],
1214 "Device technology byte 0x%x\n", buf
[6]);
1216 /* get vendor name bytes bytes 148-163 */
1217 rc
= ecore_mcp_phy_sfp_read(p_hwfn
, p_ptt
, port
, I2C_TRANSCEIVER_ADDR
,
1219 if (rc
!= ECORE_SUCCESS
)
1220 return ecore_sfp_set_error(rc
, length
, p_phy_result_buf
,
1221 "Error reading vendor name.\n");
1224 length
+= OSAL_SPRINTF(&p_phy_result_buf
[length
],
1225 "Vendor name: %s\n", buf
);
1227 /* get vendor OUI bytes 165-167 */
1228 rc
= ecore_mcp_phy_sfp_read(p_hwfn
, p_ptt
, port
, I2C_TRANSCEIVER_ADDR
,
1230 if (rc
!= ECORE_SUCCESS
)
1231 return ecore_sfp_set_error(rc
, length
, p_phy_result_buf
,
1232 "Error reading vendor OUI.\n");
1234 length
+= OSAL_SPRINTF(&p_phy_result_buf
[length
],
1235 "Vendor OUI: %02x%02x%02x\n",
1236 buf
[0], buf
[1], buf
[2]);
1238 /* get vendor PN bytes 168-183 */
1239 rc
= ecore_mcp_phy_sfp_read(p_hwfn
, p_ptt
, port
, I2C_TRANSCEIVER_ADDR
,
1241 if (rc
!= ECORE_SUCCESS
)
1242 return ecore_sfp_set_error(rc
, length
, p_phy_result_buf
,
1243 "Error reading vendor PN.\n");
1246 length
+= OSAL_SPRINTF(&p_phy_result_buf
[length
],
1247 "Vendor PN: %s\n", buf
);
1249 /* get vendor REV bytes 184-185 */
1250 rc
= ecore_mcp_phy_sfp_read(p_hwfn
, p_ptt
, port
, I2C_TRANSCEIVER_ADDR
,
1252 if (rc
!= ECORE_SUCCESS
)
1253 return ecore_sfp_set_error(rc
, length
, p_phy_result_buf
,
1254 "Error reading vendor rev.\n");
1257 length
+= OSAL_SPRINTF(&p_phy_result_buf
[length
],
1258 "Vendor rev: %s\n", buf
);
1263 /* Decode SFP information */
1264 int ecore_phy_sfp_decode(struct ecore_hwfn
*p_hwfn
, struct ecore_ptt
*p_ptt
,
1265 u32 port
, char *p_phy_result_buf
)
1267 enum _ecore_status_t rc
;
1271 /* Verify <port> field is between 0 and number of ports */
1272 rc
= ecore_validate_sfp_port(p_hwfn
, p_ptt
, port
, p_phy_result_buf
);
1273 if (rc
!= ECORE_SUCCESS
)
1276 rc
= ecore_mcp_phy_sfp_read(p_hwfn
, p_ptt
, port
, I2C_TRANSCEIVER_ADDR
,
1278 if (rc
!= ECORE_SUCCESS
)
1279 return ecore_sfp_set_error(rc
, length
, p_phy_result_buf
,
1280 "Error reading transceiver identification field.\n");
1283 case 0x3: /* SFP, SFP+, SFP-28 */
1284 length
+= OSAL_SPRINTF(&p_phy_result_buf
[length
],
1285 "SFP, SFP+ or SFP-28 inserted.\n");
1286 rc
= ecore_decode_sfp_info(p_hwfn
, p_ptt
, port
,
1287 length
, p_phy_result_buf
);
1289 case 0xc: /* QSFP */
1290 length
+= OSAL_SPRINTF(&p_phy_result_buf
[length
],
1291 "QSFP inserted.\n");
1292 rc
= ecore_decode_qsfp_info(p_hwfn
, p_ptt
, port
,
1293 length
, p_phy_result_buf
);
1295 case 0xd: /* QSFP+ */
1296 length
+= OSAL_SPRINTF(&p_phy_result_buf
[length
],
1297 "QSFP+ inserted.\n");
1298 rc
= ecore_decode_qsfp_info(p_hwfn
, p_ptt
, port
,
1299 length
, p_phy_result_buf
);
1301 case 0x11: /* QSFP-28 */
1302 length
+= OSAL_SPRINTF(&p_phy_result_buf
[length
],
1303 "QSFP-28 inserted.\n");
1304 rc
= ecore_decode_qsfp_info(p_hwfn
, p_ptt
, port
,
1305 length
, p_phy_result_buf
);
1307 case 0x12: /* CXP2 (CXP-28) */
1308 OSAL_SPRINTF(p_phy_result_buf
,
1309 "CXP2 (CXP-28) inserted.\n");
1310 rc
= ECORE_UNKNOWN_ERROR
;
1313 OSAL_SPRINTF(p_phy_result_buf
,
1314 "Unknown transceiver type inserted.\n");
1315 rc
= ECORE_UNKNOWN_ERROR
;
1322 /* Get SFP inserted status */
1323 int ecore_phy_sfp_get_inserted(struct ecore_hwfn
*p_hwfn
,
1324 struct ecore_ptt
*p_ptt
,
1325 u32 port
, char *p_phy_result_buf
)
1327 u32 transceiver_state
;
1328 u32 addr
= SECTION_OFFSIZE_ADDR(p_hwfn
->mcp_info
->public_base
,
1330 u32 mfw_mb_offsize
= ecore_rd(p_hwfn
, p_ptt
, addr
);
1331 u32 port_addr
= SECTION_ADDR(mfw_mb_offsize
, port
);
1333 transceiver_state
= ecore_rd(p_hwfn
, p_ptt
,
1335 OFFSETOF(struct public_port
,
1338 transceiver_state
= GET_FIELD(transceiver_state
, ETH_TRANSCEIVER_STATE
);
1340 OSAL_SPRINTF(p_phy_result_buf
, "%d",
1341 (transceiver_state
== ETH_TRANSCEIVER_STATE_PRESENT
));
1343 return ECORE_SUCCESS
;
1346 /* Get SFP TX disable status */
1347 int ecore_phy_sfp_get_txdisable(struct ecore_hwfn
*p_hwfn
,
1348 struct ecore_ptt
*p_ptt
,
1349 u32 port
, char *p_phy_result_buf
)
1351 enum _ecore_status_t rc
;
1355 /* Verify <port> field is between 0 and number of ports */
1356 rc
= ecore_validate_sfp_port(p_hwfn
, p_ptt
, port
, p_phy_result_buf
);
1357 if (rc
!= ECORE_SUCCESS
)
1360 rc
= ecore_mcp_phy_sfp_read(p_hwfn
, p_ptt
, port
, I2C_TRANSCEIVER_ADDR
,
1362 if (rc
!= ECORE_SUCCESS
)
1363 return ecore_sfp_set_error(rc
, length
, p_phy_result_buf
,
1364 "Error reading transceiver identification field.\n");
1367 case 0x3: /* SFP, SFP+, SFP-28 */
1368 rc
= ecore_mcp_phy_sfp_read(p_hwfn
, p_ptt
, port
,
1369 I2C_TRANSCEIVER_ADDR
, 110, 1, buf
);
1370 if (rc
!= ECORE_SUCCESS
)
1371 return ecore_sfp_set_error(rc
, length
, p_phy_result_buf
,
1372 "Error reading transceiver tx disable status field.\n");
1373 OSAL_SPRINTF(p_phy_result_buf
, "%d",
1374 ((buf
[0] & 0xC0) ? 1 : 0));
1376 case 0xc: /* QSFP */
1377 case 0xd: /* QSFP+ */
1378 case 0x11: /* QSFP-28 */
1379 rc
= ecore_mcp_phy_sfp_read(p_hwfn
, p_ptt
, port
,
1380 I2C_TRANSCEIVER_ADDR
, 86, 1, buf
);
1381 if (rc
!= ECORE_SUCCESS
)
1382 return ecore_sfp_set_error(rc
, length
, p_phy_result_buf
,
1383 "Error reading transceiver tx disable status field.\n");
1384 OSAL_SPRINTF(p_phy_result_buf
, "%d",
1385 ((buf
[0] & ((1 << port
))) ? 1 : 0));
1388 OSAL_SPRINTF(p_phy_result_buf
,
1389 "Unknown transceiver type inserted.\n");
1390 rc
= ECORE_UNKNOWN_ERROR
;
1397 /* Set SFP TX disable */
1398 int ecore_phy_sfp_set_txdisable(struct ecore_hwfn
*p_hwfn
,
1399 struct ecore_ptt
*p_ptt
,
1400 u32 port
, u8 txdisable
,
1401 char *p_phy_result_buf
)
1403 enum _ecore_status_t rc
;
1407 /* Verify <txdisable> field is between 0 and 1 */
1408 if (txdisable
> 1) {
1409 OSAL_SPRINTF(p_phy_result_buf
,
1410 "Bad tx disable value, must be 0 or 1.\n");
1414 /* Verify <port> field is between 0 and number of ports */
1415 rc
= ecore_validate_sfp_port(p_hwfn
, p_ptt
, port
,
1417 if (rc
!= ECORE_SUCCESS
)
1420 rc
= ecore_mcp_phy_sfp_read(p_hwfn
, p_ptt
, port
, I2C_TRANSCEIVER_ADDR
,
1422 if (rc
!= ECORE_SUCCESS
)
1423 return ecore_sfp_set_error(rc
, length
, p_phy_result_buf
,
1424 "Error reading transceiver identification field.\n");
1427 case 0x3: /* SFP, SFP+, SFP-28 */
1428 rc
= ecore_mcp_phy_sfp_read(p_hwfn
, p_ptt
, port
,
1429 I2C_TRANSCEIVER_ADDR
,
1430 SFP_TX_DISABLE_OFFSET
, 1, buf
);
1431 if (rc
!= ECORE_SUCCESS
)
1432 return ecore_sfp_set_error(rc
, length
, p_phy_result_buf
,
1433 "Error reading transceiver tx disable status field.\n");
1435 if (((buf
[0] & 0x40) >> 6) != txdisable
) {
1437 rc
= ecore_mcp_phy_sfp_write(p_hwfn
, p_ptt
, port
,
1438 I2C_TRANSCEIVER_ADDR
,
1439 SFP_TX_DISABLE_OFFSET
,
1441 if (rc
!= ECORE_SUCCESS
)
1442 OSAL_SPRINTF(&p_phy_result_buf
[length
],
1443 "Error setting transceiver tx disable status field.\n");
1446 if (((buf
[0] & 0x80) >> 7) != txdisable
) {
1447 u32 nvm_cfg_addr
, nvm_cfg1_offset
, port_cfg_addr
;
1450 nvm_cfg_addr
= ecore_rd(p_hwfn
, p_ptt
,
1451 MISC_REG_GEN_PURP_CR0
);
1452 nvm_cfg1_offset
= ecore_rd(p_hwfn
, p_ptt
,
1454 port_cfg_addr
= MCP_REG_SCRATCH
+ nvm_cfg1_offset
+
1455 OFFSETOF(struct nvm_cfg1
, port
[port
]);
1456 gpio
= (u16
)ecore_rd(p_hwfn
, p_ptt
,
1458 OFFSETOF(struct nvm_cfg1_port
,
1460 gpio
&= NVM_CFG1_PORT_TRANS_MODULE_ABS_MASK
;
1461 rc
= ecore_phy_gpio_write(p_hwfn
, p_ptt
, gpio
,
1464 if (rc
!= ECORE_SUCCESS
)
1465 OSAL_SPRINTF(&p_phy_result_buf
[length
],
1466 "Error setting transceiver tx disable status field.\n");
1469 case 0xc: /* QSFP */
1470 case 0xd: /* QSFP+ */
1471 case 0x11: /* QSFP-28 */
1472 rc
= ecore_mcp_phy_sfp_read(p_hwfn
, p_ptt
, port
,
1473 I2C_TRANSCEIVER_ADDR
,
1474 QSFP_TX_DISABLE_OFFSET
, 1, buf
);
1475 if (rc
!= ECORE_SUCCESS
)
1476 return ecore_sfp_set_error(rc
, length
,
1478 "Error reading transceiver tx disable status field.\n");
1479 if (((buf
[0] & (1 << port
)) >> port
) != txdisable
) {
1480 buf
[0] ^= (1 << port
);
1481 rc
= ecore_mcp_phy_sfp_write(p_hwfn
, p_ptt
, port
,
1482 I2C_TRANSCEIVER_ADDR
,
1483 QSFP_TX_DISABLE_OFFSET
,
1485 if (rc
!= ECORE_SUCCESS
)
1486 OSAL_SPRINTF(&p_phy_result_buf
[length
],
1487 "Error setting transceiver tx disable status field.\n");
1491 OSAL_SPRINTF(p_phy_result_buf
,
1492 "Unknown transceiver type inserted.\n");
1493 rc
= ECORE_UNKNOWN_ERROR
;
1500 /* Get SFP TX fault status */
1501 int ecore_phy_sfp_get_txreset(struct ecore_hwfn
*p_hwfn
,
1502 struct ecore_ptt
*p_ptt
,
1503 u32 port
, char *p_phy_result_buf
)
1505 enum _ecore_status_t rc
;
1509 /* Verify <port> field is between 0 and number of ports */
1510 rc
= ecore_validate_sfp_port(p_hwfn
, p_ptt
, port
, p_phy_result_buf
);
1511 if (rc
!= ECORE_SUCCESS
)
1514 rc
= ecore_mcp_phy_sfp_read(p_hwfn
, p_ptt
, port
, I2C_TRANSCEIVER_ADDR
,
1516 if (rc
!= ECORE_SUCCESS
)
1517 return ecore_sfp_set_error(rc
, length
, p_phy_result_buf
,
1518 "Error reading transceiver identification field.\n");
1521 case 0x3: /* SFP, SFP+, SFP-28 */
1522 rc
= ecore_mcp_phy_sfp_read(p_hwfn
, p_ptt
, port
,
1523 I2C_TRANSCEIVER_ADDR
,
1524 SFP_TX_FAULT_OFFSET
, 1, buf
);
1525 if (rc
!= ECORE_SUCCESS
)
1526 return ecore_sfp_set_error(rc
, length
, p_phy_result_buf
,
1527 "Error reading transceiver tx fault status field.\n");
1528 OSAL_SPRINTF(p_phy_result_buf
, "%d",
1529 ((buf
[0] & 0x02) ? 1 : 0));
1531 case 0xc: /* QSFP */
1532 case 0xd: /* QSFP+ */
1533 case 0x11: /* QSFP-28 */
1534 rc
= ecore_mcp_phy_sfp_read(p_hwfn
, p_ptt
, port
,
1535 I2C_TRANSCEIVER_ADDR
,
1536 QSFP_TX_FAULT_OFFSET
, 1, buf
);
1537 if (rc
!= ECORE_SUCCESS
)
1538 return ecore_sfp_set_error(rc
, length
, p_phy_result_buf
,
1539 "Error reading transceiver tx fault status field.\n");
1540 OSAL_SPRINTF(p_phy_result_buf
, "%d",
1541 ((buf
[0] & (1 << port
)) ? 1 : 0));
1544 OSAL_SPRINTF(p_phy_result_buf
,
1545 "Unknown transceiver type inserted.\n");
1546 rc
= ECORE_UNKNOWN_ERROR
;
1553 /* Get SFP RX los status */
1554 int ecore_phy_sfp_get_rxlos(struct ecore_hwfn
*p_hwfn
,
1555 struct ecore_ptt
*p_ptt
,
1556 u32 port
, char *p_phy_result_buf
)
1558 enum _ecore_status_t rc
;
1562 /* Verify <port> field is between 0 and number of ports */
1563 rc
= ecore_validate_sfp_port(p_hwfn
, p_ptt
, port
, p_phy_result_buf
);
1564 if (rc
!= ECORE_SUCCESS
)
1567 rc
= ecore_mcp_phy_sfp_read(p_hwfn
, p_ptt
, port
, I2C_TRANSCEIVER_ADDR
,
1569 if (rc
!= ECORE_SUCCESS
)
1570 return ecore_sfp_set_error(rc
, length
, p_phy_result_buf
,
1571 "Error reading transceiver identification field.\n");
1574 case 0x3: /* SFP, SFP+, SFP-28 */
1575 rc
= ecore_mcp_phy_sfp_read(p_hwfn
, p_ptt
, port
,
1576 I2C_TRANSCEIVER_ADDR
,
1577 SFP_RX_LOS_OFFSET
, 1, buf
);
1578 if (rc
!= ECORE_SUCCESS
)
1579 return ecore_sfp_set_error(rc
, length
, p_phy_result_buf
,
1580 "Error reading transceiver rx los status field.\n");
1581 OSAL_SPRINTF(p_phy_result_buf
, "%d",
1582 ((buf
[0] & 0x01) ? 1 : 0));
1584 case 0xc: /* QSFP */
1585 case 0xd: /* QSFP+ */
1586 case 0x11: /* QSFP-28 */
1587 rc
= ecore_mcp_phy_sfp_read(p_hwfn
, p_ptt
, port
,
1588 I2C_TRANSCEIVER_ADDR
,
1589 QSFP_RX_LOS_OFFSET
, 1, buf
);
1590 if (rc
!= ECORE_SUCCESS
)
1591 return ecore_sfp_set_error(rc
, length
, p_phy_result_buf
,
1592 "Error reading transceiver rx los status field.\n");
1593 OSAL_SPRINTF(p_phy_result_buf
, "%d",
1594 ((buf
[0] & (1 << port
)) ? 1 : 0));
1597 OSAL_SPRINTF(p_phy_result_buf
,
1598 "Unknown transceiver type inserted.\n");
1599 rc
= ECORE_UNKNOWN_ERROR
;
1606 /* Get SFP EEPROM memory dump */
1607 int ecore_phy_sfp_get_eeprom(struct ecore_hwfn
*p_hwfn
,
1608 struct ecore_ptt
*p_ptt
,
1609 u32 port
, char *p_phy_result_buf
)
1611 enum _ecore_status_t rc
;
1614 /* Verify <port> field is between 0 and number of ports */
1615 rc
= ecore_validate_sfp_port(p_hwfn
, p_ptt
, port
, p_phy_result_buf
);
1616 if (rc
!= ECORE_SUCCESS
)
1619 rc
= ecore_mcp_phy_sfp_read(p_hwfn
, p_ptt
, port
, I2C_TRANSCEIVER_ADDR
,
1621 if (rc
!= ECORE_SUCCESS
)
1622 return ecore_sfp_set_error(rc
, 0, p_phy_result_buf
,
1623 "Error reading transceiver identification field.\n");
1626 case 0x3: /* SFP, SFP+, SFP-28 */
1627 case 0xc: /* QSFP */
1628 case 0xd: /* QSFP+ */
1629 case 0x11: /* QSFP-28 */
1630 rc
= ecore_phy_sfp_read(p_hwfn
, p_ptt
, port
,
1631 I2C_TRANSCEIVER_ADDR
, 0,
1632 MAX_I2C_TRANSCEIVER_PAGE_SIZE
,
1636 OSAL_SPRINTF(p_phy_result_buf
,
1637 "Unknown transceiver type inserted.\n");
1638 rc
= ECORE_UNKNOWN_ERROR
;
1646 int ecore_phy_gpio_write(struct ecore_hwfn
*p_hwfn
, struct ecore_ptt
*p_ptt
,
1647 u16 gpio
, u16 gpio_val
, char *p_phy_result_buf
)
1649 enum _ecore_status_t rc
;
1651 rc
= ecore_mcp_gpio_write(p_hwfn
, p_ptt
, gpio
, gpio_val
);
1653 if (rc
== ECORE_SUCCESS
)
1654 OSAL_SPRINTF(p_phy_result_buf
,
1655 "Written successfully to gpio number %d.\n",
1658 OSAL_SPRINTF(p_phy_result_buf
,
1659 "Can't write to gpio %d\n", gpio
);
1664 /* Read from gpio */
1665 int ecore_phy_gpio_read(struct ecore_hwfn
*p_hwfn
, struct ecore_ptt
*p_ptt
,
1666 u16 gpio
, char *p_phy_result_buf
)
1668 enum _ecore_status_t rc
;
1671 rc
= ecore_mcp_gpio_read(p_hwfn
, p_ptt
, gpio
, ¶m
);
1673 if (rc
== ECORE_SUCCESS
)
1674 OSAL_SPRINTF(p_phy_result_buf
, "%x", param
);
1676 OSAL_SPRINTF(p_phy_result_buf
,
1677 "Can't read from gpio %d\n", gpio
);
1682 /* Get information from gpio */
1683 int ecore_phy_gpio_info(struct ecore_hwfn
*p_hwfn
, struct ecore_ptt
*p_ptt
,
1684 u16 gpio
, char *p_phy_result_buf
)
1686 u32 direction
, ctrl
, length
= 0;
1687 enum _ecore_status_t rc
;
1689 rc
= ecore_mcp_gpio_info(p_hwfn
, p_ptt
, gpio
, &direction
, &ctrl
);
1691 if (rc
!= ECORE_SUCCESS
) {
1692 OSAL_SPRINTF(p_phy_result_buf
,
1693 "Can't get information for gpio %d\n", gpio
);
1697 length
= OSAL_SPRINTF(p_phy_result_buf
, "Gpio %d is %s - ",
1699 ((direction
== 0) ? "output" : "input"));
1702 OSAL_SPRINTF(&p_phy_result_buf
[length
],
1703 "control is uninitialized\n");
1706 OSAL_SPRINTF(&p_phy_result_buf
[length
],
1707 "control is path 0\n");
1710 OSAL_SPRINTF(&p_phy_result_buf
[length
],
1711 "control is path 1\n");
1714 OSAL_SPRINTF(&p_phy_result_buf
[length
],
1715 "control is shared\n");
1718 OSAL_SPRINTF(&p_phy_result_buf
[length
],
1719 "\nError - control is invalid\n");
1723 return ECORE_SUCCESS
;
1726 /* Get information from gpio */
1727 int ecore_phy_extphy_read(struct ecore_hwfn
*p_hwfn
, struct ecore_ptt
*p_ptt
,
1728 u16 port
, u16 devad
, u16 reg
, char *p_phy_result_buf
)
1730 enum _ecore_status_t rc
;
1734 rc
= ecore_mcp_cmd(p_hwfn
, p_ptt
, DRV_MSG_CODE_EXT_PHY_READ
,
1735 ((port
<< DRV_MB_PARAM_PORT_SHIFT
) |
1736 (devad
<< DRV_MB_PARAM_DEVAD_SHIFT
) |
1737 (reg
<< DRV_MB_PARAM_ADDR_SHIFT
)),
1741 if ((rc
!= ECORE_SUCCESS
) || (resp_cmd
!= FW_MSG_CODE_PHY_OK
)) {
1742 OSAL_SPRINTF(p_phy_result_buf
,
1743 "Failed reading external PHY\n");
1746 OSAL_SPRINTF(p_phy_result_buf
, "0x%04x\n", val
);
1747 return ECORE_SUCCESS
;
1750 /* Get information from gpio */
1751 int ecore_phy_extphy_write(struct ecore_hwfn
*p_hwfn
, struct ecore_ptt
*p_ptt
,
1752 u16 port
, u16 devad
, u16 reg
, u16 val
,
1753 char *p_phy_result_buf
)
1755 enum _ecore_status_t rc
;
1759 rc
= ecore_mcp_nvm_wr_cmd(p_hwfn
, p_ptt
, DRV_MSG_CODE_EXT_PHY_WRITE
,
1760 ((port
<< DRV_MB_PARAM_PORT_SHIFT
) |
1761 (devad
<< DRV_MB_PARAM_DEVAD_SHIFT
) |
1762 (reg
<< DRV_MB_PARAM_ADDR_SHIFT
)),
1768 if ((rc
!= ECORE_SUCCESS
) || (resp_cmd
!= FW_MSG_CODE_PHY_OK
)) {
1769 OSAL_SPRINTF(p_phy_result_buf
,
1770 "Failed writing external PHY\n");
1773 OSAL_SPRINTF(p_phy_result_buf
, "0\n");
1774 return ECORE_SUCCESS
;