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