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 (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved. 23 */ 24 25 #include <sys/nxge/nxge_impl.h> 26 #include <sys/nxge/nxge_mac.h> 27 #include <sys/nxge/nxge_hio.h> 28 29 /* 30 * Local defines for FWARC 2006/556 31 */ 32 #define NXGE_NIU_TDMA_PROP_LEN 2 33 #define NXGE_NIU_RDMA_PROP_LEN 2 34 #define NXGE_NIU_0_INTR_PROP_LEN 19 35 #define NXGE_NIU_1_INTR_PROP_LEN 17 36 37 /* 38 * Local functions. 39 */ 40 static void nxge_get_niu_property(dev_info_t *, niu_type_t *); 41 static nxge_status_t nxge_get_mac_addr_properties(p_nxge_t); 42 static nxge_status_t nxge_use_cfg_n2niu_properties(p_nxge_t); 43 static void nxge_use_cfg_neptune_properties(p_nxge_t); 44 static void nxge_use_cfg_dma_config(p_nxge_t); 45 static void nxge_use_cfg_vlan_class_config(p_nxge_t); 46 static void nxge_use_cfg_mac_class_config(p_nxge_t); 47 static void nxge_use_cfg_class_config(p_nxge_t); 48 static void nxge_use_cfg_link_cfg(p_nxge_t); 49 static void nxge_set_hw_dma_config(p_nxge_t); 50 static void nxge_set_hw_vlan_class_config(p_nxge_t); 51 static void nxge_set_hw_mac_class_config(p_nxge_t); 52 static void nxge_set_hw_class_config(p_nxge_t); 53 static nxge_status_t nxge_use_default_dma_config_n2(p_nxge_t); 54 static void nxge_ldgv_setup(p_nxge_ldg_t *, p_nxge_ldv_t *, uint8_t, 55 uint8_t, int *); 56 static void nxge_init_mmac(p_nxge_t, boolean_t); 57 static void nxge_set_rdc_intr_property(p_nxge_t); 58 59 uint32_t nxge_use_hw_property = 1; 60 uint32_t nxge_groups_per_port = 2; 61 62 extern uint32_t nxge_use_partition; 63 extern uint32_t nxge_dma_obp_props_only; 64 65 extern uint_t nxge_rx_intr(void *, void *); 66 extern uint_t nxge_tx_intr(void *, void *); 67 extern uint_t nxge_mif_intr(void *, void *); 68 extern uint_t nxge_mac_intr(void *, void *); 69 extern uint_t nxge_syserr_intr(void *, void *); 70 extern void *nxge_list; 71 72 #define NXGE_SHARED_REG_SW_SIM 73 74 #ifdef NXGE_SHARED_REG_SW_SIM 75 uint64_t global_dev_ctrl = 0; 76 #endif 77 78 #define MAX_SIBLINGS NXGE_MAX_PORTS 79 80 extern uint32_t nxge_rbr_size; 81 extern uint32_t nxge_rcr_size; 82 extern uint32_t nxge_tx_ring_size; 83 extern uint32_t nxge_rbr_spare_size; 84 85 extern npi_status_t npi_mac_altaddr_disable(npi_handle_t, uint8_t, uint8_t); 86 87 static uint8_t p2_tx_fair[2] = {12, 12}; 88 static uint8_t p2_tx_equal[2] = {12, 12}; 89 static uint8_t p4_tx_fair[4] = {6, 6, 6, 6}; 90 static uint8_t p4_tx_equal[4] = {6, 6, 6, 6}; 91 static uint8_t p2_rx_fair[2] = {8, 8}; 92 static uint8_t p2_rx_equal[2] = {8, 8}; 93 static uint8_t p4_rx_fair[4] = {4, 4, 4, 4}; 94 static uint8_t p4_rx_equal[4] = {4, 4, 4, 4}; 95 96 static uint8_t p2_rdcgrp_fair[2] = {4, 4}; 97 static uint8_t p2_rdcgrp_equal[2] = {4, 4}; 98 static uint8_t p4_rdcgrp_fair[4] = {2, 2, 1, 1}; 99 static uint8_t p4_rdcgrp_equal[4] = {2, 2, 2, 2}; 100 static uint8_t p2_rdcgrp_cls[2] = {1, 1}; 101 static uint8_t p4_rdcgrp_cls[4] = {1, 1, 1, 1}; 102 103 static uint8_t rx_4_1G[4] = {4, 4, 4, 4}; 104 static uint8_t rx_2_10G[2] = {8, 8}; 105 static uint8_t rx_2_10G_2_1G[4] = {6, 6, 2, 2}; 106 static uint8_t rx_1_10G_3_1G[4] = {10, 2, 2, 2}; 107 static uint8_t rx_1_1G_1_10G_2_1G[4] = {2, 10, 2, 2}; 108 109 static uint8_t tx_4_1G[4] = {6, 6, 6, 6}; 110 static uint8_t tx_2_10G[2] = {12, 12}; 111 static uint8_t tx_2_10G_2_1G[4] = {10, 10, 2, 2}; 112 static uint8_t tx_1_10G_3_1G[4] = {12, 4, 4, 4}; 113 static uint8_t tx_1_1G_1_10G_2_1G[4] = {4, 12, 4, 4}; 114 115 typedef enum { 116 DEFAULT = 0, 117 EQUAL, 118 FAIR, 119 CUSTOM, 120 CLASSIFY, 121 L2_CLASSIFY, 122 L3_DISTRIBUTE, 123 L3_CLASSIFY, 124 L3_TCAM, 125 CONFIG_TOKEN_NONE 126 } config_token_t; 127 128 static char *token_names[] = { 129 "default", 130 "equal", 131 "fair", 132 "custom", 133 "classify", 134 "l2_classify", 135 "l3_distribute", 136 "l3_classify", 137 "l3_tcam", 138 "none", 139 }; 140 141 void nxge_virint_regs_dump(p_nxge_t nxgep); 142 143 void 144 nxge_virint_regs_dump(p_nxge_t nxgep) 145 { 146 npi_handle_t handle; 147 148 NXGE_DEBUG_MSG((nxgep, INT_CTL, "==> nxge_virint_regs_dump")); 149 handle = NXGE_DEV_NPI_HANDLE(nxgep); 150 (void) npi_vir_dump_pio_fzc_regs_one(handle); 151 (void) npi_vir_dump_ldgnum(handle); 152 (void) npi_vir_dump_ldsv(handle); 153 (void) npi_vir_dump_imask0(handle); 154 (void) npi_vir_dump_sid(handle); 155 (void) npi_mac_dump_regs(handle, nxgep->function_num); 156 (void) npi_ipp_dump_regs(handle, nxgep->function_num); 157 (void) npi_fflp_dump_regs(handle); 158 NXGE_DEBUG_MSG((nxgep, INT_CTL, "<== nxge_virint_regs_dump")); 159 } 160 161 /* 162 * For now: we hard coded the DMA configurations. 163 * and assume for one partition only. 164 * 165 * OBP. Then OBP will pass this partition's 166 * Neptune configurations to fcode to create 167 * properties for them. 168 * 169 * Since Neptune(PCI-E) and NIU (Niagara-2) has 170 * different bus interfaces, the driver needs 171 * to know which bus it is connected to. 172 * Ravinder suggested: create a device property. 173 * In partitioning environment, we cannot 174 * use .conf file (need to check). If conf changes, 175 * need to reboot the system. 176 * The following function assumes that we will 177 * retrieve its properties from a virtualized nexus driver. 178 */ 179 180 nxge_status_t 181 nxge_cntlops(dev_info_t *dip, nxge_ctl_enum_t ctlop, void *arg, void *result) 182 { 183 nxge_status_t status = NXGE_OK; 184 int instance; 185 p_nxge_t nxgep; 186 187 #ifndef NXGE_SHARED_REG_SW_SIM 188 npi_handle_t handle; 189 uint16_t sr16, cr16; 190 #endif 191 instance = ddi_get_instance(dip); 192 NXGE_DEBUG_MSG((NULL, VIR_CTL, "Instance %d ", instance)); 193 194 if (nxge_list == NULL) { 195 NXGE_ERROR_MSG((NULL, NXGE_ERR_CTL, 196 "nxge_cntlops: nxge_list null")); 197 return (NXGE_ERROR); 198 } 199 nxgep = (p_nxge_t)ddi_get_soft_state(nxge_list, instance); 200 if (nxgep == NULL) { 201 NXGE_ERROR_MSG((NULL, NXGE_ERR_CTL, 202 "nxge_cntlops: nxgep null")); 203 return (NXGE_ERROR); 204 } 205 #ifndef NXGE_SHARED_REG_SW_SIM 206 handle = nxgep->npi_reg_handle; 207 #endif 208 switch (ctlop) { 209 case NXGE_CTLOPS_NIUTYPE: 210 nxge_get_niu_property(dip, (niu_type_t *)result); 211 return (status); 212 213 case NXGE_CTLOPS_GET_SHARED_REG: 214 #ifdef NXGE_SHARED_REG_SW_SIM 215 *(uint64_t *)result = global_dev_ctrl; 216 return (0); 217 #else 218 status = npi_dev_func_sr_sr_get(handle, &sr16); 219 *(uint16_t *)result = sr16; 220 NXGE_DEBUG_MSG((NULL, VIR_CTL, 221 "nxge_cntlops: NXGE_CTLOPS_GET_SHARED_REG")); 222 return (0); 223 #endif 224 225 case NXGE_CTLOPS_SET_SHARED_REG_LOCK: 226 #ifdef NXGE_SHARED_REG_SW_SIM 227 global_dev_ctrl = *(uint64_t *)arg; 228 return (0); 229 #else 230 status = NPI_FAILURE; 231 while (status != NPI_SUCCESS) 232 status = npi_dev_func_sr_lock_enter(handle); 233 234 sr16 = *(uint16_t *)arg; 235 status = npi_dev_func_sr_sr_set_only(handle, &sr16); 236 status = npi_dev_func_sr_lock_free(handle); 237 NXGE_DEBUG_MSG((NULL, VIR_CTL, 238 "nxge_cntlops: NXGE_CTLOPS_SET_SHARED_REG")); 239 return (0); 240 #endif 241 242 case NXGE_CTLOPS_UPDATE_SHARED_REG: 243 #ifdef NXGE_SHARED_REG_SW_SIM 244 global_dev_ctrl |= *(uint64_t *)arg; 245 return (0); 246 #else 247 status = NPI_FAILURE; 248 while (status != NPI_SUCCESS) 249 status = npi_dev_func_sr_lock_enter(handle); 250 status = npi_dev_func_sr_sr_get(handle, &sr16); 251 sr16 |= *(uint16_t *)arg; 252 status = npi_dev_func_sr_sr_set_only(handle, &sr16); 253 status = npi_dev_func_sr_lock_free(handle); 254 NXGE_DEBUG_MSG((NULL, VIR_CTL, 255 "nxge_cntlops: NXGE_CTLOPS_SET_SHARED_REG")); 256 return (0); 257 #endif 258 259 case NXGE_CTLOPS_CLEAR_BIT_SHARED_REG_UL: 260 #ifdef NXGE_SHARED_REG_SW_SIM 261 global_dev_ctrl |= *(uint64_t *)arg; 262 return (0); 263 #else 264 status = npi_dev_func_sr_sr_get(handle, &sr16); 265 cr16 = *(uint16_t *)arg; 266 sr16 &= ~cr16; 267 status = npi_dev_func_sr_sr_set_only(handle, &sr16); 268 NXGE_DEBUG_MSG((NULL, VIR_CTL, 269 "nxge_cntlops: NXGE_CTLOPS_SET_SHARED_REG")); 270 return (0); 271 #endif 272 273 case NXGE_CTLOPS_CLEAR_BIT_SHARED_REG: 274 #ifdef NXGE_SHARED_REG_SW_SIM 275 global_dev_ctrl |= *(uint64_t *)arg; 276 return (0); 277 #else 278 status = NPI_FAILURE; 279 while (status != NPI_SUCCESS) 280 status = npi_dev_func_sr_lock_enter(handle); 281 status = npi_dev_func_sr_sr_get(handle, &sr16); 282 cr16 = *(uint16_t *)arg; 283 sr16 &= ~cr16; 284 status = npi_dev_func_sr_sr_set_only(handle, &sr16); 285 status = npi_dev_func_sr_lock_free(handle); 286 NXGE_DEBUG_MSG((NULL, VIR_CTL, 287 "nxge_cntlops: NXGE_CTLOPS_SET_SHARED_REG")); 288 return (0); 289 #endif 290 291 case NXGE_CTLOPS_GET_LOCK_BLOCK: 292 #ifdef NXGE_SHARED_REG_SW_SIM 293 global_dev_ctrl |= *(uint64_t *)arg; 294 return (0); 295 #else 296 status = NPI_FAILURE; 297 while (status != NPI_SUCCESS) 298 status = npi_dev_func_sr_lock_enter(handle); 299 NXGE_DEBUG_MSG((NULL, VIR_CTL, 300 "nxge_cntlops: NXGE_CTLOPS_GET_LOCK_BLOCK")); 301 return (0); 302 #endif 303 case NXGE_CTLOPS_GET_LOCK_TRY: 304 #ifdef NXGE_SHARED_REG_SW_SIM 305 global_dev_ctrl |= *(uint64_t *)arg; 306 return (0); 307 #else 308 status = npi_dev_func_sr_lock_enter(handle); 309 NXGE_DEBUG_MSG((NULL, VIR_CTL, 310 "nxge_cntlops: NXGE_CTLOPS_GET_LOCK_TRY")); 311 if (status == NPI_SUCCESS) 312 return (NXGE_OK); 313 else 314 return (NXGE_ERROR); 315 #endif 316 case NXGE_CTLOPS_FREE_LOCK: 317 #ifdef NXGE_SHARED_REG_SW_SIM 318 global_dev_ctrl |= *(uint64_t *)arg; 319 return (0); 320 #else 321 status = npi_dev_func_sr_lock_free(handle); 322 NXGE_DEBUG_MSG((NULL, VIR_CTL, 323 "nxge_cntlops: NXGE_CTLOPS_GET_LOCK_FREE")); 324 if (status == NPI_SUCCESS) 325 return (NXGE_OK); 326 else 327 return (NXGE_ERROR); 328 #endif 329 330 default: 331 status = NXGE_ERROR; 332 } 333 334 return (status); 335 } 336 337 void 338 nxge_common_lock_get(p_nxge_t nxgep) 339 { 340 uint32_t status = NPI_FAILURE; 341 npi_handle_t handle; 342 343 #if defined(NXGE_SHARE_REG_SW_SIM) 344 return; 345 #endif 346 handle = nxgep->npi_reg_handle; 347 while (status != NPI_SUCCESS) 348 status = npi_dev_func_sr_lock_enter(handle); 349 } 350 351 void 352 nxge_common_lock_free(p_nxge_t nxgep) 353 { 354 npi_handle_t handle; 355 356 #if defined(NXGE_SHARE_REG_SW_SIM) 357 return; 358 #endif 359 handle = nxgep->npi_reg_handle; 360 (void) npi_dev_func_sr_lock_free(handle); 361 } 362 363 364 static void 365 nxge_get_niu_property(dev_info_t *dip, niu_type_t *niu_type) 366 { 367 uchar_t *prop_val; 368 uint_t prop_len; 369 370 *niu_type = NIU_TYPE_NONE; 371 if (ddi_prop_lookup_byte_array(DDI_DEV_T_ANY, dip, 0, 372 "niu-type", (uchar_t **)&prop_val, 373 &prop_len) == DDI_PROP_SUCCESS) { 374 if (strncmp("niu", (caddr_t)prop_val, (size_t)prop_len) == 0) { 375 *niu_type = N2_NIU; 376 } 377 ddi_prop_free(prop_val); 378 } 379 } 380 381 static config_token_t 382 nxge_get_config_token(char *prop) 383 { 384 config_token_t token = DEFAULT; 385 386 while (token < CONFIG_TOKEN_NONE) { 387 if (strncmp(prop, token_names[token], 4) == 0) 388 break; 389 token++; 390 } 391 return (token); 392 } 393 394 /* per port */ 395 396 static nxge_status_t 397 nxge_update_rxdma_grp_properties(p_nxge_t nxgep, config_token_t token, 398 dev_info_t *s_dip[]) 399 { 400 nxge_status_t status = NXGE_OK; 401 int ddi_status; 402 int num_ports = nxgep->nports; 403 int port, bits, j; 404 uint8_t start_grp = 0, num_grps = 0; 405 p_nxge_param_t param_arr; 406 uint32_t grp_bitmap[MAX_SIBLINGS]; 407 int custom_start_grp[MAX_SIBLINGS]; 408 int custom_num_grp[MAX_SIBLINGS]; 409 uint8_t bad_config = B_FALSE; 410 char *start_prop, *num_prop, *cfg_prop; 411 412 start_grp = 0; 413 param_arr = nxgep->param_arr; 414 start_prop = param_arr[param_rdc_grps_start].fcode_name; 415 num_prop = param_arr[param_rx_rdc_grps].fcode_name; 416 417 switch (token) { 418 case FAIR: 419 cfg_prop = "fair"; 420 for (port = 0; port < num_ports; port++) { 421 custom_num_grp[port] = 422 (num_ports == 4) ? 423 p4_rdcgrp_fair[port] : 424 p2_rdcgrp_fair[port]; 425 custom_start_grp[port] = start_grp; 426 start_grp += custom_num_grp[port]; 427 } 428 break; 429 430 case EQUAL: 431 cfg_prop = "equal"; 432 for (port = 0; port < num_ports; port++) { 433 custom_num_grp[port] = 434 (num_ports == 4) ? 435 p4_rdcgrp_equal[port] : 436 p2_rdcgrp_equal[port]; 437 custom_start_grp[port] = start_grp; 438 start_grp += custom_num_grp[port]; 439 } 440 break; 441 442 443 case CLASSIFY: 444 cfg_prop = "classify"; 445 for (port = 0; port < num_ports; port++) { 446 custom_num_grp[port] = (num_ports == 4) ? 447 p4_rdcgrp_cls[port] : p2_rdcgrp_cls[port]; 448 custom_start_grp[port] = start_grp; 449 start_grp += custom_num_grp[port]; 450 } 451 break; 452 453 case CUSTOM: 454 cfg_prop = "custom"; 455 /* See if it is good config */ 456 num_grps = 0; 457 for (port = 0; port < num_ports; port++) { 458 custom_start_grp[port] = 459 ddi_prop_get_int(DDI_DEV_T_NONE, s_dip[port], 460 DDI_PROP_DONTPASS, start_prop, -1); 461 if ((custom_start_grp[port] == -1) || 462 (custom_start_grp[port] >= 463 NXGE_MAX_RDC_GRPS)) { 464 bad_config = B_TRUE; 465 break; 466 } 467 custom_num_grp[port] = ddi_prop_get_int( 468 DDI_DEV_T_NONE, 469 s_dip[port], 470 DDI_PROP_DONTPASS, 471 num_prop, -1); 472 473 if ((custom_num_grp[port] == -1) || 474 (custom_num_grp[port] > 475 NXGE_MAX_RDC_GRPS) || 476 ((custom_num_grp[port] + 477 custom_start_grp[port]) >= 478 NXGE_MAX_RDC_GRPS)) { 479 bad_config = B_TRUE; 480 break; 481 } 482 num_grps += custom_num_grp[port]; 483 if (num_grps > NXGE_MAX_RDC_GRPS) { 484 bad_config = B_TRUE; 485 break; 486 } 487 grp_bitmap[port] = 0; 488 for (bits = 0; 489 bits < custom_num_grp[port]; 490 bits++) { 491 grp_bitmap[port] |= 492 (1 << (bits + custom_start_grp[port])); 493 } 494 495 } 496 497 if (bad_config == B_FALSE) { 498 /* check for overlap */ 499 for (port = 0; port < num_ports - 1; port++) { 500 for (j = port + 1; j < num_ports; j++) { 501 if (grp_bitmap[port] & 502 grp_bitmap[j]) { 503 bad_config = B_TRUE; 504 break; 505 } 506 } 507 if (bad_config == B_TRUE) 508 break; 509 } 510 } 511 if (bad_config == B_TRUE) { 512 /* use default config */ 513 for (port = 0; port < num_ports; port++) { 514 custom_num_grp[port] = 515 (num_ports == 4) ? 516 p4_rx_fair[port] : p2_rx_fair[port]; 517 custom_start_grp[port] = start_grp; 518 start_grp += custom_num_grp[port]; 519 } 520 } 521 break; 522 523 default: 524 /* use default config */ 525 cfg_prop = "fair"; 526 for (port = 0; port < num_ports; port++) { 527 custom_num_grp[port] = (num_ports == 4) ? 528 p4_rx_fair[port] : p2_rx_fair[port]; 529 custom_start_grp[port] = start_grp; 530 start_grp += custom_num_grp[port]; 531 } 532 break; 533 } 534 535 /* Now Update the rx properties */ 536 for (port = 0; port < num_ports; port++) { 537 ddi_status = ddi_prop_update_string(DDI_DEV_T_NONE, s_dip[port], 538 "rxdma-grp-cfg", cfg_prop); 539 if (ddi_status != DDI_PROP_SUCCESS) { 540 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 541 " property %s not updating", 542 cfg_prop)); 543 status |= NXGE_DDI_FAILED; 544 } 545 ddi_status = ddi_prop_update_int(DDI_DEV_T_NONE, s_dip[port], 546 num_prop, custom_num_grp[port]); 547 548 if (ddi_status != DDI_PROP_SUCCESS) { 549 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 550 " property %s not updating", 551 num_prop)); 552 status |= NXGE_DDI_FAILED; 553 } 554 ddi_status = ddi_prop_update_int(DDI_DEV_T_NONE, s_dip[port], 555 start_prop, custom_start_grp[port]); 556 557 if (ddi_status != DDI_PROP_SUCCESS) { 558 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 559 " property %s not updating", 560 start_prop)); 561 status |= NXGE_DDI_FAILED; 562 } 563 } 564 if (status & NXGE_DDI_FAILED) 565 status |= NXGE_ERROR; 566 567 return (status); 568 } 569 570 static nxge_status_t 571 nxge_update_rxdma_properties(p_nxge_t nxgep, config_token_t token, 572 dev_info_t *s_dip[]) 573 { 574 nxge_status_t status = NXGE_OK; 575 int ddi_status; 576 int num_ports = nxgep->nports; 577 int port, bits, j; 578 uint8_t start_rdc = 0, num_rdc = 0; 579 p_nxge_param_t param_arr; 580 uint32_t rdc_bitmap[MAX_SIBLINGS]; 581 int custom_start_rdc[MAX_SIBLINGS]; 582 int custom_num_rdc[MAX_SIBLINGS]; 583 uint8_t bad_config = B_FALSE; 584 int *prop_val; 585 uint_t prop_len; 586 char *start_rdc_prop, *num_rdc_prop, *cfg_prop; 587 588 start_rdc = 0; 589 param_arr = nxgep->param_arr; 590 start_rdc_prop = param_arr[param_rxdma_channels_begin].fcode_name; 591 num_rdc_prop = param_arr[param_rxdma_channels].fcode_name; 592 593 switch (token) { 594 case FAIR: 595 cfg_prop = "fair"; 596 for (port = 0; port < num_ports; port++) { 597 custom_num_rdc[port] = (num_ports == 4) ? 598 p4_rx_fair[port] : p2_rx_fair[port]; 599 custom_start_rdc[port] = start_rdc; 600 start_rdc += custom_num_rdc[port]; 601 } 602 break; 603 604 case EQUAL: 605 cfg_prop = "equal"; 606 for (port = 0; port < num_ports; port++) { 607 custom_num_rdc[port] = (num_ports == 4) ? 608 p4_rx_equal[port] : 609 p2_rx_equal[port]; 610 custom_start_rdc[port] = start_rdc; 611 start_rdc += custom_num_rdc[port]; 612 } 613 break; 614 615 case CUSTOM: 616 cfg_prop = "custom"; 617 /* See if it is good config */ 618 num_rdc = 0; 619 for (port = 0; port < num_ports; port++) { 620 ddi_status = ddi_prop_lookup_int_array( 621 DDI_DEV_T_ANY, 622 s_dip[port], 0, 623 start_rdc_prop, 624 &prop_val, 625 &prop_len); 626 if (ddi_status == DDI_SUCCESS) 627 custom_start_rdc[port] = *prop_val; 628 else { 629 NXGE_DEBUG_MSG((nxgep, CFG_CTL, 630 " %s custom start port %d" 631 " read failed ", 632 " rxdma-cfg", port)); 633 bad_config = B_TRUE; 634 status |= NXGE_DDI_FAILED; 635 } 636 if ((custom_start_rdc[port] == -1) || 637 (custom_start_rdc[port] >= 638 NXGE_MAX_RDCS)) { 639 NXGE_DEBUG_MSG((nxgep, CFG_CTL, 640 " %s custom start %d" 641 " out of range %x ", 642 " rxdma-cfg", 643 port, 644 custom_start_rdc[port])); 645 bad_config = B_TRUE; 646 break; 647 } 648 ddi_status = ddi_prop_lookup_int_array( 649 DDI_DEV_T_ANY, 650 s_dip[port], 651 0, 652 num_rdc_prop, 653 &prop_val, 654 &prop_len); 655 656 if (ddi_status == DDI_SUCCESS) 657 custom_num_rdc[port] = *prop_val; 658 else { 659 NXGE_DEBUG_MSG((nxgep, CFG_CTL, 660 " %s custom num port %d" 661 " read failed ", 662 "rxdma-cfg", port)); 663 bad_config = B_TRUE; 664 status |= NXGE_DDI_FAILED; 665 } 666 667 if ((custom_num_rdc[port] == -1) || 668 (custom_num_rdc[port] > 669 NXGE_MAX_RDCS) || 670 ((custom_num_rdc[port] + 671 custom_start_rdc[port]) > 672 NXGE_MAX_RDCS)) { 673 NXGE_DEBUG_MSG((nxgep, CFG_CTL, 674 " %s custom num %d" 675 " out of range %x ", 676 " rxdma-cfg", 677 port, custom_num_rdc[port])); 678 bad_config = B_TRUE; 679 break; 680 } 681 num_rdc += custom_num_rdc[port]; 682 if (num_rdc > NXGE_MAX_RDCS) { 683 bad_config = B_TRUE; 684 break; 685 } 686 rdc_bitmap[port] = 0; 687 for (bits = 0; 688 bits < custom_num_rdc[port]; bits++) { 689 rdc_bitmap[port] |= 690 (1 << (bits + custom_start_rdc[port])); 691 } 692 } 693 694 if (bad_config == B_FALSE) { 695 /* check for overlap */ 696 for (port = 0; port < num_ports - 1; port++) { 697 for (j = port + 1; j < num_ports; j++) { 698 if (rdc_bitmap[port] & 699 rdc_bitmap[j]) { 700 NXGE_DEBUG_MSG((nxgep, 701 CFG_CTL, 702 " rxdma-cfg" 703 " property custom" 704 " bit overlap" 705 " %d %d ", 706 port, j)); 707 bad_config = B_TRUE; 708 break; 709 } 710 } 711 if (bad_config == B_TRUE) 712 break; 713 } 714 } 715 if (bad_config == B_TRUE) { 716 /* use default config */ 717 NXGE_DEBUG_MSG((nxgep, CFG_CTL, 718 " rxdma-cfg property:" 719 " bad custom config:" 720 " use default")); 721 for (port = 0; port < num_ports; port++) { 722 custom_num_rdc[port] = 723 (num_ports == 4) ? 724 p4_rx_fair[port] : 725 p2_rx_fair[port]; 726 custom_start_rdc[port] = start_rdc; 727 start_rdc += custom_num_rdc[port]; 728 } 729 } 730 break; 731 732 default: 733 /* use default config */ 734 cfg_prop = "fair"; 735 for (port = 0; port < num_ports; port++) { 736 custom_num_rdc[port] = (num_ports == 4) ? 737 p4_rx_fair[port] : p2_rx_fair[port]; 738 custom_start_rdc[port] = start_rdc; 739 start_rdc += custom_num_rdc[port]; 740 } 741 break; 742 } 743 744 /* Now Update the rx properties */ 745 for (port = 0; port < num_ports; port++) { 746 NXGE_DEBUG_MSG((nxgep, CFG_CTL, 747 " update property rxdma-cfg with %s ", cfg_prop)); 748 ddi_status = ddi_prop_update_string(DDI_DEV_T_NONE, s_dip[port], 749 "rxdma-cfg", cfg_prop); 750 if (ddi_status != DDI_PROP_SUCCESS) { 751 NXGE_DEBUG_MSG((nxgep, CFG_CTL, 752 " property rxdma-cfg is not updating to %s", 753 cfg_prop)); 754 status |= NXGE_DDI_FAILED; 755 } 756 NXGE_DEBUG_MSG((nxgep, CFG_CTL, " update property %s with %d ", 757 num_rdc_prop, custom_num_rdc[port])); 758 759 ddi_status = ddi_prop_update_int(DDI_DEV_T_NONE, s_dip[port], 760 num_rdc_prop, custom_num_rdc[port]); 761 762 if (ddi_status != DDI_PROP_SUCCESS) { 763 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 764 " property %s not updating with %d", 765 num_rdc_prop, custom_num_rdc[port])); 766 status |= NXGE_DDI_FAILED; 767 } 768 NXGE_DEBUG_MSG((nxgep, CFG_CTL, " update property %s with %d ", 769 start_rdc_prop, custom_start_rdc[port])); 770 ddi_status = ddi_prop_update_int(DDI_DEV_T_NONE, s_dip[port], 771 start_rdc_prop, custom_start_rdc[port]); 772 773 if (ddi_status != DDI_PROP_SUCCESS) { 774 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 775 " property %s not updating with %d ", 776 start_rdc_prop, custom_start_rdc[port])); 777 status |= NXGE_DDI_FAILED; 778 } 779 } 780 if (status & NXGE_DDI_FAILED) 781 status |= NXGE_ERROR; 782 return (status); 783 } 784 785 static nxge_status_t 786 nxge_update_txdma_properties(p_nxge_t nxgep, config_token_t token, 787 dev_info_t *s_dip[]) 788 { 789 nxge_status_t status = NXGE_OK; 790 int ddi_status = DDI_SUCCESS; 791 int num_ports = nxgep->nports; 792 int port, bits, j; 793 uint8_t start_tdc, num_tdc = 0; 794 p_nxge_param_t param_arr; 795 uint32_t tdc_bitmap[MAX_SIBLINGS]; 796 int custom_start_tdc[MAX_SIBLINGS]; 797 int custom_num_tdc[MAX_SIBLINGS]; 798 uint8_t bad_config = B_FALSE; 799 int *prop_val; 800 uint_t prop_len; 801 char *start_tdc_prop, *num_tdc_prop, *cfg_prop; 802 803 start_tdc = 0; 804 param_arr = nxgep->param_arr; 805 start_tdc_prop = param_arr[param_txdma_channels_begin].fcode_name; 806 num_tdc_prop = param_arr[param_txdma_channels].fcode_name; 807 808 switch (token) { 809 case FAIR: 810 cfg_prop = "fair"; 811 for (port = 0; port < num_ports; port++) { 812 custom_num_tdc[port] = (num_ports == 4) ? 813 p4_tx_fair[port] : p2_tx_fair[port]; 814 custom_start_tdc[port] = start_tdc; 815 start_tdc += custom_num_tdc[port]; 816 } 817 break; 818 819 case EQUAL: 820 cfg_prop = "equal"; 821 for (port = 0; port < num_ports; port++) { 822 custom_num_tdc[port] = (num_ports == 4) ? 823 p4_tx_equal[port] : p2_tx_equal[port]; 824 custom_start_tdc[port] = start_tdc; 825 start_tdc += custom_num_tdc[port]; 826 } 827 break; 828 829 case CUSTOM: 830 cfg_prop = "custom"; 831 /* See if it is good config */ 832 num_tdc = 0; 833 for (port = 0; port < num_ports; port++) { 834 ddi_status = ddi_prop_lookup_int_array( 835 DDI_DEV_T_ANY, s_dip[port], 0, start_tdc_prop, 836 &prop_val, &prop_len); 837 if (ddi_status == DDI_SUCCESS) 838 custom_start_tdc[port] = *prop_val; 839 else { 840 NXGE_DEBUG_MSG((nxgep, CFG_CTL, 841 " %s custom start port %d" 842 " read failed ", " txdma-cfg", port)); 843 bad_config = B_TRUE; 844 status |= NXGE_DDI_FAILED; 845 } 846 847 if ((custom_start_tdc[port] == -1) || 848 (custom_start_tdc[port] >= 849 NXGE_MAX_RDCS)) { 850 NXGE_DEBUG_MSG((nxgep, CFG_CTL, 851 " %s custom start %d" 852 " out of range %x ", " txdma-cfg", 853 port, custom_start_tdc[port])); 854 bad_config = B_TRUE; 855 break; 856 } 857 858 ddi_status = ddi_prop_lookup_int_array( 859 DDI_DEV_T_ANY, s_dip[port], 0, num_tdc_prop, 860 &prop_val, &prop_len); 861 if (ddi_status == DDI_SUCCESS) 862 custom_num_tdc[port] = *prop_val; 863 else { 864 NXGE_DEBUG_MSG((nxgep, CFG_CTL, 865 " %s custom num port %d" 866 " read failed ", " txdma-cfg", port)); 867 bad_config = B_TRUE; 868 status |= NXGE_DDI_FAILED; 869 } 870 871 if ((custom_num_tdc[port] == -1) || 872 (custom_num_tdc[port] > 873 NXGE_MAX_TDCS) || 874 ((custom_num_tdc[port] + 875 custom_start_tdc[port]) > 876 NXGE_MAX_TDCS)) { 877 NXGE_DEBUG_MSG((nxgep, CFG_CTL, 878 " %s custom num %d" 879 " out of range %x ", " rxdma-cfg", 880 port, custom_num_tdc[port])); 881 bad_config = B_TRUE; 882 break; 883 } 884 num_tdc += custom_num_tdc[port]; 885 if (num_tdc > NXGE_MAX_TDCS) { 886 bad_config = B_TRUE; 887 break; 888 } 889 tdc_bitmap[port] = 0; 890 for (bits = 0; 891 bits < custom_num_tdc[port]; bits++) { 892 tdc_bitmap[port] |= 893 (1 << 894 (bits + custom_start_tdc[port])); 895 } 896 897 } 898 899 if (bad_config == B_FALSE) { 900 /* check for overlap */ 901 for (port = 0; port < num_ports - 1; port++) { 902 for (j = port + 1; j < num_ports; j++) { 903 if (tdc_bitmap[port] & 904 tdc_bitmap[j]) { 905 NXGE_DEBUG_MSG((nxgep, CFG_CTL, 906 " rxdma-cfg" 907 " property custom" 908 " bit overlap" 909 " %d %d ", 910 port, j)); 911 bad_config = B_TRUE; 912 break; 913 } 914 } 915 if (bad_config == B_TRUE) 916 break; 917 } 918 } 919 if (bad_config == B_TRUE) { 920 /* use default config */ 921 NXGE_DEBUG_MSG((nxgep, CFG_CTL, 922 " txdma-cfg property:" 923 " bad custom config:" " use default")); 924 925 for (port = 0; port < num_ports; port++) { 926 custom_num_tdc[port] = (num_ports == 4) ? 927 p4_tx_fair[port] : p2_tx_fair[port]; 928 custom_start_tdc[port] = start_tdc; 929 start_tdc += custom_num_tdc[port]; 930 } 931 } 932 break; 933 934 default: 935 /* use default config */ 936 cfg_prop = "fair"; 937 for (port = 0; port < num_ports; port++) { 938 custom_num_tdc[port] = (num_ports == 4) ? 939 p4_tx_fair[port] : p2_tx_fair[port]; 940 custom_start_tdc[port] = start_tdc; 941 start_tdc += custom_num_tdc[port]; 942 } 943 break; 944 } 945 946 /* Now Update the tx properties */ 947 for (port = 0; port < num_ports; port++) { 948 NXGE_DEBUG_MSG((nxgep, CFG_CTL, 949 " update property txdma-cfg with %s ", cfg_prop)); 950 ddi_status = ddi_prop_update_string(DDI_DEV_T_NONE, s_dip[port], 951 "txdma-cfg", cfg_prop); 952 if (ddi_status != DDI_PROP_SUCCESS) { 953 NXGE_DEBUG_MSG((nxgep, CFG_CTL, 954 " property txdma-cfg is not updating to %s", 955 cfg_prop)); 956 status |= NXGE_DDI_FAILED; 957 } 958 NXGE_DEBUG_MSG((nxgep, CFG_CTL, " update property %s with %d ", 959 num_tdc_prop, custom_num_tdc[port])); 960 961 ddi_status = ddi_prop_update_int(DDI_DEV_T_NONE, s_dip[port], 962 num_tdc_prop, custom_num_tdc[port]); 963 964 if (ddi_status != DDI_PROP_SUCCESS) { 965 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 966 " property %s not updating with %d", 967 num_tdc_prop, 968 custom_num_tdc[port])); 969 status |= NXGE_DDI_FAILED; 970 } 971 972 NXGE_DEBUG_MSG((nxgep, CFG_CTL, " update property %s with %d ", 973 start_tdc_prop, custom_start_tdc[port])); 974 975 ddi_status = ddi_prop_update_int(DDI_DEV_T_NONE, s_dip[port], 976 start_tdc_prop, custom_start_tdc[port]); 977 if (ddi_status != DDI_PROP_SUCCESS) { 978 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 979 " property %s not updating with %d ", 980 start_tdc_prop, custom_start_tdc[port])); 981 status |= NXGE_DDI_FAILED; 982 } 983 } 984 if (status & NXGE_DDI_FAILED) 985 status |= NXGE_ERROR; 986 return (status); 987 } 988 989 static nxge_status_t 990 nxge_update_cfg_properties(p_nxge_t nxgep, uint32_t flags, 991 config_token_t token, dev_info_t *s_dip[]) 992 { 993 nxge_status_t status = NXGE_OK; 994 995 switch (flags) { 996 case COMMON_TXDMA_CFG: 997 if (nxge_dma_obp_props_only == 0) 998 status = nxge_update_txdma_properties(nxgep, 999 token, s_dip); 1000 break; 1001 case COMMON_RXDMA_CFG: 1002 if (nxge_dma_obp_props_only == 0) 1003 status = nxge_update_rxdma_properties(nxgep, 1004 token, s_dip); 1005 1006 break; 1007 case COMMON_RXDMA_GRP_CFG: 1008 status = nxge_update_rxdma_grp_properties(nxgep, 1009 token, s_dip); 1010 break; 1011 default: 1012 return (NXGE_ERROR); 1013 } 1014 return (status); 1015 } 1016 1017 /* 1018 * verify consistence. 1019 * (May require publishing the properties on all the ports. 1020 * 1021 * What if properties are published on function 0 device only? 1022 * 1023 * 1024 * rxdma-cfg, txdma-cfg, rxdma-grp-cfg (required ) 1025 * What about class configs? 1026 * 1027 * If consistent, update the property on all the siblings. 1028 * set a flag on hardware shared register 1029 * The rest of the siblings will check the flag 1030 * if the flag is set, they will use the updated property 1031 * without doing any validation. 1032 */ 1033 1034 nxge_status_t 1035 nxge_cfg_verify_set_classify_prop(p_nxge_t nxgep, char *prop, 1036 uint64_t known_cfg, uint32_t override, dev_info_t *c_dip[]) 1037 { 1038 nxge_status_t status = NXGE_OK; 1039 int ddi_status = DDI_SUCCESS; 1040 int i = 0, found = 0, update_prop = B_TRUE; 1041 int *cfg_val; 1042 uint_t new_value, cfg_value[MAX_SIBLINGS]; 1043 uint_t prop_len; 1044 uint_t known_cfg_value; 1045 1046 known_cfg_value = (uint_t)known_cfg; 1047 1048 if (override == B_TRUE) { 1049 new_value = known_cfg_value; 1050 for (i = 0; i < nxgep->nports; i++) { 1051 ddi_status = ddi_prop_update_int(DDI_DEV_T_NONE, 1052 c_dip[i], prop, new_value); 1053 #ifdef NXGE_DEBUG_ERROR 1054 if (ddi_status != DDI_PROP_SUCCESS) 1055 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 1056 " property %s failed update ", prop)); 1057 #endif 1058 } 1059 if (ddi_status != DDI_PROP_SUCCESS) 1060 return (NXGE_ERROR | NXGE_DDI_FAILED); 1061 } 1062 for (i = 0; i < nxgep->nports; i++) { 1063 cfg_value[i] = known_cfg_value; 1064 if (ddi_prop_lookup_int_array(DDI_DEV_T_ANY, c_dip[i], 0, 1065 prop, &cfg_val, 1066 &prop_len) == DDI_PROP_SUCCESS) { 1067 cfg_value[i] = *cfg_val; 1068 ddi_prop_free(cfg_val); 1069 found++; 1070 } 1071 } 1072 1073 if (found != i) { 1074 NXGE_DEBUG_MSG((nxgep, CFG_CTL, 1075 " property %s not specified on all ports", prop)); 1076 if (found == 0) { 1077 /* not specified: Use default */ 1078 NXGE_DEBUG_MSG((nxgep, CFG_CTL, 1079 " property %s not specified on any port:" 1080 " Using default", prop)); 1081 new_value = known_cfg_value; 1082 } else { 1083 /* specified on some */ 1084 NXGE_DEBUG_MSG((nxgep, CFG_CTL, 1085 " property %s not specified" 1086 " on some ports: Using default", prop)); 1087 /* ? use p0 value instead ? */ 1088 new_value = known_cfg_value; 1089 } 1090 } else { 1091 /* check type and consistence */ 1092 /* found on all devices */ 1093 for (i = 1; i < found; i++) { 1094 if (cfg_value[i] != cfg_value[i - 1]) { 1095 NXGE_DEBUG_MSG((nxgep, CFG_CTL, 1096 " property %s inconsistent:" 1097 " Using default", prop)); 1098 new_value = known_cfg_value; 1099 break; 1100 } 1101 /* 1102 * Found on all the ports and consistent. Nothing to 1103 * do. 1104 */ 1105 update_prop = B_FALSE; 1106 } 1107 } 1108 1109 if (update_prop == B_TRUE) { 1110 for (i = 0; i < nxgep->nports; i++) { 1111 ddi_status = ddi_prop_update_int(DDI_DEV_T_NONE, 1112 c_dip[i], prop, new_value); 1113 #ifdef NXGE_DEBUG_ERROR 1114 if (ddi_status != DDI_SUCCESS) 1115 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 1116 " property %s not updating with %d" 1117 " Using default", 1118 prop, new_value)); 1119 #endif 1120 if (ddi_status != DDI_PROP_SUCCESS) 1121 status |= NXGE_DDI_FAILED; 1122 } 1123 } 1124 if (status & NXGE_DDI_FAILED) 1125 status |= NXGE_ERROR; 1126 1127 return (status); 1128 } 1129 1130 static uint64_t 1131 nxge_class_get_known_cfg(p_nxge_t nxgep, int class_prop, int rx_quick_cfg) 1132 { 1133 int start_prop; 1134 uint64_t cfg_value; 1135 p_nxge_param_t param_arr; 1136 1137 param_arr = nxgep->param_arr; 1138 cfg_value = param_arr[class_prop].value; 1139 start_prop = param_h1_init_value; 1140 1141 /* update the properties per quick config */ 1142 switch (rx_quick_cfg) { 1143 case CFG_L3_WEB: 1144 case CFG_L3_DISTRIBUTE: 1145 cfg_value = nxge_classify_get_cfg_value(nxgep, 1146 rx_quick_cfg, class_prop - start_prop); 1147 break; 1148 default: 1149 cfg_value = param_arr[class_prop].value; 1150 break; 1151 } 1152 return (cfg_value); 1153 } 1154 1155 static nxge_status_t 1156 nxge_cfg_verify_set_classify(p_nxge_t nxgep, dev_info_t *c_dip[]) 1157 { 1158 nxge_status_t status = NXGE_OK; 1159 int rx_quick_cfg, class_prop, start_prop, end_prop; 1160 char *prop_name; 1161 int override = B_TRUE; 1162 uint64_t cfg_value; 1163 p_nxge_param_t param_arr; 1164 1165 param_arr = nxgep->param_arr; 1166 rx_quick_cfg = param_arr[param_rx_quick_cfg].value; 1167 start_prop = param_h1_init_value; 1168 end_prop = param_class_opt_ipv6_sctp; 1169 1170 /* update the properties per quick config */ 1171 if (rx_quick_cfg == CFG_NOT_SPECIFIED) 1172 override = B_FALSE; 1173 1174 /* 1175 * these parameter affect the classification outcome. 1176 * these parameters are used to configure the Flow key and 1177 * the TCAM key for each of the IP classes. 1178 * Included here are also the H1 and H2 initial values 1179 * which affect the distribution as well as final hash value 1180 * (hence the offset into RDC table and FCRAM bucket location) 1181 * 1182 */ 1183 for (class_prop = start_prop; class_prop <= end_prop; class_prop++) { 1184 prop_name = param_arr[class_prop].fcode_name; 1185 cfg_value = nxge_class_get_known_cfg(nxgep, 1186 class_prop, rx_quick_cfg); 1187 status = nxge_cfg_verify_set_classify_prop(nxgep, prop_name, 1188 cfg_value, override, c_dip); 1189 } 1190 1191 /* 1192 * these properties do not affect the actual classification outcome. 1193 * used to enable/disable or tune the fflp hardware 1194 * 1195 * fcram_access_ratio, tcam_access_ratio, tcam_enable, llc_snap_enable 1196 * 1197 */ 1198 override = B_FALSE; 1199 for (class_prop = param_fcram_access_ratio; 1200 class_prop <= param_llc_snap_enable; class_prop++) { 1201 prop_name = param_arr[class_prop].fcode_name; 1202 cfg_value = param_arr[class_prop].value; 1203 status = nxge_cfg_verify_set_classify_prop(nxgep, prop_name, 1204 cfg_value, override, c_dip); 1205 } 1206 1207 return (status); 1208 } 1209 1210 nxge_status_t 1211 nxge_cfg_verify_set(p_nxge_t nxgep, uint32_t flag) 1212 { 1213 nxge_status_t status = NXGE_OK; 1214 int i = 0, found = 0; 1215 int num_siblings; 1216 dev_info_t *c_dip[MAX_SIBLINGS + 1]; 1217 char *prop_val[MAX_SIBLINGS]; 1218 config_token_t c_token[MAX_SIBLINGS]; 1219 char *prop; 1220 1221 if (nxge_dma_obp_props_only) 1222 return (NXGE_OK); 1223 1224 num_siblings = 0; 1225 c_dip[num_siblings] = ddi_get_child(nxgep->p_dip); 1226 while (c_dip[num_siblings]) { 1227 c_dip[num_siblings + 1] = 1228 ddi_get_next_sibling(c_dip[num_siblings]); 1229 num_siblings++; 1230 } 1231 1232 switch (flag) { 1233 case COMMON_TXDMA_CFG: 1234 prop = "txdma-cfg"; 1235 break; 1236 case COMMON_RXDMA_CFG: 1237 prop = "rxdma-cfg"; 1238 break; 1239 case COMMON_RXDMA_GRP_CFG: 1240 prop = "rxdma-grp-cfg"; 1241 break; 1242 case COMMON_CLASS_CFG: 1243 status = nxge_cfg_verify_set_classify(nxgep, c_dip); 1244 return (status); 1245 default: 1246 return (NXGE_ERROR); 1247 } 1248 1249 i = 0; 1250 while (i < num_siblings) { 1251 if (ddi_prop_lookup_string(DDI_DEV_T_ANY, c_dip[i], 0, prop, 1252 (char **)&prop_val[i]) == DDI_PROP_SUCCESS) { 1253 c_token[i] = nxge_get_config_token(prop_val[i]); 1254 ddi_prop_free(prop_val[i]); 1255 found++; 1256 } else 1257 c_token[i] = CONFIG_TOKEN_NONE; 1258 i++; 1259 } 1260 1261 if (found != i) { 1262 if (found == 0) { 1263 /* not specified: Use default */ 1264 NXGE_DEBUG_MSG((nxgep, CFG_CTL, 1265 " property %s not specified on any port:" 1266 " Using default", prop)); 1267 1268 status = nxge_update_cfg_properties(nxgep, 1269 flag, FAIR, c_dip); 1270 return (status); 1271 } else { 1272 /* 1273 * if the convention is to use function 0 device then 1274 * populate the other devices with this configuration. 1275 * 1276 * The other alternative is to use the default config. 1277 */ 1278 /* not specified: Use default */ 1279 NXGE_DEBUG_MSG((nxgep, CFG_CTL, 1280 " property %s not specified on some ports:" 1281 " Using default", prop)); 1282 status = nxge_update_cfg_properties(nxgep, 1283 flag, FAIR, c_dip); 1284 return (status); 1285 } 1286 } 1287 1288 /* check type and consistence */ 1289 /* found on all devices */ 1290 for (i = 1; i < found; i++) { 1291 if (c_token[i] != c_token[i - 1]) { 1292 NXGE_DEBUG_MSG((nxgep, CFG_CTL, 1293 " property %s inconsistent:" 1294 " Using default", prop)); 1295 status = nxge_update_cfg_properties(nxgep, 1296 flag, FAIR, c_dip); 1297 return (status); 1298 } 1299 } 1300 1301 /* 1302 * Found on all the ports check if it is custom configuration. if 1303 * custom, then verify consistence 1304 * 1305 * finally create soft properties 1306 */ 1307 status = nxge_update_cfg_properties(nxgep, flag, c_token[0], c_dip); 1308 return (status); 1309 } 1310 1311 nxge_status_t 1312 nxge_cfg_verify_set_quick_config(p_nxge_t nxgep) 1313 { 1314 nxge_status_t status = NXGE_OK; 1315 int ddi_status = DDI_SUCCESS; 1316 char *prop_val; 1317 char *rx_prop; 1318 char *prop; 1319 uint32_t cfg_value = CFG_NOT_SPECIFIED; 1320 p_nxge_param_t param_arr; 1321 1322 param_arr = nxgep->param_arr; 1323 rx_prop = param_arr[param_rx_quick_cfg].fcode_name; 1324 1325 prop = "rx-quick-cfg"; 1326 1327 /* 1328 * good value are 1329 * 1330 * "web-server" "generic-server" "l3-classify" "flow-classify" 1331 */ 1332 if (ddi_prop_lookup_string(DDI_DEV_T_ANY, nxgep->dip, 0, 1333 prop, (char **)&prop_val) != DDI_PROP_SUCCESS) { 1334 NXGE_DEBUG_MSG((nxgep, VPD_CTL, 1335 " property %s not specified: using default ", prop)); 1336 cfg_value = CFG_NOT_SPECIFIED; 1337 } else { 1338 cfg_value = CFG_L3_DISTRIBUTE; 1339 if (strncmp("web-server", (caddr_t)prop_val, 8) == 0) { 1340 cfg_value = CFG_L3_WEB; 1341 NXGE_DEBUG_MSG((nxgep, CFG_CTL, 1342 " %s: web server ", prop)); 1343 } 1344 if (strncmp("generic-server", (caddr_t)prop_val, 8) == 0) { 1345 cfg_value = CFG_L3_DISTRIBUTE; 1346 NXGE_DEBUG_MSG((nxgep, CFG_CTL, 1347 " %s: distribute ", prop)); 1348 } 1349 /* more */ 1350 ddi_prop_free(prop_val); 1351 } 1352 1353 ddi_status = ddi_prop_update_int(DDI_DEV_T_NONE, nxgep->dip, 1354 rx_prop, cfg_value); 1355 if (ddi_status != DDI_PROP_SUCCESS) 1356 status |= NXGE_DDI_FAILED; 1357 1358 /* now handle specified cases: */ 1359 if (status & NXGE_DDI_FAILED) 1360 status |= NXGE_ERROR; 1361 return (status); 1362 } 1363 1364 /* 1365 * Device properties adv-autoneg-cap etc are defined by FWARC 1366 * http://sac.sfbay/FWARC/2002/345/20020610_asif.haswarey 1367 */ 1368 static void 1369 nxge_use_cfg_link_cfg(p_nxge_t nxgep) 1370 { 1371 int *prop_val; 1372 uint_t prop_len; 1373 dev_info_t *dip; 1374 int speed; 1375 int duplex; 1376 int adv_autoneg_cap; 1377 int adv_10gfdx_cap; 1378 int adv_10ghdx_cap; 1379 int adv_1000fdx_cap; 1380 int adv_1000hdx_cap; 1381 int adv_100fdx_cap; 1382 int adv_100hdx_cap; 1383 int adv_10fdx_cap; 1384 int adv_10hdx_cap; 1385 int status = DDI_SUCCESS; 1386 1387 dip = nxgep->dip; 1388 1389 /* 1390 * first find out the card type and the supported link speeds and 1391 * features 1392 */ 1393 /* add code for card type */ 1394 if (ddi_prop_lookup_int_array(DDI_DEV_T_ANY, dip, 0, "adv-autoneg-cap", 1395 &prop_val, &prop_len) == DDI_PROP_SUCCESS) { 1396 ddi_prop_free(prop_val); 1397 return; 1398 } 1399 1400 if (ddi_prop_lookup_int_array(DDI_DEV_T_ANY, dip, 0, "adv-10gfdx-cap", 1401 &prop_val, &prop_len) == DDI_PROP_SUCCESS) { 1402 ddi_prop_free(prop_val); 1403 return; 1404 } 1405 1406 if (ddi_prop_lookup_int_array(DDI_DEV_T_ANY, dip, 0, "adv-1000hdx-cap", 1407 &prop_val, &prop_len) == DDI_PROP_SUCCESS) { 1408 ddi_prop_free(prop_val); 1409 return; 1410 } 1411 1412 if (ddi_prop_lookup_int_array(DDI_DEV_T_ANY, dip, 0, "adv-1000fdx-cap", 1413 &prop_val, &prop_len) == DDI_PROP_SUCCESS) { 1414 ddi_prop_free(prop_val); 1415 return; 1416 } 1417 1418 if (ddi_prop_lookup_int_array(DDI_DEV_T_ANY, dip, 0, "adv-100fdx-cap", 1419 &prop_val, &prop_len) == DDI_PROP_SUCCESS) { 1420 ddi_prop_free(prop_val); 1421 return; 1422 } 1423 1424 if (ddi_prop_lookup_int_array(DDI_DEV_T_ANY, dip, 0, "adv-100hdx-cap", 1425 &prop_val, &prop_len) == DDI_PROP_SUCCESS) { 1426 ddi_prop_free(prop_val); 1427 return; 1428 } 1429 1430 if (ddi_prop_lookup_int_array(DDI_DEV_T_ANY, dip, 0, "adv-10fdx-cap", 1431 &prop_val, &prop_len) == DDI_PROP_SUCCESS) { 1432 ddi_prop_free(prop_val); 1433 return; 1434 } 1435 1436 if (ddi_prop_lookup_int_array(DDI_DEV_T_ANY, dip, 0, "adv-10hdx-cap", 1437 &prop_val, &prop_len) == DDI_PROP_SUCCESS) { 1438 ddi_prop_free(prop_val); 1439 return; 1440 } 1441 1442 if (ddi_prop_lookup_byte_array(DDI_DEV_T_ANY, dip, 0, "speed", 1443 (uchar_t **)&prop_val, &prop_len) == DDI_PROP_SUCCESS) { 1444 if (strncmp("10000", (caddr_t)prop_val, 1445 (size_t)prop_len) == 0) { 1446 speed = 10000; 1447 } else if (strncmp("1000", (caddr_t)prop_val, 1448 (size_t)prop_len) == 0) { 1449 speed = 1000; 1450 } else if (strncmp("100", (caddr_t)prop_val, 1451 (size_t)prop_len) == 0) { 1452 speed = 100; 1453 } else if (strncmp("10", (caddr_t)prop_val, 1454 (size_t)prop_len) == 0) { 1455 speed = 10; 1456 } else if (strncmp("auto", (caddr_t)prop_val, 1457 (size_t)prop_len) == 0) { 1458 speed = 0; 1459 } else { 1460 NXGE_ERROR_MSG((nxgep, NXGE_NOTE, 1461 "speed property is invalid reverting to auto")); 1462 speed = 0; 1463 } 1464 ddi_prop_free(prop_val); 1465 } else 1466 speed = 0; 1467 1468 if (ddi_prop_lookup_byte_array(DDI_DEV_T_ANY, dip, 0, "duplex", 1469 (uchar_t **)&prop_val, &prop_len) == DDI_PROP_SUCCESS) { 1470 if (strncmp("full", (caddr_t)prop_val, 1471 (size_t)prop_len) == 0) { 1472 duplex = 2; 1473 } else if (strncmp("half", (caddr_t)prop_val, 1474 (size_t)prop_len) == 0) { 1475 duplex = 1; 1476 } else if (strncmp("auto", (caddr_t)prop_val, 1477 (size_t)prop_len) == 0) { 1478 duplex = 0; 1479 } else { 1480 NXGE_ERROR_MSG((nxgep, NXGE_NOTE, 1481 "duplex property is invalid" 1482 " reverting to auto")); 1483 duplex = 0; 1484 } 1485 ddi_prop_free(prop_val); 1486 } else 1487 duplex = 0; 1488 1489 /* speed == 0 or duplex == 0 means auto negotiation. */ 1490 adv_autoneg_cap = (speed == 0) || (duplex == 0); 1491 if (adv_autoneg_cap == 0) { 1492 adv_10gfdx_cap = ((speed == 10000) && (duplex == 2)); 1493 adv_10ghdx_cap = adv_10gfdx_cap; 1494 adv_10ghdx_cap |= ((speed == 10000) && (duplex == 1)); 1495 adv_1000fdx_cap = adv_10ghdx_cap; 1496 adv_1000fdx_cap |= ((speed == 1000) && (duplex == 2)); 1497 adv_1000hdx_cap = adv_1000fdx_cap; 1498 adv_1000hdx_cap |= ((speed == 1000) && (duplex == 1)); 1499 adv_100fdx_cap = adv_1000hdx_cap; 1500 adv_100fdx_cap |= ((speed == 100) && (duplex == 2)); 1501 adv_100hdx_cap = adv_100fdx_cap; 1502 adv_100hdx_cap |= ((speed == 100) && (duplex == 1)); 1503 adv_10fdx_cap = adv_100hdx_cap; 1504 adv_10fdx_cap |= ((speed == 10) && (duplex == 2)); 1505 adv_10hdx_cap = adv_10fdx_cap; 1506 adv_10hdx_cap |= ((speed == 10) && (duplex == 1)); 1507 } else if (speed == 0) { 1508 adv_10gfdx_cap = (duplex == 2); 1509 adv_10ghdx_cap = (duplex == 1); 1510 adv_1000fdx_cap = (duplex == 2); 1511 adv_1000hdx_cap = (duplex == 1); 1512 adv_100fdx_cap = (duplex == 2); 1513 adv_100hdx_cap = (duplex == 1); 1514 adv_10fdx_cap = (duplex == 2); 1515 adv_10hdx_cap = (duplex == 1); 1516 } 1517 if (duplex == 0) { 1518 adv_10gfdx_cap = (speed == 0); 1519 adv_10gfdx_cap |= (speed == 10000); 1520 adv_10ghdx_cap = adv_10gfdx_cap; 1521 adv_10ghdx_cap |= (speed == 10000); 1522 adv_1000fdx_cap = adv_10ghdx_cap; 1523 adv_1000fdx_cap |= (speed == 1000); 1524 adv_1000hdx_cap = adv_1000fdx_cap; 1525 adv_1000hdx_cap |= (speed == 1000); 1526 adv_100fdx_cap = adv_1000hdx_cap; 1527 adv_100fdx_cap |= (speed == 100); 1528 adv_100hdx_cap = adv_100fdx_cap; 1529 adv_100hdx_cap |= (speed == 100); 1530 adv_10fdx_cap = adv_100hdx_cap; 1531 adv_10fdx_cap |= (speed == 10); 1532 adv_10hdx_cap = adv_10fdx_cap; 1533 adv_10hdx_cap |= (speed == 10); 1534 } 1535 status = ddi_prop_update_int_array(DDI_DEV_T_NONE, dip, 1536 "adv-autoneg-cap", &adv_autoneg_cap, 1); 1537 if (status) 1538 return; 1539 1540 status = ddi_prop_update_int_array(DDI_DEV_T_NONE, dip, 1541 "adv-10gfdx-cap", &adv_10gfdx_cap, 1); 1542 if (status) 1543 goto nxge_map_myargs_to_gmii_fail1; 1544 1545 status = ddi_prop_update_int_array(DDI_DEV_T_NONE, dip, 1546 "adv-10ghdx-cap", &adv_10ghdx_cap, 1); 1547 if (status) 1548 goto nxge_map_myargs_to_gmii_fail2; 1549 1550 status = ddi_prop_update_int_array(DDI_DEV_T_NONE, dip, 1551 "adv-1000fdx-cap", &adv_1000fdx_cap, 1); 1552 if (status) 1553 goto nxge_map_myargs_to_gmii_fail3; 1554 1555 status = ddi_prop_update_int_array(DDI_DEV_T_NONE, dip, 1556 "adv-1000hdx-cap", &adv_1000hdx_cap, 1); 1557 if (status) 1558 goto nxge_map_myargs_to_gmii_fail4; 1559 1560 status = ddi_prop_update_int_array(DDI_DEV_T_NONE, dip, 1561 "adv-100fdx-cap", &adv_100fdx_cap, 1); 1562 if (status) 1563 goto nxge_map_myargs_to_gmii_fail5; 1564 1565 status = ddi_prop_update_int_array(DDI_DEV_T_NONE, dip, 1566 "adv-100hdx-cap", &adv_100hdx_cap, 1); 1567 if (status) 1568 goto nxge_map_myargs_to_gmii_fail6; 1569 1570 status = ddi_prop_update_int_array(DDI_DEV_T_NONE, dip, 1571 "adv-10fdx-cap", &adv_10fdx_cap, 1); 1572 if (status) 1573 goto nxge_map_myargs_to_gmii_fail7; 1574 1575 status = ddi_prop_update_int_array(DDI_DEV_T_NONE, dip, 1576 "adv-10hdx-cap", &adv_10hdx_cap, 1); 1577 if (status) 1578 goto nxge_map_myargs_to_gmii_fail8; 1579 1580 return; 1581 1582 nxge_map_myargs_to_gmii_fail9: 1583 (void) ddi_prop_remove(DDI_DEV_T_NONE, dip, "adv-10hdx-cap"); 1584 1585 nxge_map_myargs_to_gmii_fail8: 1586 (void) ddi_prop_remove(DDI_DEV_T_NONE, dip, "adv-10fdx-cap"); 1587 1588 nxge_map_myargs_to_gmii_fail7: 1589 (void) ddi_prop_remove(DDI_DEV_T_NONE, dip, "adv-100hdx-cap"); 1590 1591 nxge_map_myargs_to_gmii_fail6: 1592 (void) ddi_prop_remove(DDI_DEV_T_NONE, dip, "adv-100fdx-cap"); 1593 1594 nxge_map_myargs_to_gmii_fail5: 1595 (void) ddi_prop_remove(DDI_DEV_T_NONE, dip, "adv-1000hdx-cap"); 1596 1597 nxge_map_myargs_to_gmii_fail4: 1598 (void) ddi_prop_remove(DDI_DEV_T_NONE, dip, "adv-1000fdx-cap"); 1599 1600 nxge_map_myargs_to_gmii_fail3: 1601 (void) ddi_prop_remove(DDI_DEV_T_NONE, dip, "adv-10ghdx-cap"); 1602 1603 nxge_map_myargs_to_gmii_fail2: 1604 (void) ddi_prop_remove(DDI_DEV_T_NONE, dip, "adv-10gfdx-cap"); 1605 1606 nxge_map_myargs_to_gmii_fail1: 1607 (void) ddi_prop_remove(DDI_DEV_T_NONE, dip, "adv-autoneg-cap"); 1608 } 1609 1610 nxge_status_t 1611 nxge_get_config_properties(p_nxge_t nxgep) 1612 { 1613 nxge_status_t status = NXGE_OK; 1614 p_nxge_hw_list_t hw_p; 1615 char **prop_val; 1616 uint_t prop_len; 1617 uint_t i; 1618 1619 NXGE_DEBUG_MSG((nxgep, VPD_CTL, " ==> nxge_get_config_properties")); 1620 1621 if ((hw_p = nxgep->nxge_hw_p) == NULL) { 1622 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 1623 " nxge_get_config_properties:" 1624 " common hardware not set", nxgep->niu_type)); 1625 return (NXGE_ERROR); 1626 } 1627 1628 /* 1629 * Get info on how many ports Neptune card has. 1630 */ 1631 nxgep->nports = nxge_get_nports(nxgep); 1632 if (nxgep->nports <= 0) { 1633 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 1634 "<==nxge_get_config_properties: Invalid Neptune type 0x%x", 1635 nxgep->niu_type)); 1636 return (NXGE_ERROR); 1637 } 1638 nxgep->classifier.tcam_size = TCAM_NIU_TCAM_MAX_ENTRY; 1639 if (NXGE_IS_VALID_NEPTUNE_TYPE(nxgep)) { 1640 nxgep->classifier.tcam_size = TCAM_NXGE_TCAM_MAX_ENTRY; 1641 } 1642 if (nxgep->function_num >= nxgep->nports) { 1643 return (NXGE_ERROR); 1644 } 1645 1646 status = nxge_get_mac_addr_properties(nxgep); 1647 if (status != NXGE_OK) 1648 return (NXGE_ERROR); 1649 1650 /* 1651 * read the configuration type. If none is specified, used default. 1652 * Config types: equal: (default) DMA channels, RDC groups, TCAM, FCRAM 1653 * are shared equally across all the ports. 1654 * 1655 * Fair: DMA channels, RDC groups, TCAM, FCRAM are shared proportional 1656 * to the port speed. 1657 * 1658 * 1659 * custom: DMA channels, RDC groups, TCAM, FCRAM partition is 1660 * specified in nxge.conf. Need to read each parameter and set 1661 * up the parameters in nxge structures. 1662 * 1663 */ 1664 switch (nxgep->niu_type) { 1665 case N2_NIU: 1666 NXGE_DEBUG_MSG((nxgep, VPD_CTL, 1667 " ==> nxge_get_config_properties: N2")); 1668 MUTEX_ENTER(&hw_p->nxge_cfg_lock); 1669 if ((hw_p->flags & COMMON_CFG_VALID) != 1670 COMMON_CFG_VALID) { 1671 status = nxge_cfg_verify_set(nxgep, 1672 COMMON_RXDMA_GRP_CFG); 1673 status = nxge_cfg_verify_set(nxgep, 1674 COMMON_CLASS_CFG); 1675 hw_p->flags |= COMMON_CFG_VALID; 1676 } 1677 MUTEX_EXIT(&hw_p->nxge_cfg_lock); 1678 status = nxge_use_cfg_n2niu_properties(nxgep); 1679 break; 1680 default: 1681 if (!NXGE_IS_VALID_NEPTUNE_TYPE(nxgep)) { 1682 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 1683 " nxge_get_config_properties:" 1684 " unknown NIU type 0x%x", nxgep->niu_type)); 1685 return (NXGE_ERROR); 1686 } 1687 1688 NXGE_DEBUG_MSG((nxgep, VPD_CTL, 1689 " ==> nxge_get_config_properties: Neptune")); 1690 status = nxge_cfg_verify_set_quick_config(nxgep); 1691 MUTEX_ENTER(&hw_p->nxge_cfg_lock); 1692 if ((hw_p->flags & COMMON_CFG_VALID) != 1693 COMMON_CFG_VALID) { 1694 status = nxge_cfg_verify_set(nxgep, 1695 COMMON_TXDMA_CFG); 1696 status = nxge_cfg_verify_set(nxgep, 1697 COMMON_RXDMA_CFG); 1698 status = nxge_cfg_verify_set(nxgep, 1699 COMMON_RXDMA_GRP_CFG); 1700 status = nxge_cfg_verify_set(nxgep, 1701 COMMON_CLASS_CFG); 1702 hw_p->flags |= COMMON_CFG_VALID; 1703 } 1704 MUTEX_EXIT(&hw_p->nxge_cfg_lock); 1705 nxge_use_cfg_neptune_properties(nxgep); 1706 status = NXGE_OK; 1707 break; 1708 } 1709 1710 /* 1711 * Get the software LSO enable flag property from the 1712 * driver configuration file (nxge.conf). 1713 * This flag will be set to disable (0) if this property 1714 * does not exist. 1715 */ 1716 nxgep->soft_lso_enable = ddi_prop_get_int(DDI_DEV_T_ANY, nxgep->dip, 1717 DDI_PROP_DONTPASS | DDI_PROP_NOTPROM, "soft-lso-enable", 0); 1718 NXGE_DEBUG_MSG((nxgep, VPD_CTL, 1719 "nxge_get_config_properties: software lso %d\n", 1720 nxgep->soft_lso_enable)); 1721 1722 nxgep->niu_hw_type = NIU_HW_TYPE_DEFAULT; 1723 if (nxgep->niu_type == N2_NIU) { 1724 1725 uchar_t *s_prop_val; 1726 1727 /* 1728 * For NIU, the next generation KT has 1729 * a few differences in features that the 1730 * driver needs to handle them 1731 * accordingly. 1732 */ 1733 if (ddi_prop_lookup_string_array(DDI_DEV_T_ANY, nxgep->dip, 0, 1734 "compatible", &prop_val, &prop_len) == DDI_PROP_SUCCESS) { 1735 for (i = 0; i < prop_len; i++) { 1736 if ((strcmp((caddr_t)prop_val[i], 1737 KT_NIU_COMPATIBLE) == 0)) { 1738 nxgep->niu_hw_type = NIU_HW_TYPE_RF; 1739 NXGE_DEBUG_MSG((nxgep, VPD_CTL, 1740 "NIU type %d", nxgep->niu_hw_type)); 1741 break; 1742 } 1743 } 1744 } 1745 1746 ddi_prop_free(prop_val); 1747 /* 1748 * Some Serdes and PHY properties may also be provided as OBP 1749 * properties 1750 */ 1751 if (ddi_prop_lookup_byte_array(DDI_DEV_T_ANY, nxgep->dip, 0, 1752 "tx-cfg-l", &s_prop_val, &prop_len) == DDI_PROP_SUCCESS) { 1753 nxgep->srds_prop.tx_cfg_l = 1754 (uint16_t)(*(uint32_t *)s_prop_val); 1755 NXGE_DEBUG_MSG((nxgep, VPD_CTL, 1756 "nxge_get_config_properties: " 1757 "tx_cfg_l 0x%x, Read from OBP", 1758 nxgep->srds_prop.tx_cfg_l)); 1759 nxgep->srds_prop.prop_set |= NXGE_SRDS_TXCFGL; 1760 ddi_prop_free(s_prop_val); 1761 } 1762 if (ddi_prop_lookup_byte_array(DDI_DEV_T_ANY, nxgep->dip, 0, 1763 "tx-cfg-h", &s_prop_val, &prop_len) == DDI_PROP_SUCCESS) { 1764 nxgep->srds_prop.tx_cfg_h = 1765 (uint16_t)(*(uint32_t *)s_prop_val); 1766 NXGE_DEBUG_MSG((nxgep, VPD_CTL, 1767 "nxge_get_config_properties: " 1768 "tx_cfg_h 0x%x, Read from OBP", 1769 nxgep->srds_prop.tx_cfg_h)); 1770 nxgep->srds_prop.prop_set |= NXGE_SRDS_TXCFGH; 1771 ddi_prop_free(s_prop_val); 1772 } 1773 if (ddi_prop_lookup_byte_array(DDI_DEV_T_ANY, nxgep->dip, 0, 1774 "rx-cfg-l", &s_prop_val, &prop_len) == DDI_PROP_SUCCESS) { 1775 nxgep->srds_prop.rx_cfg_l = 1776 (uint16_t)(*(uint32_t *)s_prop_val); 1777 NXGE_DEBUG_MSG((nxgep, VPD_CTL, 1778 "nxge_get_config_properties: " 1779 "rx_cfg_l 0x%x, Read from OBP", 1780 nxgep->srds_prop.rx_cfg_l)); 1781 nxgep->srds_prop.prop_set |= NXGE_SRDS_RXCFGL; 1782 ddi_prop_free(s_prop_val); 1783 } 1784 if (ddi_prop_lookup_byte_array(DDI_DEV_T_ANY, nxgep->dip, 0, 1785 "rx-cfg-h", &s_prop_val, &prop_len) == DDI_PROP_SUCCESS) { 1786 nxgep->srds_prop.rx_cfg_h = 1787 (uint16_t)(*(uint32_t *)s_prop_val); 1788 NXGE_DEBUG_MSG((nxgep, VPD_CTL, 1789 "nxge_get_config_properties: " 1790 "rx_cfg_h 0x%x, Read from OBP", 1791 nxgep->srds_prop.rx_cfg_h)); 1792 nxgep->srds_prop.prop_set |= NXGE_SRDS_RXCFGH; 1793 ddi_prop_free(s_prop_val); 1794 } 1795 if (ddi_prop_lookup_byte_array(DDI_DEV_T_ANY, nxgep->dip, 0, 1796 "pll-cfg", &s_prop_val, &prop_len) == DDI_PROP_SUCCESS) { 1797 nxgep->srds_prop.pll_cfg_l = 1798 (uint16_t)(*(uint32_t *)s_prop_val); 1799 NXGE_DEBUG_MSG((nxgep, VPD_CTL, 1800 "nxge_get_config_properties: " 1801 "pll_cfg_l 0x%x, Read from OBP", 1802 nxgep->srds_prop.pll_cfg_l)); 1803 nxgep->srds_prop.prop_set |= NXGE_SRDS_PLLCFGL; 1804 ddi_prop_free(s_prop_val); 1805 } 1806 if (ddi_prop_lookup_byte_array(DDI_DEV_T_ANY, nxgep->dip, 0, 1807 "phy-reg-values", &s_prop_val, &prop_len) == 1808 DDI_PROP_SUCCESS) { 1809 1810 int tun_cnt, i; 1811 uchar_t *arr = s_prop_val; 1812 1813 tun_cnt = prop_len / 6; /* 3 values, 2 bytes each */ 1814 nxgep->phy_prop.arr = 1815 KMEM_ZALLOC(sizeof (nxge_phy_mdio_val_t) * tun_cnt, 1816 KM_SLEEP); 1817 nxgep->phy_prop.cnt = tun_cnt; 1818 for (i = 0; i < tun_cnt; i++) { 1819 nxgep->phy_prop.arr[i].dev = *(uint16_t *)arr; 1820 arr += 2; 1821 nxgep->phy_prop.arr[i].reg = *(uint16_t *)arr; 1822 arr += 2; 1823 nxgep->phy_prop.arr[i].val = *(uint16_t *)arr; 1824 arr += 2; 1825 NXGE_DEBUG_MSG((nxgep, VPD_CTL, 1826 "nxge_get_config_properties: From OBP, " 1827 "read PHY <dev.reg.val> = " 1828 "<0x%x.0x%x.0x%x>", 1829 nxgep->phy_prop.arr[i].dev, 1830 nxgep->phy_prop.arr[i].reg, 1831 nxgep->phy_prop.arr[i].val)); 1832 } 1833 ddi_prop_free(s_prop_val); 1834 } 1835 } 1836 1837 NXGE_DEBUG_MSG((nxgep, VPD_CTL, " <== nxge_get_config_properties")); 1838 return (status); 1839 } 1840 1841 static nxge_status_t 1842 nxge_use_cfg_n2niu_properties(p_nxge_t nxgep) 1843 { 1844 nxge_status_t status = NXGE_OK; 1845 1846 NXGE_DEBUG_MSG((nxgep, CFG_CTL, " ==> nxge_use_cfg_n2niu_properties")); 1847 1848 status = nxge_use_default_dma_config_n2(nxgep); 1849 if (status != NXGE_OK) { 1850 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 1851 " ==> nxge_use_cfg_n2niu_properties (err 0x%x)", 1852 status)); 1853 return (status | NXGE_ERROR); 1854 } 1855 1856 (void) nxge_use_cfg_vlan_class_config(nxgep); 1857 (void) nxge_use_cfg_mac_class_config(nxgep); 1858 (void) nxge_use_cfg_class_config(nxgep); 1859 (void) nxge_use_cfg_link_cfg(nxgep); 1860 1861 /* 1862 * Read in the hardware (fcode) properties. Use the ndd array to read 1863 * each property. 1864 */ 1865 (void) nxge_get_param_soft_properties(nxgep); 1866 NXGE_DEBUG_MSG((nxgep, CFG_CTL, " <== nxge_use_cfg_n2niu_properties")); 1867 1868 return (status); 1869 } 1870 1871 static void 1872 nxge_use_cfg_neptune_properties(p_nxge_t nxgep) 1873 { 1874 NXGE_DEBUG_MSG((nxgep, CFG_CTL, "==> nxge_use_cfg_neptune_properties")); 1875 1876 (void) nxge_use_cfg_dma_config(nxgep); 1877 (void) nxge_use_cfg_vlan_class_config(nxgep); 1878 (void) nxge_use_cfg_mac_class_config(nxgep); 1879 (void) nxge_use_cfg_class_config(nxgep); 1880 (void) nxge_use_cfg_link_cfg(nxgep); 1881 1882 /* 1883 * Read in the hardware (fcode) properties. Use the ndd array to read 1884 * each property. 1885 */ 1886 (void) nxge_get_param_soft_properties(nxgep); 1887 NXGE_DEBUG_MSG((nxgep, CFG_CTL, "<== nxge_use_cfg_neptune_properties")); 1888 } 1889 1890 /* 1891 * FWARC 2006/556 for N2 NIU. Get the properties 1892 * from the prom. 1893 */ 1894 static nxge_status_t 1895 nxge_use_default_dma_config_n2(p_nxge_t nxgep) 1896 { 1897 int ndmas; 1898 uint8_t func; 1899 p_nxge_dma_pt_cfg_t p_dma_cfgp; 1900 p_nxge_hw_pt_cfg_t p_cfgp; 1901 int *prop_val; 1902 uint_t prop_len; 1903 int i; 1904 nxge_status_t status = NXGE_OK; 1905 1906 NXGE_DEBUG_MSG((nxgep, OBP_CTL, "==> nxge_use_default_dma_config_n2")); 1907 1908 p_dma_cfgp = (p_nxge_dma_pt_cfg_t)&nxgep->pt_config; 1909 p_cfgp = (p_nxge_hw_pt_cfg_t)&p_dma_cfgp->hw_config; 1910 1911 func = nxgep->function_num; 1912 p_cfgp->function_number = func; 1913 ndmas = NXGE_TDMA_PER_NIU_PORT; 1914 if (ddi_prop_lookup_int_array(DDI_DEV_T_ANY, nxgep->dip, 0, 1915 "tx-dma-channels", (int **)&prop_val, 1916 &prop_len) == DDI_PROP_SUCCESS) { 1917 if (prop_len != NXGE_NIU_TDMA_PROP_LEN) { 1918 ddi_prop_free(prop_val); 1919 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 1920 "==> nxge_use_default_dma_config_n2: " 1921 "invalid tx-dma-channels property for the NIU, " 1922 "using defaults")); 1923 /* 1924 * Just failover to defaults 1925 */ 1926 p_cfgp->tdc.start = (func * NXGE_TDMA_PER_NIU_PORT); 1927 ndmas = NXGE_TDMA_PER_NIU_PORT; 1928 } else { 1929 p_cfgp->tdc.start = prop_val[0]; 1930 NXGE_DEBUG_MSG((nxgep, OBP_CTL, 1931 "==> nxge_use_default_dma_config_n2: tdc starts %d " 1932 "(#%d)", p_cfgp->tdc.start, prop_len)); 1933 1934 ndmas = prop_val[1]; 1935 NXGE_DEBUG_MSG((nxgep, OBP_CTL, 1936 "==> nxge_use_default_dma_config_n2: #tdc %d (#%d)", 1937 ndmas, prop_len)); 1938 ddi_prop_free(prop_val); 1939 } 1940 } else { 1941 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 1942 "==> nxge_use_default_dma_config_n2: " 1943 "get tx-dma-channels failed")); 1944 return (NXGE_DDI_FAILED); 1945 } 1946 1947 p_cfgp->tdc.count = ndmas; 1948 p_cfgp->tdc.owned = p_cfgp->tdc.count; 1949 1950 NXGE_DEBUG_MSG((nxgep, OBP_CTL, "==> nxge_use_default_dma_config_n2: " 1951 "p_cfgp 0x%llx max_tdcs %d start %d", 1952 p_cfgp, p_cfgp->tdc.count, p_cfgp->tdc.start)); 1953 1954 /* Receive DMA */ 1955 ndmas = NXGE_RDMA_PER_NIU_PORT; 1956 if (ddi_prop_lookup_int_array(DDI_DEV_T_ANY, nxgep->dip, 0, 1957 "rx-dma-channels", (int **)&prop_val, 1958 &prop_len) == DDI_PROP_SUCCESS) { 1959 if (prop_len != NXGE_NIU_RDMA_PROP_LEN) { 1960 ddi_prop_free(prop_val); 1961 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 1962 "==> nxge_use_default_dma_config_n2: " 1963 "invalid rx-dma-channels property for the NIU, " 1964 "using defaults")); 1965 /* 1966 * Just failover to defaults 1967 */ 1968 p_cfgp->start_rdc = (func * NXGE_RDMA_PER_NIU_PORT); 1969 ndmas = NXGE_RDMA_PER_NIU_PORT; 1970 } else { 1971 p_cfgp->start_rdc = prop_val[0]; 1972 NXGE_DEBUG_MSG((nxgep, OBP_CTL, 1973 "==> nxge_use_default_dma_config_n2(obp):" 1974 " rdc start %d (#%d)", 1975 p_cfgp->start_rdc, prop_len)); 1976 ndmas = prop_val[1]; 1977 NXGE_DEBUG_MSG((nxgep, OBP_CTL, 1978 "==> nxge_use_default_dma_config_n2(obp): " 1979 "#rdc %d (#%d)", ndmas, prop_len)); 1980 ddi_prop_free(prop_val); 1981 } 1982 } else { 1983 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 1984 "==> nxge_use_default_dma_config_n2: " 1985 "get rx-dma-channel failed")); 1986 return (NXGE_DDI_FAILED); 1987 } 1988 1989 p_cfgp->max_rdcs = ndmas; 1990 nxgep->rdc_mask = (ndmas - 1); 1991 1992 /* Hypervisor: rdc # and group # use the same # !! */ 1993 p_cfgp->max_grpids = p_cfgp->max_rdcs + p_cfgp->tdc.owned; 1994 p_cfgp->mif_ldvid = p_cfgp->mac_ldvid = p_cfgp->ser_ldvid = 0; 1995 1996 if (ddi_prop_lookup_int_array(DDI_DEV_T_ANY, nxgep->dip, 0, 1997 "interrupts", (int **)&prop_val, 1998 &prop_len) == DDI_PROP_SUCCESS) { 1999 if ((prop_len != NXGE_NIU_0_INTR_PROP_LEN) && 2000 (prop_len != NXGE_NIU_1_INTR_PROP_LEN)) { 2001 ddi_prop_free(prop_val); 2002 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 2003 "==> nxge_use_default_dma_config_n2: " 2004 "get interrupts failed")); 2005 return (NXGE_DDI_FAILED); 2006 } 2007 2008 /* 2009 * For each device assigned, the content of each interrupts 2010 * property is its logical device group. 2011 * 2012 * Assignment of interrupts property is in the the following 2013 * order: 2014 * 2015 * MAC MIF (if configured) SYSTEM ERROR (if configured) first 2016 * receive channel next channel...... last receive channel 2017 * first transmit channel next channel...... last transmit 2018 * channel 2019 * 2020 * prop_len should be at least for one mac and total # of rx and 2021 * tx channels. Function 0 owns MIF and ERROR 2022 */ 2023 NXGE_DEBUG_MSG((nxgep, OBP_CTL, 2024 "==> nxge_use_default_dma_config_n2(obp): " 2025 "# interrupts %d", prop_len)); 2026 2027 switch (func) { 2028 case 0: 2029 p_cfgp->ldg_chn_start = 3; 2030 p_cfgp->mac_ldvid = NXGE_MAC_LD_PORT0; 2031 p_cfgp->mif_ldvid = NXGE_MIF_LD; 2032 p_cfgp->ser_ldvid = NXGE_SYS_ERROR_LD; 2033 2034 break; 2035 case 1: 2036 p_cfgp->ldg_chn_start = 1; 2037 p_cfgp->mac_ldvid = NXGE_MAC_LD_PORT1; 2038 2039 break; 2040 default: 2041 status = NXGE_DDI_FAILED; 2042 break; 2043 } 2044 2045 if (status != NXGE_OK) 2046 return (status); 2047 2048 for (i = 0; i < prop_len; i++) { 2049 p_cfgp->ldg[i] = prop_val[i]; 2050 NXGE_DEBUG_MSG((nxgep, OBP_CTL, 2051 "==> nxge_use_default_dma_config_n2(obp): " 2052 "F%d: interrupt #%d, ldg %d", 2053 nxgep->function_num, i, p_cfgp->ldg[i])); 2054 } 2055 2056 p_cfgp->max_grpids = prop_len; 2057 NXGE_DEBUG_MSG((nxgep, OBP_CTL, 2058 "==> nxge_use_default_dma_config_n2(obp): %d " 2059 "(#%d) maxgrpids %d channel starts %d", 2060 p_cfgp->mac_ldvid, i, p_cfgp->max_grpids, 2061 p_cfgp->ldg_chn_start)); 2062 ddi_prop_free(prop_val); 2063 } else { 2064 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 2065 "==> nxge_use_default_dma_config_n2: " 2066 "get interrupts failed")); 2067 return (NXGE_DDI_FAILED); 2068 } 2069 2070 p_cfgp->max_ldgs = p_cfgp->max_grpids; 2071 NXGE_DEBUG_MSG((nxgep, OBP_CTL, 2072 "==> nxge_use_default_dma_config_n2: p_cfgp 0x%llx max_rdcs %d " 2073 "max_grpids %d macid %d mifid %d serrid %d", 2074 p_cfgp, p_cfgp->max_rdcs, p_cfgp->max_grpids, 2075 p_cfgp->mac_ldvid, p_cfgp->mif_ldvid, p_cfgp->ser_ldvid)); 2076 2077 2078 NXGE_DEBUG_MSG((nxgep, OBP_CTL, "==> nxge_use_default_dma_config_n2: " 2079 "p_cfgp p%p start_ldg %d nxgep->max_ldgs %d", 2080 p_cfgp, p_cfgp->start_ldg, p_cfgp->max_ldgs)); 2081 2082 /* 2083 * RDC groups and the beginning RDC group assigned to this function. 2084 */ 2085 p_cfgp->max_rdc_grpids = NXGE_MAX_RDC_GROUPS / nxgep->nports; 2086 p_cfgp->def_mac_rxdma_grpid = 2087 nxgep->function_num * NXGE_MAX_RDC_GROUPS / nxgep->nports; 2088 p_cfgp->def_mac_txdma_grpid = 2089 nxgep->function_num * NXGE_MAX_TDC_GROUPS / nxgep->nports; 2090 2091 if ((p_cfgp->def_mac_rxdma_grpid = nxge_fzc_rdc_tbl_bind(nxgep, 2092 p_cfgp->def_mac_rxdma_grpid, B_TRUE)) >= NXGE_MAX_RDC_GRPS) { 2093 NXGE_ERROR_MSG((nxgep, CFG_CTL, 2094 "nxge_use_default_dma_config_n2(): " 2095 "nxge_fzc_rdc_tbl_bind failed")); 2096 return (NXGE_DDI_FAILED); 2097 } 2098 2099 status = ddi_prop_update_int(DDI_DEV_T_NONE, nxgep->dip, 2100 "rx-rdc-grps", p_cfgp->max_rdc_grpids); 2101 if (status) { 2102 return (NXGE_DDI_FAILED); 2103 } 2104 status = ddi_prop_update_int(DDI_DEV_T_NONE, nxgep->dip, 2105 "rx-rdc-grps-begin", p_cfgp->def_mac_rxdma_grpid); 2106 if (status) { 2107 (void) ddi_prop_remove(DDI_DEV_T_NONE, nxgep->dip, 2108 "rx-rdc-grps"); 2109 return (NXGE_DDI_FAILED); 2110 } 2111 NXGE_DEBUG_MSG((nxgep, OBP_CTL, "==> nxge_use_default_dma_config_n2: " 2112 "p_cfgp $%p # rdc groups %d start rdc group id %d", 2113 p_cfgp, p_cfgp->max_rdc_grpids, 2114 p_cfgp->def_mac_rxdma_grpid)); 2115 2116 nxgep->intr_timeout = NXGE_RDC_RCR_TIMEOUT; 2117 if (ddi_prop_lookup_int_array(DDI_DEV_T_ANY, nxgep->dip, 0, 2118 "rxdma-intr-time", (int **)&prop_val, &prop_len) == 2119 DDI_PROP_SUCCESS) { 2120 if ((prop_len > 0) && (prop_len <= p_cfgp->max_rdcs)) { 2121 nxgep->intr_timeout = prop_val[0]; 2122 (void) ddi_prop_update_int_array(DDI_DEV_T_NONE, 2123 nxgep->dip, "rxdma-intr-time", prop_val, prop_len); 2124 } 2125 ddi_prop_free(prop_val); 2126 } 2127 2128 nxgep->intr_threshold = NXGE_RDC_RCR_THRESHOLD; 2129 if (ddi_prop_lookup_int_array(DDI_DEV_T_ANY, nxgep->dip, 0, 2130 "rxdma-intr-pkts", (int **)&prop_val, &prop_len) == 2131 DDI_PROP_SUCCESS) { 2132 if ((prop_len > 0) && (prop_len <= p_cfgp->max_rdcs)) { 2133 nxgep->intr_threshold = prop_val[0]; 2134 (void) ddi_prop_update_int_array(DDI_DEV_T_NONE, 2135 nxgep->dip, "rxdma-intr-pkts", prop_val, prop_len); 2136 } 2137 ddi_prop_free(prop_val); 2138 } 2139 2140 nxge_set_hw_dma_config(nxgep); 2141 NXGE_DEBUG_MSG((nxgep, OBP_CTL, "<== nxge_use_default_dma_config_n2")); 2142 return (status); 2143 } 2144 2145 static void 2146 nxge_use_cfg_dma_config(p_nxge_t nxgep) 2147 { 2148 int tx_ndmas, rx_ndmas, nrxgp, st_txdma, st_rxdma; 2149 p_nxge_dma_pt_cfg_t p_dma_cfgp; 2150 p_nxge_hw_pt_cfg_t p_cfgp; 2151 dev_info_t *dip; 2152 p_nxge_param_t param_arr; 2153 char *prop; 2154 int *prop_val; 2155 uint_t prop_len; 2156 int i; 2157 uint8_t *ch_arr_p; 2158 2159 NXGE_DEBUG_MSG((nxgep, CFG_CTL, " ==> nxge_use_cfg_dma_config")); 2160 param_arr = nxgep->param_arr; 2161 2162 p_dma_cfgp = (p_nxge_dma_pt_cfg_t)&nxgep->pt_config; 2163 p_cfgp = (p_nxge_hw_pt_cfg_t)&p_dma_cfgp->hw_config; 2164 dip = nxgep->dip; 2165 p_cfgp->function_number = nxgep->function_num; 2166 prop = param_arr[param_txdma_channels_begin].fcode_name; 2167 2168 if (ddi_prop_lookup_int_array(DDI_DEV_T_ANY, dip, 0, prop, 2169 &prop_val, &prop_len) == DDI_PROP_SUCCESS) { 2170 p_cfgp->tdc.start = *prop_val; 2171 ddi_prop_free(prop_val); 2172 } else { 2173 switch (nxgep->niu_type) { 2174 case NEPTUNE_4_1GC: 2175 ch_arr_p = &tx_4_1G[0]; 2176 break; 2177 case NEPTUNE_2_10GF: 2178 ch_arr_p = &tx_2_10G[0]; 2179 break; 2180 case NEPTUNE_2_10GF_2_1GC: 2181 case NEPTUNE_2_10GF_2_1GRF: 2182 ch_arr_p = &tx_2_10G_2_1G[0]; 2183 break; 2184 case NEPTUNE_1_10GF_3_1GC: 2185 ch_arr_p = &tx_1_10G_3_1G[0]; 2186 break; 2187 case NEPTUNE_1_1GC_1_10GF_2_1GC: 2188 ch_arr_p = &tx_1_1G_1_10G_2_1G[0]; 2189 break; 2190 default: 2191 switch (nxgep->platform_type) { 2192 case P_NEPTUNE_ALONSO: 2193 ch_arr_p = &tx_2_10G_2_1G[0]; 2194 break; 2195 default: 2196 ch_arr_p = &p4_tx_equal[0]; 2197 break; 2198 } 2199 break; 2200 } 2201 st_txdma = 0; 2202 for (i = 0; i < nxgep->function_num; i++, ch_arr_p++) 2203 st_txdma += *ch_arr_p; 2204 2205 (void) ddi_prop_update_int(DDI_DEV_T_NONE, nxgep->dip, 2206 prop, st_txdma); 2207 p_cfgp->tdc.start = st_txdma; 2208 } 2209 2210 prop = param_arr[param_txdma_channels].fcode_name; 2211 if (ddi_prop_lookup_int_array(DDI_DEV_T_ANY, dip, 0, prop, 2212 &prop_val, &prop_len) == DDI_PROP_SUCCESS) { 2213 tx_ndmas = *prop_val; 2214 ddi_prop_free(prop_val); 2215 } else { 2216 switch (nxgep->niu_type) { 2217 case NEPTUNE_4_1GC: 2218 tx_ndmas = tx_4_1G[nxgep->function_num]; 2219 break; 2220 case NEPTUNE_2_10GF: 2221 tx_ndmas = tx_2_10G[nxgep->function_num]; 2222 break; 2223 case NEPTUNE_2_10GF_2_1GC: 2224 case NEPTUNE_2_10GF_2_1GRF: 2225 tx_ndmas = tx_2_10G_2_1G[nxgep->function_num]; 2226 break; 2227 case NEPTUNE_1_10GF_3_1GC: 2228 tx_ndmas = tx_1_10G_3_1G[nxgep->function_num]; 2229 break; 2230 case NEPTUNE_1_1GC_1_10GF_2_1GC: 2231 tx_ndmas = tx_1_1G_1_10G_2_1G[nxgep->function_num]; 2232 break; 2233 default: 2234 switch (nxgep->platform_type) { 2235 case P_NEPTUNE_ALONSO: 2236 tx_ndmas = tx_2_10G_2_1G[nxgep->function_num]; 2237 break; 2238 default: 2239 tx_ndmas = p4_tx_equal[nxgep->function_num]; 2240 break; 2241 } 2242 break; 2243 } 2244 (void) ddi_prop_update_int(DDI_DEV_T_NONE, nxgep->dip, 2245 prop, tx_ndmas); 2246 } 2247 2248 p_cfgp->tdc.count = tx_ndmas; 2249 p_cfgp->tdc.owned = p_cfgp->tdc.count; 2250 NXGE_DEBUG_MSG((nxgep, CFG_CTL, "==> nxge_use_cfg_dma_config: " 2251 "p_cfgp 0x%llx max_tdcs %d", p_cfgp, p_cfgp->tdc.count)); 2252 2253 prop = param_arr[param_rxdma_channels_begin].fcode_name; 2254 2255 if (ddi_prop_lookup_int_array(DDI_DEV_T_ANY, dip, 0, prop, 2256 &prop_val, &prop_len) == DDI_PROP_SUCCESS) { 2257 p_cfgp->start_rdc = *prop_val; 2258 ddi_prop_free(prop_val); 2259 } else { 2260 switch (nxgep->niu_type) { 2261 case NEPTUNE_4_1GC: 2262 ch_arr_p = &rx_4_1G[0]; 2263 break; 2264 case NEPTUNE_2_10GF: 2265 ch_arr_p = &rx_2_10G[0]; 2266 break; 2267 case NEPTUNE_2_10GF_2_1GC: 2268 case NEPTUNE_2_10GF_2_1GRF: 2269 ch_arr_p = &rx_2_10G_2_1G[0]; 2270 break; 2271 case NEPTUNE_1_10GF_3_1GC: 2272 ch_arr_p = &rx_1_10G_3_1G[0]; 2273 break; 2274 case NEPTUNE_1_1GC_1_10GF_2_1GC: 2275 ch_arr_p = &rx_1_1G_1_10G_2_1G[0]; 2276 break; 2277 default: 2278 switch (nxgep->platform_type) { 2279 case P_NEPTUNE_ALONSO: 2280 ch_arr_p = &rx_2_10G_2_1G[0]; 2281 break; 2282 default: 2283 ch_arr_p = &p4_rx_equal[0]; 2284 break; 2285 } 2286 break; 2287 } 2288 st_rxdma = 0; 2289 for (i = 0; i < nxgep->function_num; i++, ch_arr_p++) 2290 st_rxdma += *ch_arr_p; 2291 2292 (void) ddi_prop_update_int(DDI_DEV_T_NONE, nxgep->dip, 2293 prop, st_rxdma); 2294 p_cfgp->start_rdc = st_rxdma; 2295 } 2296 2297 prop = param_arr[param_rxdma_channels].fcode_name; 2298 2299 if (ddi_prop_lookup_int_array(DDI_DEV_T_ANY, dip, 0, prop, 2300 &prop_val, &prop_len) == DDI_PROP_SUCCESS) { 2301 rx_ndmas = *prop_val; 2302 ddi_prop_free(prop_val); 2303 } else { 2304 switch (nxgep->niu_type) { 2305 case NEPTUNE_4_1GC: 2306 rx_ndmas = rx_4_1G[nxgep->function_num]; 2307 break; 2308 case NEPTUNE_2_10GF: 2309 rx_ndmas = rx_2_10G[nxgep->function_num]; 2310 break; 2311 case NEPTUNE_2_10GF_2_1GC: 2312 case NEPTUNE_2_10GF_2_1GRF: 2313 rx_ndmas = rx_2_10G_2_1G[nxgep->function_num]; 2314 break; 2315 case NEPTUNE_1_10GF_3_1GC: 2316 rx_ndmas = rx_1_10G_3_1G[nxgep->function_num]; 2317 break; 2318 case NEPTUNE_1_1GC_1_10GF_2_1GC: 2319 rx_ndmas = rx_1_1G_1_10G_2_1G[nxgep->function_num]; 2320 break; 2321 default: 2322 switch (nxgep->platform_type) { 2323 case P_NEPTUNE_ALONSO: 2324 rx_ndmas = rx_2_10G_2_1G[nxgep->function_num]; 2325 break; 2326 default: 2327 rx_ndmas = p4_rx_equal[nxgep->function_num]; 2328 break; 2329 } 2330 break; 2331 } 2332 (void) ddi_prop_update_int(DDI_DEV_T_NONE, nxgep->dip, 2333 prop, rx_ndmas); 2334 } 2335 2336 p_cfgp->max_rdcs = rx_ndmas; 2337 2338 /* 2339 * RDC groups and the beginning RDC group assigned to this function. 2340 * XXX: this may be wrong if prop value is used. 2341 */ 2342 p_cfgp->def_mac_rxdma_grpid = 2343 nxgep->function_num * NXGE_MAX_RDC_GROUPS / nxgep->nports; 2344 p_cfgp->def_mac_txdma_grpid = 2345 nxgep->function_num * NXGE_MAX_TDC_GROUPS / nxgep->nports; 2346 2347 if ((p_cfgp->def_mac_rxdma_grpid = nxge_fzc_rdc_tbl_bind(nxgep, 2348 p_cfgp->def_mac_rxdma_grpid, B_TRUE)) >= NXGE_MAX_RDC_GRPS) { 2349 NXGE_ERROR_MSG((nxgep, CFG_CTL, 2350 "nxge_use_default_dma_config2(): " 2351 "nxge_fzc_rdc_tbl_bind failed")); 2352 goto nxge_use_cfg_dma_config_exit; 2353 } 2354 2355 prop = param_arr[param_rx_rdc_grps].fcode_name; 2356 if (ddi_prop_lookup_int_array(DDI_DEV_T_ANY, dip, 0, prop, 2357 &prop_val, &prop_len) == DDI_PROP_SUCCESS) { 2358 nrxgp = *prop_val; 2359 ddi_prop_free(prop_val); 2360 } else { 2361 nrxgp = NXGE_MAX_RDC_GRPS / nxgep->nports; 2362 (void) ddi_prop_update_int(DDI_DEV_T_NONE, nxgep->dip, 2363 prop, nrxgp); 2364 NXGE_DEBUG_MSG((nxgep, CFG_CTL, 2365 "==> nxge_use_default_dma_config: " 2366 "num_rdc_grpid not found: use def:# of " 2367 "rdc groups %d\n", nrxgp)); 2368 } 2369 p_cfgp->max_rdc_grpids = nrxgp; 2370 2371 /* 2372 * 2/4 ports have the same hard-wired logical groups assigned. 2373 */ 2374 p_cfgp->start_ldg = nxgep->function_num * NXGE_LDGRP_PER_4PORTS; 2375 p_cfgp->max_ldgs = NXGE_LDGRP_PER_4PORTS; 2376 2377 NXGE_DEBUG_MSG((nxgep, CFG_CTL, "==> nxge_use_default_dma_config: " 2378 "p_cfgp 0x%llx max_rdcs %d max_grpids %d default_grpid %d", 2379 p_cfgp, p_cfgp->max_rdcs, p_cfgp->max_grpids, 2380 p_cfgp->def_mac_rxdma_grpid)); 2381 2382 NXGE_DEBUG_MSG((nxgep, CFG_CTL, "==> nxge_use_cfg_dma_config: " 2383 "p_cfgp 0x%016llx start_ldg %d nxgep->max_ldgs %d " 2384 "def_mac_rxdma_grpid %d", 2385 p_cfgp, p_cfgp->start_ldg, p_cfgp->max_ldgs, 2386 p_cfgp->def_mac_rxdma_grpid)); 2387 2388 nxgep->intr_timeout = NXGE_RDC_RCR_TIMEOUT; 2389 prop = param_arr[param_rxdma_intr_time].fcode_name; 2390 2391 if (ddi_prop_lookup_int_array(DDI_DEV_T_ANY, dip, 0, prop, 2392 &prop_val, &prop_len) == DDI_PROP_SUCCESS) { 2393 if ((prop_len > 0) && (prop_len <= p_cfgp->max_rdcs)) { 2394 nxgep->intr_timeout = prop_val[0]; 2395 (void) ddi_prop_update_int_array(DDI_DEV_T_NONE, 2396 nxgep->dip, prop, prop_val, prop_len); 2397 } 2398 ddi_prop_free(prop_val); 2399 } 2400 2401 nxgep->intr_threshold = NXGE_RDC_RCR_THRESHOLD; 2402 prop = param_arr[param_rxdma_intr_pkts].fcode_name; 2403 2404 if (ddi_prop_lookup_int_array(DDI_DEV_T_ANY, dip, 0, prop, 2405 &prop_val, &prop_len) == DDI_PROP_SUCCESS) { 2406 if ((prop_len > 0) && (prop_len <= p_cfgp->max_rdcs)) { 2407 nxgep->intr_threshold = prop_val[0]; 2408 (void) ddi_prop_update_int_array(DDI_DEV_T_NONE, 2409 nxgep->dip, prop, prop_val, prop_len); 2410 } 2411 ddi_prop_free(prop_val); 2412 } 2413 nxge_set_hw_dma_config(nxgep); 2414 2415 NXGE_DEBUG_MSG((nxgep, CFG_CTL, "<== nxge_use_cfg_dma_config: " 2416 "sTDC[%d] nTDC[%d] sRDC[%d] nRDC[%d]", 2417 p_cfgp->tdc.start, p_cfgp->tdc.count, 2418 p_cfgp->start_rdc, p_cfgp->max_rdcs)); 2419 2420 nxge_use_cfg_dma_config_exit: 2421 NXGE_DEBUG_MSG((nxgep, CFG_CTL, "<== nxge_use_cfg_dma_config")); 2422 } 2423 2424 void 2425 nxge_get_logical_props(p_nxge_t nxgep) 2426 { 2427 nxge_dma_pt_cfg_t *port = &nxgep->pt_config; 2428 nxge_hw_pt_cfg_t *hardware; 2429 nxge_rdc_grp_t *group; 2430 2431 (void) memset(port, 0, sizeof (*port)); 2432 2433 port->mac_port = nxgep->function_num; /* := function number */ 2434 2435 /* 2436 * alloc_buf_size: 2437 * dead variables. 2438 */ 2439 port->rbr_size = nxge_rbr_size; 2440 port->rcr_size = nxge_rcr_size; 2441 2442 port->tx_dma_map = 0; /* Transmit DMA channel bit map */ 2443 2444 nxge_set_rdc_intr_property(nxgep); 2445 2446 port->rcr_full_header = NXGE_RCR_FULL_HEADER; 2447 port->rx_drr_weight = PT_DRR_WT_DEFAULT_10G; 2448 2449 /* ----------------------------------------------------- */ 2450 hardware = &port->hw_config; 2451 2452 (void) memset(hardware, 0, sizeof (*hardware)); 2453 2454 /* 2455 * partition_id, read_write_mode: 2456 * dead variables. 2457 */ 2458 2459 /* 2460 * drr_wt, rx_full_header, *_ldg?, start_mac_entry, 2461 * mac_pref, def_mac_rxdma_grpid, start_vlan, max_vlans, 2462 * start_ldgs, max_ldgs, max_ldvs, 2463 * vlan_pref, def_vlan_rxdma_grpid are meaningful only 2464 * in the service domain. 2465 */ 2466 2467 group = &port->rdc_grps[0]; 2468 2469 group->flag = B_TRUE; /* configured */ 2470 group->config_method = RDC_TABLE_ENTRY_METHOD_REP; 2471 group->port = NXGE_GET_PORT_NUM(nxgep->function_num); 2472 2473 /* HIO futures: this is still an open question. */ 2474 hardware->max_macs = 1; 2475 } 2476 2477 static void 2478 nxge_use_cfg_vlan_class_config(p_nxge_t nxgep) 2479 { 2480 uint_t vlan_cnt; 2481 int *vlan_cfg_val; 2482 int status; 2483 p_nxge_param_t param_arr; 2484 char *prop; 2485 2486 NXGE_DEBUG_MSG((nxgep, CFG_CTL, " ==> nxge_use_cfg_vlan_config")); 2487 param_arr = nxgep->param_arr; 2488 prop = param_arr[param_vlan_2rdc_grp].fcode_name; 2489 2490 status = ddi_prop_lookup_int_array(DDI_DEV_T_ANY, nxgep->dip, 0, prop, 2491 &vlan_cfg_val, &vlan_cnt); 2492 if (status == DDI_PROP_SUCCESS) { 2493 status = ddi_prop_update_int_array(DDI_DEV_T_NONE, 2494 nxgep->dip, prop, vlan_cfg_val, vlan_cnt); 2495 ddi_prop_free(vlan_cfg_val); 2496 } 2497 nxge_set_hw_vlan_class_config(nxgep); 2498 NXGE_DEBUG_MSG((nxgep, CFG_CTL, " <== nxge_use_cfg_vlan_config")); 2499 } 2500 2501 static void 2502 nxge_use_cfg_mac_class_config(p_nxge_t nxgep) 2503 { 2504 p_nxge_dma_pt_cfg_t p_dma_cfgp; 2505 p_nxge_hw_pt_cfg_t p_cfgp; 2506 uint_t mac_cnt; 2507 int *mac_cfg_val; 2508 int status; 2509 p_nxge_param_t param_arr; 2510 char *prop; 2511 2512 NXGE_DEBUG_MSG((nxgep, CFG_CTL, "==> nxge_use_cfg_mac_class_config")); 2513 p_dma_cfgp = (p_nxge_dma_pt_cfg_t)&nxgep->pt_config; 2514 p_cfgp = (p_nxge_hw_pt_cfg_t)&p_dma_cfgp->hw_config; 2515 p_cfgp->start_mac_entry = 0; 2516 param_arr = nxgep->param_arr; 2517 prop = param_arr[param_mac_2rdc_grp].fcode_name; 2518 2519 switch (nxgep->function_num) { 2520 case 0: 2521 case 1: 2522 /* 10G ports */ 2523 p_cfgp->max_macs = NXGE_MAX_MACS_XMACS; 2524 break; 2525 case 2: 2526 case 3: 2527 /* 1G ports */ 2528 default: 2529 p_cfgp->max_macs = NXGE_MAX_MACS_BMACS; 2530 break; 2531 } 2532 2533 p_cfgp->mac_pref = 1; 2534 NXGE_DEBUG_MSG((nxgep, OBP_CTL, 2535 "== nxge_use_cfg_mac_class_config: " 2536 " mac_pref bit set def_mac_rxdma_grpid %d", 2537 p_cfgp->def_mac_rxdma_grpid)); 2538 2539 status = ddi_prop_lookup_int_array(DDI_DEV_T_ANY, nxgep->dip, 0, prop, 2540 &mac_cfg_val, &mac_cnt); 2541 if (status == DDI_PROP_SUCCESS) { 2542 if (mac_cnt <= p_cfgp->max_macs) 2543 status = ddi_prop_update_int_array(DDI_DEV_T_NONE, 2544 nxgep->dip, prop, mac_cfg_val, mac_cnt); 2545 ddi_prop_free(mac_cfg_val); 2546 } 2547 nxge_set_hw_mac_class_config(nxgep); 2548 NXGE_DEBUG_MSG((nxgep, CFG_CTL, " <== nxge_use_cfg_mac_class_config")); 2549 } 2550 2551 static void 2552 nxge_use_cfg_class_config(p_nxge_t nxgep) 2553 { 2554 nxge_set_hw_class_config(nxgep); 2555 } 2556 2557 static void 2558 nxge_set_rdc_intr_property(p_nxge_t nxgep) 2559 { 2560 int i; 2561 p_nxge_dma_pt_cfg_t p_dma_cfgp; 2562 2563 NXGE_DEBUG_MSG((nxgep, CFG_CTL, " ==> nxge_set_rdc_intr_property")); 2564 p_dma_cfgp = (p_nxge_dma_pt_cfg_t)&nxgep->pt_config; 2565 2566 for (i = 0; i < NXGE_MAX_RDCS; i++) { 2567 p_dma_cfgp->rcr_timeout[i] = nxgep->intr_timeout; 2568 p_dma_cfgp->rcr_threshold[i] = nxgep->intr_threshold; 2569 } 2570 2571 NXGE_DEBUG_MSG((nxgep, CFG_CTL, " <== nxge_set_rdc_intr_property")); 2572 } 2573 2574 static void 2575 nxge_set_hw_dma_config(p_nxge_t nxgep) 2576 { 2577 int i, j, ngrps, bitmap, end, st_rdc; 2578 p_nxge_dma_pt_cfg_t p_dma_cfgp; 2579 p_nxge_hw_pt_cfg_t p_cfgp; 2580 p_nxge_rdc_grp_t rdc_grp_p; 2581 p_nxge_tdc_grp_t tdc_grp_p; 2582 nxge_grp_t *group; 2583 uint8_t nrdcs; 2584 dc_map_t map = 0; 2585 2586 NXGE_DEBUG_MSG((nxgep, CFG_CTL, "==> nxge_set_hw_dma_config")); 2587 2588 p_dma_cfgp = (p_nxge_dma_pt_cfg_t)&nxgep->pt_config; 2589 p_cfgp = (p_nxge_hw_pt_cfg_t)&p_dma_cfgp->hw_config; 2590 2591 switch (nxgep->niu_type) { 2592 case NEPTUNE_4_1GC: 2593 case NEPTUNE_2_10GF_2_1GC: 2594 case NEPTUNE_1_10GF_3_1GC: 2595 case NEPTUNE_1_1GC_1_10GF_2_1GC: 2596 case NEPTUNE_2_10GF_2_1GRF: 2597 default: 2598 ngrps = 2; 2599 break; 2600 case NEPTUNE_2_10GF: 2601 case NEPTUNE_2_1GRF: 2602 case N2_NIU: 2603 ngrps = 4; 2604 break; 2605 } 2606 2607 /* 2608 * Setup TDC groups 2609 */ 2610 bitmap = 0; 2611 end = p_cfgp->tdc.start + p_cfgp->tdc.owned; 2612 for (i = p_cfgp->tdc.start; i < end; i++) { 2613 bitmap |= (1 << i); 2614 } 2615 2616 nxgep->tx_set.owned.map |= bitmap; /* Owned, & not shared. */ 2617 nxgep->tx_set.owned.count = p_cfgp->tdc.owned; 2618 p_dma_cfgp->tx_dma_map = bitmap; 2619 2620 for (i = 0; i < ngrps; i++) { 2621 group = (nxge_grp_t *)nxge_grp_add(nxgep, 2622 NXGE_TRANSMIT_GROUP); 2623 tdc_grp_p = &p_dma_cfgp->tdc_grps[ 2624 p_cfgp->def_mac_txdma_grpid + i]; 2625 if (i == 0) 2626 tdc_grp_p->map = bitmap; 2627 else 2628 tdc_grp_p->map = 0; 2629 /* no ring is associated with a group initially */ 2630 tdc_grp_p->start_tdc = 0; 2631 tdc_grp_p->max_tdcs = 0; 2632 tdc_grp_p->grp_index = group->index; 2633 } 2634 2635 /* 2636 * Setup RDC groups 2637 */ 2638 st_rdc = p_cfgp->start_rdc; 2639 for (i = 0; i < ngrps; i++) { 2640 /* 2641 * All rings are associated with the default group initially 2642 */ 2643 if (i == 0) { 2644 /* default group */ 2645 switch (nxgep->niu_type) { 2646 case NEPTUNE_4_1GC: 2647 nrdcs = rx_4_1G[nxgep->function_num]; 2648 break; 2649 case N2_NIU: 2650 case NEPTUNE_2_10GF: 2651 nrdcs = rx_2_10G[nxgep->function_num]; 2652 break; 2653 case NEPTUNE_2_10GF_2_1GC: 2654 nrdcs = rx_2_10G_2_1G[nxgep->function_num]; 2655 break; 2656 case NEPTUNE_1_10GF_3_1GC: 2657 nrdcs = rx_1_10G_3_1G[nxgep->function_num]; 2658 break; 2659 case NEPTUNE_1_1GC_1_10GF_2_1GC: 2660 nrdcs = rx_1_1G_1_10G_2_1G[nxgep->function_num]; 2661 break; 2662 default: 2663 switch (nxgep->platform_type) { 2664 case P_NEPTUNE_ALONSO: 2665 nrdcs = 2666 rx_2_10G_2_1G[nxgep->function_num]; 2667 break; 2668 default: 2669 nrdcs = rx_4_1G[nxgep->function_num]; 2670 break; 2671 } 2672 break; 2673 } 2674 2675 if (p_cfgp->max_rdcs < nrdcs) 2676 nrdcs = p_cfgp->max_rdcs; 2677 } else { 2678 nrdcs = 0; 2679 } 2680 2681 rdc_grp_p = &p_dma_cfgp->rdc_grps[ 2682 p_cfgp->def_mac_rxdma_grpid + i]; 2683 rdc_grp_p->start_rdc = st_rdc; 2684 rdc_grp_p->max_rdcs = nrdcs; 2685 rdc_grp_p->def_rdc = rdc_grp_p->start_rdc; 2686 2687 /* default to: 0, 1, 2, 3, ...., 0, 1, 2, 3.... */ 2688 if (nrdcs != 0) { 2689 for (j = 0; j < nrdcs; j++) { 2690 map |= (1 << j); 2691 } 2692 map <<= rdc_grp_p->start_rdc; 2693 } else 2694 map = 0; 2695 rdc_grp_p->map = map; 2696 2697 nxgep->rx_set.owned.map |= map; /* Owned, & not shared. */ 2698 nxgep->rx_set.owned.count = nrdcs; 2699 2700 group = (nxge_grp_t *)nxge_grp_add(nxgep, NXGE_RECEIVE_GROUP); 2701 2702 rdc_grp_p->config_method = RDC_TABLE_ENTRY_METHOD_SEQ; 2703 rdc_grp_p->flag = B_TRUE; /* This group has been configured. */ 2704 rdc_grp_p->grp_index = group->index; 2705 rdc_grp_p->port = NXGE_GET_PORT_NUM(nxgep->function_num); 2706 2707 map = 0; 2708 } 2709 2710 2711 /* default RDC */ 2712 p_cfgp->def_rdc = p_cfgp->start_rdc; 2713 nxgep->def_rdc = p_cfgp->start_rdc; 2714 2715 /* full 18 byte header ? */ 2716 p_dma_cfgp->rcr_full_header = NXGE_RCR_FULL_HEADER; 2717 p_dma_cfgp->rx_drr_weight = PT_DRR_WT_DEFAULT_10G; 2718 if (nxgep->function_num > 1) 2719 p_dma_cfgp->rx_drr_weight = PT_DRR_WT_DEFAULT_1G; 2720 p_dma_cfgp->rbr_size = nxge_rbr_size; 2721 p_dma_cfgp->rcr_size = nxge_rcr_size; 2722 2723 nxge_set_rdc_intr_property(nxgep); 2724 NXGE_DEBUG_MSG((nxgep, CFG_CTL, " <== nxge_set_hw_dma_config")); 2725 } 2726 2727 boolean_t 2728 nxge_check_rxdma_port_member(p_nxge_t nxgep, uint8_t rdc) 2729 { 2730 p_nxge_dma_pt_cfg_t p_dma_cfgp; 2731 p_nxge_hw_pt_cfg_t p_cfgp; 2732 int status = B_TRUE; 2733 2734 NXGE_DEBUG_MSG((nxgep, CFG2_CTL, "==> nxge_check_rxdma_port_member")); 2735 2736 p_dma_cfgp = (p_nxge_dma_pt_cfg_t)&nxgep->pt_config; 2737 p_cfgp = (p_nxge_hw_pt_cfg_t)&p_dma_cfgp->hw_config; 2738 2739 /* Receive DMA Channels */ 2740 if (rdc < p_cfgp->max_rdcs) 2741 status = B_TRUE; 2742 NXGE_DEBUG_MSG((nxgep, CFG2_CTL, " <== nxge_check_rxdma_port_member")); 2743 return (status); 2744 } 2745 2746 boolean_t 2747 nxge_check_txdma_port_member(p_nxge_t nxgep, uint8_t tdc) 2748 { 2749 int status = B_FALSE; 2750 2751 NXGE_DEBUG_MSG((nxgep, CFG2_CTL, "==> nxge_check_txdma_port_member")); 2752 2753 if (tdc >= nxgep->pt_config.hw_config.tdc.start && 2754 tdc < nxgep->pt_config.hw_config.tdc.count) 2755 status = B_TRUE; 2756 2757 NXGE_DEBUG_MSG((nxgep, CFG2_CTL, " <== nxge_check_txdma_port_member")); 2758 return (status); 2759 } 2760 2761 boolean_t 2762 nxge_check_rxdma_rdcgrp_member(p_nxge_t nxgep, uint8_t rdc_grp, uint8_t rdc) 2763 { 2764 p_nxge_dma_pt_cfg_t p_dma_cfgp; 2765 int status = B_TRUE; 2766 p_nxge_rdc_grp_t rdc_grp_p; 2767 2768 NXGE_DEBUG_MSG((nxgep, CFG2_CTL, 2769 " ==> nxge_check_rxdma_rdcgrp_member")); 2770 NXGE_DEBUG_MSG((nxgep, CFG2_CTL, " nxge_check_rxdma_rdcgrp_member" 2771 " rdc %d group %d", rdc, rdc_grp)); 2772 p_dma_cfgp = (p_nxge_dma_pt_cfg_t)&nxgep->pt_config; 2773 2774 rdc_grp_p = &p_dma_cfgp->rdc_grps[rdc_grp]; 2775 NXGE_DEBUG_MSG((nxgep, CFG2_CTL, " max %d ", rdc_grp_p->max_rdcs)); 2776 if (rdc >= rdc_grp_p->max_rdcs) { 2777 status = B_FALSE; 2778 } 2779 NXGE_DEBUG_MSG((nxgep, CFG2_CTL, 2780 " <== nxge_check_rxdma_rdcgrp_member")); 2781 return (status); 2782 } 2783 2784 boolean_t 2785 nxge_check_rdcgrp_port_member(p_nxge_t nxgep, uint8_t rdc_grp) 2786 { 2787 p_nxge_dma_pt_cfg_t p_dma_cfgp; 2788 p_nxge_hw_pt_cfg_t p_cfgp; 2789 int status = B_TRUE; 2790 2791 NXGE_DEBUG_MSG((nxgep, CFG2_CTL, "==> nxge_check_rdcgrp_port_member")); 2792 2793 p_dma_cfgp = (p_nxge_dma_pt_cfg_t)&nxgep->pt_config; 2794 p_cfgp = (p_nxge_hw_pt_cfg_t)&p_dma_cfgp->hw_config; 2795 2796 if (rdc_grp >= p_cfgp->max_rdc_grpids) 2797 status = B_FALSE; 2798 NXGE_DEBUG_MSG((nxgep, CFG2_CTL, " <== nxge_check_rdcgrp_port_member")); 2799 return (status); 2800 } 2801 2802 static void 2803 nxge_set_hw_vlan_class_config(p_nxge_t nxgep) 2804 { 2805 int i; 2806 p_nxge_dma_pt_cfg_t p_dma_cfgp; 2807 p_nxge_hw_pt_cfg_t p_cfgp; 2808 p_nxge_param_t param_arr; 2809 uint_t vlan_cnt; 2810 int *vlan_cfg_val; 2811 nxge_param_map_t *vmap; 2812 char *prop; 2813 p_nxge_class_pt_cfg_t p_class_cfgp; 2814 uint32_t good_cfg[32]; 2815 int good_count = 0; 2816 nxge_mv_cfg_t *vlan_tbl; 2817 2818 NXGE_DEBUG_MSG((nxgep, CFG_CTL, " ==> nxge_set_hw_vlan_config")); 2819 p_dma_cfgp = (p_nxge_dma_pt_cfg_t)&nxgep->pt_config; 2820 p_cfgp = (p_nxge_hw_pt_cfg_t)&p_dma_cfgp->hw_config; 2821 p_class_cfgp = (p_nxge_class_pt_cfg_t)&nxgep->class_config; 2822 2823 param_arr = nxgep->param_arr; 2824 prop = param_arr[param_vlan_2rdc_grp].fcode_name; 2825 2826 /* 2827 * By default, VLAN to RDC group mapping is disabled Need to read HW or 2828 * .conf properties to find out if mapping is required 2829 * 2830 * Format 2831 * 2832 * uint32_t array, each array entry specifying the VLAN id and the 2833 * mapping 2834 * 2835 * bit[30] = add bit[29] = remove bit[28] = preference bits[23-16] = 2836 * rdcgrp bits[15-0] = VLAN ID ( ) 2837 */ 2838 2839 for (i = 0; i < NXGE_MAX_VLANS; i++) { 2840 p_class_cfgp->vlan_tbl[i].flag = 0; 2841 } 2842 2843 vlan_tbl = (nxge_mv_cfg_t *)&p_class_cfgp->vlan_tbl[0]; 2844 if (ddi_prop_lookup_int_array(DDI_DEV_T_ANY, nxgep->dip, 0, prop, 2845 &vlan_cfg_val, &vlan_cnt) == DDI_PROP_SUCCESS) { 2846 for (i = 0; i < vlan_cnt; i++) { 2847 vmap = (nxge_param_map_t *)&vlan_cfg_val[i]; 2848 if ((vmap->param_id) && 2849 (vmap->param_id < NXGE_MAX_VLANS) && 2850 (vmap->map_to < 2851 p_cfgp->max_rdc_grpids) && 2852 (vmap->map_to >= (uint8_t)0)) { 2853 NXGE_DEBUG_MSG((nxgep, CFG2_CTL, 2854 " nxge_vlan_config mapping" 2855 " id %d grp %d", 2856 vmap->param_id, vmap->map_to)); 2857 good_cfg[good_count] = vlan_cfg_val[i]; 2858 if (vlan_tbl[vmap->param_id].flag == 0) 2859 good_count++; 2860 vlan_tbl[vmap->param_id].flag = 1; 2861 vlan_tbl[vmap->param_id].rdctbl = 2862 vmap->map_to + p_cfgp->def_mac_rxdma_grpid; 2863 vlan_tbl[vmap->param_id].mpr_npr = vmap->pref; 2864 } 2865 } 2866 ddi_prop_free(vlan_cfg_val); 2867 if (good_count != vlan_cnt) { 2868 (void) ddi_prop_update_int_array(DDI_DEV_T_NONE, 2869 nxgep->dip, prop, (int *)good_cfg, good_count); 2870 } 2871 } 2872 NXGE_DEBUG_MSG((nxgep, CFG_CTL, "<== nxge_set_hw_vlan_config")); 2873 } 2874 2875 static void 2876 nxge_set_hw_mac_class_config(p_nxge_t nxgep) 2877 { 2878 int i; 2879 p_nxge_dma_pt_cfg_t p_dma_cfgp; 2880 p_nxge_hw_pt_cfg_t p_cfgp; 2881 p_nxge_param_t param_arr; 2882 uint_t mac_cnt; 2883 int *mac_cfg_val; 2884 nxge_param_map_t *mac_map; 2885 char *prop; 2886 p_nxge_class_pt_cfg_t p_class_cfgp; 2887 int good_count = 0; 2888 int good_cfg[NXGE_MAX_MACS]; 2889 nxge_mv_cfg_t *mac_host_info; 2890 2891 NXGE_DEBUG_MSG((nxgep, CFG_CTL, "==> nxge_set_hw_mac_config")); 2892 2893 p_dma_cfgp = (p_nxge_dma_pt_cfg_t)&nxgep->pt_config; 2894 p_cfgp = (p_nxge_hw_pt_cfg_t)&p_dma_cfgp->hw_config; 2895 p_class_cfgp = (p_nxge_class_pt_cfg_t)&nxgep->class_config; 2896 mac_host_info = (nxge_mv_cfg_t *)&p_class_cfgp->mac_host_info[0]; 2897 2898 param_arr = nxgep->param_arr; 2899 prop = param_arr[param_mac_2rdc_grp].fcode_name; 2900 2901 for (i = 0; i < NXGE_MAX_MACS; i++) { 2902 p_class_cfgp->mac_host_info[i].flag = 0; 2903 p_class_cfgp->mac_host_info[i].rdctbl = 2904 p_cfgp->def_mac_rxdma_grpid; 2905 } 2906 2907 if (ddi_prop_lookup_int_array(DDI_DEV_T_ANY, nxgep->dip, 0, prop, 2908 &mac_cfg_val, &mac_cnt) == DDI_PROP_SUCCESS) { 2909 for (i = 0; i < mac_cnt; i++) { 2910 mac_map = (nxge_param_map_t *)&mac_cfg_val[i]; 2911 if ((mac_map->param_id < p_cfgp->max_macs) && 2912 (mac_map->map_to < 2913 p_cfgp->max_rdc_grpids) && 2914 (mac_map->map_to >= (uint8_t)0)) { 2915 NXGE_DEBUG_MSG((nxgep, CFG2_CTL, 2916 " nxge_mac_config mapping" 2917 " id %d grp %d", 2918 mac_map->param_id, mac_map->map_to)); 2919 mac_host_info[mac_map->param_id].mpr_npr = 2920 p_cfgp->mac_pref; 2921 mac_host_info[mac_map->param_id].rdctbl = 2922 mac_map->map_to + 2923 p_cfgp->def_mac_rxdma_grpid; 2924 good_cfg[good_count] = mac_cfg_val[i]; 2925 if (mac_host_info[mac_map->param_id].flag == 0) 2926 good_count++; 2927 mac_host_info[mac_map->param_id].flag = 1; 2928 } 2929 } 2930 ddi_prop_free(mac_cfg_val); 2931 if (good_count != mac_cnt) { 2932 (void) ddi_prop_update_int_array(DDI_DEV_T_NONE, 2933 nxgep->dip, prop, good_cfg, good_count); 2934 } 2935 } 2936 NXGE_DEBUG_MSG((nxgep, CFG_CTL, "<== nxge_set_hw_mac_config")); 2937 } 2938 2939 static void 2940 nxge_set_hw_class_config(p_nxge_t nxgep) 2941 { 2942 int i; 2943 p_nxge_param_t param_arr; 2944 int *int_prop_val; 2945 uint32_t cfg_value; 2946 char *prop; 2947 p_nxge_class_pt_cfg_t p_class_cfgp; 2948 int start_prop, end_prop; 2949 uint_t prop_cnt; 2950 int start_class, j = 0; 2951 2952 NXGE_DEBUG_MSG((nxgep, CFG_CTL, " ==> nxge_set_hw_class_config")); 2953 2954 p_class_cfgp = (p_nxge_class_pt_cfg_t)&nxgep->class_config; 2955 param_arr = nxgep->param_arr; 2956 start_prop = param_class_opt_ipv4_tcp; 2957 end_prop = param_class_opt_ipv6_sctp; 2958 start_class = TCAM_CLASS_TCP_IPV4; 2959 2960 for (i = start_prop, j = 0; i <= end_prop; i++, j++) { 2961 prop = param_arr[i].fcode_name; 2962 if (ddi_prop_lookup_int_array(DDI_DEV_T_ANY, nxgep->dip, 2963 0, prop, &int_prop_val, 2964 &prop_cnt) == DDI_PROP_SUCCESS) { 2965 cfg_value = (uint32_t)*int_prop_val; 2966 ddi_prop_free(int_prop_val); 2967 } else { 2968 cfg_value = (uint32_t)param_arr[i].value; 2969 } 2970 p_class_cfgp->class_cfg[start_class + j] = cfg_value; 2971 } 2972 2973 prop = param_arr[param_h1_init_value].fcode_name; 2974 2975 if (ddi_prop_lookup_int_array(DDI_DEV_T_ANY, nxgep->dip, 0, prop, 2976 &int_prop_val, &prop_cnt) == DDI_PROP_SUCCESS) { 2977 cfg_value = (uint32_t)*int_prop_val; 2978 ddi_prop_free(int_prop_val); 2979 } else { 2980 cfg_value = (uint32_t)param_arr[param_h1_init_value].value; 2981 } 2982 2983 p_class_cfgp->init_h1 = (uint32_t)cfg_value; 2984 prop = param_arr[param_h2_init_value].fcode_name; 2985 2986 if (ddi_prop_lookup_int_array(DDI_DEV_T_ANY, nxgep->dip, 0, prop, 2987 &int_prop_val, &prop_cnt) == DDI_PROP_SUCCESS) { 2988 cfg_value = (uint32_t)*int_prop_val; 2989 ddi_prop_free(int_prop_val); 2990 } else { 2991 cfg_value = (uint32_t)param_arr[param_h2_init_value].value; 2992 } 2993 2994 p_class_cfgp->init_h2 = (uint16_t)cfg_value; 2995 NXGE_DEBUG_MSG((nxgep, CFG_CTL, " <== nxge_set_hw_class_config")); 2996 } 2997 2998 nxge_status_t 2999 nxge_ldgv_init_n2(p_nxge_t nxgep, int *navail_p, int *nrequired_p) 3000 { 3001 int i, maxldvs, maxldgs, nldvs; 3002 int ldv, endldg; 3003 uint8_t func; 3004 uint8_t channel; 3005 uint8_t chn_start; 3006 boolean_t own_sys_err = B_FALSE, own_fzc = B_FALSE; 3007 p_nxge_dma_pt_cfg_t p_dma_cfgp; 3008 p_nxge_hw_pt_cfg_t p_cfgp; 3009 p_nxge_ldgv_t ldgvp; 3010 p_nxge_ldg_t ldgp, ptr; 3011 p_nxge_ldv_t ldvp, sysldvp; 3012 nxge_status_t status = NXGE_OK; 3013 nxge_grp_set_t *set; 3014 3015 NXGE_DEBUG_MSG((nxgep, INT_CTL, "==> nxge_ldgv_init_n2")); 3016 if (!*navail_p) { 3017 *nrequired_p = 0; 3018 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 3019 "<== nxge_ldgv_init:no avail")); 3020 return (NXGE_ERROR); 3021 } 3022 /* 3023 * N2/NIU: one logical device owns one logical group. and each 3024 * device/group will be assigned one vector by Hypervisor. 3025 */ 3026 p_dma_cfgp = (p_nxge_dma_pt_cfg_t)&nxgep->pt_config; 3027 p_cfgp = (p_nxge_hw_pt_cfg_t)&p_dma_cfgp->hw_config; 3028 maxldgs = p_cfgp->max_ldgs; 3029 if (!maxldgs) { 3030 /* No devices configured. */ 3031 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, "<== nxge_ldgv_init_n2: " 3032 "no logical groups configured.")); 3033 return (NXGE_ERROR); 3034 } else { 3035 maxldvs = maxldgs + 1; 3036 } 3037 3038 /* 3039 * If function zero instance, it needs to handle the system and MIF 3040 * error interrupts. MIF interrupt may not be needed for N2/NIU. 3041 */ 3042 func = nxgep->function_num; 3043 if (func == 0) { 3044 own_sys_err = B_TRUE; 3045 if (!p_cfgp->ser_ldvid) { 3046 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 3047 "nxge_ldgv_init_n2: func 0, ERR ID not set!")); 3048 } 3049 /* MIF interrupt */ 3050 if (!p_cfgp->mif_ldvid) { 3051 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 3052 "nxge_ldgv_init_n2: func 0, MIF ID not set!")); 3053 } 3054 } 3055 3056 /* 3057 * Assume single partition, each function owns mac. 3058 */ 3059 if (!nxge_use_partition) 3060 own_fzc = B_TRUE; 3061 3062 ldgvp = nxgep->ldgvp; 3063 if (ldgvp == NULL) { 3064 ldgvp = KMEM_ZALLOC(sizeof (nxge_ldgv_t), KM_SLEEP); 3065 nxgep->ldgvp = ldgvp; 3066 ldgvp->maxldgs = (uint8_t)maxldgs; 3067 ldgvp->maxldvs = (uint8_t)maxldvs; 3068 ldgp = ldgvp->ldgp = KMEM_ZALLOC( 3069 sizeof (nxge_ldg_t) * maxldgs, KM_SLEEP); 3070 ldvp = ldgvp->ldvp = KMEM_ZALLOC( 3071 sizeof (nxge_ldv_t) * maxldvs, KM_SLEEP); 3072 } else { 3073 ldgp = ldgvp->ldgp; 3074 ldvp = ldgvp->ldvp; 3075 } 3076 3077 ldgvp->ndma_ldvs = p_cfgp->tdc.owned + p_cfgp->max_rdcs; 3078 ldgvp->tmres = NXGE_TIMER_RESO; 3079 3080 NXGE_DEBUG_MSG((nxgep, INT_CTL, 3081 "==> nxge_ldgv_init_n2: maxldvs %d maxldgs %d", 3082 maxldvs, maxldgs)); 3083 3084 /* logical start_ldg is ldv */ 3085 ptr = ldgp; 3086 for (i = 0; i < maxldgs; i++) { 3087 ptr->func = func; 3088 ptr->arm = B_TRUE; 3089 ptr->vldg_index = (uint8_t)i; 3090 ptr->ldg_timer = NXGE_TIMER_LDG; 3091 ptr->ldg = p_cfgp->ldg[i]; 3092 ptr->sys_intr_handler = nxge_intr; 3093 ptr->nldvs = 0; 3094 ptr->ldvp = NULL; 3095 ptr->nxgep = nxgep; 3096 NXGE_DEBUG_MSG((nxgep, INT_CTL, 3097 "==> nxge_ldgv_init_n2: maxldvs %d maxldgs %d " 3098 "ldg %d ldgptr $%p", 3099 maxldvs, maxldgs, ptr->ldg, ptr)); 3100 ptr++; 3101 } 3102 3103 endldg = NXGE_INT_MAX_LDG; 3104 nldvs = 0; 3105 ldgvp->nldvs = 0; 3106 ldgp->ldvp = NULL; 3107 *nrequired_p = 0; 3108 3109 /* 3110 * logical device group table is organized in the following order (same 3111 * as what interrupt property has). function 0: owns MAC, MIF, error, 3112 * rx, tx. function 1: owns MAC, rx, tx. 3113 */ 3114 3115 if (own_fzc && p_cfgp->mac_ldvid) { 3116 /* Each function should own MAC interrupt */ 3117 ldv = p_cfgp->mac_ldvid; 3118 ldvp->ldv = (uint8_t)ldv; 3119 ldvp->is_mac = B_TRUE; 3120 ldvp->ldv_intr_handler = nxge_mac_intr; 3121 ldvp->ldv_ldf_masks = 0; 3122 ldvp->nxgep = nxgep; 3123 NXGE_DEBUG_MSG((nxgep, INT_CTL, 3124 "==> nxge_ldgv_init_n2(mac): maxldvs %d ldv %d " 3125 "ldg %d ldgptr $%p ldvptr $%p", 3126 maxldvs, ldv, ldgp->ldg, ldgp, ldvp)); 3127 nxge_ldgv_setup(&ldgp, &ldvp, ldv, endldg, nrequired_p); 3128 nldvs++; 3129 } 3130 3131 if (own_fzc && p_cfgp->mif_ldvid) { 3132 ldv = p_cfgp->mif_ldvid; 3133 ldvp->ldv = (uint8_t)ldv; 3134 ldvp->is_mif = B_TRUE; 3135 ldvp->ldv_intr_handler = nxge_mif_intr; 3136 ldvp->ldv_ldf_masks = 0; 3137 ldvp->nxgep = nxgep; 3138 NXGE_DEBUG_MSG((nxgep, INT_CTL, 3139 "==> nxge_ldgv_init_n2(mif): maxldvs %d ldv %d " 3140 "ldg %d ldgptr $%p ldvptr $%p", 3141 maxldvs, ldv, ldgp->ldg, ldgp, ldvp)); 3142 nxge_ldgv_setup(&ldgp, &ldvp, ldv, endldg, nrequired_p); 3143 nldvs++; 3144 } 3145 3146 /* 3147 * HW based syserr interrupt for port0, and SW based syserr interrupt 3148 * for port1 3149 */ 3150 if (own_sys_err && p_cfgp->ser_ldvid) { 3151 ldv = p_cfgp->ser_ldvid; 3152 /* 3153 * Unmask the system interrupt states. 3154 */ 3155 (void) nxge_fzc_sys_err_mask_set(nxgep, SYS_ERR_SMX_MASK | 3156 SYS_ERR_IPP_MASK | SYS_ERR_TXC_MASK | 3157 SYS_ERR_ZCP_MASK); 3158 3159 ldvp->use_timer = B_TRUE; 3160 ldvp->ldv = (uint8_t)ldv; 3161 ldvp->is_syserr = B_TRUE; 3162 ldvp->ldv_intr_handler = nxge_syserr_intr; 3163 ldvp->ldv_ldf_masks = 0; 3164 ldvp->nxgep = nxgep; 3165 ldgvp->ldvp_syserr = ldvp; 3166 3167 NXGE_DEBUG_MSG((nxgep, INT_CTL, 3168 "==> nxge_ldgv_init_n2(syserr): maxldvs %d ldv %d " 3169 "ldg %d ldgptr $%p ldvptr p%p", 3170 maxldvs, ldv, ldgp->ldg, ldgp, ldvp)); 3171 nxge_ldgv_setup(&ldgp, &ldvp, ldv, endldg, nrequired_p); 3172 nldvs++; 3173 } else { 3174 /* 3175 * SW based: allocate the ldv for the syserr since the vector 3176 * should not be consumed for port1 3177 */ 3178 sysldvp = KMEM_ZALLOC(sizeof (nxge_ldv_t), KM_SLEEP); 3179 sysldvp->use_timer = B_TRUE; 3180 sysldvp->ldv = NXGE_SYS_ERROR_LD; 3181 sysldvp->is_syserr = B_TRUE; 3182 sysldvp->ldv_intr_handler = nxge_syserr_intr; 3183 sysldvp->ldv_ldf_masks = 0; 3184 sysldvp->nxgep = nxgep; 3185 ldgvp->ldvp_syserr = sysldvp; 3186 ldgvp->ldvp_syserr_alloced = B_TRUE; 3187 } 3188 3189 3190 NXGE_DEBUG_MSG((nxgep, INT_CTL, "==> nxge_ldgv_init_n2: " 3191 "(before rx) func %d nldvs %d navail %d nrequired %d", 3192 func, nldvs, *navail_p, *nrequired_p)); 3193 3194 /* 3195 * Start with RDC to configure logical devices for each group. 3196 */ 3197 chn_start = p_cfgp->ldg_chn_start; 3198 set = &nxgep->rx_set; 3199 for (channel = 0; channel < NXGE_MAX_RDCS; channel++) { 3200 if ((1 << channel) & set->owned.map) { 3201 ldvp->is_rxdma = B_TRUE; 3202 ldvp->ldv = (uint8_t)channel + NXGE_RDMA_LD_START; 3203 ldvp->channel = channel; 3204 ldvp->vdma_index = (uint8_t)channel; 3205 ldvp->ldv_intr_handler = nxge_rx_intr; 3206 ldvp->ldv_ldf_masks = 0; 3207 ldvp->nxgep = nxgep; 3208 ldgp->ldg = p_cfgp->ldg[chn_start]; 3209 3210 NXGE_DEBUG_MSG((nxgep, INT_CTL, 3211 "==> nxge_ldgv_init_n2(rx%d): maxldvs %d ldv %d " 3212 "ldg %d ldgptr 0x%016llx ldvptr 0x%016llx", 3213 i, maxldvs, ldv, ldgp->ldg, ldgp, ldvp)); 3214 nxge_ldgv_setup(&ldgp, &ldvp, ldvp->ldv, 3215 endldg, nrequired_p); 3216 nldvs++; 3217 chn_start++; 3218 } 3219 } 3220 3221 NXGE_DEBUG_MSG((nxgep, INT_CTL, "==> nxge_ldgv_init_n2: " 3222 "func %d nldvs %d navail %d nrequired %d", 3223 func, nldvs, *navail_p, *nrequired_p)); 3224 3225 NXGE_DEBUG_MSG((nxgep, INT_CTL, "==> nxge_ldgv_init_n2: " 3226 "func %d nldvs %d navail %d nrequired %d ldgp 0x%llx " 3227 "ldvp 0x%llx", 3228 func, nldvs, *navail_p, *nrequired_p, ldgp, ldvp)); 3229 /* 3230 * Transmit DMA channels. 3231 */ 3232 chn_start = p_cfgp->ldg_chn_start + 8; 3233 set = &nxgep->tx_set; 3234 for (channel = 0; channel < NXGE_MAX_TDCS; channel++) { 3235 if ((1 << channel) & set->owned.map) { 3236 ldvp->is_txdma = B_TRUE; 3237 ldvp->ldv = (uint8_t)channel + NXGE_TDMA_LD_START; 3238 ldvp->channel = channel; 3239 ldvp->vdma_index = (uint8_t)channel; 3240 ldvp->ldv_intr_handler = nxge_tx_intr; 3241 ldvp->ldv_ldf_masks = 0; 3242 ldgp->ldg = p_cfgp->ldg[chn_start]; 3243 ldvp->nxgep = nxgep; 3244 NXGE_DEBUG_MSG((nxgep, INT_CTL, 3245 "==> nxge_ldgv_init_n2(tx%d): maxldvs %d ldv %d " 3246 "ldg %d ldgptr %p ldvptr %p", 3247 channel, maxldvs, ldv, ldgp->ldg, ldgp, ldvp)); 3248 nxge_ldgv_setup(&ldgp, &ldvp, ldvp->ldv, 3249 endldg, nrequired_p); 3250 nldvs++; 3251 chn_start++; 3252 } 3253 } 3254 3255 ldgvp->ldg_intrs = *nrequired_p; 3256 ldgvp->nldvs = (uint8_t)nldvs; 3257 3258 NXGE_DEBUG_MSG((nxgep, INT_CTL, "==> nxge_ldgv_init_n2: " 3259 "func %d nldvs %d maxgrps %d navail %d nrequired %d", 3260 func, nldvs, maxldgs, *navail_p, *nrequired_p)); 3261 3262 NXGE_DEBUG_MSG((nxgep, INT_CTL, "<== nxge_ldgv_init_n2")); 3263 return (status); 3264 } 3265 3266 /* 3267 * Interrupts related interface functions. 3268 */ 3269 3270 nxge_status_t 3271 nxge_ldgv_init(p_nxge_t nxgep, int *navail_p, int *nrequired_p) 3272 { 3273 int i, maxldvs, maxldgs, nldvs; 3274 int ldv, ldg, endldg, ngrps; 3275 uint8_t func; 3276 uint8_t channel; 3277 boolean_t own_sys_err = B_FALSE, own_fzc = B_FALSE; 3278 p_nxge_dma_pt_cfg_t p_dma_cfgp; 3279 p_nxge_hw_pt_cfg_t p_cfgp; 3280 p_nxge_ldgv_t ldgvp; 3281 p_nxge_ldg_t ldgp, ptr; 3282 p_nxge_ldv_t ldvp; 3283 nxge_grp_set_t *set; 3284 3285 nxge_status_t status = NXGE_OK; 3286 3287 NXGE_DEBUG_MSG((nxgep, INT_CTL, "==> nxge_ldgv_init")); 3288 if (!*navail_p) { 3289 *nrequired_p = 0; 3290 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 3291 "<== nxge_ldgv_init:no avail")); 3292 return (NXGE_ERROR); 3293 } 3294 p_dma_cfgp = (p_nxge_dma_pt_cfg_t)&nxgep->pt_config; 3295 p_cfgp = (p_nxge_hw_pt_cfg_t)&p_dma_cfgp->hw_config; 3296 3297 nldvs = p_cfgp->tdc.owned + p_cfgp->max_rdcs; 3298 3299 /* 3300 * If function zero instance, it needs to handle the system error 3301 * interrupts. 3302 */ 3303 func = nxgep->function_num; 3304 if (func == 0) { 3305 nldvs++; 3306 own_sys_err = B_TRUE; 3307 } else { 3308 /* use timer */ 3309 nldvs++; 3310 } 3311 3312 /* 3313 * Assume single partition, each function owns mac. 3314 */ 3315 if (!nxge_use_partition) { 3316 /* mac */ 3317 nldvs++; 3318 /* MIF */ 3319 nldvs++; 3320 own_fzc = B_TRUE; 3321 } 3322 maxldvs = nldvs; 3323 maxldgs = p_cfgp->max_ldgs; 3324 if (!maxldvs || !maxldgs) { 3325 /* No devices configured. */ 3326 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, "<== nxge_ldgv_init: " 3327 "no logical devices or groups configured.")); 3328 return (NXGE_ERROR); 3329 } 3330 ldgvp = nxgep->ldgvp; 3331 if (ldgvp == NULL) { 3332 ldgvp = KMEM_ZALLOC(sizeof (nxge_ldgv_t), KM_SLEEP); 3333 nxgep->ldgvp = ldgvp; 3334 ldgvp->maxldgs = (uint8_t)maxldgs; 3335 ldgvp->maxldvs = (uint8_t)maxldvs; 3336 ldgp = ldgvp->ldgp = KMEM_ZALLOC(sizeof (nxge_ldg_t) * maxldgs, 3337 KM_SLEEP); 3338 ldvp = ldgvp->ldvp = KMEM_ZALLOC(sizeof (nxge_ldv_t) * maxldvs, 3339 KM_SLEEP); 3340 } 3341 ldgvp->ndma_ldvs = p_cfgp->tdc.owned + p_cfgp->max_rdcs; 3342 ldgvp->tmres = NXGE_TIMER_RESO; 3343 3344 NXGE_DEBUG_MSG((nxgep, INT_CTL, 3345 "==> nxge_ldgv_init: maxldvs %d maxldgs %d nldvs %d", 3346 maxldvs, maxldgs, nldvs)); 3347 ldg = p_cfgp->start_ldg; 3348 ptr = ldgp; 3349 for (i = 0; i < maxldgs; i++) { 3350 ptr->func = func; 3351 ptr->arm = B_TRUE; 3352 ptr->vldg_index = (uint8_t)i; 3353 ptr->ldg_timer = NXGE_TIMER_LDG; 3354 ptr->ldg = ldg++; 3355 ptr->sys_intr_handler = nxge_intr; 3356 ptr->nldvs = 0; 3357 ptr->nxgep = nxgep; 3358 NXGE_DEBUG_MSG((nxgep, INT_CTL, 3359 "==> nxge_ldgv_init: maxldvs %d maxldgs %d ldg %d", 3360 maxldvs, maxldgs, ptr->ldg)); 3361 ptr++; 3362 } 3363 3364 ldg = p_cfgp->start_ldg; 3365 if (maxldgs > *navail_p) { 3366 ngrps = *navail_p; 3367 } else { 3368 ngrps = maxldgs; 3369 } 3370 endldg = ldg + ngrps; 3371 3372 /* 3373 * Receive DMA channels. 3374 */ 3375 nldvs = 0; 3376 ldgvp->nldvs = 0; 3377 ldgp->ldvp = NULL; 3378 *nrequired_p = 0; 3379 3380 /* 3381 * Start with RDC to configure logical devices for each group. 3382 */ 3383 set = &nxgep->rx_set; 3384 for (channel = 0; channel < NXGE_MAX_RDCS; channel++) { 3385 if ((1 << channel) & set->owned.map) { 3386 /* For now, <channel & <vdma_index> are the same. */ 3387 ldvp->is_rxdma = B_TRUE; 3388 ldvp->ldv = (uint8_t)channel + NXGE_RDMA_LD_START; 3389 ldvp->channel = channel; 3390 ldvp->vdma_index = (uint8_t)channel; 3391 ldvp->ldv_intr_handler = nxge_rx_intr; 3392 ldvp->ldv_ldf_masks = 0; 3393 ldvp->use_timer = B_FALSE; 3394 ldvp->nxgep = nxgep; 3395 nxge_ldgv_setup(&ldgp, &ldvp, ldvp->ldv, 3396 endldg, nrequired_p); 3397 nldvs++; 3398 } 3399 } 3400 3401 /* 3402 * Transmit DMA channels. 3403 */ 3404 set = &nxgep->tx_set; 3405 for (channel = 0; channel < NXGE_MAX_TDCS; channel++) { 3406 if ((1 << channel) & set->owned.map) { 3407 /* For now, <channel & <vdma_index> are the same. */ 3408 ldvp->is_txdma = B_TRUE; 3409 ldvp->ldv = (uint8_t)channel + NXGE_TDMA_LD_START; 3410 ldvp->channel = channel; 3411 ldvp->vdma_index = (uint8_t)channel; 3412 ldvp->ldv_intr_handler = nxge_tx_intr; 3413 ldvp->ldv_ldf_masks = 0; 3414 ldvp->use_timer = B_FALSE; 3415 ldvp->nxgep = nxgep; 3416 nxge_ldgv_setup(&ldgp, &ldvp, ldvp->ldv, 3417 endldg, nrequired_p); 3418 nldvs++; 3419 } 3420 } 3421 3422 if (own_fzc) { 3423 ldv = NXGE_MIF_LD; 3424 ldvp->ldv = (uint8_t)ldv; 3425 ldvp->is_mif = B_TRUE; 3426 ldvp->ldv_intr_handler = nxge_mif_intr; 3427 ldvp->ldv_ldf_masks = 0; 3428 ldvp->use_timer = B_FALSE; 3429 ldvp->nxgep = nxgep; 3430 nxge_ldgv_setup(&ldgp, &ldvp, ldv, endldg, nrequired_p); 3431 nldvs++; 3432 } 3433 /* 3434 * MAC port (function zero control) 3435 */ 3436 if (own_fzc) { 3437 ldvp->is_mac = B_TRUE; 3438 ldvp->ldv_intr_handler = nxge_mac_intr; 3439 ldvp->ldv_ldf_masks = 0; 3440 ldv = func + NXGE_MAC_LD_START; 3441 ldvp->ldv = (uint8_t)ldv; 3442 ldvp->use_timer = B_FALSE; 3443 ldvp->nxgep = nxgep; 3444 nxge_ldgv_setup(&ldgp, &ldvp, ldv, endldg, nrequired_p); 3445 nldvs++; 3446 } 3447 NXGE_DEBUG_MSG((nxgep, INT_CTL, "==> nxge_ldgv_init: " 3448 "func %d nldvs %d navail %d nrequired %d", 3449 func, nldvs, *navail_p, *nrequired_p)); 3450 /* 3451 * Function 0 owns system error interrupts. 3452 */ 3453 ldvp->use_timer = B_TRUE; 3454 if (own_sys_err) { 3455 ldv = NXGE_SYS_ERROR_LD; 3456 ldvp->ldv = (uint8_t)ldv; 3457 ldvp->is_syserr = B_TRUE; 3458 ldvp->ldv_intr_handler = nxge_syserr_intr; 3459 ldvp->ldv_ldf_masks = 0; 3460 ldvp->nxgep = nxgep; 3461 ldgvp->ldvp_syserr = ldvp; 3462 /* 3463 * Unmask the system interrupt states. 3464 */ 3465 (void) nxge_fzc_sys_err_mask_set(nxgep, SYS_ERR_SMX_MASK | 3466 SYS_ERR_IPP_MASK | SYS_ERR_TXC_MASK | 3467 SYS_ERR_ZCP_MASK); 3468 3469 (void) nxge_ldgv_setup(&ldgp, &ldvp, ldv, endldg, nrequired_p); 3470 nldvs++; 3471 } else { 3472 ldv = NXGE_SYS_ERROR_LD; 3473 ldvp->ldv = (uint8_t)ldv; 3474 ldvp->is_syserr = B_TRUE; 3475 ldvp->ldv_intr_handler = nxge_syserr_intr; 3476 ldvp->nxgep = nxgep; 3477 ldvp->ldv_ldf_masks = 0; 3478 ldgvp->ldvp_syserr = ldvp; 3479 } 3480 3481 ldgvp->ldg_intrs = *nrequired_p; 3482 3483 NXGE_DEBUG_MSG((nxgep, INT_CTL, "==> nxge_ldgv_init: " 3484 "func %d nldvs %d navail %d nrequired %d", 3485 func, nldvs, *navail_p, *nrequired_p)); 3486 3487 NXGE_DEBUG_MSG((nxgep, INT_CTL, "<== nxge_ldgv_init")); 3488 return (status); 3489 } 3490 3491 nxge_status_t 3492 nxge_ldgv_uninit(p_nxge_t nxgep) 3493 { 3494 p_nxge_ldgv_t ldgvp; 3495 3496 NXGE_DEBUG_MSG((nxgep, INT_CTL, "==> nxge_ldgv_uninit")); 3497 ldgvp = nxgep->ldgvp; 3498 if (ldgvp == NULL) { 3499 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, "<== nxge_ldgv_uninit: " 3500 "no logical group configured.")); 3501 return (NXGE_OK); 3502 } 3503 if (ldgvp->ldvp_syserr_alloced == B_TRUE) { 3504 KMEM_FREE(ldgvp->ldvp_syserr, sizeof (nxge_ldv_t)); 3505 } 3506 if (ldgvp->ldgp) { 3507 KMEM_FREE(ldgvp->ldgp, sizeof (nxge_ldg_t) * ldgvp->maxldgs); 3508 } 3509 if (ldgvp->ldvp) { 3510 KMEM_FREE(ldgvp->ldvp, sizeof (nxge_ldv_t) * ldgvp->maxldvs); 3511 } 3512 KMEM_FREE(ldgvp, sizeof (nxge_ldgv_t)); 3513 nxgep->ldgvp = NULL; 3514 3515 NXGE_DEBUG_MSG((nxgep, INT_CTL, "<== nxge_ldgv_uninit")); 3516 return (NXGE_OK); 3517 } 3518 3519 nxge_status_t 3520 nxge_intr_ldgv_init(p_nxge_t nxgep) 3521 { 3522 nxge_status_t status = NXGE_OK; 3523 3524 NXGE_DEBUG_MSG((nxgep, INT_CTL, "==> nxge_intr_ldgv_init")); 3525 /* 3526 * Configure the logical device group numbers, state vectors and 3527 * interrupt masks for each logical device. 3528 */ 3529 status = nxge_fzc_intr_init(nxgep); 3530 3531 /* 3532 * Configure logical device masks and timers. 3533 */ 3534 status = nxge_intr_mask_mgmt(nxgep); 3535 3536 NXGE_DEBUG_MSG((nxgep, INT_CTL, "<== nxge_intr_ldgv_init")); 3537 return (status); 3538 } 3539 3540 nxge_status_t 3541 nxge_intr_mask_mgmt(p_nxge_t nxgep) 3542 { 3543 p_nxge_ldgv_t ldgvp; 3544 p_nxge_ldg_t ldgp; 3545 p_nxge_ldv_t ldvp; 3546 npi_handle_t handle; 3547 int i, j; 3548 npi_status_t rs = NPI_SUCCESS; 3549 3550 NXGE_DEBUG_MSG((nxgep, INT_CTL, "==> nxge_intr_mask_mgmt")); 3551 3552 if ((ldgvp = nxgep->ldgvp) == NULL) { 3553 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 3554 "<== nxge_intr_mask_mgmt: Null ldgvp")); 3555 return (NXGE_ERROR); 3556 } 3557 handle = NXGE_DEV_NPI_HANDLE(nxgep); 3558 ldgp = ldgvp->ldgp; 3559 ldvp = ldgvp->ldvp; 3560 if (ldgp == NULL || ldvp == NULL) { 3561 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 3562 "<== nxge_intr_mask_mgmt: Null ldgp or ldvp")); 3563 return (NXGE_ERROR); 3564 } 3565 NXGE_DEBUG_MSG((nxgep, INT_CTL, 3566 "==> nxge_intr_mask_mgmt: # of intrs %d ", ldgvp->ldg_intrs)); 3567 /* Initialize masks. */ 3568 if (nxgep->niu_type != N2_NIU) { 3569 NXGE_DEBUG_MSG((nxgep, INT_CTL, 3570 "==> nxge_intr_mask_mgmt(Neptune): # intrs %d ", 3571 ldgvp->ldg_intrs)); 3572 for (i = 0; i < ldgvp->ldg_intrs; i++, ldgp++) { 3573 NXGE_DEBUG_MSG((nxgep, INT_CTL, 3574 "==> nxge_intr_mask_mgmt(Neptune): # ldv %d " 3575 "in group %d", ldgp->nldvs, ldgp->ldg)); 3576 for (j = 0; j < ldgp->nldvs; j++, ldvp++) { 3577 NXGE_DEBUG_MSG((nxgep, INT_CTL, 3578 "==> nxge_intr_mask_mgmt: set ldv # %d " 3579 "for ldg %d", ldvp->ldv, ldgp->ldg)); 3580 rs = npi_intr_mask_set(handle, ldvp->ldv, 3581 ldvp->ldv_ldf_masks); 3582 if (rs != NPI_SUCCESS) { 3583 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 3584 "<== nxge_intr_mask_mgmt: " 3585 "set mask failed " 3586 " rs 0x%x ldv %d mask 0x%x", 3587 rs, ldvp->ldv, 3588 ldvp->ldv_ldf_masks)); 3589 return (NXGE_ERROR | rs); 3590 } 3591 NXGE_DEBUG_MSG((nxgep, INT_CTL, 3592 "==> nxge_intr_mask_mgmt: " 3593 "set mask OK " 3594 " rs 0x%x ldv %d mask 0x%x", 3595 rs, ldvp->ldv, 3596 ldvp->ldv_ldf_masks)); 3597 } 3598 } 3599 } 3600 ldgp = ldgvp->ldgp; 3601 /* Configure timer and arm bit */ 3602 for (i = 0; i < nxgep->ldgvp->ldg_intrs; i++, ldgp++) { 3603 rs = npi_intr_ldg_mgmt_set(handle, ldgp->ldg, 3604 ldgp->arm, ldgp->ldg_timer); 3605 if (rs != NPI_SUCCESS) { 3606 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 3607 "<== nxge_intr_mask_mgmt: " 3608 "set timer failed " 3609 " rs 0x%x dg %d timer 0x%x", 3610 rs, ldgp->ldg, ldgp->ldg_timer)); 3611 return (NXGE_ERROR | rs); 3612 } 3613 NXGE_DEBUG_MSG((nxgep, INT_CTL, 3614 "==> nxge_intr_mask_mgmt: " 3615 "set timer OK " 3616 " rs 0x%x ldg %d timer 0x%x", 3617 rs, ldgp->ldg, ldgp->ldg_timer)); 3618 } 3619 3620 NXGE_DEBUG_MSG((nxgep, INT_CTL, "<== nxge_fzc_intr_mask_mgmt")); 3621 return (NXGE_OK); 3622 } 3623 3624 nxge_status_t 3625 nxge_intr_mask_mgmt_set(p_nxge_t nxgep, boolean_t on) 3626 { 3627 p_nxge_ldgv_t ldgvp; 3628 p_nxge_ldg_t ldgp; 3629 p_nxge_ldv_t ldvp; 3630 npi_handle_t handle; 3631 int i, j; 3632 npi_status_t rs = NPI_SUCCESS; 3633 3634 NXGE_DEBUG_MSG((nxgep, INT_CTL, 3635 "==> nxge_intr_mask_mgmt_set (%d)", on)); 3636 3637 if (nxgep->niu_type == N2_NIU) { 3638 NXGE_DEBUG_MSG((nxgep, INT_CTL, 3639 "<== nxge_intr_mask_mgmt_set (%d) not set (N2/NIU)", 3640 on)); 3641 return (NXGE_ERROR); 3642 } 3643 3644 if ((ldgvp = nxgep->ldgvp) == NULL) { 3645 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 3646 "==> nxge_intr_mask_mgmt_set: Null ldgvp")); 3647 return (NXGE_ERROR); 3648 } 3649 3650 handle = NXGE_DEV_NPI_HANDLE(nxgep); 3651 ldgp = ldgvp->ldgp; 3652 ldvp = ldgvp->ldvp; 3653 if (ldgp == NULL || ldvp == NULL) { 3654 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 3655 "<== nxge_intr_mask_mgmt_set: Null ldgp or ldvp")); 3656 return (NXGE_ERROR); 3657 } 3658 /* set masks. */ 3659 for (i = 0; i < ldgvp->ldg_intrs; i++, ldgp++) { 3660 NXGE_DEBUG_MSG((nxgep, INT_CTL, 3661 "==> nxge_intr_mask_mgmt_set: flag %d ldg %d" 3662 "set mask nldvs %d", on, ldgp->ldg, ldgp->nldvs)); 3663 for (j = 0; j < ldgp->nldvs; j++, ldvp++) { 3664 NXGE_DEBUG_MSG((nxgep, INT_CTL, 3665 "==> nxge_intr_mask_mgmt_set: " 3666 "for %d %d flag %d", i, j, on)); 3667 if (on) { 3668 ldvp->ldv_ldf_masks = 0; 3669 NXGE_DEBUG_MSG((nxgep, INT_CTL, 3670 "==> nxge_intr_mask_mgmt_set: " 3671 "ON mask off")); 3672 } else if (!on) { 3673 ldvp->ldv_ldf_masks = (uint8_t)LD_IM1_MASK; 3674 NXGE_DEBUG_MSG((nxgep, INT_CTL, 3675 "==> nxge_intr_mask_mgmt_set:mask on")); 3676 } 3677 rs = npi_intr_mask_set(handle, ldvp->ldv, 3678 ldvp->ldv_ldf_masks); 3679 if (rs != NPI_SUCCESS) { 3680 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 3681 "==> nxge_intr_mask_mgmt_set: " 3682 "set mask failed " 3683 " rs 0x%x ldv %d mask 0x%x", 3684 rs, ldvp->ldv, ldvp->ldv_ldf_masks)); 3685 return (NXGE_ERROR | rs); 3686 } 3687 NXGE_DEBUG_MSG((nxgep, INT_CTL, 3688 "==> nxge_intr_mask_mgmt_set: flag %d" 3689 "set mask OK " 3690 " ldv %d mask 0x%x", 3691 on, ldvp->ldv, ldvp->ldv_ldf_masks)); 3692 } 3693 } 3694 3695 ldgp = ldgvp->ldgp; 3696 /* set the arm bit */ 3697 for (i = 0; i < nxgep->ldgvp->ldg_intrs; i++, ldgp++) { 3698 if (on && !ldgp->arm) { 3699 ldgp->arm = B_TRUE; 3700 } else if (!on && ldgp->arm) { 3701 ldgp->arm = B_FALSE; 3702 } 3703 rs = npi_intr_ldg_mgmt_set(handle, ldgp->ldg, 3704 ldgp->arm, ldgp->ldg_timer); 3705 if (rs != NPI_SUCCESS) { 3706 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 3707 "<== nxge_intr_mask_mgmt_set: " 3708 "set timer failed " 3709 " rs 0x%x ldg %d timer 0x%x", 3710 rs, ldgp->ldg, ldgp->ldg_timer)); 3711 return (NXGE_ERROR | rs); 3712 } 3713 NXGE_DEBUG_MSG((nxgep, INT_CTL, 3714 "==> nxge_intr_mask_mgmt_set: OK (flag %d) " 3715 "set timer " 3716 " ldg %d timer 0x%x", 3717 on, ldgp->ldg, ldgp->ldg_timer)); 3718 } 3719 3720 NXGE_DEBUG_MSG((nxgep, INT_CTL, "<== nxge_intr_mask_mgmt_set")); 3721 return (NXGE_OK); 3722 } 3723 3724 static nxge_status_t 3725 nxge_get_mac_addr_properties(p_nxge_t nxgep) 3726 { 3727 #if defined(_BIG_ENDIAN) 3728 uchar_t *prop_val; 3729 uint_t prop_len; 3730 uint_t j; 3731 #endif 3732 uint_t i; 3733 uint8_t func_num; 3734 boolean_t compute_macs = B_TRUE; 3735 3736 NXGE_DEBUG_MSG((nxgep, DDI_CTL, "==> nxge_get_mac_addr_properties ")); 3737 3738 #if defined(_BIG_ENDIAN) 3739 /* 3740 * Get the ethernet address. 3741 */ 3742 (void) localetheraddr((struct ether_addr *)NULL, &nxgep->ouraddr); 3743 3744 /* 3745 * Check if it is an adapter with its own local mac address If it is 3746 * present, override the system mac address. 3747 */ 3748 if (ddi_prop_lookup_byte_array(DDI_DEV_T_ANY, nxgep->dip, 0, 3749 "local-mac-address", &prop_val, 3750 &prop_len) == DDI_PROP_SUCCESS) { 3751 if (prop_len == ETHERADDRL) { 3752 nxgep->factaddr = *(p_ether_addr_t)prop_val; 3753 NXGE_DEBUG_MSG((nxgep, DDI_CTL, "Local mac address = " 3754 "%02x:%02x:%02x:%02x:%02x:%02x", 3755 prop_val[0], prop_val[1], prop_val[2], 3756 prop_val[3], prop_val[4], prop_val[5])); 3757 } 3758 ddi_prop_free(prop_val); 3759 } 3760 if (ddi_prop_lookup_byte_array(DDI_DEV_T_ANY, nxgep->dip, 0, 3761 "local-mac-address?", &prop_val, 3762 &prop_len) == DDI_PROP_SUCCESS) { 3763 if (strncmp("true", (caddr_t)prop_val, (size_t)prop_len) == 0) { 3764 nxgep->ouraddr = nxgep->factaddr; 3765 NXGE_DEBUG_MSG((nxgep, DDI_CTL, 3766 "Using local MAC address")); 3767 } 3768 ddi_prop_free(prop_val); 3769 } else { 3770 nxgep->ouraddr = nxgep->factaddr; 3771 } 3772 3773 if ((!nxgep->vpd_info.present) || 3774 (nxge_is_valid_local_mac(nxgep->factaddr))) 3775 goto got_mac_addr; 3776 3777 NXGE_DEBUG_MSG((nxgep, DDI_CTL, "nxge_get_mac_addr_properties: " 3778 "MAC address from properties is not valid...reading from PROM")); 3779 3780 #endif 3781 if (!nxgep->vpd_info.ver_valid) { 3782 (void) nxge_espc_mac_addrs_get(nxgep); 3783 if (!nxge_is_valid_local_mac(nxgep->factaddr)) { 3784 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, "Failed to get " 3785 "MAC address")); 3786 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, "EEPROM version " 3787 "[%s] invalid...please update", 3788 nxgep->vpd_info.ver)); 3789 return (NXGE_ERROR); 3790 } 3791 nxgep->ouraddr = nxgep->factaddr; 3792 goto got_mac_addr; 3793 } 3794 /* 3795 * First get the MAC address from the info in the VPD data read 3796 * from the EEPROM. 3797 */ 3798 nxge_espc_get_next_mac_addr(nxgep->vpd_info.mac_addr, 3799 nxgep->function_num, &nxgep->factaddr); 3800 3801 if (!nxge_is_valid_local_mac(nxgep->factaddr)) { 3802 NXGE_DEBUG_MSG((nxgep, DDI_CTL, 3803 "nxge_get_mac_addr_properties: " 3804 "MAC address in EEPROM VPD data not valid" 3805 "...reading from NCR registers")); 3806 (void) nxge_espc_mac_addrs_get(nxgep); 3807 if (!nxge_is_valid_local_mac(nxgep->factaddr)) { 3808 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, "Failed to get " 3809 "MAC address")); 3810 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, "EEPROM version " 3811 "[%s] invalid...please update", 3812 nxgep->vpd_info.ver)); 3813 return (NXGE_ERROR); 3814 } 3815 } 3816 3817 nxgep->ouraddr = nxgep->factaddr; 3818 3819 got_mac_addr: 3820 func_num = nxgep->function_num; 3821 3822 /* 3823 * Note: mac-addresses property is the list of mac addresses for a 3824 * port. NXGE_MAX_MMAC_ADDRS is the total number of MAC addresses 3825 * allocated for a board. 3826 */ 3827 nxgep->nxge_mmac_info.total_factory_macs = NXGE_MAX_MMAC_ADDRS; 3828 3829 #if defined(_BIG_ENDIAN) 3830 if (ddi_prop_lookup_byte_array(DDI_DEV_T_ANY, nxgep->dip, 0, 3831 "mac-addresses", &prop_val, &prop_len) == DDI_PROP_SUCCESS) { 3832 /* 3833 * XAUI may have up to 18 MACs, more than the XMAC can 3834 * use (1 unique MAC plus 16 alternate MACs) 3835 */ 3836 nxgep->nxge_mmac_info.num_factory_mmac = 3837 prop_len / ETHERADDRL - 1; 3838 if (nxgep->nxge_mmac_info.num_factory_mmac > 3839 XMAC_MAX_ALT_ADDR_ENTRY) { 3840 nxgep->nxge_mmac_info.num_factory_mmac = 3841 XMAC_MAX_ALT_ADDR_ENTRY; 3842 } 3843 3844 for (i = 1; i <= nxgep->nxge_mmac_info.num_factory_mmac; i++) { 3845 for (j = 0; j < ETHERADDRL; j++) { 3846 nxgep->nxge_mmac_info.factory_mac_pool[i][j] = 3847 *(prop_val + (i * ETHERADDRL) + j); 3848 } 3849 NXGE_DEBUG_MSG((nxgep, DDI_CTL, 3850 "nxge_get_mac_addr_properties: Alt mac[%d] from " 3851 "mac-addresses property[%2x:%2x:%2x:%2x:%2x:%2x]", 3852 i, nxgep->nxge_mmac_info.factory_mac_pool[i][0], 3853 nxgep->nxge_mmac_info.factory_mac_pool[i][1], 3854 nxgep->nxge_mmac_info.factory_mac_pool[i][2], 3855 nxgep->nxge_mmac_info.factory_mac_pool[i][3], 3856 nxgep->nxge_mmac_info.factory_mac_pool[i][4], 3857 nxgep->nxge_mmac_info.factory_mac_pool[i][5])); 3858 } 3859 3860 compute_macs = B_FALSE; 3861 ddi_prop_free(prop_val); 3862 goto got_mmac_info; 3863 } 3864 #endif 3865 /* 3866 * total_factory_macs = 32 3867 * num_factory_mmac = (32 >> (nports/2)) - 1 3868 * So if nports = 4, then num_factory_mmac = 7 3869 * if nports = 2, then num_factory_mmac = 15 3870 */ 3871 nxgep->nxge_mmac_info.num_factory_mmac = 3872 ((nxgep->nxge_mmac_info.total_factory_macs >> 3873 (nxgep->nports >> 1))) - 1; 3874 3875 got_mmac_info: 3876 3877 if ((nxgep->function_num < 2) && 3878 (nxgep->nxge_mmac_info.num_factory_mmac > 3879 XMAC_MAX_ALT_ADDR_ENTRY)) { 3880 nxgep->nxge_mmac_info.num_factory_mmac = 3881 XMAC_MAX_ALT_ADDR_ENTRY; 3882 } else if ((nxgep->function_num > 1) && 3883 (nxgep->nxge_mmac_info.num_factory_mmac > 3884 BMAC_MAX_ALT_ADDR_ENTRY)) { 3885 nxgep->nxge_mmac_info.num_factory_mmac = 3886 BMAC_MAX_ALT_ADDR_ENTRY; 3887 } 3888 3889 for (i = 0; i <= nxgep->nxge_mmac_info.num_mmac; i++) { 3890 (void) npi_mac_altaddr_disable(nxgep->npi_handle, 3891 NXGE_GET_PORT_NUM(func_num), i); 3892 } 3893 3894 (void) nxge_init_mmac(nxgep, compute_macs); 3895 return (NXGE_OK); 3896 } 3897 3898 void 3899 nxge_get_xcvr_properties(p_nxge_t nxgep) 3900 { 3901 uchar_t *prop_val; 3902 uint_t prop_len; 3903 3904 NXGE_DEBUG_MSG((nxgep, DDI_CTL, "==> nxge_get_xcvr_properties")); 3905 3906 /* 3907 * Read the type of physical layer interface being used. 3908 */ 3909 nxgep->statsp->mac_stats.xcvr_inuse = INT_MII_XCVR; 3910 if (ddi_prop_lookup_byte_array(DDI_DEV_T_ANY, nxgep->dip, 0, 3911 "phy-type", &prop_val, &prop_len) == DDI_PROP_SUCCESS) { 3912 if (strncmp("pcs", (caddr_t)prop_val, 3913 (size_t)prop_len) == 0) { 3914 nxgep->statsp->mac_stats.xcvr_inuse = PCS_XCVR; 3915 } else { 3916 nxgep->statsp->mac_stats.xcvr_inuse = INT_MII_XCVR; 3917 } 3918 ddi_prop_free(prop_val); 3919 } else if (ddi_prop_lookup_byte_array(DDI_DEV_T_ANY, nxgep->dip, 0, 3920 "phy-interface", &prop_val, 3921 &prop_len) == DDI_PROP_SUCCESS) { 3922 if (strncmp("pcs", (caddr_t)prop_val, (size_t)prop_len) == 0) { 3923 nxgep->statsp->mac_stats.xcvr_inuse = PCS_XCVR; 3924 } else { 3925 nxgep->statsp->mac_stats.xcvr_inuse = INT_MII_XCVR; 3926 } 3927 ddi_prop_free(prop_val); 3928 } 3929 } 3930 3931 /* 3932 * Static functions start here. 3933 */ 3934 3935 static void 3936 nxge_ldgv_setup(p_nxge_ldg_t *ldgp, p_nxge_ldv_t *ldvp, uint8_t ldv, 3937 uint8_t endldg, int *ngrps) 3938 { 3939 NXGE_DEBUG_MSG((NULL, INT_CTL, "==> nxge_ldgv_setup")); 3940 /* Assign the group number for each device. */ 3941 (*ldvp)->ldg_assigned = (*ldgp)->ldg; 3942 (*ldvp)->ldgp = *ldgp; 3943 (*ldvp)->ldv = ldv; 3944 3945 NXGE_DEBUG_MSG((NULL, INT_CTL, "==> nxge_ldgv_setup: " 3946 "ldv %d endldg %d ldg %d, ldvp $%p", 3947 ldv, endldg, (*ldgp)->ldg, (*ldgp)->ldvp)); 3948 3949 (*ldgp)->nldvs++; 3950 if ((*ldgp)->ldg == (endldg - 1)) { 3951 if ((*ldgp)->ldvp == NULL) { 3952 (*ldgp)->ldvp = *ldvp; 3953 *ngrps += 1; 3954 NXGE_DEBUG_MSG((NULL, INT_CTL, 3955 "==> nxge_ldgv_setup: ngrps %d", *ngrps)); 3956 } 3957 NXGE_DEBUG_MSG((NULL, INT_CTL, 3958 "==> nxge_ldgv_setup: ldvp $%p ngrps %d", 3959 *ldvp, *ngrps)); 3960 ++*ldvp; 3961 } else { 3962 (*ldgp)->ldvp = *ldvp; 3963 *ngrps += 1; 3964 NXGE_DEBUG_MSG((NULL, INT_CTL, "==> nxge_ldgv_setup(done): " 3965 "ldv %d endldg %d ldg %d, ldvp $%p", 3966 ldv, endldg, (*ldgp)->ldg, (*ldgp)->ldvp)); 3967 (*ldvp) = ++*ldvp; 3968 (*ldgp) = ++*ldgp; 3969 NXGE_DEBUG_MSG((NULL, INT_CTL, 3970 "==> nxge_ldgv_setup: new ngrps %d", *ngrps)); 3971 } 3972 3973 NXGE_DEBUG_MSG((NULL, INT_CTL, "==> nxge_ldgv_setup: " 3974 "ldv %d ldvp $%p endldg %d ngrps %d", 3975 ldv, ldvp, endldg, *ngrps)); 3976 3977 NXGE_DEBUG_MSG((NULL, INT_CTL, "<== nxge_ldgv_setup")); 3978 } 3979 3980 /* 3981 * Note: This function assumes the following distribution of mac 3982 * addresses among 4 ports in neptune: 3983 * 3984 * ------------- 3985 * 0| |0 - local-mac-address for fn 0 3986 * ------------- 3987 * 1| |1 - local-mac-address for fn 1 3988 * ------------- 3989 * 2| |2 - local-mac-address for fn 2 3990 * ------------- 3991 * 3| |3 - local-mac-address for fn 3 3992 * ------------- 3993 * | |4 - Start of alt. mac addr. for fn 0 3994 * | | 3995 * | | 3996 * | |10 3997 * -------------- 3998 * | |11 - Start of alt. mac addr. for fn 1 3999 * | | 4000 * | | 4001 * | |17 4002 * -------------- 4003 * | |18 - Start of alt. mac addr. for fn 2 4004 * | | 4005 * | | 4006 * | |24 4007 * -------------- 4008 * | |25 - Start of alt. mac addr. for fn 3 4009 * | | 4010 * | | 4011 * | |31 4012 * -------------- 4013 * 4014 * For N2/NIU the mac addresses is from XAUI card. 4015 * 4016 * When 'compute_addrs' is true, the alternate mac addresses are computed 4017 * using the unique mac address as base. Otherwise the alternate addresses 4018 * are assigned from the list read off the 'mac-addresses' property. 4019 */ 4020 4021 static void 4022 nxge_init_mmac(p_nxge_t nxgep, boolean_t compute_addrs) 4023 { 4024 int slot; 4025 uint8_t func_num; 4026 uint16_t *base_mmac_addr; 4027 uint32_t alt_mac_ls4b; 4028 uint16_t *mmac_addr; 4029 uint32_t base_mac_ls4b; /* least significant 4 bytes */ 4030 nxge_mmac_t *mmac_info; 4031 npi_mac_addr_t mac_addr; 4032 4033 func_num = nxgep->function_num; 4034 base_mmac_addr = (uint16_t *)&nxgep->factaddr; 4035 mmac_info = (nxge_mmac_t *)&nxgep->nxge_mmac_info; 4036 4037 if (compute_addrs) { 4038 base_mac_ls4b = ((uint32_t)base_mmac_addr[1]) << 16 | 4039 base_mmac_addr[2]; 4040 4041 if (nxgep->niu_type == N2_NIU) { 4042 /* ls4b of 1st altmac */ 4043 alt_mac_ls4b = base_mac_ls4b + 1; 4044 } else { /* Neptune */ 4045 alt_mac_ls4b = base_mac_ls4b + 4046 (nxgep->nports - func_num) + 4047 (func_num * (mmac_info->num_factory_mmac)); 4048 } 4049 } 4050 4051 /* Set flags for unique MAC */ 4052 mmac_info->mac_pool[0].flags |= MMAC_SLOT_USED | MMAC_VENDOR_ADDR; 4053 4054 /* Clear flags of all alternate MAC slots */ 4055 for (slot = 1; slot <= mmac_info->num_mmac; slot++) { 4056 if (slot <= mmac_info->num_factory_mmac) 4057 mmac_info->mac_pool[slot].flags = MMAC_VENDOR_ADDR; 4058 else 4059 mmac_info->mac_pool[slot].flags = 0; 4060 } 4061 4062 /* Generate and store factory alternate MACs */ 4063 for (slot = 1; slot <= mmac_info->num_factory_mmac; slot++) { 4064 mmac_addr = (uint16_t *)&mmac_info->factory_mac_pool[slot]; 4065 if (compute_addrs) { 4066 mmac_addr[0] = base_mmac_addr[0]; 4067 mac_addr.w2 = mmac_addr[0]; 4068 4069 mmac_addr[1] = (alt_mac_ls4b >> 16) & 0x0FFFF; 4070 mac_addr.w1 = mmac_addr[1]; 4071 4072 mmac_addr[2] = alt_mac_ls4b & 0x0FFFF; 4073 mac_addr.w0 = mmac_addr[2]; 4074 4075 alt_mac_ls4b++; 4076 } else { 4077 mac_addr.w2 = mmac_addr[0]; 4078 mac_addr.w1 = mmac_addr[1]; 4079 mac_addr.w0 = mmac_addr[2]; 4080 } 4081 4082 NXGE_DEBUG_MSG((nxgep, DDI_CTL, 4083 "mac_pool_addr[%2x:%2x:%2x:%2x:%2x:%2x] npi_addr[%x%x%x]", 4084 mmac_info->factory_mac_pool[slot][0], 4085 mmac_info->factory_mac_pool[slot][1], 4086 mmac_info->factory_mac_pool[slot][2], 4087 mmac_info->factory_mac_pool[slot][3], 4088 mmac_info->factory_mac_pool[slot][4], 4089 mmac_info->factory_mac_pool[slot][5], 4090 mac_addr.w0, mac_addr.w1, mac_addr.w2)); 4091 /* 4092 * slot minus 1 because npi_mac_altaddr_entry expects 0 4093 * for the first alternate mac address. 4094 */ 4095 (void) npi_mac_altaddr_entry(nxgep->npi_handle, OP_SET, 4096 NXGE_GET_PORT_NUM(func_num), slot - 1, &mac_addr); 4097 } 4098 /* Initialize the first two parameters for mmac kstat */ 4099 nxgep->statsp->mmac_stats.mmac_max_cnt = mmac_info->num_mmac; 4100 nxgep->statsp->mmac_stats.mmac_avail_cnt = mmac_info->num_mmac; 4101 } 4102 4103 /* 4104 * Convert an RDC group index into a port ring index. That is, map 4105 * <groupid> to an index into nxgep->rx_ring_handles. 4106 * (group ring index -> port ring index) 4107 */ 4108 int 4109 nxge_get_rxring_index(p_nxge_t nxgep, int groupid, int ringidx) 4110 { 4111 int i; 4112 int index = 0; 4113 p_nxge_rdc_grp_t rdc_grp_p; 4114 p_nxge_dma_pt_cfg_t p_dma_cfgp; 4115 p_nxge_hw_pt_cfg_t p_cfgp; 4116 4117 p_dma_cfgp = &nxgep->pt_config; 4118 p_cfgp = &p_dma_cfgp->hw_config; 4119 4120 if (isLDOMguest(nxgep)) 4121 return (ringidx); 4122 4123 for (i = 0; i < groupid; i++) { 4124 rdc_grp_p = 4125 &p_dma_cfgp->rdc_grps[p_cfgp->def_mac_rxdma_grpid + i]; 4126 index += rdc_grp_p->max_rdcs; 4127 } 4128 4129 return (index + ringidx); 4130 } 4131