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