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 2007 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 nxge_status_t 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 nxge_status_t 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 MUTEX_ENTER(&nxgep->nxge_hw_p->nxge_cfg_lock); 219 (void) npi_espc_pio_enable(handle); 220 status = npi_espc_vpd_info_get(handle, &nxgep->vpd_info, 221 NXGE_EROM_LEN); 222 (void) npi_espc_pio_disable(handle); 223 MUTEX_EXIT(&nxgep->nxge_hw_p->nxge_cfg_lock); 224 225 nxgep->vpd_info.ver_valid = B_FALSE; 226 if (status == NPI_SUCCESS) { 227 (void) nxge_check_vpd_version(nxgep); 228 return (NXGE_OK); 229 } else 230 return (NXGE_ERROR); 231 } 232 233 static nxge_status_t 234 nxge_check_vpd_version(p_nxge_t nxgep) 235 { 236 int i, j; 237 nxge_status_t status = NXGE_OK; 238 const char *fcode_str = NXGE_FCODE_ID_STR; 239 int fcode_str_len = strlen(fcode_str); 240 char ver_num_str[NXGE_FCODE_VER_STR_LEN]; 241 char *ver_num_w; 242 char *ver_num_f; 243 int ver_num_w_len = 0; 244 int ver_num_f_len = 0; 245 int ver_w = 0; 246 int ver_f = 0; 247 248 nxgep->vpd_info.ver_valid = B_FALSE; 249 ver_num_str[0] = '\0'; 250 251 for (i = 0; i < NXGE_VPD_VER_LEN; i++) { 252 if (nxgep->vpd_info.ver[i] == fcode_str[0]) { 253 if ((i + fcode_str_len + NXGE_FCODE_VER_STR_LEN) > 254 NXGE_VPD_VER_LEN) 255 break; 256 for (j = 0; j < fcode_str_len; j++, i++) { 257 if (nxgep->vpd_info.ver[i] != fcode_str[j]) 258 break; 259 } 260 if (j < fcode_str_len) 261 continue; 262 263 /* found the Fcode version string */ 264 for (j = 0; j < NXGE_FCODE_VER_STR_LEN; j++, i++) { 265 ver_num_str[j] = nxgep->vpd_info.ver[i]; 266 if (ver_num_str[j] == ' ') 267 break; 268 } 269 ver_num_str[j] = '\0'; 270 break; 271 } 272 } 273 274 ver_num_w = ver_num_str; 275 for (i = 0; i < strlen(ver_num_str); i++) { 276 if (ver_num_str[i] == '.') { 277 ver_num_f = &ver_num_str[i + 1]; 278 ver_num_w_len = i; 279 ver_num_f_len = strlen(ver_num_str) - (i + 1); 280 break; 281 } 282 } 283 284 for (i = 0; i < ver_num_w_len; i++) { 285 ver_w = (ver_w * 10) + (ver_num_w[i] - '0'); 286 } 287 288 for (i = 0; i < ver_num_f_len; i++) { 289 ver_f = (ver_f * 10) + (ver_num_f[i] - '0'); 290 } 291 292 if ((ver_w > NXGE_VPD_VALID_VER_W) || 293 (ver_w == NXGE_VPD_VALID_VER_W && ver_f >= NXGE_VPD_VALID_VER_F)) 294 nxgep->vpd_info.ver_valid = B_TRUE; 295 296 return (status); 297 } 298