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