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