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