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