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