physim.c (2864B)
1 /* 2 * 3 * This license is set out in https://raw.githubusercontent.com/Broadcom-Network-Switching-Software/OpenBCM/master/Legal/LICENSE file. 4 * 5 * Copyright 2007-2019 Broadcom Inc. All rights reserved. 6 * 7 * The part of PCID that simulates a PHY 8 * 9 * Requires: 10 * 11 * Provides: 12 * soc_internal_miim_op 13 */ 14 15 #include <shared/bsl.h> 16 17 #include <unistd.h> 18 #include <stdlib.h> 19 20 #include <sys/types.h> 21 #include <sys/time.h> 22 23 #include <soc/cmic.h> 24 #include <soc/drv.h> 25 #include <soc/debug.h> 26 #include <sal/appl/io.h> 27 #include <bde/pli/verinet.h> 28 29 #include "pcid.h" 30 #include "cmicsim.h" 31 32 #define PHY_ID_COUNT 256 33 #define PHY_ADDR_COUNT 32 34 35 static uint16 phy_resetval_5228[PHY_ADDR_COUNT] = { 36 0x3000, 0x7809, 0x0040, 0x61d4, 0x01e1, 0x0000, 0x0004, 0x2001, 37 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 38 0x1000, 0x0001, 0x0000, 0x0000, 0x0200, 0x0600, 0x0100, 0x0000, 39 0x003c, 0x0002, 0x1f00, 0x009a, 0x002c, 0x0000, 0x0000, 0x000b, 40 }; 41 42 static uint16 phy_resetval_5402[PHY_ADDR_COUNT] = { 43 0x1100, 0x7949, 0x0020, 0x6061, 0x0061, 0x0000, 0x0004, 0x2001, 44 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x3000, 45 0x0002, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 46 0x0420, 0x0000, 0x0000, 0xffff, 0x0000, 0x0000, 0x0000, 0x0000, 47 }; 48 49 static uint16 phy_regs[PHY_ID_COUNT][PHY_ADDR_COUNT]; 50 51 static void 52 phy_reset(uint8 phy_id) 53 { 54 /* This only handles (kind of) the 24+2 switches */ 55 56 sal_memcpy(&phy_regs[phy_id], 57 (phy_id < 25) ? phy_resetval_5228 : phy_resetval_5402, 58 sizeof (phy_regs[phy_id])); 59 } 60 61 /* 62 * soc_internal_miim_op 63 * 64 * Look at miim parameters and make up a response. 65 */ 66 67 void 68 soc_internal_miim_op(pcid_info_t *pcid_info, int read) 69 { 70 uint8 phy_id; 71 uint8 phy_addr; 72 uint16 phy_wr_data; 73 74 phy_addr = PCIM(pcid_info, CMIC_MIIM_PARAM) >> 24 & 0x1f; 75 phy_id = PCIM(pcid_info, CMIC_MIIM_PARAM) >> 16 & 0xff; 76 77 /* Simulate power-on reset */ 78 79 if (phy_regs[phy_id][2] == 0 && phy_regs[phy_id][3] == 0) { 80 phy_reset(phy_id); 81 } 82 83 if (read) { 84 LOG_VERBOSE(BSL_LS_SOC_COMMON, 85 (BSL_META("Responding to MIIM read: id=0x%02x addr=0x%02x data=0x%04x\n"), 86 phy_id, phy_addr, phy_regs[phy_id][phy_addr])); 87 PCIM(pcid_info, CMIC_MIIM_READ_DATA) = phy_regs[phy_id][phy_addr]; 88 } else { 89 phy_wr_data = PCIM(pcid_info, CMIC_MIIM_PARAM) & 0xffff; 90 LOG_VERBOSE(BSL_LS_SOC_COMMON, 91 (BSL_META("Responding to MIIM write: " 92 "id=0x%02x addr=0x%02x data=0x%04x\n"), 93 phy_id, phy_addr, phy_wr_data)); 94 if (phy_addr == 0 && (phy_wr_data & 0x8000) != 0) { 95 phy_reset(phy_id); 96 } else { 97 phy_regs[phy_id][phy_addr] = phy_wr_data; 98 } 99 } 100 101 PCIM(pcid_info, CMIC_SCHAN_CTRL) |= SC_MIIM_OP_DONE_TST; 102 }