1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 * or http://www.opensolaris.org/os/licensing. 10 * See the License for the specific language governing permissions 11 * and limitations under the License. 12 * 13 * When distributing Covered Code, include this CDDL HEADER in each 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 * If applicable, add the following below this CDDL HEADER, with the 16 * fields enclosed by brackets "[]" replaced with your own identifying 17 * information: Portions Copyright [yyyy] [name of copyright owner] 18 * 19 * CDDL HEADER END 20 */ 21 /* 22 * Copyright 2008 Sun Microsystems, Inc. All rights reserved. 23 * Use is subject to license terms. 24 */ 25 26 #pragma ident "%Z%%M% %I% %E% SMI" 27 28 #include <nxge_impl.h> 29 #include <nxge_mac.h> 30 #include <npi_espc.h> 31 #include <nxge_espc.h> 32 33 static void nxge_check_vpd_version(p_nxge_t nxgep); 34 35 void 36 nxge_espc_get_next_mac_addr(uint8_t *st_mac, uint8_t nxt_cnt, 37 struct ether_addr *final_mac) 38 { 39 uint64_t mac[ETHERADDRL]; 40 uint64_t mac_addr = 0; 41 int i, j; 42 43 for (i = ETHERADDRL - 1, j = 0; j < ETHERADDRL; i--, j++) { 44 mac[j] = st_mac[i]; 45 mac_addr |= (mac[j] << (j*8)); 46 } 47 48 mac_addr += nxt_cnt; 49 50 final_mac->ether_addr_octet[0] = (mac_addr & 0xff0000000000) >> 40; 51 final_mac->ether_addr_octet[1] = (mac_addr & 0xff00000000) >> 32; 52 final_mac->ether_addr_octet[2] = (mac_addr & 0xff000000) >> 24; 53 final_mac->ether_addr_octet[3] = (mac_addr & 0xff0000) >> 16; 54 final_mac->ether_addr_octet[4] = (mac_addr & 0xff00) >> 8; 55 final_mac->ether_addr_octet[5] = (mac_addr & 0xff); 56 } 57 58 nxge_status_t 59 nxge_espc_mac_addrs_get(p_nxge_t nxgep) 60 { 61 nxge_status_t status = NXGE_OK; 62 npi_status_t npi_status = NPI_SUCCESS; 63 uint8_t port_num = nxgep->mac.portnum; 64 npi_handle_t handle = NXGE_DEV_NPI_HANDLE(nxgep); 65 uint8_t mac_addr[ETHERADDRL]; 66 67 NXGE_DEBUG_MSG((nxgep, MAC_CTL, 68 "==> nxge_espc_mac_addr_get, port[%d]", 69 port_num)); 70 71 npi_status = npi_espc_mac_addr_get(handle, mac_addr); 72 if (npi_status != NPI_SUCCESS) { 73 status = (NXGE_ERROR | npi_status); 74 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 75 "nxge_espc_mac_addr_get, port[%d] failed", 76 port_num)); 77 goto exit; 78 } 79 80 nxge_espc_get_next_mac_addr(mac_addr, port_num, &nxgep->factaddr); 81 NXGE_DEBUG_MSG((nxgep, CFG_CTL, 82 "Got MAC Addr: %2x:%2x:%2x:%2x:%2x%:%2x%c \n", 83 mac_addr[0], mac_addr[1], 84 mac_addr[2], mac_addr[3], 85 mac_addr[4], mac_addr[5])); 86 87 exit: 88 NXGE_DEBUG_MSG((nxgep, CFG_CTL, "<== nxge_espc_mac_addr_get, " 89 "status [0x%x]", status)); 90 91 return (status); 92 } 93 94 nxge_status_t 95 nxge_espc_num_macs_get(p_nxge_t nxgep, uint8_t *nmacs) 96 { 97 nxge_status_t status = NXGE_OK; 98 npi_status_t npi_status = NPI_SUCCESS; 99 npi_handle_t handle = NXGE_DEV_NPI_HANDLE(nxgep); 100 NXGE_DEBUG_MSG((nxgep, CFG_CTL, "==> nxge_espc_num_macs_get")); 101 102 npi_status = npi_espc_num_macs_get(handle, nmacs); 103 if (npi_status != NPI_SUCCESS) { 104 status = (NXGE_ERROR | npi_status); 105 } 106 107 NXGE_DEBUG_MSG((nxgep, CFG_CTL, "<== nxge_espc_num_macs_get, " 108 "status [0x%x]", status)); 109 110 return (status); 111 } 112 113 nxge_status_t 114 nxge_espc_num_ports_get(p_nxge_t nxgep) 115 { 116 nxge_status_t status = NXGE_OK; 117 npi_status_t npi_status = NPI_SUCCESS; 118 npi_handle_t handle = NXGE_DEV_NPI_HANDLE(nxgep); 119 uint8_t nports = 0; 120 NXGE_DEBUG_MSG((nxgep, CFG_CTL, "==> nxge_espc_num_ports_get")); 121 122 npi_status = npi_espc_num_ports_get(handle, &nports); 123 if (npi_status != NPI_SUCCESS) { 124 status = (NXGE_ERROR | npi_status); 125 } 126 nxgep->nports = nports; 127 NXGE_DEBUG_MSG((nxgep, CFG_CTL, " nxge_espc_num_ports_get " 128 "ports [0x%x]", nports)); 129 130 NXGE_DEBUG_MSG((nxgep, CFG_CTL, "<== nxge_espc_num_ports_get, " 131 "status [0x%x]", status)); 132 133 return (status); 134 } 135 136 nxge_status_t 137 nxge_espc_phy_type_get(p_nxge_t nxgep) 138 { 139 nxge_status_t status = NXGE_OK; 140 npi_status_t npi_status = NPI_SUCCESS; 141 npi_handle_t handle = NXGE_DEV_NPI_HANDLE(nxgep); 142 uint8_t port_num = nxgep->mac.portnum; 143 uint8_t phy_type; 144 145 NXGE_DEBUG_MSG((nxgep, CFG_CTL, "==> nxge_espc_phy_type_get, port[%d]", 146 port_num)); 147 148 npi_status = npi_espc_port_phy_type_get(handle, &phy_type, 149 port_num); 150 if (npi_status != NPI_SUCCESS) { 151 status = (NXGE_ERROR | npi_status); 152 goto exit; 153 } 154 155 switch (phy_type) { 156 case ESC_PHY_10G_FIBER: 157 nxgep->mac.portmode = PORT_10G_FIBER; 158 nxgep->statsp->mac_stats.xcvr_inuse = XPCS_XCVR; 159 break; 160 case ESC_PHY_10G_COPPER: 161 nxgep->mac.portmode = PORT_10G_COPPER; 162 nxgep->statsp->mac_stats.xcvr_inuse = XPCS_XCVR; 163 break; 164 case ESC_PHY_1G_FIBER: 165 nxgep->mac.portmode = PORT_1G_FIBER; 166 nxgep->statsp->mac_stats.xcvr_inuse = PCS_XCVR; 167 break; 168 case ESC_PHY_1G_COPPER: 169 nxgep->mac.portmode = PORT_1G_COPPER; 170 nxgep->statsp->mac_stats.xcvr_inuse = INT_MII_XCVR; 171 break; 172 case ESC_PHY_NONE: 173 status = NXGE_ERROR; 174 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, "nxge_espc_phy_type_get:" 175 "No phy type set")); 176 break; 177 default: 178 status = NXGE_ERROR; 179 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, "nxge_espc_phy_type_get: " 180 "Unknown phy type [%d]", phy_type)); 181 break; 182 } 183 184 exit: 185 186 NXGE_DEBUG_MSG((nxgep, CFG_CTL, "<== nxge_espc_phy_type_get, " 187 "status [0x%x]", status)); 188 189 return (status); 190 } 191 192 nxge_status_t 193 nxge_espc_max_frame_sz_get(p_nxge_t nxgep) 194 { 195 nxge_status_t status = NXGE_OK; 196 npi_status_t npi_status = NPI_SUCCESS; 197 npi_handle_t handle = NXGE_DEV_NPI_HANDLE(nxgep); 198 199 NXGE_DEBUG_MSG((nxgep, CFG_CTL, "==> nxge_espc_max_frame_sz_get")); 200 201 npi_status = npi_espc_max_frame_get(handle, &nxgep->mac.maxframesize); 202 if (npi_status != NPI_SUCCESS) { 203 status = (NXGE_ERROR | npi_status); 204 } 205 206 NXGE_DEBUG_MSG((nxgep, CFG_CTL, " nxge_espc_max_frame_sz_get, " 207 "status [0x%x]", status)); 208 209 return (status); 210 } 211 212 void 213 nxge_vpd_info_get(p_nxge_t nxgep) 214 { 215 npi_status_t status; 216 npi_handle_t handle = NXGE_DEV_NPI_HANDLE(nxgep); 217 218 if ((nxgep->platform_type == P_NEPTUNE_NIU) || 219 (nxgep->platform_type == P_NEPTUNE_MARAMBA_P0) || 220 (nxgep->platform_type == P_NEPTUNE_MARAMBA_P1)) { 221 nxgep->vpd_info.present = B_FALSE; 222 return; 223 } 224 225 nxgep->vpd_info.present = B_TRUE; 226 nxgep->vpd_info.ver_valid = B_FALSE; 227 228 MUTEX_ENTER(&nxgep->nxge_hw_p->nxge_cfg_lock); 229 (void) npi_espc_pio_enable(handle); 230 status = npi_espc_vpd_info_get(handle, &nxgep->vpd_info, 231 NXGE_EROM_LEN); 232 (void) npi_espc_pio_disable(handle); 233 MUTEX_EXIT(&nxgep->nxge_hw_p->nxge_cfg_lock); 234 235 if (status != NPI_SUCCESS) 236 return; 237 238 nxge_check_vpd_version(nxgep); 239 if (!nxgep->vpd_info.ver_valid) 240 return; 241 242 /* Determine the platform type */ 243 if ((strncmp(nxgep->vpd_info.bd_model, NXGE_QGC_LP_BM_STR, 244 strlen(NXGE_QGC_LP_BM_STR)) == 0) || 245 (strncmp(nxgep->vpd_info.bd_model, NXGE_QGC_PEM_BM_STR, 246 strlen(NXGE_QGC_PEM_BM_STR)) == 0)) { 247 nxgep->platform_type = P_NEPTUNE_ATLAS_4PORT; 248 } else if ((strncmp(nxgep->vpd_info.bd_model, 249 NXGE_2XGF_LP_BM_STR, strlen(NXGE_2XGF_LP_BM_STR)) == 0) || 250 (strncmp(nxgep->vpd_info.bd_model, NXGE_2XGF_PEM_BM_STR, 251 strlen(NXGE_2XGF_PEM_BM_STR)) == 0)) { 252 nxgep->platform_type = P_NEPTUNE_ATLAS_2PORT; 253 } else if (strncmp(nxgep->vpd_info.bd_model, 254 NXGE_ALONSO_BM_STR, strlen(NXGE_ALONSO_BM_STR)) == 0) { 255 nxgep->platform_type = P_NEPTUNE_ALONSO; 256 } else if (strncmp(nxgep->vpd_info.bd_model, 257 NXGE_RFEM_BM_STR, strlen(NXGE_RFEM_BM_STR)) == 0) { 258 nxgep->hot_swappable_phy = B_TRUE; 259 } 260 261 /* If Alonso platform, replace "mif" for the last 2 ports phy-type */ 262 if ((nxgep->platform_type == P_NEPTUNE_ALONSO) && 263 ((nxgep->function_num == 2) || (nxgep->function_num == 3))) { 264 (void) strcpy(nxgep->vpd_info.phy_type, "mif"); 265 } 266 } 267 268 static void 269 nxge_check_vpd_version(p_nxge_t nxgep) 270 { 271 int i, j; 272 const char *fcode_str = NXGE_FCODE_ID_STR; 273 int fcode_str_len = strlen(fcode_str); 274 char ver_num_str[NXGE_FCODE_VER_STR_LEN]; 275 char *ver_num_w; 276 char *ver_num_f; 277 int ver_num_w_len = 0; 278 int ver_num_f_len = 0; 279 int ver_w = 0; 280 int ver_f = 0; 281 282 nxgep->vpd_info.ver_valid = B_FALSE; 283 ver_num_str[0] = '\0'; 284 285 for (i = 0; i < NXGE_VPD_VER_LEN; i++) { 286 if (nxgep->vpd_info.ver[i] == fcode_str[0]) { 287 if ((i + fcode_str_len + NXGE_FCODE_VER_STR_LEN) > 288 NXGE_VPD_VER_LEN) 289 break; 290 for (j = 0; j < fcode_str_len; j++, i++) { 291 if (nxgep->vpd_info.ver[i] != fcode_str[j]) 292 break; 293 } 294 if (j < fcode_str_len) 295 continue; 296 297 /* found the Fcode version string */ 298 for (j = 0; j < NXGE_FCODE_VER_STR_LEN; j++, i++) { 299 ver_num_str[j] = nxgep->vpd_info.ver[i]; 300 if (ver_num_str[j] == ' ') 301 break; 302 } 303 ver_num_str[j] = '\0'; 304 break; 305 } 306 } 307 308 ver_num_w = ver_num_str; 309 for (i = 0; i < strlen(ver_num_str); i++) { 310 if (ver_num_str[i] == '.') { 311 ver_num_f = &ver_num_str[i + 1]; 312 ver_num_w_len = i; 313 ver_num_f_len = strlen(ver_num_str) - (i + 1); 314 break; 315 } 316 } 317 318 for (i = 0; i < ver_num_w_len; i++) { 319 ver_w = (ver_w * 10) + (ver_num_w[i] - '0'); 320 } 321 322 for (i = 0; i < ver_num_f_len; i++) { 323 ver_f = (ver_f * 10) + (ver_num_f[i] - '0'); 324 } 325 326 if ((ver_w > NXGE_VPD_VALID_VER_W) || 327 (ver_w == NXGE_VPD_VALID_VER_W && ver_f >= NXGE_VPD_VALID_VER_F)) 328 nxgep->vpd_info.ver_valid = B_TRUE; 329 330 } 331