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, ¶m); 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