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 /* 1360 * Device properties adv-autoneg-cap etc are defined by FWARC 1361 * http://sac.sfbay/FWARC/2002/345/20020610_asif.haswarey 1362 */ 1363 static void 1364 nxge_use_cfg_link_cfg(p_nxge_t nxgep) 1365 { 1366 int *prop_val; 1367 uint_t prop_len; 1368 dev_info_t *dip; 1369 int speed; 1370 int duplex; 1371 int adv_autoneg_cap; 1372 int adv_10gfdx_cap; 1373 int adv_10ghdx_cap; 1374 int adv_1000fdx_cap; 1375 int adv_1000hdx_cap; 1376 int adv_100fdx_cap; 1377 int adv_100hdx_cap; 1378 int adv_10fdx_cap; 1379 int adv_10hdx_cap; 1380 int status = DDI_SUCCESS; 1381 1382 dip = nxgep->dip; 1383 1384 /* 1385 * first find out the card type and the supported link speeds and 1386 * features 1387 */ 1388 /* add code for card type */ 1389 if (ddi_prop_lookup_int_array(DDI_DEV_T_ANY, dip, 0, "adv-autoneg-cap", 1390 &prop_val, &prop_len) == DDI_PROP_SUCCESS) { 1391 ddi_prop_free(prop_val); 1392 return; 1393 } 1394 1395 if (ddi_prop_lookup_int_array(DDI_DEV_T_ANY, dip, 0, "adv-10gfdx-cap", 1396 &prop_val, &prop_len) == DDI_PROP_SUCCESS) { 1397 ddi_prop_free(prop_val); 1398 return; 1399 } 1400 1401 if (ddi_prop_lookup_int_array(DDI_DEV_T_ANY, dip, 0, "adv-1000hdx-cap", 1402 &prop_val, &prop_len) == DDI_PROP_SUCCESS) { 1403 ddi_prop_free(prop_val); 1404 return; 1405 } 1406 1407 if (ddi_prop_lookup_int_array(DDI_DEV_T_ANY, dip, 0, "adv-1000fdx-cap", 1408 &prop_val, &prop_len) == DDI_PROP_SUCCESS) { 1409 ddi_prop_free(prop_val); 1410 return; 1411 } 1412 1413 if (ddi_prop_lookup_int_array(DDI_DEV_T_ANY, dip, 0, "adv-100fdx-cap", 1414 &prop_val, &prop_len) == DDI_PROP_SUCCESS) { 1415 ddi_prop_free(prop_val); 1416 return; 1417 } 1418 1419 if (ddi_prop_lookup_int_array(DDI_DEV_T_ANY, dip, 0, "adv-100hdx-cap", 1420 &prop_val, &prop_len) == DDI_PROP_SUCCESS) { 1421 ddi_prop_free(prop_val); 1422 return; 1423 } 1424 1425 if (ddi_prop_lookup_int_array(DDI_DEV_T_ANY, dip, 0, "adv-10fdx-cap", 1426 &prop_val, &prop_len) == DDI_PROP_SUCCESS) { 1427 ddi_prop_free(prop_val); 1428 return; 1429 } 1430 1431 if (ddi_prop_lookup_int_array(DDI_DEV_T_ANY, dip, 0, "adv-10hdx-cap", 1432 &prop_val, &prop_len) == DDI_PROP_SUCCESS) { 1433 ddi_prop_free(prop_val); 1434 return; 1435 } 1436 1437 if (ddi_prop_lookup_byte_array(DDI_DEV_T_ANY, dip, 0, "speed", 1438 (uchar_t **)&prop_val, &prop_len) == DDI_PROP_SUCCESS) { 1439 if (strncmp("10000", (caddr_t)prop_val, 1440 (size_t)prop_len) == 0) { 1441 speed = 10000; 1442 } else if (strncmp("1000", (caddr_t)prop_val, 1443 (size_t)prop_len) == 0) { 1444 speed = 1000; 1445 } else if (strncmp("100", (caddr_t)prop_val, 1446 (size_t)prop_len) == 0) { 1447 speed = 100; 1448 } else if (strncmp("10", (caddr_t)prop_val, 1449 (size_t)prop_len) == 0) { 1450 speed = 10; 1451 } else if (strncmp("auto", (caddr_t)prop_val, 1452 (size_t)prop_len) == 0) { 1453 speed = 0; 1454 } else { 1455 NXGE_ERROR_MSG((nxgep, NXGE_NOTE, 1456 "speed property is invalid reverting to auto")); 1457 speed = 0; 1458 } 1459 ddi_prop_free(prop_val); 1460 } else 1461 speed = 0; 1462 1463 if (ddi_prop_lookup_byte_array(DDI_DEV_T_ANY, dip, 0, "duplex", 1464 (uchar_t **)&prop_val, &prop_len) == DDI_PROP_SUCCESS) { 1465 if (strncmp("full", (caddr_t)prop_val, 1466 (size_t)prop_len) == 0) { 1467 duplex = 2; 1468 } else if (strncmp("half", (caddr_t)prop_val, 1469 (size_t)prop_len) == 0) { 1470 duplex = 1; 1471 } else if (strncmp("auto", (caddr_t)prop_val, 1472 (size_t)prop_len) == 0) { 1473 duplex = 0; 1474 } else { 1475 NXGE_ERROR_MSG((nxgep, NXGE_NOTE, 1476 "duplex property is invalid" 1477 " reverting to auto")); 1478 duplex = 0; 1479 } 1480 ddi_prop_free(prop_val); 1481 } else 1482 duplex = 0; 1483 1484 /* speed == 0 or duplex == 0 means auto negotiation. */ 1485 adv_autoneg_cap = (speed == 0) || (duplex == 0); 1486 if (adv_autoneg_cap == 0) { 1487 adv_10gfdx_cap = ((speed == 10000) && (duplex == 2)); 1488 adv_10ghdx_cap = adv_10gfdx_cap; 1489 adv_10ghdx_cap |= ((speed == 10000) && (duplex == 1)); 1490 adv_1000fdx_cap = adv_10ghdx_cap; 1491 adv_1000fdx_cap |= ((speed == 1000) && (duplex == 2)); 1492 adv_1000hdx_cap = adv_1000fdx_cap; 1493 adv_1000hdx_cap |= ((speed == 1000) && (duplex == 1)); 1494 adv_100fdx_cap = adv_1000hdx_cap; 1495 adv_100fdx_cap |= ((speed == 100) && (duplex == 2)); 1496 adv_100hdx_cap = adv_100fdx_cap; 1497 adv_100hdx_cap |= ((speed == 100) && (duplex == 1)); 1498 adv_10fdx_cap = adv_100hdx_cap; 1499 adv_10fdx_cap |= ((speed == 10) && (duplex == 2)); 1500 adv_10hdx_cap = adv_10fdx_cap; 1501 adv_10hdx_cap |= ((speed == 10) && (duplex == 1)); 1502 } else if (speed == 0) { 1503 adv_10gfdx_cap = (duplex == 2); 1504 adv_10ghdx_cap = (duplex == 1); 1505 adv_1000fdx_cap = (duplex == 2); 1506 adv_1000hdx_cap = (duplex == 1); 1507 adv_100fdx_cap = (duplex == 2); 1508 adv_100hdx_cap = (duplex == 1); 1509 adv_10fdx_cap = (duplex == 2); 1510 adv_10hdx_cap = (duplex == 1); 1511 } 1512 if (duplex == 0) { 1513 adv_10gfdx_cap = (speed == 0); 1514 adv_10gfdx_cap |= (speed == 10000); 1515 adv_10ghdx_cap = adv_10gfdx_cap; 1516 adv_10ghdx_cap |= (speed == 10000); 1517 adv_1000fdx_cap = adv_10ghdx_cap; 1518 adv_1000fdx_cap |= (speed == 1000); 1519 adv_1000hdx_cap = adv_1000fdx_cap; 1520 adv_1000hdx_cap |= (speed == 1000); 1521 adv_100fdx_cap = adv_1000hdx_cap; 1522 adv_100fdx_cap |= (speed == 100); 1523 adv_100hdx_cap = adv_100fdx_cap; 1524 adv_100hdx_cap |= (speed == 100); 1525 adv_10fdx_cap = adv_100hdx_cap; 1526 adv_10fdx_cap |= (speed == 10); 1527 adv_10hdx_cap = adv_10fdx_cap; 1528 adv_10hdx_cap |= (speed == 10); 1529 } 1530 status = ddi_prop_update_int_array(DDI_DEV_T_NONE, dip, 1531 "adv-autoneg-cap", &adv_autoneg_cap, 1); 1532 if (status) 1533 return; 1534 1535 status = ddi_prop_update_int_array(DDI_DEV_T_NONE, dip, 1536 "adv-10gfdx-cap", &adv_10gfdx_cap, 1); 1537 if (status) 1538 goto nxge_map_myargs_to_gmii_fail1; 1539 1540 status = ddi_prop_update_int_array(DDI_DEV_T_NONE, dip, 1541 "adv-10ghdx-cap", &adv_10ghdx_cap, 1); 1542 if (status) 1543 goto nxge_map_myargs_to_gmii_fail2; 1544 1545 status = ddi_prop_update_int_array(DDI_DEV_T_NONE, dip, 1546 "adv-1000fdx-cap", &adv_1000fdx_cap, 1); 1547 if (status) 1548 goto nxge_map_myargs_to_gmii_fail3; 1549 1550 status = ddi_prop_update_int_array(DDI_DEV_T_NONE, dip, 1551 "adv-1000hdx-cap", &adv_1000hdx_cap, 1); 1552 if (status) 1553 goto nxge_map_myargs_to_gmii_fail4; 1554 1555 status = ddi_prop_update_int_array(DDI_DEV_T_NONE, dip, 1556 "adv-100fdx-cap", &adv_100fdx_cap, 1); 1557 if (status) 1558 goto nxge_map_myargs_to_gmii_fail5; 1559 1560 status = ddi_prop_update_int_array(DDI_DEV_T_NONE, dip, 1561 "adv-100hdx-cap", &adv_100hdx_cap, 1); 1562 if (status) 1563 goto nxge_map_myargs_to_gmii_fail6; 1564 1565 status = ddi_prop_update_int_array(DDI_DEV_T_NONE, dip, 1566 "adv-10fdx-cap", &adv_10fdx_cap, 1); 1567 if (status) 1568 goto nxge_map_myargs_to_gmii_fail7; 1569 1570 status = ddi_prop_update_int_array(DDI_DEV_T_NONE, dip, 1571 "adv-10hdx-cap", &adv_10hdx_cap, 1); 1572 if (status) 1573 goto nxge_map_myargs_to_gmii_fail8; 1574 1575 return; 1576 1577 nxge_map_myargs_to_gmii_fail9: 1578 (void) ddi_prop_remove(DDI_DEV_T_NONE, dip, "adv-10hdx-cap"); 1579 1580 nxge_map_myargs_to_gmii_fail8: 1581 (void) ddi_prop_remove(DDI_DEV_T_NONE, dip, "adv-10fdx-cap"); 1582 1583 nxge_map_myargs_to_gmii_fail7: 1584 (void) ddi_prop_remove(DDI_DEV_T_NONE, dip, "adv-100hdx-cap"); 1585 1586 nxge_map_myargs_to_gmii_fail6: 1587 (void) ddi_prop_remove(DDI_DEV_T_NONE, dip, "adv-100fdx-cap"); 1588 1589 nxge_map_myargs_to_gmii_fail5: 1590 (void) ddi_prop_remove(DDI_DEV_T_NONE, dip, "adv-1000hdx-cap"); 1591 1592 nxge_map_myargs_to_gmii_fail4: 1593 (void) ddi_prop_remove(DDI_DEV_T_NONE, dip, "adv-1000fdx-cap"); 1594 1595 nxge_map_myargs_to_gmii_fail3: 1596 (void) ddi_prop_remove(DDI_DEV_T_NONE, dip, "adv-10ghdx-cap"); 1597 1598 nxge_map_myargs_to_gmii_fail2: 1599 (void) ddi_prop_remove(DDI_DEV_T_NONE, dip, "adv-10gfdx-cap"); 1600 1601 nxge_map_myargs_to_gmii_fail1: 1602 (void) ddi_prop_remove(DDI_DEV_T_NONE, dip, "adv-autoneg-cap"); 1603 } 1604 1605 nxge_status_t 1606 nxge_get_config_properties(p_nxge_t nxgep) 1607 { 1608 nxge_status_t status = NXGE_OK; 1609 p_nxge_hw_list_t hw_p; 1610 1611 NXGE_DEBUG_MSG((nxgep, VPD_CTL, " ==> nxge_get_config_properties")); 1612 1613 if ((hw_p = nxgep->nxge_hw_p) == NULL) { 1614 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 1615 " nxge_get_config_properties:" 1616 " common hardware not set", nxgep->niu_type)); 1617 return (NXGE_ERROR); 1618 } 1619 1620 /* 1621 * Get info on how many ports Neptune card has. 1622 */ 1623 nxgep->nports = nxge_get_nports(nxgep); 1624 if (nxgep->nports <= 0) { 1625 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 1626 "<==nxge_get_config_properties: Invalid Neptune type 0x%x", 1627 nxgep->niu_type)); 1628 return (NXGE_ERROR); 1629 } 1630 nxgep->classifier.tcam_size = TCAM_NIU_TCAM_MAX_ENTRY; 1631 if (NXGE_IS_VALID_NEPTUNE_TYPE(nxgep)) { 1632 nxgep->classifier.tcam_size = TCAM_NXGE_TCAM_MAX_ENTRY; 1633 } 1634 if (nxgep->function_num >= nxgep->nports) { 1635 return (NXGE_ERROR); 1636 } 1637 1638 status = nxge_get_mac_addr_properties(nxgep); 1639 if (status != NXGE_OK) 1640 return (NXGE_ERROR); 1641 1642 /* 1643 * read the configuration type. If none is specified, used default. 1644 * Config types: equal: (default) DMA channels, RDC groups, TCAM, FCRAM 1645 * are shared equally across all the ports. 1646 * 1647 * Fair: DMA channels, RDC groups, TCAM, FCRAM are shared proportional 1648 * to the port speed. 1649 * 1650 * 1651 * custom: DMA channels, RDC groups, TCAM, FCRAM partition is 1652 * specified in nxge.conf. Need to read each parameter and set 1653 * up the parameters in nxge structures. 1654 * 1655 */ 1656 switch (nxgep->niu_type) { 1657 case N2_NIU: 1658 NXGE_DEBUG_MSG((nxgep, VPD_CTL, 1659 " ==> nxge_get_config_properties: N2")); 1660 MUTEX_ENTER(&hw_p->nxge_cfg_lock); 1661 if ((hw_p->flags & COMMON_CFG_VALID) != 1662 COMMON_CFG_VALID) { 1663 status = nxge_cfg_verify_set(nxgep, 1664 COMMON_RXDMA_GRP_CFG); 1665 status = nxge_cfg_verify_set(nxgep, 1666 COMMON_CLASS_CFG); 1667 hw_p->flags |= COMMON_CFG_VALID; 1668 } 1669 MUTEX_EXIT(&hw_p->nxge_cfg_lock); 1670 status = nxge_use_cfg_n2niu_properties(nxgep); 1671 break; 1672 default: 1673 if (!NXGE_IS_VALID_NEPTUNE_TYPE(nxgep)) { 1674 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 1675 " nxge_get_config_properties:" 1676 " unknown NIU type 0x%x", nxgep->niu_type)); 1677 return (NXGE_ERROR); 1678 } 1679 1680 NXGE_DEBUG_MSG((nxgep, VPD_CTL, 1681 " ==> nxge_get_config_properties: Neptune")); 1682 status = nxge_cfg_verify_set_quick_config(nxgep); 1683 MUTEX_ENTER(&hw_p->nxge_cfg_lock); 1684 if ((hw_p->flags & COMMON_CFG_VALID) != 1685 COMMON_CFG_VALID) { 1686 status = nxge_cfg_verify_set(nxgep, 1687 COMMON_TXDMA_CFG); 1688 status = nxge_cfg_verify_set(nxgep, 1689 COMMON_RXDMA_CFG); 1690 status = nxge_cfg_verify_set(nxgep, 1691 COMMON_RXDMA_GRP_CFG); 1692 status = nxge_cfg_verify_set(nxgep, 1693 COMMON_CLASS_CFG); 1694 hw_p->flags |= COMMON_CFG_VALID; 1695 } 1696 MUTEX_EXIT(&hw_p->nxge_cfg_lock); 1697 nxge_use_cfg_neptune_properties(nxgep); 1698 status = NXGE_OK; 1699 break; 1700 } 1701 1702 /* 1703 * Get the software LSO enable flag property from the 1704 * driver configuration file (nxge.conf). 1705 * This flag will be set to disable (0) if this property 1706 * does not exist. 1707 */ 1708 nxgep->soft_lso_enable = ddi_prop_get_int(DDI_DEV_T_ANY, nxgep->dip, 1709 DDI_PROP_DONTPASS | DDI_PROP_NOTPROM, "soft-lso-enable", 0); 1710 NXGE_DEBUG_MSG((nxgep, VPD_CTL, 1711 "nxge_get_config_properties: software lso %d\n", 1712 nxgep->soft_lso_enable)); 1713 1714 NXGE_DEBUG_MSG((nxgep, VPD_CTL, " <== nxge_get_config_properties")); 1715 return (status); 1716 } 1717 1718 static nxge_status_t 1719 nxge_use_cfg_n2niu_properties(p_nxge_t nxgep) 1720 { 1721 nxge_status_t status = NXGE_OK; 1722 1723 NXGE_DEBUG_MSG((nxgep, CFG_CTL, " ==> nxge_use_cfg_n2niu_properties")); 1724 1725 status = nxge_use_default_dma_config_n2(nxgep); 1726 if (status != NXGE_OK) { 1727 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 1728 " ==> nxge_use_cfg_n2niu_properties (err 0x%x)", 1729 status)); 1730 return (status | NXGE_ERROR); 1731 } 1732 1733 (void) nxge_use_cfg_vlan_class_config(nxgep); 1734 (void) nxge_use_cfg_mac_class_config(nxgep); 1735 (void) nxge_use_cfg_class_config(nxgep); 1736 (void) nxge_use_cfg_link_cfg(nxgep); 1737 1738 /* 1739 * Read in the hardware (fcode) properties. Use the ndd array to read 1740 * each property. 1741 */ 1742 (void) nxge_get_param_soft_properties(nxgep); 1743 NXGE_DEBUG_MSG((nxgep, CFG_CTL, " <== nxge_use_cfg_n2niu_properties")); 1744 1745 return (status); 1746 } 1747 1748 static void 1749 nxge_use_cfg_neptune_properties(p_nxge_t nxgep) 1750 { 1751 NXGE_DEBUG_MSG((nxgep, CFG_CTL, "==> nxge_use_cfg_neptune_properties")); 1752 1753 (void) nxge_use_cfg_dma_config(nxgep); 1754 (void) nxge_use_cfg_vlan_class_config(nxgep); 1755 (void) nxge_use_cfg_mac_class_config(nxgep); 1756 (void) nxge_use_cfg_class_config(nxgep); 1757 (void) nxge_use_cfg_link_cfg(nxgep); 1758 1759 /* 1760 * Read in the hardware (fcode) properties. Use the ndd array to read 1761 * each property. 1762 */ 1763 (void) nxge_get_param_soft_properties(nxgep); 1764 NXGE_DEBUG_MSG((nxgep, CFG_CTL, "<== nxge_use_cfg_neptune_properties")); 1765 } 1766 1767 /* 1768 * FWARC 2006/556 1769 */ 1770 1771 static nxge_status_t 1772 nxge_use_default_dma_config_n2(p_nxge_t nxgep) 1773 { 1774 int ndmas; 1775 uint8_t func; 1776 p_nxge_dma_pt_cfg_t p_dma_cfgp; 1777 p_nxge_hw_pt_cfg_t p_cfgp; 1778 int *prop_val; 1779 uint_t prop_len; 1780 int i; 1781 nxge_status_t status = NXGE_OK; 1782 1783 NXGE_DEBUG_MSG((nxgep, OBP_CTL, "==> nxge_use_default_dma_config_n2")); 1784 1785 p_dma_cfgp = (p_nxge_dma_pt_cfg_t)&nxgep->pt_config; 1786 p_cfgp = (p_nxge_hw_pt_cfg_t)&p_dma_cfgp->hw_config; 1787 1788 func = nxgep->function_num; 1789 p_cfgp->function_number = func; 1790 ndmas = NXGE_TDMA_PER_NIU_PORT; 1791 if (ddi_prop_lookup_int_array(DDI_DEV_T_ANY, nxgep->dip, 0, 1792 "tx-dma-channels", (int **)&prop_val, 1793 &prop_len) == DDI_PROP_SUCCESS) { 1794 p_cfgp->tdc.start = prop_val[0]; 1795 NXGE_DEBUG_MSG((nxgep, OBP_CTL, 1796 "==> nxge_use_default_dma_config_n2: tdc starts %d " 1797 "(#%d)", p_cfgp->tdc.start, prop_len)); 1798 1799 ndmas = prop_val[1]; 1800 NXGE_DEBUG_MSG((nxgep, OBP_CTL, 1801 "==> nxge_use_default_dma_config_n2: #tdc %d (#%d)", 1802 ndmas, prop_len)); 1803 ddi_prop_free(prop_val); 1804 } else { 1805 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 1806 "==> nxge_use_default_dma_config_n2: " 1807 "get tx-dma-channels failed")); 1808 return (NXGE_DDI_FAILED); 1809 } 1810 1811 p_cfgp->tdc.count = nxgep->max_tdcs = ndmas; 1812 p_cfgp->tdc.owned = p_cfgp->tdc.count; 1813 1814 NXGE_DEBUG_MSG((nxgep, OBP_CTL, "==> nxge_use_default_dma_config_n2: " 1815 "p_cfgp 0x%llx max_tdcs %d nxgep->max_tdcs %d start %d", 1816 p_cfgp, p_cfgp->tdc.count, nxgep->max_tdcs, p_cfgp->tdc.start)); 1817 1818 /* Receive DMA */ 1819 ndmas = NXGE_RDMA_PER_NIU_PORT; 1820 if (ddi_prop_lookup_int_array(DDI_DEV_T_ANY, nxgep->dip, 0, 1821 "rx-dma-channels", (int **)&prop_val, 1822 &prop_len) == DDI_PROP_SUCCESS) { 1823 p_cfgp->start_rdc = prop_val[0]; 1824 NXGE_DEBUG_MSG((nxgep, OBP_CTL, 1825 "==> nxge_use_default_dma_config_n2(obp): rdc start %d" 1826 " (#%d)", p_cfgp->start_rdc, prop_len)); 1827 ndmas = prop_val[1]; 1828 NXGE_DEBUG_MSG((nxgep, OBP_CTL, 1829 "==> nxge_use_default_dma_config_n2(obp):#rdc %d (#%d)", 1830 ndmas, prop_len)); 1831 ddi_prop_free(prop_val); 1832 } else { 1833 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 1834 "==> nxge_use_default_dma_config_n2: " 1835 "get rx-dma-channel failed")); 1836 return (NXGE_DDI_FAILED); 1837 } 1838 1839 p_cfgp->max_rdcs = nxgep->max_rdcs = ndmas; 1840 nxgep->rdc_mask = (ndmas - 1); 1841 1842 /* Hypervisor: rdc # and group # use the same # !! */ 1843 p_cfgp->max_grpids = p_cfgp->max_rdcs + p_cfgp->tdc.owned; 1844 p_cfgp->start_grpid = 0; 1845 p_cfgp->mif_ldvid = p_cfgp->mac_ldvid = p_cfgp->ser_ldvid = 0; 1846 1847 if (ddi_prop_lookup_int_array(DDI_DEV_T_ANY, nxgep->dip, 0, 1848 "interrupts", (int **)&prop_val, 1849 &prop_len) == DDI_PROP_SUCCESS) { 1850 /* 1851 * For each device assigned, the content of each interrupts 1852 * property is its logical device group. 1853 * 1854 * Assignment of interrupts property is in the the following 1855 * order: 1856 * 1857 * MAC MIF (if configured) SYSTEM ERROR (if configured) first 1858 * receive channel next channel...... last receive channel 1859 * first transmit channel next channel...... last transmit 1860 * channel 1861 * 1862 * prop_len should be at least for one mac and total # of rx and 1863 * tx channels. Function 0 owns MIF and ERROR 1864 */ 1865 NXGE_DEBUG_MSG((nxgep, OBP_CTL, 1866 "==> nxge_use_default_dma_config_n2(obp): " 1867 "# interrupts %d", prop_len)); 1868 1869 switch (func) { 1870 case 0: 1871 p_cfgp->ldg_chn_start = 3; 1872 p_cfgp->mac_ldvid = NXGE_MAC_LD_PORT0; 1873 p_cfgp->mif_ldvid = NXGE_MIF_LD; 1874 p_cfgp->ser_ldvid = NXGE_SYS_ERROR_LD; 1875 1876 break; 1877 case 1: 1878 p_cfgp->ldg_chn_start = 1; 1879 p_cfgp->mac_ldvid = NXGE_MAC_LD_PORT1; 1880 1881 break; 1882 default: 1883 status = NXGE_DDI_FAILED; 1884 break; 1885 } 1886 1887 if (status != NXGE_OK) 1888 return (status); 1889 1890 for (i = 0; i < prop_len; i++) { 1891 p_cfgp->ldg[i] = prop_val[i]; 1892 NXGE_DEBUG_MSG((nxgep, OBP_CTL, 1893 "==> nxge_use_default_dma_config_n2(obp): " 1894 "F%d: interrupt #%d, ldg %d", 1895 nxgep->function_num, i, p_cfgp->ldg[i])); 1896 } 1897 1898 p_cfgp->max_grpids = prop_len; 1899 NXGE_DEBUG_MSG((nxgep, OBP_CTL, 1900 "==> nxge_use_default_dma_config_n2(obp): %d " 1901 "(#%d) maxgrpids %d channel starts %d", 1902 p_cfgp->mac_ldvid, i, p_cfgp->max_grpids, 1903 p_cfgp->ldg_chn_start)); 1904 ddi_prop_free(prop_val); 1905 } else { 1906 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 1907 "==> nxge_use_default_dma_config_n2: " 1908 "get interrupts failed")); 1909 return (NXGE_DDI_FAILED); 1910 } 1911 1912 p_cfgp->max_ldgs = p_cfgp->max_grpids; 1913 NXGE_DEBUG_MSG((nxgep, OBP_CTL, 1914 "==> nxge_use_default_dma_config_n2: " 1915 "p_cfgp 0x%llx max_rdcs %d nxgep->max_rdcs %d max_grpids %d" 1916 "start_grpid %d macid %d mifid %d serrid %d", 1917 p_cfgp, p_cfgp->max_rdcs, nxgep->max_rdcs, p_cfgp->max_grpids, 1918 p_cfgp->start_grpid, 1919 p_cfgp->mac_ldvid, p_cfgp->mif_ldvid, p_cfgp->ser_ldvid)); 1920 1921 NXGE_DEBUG_MSG((nxgep, OBP_CTL, "==> nxge_use_default_dma_config_n2: " 1922 "p_cfgp p%p start_ldg %d nxgep->max_ldgs %d", 1923 p_cfgp, p_cfgp->start_ldg, p_cfgp->max_ldgs)); 1924 1925 /* 1926 * RDC groups and the beginning RDC group assigned to this function. 1927 */ 1928 p_cfgp->max_rdc_grpids = 1; 1929 p_cfgp->def_mac_rxdma_grpid = (nxgep->function_num * 1); 1930 1931 if ((p_cfgp->def_mac_rxdma_grpid = nxge_fzc_rdc_tbl_bind 1932 (nxgep, p_cfgp->def_mac_rxdma_grpid, B_TRUE)) 1933 >= NXGE_MAX_RDC_GRPS) { 1934 NXGE_ERROR_MSG((nxgep, CFG_CTL, 1935 "nxge_use_default_dma_config_n2(): " 1936 "nxge_fzc_rdc_tbl_bind failed")); 1937 return (NXGE_DDI_FAILED); 1938 } 1939 1940 status = ddi_prop_update_int(DDI_DEV_T_NONE, nxgep->dip, 1941 "rx-rdc-grps", p_cfgp->max_rdc_grpids); 1942 if (status) { 1943 return (NXGE_DDI_FAILED); 1944 } 1945 status = ddi_prop_update_int(DDI_DEV_T_NONE, nxgep->dip, 1946 "rx-rdc-grps-begin", p_cfgp->def_mac_rxdma_grpid); 1947 if (status) { 1948 (void) ddi_prop_remove(DDI_DEV_T_NONE, nxgep->dip, 1949 "rx-rdc-grps"); 1950 return (NXGE_DDI_FAILED); 1951 } 1952 NXGE_DEBUG_MSG((nxgep, OBP_CTL, "==> nxge_use_default_dma_config_n2: " 1953 "p_cfgp $%p # rdc groups %d start rdc group id %d", 1954 p_cfgp, p_cfgp->max_rdc_grpids, 1955 p_cfgp->def_mac_rxdma_grpid)); 1956 1957 nxge_set_hw_dma_config(nxgep); 1958 NXGE_DEBUG_MSG((nxgep, OBP_CTL, "<== nxge_use_default_dma_config_n2")); 1959 return (status); 1960 } 1961 1962 static void 1963 nxge_use_cfg_dma_config(p_nxge_t nxgep) 1964 { 1965 int tx_ndmas, rx_ndmas, nrxgp, st_txdma, st_rxdma; 1966 p_nxge_dma_pt_cfg_t p_dma_cfgp; 1967 p_nxge_hw_pt_cfg_t p_cfgp; 1968 dev_info_t *dip; 1969 p_nxge_param_t param_arr; 1970 char *prop; 1971 int *prop_val; 1972 uint_t prop_len; 1973 int i; 1974 uint8_t *ch_arr_p; 1975 1976 NXGE_DEBUG_MSG((nxgep, CFG_CTL, " ==> nxge_use_cfg_dma_config")); 1977 param_arr = nxgep->param_arr; 1978 1979 p_dma_cfgp = (p_nxge_dma_pt_cfg_t)&nxgep->pt_config; 1980 p_cfgp = (p_nxge_hw_pt_cfg_t)&p_dma_cfgp->hw_config; 1981 dip = nxgep->dip; 1982 p_cfgp->function_number = nxgep->function_num; 1983 prop = param_arr[param_txdma_channels_begin].fcode_name; 1984 1985 if (ddi_prop_lookup_int_array(DDI_DEV_T_ANY, dip, 0, prop, 1986 &prop_val, &prop_len) == DDI_PROP_SUCCESS) { 1987 p_cfgp->tdc.start = *prop_val; 1988 ddi_prop_free(prop_val); 1989 } else { 1990 switch (nxgep->niu_type) { 1991 case NEPTUNE_4_1GC: 1992 ch_arr_p = &tx_4_1G[0]; 1993 break; 1994 case NEPTUNE_2_10GF: 1995 ch_arr_p = &tx_2_10G[0]; 1996 break; 1997 case NEPTUNE_2_10GF_2_1GC: 1998 case NEPTUNE_2_10GF_2_1GRF: 1999 ch_arr_p = &tx_2_10G_2_1G[0]; 2000 break; 2001 case NEPTUNE_1_10GF_3_1GC: 2002 ch_arr_p = &tx_1_10G_3_1G[0]; 2003 break; 2004 case NEPTUNE_1_1GC_1_10GF_2_1GC: 2005 ch_arr_p = &tx_1_1G_1_10G_2_1G[0]; 2006 break; 2007 default: 2008 switch (nxgep->platform_type) { 2009 case P_NEPTUNE_ALONSO: 2010 ch_arr_p = &tx_2_10G_2_1G[0]; 2011 break; 2012 default: 2013 ch_arr_p = &p4_tx_equal[0]; 2014 break; 2015 } 2016 break; 2017 } 2018 st_txdma = 0; 2019 for (i = 0; i < nxgep->function_num; i++, ch_arr_p++) 2020 st_txdma += *ch_arr_p; 2021 2022 (void) ddi_prop_update_int(DDI_DEV_T_NONE, nxgep->dip, 2023 prop, st_txdma); 2024 p_cfgp->tdc.start = st_txdma; 2025 } 2026 2027 prop = param_arr[param_txdma_channels].fcode_name; 2028 if (ddi_prop_lookup_int_array(DDI_DEV_T_ANY, dip, 0, prop, 2029 &prop_val, &prop_len) == DDI_PROP_SUCCESS) { 2030 tx_ndmas = *prop_val; 2031 ddi_prop_free(prop_val); 2032 } else { 2033 switch (nxgep->niu_type) { 2034 case NEPTUNE_4_1GC: 2035 tx_ndmas = tx_4_1G[nxgep->function_num]; 2036 break; 2037 case NEPTUNE_2_10GF: 2038 tx_ndmas = tx_2_10G[nxgep->function_num]; 2039 break; 2040 case NEPTUNE_2_10GF_2_1GC: 2041 case NEPTUNE_2_10GF_2_1GRF: 2042 tx_ndmas = tx_2_10G_2_1G[nxgep->function_num]; 2043 break; 2044 case NEPTUNE_1_10GF_3_1GC: 2045 tx_ndmas = tx_1_10G_3_1G[nxgep->function_num]; 2046 break; 2047 case NEPTUNE_1_1GC_1_10GF_2_1GC: 2048 tx_ndmas = tx_1_1G_1_10G_2_1G[nxgep->function_num]; 2049 break; 2050 default: 2051 switch (nxgep->platform_type) { 2052 case P_NEPTUNE_ALONSO: 2053 tx_ndmas = tx_2_10G_2_1G[nxgep->function_num]; 2054 break; 2055 default: 2056 tx_ndmas = p4_tx_equal[nxgep->function_num]; 2057 break; 2058 } 2059 break; 2060 } 2061 (void) ddi_prop_update_int(DDI_DEV_T_NONE, nxgep->dip, 2062 prop, tx_ndmas); 2063 } 2064 2065 p_cfgp->tdc.count = nxgep->max_tdcs = tx_ndmas; 2066 p_cfgp->tdc.owned = p_cfgp->tdc.count; 2067 NXGE_DEBUG_MSG((nxgep, CFG_CTL, "==> nxge_use_cfg_dma_config: " 2068 "p_cfgp 0x%llx max_tdcs %d nxgep->max_tdcs %d", 2069 p_cfgp, p_cfgp->tdc.count, nxgep->max_tdcs)); 2070 2071 prop = param_arr[param_rxdma_channels_begin].fcode_name; 2072 2073 if (ddi_prop_lookup_int_array(DDI_DEV_T_ANY, dip, 0, prop, 2074 &prop_val, &prop_len) == DDI_PROP_SUCCESS) { 2075 p_cfgp->start_rdc = *prop_val; 2076 ddi_prop_free(prop_val); 2077 } else { 2078 switch (nxgep->niu_type) { 2079 case NEPTUNE_4_1GC: 2080 ch_arr_p = &rx_4_1G[0]; 2081 break; 2082 case NEPTUNE_2_10GF: 2083 ch_arr_p = &rx_2_10G[0]; 2084 break; 2085 case NEPTUNE_2_10GF_2_1GC: 2086 case NEPTUNE_2_10GF_2_1GRF: 2087 ch_arr_p = &rx_2_10G_2_1G[0]; 2088 break; 2089 case NEPTUNE_1_10GF_3_1GC: 2090 ch_arr_p = &rx_1_10G_3_1G[0]; 2091 break; 2092 case NEPTUNE_1_1GC_1_10GF_2_1GC: 2093 ch_arr_p = &rx_1_1G_1_10G_2_1G[0]; 2094 break; 2095 default: 2096 switch (nxgep->platform_type) { 2097 case P_NEPTUNE_ALONSO: 2098 ch_arr_p = &rx_2_10G_2_1G[0]; 2099 break; 2100 default: 2101 ch_arr_p = &p4_rx_equal[0]; 2102 break; 2103 } 2104 break; 2105 } 2106 st_rxdma = 0; 2107 for (i = 0; i < nxgep->function_num; i++, ch_arr_p++) 2108 st_rxdma += *ch_arr_p; 2109 2110 (void) ddi_prop_update_int(DDI_DEV_T_NONE, nxgep->dip, 2111 prop, st_rxdma); 2112 p_cfgp->start_rdc = st_rxdma; 2113 } 2114 2115 prop = param_arr[param_rxdma_channels].fcode_name; 2116 2117 if (ddi_prop_lookup_int_array(DDI_DEV_T_ANY, dip, 0, prop, 2118 &prop_val, &prop_len) == DDI_PROP_SUCCESS) { 2119 rx_ndmas = *prop_val; 2120 ddi_prop_free(prop_val); 2121 } else { 2122 switch (nxgep->niu_type) { 2123 case NEPTUNE_4_1GC: 2124 rx_ndmas = rx_4_1G[nxgep->function_num]; 2125 break; 2126 case NEPTUNE_2_10GF: 2127 rx_ndmas = rx_2_10G[nxgep->function_num]; 2128 break; 2129 case NEPTUNE_2_10GF_2_1GC: 2130 case NEPTUNE_2_10GF_2_1GRF: 2131 rx_ndmas = rx_2_10G_2_1G[nxgep->function_num]; 2132 break; 2133 case NEPTUNE_1_10GF_3_1GC: 2134 rx_ndmas = rx_1_10G_3_1G[nxgep->function_num]; 2135 break; 2136 case NEPTUNE_1_1GC_1_10GF_2_1GC: 2137 rx_ndmas = rx_1_1G_1_10G_2_1G[nxgep->function_num]; 2138 break; 2139 default: 2140 switch (nxgep->platform_type) { 2141 case P_NEPTUNE_ALONSO: 2142 rx_ndmas = rx_2_10G_2_1G[nxgep->function_num]; 2143 break; 2144 default: 2145 rx_ndmas = p4_rx_equal[nxgep->function_num]; 2146 break; 2147 } 2148 break; 2149 } 2150 (void) ddi_prop_update_int(DDI_DEV_T_NONE, nxgep->dip, 2151 prop, rx_ndmas); 2152 } 2153 2154 p_cfgp->max_rdcs = nxgep->max_rdcs = rx_ndmas; 2155 2156 prop = param_arr[param_rdc_grps_start].fcode_name; 2157 if (ddi_prop_lookup_int_array(DDI_DEV_T_ANY, dip, 0, prop, 2158 &prop_val, &prop_len) == DDI_PROP_SUCCESS) { 2159 p_cfgp->def_mac_rxdma_grpid = *prop_val; 2160 ddi_prop_free(prop_val); 2161 if ((p_cfgp->def_mac_rxdma_grpid = nxge_fzc_rdc_tbl_bind 2162 (nxgep, p_cfgp->def_mac_rxdma_grpid, B_TRUE)) 2163 >= NXGE_MAX_RDC_GRPS) { 2164 NXGE_ERROR_MSG((nxgep, CFG_CTL, 2165 "nxge_use_cfg_dma_config(): " 2166 "nxge_fzc_rdc_tbl_bind failed")); 2167 cmn_err(CE_CONT, "nxge%d: group not available!\n", 2168 nxgep->instance); 2169 goto nxge_use_cfg_dma_config_exit; 2170 } 2171 2172 NXGE_DEBUG_MSG((nxgep, CFG_CTL, 2173 "==> nxge_use_default_dma_config: " 2174 "use property " "start_grpid %d ", 2175 p_cfgp->start_grpid)); 2176 } else { 2177 p_cfgp->def_mac_rxdma_grpid = nxgep->function_num; 2178 if ((p_cfgp->def_mac_rxdma_grpid = nxge_fzc_rdc_tbl_bind( 2179 nxgep, p_cfgp->def_mac_rxdma_grpid, B_TRUE)) >= 2180 NXGE_MAX_RDC_GRPS) { 2181 cmn_err(CE_CONT, "nxge%d: group not available!\n", 2182 nxgep->instance); 2183 goto nxge_use_cfg_dma_config_exit; 2184 } 2185 (void) ddi_prop_update_int(DDI_DEV_T_NONE, nxgep->dip, 2186 prop, p_cfgp->def_mac_rxdma_grpid); 2187 NXGE_DEBUG_MSG((nxgep, CFG_CTL, 2188 "==> nxge_use_default_dma_config: " 2189 "use default " 2190 "start_grpid %d (same as function #)", 2191 p_cfgp->start_grpid)); 2192 } 2193 2194 prop = param_arr[param_rx_rdc_grps].fcode_name; 2195 if (ddi_prop_lookup_int_array(DDI_DEV_T_ANY, dip, 0, prop, 2196 &prop_val, &prop_len) == DDI_PROP_SUCCESS) { 2197 nrxgp = *prop_val; 2198 ddi_prop_free(prop_val); 2199 } else { 2200 nrxgp = 1; 2201 (void) ddi_prop_update_int(DDI_DEV_T_NONE, nxgep->dip, 2202 prop, nrxgp); 2203 NXGE_DEBUG_MSG((nxgep, CFG_CTL, 2204 "==> nxge_use_default_dma_config: " 2205 "num_rdc_grpid not found: use def:# of " 2206 "rdc groups %d\n", nrxgp)); 2207 } 2208 2209 p_cfgp->max_rdc_grpids = nrxgp; 2210 2211 /* 2212 * 2/4 ports have the same hard-wired logical groups assigned. 2213 */ 2214 p_cfgp->start_ldg = nxgep->function_num * NXGE_LDGRP_PER_4PORTS; 2215 p_cfgp->max_ldgs = NXGE_LDGRP_PER_4PORTS; 2216 2217 NXGE_DEBUG_MSG((nxgep, CFG_CTL, "==> nxge_use_default_dma_config: " 2218 "p_cfgp 0x%llx max_rdcs %d nxgep->max_rdcs %d max_grpids %d" 2219 "start_grpid %d", 2220 p_cfgp, p_cfgp->max_rdcs, nxgep->max_rdcs, p_cfgp->max_grpids, 2221 p_cfgp->start_grpid)); 2222 2223 NXGE_DEBUG_MSG((nxgep, CFG_CTL, "==> nxge_use_cfg_dma_config: " 2224 "p_cfgp 0x%016llx start_ldg %d nxgep->max_ldgs %d " 2225 "def_mac_rxdma_grpid %d", 2226 p_cfgp, p_cfgp->start_ldg, p_cfgp->max_ldgs, 2227 p_cfgp->def_mac_rxdma_grpid)); 2228 2229 prop = param_arr[param_rxdma_intr_time].fcode_name; 2230 2231 if (ddi_prop_lookup_int_array(DDI_DEV_T_ANY, dip, 0, prop, 2232 &prop_val, &prop_len) == DDI_PROP_SUCCESS) { 2233 if ((prop_len > 0) && (prop_len <= p_cfgp->max_rdcs)) { 2234 (void) ddi_prop_update_int_array(DDI_DEV_T_NONE, 2235 nxgep->dip, prop, prop_val, prop_len); 2236 } 2237 ddi_prop_free(prop_val); 2238 } 2239 prop = param_arr[param_rxdma_intr_pkts].fcode_name; 2240 2241 if (ddi_prop_lookup_int_array(DDI_DEV_T_ANY, dip, 0, prop, 2242 &prop_val, &prop_len) == DDI_PROP_SUCCESS) { 2243 if ((prop_len > 0) && (prop_len <= p_cfgp->max_rdcs)) { 2244 (void) ddi_prop_update_int_array(DDI_DEV_T_NONE, 2245 nxgep->dip, prop, prop_val, prop_len); 2246 } 2247 ddi_prop_free(prop_val); 2248 } 2249 nxge_set_hw_dma_config(nxgep); 2250 2251 NXGE_DEBUG_MSG((nxgep, CFG_CTL, "<== nxge_use_cfg_dma_config: " 2252 "sTDC[%d] nTDC[%d] sRDC[%d] nRDC[%d]", 2253 p_cfgp->tdc.start, p_cfgp->tdc.count, 2254 p_cfgp->start_rdc, p_cfgp->max_rdcs)); 2255 2256 nxge_use_cfg_dma_config_exit: 2257 NXGE_DEBUG_MSG((nxgep, CFG_CTL, "<== nxge_use_cfg_dma_config")); 2258 } 2259 2260 void 2261 nxge_get_logical_props(p_nxge_t nxgep) 2262 { 2263 nxge_dma_pt_cfg_t *port = &nxgep->pt_config; 2264 nxge_hw_pt_cfg_t *hardware; 2265 nxge_rdc_grp_t *group; 2266 2267 (void) memset(port, 0, sizeof (*port)); 2268 2269 port->mac_port = 0; /* := function number */ 2270 2271 /* 2272 * alloc_buf_size: 2273 * dead variables. 2274 */ 2275 port->rbr_size = nxge_rbr_size; 2276 port->rcr_size = nxge_rcr_size; 2277 2278 port->tx_dma_map = 0; /* Transmit DMA channel bit map */ 2279 2280 nxge_set_rdc_intr_property(nxgep); 2281 2282 port->rcr_full_header = NXGE_RCR_FULL_HEADER; 2283 port->rx_drr_weight = PT_DRR_WT_DEFAULT_10G; 2284 2285 /* ----------------------------------------------------- */ 2286 hardware = &port->hw_config; 2287 2288 (void) memset(hardware, 0, sizeof (*hardware)); 2289 2290 /* 2291 * partition_id, read_write_mode: 2292 * dead variables. 2293 */ 2294 2295 /* 2296 * drr_wt, rx_full_header, *_ldg?, start_mac_entry, 2297 * mac_pref, def_mac_rxdma_grpid, start_vlan, max_vlans, 2298 * start_ldgs, max_ldgs, max_ldvs, 2299 * vlan_pref, def_vlan_rxdma_grpid are meaningful only 2300 * in the service domain. 2301 */ 2302 2303 group = &port->rdc_grps[0]; 2304 2305 group->flag = 1; /* configured */ 2306 group->config_method = RDC_TABLE_ENTRY_METHOD_REP; 2307 2308 /* HIO futures: this is still an open question. */ 2309 hardware->max_macs = 1; 2310 } 2311 2312 static void 2313 nxge_use_cfg_vlan_class_config(p_nxge_t nxgep) 2314 { 2315 uint_t vlan_cnt; 2316 int *vlan_cfg_val; 2317 int status; 2318 p_nxge_param_t param_arr; 2319 char *prop; 2320 2321 NXGE_DEBUG_MSG((nxgep, CFG_CTL, " ==> nxge_use_cfg_vlan_config")); 2322 param_arr = nxgep->param_arr; 2323 prop = param_arr[param_vlan_2rdc_grp].fcode_name; 2324 2325 status = ddi_prop_lookup_int_array(DDI_DEV_T_ANY, nxgep->dip, 0, prop, 2326 &vlan_cfg_val, &vlan_cnt); 2327 if (status == DDI_PROP_SUCCESS) { 2328 status = ddi_prop_update_int_array(DDI_DEV_T_NONE, 2329 nxgep->dip, prop, vlan_cfg_val, vlan_cnt); 2330 ddi_prop_free(vlan_cfg_val); 2331 } 2332 nxge_set_hw_vlan_class_config(nxgep); 2333 NXGE_DEBUG_MSG((nxgep, CFG_CTL, " <== nxge_use_cfg_vlan_config")); 2334 } 2335 2336 static void 2337 nxge_use_cfg_mac_class_config(p_nxge_t nxgep) 2338 { 2339 p_nxge_dma_pt_cfg_t p_dma_cfgp; 2340 p_nxge_hw_pt_cfg_t p_cfgp; 2341 uint_t mac_cnt; 2342 int *mac_cfg_val; 2343 int status; 2344 p_nxge_param_t param_arr; 2345 char *prop; 2346 2347 NXGE_DEBUG_MSG((nxgep, CFG_CTL, "==> nxge_use_cfg_mac_class_config")); 2348 p_dma_cfgp = (p_nxge_dma_pt_cfg_t)&nxgep->pt_config; 2349 p_cfgp = (p_nxge_hw_pt_cfg_t)&p_dma_cfgp->hw_config; 2350 p_cfgp->start_mac_entry = 0; 2351 param_arr = nxgep->param_arr; 2352 prop = param_arr[param_mac_2rdc_grp].fcode_name; 2353 2354 switch (nxgep->function_num) { 2355 case 0: 2356 case 1: 2357 /* 10G ports */ 2358 p_cfgp->max_macs = NXGE_MAX_MACS_XMACS; 2359 break; 2360 case 2: 2361 case 3: 2362 /* 1G ports */ 2363 default: 2364 p_cfgp->max_macs = NXGE_MAX_MACS_BMACS; 2365 break; 2366 } 2367 2368 p_cfgp->mac_pref = 1; 2369 NXGE_DEBUG_MSG((nxgep, OBP_CTL, 2370 "== nxge_use_cfg_mac_class_config: " 2371 " mac_pref bit set def_mac_rxdma_grpid %d", 2372 p_cfgp->def_mac_rxdma_grpid)); 2373 2374 status = ddi_prop_lookup_int_array(DDI_DEV_T_ANY, nxgep->dip, 0, prop, 2375 &mac_cfg_val, &mac_cnt); 2376 if (status == DDI_PROP_SUCCESS) { 2377 if (mac_cnt <= p_cfgp->max_macs) 2378 status = ddi_prop_update_int_array(DDI_DEV_T_NONE, 2379 nxgep->dip, prop, mac_cfg_val, mac_cnt); 2380 ddi_prop_free(mac_cfg_val); 2381 } 2382 nxge_set_hw_mac_class_config(nxgep); 2383 NXGE_DEBUG_MSG((nxgep, CFG_CTL, " <== nxge_use_cfg_mac_class_config")); 2384 } 2385 2386 static void 2387 nxge_use_cfg_class_config(p_nxge_t nxgep) 2388 { 2389 nxge_set_hw_class_config(nxgep); 2390 } 2391 2392 static void 2393 nxge_set_rdc_intr_property(p_nxge_t nxgep) 2394 { 2395 int i; 2396 p_nxge_dma_pt_cfg_t p_dma_cfgp; 2397 2398 NXGE_DEBUG_MSG((nxgep, CFG_CTL, " ==> nxge_set_rdc_intr_property")); 2399 p_dma_cfgp = (p_nxge_dma_pt_cfg_t)&nxgep->pt_config; 2400 2401 for (i = 0; i < NXGE_MAX_RDCS; i++) { 2402 p_dma_cfgp->rcr_timeout[i] = nxge_rcr_timeout; 2403 p_dma_cfgp->rcr_threshold[i] = nxge_rcr_threshold; 2404 } 2405 2406 NXGE_DEBUG_MSG((nxgep, CFG_CTL, " <== nxge_set_rdc_intr_property")); 2407 } 2408 2409 static void 2410 nxge_set_hw_dma_config(p_nxge_t nxgep) 2411 { 2412 int i, ndmas, ngrps, bitmap, end, st_rdc; 2413 int32_t status; 2414 uint8_t rdcs_per_grp; 2415 p_nxge_dma_pt_cfg_t p_dma_cfgp; 2416 p_nxge_hw_pt_cfg_t p_cfgp; 2417 p_nxge_rdc_grp_t rdc_grp_p; 2418 int rdcgrp_cfg = CFG_NOT_SPECIFIED, rx_quick_cfg; 2419 char *prop, *prop_val; 2420 p_nxge_param_t param_arr; 2421 config_token_t token; 2422 nxge_grp_t *group; 2423 2424 NXGE_DEBUG_MSG((nxgep, CFG_CTL, "==> nxge_set_hw_dma_config")); 2425 2426 p_dma_cfgp = (p_nxge_dma_pt_cfg_t)&nxgep->pt_config; 2427 p_cfgp = (p_nxge_hw_pt_cfg_t)&p_dma_cfgp->hw_config; 2428 rdc_grp_p = p_dma_cfgp->rdc_grps; 2429 2430 bitmap = 0; 2431 end = p_cfgp->tdc.start + p_cfgp->tdc.owned; 2432 p_dma_cfgp->tx_dma_map = 0; 2433 for (i = p_cfgp->tdc.start; i < end; i++) { 2434 bitmap |= (1 << i); 2435 } 2436 2437 nxgep->tx_set.owned.map |= bitmap; /* Owned, & not shared. */ 2438 2439 group = (nxge_grp_t *)nxge_grp_add(nxgep, NXGE_TRANSMIT_GROUP); 2440 group->map = bitmap; 2441 2442 p_dma_cfgp->tx_dma_map = bitmap; 2443 param_arr = nxgep->param_arr; 2444 2445 /* Assume RDCs are evenly distributed */ 2446 rx_quick_cfg = param_arr[param_rx_quick_cfg].value; 2447 switch (rx_quick_cfg) { 2448 case CFG_NOT_SPECIFIED: 2449 prop = "rxdma-grp-cfg"; 2450 status = ddi_prop_lookup_string(DDI_DEV_T_NONE, 2451 nxgep->dip, 0, prop, (char **)&prop_val); 2452 if (status != DDI_PROP_SUCCESS) { 2453 NXGE_DEBUG_MSG((nxgep, CFG_CTL, 2454 " property %s not found", prop)); 2455 rdcgrp_cfg = CFG_L3_DISTRIBUTE; 2456 } else { 2457 token = nxge_get_config_token(prop_val); 2458 switch (token) { 2459 case L2_CLASSIFY: 2460 break; 2461 case CLASSIFY: 2462 case L3_CLASSIFY: 2463 case L3_DISTRIBUTE: 2464 case L3_TCAM: 2465 rdcgrp_cfg = CFG_L3_DISTRIBUTE; 2466 break; 2467 default: 2468 rdcgrp_cfg = CFG_L3_DISTRIBUTE; 2469 break; 2470 } 2471 ddi_prop_free(prop_val); 2472 } 2473 break; 2474 case CFG_L3_WEB: 2475 case CFG_L3_DISTRIBUTE: 2476 case CFG_L2_CLASSIFY: 2477 case CFG_L3_TCAM: 2478 rdcgrp_cfg = rx_quick_cfg; 2479 break; 2480 default: 2481 rdcgrp_cfg = CFG_L3_DISTRIBUTE; 2482 break; 2483 } 2484 2485 st_rdc = p_cfgp->start_rdc; 2486 2487 switch (rdcgrp_cfg) { 2488 case CFG_L3_DISTRIBUTE: 2489 case CFG_L3_WEB: 2490 case CFG_L3_TCAM: 2491 ndmas = p_cfgp->max_rdcs; 2492 ngrps = 1; 2493 rdcs_per_grp = ndmas / ngrps; 2494 break; 2495 case CFG_L2_CLASSIFY: 2496 ndmas = p_cfgp->max_rdcs / 2; 2497 if (p_cfgp->max_rdcs < 2) 2498 ndmas = 1; 2499 ngrps = 1; 2500 rdcs_per_grp = ndmas / ngrps; 2501 break; 2502 default: 2503 ngrps = p_cfgp->max_rdc_grpids; 2504 ndmas = p_cfgp->max_rdcs; 2505 rdcs_per_grp = ndmas / ngrps; 2506 break; 2507 } 2508 2509 for (i = 0; i < ngrps; i++) { 2510 uint8_t count = rdcs_per_grp; 2511 dc_map_t map = 0; 2512 2513 rdc_grp_p = &p_dma_cfgp->rdc_grps[ 2514 p_cfgp->def_mac_rxdma_grpid + i]; 2515 rdc_grp_p->start_rdc = st_rdc + i * rdcs_per_grp; 2516 rdc_grp_p->max_rdcs = rdcs_per_grp; 2517 rdc_grp_p->def_rdc = rdc_grp_p->start_rdc; 2518 2519 /* default to: 0, 1, 2, 3, ...., 0, 1, 2, 3.... */ 2520 while (count) { 2521 map |= (1 << count); 2522 count--; 2523 } 2524 map >>= 1; /* In case <start_rdc> is zero (0) */ 2525 map <<= rdc_grp_p->start_rdc; 2526 rdc_grp_p->map = map; 2527 2528 nxgep->rx_set.owned.map |= map; /* Owned, & not shared. */ 2529 2530 group = (nxge_grp_t *)nxge_grp_add(nxgep, NXGE_RECEIVE_GROUP); 2531 group->map = rdc_grp_p->map; 2532 2533 rdc_grp_p->config_method = RDC_TABLE_ENTRY_METHOD_SEQ; 2534 rdc_grp_p->flag = 1; /* This group has been configured. */ 2535 } 2536 2537 2538 /* default RDC */ 2539 p_cfgp->def_rdc = p_cfgp->start_rdc; 2540 nxgep->def_rdc = p_cfgp->start_rdc; 2541 2542 /* full 18 byte header ? */ 2543 p_dma_cfgp->rcr_full_header = NXGE_RCR_FULL_HEADER; 2544 p_dma_cfgp->rx_drr_weight = PT_DRR_WT_DEFAULT_10G; 2545 if (nxgep->function_num > 1) 2546 p_dma_cfgp->rx_drr_weight = PT_DRR_WT_DEFAULT_1G; 2547 p_dma_cfgp->rbr_size = nxge_rbr_size; 2548 p_dma_cfgp->rcr_size = nxge_rcr_size; 2549 2550 nxge_set_rdc_intr_property(nxgep); 2551 NXGE_DEBUG_MSG((nxgep, CFG_CTL, " <== nxge_set_hw_dma_config")); 2552 } 2553 2554 boolean_t 2555 nxge_check_rxdma_port_member(p_nxge_t nxgep, uint8_t rdc) 2556 { 2557 p_nxge_dma_pt_cfg_t p_dma_cfgp; 2558 p_nxge_hw_pt_cfg_t p_cfgp; 2559 int status = B_TRUE; 2560 2561 NXGE_DEBUG_MSG((nxgep, CFG2_CTL, "==> nxge_check_rxdma_port_member")); 2562 2563 p_dma_cfgp = (p_nxge_dma_pt_cfg_t)&nxgep->pt_config; 2564 p_cfgp = (p_nxge_hw_pt_cfg_t)&p_dma_cfgp->hw_config; 2565 2566 /* Receive DMA Channels */ 2567 if (rdc < p_cfgp->max_rdcs) 2568 status = B_TRUE; 2569 NXGE_DEBUG_MSG((nxgep, CFG2_CTL, " <== nxge_check_rxdma_port_member")); 2570 return (status); 2571 } 2572 2573 boolean_t 2574 nxge_check_txdma_port_member(p_nxge_t nxgep, uint8_t tdc) 2575 { 2576 int status = B_FALSE; 2577 2578 NXGE_DEBUG_MSG((nxgep, CFG2_CTL, "==> nxge_check_txdma_port_member")); 2579 2580 if (tdc >= nxgep->pt_config.hw_config.tdc.start && 2581 tdc < nxgep->pt_config.hw_config.tdc.count) 2582 status = B_TRUE; 2583 2584 NXGE_DEBUG_MSG((nxgep, CFG2_CTL, " <== nxge_check_txdma_port_member")); 2585 return (status); 2586 } 2587 2588 boolean_t 2589 nxge_check_rxdma_rdcgrp_member(p_nxge_t nxgep, uint8_t rdc_grp, uint8_t rdc) 2590 { 2591 p_nxge_dma_pt_cfg_t p_dma_cfgp; 2592 int status = B_TRUE; 2593 p_nxge_rdc_grp_t rdc_grp_p; 2594 2595 NXGE_DEBUG_MSG((nxgep, CFG2_CTL, 2596 " ==> nxge_check_rxdma_rdcgrp_member")); 2597 NXGE_DEBUG_MSG((nxgep, CFG2_CTL, " nxge_check_rxdma_rdcgrp_member" 2598 " rdc %d group %d", rdc, rdc_grp)); 2599 p_dma_cfgp = (p_nxge_dma_pt_cfg_t)&nxgep->pt_config; 2600 2601 rdc_grp_p = &p_dma_cfgp->rdc_grps[rdc_grp]; 2602 NXGE_DEBUG_MSG((nxgep, CFG2_CTL, " max %d ", rdc_grp_p->max_rdcs)); 2603 if (rdc >= rdc_grp_p->max_rdcs) { 2604 status = B_FALSE; 2605 } 2606 NXGE_DEBUG_MSG((nxgep, CFG2_CTL, 2607 " <== nxge_check_rxdma_rdcgrp_member")); 2608 return (status); 2609 } 2610 2611 boolean_t 2612 nxge_check_rdcgrp_port_member(p_nxge_t nxgep, uint8_t rdc_grp) 2613 { 2614 p_nxge_dma_pt_cfg_t p_dma_cfgp; 2615 p_nxge_hw_pt_cfg_t p_cfgp; 2616 int status = B_TRUE; 2617 2618 NXGE_DEBUG_MSG((nxgep, CFG2_CTL, "==> nxge_check_rdcgrp_port_member")); 2619 2620 p_dma_cfgp = (p_nxge_dma_pt_cfg_t)&nxgep->pt_config; 2621 p_cfgp = (p_nxge_hw_pt_cfg_t)&p_dma_cfgp->hw_config; 2622 2623 if (rdc_grp >= p_cfgp->max_rdc_grpids) 2624 status = B_FALSE; 2625 NXGE_DEBUG_MSG((nxgep, CFG2_CTL, " <== nxge_check_rdcgrp_port_member")); 2626 return (status); 2627 } 2628 2629 static void 2630 nxge_set_hw_vlan_class_config(p_nxge_t nxgep) 2631 { 2632 int i; 2633 p_nxge_dma_pt_cfg_t p_dma_cfgp; 2634 p_nxge_hw_pt_cfg_t p_cfgp; 2635 p_nxge_param_t param_arr; 2636 uint_t vlan_cnt; 2637 int *vlan_cfg_val; 2638 nxge_param_map_t *vmap; 2639 char *prop; 2640 p_nxge_class_pt_cfg_t p_class_cfgp; 2641 uint32_t good_cfg[32]; 2642 int good_count = 0; 2643 nxge_mv_cfg_t *vlan_tbl; 2644 2645 NXGE_DEBUG_MSG((nxgep, CFG_CTL, " ==> nxge_set_hw_vlan_config")); 2646 p_dma_cfgp = (p_nxge_dma_pt_cfg_t)&nxgep->pt_config; 2647 p_cfgp = (p_nxge_hw_pt_cfg_t)&p_dma_cfgp->hw_config; 2648 p_class_cfgp = (p_nxge_class_pt_cfg_t)&nxgep->class_config; 2649 2650 param_arr = nxgep->param_arr; 2651 prop = param_arr[param_vlan_2rdc_grp].fcode_name; 2652 2653 /* 2654 * By default, VLAN to RDC group mapping is disabled Need to read HW or 2655 * .conf properties to find out if mapping is required 2656 * 2657 * Format 2658 * 2659 * uint32_t array, each array entry specifying the VLAN id and the 2660 * mapping 2661 * 2662 * bit[30] = add bit[29] = remove bit[28] = preference bits[23-16] = 2663 * rdcgrp bits[15-0] = VLAN ID ( ) 2664 */ 2665 2666 for (i = 0; i < NXGE_MAX_VLANS; i++) { 2667 p_class_cfgp->vlan_tbl[i].flag = 0; 2668 } 2669 2670 vlan_tbl = (nxge_mv_cfg_t *)&p_class_cfgp->vlan_tbl[0]; 2671 if (ddi_prop_lookup_int_array(DDI_DEV_T_ANY, nxgep->dip, 0, prop, 2672 &vlan_cfg_val, &vlan_cnt) == DDI_PROP_SUCCESS) { 2673 for (i = 0; i < vlan_cnt; i++) { 2674 vmap = (nxge_param_map_t *)&vlan_cfg_val[i]; 2675 if ((vmap->param_id) && 2676 (vmap->param_id < NXGE_MAX_VLANS) && 2677 (vmap->map_to < 2678 p_cfgp->max_rdc_grpids) && 2679 (vmap->map_to >= (uint8_t)0)) { 2680 NXGE_DEBUG_MSG((nxgep, CFG2_CTL, 2681 " nxge_vlan_config mapping" 2682 " id %d grp %d", 2683 vmap->param_id, vmap->map_to)); 2684 good_cfg[good_count] = vlan_cfg_val[i]; 2685 if (vlan_tbl[vmap->param_id].flag == 0) 2686 good_count++; 2687 vlan_tbl[vmap->param_id].flag = 1; 2688 vlan_tbl[vmap->param_id].rdctbl = 2689 vmap->map_to + p_cfgp->def_mac_rxdma_grpid; 2690 vlan_tbl[vmap->param_id].mpr_npr = vmap->pref; 2691 } 2692 } 2693 ddi_prop_free(vlan_cfg_val); 2694 if (good_count != vlan_cnt) { 2695 (void) ddi_prop_update_int_array(DDI_DEV_T_NONE, 2696 nxgep->dip, prop, (int *)good_cfg, good_count); 2697 } 2698 } 2699 NXGE_DEBUG_MSG((nxgep, CFG_CTL, "<== nxge_set_hw_vlan_config")); 2700 } 2701 2702 static void 2703 nxge_set_hw_mac_class_config(p_nxge_t nxgep) 2704 { 2705 int i; 2706 p_nxge_dma_pt_cfg_t p_dma_cfgp; 2707 p_nxge_hw_pt_cfg_t p_cfgp; 2708 p_nxge_param_t param_arr; 2709 uint_t mac_cnt; 2710 int *mac_cfg_val; 2711 nxge_param_map_t *mac_map; 2712 char *prop; 2713 p_nxge_class_pt_cfg_t p_class_cfgp; 2714 int good_count = 0; 2715 int good_cfg[NXGE_MAX_MACS]; 2716 nxge_mv_cfg_t *mac_host_info; 2717 2718 NXGE_DEBUG_MSG((nxgep, CFG_CTL, "==> nxge_set_hw_mac_config")); 2719 2720 p_dma_cfgp = (p_nxge_dma_pt_cfg_t)&nxgep->pt_config; 2721 p_cfgp = (p_nxge_hw_pt_cfg_t)&p_dma_cfgp->hw_config; 2722 p_class_cfgp = (p_nxge_class_pt_cfg_t)&nxgep->class_config; 2723 mac_host_info = (nxge_mv_cfg_t *)&p_class_cfgp->mac_host_info[0]; 2724 2725 param_arr = nxgep->param_arr; 2726 prop = param_arr[param_mac_2rdc_grp].fcode_name; 2727 2728 for (i = 0; i < NXGE_MAX_MACS; i++) { 2729 p_class_cfgp->mac_host_info[i].flag = 0; 2730 p_class_cfgp->mac_host_info[i].rdctbl = 2731 p_cfgp->def_mac_rxdma_grpid; 2732 } 2733 2734 if (ddi_prop_lookup_int_array(DDI_DEV_T_ANY, nxgep->dip, 0, prop, 2735 &mac_cfg_val, &mac_cnt) == DDI_PROP_SUCCESS) { 2736 for (i = 0; i < mac_cnt; i++) { 2737 mac_map = (nxge_param_map_t *)&mac_cfg_val[i]; 2738 if ((mac_map->param_id < p_cfgp->max_macs) && 2739 (mac_map->map_to < 2740 p_cfgp->max_rdc_grpids) && 2741 (mac_map->map_to >= (uint8_t)0)) { 2742 NXGE_DEBUG_MSG((nxgep, CFG2_CTL, 2743 " nxge_mac_config mapping" 2744 " id %d grp %d", 2745 mac_map->param_id, mac_map->map_to)); 2746 mac_host_info[mac_map->param_id].mpr_npr = 2747 mac_map->pref; 2748 mac_host_info[mac_map->param_id].rdctbl = 2749 mac_map->map_to + 2750 p_cfgp->def_mac_rxdma_grpid; 2751 good_cfg[good_count] = mac_cfg_val[i]; 2752 if (mac_host_info[mac_map->param_id].flag == 0) 2753 good_count++; 2754 mac_host_info[mac_map->param_id].flag = 1; 2755 } 2756 } 2757 ddi_prop_free(mac_cfg_val); 2758 if (good_count != mac_cnt) { 2759 (void) ddi_prop_update_int_array(DDI_DEV_T_NONE, 2760 nxgep->dip, prop, good_cfg, good_count); 2761 } 2762 } 2763 NXGE_DEBUG_MSG((nxgep, CFG_CTL, "<== nxge_set_hw_mac_config")); 2764 } 2765 2766 static void 2767 nxge_set_hw_class_config(p_nxge_t nxgep) 2768 { 2769 int i; 2770 p_nxge_param_t param_arr; 2771 int *int_prop_val; 2772 uint32_t cfg_value; 2773 char *prop; 2774 p_nxge_class_pt_cfg_t p_class_cfgp; 2775 int start_prop, end_prop; 2776 uint_t prop_cnt; 2777 2778 NXGE_DEBUG_MSG((nxgep, CFG_CTL, " ==> nxge_set_hw_class_config")); 2779 2780 p_class_cfgp = (p_nxge_class_pt_cfg_t)&nxgep->class_config; 2781 param_arr = nxgep->param_arr; 2782 start_prop = param_class_opt_ip_usr4; 2783 end_prop = param_class_opt_ipv6_sctp; 2784 2785 for (i = start_prop; i <= end_prop; i++) { 2786 prop = param_arr[i].fcode_name; 2787 if (ddi_prop_lookup_int_array(DDI_DEV_T_ANY, nxgep->dip, 2788 0, prop, &int_prop_val, 2789 &prop_cnt) == DDI_PROP_SUCCESS) { 2790 cfg_value = (uint32_t)*int_prop_val; 2791 ddi_prop_free(int_prop_val); 2792 } else { 2793 cfg_value = (uint32_t)param_arr[i].value; 2794 } 2795 p_class_cfgp->class_cfg[i - start_prop] = cfg_value; 2796 } 2797 2798 prop = param_arr[param_h1_init_value].fcode_name; 2799 2800 if (ddi_prop_lookup_int_array(DDI_DEV_T_ANY, nxgep->dip, 0, prop, 2801 &int_prop_val, &prop_cnt) == DDI_PROP_SUCCESS) { 2802 cfg_value = (uint32_t)*int_prop_val; 2803 ddi_prop_free(int_prop_val); 2804 } else { 2805 cfg_value = (uint32_t)param_arr[param_h1_init_value].value; 2806 } 2807 2808 p_class_cfgp->init_h1 = (uint32_t)cfg_value; 2809 prop = param_arr[param_h2_init_value].fcode_name; 2810 2811 if (ddi_prop_lookup_int_array(DDI_DEV_T_ANY, nxgep->dip, 0, prop, 2812 &int_prop_val, &prop_cnt) == DDI_PROP_SUCCESS) { 2813 cfg_value = (uint32_t)*int_prop_val; 2814 ddi_prop_free(int_prop_val); 2815 } else { 2816 cfg_value = (uint32_t)param_arr[param_h2_init_value].value; 2817 } 2818 2819 p_class_cfgp->init_h2 = (uint16_t)cfg_value; 2820 NXGE_DEBUG_MSG((nxgep, CFG_CTL, " <== nxge_set_hw_class_config")); 2821 } 2822 2823 nxge_status_t 2824 nxge_ldgv_init_n2(p_nxge_t nxgep, int *navail_p, int *nrequired_p) 2825 { 2826 int i, maxldvs, maxldgs, nldvs; 2827 int ldv, endldg; 2828 uint8_t func; 2829 uint8_t channel; 2830 uint8_t chn_start; 2831 boolean_t own_sys_err = B_FALSE, own_fzc = B_FALSE; 2832 p_nxge_dma_pt_cfg_t p_dma_cfgp; 2833 p_nxge_hw_pt_cfg_t p_cfgp; 2834 p_nxge_ldgv_t ldgvp; 2835 p_nxge_ldg_t ldgp, ptr; 2836 p_nxge_ldv_t ldvp; 2837 nxge_status_t status = NXGE_OK; 2838 nxge_grp_set_t *set; 2839 2840 NXGE_DEBUG_MSG((nxgep, INT_CTL, "==> nxge_ldgv_init_n2")); 2841 if (!*navail_p) { 2842 *nrequired_p = 0; 2843 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 2844 "<== nxge_ldgv_init:no avail")); 2845 return (NXGE_ERROR); 2846 } 2847 /* 2848 * N2/NIU: one logical device owns one logical group. and each 2849 * device/group will be assigned one vector by Hypervisor. 2850 */ 2851 p_dma_cfgp = (p_nxge_dma_pt_cfg_t)&nxgep->pt_config; 2852 p_cfgp = (p_nxge_hw_pt_cfg_t)&p_dma_cfgp->hw_config; 2853 maxldgs = p_cfgp->max_ldgs; 2854 if (!maxldgs) { 2855 /* No devices configured. */ 2856 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, "<== nxge_ldgv_init_n2: " 2857 "no logical groups configured.")); 2858 return (NXGE_ERROR); 2859 } else { 2860 maxldvs = maxldgs + 1; 2861 } 2862 2863 /* 2864 * If function zero instance, it needs to handle the system and MIF 2865 * error interrupts. MIF interrupt may not be needed for N2/NIU. 2866 */ 2867 func = nxgep->function_num; 2868 if (func == 0) { 2869 own_sys_err = B_TRUE; 2870 if (!p_cfgp->ser_ldvid) { 2871 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 2872 "nxge_ldgv_init_n2: func 0, ERR ID not set!")); 2873 } 2874 /* MIF interrupt */ 2875 if (!p_cfgp->mif_ldvid) { 2876 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 2877 "nxge_ldgv_init_n2: func 0, MIF ID not set!")); 2878 } 2879 } 2880 2881 /* 2882 * Assume single partition, each function owns mac. 2883 */ 2884 if (!nxge_use_partition) 2885 own_fzc = B_TRUE; 2886 2887 ldgvp = nxgep->ldgvp; 2888 if (ldgvp == NULL) { 2889 ldgvp = KMEM_ZALLOC(sizeof (nxge_ldgv_t), KM_SLEEP); 2890 nxgep->ldgvp = ldgvp; 2891 ldgvp->maxldgs = (uint8_t)maxldgs; 2892 ldgvp->maxldvs = (uint8_t)maxldvs; 2893 ldgp = ldgvp->ldgp = KMEM_ZALLOC( 2894 sizeof (nxge_ldg_t) * maxldgs, KM_SLEEP); 2895 ldvp = ldgvp->ldvp = KMEM_ZALLOC( 2896 sizeof (nxge_ldv_t) * maxldvs, KM_SLEEP); 2897 } else { 2898 ldgp = ldgvp->ldgp; 2899 ldvp = ldgvp->ldvp; 2900 } 2901 2902 ldgvp->ndma_ldvs = p_cfgp->tdc.owned + p_cfgp->max_rdcs; 2903 ldgvp->tmres = NXGE_TIMER_RESO; 2904 2905 NXGE_DEBUG_MSG((nxgep, INT_CTL, 2906 "==> nxge_ldgv_init_n2: maxldvs %d maxldgs %d", 2907 maxldvs, maxldgs)); 2908 2909 /* logical start_ldg is ldv */ 2910 ptr = ldgp; 2911 for (i = 0; i < maxldgs; i++) { 2912 ptr->func = func; 2913 ptr->arm = B_TRUE; 2914 ptr->vldg_index = (uint8_t)i; 2915 ptr->ldg_timer = NXGE_TIMER_LDG; 2916 ptr->ldg = p_cfgp->ldg[i]; 2917 ptr->sys_intr_handler = nxge_intr; 2918 ptr->nldvs = 0; 2919 ptr->ldvp = NULL; 2920 ptr->nxgep = nxgep; 2921 NXGE_DEBUG_MSG((nxgep, INT_CTL, 2922 "==> nxge_ldgv_init_n2: maxldvs %d maxldgs %d " 2923 "ldg %d ldgptr $%p", 2924 maxldvs, maxldgs, ptr->ldg, ptr)); 2925 ptr++; 2926 } 2927 2928 endldg = NXGE_INT_MAX_LDG; 2929 nldvs = 0; 2930 ldgvp->nldvs = 0; 2931 ldgp->ldvp = NULL; 2932 *nrequired_p = 0; 2933 2934 /* 2935 * logical device group table is organized in the following order (same 2936 * as what interrupt property has). function 0: owns MAC, MIF, error, 2937 * rx, tx. function 1: owns MAC, rx, tx. 2938 */ 2939 2940 if (own_fzc && p_cfgp->mac_ldvid) { 2941 /* Each function should own MAC interrupt */ 2942 ldv = p_cfgp->mac_ldvid; 2943 ldvp->ldv = (uint8_t)ldv; 2944 ldvp->is_mac = B_TRUE; 2945 ldvp->ldv_intr_handler = nxge_mac_intr; 2946 ldvp->ldv_ldf_masks = 0; 2947 ldvp->nxgep = nxgep; 2948 NXGE_DEBUG_MSG((nxgep, INT_CTL, 2949 "==> nxge_ldgv_init_n2(mac): maxldvs %d ldv %d " 2950 "ldg %d ldgptr $%p ldvptr $%p", 2951 maxldvs, ldv, ldgp->ldg, ldgp, ldvp)); 2952 nxge_ldgv_setup(&ldgp, &ldvp, ldv, endldg, nrequired_p); 2953 nldvs++; 2954 } 2955 2956 if (own_fzc && p_cfgp->mif_ldvid) { 2957 ldv = p_cfgp->mif_ldvid; 2958 ldvp->ldv = (uint8_t)ldv; 2959 ldvp->is_mif = B_TRUE; 2960 ldvp->ldv_intr_handler = nxge_mif_intr; 2961 ldvp->ldv_ldf_masks = 0; 2962 ldvp->nxgep = nxgep; 2963 NXGE_DEBUG_MSG((nxgep, INT_CTL, 2964 "==> nxge_ldgv_init_n2(mif): maxldvs %d ldv %d " 2965 "ldg %d ldgptr $%p ldvptr $%p", 2966 maxldvs, ldv, ldgp->ldg, ldgp, ldvp)); 2967 nxge_ldgv_setup(&ldgp, &ldvp, ldv, endldg, nrequired_p); 2968 nldvs++; 2969 } 2970 2971 ldv = NXGE_SYS_ERROR_LD; 2972 ldvp->use_timer = B_TRUE; 2973 if (own_sys_err && p_cfgp->ser_ldvid) { 2974 ldv = p_cfgp->ser_ldvid; 2975 /* 2976 * Unmask the system interrupt states. 2977 */ 2978 (void) nxge_fzc_sys_err_mask_set(nxgep, SYS_ERR_SMX_MASK | 2979 SYS_ERR_IPP_MASK | SYS_ERR_TXC_MASK | 2980 SYS_ERR_ZCP_MASK); 2981 } 2982 ldvp->ldv = (uint8_t)ldv; 2983 ldvp->is_syserr = B_TRUE; 2984 ldvp->ldv_intr_handler = nxge_syserr_intr; 2985 ldvp->ldv_ldf_masks = 0; 2986 ldvp->nxgep = nxgep; 2987 ldgvp->ldvp_syserr = ldvp; 2988 2989 NXGE_DEBUG_MSG((nxgep, INT_CTL, 2990 "==> nxge_ldgv_init_n2(syserr): maxldvs %d ldv %d " 2991 "ldg %d ldgptr $%p ldvptr p%p", 2992 maxldvs, ldv, ldgp->ldg, ldgp, ldvp)); 2993 2994 if (own_sys_err && p_cfgp->ser_ldvid) { 2995 (void) nxge_ldgv_setup(&ldgp, &ldvp, ldv, endldg, nrequired_p); 2996 } else { 2997 ldvp++; 2998 } 2999 3000 nldvs++; 3001 3002 NXGE_DEBUG_MSG((nxgep, INT_CTL, "==> nxge_ldgv_init_n2: " 3003 "(before rx) func %d nldvs %d navail %d nrequired %d", 3004 func, nldvs, *navail_p, *nrequired_p)); 3005 3006 /* 3007 * Start with RDC to configure logical devices for each group. 3008 */ 3009 chn_start = p_cfgp->ldg_chn_start; 3010 set = &nxgep->rx_set; 3011 for (channel = 0; channel < NXGE_MAX_RDCS; channel++) { 3012 if ((1 << channel) & set->owned.map) { 3013 ldvp->is_rxdma = B_TRUE; 3014 ldvp->ldv = (uint8_t)channel + NXGE_RDMA_LD_START; 3015 ldvp->channel = channel; 3016 ldvp->vdma_index = (uint8_t)channel; 3017 ldvp->ldv_intr_handler = nxge_rx_intr; 3018 ldvp->ldv_ldf_masks = 0; 3019 ldvp->nxgep = nxgep; 3020 ldgp->ldg = p_cfgp->ldg[chn_start]; 3021 3022 NXGE_DEBUG_MSG((nxgep, INT_CTL, 3023 "==> nxge_ldgv_init_n2(rx%d): maxldvs %d ldv %d " 3024 "ldg %d ldgptr 0x%016llx ldvptr 0x%016llx", 3025 i, maxldvs, ldv, ldgp->ldg, ldgp, ldvp)); 3026 nxge_ldgv_setup(&ldgp, &ldvp, ldvp->ldv, 3027 endldg, nrequired_p); 3028 nldvs++; 3029 chn_start++; 3030 } 3031 } 3032 3033 NXGE_DEBUG_MSG((nxgep, INT_CTL, "==> nxge_ldgv_init_n2: " 3034 "func %d nldvs %d navail %d nrequired %d", 3035 func, nldvs, *navail_p, *nrequired_p)); 3036 3037 NXGE_DEBUG_MSG((nxgep, INT_CTL, "==> nxge_ldgv_init_n2: " 3038 "func %d nldvs %d navail %d nrequired %d ldgp 0x%llx " 3039 "ldvp 0x%llx", 3040 func, nldvs, *navail_p, *nrequired_p, ldgp, ldvp)); 3041 /* 3042 * Transmit DMA channels. 3043 */ 3044 chn_start = p_cfgp->ldg_chn_start + 8; 3045 set = &nxgep->tx_set; 3046 for (channel = 0; channel < NXGE_MAX_TDCS; channel++) { 3047 if ((1 << channel) & set->owned.map) { 3048 ldvp->is_txdma = B_TRUE; 3049 ldvp->ldv = (uint8_t)channel + NXGE_TDMA_LD_START; 3050 ldvp->channel = channel; 3051 ldvp->vdma_index = (uint8_t)channel; 3052 ldvp->ldv_intr_handler = nxge_tx_intr; 3053 ldvp->ldv_ldf_masks = 0; 3054 ldgp->ldg = p_cfgp->ldg[chn_start]; 3055 ldvp->nxgep = nxgep; 3056 NXGE_DEBUG_MSG((nxgep, INT_CTL, 3057 "==> nxge_ldgv_init_n2(tx%d): maxldvs %d ldv %d " 3058 "ldg %d ldgptr %p ldvptr %p", 3059 channel, maxldvs, ldv, ldgp->ldg, ldgp, ldvp)); 3060 nxge_ldgv_setup(&ldgp, &ldvp, ldvp->ldv, 3061 endldg, nrequired_p); 3062 nldvs++; 3063 chn_start++; 3064 } 3065 } 3066 3067 ldgvp->ldg_intrs = *nrequired_p; 3068 ldgvp->nldvs = (uint8_t)nldvs; 3069 3070 NXGE_DEBUG_MSG((nxgep, INT_CTL, "==> nxge_ldgv_init_n2: " 3071 "func %d nldvs %d maxgrps %d navail %d nrequired %d", 3072 func, nldvs, maxldgs, *navail_p, *nrequired_p)); 3073 3074 NXGE_DEBUG_MSG((nxgep, INT_CTL, "<== nxge_ldgv_init_n2")); 3075 return (status); 3076 } 3077 3078 /* 3079 * Interrupts related interface functions. 3080 */ 3081 3082 nxge_status_t 3083 nxge_ldgv_init(p_nxge_t nxgep, int *navail_p, int *nrequired_p) 3084 { 3085 int i, maxldvs, maxldgs, nldvs; 3086 int ldv, ldg, endldg, ngrps; 3087 uint8_t func; 3088 uint8_t channel; 3089 boolean_t own_sys_err = B_FALSE, own_fzc = B_FALSE; 3090 p_nxge_dma_pt_cfg_t p_dma_cfgp; 3091 p_nxge_hw_pt_cfg_t p_cfgp; 3092 p_nxge_ldgv_t ldgvp; 3093 p_nxge_ldg_t ldgp, ptr; 3094 p_nxge_ldv_t ldvp; 3095 nxge_grp_set_t *set; 3096 3097 nxge_status_t status = NXGE_OK; 3098 3099 NXGE_DEBUG_MSG((nxgep, INT_CTL, "==> nxge_ldgv_init")); 3100 if (!*navail_p) { 3101 *nrequired_p = 0; 3102 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 3103 "<== nxge_ldgv_init:no avail")); 3104 return (NXGE_ERROR); 3105 } 3106 p_dma_cfgp = (p_nxge_dma_pt_cfg_t)&nxgep->pt_config; 3107 p_cfgp = (p_nxge_hw_pt_cfg_t)&p_dma_cfgp->hw_config; 3108 3109 nldvs = p_cfgp->tdc.owned + p_cfgp->max_rdcs; 3110 3111 /* 3112 * If function zero instance, it needs to handle the system error 3113 * interrupts. 3114 */ 3115 func = nxgep->function_num; 3116 if (func == 0) { 3117 nldvs++; 3118 own_sys_err = B_TRUE; 3119 } else { 3120 /* use timer */ 3121 nldvs++; 3122 } 3123 3124 /* 3125 * Assume single partition, each function owns mac. 3126 */ 3127 if (!nxge_use_partition) { 3128 /* mac */ 3129 nldvs++; 3130 /* MIF */ 3131 nldvs++; 3132 own_fzc = B_TRUE; 3133 } 3134 maxldvs = nldvs; 3135 maxldgs = p_cfgp->max_ldgs; 3136 if (!maxldvs || !maxldgs) { 3137 /* No devices configured. */ 3138 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, "<== nxge_ldgv_init: " 3139 "no logical devices or groups configured.")); 3140 return (NXGE_ERROR); 3141 } 3142 ldgvp = nxgep->ldgvp; 3143 if (ldgvp == NULL) { 3144 ldgvp = KMEM_ZALLOC(sizeof (nxge_ldgv_t), KM_SLEEP); 3145 nxgep->ldgvp = ldgvp; 3146 ldgvp->maxldgs = (uint8_t)maxldgs; 3147 ldgvp->maxldvs = (uint8_t)maxldvs; 3148 ldgp = ldgvp->ldgp = KMEM_ZALLOC(sizeof (nxge_ldg_t) * maxldgs, 3149 KM_SLEEP); 3150 ldvp = ldgvp->ldvp = KMEM_ZALLOC(sizeof (nxge_ldv_t) * maxldvs, 3151 KM_SLEEP); 3152 } 3153 ldgvp->ndma_ldvs = p_cfgp->tdc.owned + p_cfgp->max_rdcs; 3154 ldgvp->tmres = NXGE_TIMER_RESO; 3155 3156 NXGE_DEBUG_MSG((nxgep, INT_CTL, 3157 "==> nxge_ldgv_init: maxldvs %d maxldgs %d nldvs %d", 3158 maxldvs, maxldgs, nldvs)); 3159 ldg = p_cfgp->start_ldg; 3160 ptr = ldgp; 3161 for (i = 0; i < maxldgs; i++) { 3162 ptr->func = func; 3163 ptr->arm = B_TRUE; 3164 ptr->vldg_index = (uint8_t)i; 3165 ptr->ldg_timer = NXGE_TIMER_LDG; 3166 ptr->ldg = ldg++; 3167 ptr->sys_intr_handler = nxge_intr; 3168 ptr->nldvs = 0; 3169 ptr->nxgep = nxgep; 3170 NXGE_DEBUG_MSG((nxgep, INT_CTL, 3171 "==> nxge_ldgv_init: maxldvs %d maxldgs %d ldg %d", 3172 maxldvs, maxldgs, ptr->ldg)); 3173 ptr++; 3174 } 3175 3176 ldg = p_cfgp->start_ldg; 3177 if (maxldgs > *navail_p) { 3178 ngrps = *navail_p; 3179 } else { 3180 ngrps = maxldgs; 3181 } 3182 endldg = ldg + ngrps; 3183 3184 /* 3185 * Receive DMA channels. 3186 */ 3187 nldvs = 0; 3188 ldgvp->nldvs = 0; 3189 ldgp->ldvp = NULL; 3190 *nrequired_p = 0; 3191 3192 /* 3193 * Start with RDC to configure logical devices for each group. 3194 */ 3195 set = &nxgep->rx_set; 3196 for (channel = 0; channel < NXGE_MAX_RDCS; channel++) { 3197 if ((1 << channel) & set->owned.map) { 3198 /* For now, <channel & <vdma_index> are the same. */ 3199 ldvp->is_rxdma = B_TRUE; 3200 ldvp->ldv = (uint8_t)channel + NXGE_RDMA_LD_START; 3201 ldvp->channel = channel; 3202 ldvp->vdma_index = (uint8_t)channel; 3203 ldvp->ldv_intr_handler = nxge_rx_intr; 3204 ldvp->ldv_ldf_masks = 0; 3205 ldvp->use_timer = B_FALSE; 3206 ldvp->nxgep = nxgep; 3207 nxge_ldgv_setup(&ldgp, &ldvp, ldvp->ldv, 3208 endldg, nrequired_p); 3209 nldvs++; 3210 } 3211 } 3212 3213 /* 3214 * Transmit DMA channels. 3215 */ 3216 set = &nxgep->tx_set; 3217 for (channel = 0; channel < NXGE_MAX_TDCS; channel++) { 3218 if ((1 << channel) & set->owned.map) { 3219 /* For now, <channel & <vdma_index> are the same. */ 3220 ldvp->is_txdma = B_TRUE; 3221 ldvp->ldv = (uint8_t)channel + NXGE_TDMA_LD_START; 3222 ldvp->channel = channel; 3223 ldvp->vdma_index = (uint8_t)channel; 3224 ldvp->ldv_intr_handler = nxge_tx_intr; 3225 ldvp->ldv_ldf_masks = 0; 3226 ldvp->use_timer = B_FALSE; 3227 ldvp->nxgep = nxgep; 3228 nxge_ldgv_setup(&ldgp, &ldvp, ldvp->ldv, 3229 endldg, nrequired_p); 3230 nldvs++; 3231 } 3232 } 3233 3234 if (own_fzc) { 3235 ldv = NXGE_MIF_LD; 3236 ldvp->ldv = (uint8_t)ldv; 3237 ldvp->is_mif = B_TRUE; 3238 ldvp->ldv_intr_handler = nxge_mif_intr; 3239 ldvp->ldv_ldf_masks = 0; 3240 ldvp->use_timer = B_FALSE; 3241 ldvp->nxgep = nxgep; 3242 nxge_ldgv_setup(&ldgp, &ldvp, ldv, endldg, nrequired_p); 3243 nldvs++; 3244 } 3245 /* 3246 * MAC port (function zero control) 3247 */ 3248 if (own_fzc) { 3249 ldvp->is_mac = B_TRUE; 3250 ldvp->ldv_intr_handler = nxge_mac_intr; 3251 ldvp->ldv_ldf_masks = 0; 3252 ldv = func + NXGE_MAC_LD_START; 3253 ldvp->ldv = (uint8_t)ldv; 3254 ldvp->use_timer = B_FALSE; 3255 ldvp->nxgep = nxgep; 3256 nxge_ldgv_setup(&ldgp, &ldvp, ldv, endldg, nrequired_p); 3257 nldvs++; 3258 } 3259 NXGE_DEBUG_MSG((nxgep, INT_CTL, "==> nxge_ldgv_init: " 3260 "func %d nldvs %d navail %d nrequired %d", 3261 func, nldvs, *navail_p, *nrequired_p)); 3262 /* 3263 * Function 0 owns system error interrupts. 3264 */ 3265 ldvp->use_timer = B_TRUE; 3266 if (own_sys_err) { 3267 ldv = NXGE_SYS_ERROR_LD; 3268 ldvp->ldv = (uint8_t)ldv; 3269 ldvp->is_syserr = B_TRUE; 3270 ldvp->ldv_intr_handler = nxge_syserr_intr; 3271 ldvp->ldv_ldf_masks = 0; 3272 ldvp->nxgep = nxgep; 3273 ldgvp->ldvp_syserr = ldvp; 3274 /* 3275 * Unmask the system interrupt states. 3276 */ 3277 (void) nxge_fzc_sys_err_mask_set(nxgep, SYS_ERR_SMX_MASK | 3278 SYS_ERR_IPP_MASK | SYS_ERR_TXC_MASK | 3279 SYS_ERR_ZCP_MASK); 3280 3281 (void) nxge_ldgv_setup(&ldgp, &ldvp, ldv, endldg, nrequired_p); 3282 nldvs++; 3283 } else { 3284 ldv = NXGE_SYS_ERROR_LD; 3285 ldvp->ldv = (uint8_t)ldv; 3286 ldvp->is_syserr = B_TRUE; 3287 ldvp->ldv_intr_handler = nxge_syserr_intr; 3288 ldvp->nxgep = nxgep; 3289 ldvp->ldv_ldf_masks = 0; 3290 ldgvp->ldvp_syserr = ldvp; 3291 } 3292 3293 ldgvp->ldg_intrs = *nrequired_p; 3294 3295 NXGE_DEBUG_MSG((nxgep, INT_CTL, "==> nxge_ldgv_init: " 3296 "func %d nldvs %d navail %d nrequired %d", 3297 func, nldvs, *navail_p, *nrequired_p)); 3298 3299 NXGE_DEBUG_MSG((nxgep, INT_CTL, "<== nxge_ldgv_init")); 3300 return (status); 3301 } 3302 3303 nxge_status_t 3304 nxge_ldgv_uninit(p_nxge_t nxgep) 3305 { 3306 p_nxge_ldgv_t ldgvp; 3307 3308 NXGE_DEBUG_MSG((nxgep, INT_CTL, "==> nxge_ldgv_uninit")); 3309 ldgvp = nxgep->ldgvp; 3310 if (ldgvp == NULL) { 3311 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, "<== nxge_ldgv_uninit: " 3312 "no logical group configured.")); 3313 return (NXGE_OK); 3314 } 3315 if (ldgvp->ldgp) { 3316 KMEM_FREE(ldgvp->ldgp, sizeof (nxge_ldg_t) * ldgvp->maxldgs); 3317 } 3318 if (ldgvp->ldvp) { 3319 KMEM_FREE(ldgvp->ldvp, sizeof (nxge_ldv_t) * ldgvp->maxldvs); 3320 } 3321 KMEM_FREE(ldgvp, sizeof (nxge_ldgv_t)); 3322 nxgep->ldgvp = NULL; 3323 3324 NXGE_DEBUG_MSG((nxgep, INT_CTL, "<== nxge_ldgv_uninit")); 3325 return (NXGE_OK); 3326 } 3327 3328 nxge_status_t 3329 nxge_intr_ldgv_init(p_nxge_t nxgep) 3330 { 3331 nxge_status_t status = NXGE_OK; 3332 3333 NXGE_DEBUG_MSG((nxgep, INT_CTL, "==> nxge_intr_ldgv_init")); 3334 /* 3335 * Configure the logical device group numbers, state vectors and 3336 * interrupt masks for each logical device. 3337 */ 3338 status = nxge_fzc_intr_init(nxgep); 3339 3340 /* 3341 * Configure logical device masks and timers. 3342 */ 3343 status = nxge_intr_mask_mgmt(nxgep); 3344 3345 NXGE_DEBUG_MSG((nxgep, INT_CTL, "<== nxge_intr_ldgv_init")); 3346 return (status); 3347 } 3348 3349 nxge_status_t 3350 nxge_intr_mask_mgmt(p_nxge_t nxgep) 3351 { 3352 p_nxge_ldgv_t ldgvp; 3353 p_nxge_ldg_t ldgp; 3354 p_nxge_ldv_t ldvp; 3355 npi_handle_t handle; 3356 int i, j; 3357 npi_status_t rs = NPI_SUCCESS; 3358 3359 NXGE_DEBUG_MSG((nxgep, INT_CTL, "==> nxge_intr_mask_mgmt")); 3360 3361 if ((ldgvp = nxgep->ldgvp) == NULL) { 3362 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 3363 "<== nxge_intr_mask_mgmt: Null ldgvp")); 3364 return (NXGE_ERROR); 3365 } 3366 handle = NXGE_DEV_NPI_HANDLE(nxgep); 3367 ldgp = ldgvp->ldgp; 3368 ldvp = ldgvp->ldvp; 3369 if (ldgp == NULL || ldvp == NULL) { 3370 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 3371 "<== nxge_intr_mask_mgmt: Null ldgp or ldvp")); 3372 return (NXGE_ERROR); 3373 } 3374 NXGE_DEBUG_MSG((nxgep, INT_CTL, 3375 "==> nxge_intr_mask_mgmt: # of intrs %d ", ldgvp->ldg_intrs)); 3376 /* Initialize masks. */ 3377 if (nxgep->niu_type != N2_NIU) { 3378 NXGE_DEBUG_MSG((nxgep, INT_CTL, 3379 "==> nxge_intr_mask_mgmt(Neptune): # intrs %d ", 3380 ldgvp->ldg_intrs)); 3381 for (i = 0; i < ldgvp->ldg_intrs; i++, ldgp++) { 3382 NXGE_DEBUG_MSG((nxgep, INT_CTL, 3383 "==> nxge_intr_mask_mgmt(Neptune): # ldv %d " 3384 "in group %d", ldgp->nldvs, ldgp->ldg)); 3385 for (j = 0; j < ldgp->nldvs; j++, ldvp++) { 3386 NXGE_DEBUG_MSG((nxgep, INT_CTL, 3387 "==> nxge_intr_mask_mgmt: set ldv # %d " 3388 "for ldg %d", ldvp->ldv, ldgp->ldg)); 3389 rs = npi_intr_mask_set(handle, ldvp->ldv, 3390 ldvp->ldv_ldf_masks); 3391 if (rs != NPI_SUCCESS) { 3392 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 3393 "<== nxge_intr_mask_mgmt: " 3394 "set mask failed " 3395 " rs 0x%x ldv %d mask 0x%x", 3396 rs, ldvp->ldv, 3397 ldvp->ldv_ldf_masks)); 3398 return (NXGE_ERROR | rs); 3399 } 3400 NXGE_DEBUG_MSG((nxgep, INT_CTL, 3401 "==> nxge_intr_mask_mgmt: " 3402 "set mask OK " 3403 " rs 0x%x ldv %d mask 0x%x", 3404 rs, ldvp->ldv, 3405 ldvp->ldv_ldf_masks)); 3406 } 3407 } 3408 } 3409 ldgp = ldgvp->ldgp; 3410 /* Configure timer and arm bit */ 3411 for (i = 0; i < nxgep->ldgvp->ldg_intrs; i++, ldgp++) { 3412 rs = npi_intr_ldg_mgmt_set(handle, ldgp->ldg, 3413 ldgp->arm, ldgp->ldg_timer); 3414 if (rs != NPI_SUCCESS) { 3415 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 3416 "<== nxge_intr_mask_mgmt: " 3417 "set timer failed " 3418 " rs 0x%x dg %d timer 0x%x", 3419 rs, ldgp->ldg, ldgp->ldg_timer)); 3420 return (NXGE_ERROR | rs); 3421 } 3422 NXGE_DEBUG_MSG((nxgep, INT_CTL, 3423 "==> nxge_intr_mask_mgmt: " 3424 "set timer OK " 3425 " rs 0x%x ldg %d timer 0x%x", 3426 rs, ldgp->ldg, ldgp->ldg_timer)); 3427 } 3428 3429 NXGE_DEBUG_MSG((nxgep, INT_CTL, "<== nxge_fzc_intr_mask_mgmt")); 3430 return (NXGE_OK); 3431 } 3432 3433 nxge_status_t 3434 nxge_intr_mask_mgmt_set(p_nxge_t nxgep, boolean_t on) 3435 { 3436 p_nxge_ldgv_t ldgvp; 3437 p_nxge_ldg_t ldgp; 3438 p_nxge_ldv_t ldvp; 3439 npi_handle_t handle; 3440 int i, j; 3441 npi_status_t rs = NPI_SUCCESS; 3442 3443 NXGE_DEBUG_MSG((nxgep, INT_CTL, 3444 "==> nxge_intr_mask_mgmt_set (%d)", on)); 3445 3446 if (nxgep->niu_type == N2_NIU) { 3447 NXGE_DEBUG_MSG((nxgep, INT_CTL, 3448 "<== nxge_intr_mask_mgmt_set (%d) not set (N2/NIU)", 3449 on)); 3450 return (NXGE_ERROR); 3451 } 3452 3453 if ((ldgvp = nxgep->ldgvp) == NULL) { 3454 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 3455 "==> nxge_intr_mask_mgmt_set: Null ldgvp")); 3456 return (NXGE_ERROR); 3457 } 3458 3459 handle = NXGE_DEV_NPI_HANDLE(nxgep); 3460 ldgp = ldgvp->ldgp; 3461 ldvp = ldgvp->ldvp; 3462 if (ldgp == NULL || ldvp == NULL) { 3463 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 3464 "<== nxge_intr_mask_mgmt_set: Null ldgp or ldvp")); 3465 return (NXGE_ERROR); 3466 } 3467 /* set masks. */ 3468 for (i = 0; i < ldgvp->ldg_intrs; i++, ldgp++) { 3469 NXGE_DEBUG_MSG((nxgep, INT_CTL, 3470 "==> nxge_intr_mask_mgmt_set: flag %d ldg %d" 3471 "set mask nldvs %d", on, ldgp->ldg, ldgp->nldvs)); 3472 for (j = 0; j < ldgp->nldvs; j++, ldvp++) { 3473 NXGE_DEBUG_MSG((nxgep, INT_CTL, 3474 "==> nxge_intr_mask_mgmt_set: " 3475 "for %d %d flag %d", i, j, on)); 3476 if (on) { 3477 ldvp->ldv_ldf_masks = 0; 3478 NXGE_DEBUG_MSG((nxgep, INT_CTL, 3479 "==> nxge_intr_mask_mgmt_set: " 3480 "ON mask off")); 3481 } else if (!on) { 3482 ldvp->ldv_ldf_masks = (uint8_t)LD_IM1_MASK; 3483 NXGE_DEBUG_MSG((nxgep, INT_CTL, 3484 "==> nxge_intr_mask_mgmt_set:mask on")); 3485 } 3486 rs = npi_intr_mask_set(handle, ldvp->ldv, 3487 ldvp->ldv_ldf_masks); 3488 if (rs != NPI_SUCCESS) { 3489 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 3490 "==> nxge_intr_mask_mgmt_set: " 3491 "set mask failed " 3492 " rs 0x%x ldv %d mask 0x%x", 3493 rs, ldvp->ldv, ldvp->ldv_ldf_masks)); 3494 return (NXGE_ERROR | rs); 3495 } 3496 NXGE_DEBUG_MSG((nxgep, INT_CTL, 3497 "==> nxge_intr_mask_mgmt_set: flag %d" 3498 "set mask OK " 3499 " ldv %d mask 0x%x", 3500 on, ldvp->ldv, ldvp->ldv_ldf_masks)); 3501 } 3502 } 3503 3504 ldgp = ldgvp->ldgp; 3505 /* set the arm bit */ 3506 for (i = 0; i < nxgep->ldgvp->ldg_intrs; i++, ldgp++) { 3507 if (on && !ldgp->arm) { 3508 ldgp->arm = B_TRUE; 3509 } else if (!on && ldgp->arm) { 3510 ldgp->arm = B_FALSE; 3511 } 3512 rs = npi_intr_ldg_mgmt_set(handle, ldgp->ldg, 3513 ldgp->arm, ldgp->ldg_timer); 3514 if (rs != NPI_SUCCESS) { 3515 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 3516 "<== nxge_intr_mask_mgmt_set: " 3517 "set timer failed " 3518 " rs 0x%x ldg %d timer 0x%x", 3519 rs, ldgp->ldg, ldgp->ldg_timer)); 3520 return (NXGE_ERROR | rs); 3521 } 3522 NXGE_DEBUG_MSG((nxgep, INT_CTL, 3523 "==> nxge_intr_mask_mgmt_set: OK (flag %d) " 3524 "set timer " 3525 " ldg %d timer 0x%x", 3526 on, ldgp->ldg, ldgp->ldg_timer)); 3527 } 3528 3529 NXGE_DEBUG_MSG((nxgep, INT_CTL, "<== nxge_intr_mask_mgmt_set")); 3530 return (NXGE_OK); 3531 } 3532 3533 static nxge_status_t 3534 nxge_get_mac_addr_properties(p_nxge_t nxgep) 3535 { 3536 #if defined(_BIG_ENDIAN) 3537 uchar_t *prop_val; 3538 uint_t prop_len; 3539 uint_t j; 3540 #endif 3541 uint_t i; 3542 uint8_t func_num; 3543 boolean_t compute_macs = B_TRUE; 3544 3545 NXGE_DEBUG_MSG((nxgep, DDI_CTL, "==> nxge_get_mac_addr_properties ")); 3546 3547 #if defined(_BIG_ENDIAN) 3548 /* 3549 * Get the ethernet address. 3550 */ 3551 (void) localetheraddr((struct ether_addr *)NULL, &nxgep->ouraddr); 3552 3553 /* 3554 * Check if it is an adapter with its own local mac address If it is 3555 * present, override the system mac address. 3556 */ 3557 if (ddi_prop_lookup_byte_array(DDI_DEV_T_ANY, nxgep->dip, 0, 3558 "local-mac-address", &prop_val, 3559 &prop_len) == DDI_PROP_SUCCESS) { 3560 if (prop_len == ETHERADDRL) { 3561 nxgep->factaddr = *(p_ether_addr_t)prop_val; 3562 NXGE_DEBUG_MSG((nxgep, DDI_CTL, "Local mac address = " 3563 "%02x:%02x:%02x:%02x:%02x:%02x", 3564 prop_val[0], prop_val[1], prop_val[2], 3565 prop_val[3], prop_val[4], prop_val[5])); 3566 } 3567 ddi_prop_free(prop_val); 3568 } 3569 if (ddi_prop_lookup_byte_array(DDI_DEV_T_ANY, nxgep->dip, 0, 3570 "local-mac-address?", &prop_val, 3571 &prop_len) == DDI_PROP_SUCCESS) { 3572 if (strncmp("true", (caddr_t)prop_val, (size_t)prop_len) == 0) { 3573 nxgep->ouraddr = nxgep->factaddr; 3574 NXGE_DEBUG_MSG((nxgep, DDI_CTL, 3575 "Using local MAC address")); 3576 } 3577 ddi_prop_free(prop_val); 3578 } else { 3579 nxgep->ouraddr = nxgep->factaddr; 3580 } 3581 3582 if ((!nxgep->vpd_info.present) || 3583 (nxge_is_valid_local_mac(nxgep->factaddr))) 3584 goto got_mac_addr; 3585 3586 NXGE_DEBUG_MSG((nxgep, DDI_CTL, "nxge_get_mac_addr_properties: " 3587 "MAC address from properties is not valid...reading from PROM")); 3588 3589 #endif 3590 if (!nxgep->vpd_info.ver_valid) { 3591 (void) nxge_espc_mac_addrs_get(nxgep); 3592 if (!nxge_is_valid_local_mac(nxgep->factaddr)) { 3593 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, "Failed to get " 3594 "MAC address")); 3595 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, "EEPROM version " 3596 "[%s] invalid...please update", 3597 nxgep->vpd_info.ver)); 3598 return (NXGE_ERROR); 3599 } 3600 nxgep->ouraddr = nxgep->factaddr; 3601 goto got_mac_addr; 3602 } 3603 /* 3604 * First get the MAC address from the info in the VPD data read 3605 * from the EEPROM. 3606 */ 3607 nxge_espc_get_next_mac_addr(nxgep->vpd_info.mac_addr, 3608 nxgep->function_num, &nxgep->factaddr); 3609 3610 if (!nxge_is_valid_local_mac(nxgep->factaddr)) { 3611 NXGE_DEBUG_MSG((nxgep, DDI_CTL, 3612 "nxge_get_mac_addr_properties: " 3613 "MAC address in EEPROM VPD data not valid" 3614 "...reading from NCR registers")); 3615 (void) nxge_espc_mac_addrs_get(nxgep); 3616 if (!nxge_is_valid_local_mac(nxgep->factaddr)) { 3617 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, "Failed to get " 3618 "MAC address")); 3619 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, "EEPROM version " 3620 "[%s] invalid...please update", 3621 nxgep->vpd_info.ver)); 3622 return (NXGE_ERROR); 3623 } 3624 } 3625 3626 nxgep->ouraddr = nxgep->factaddr; 3627 3628 got_mac_addr: 3629 func_num = nxgep->function_num; 3630 3631 /* 3632 * Note: mac-addresses property is the list of mac addresses for a 3633 * port. NXGE_MAX_MMAC_ADDRS is the total number of MAC addresses 3634 * allocated for a board. 3635 */ 3636 nxgep->nxge_mmac_info.total_factory_macs = NXGE_MAX_MMAC_ADDRS; 3637 3638 #if defined(_BIG_ENDIAN) 3639 if (ddi_prop_lookup_byte_array(DDI_DEV_T_ANY, nxgep->dip, 0, 3640 "mac-addresses", &prop_val, &prop_len) == DDI_PROP_SUCCESS) { 3641 /* 3642 * XAUI may have up to 18 MACs, more than the XMAC can 3643 * use (1 unique MAC plus 16 alternate MACs) 3644 */ 3645 nxgep->nxge_mmac_info.num_factory_mmac = 3646 prop_len / ETHERADDRL - 1; 3647 if (nxgep->nxge_mmac_info.num_factory_mmac > 3648 XMAC_MAX_ALT_ADDR_ENTRY) { 3649 nxgep->nxge_mmac_info.num_factory_mmac = 3650 XMAC_MAX_ALT_ADDR_ENTRY; 3651 } 3652 3653 for (i = 1; i <= nxgep->nxge_mmac_info.num_factory_mmac; i++) { 3654 for (j = 0; j < ETHERADDRL; j++) { 3655 nxgep->nxge_mmac_info.factory_mac_pool[i][j] = 3656 *(prop_val + (i * ETHERADDRL) + j); 3657 } 3658 NXGE_DEBUG_MSG((nxgep, DDI_CTL, 3659 "nxge_get_mac_addr_properties: Alt mac[%d] from " 3660 "mac-addresses property[%2x:%2x:%2x:%2x:%2x:%2x]", 3661 i, nxgep->nxge_mmac_info.factory_mac_pool[i][0], 3662 nxgep->nxge_mmac_info.factory_mac_pool[i][1], 3663 nxgep->nxge_mmac_info.factory_mac_pool[i][2], 3664 nxgep->nxge_mmac_info.factory_mac_pool[i][3], 3665 nxgep->nxge_mmac_info.factory_mac_pool[i][4], 3666 nxgep->nxge_mmac_info.factory_mac_pool[i][5])); 3667 } 3668 3669 compute_macs = B_FALSE; 3670 ddi_prop_free(prop_val); 3671 goto got_mmac_info; 3672 } 3673 #endif 3674 /* 3675 * total_factory_macs = 32 3676 * num_factory_mmac = (32 >> (nports/2)) - 1 3677 * So if nports = 4, then num_factory_mmac = 7 3678 * if nports = 2, then num_factory_mmac = 15 3679 */ 3680 nxgep->nxge_mmac_info.num_factory_mmac = 3681 ((nxgep->nxge_mmac_info.total_factory_macs >> 3682 (nxgep->nports >> 1))) - 1; 3683 3684 got_mmac_info: 3685 3686 if ((nxgep->function_num < 2) && 3687 (nxgep->nxge_mmac_info.num_factory_mmac > 3688 XMAC_MAX_ALT_ADDR_ENTRY)) { 3689 nxgep->nxge_mmac_info.num_factory_mmac = 3690 XMAC_MAX_ALT_ADDR_ENTRY; 3691 } else if ((nxgep->function_num > 1) && 3692 (nxgep->nxge_mmac_info.num_factory_mmac > 3693 BMAC_MAX_ALT_ADDR_ENTRY)) { 3694 nxgep->nxge_mmac_info.num_factory_mmac = 3695 BMAC_MAX_ALT_ADDR_ENTRY; 3696 } 3697 3698 for (i = 0; i <= nxgep->nxge_mmac_info.num_mmac; i++) { 3699 (void) npi_mac_altaddr_disable(nxgep->npi_handle, 3700 NXGE_GET_PORT_NUM(func_num), i); 3701 } 3702 3703 (void) nxge_init_mmac(nxgep, compute_macs); 3704 return (NXGE_OK); 3705 } 3706 3707 void 3708 nxge_get_xcvr_properties(p_nxge_t nxgep) 3709 { 3710 uchar_t *prop_val; 3711 uint_t prop_len; 3712 3713 NXGE_DEBUG_MSG((nxgep, DDI_CTL, "==> nxge_get_xcvr_properties")); 3714 3715 /* 3716 * Read the type of physical layer interface being used. 3717 */ 3718 nxgep->statsp->mac_stats.xcvr_inuse = INT_MII_XCVR; 3719 if (ddi_prop_lookup_byte_array(DDI_DEV_T_ANY, nxgep->dip, 0, 3720 "phy-type", &prop_val, &prop_len) == DDI_PROP_SUCCESS) { 3721 if (strncmp("pcs", (caddr_t)prop_val, 3722 (size_t)prop_len) == 0) { 3723 nxgep->statsp->mac_stats.xcvr_inuse = PCS_XCVR; 3724 } else { 3725 nxgep->statsp->mac_stats.xcvr_inuse = INT_MII_XCVR; 3726 } 3727 ddi_prop_free(prop_val); 3728 } else if (ddi_prop_lookup_byte_array(DDI_DEV_T_ANY, nxgep->dip, 0, 3729 "phy-interface", &prop_val, 3730 &prop_len) == DDI_PROP_SUCCESS) { 3731 if (strncmp("pcs", (caddr_t)prop_val, (size_t)prop_len) == 0) { 3732 nxgep->statsp->mac_stats.xcvr_inuse = PCS_XCVR; 3733 } else { 3734 nxgep->statsp->mac_stats.xcvr_inuse = INT_MII_XCVR; 3735 } 3736 ddi_prop_free(prop_val); 3737 } 3738 } 3739 3740 /* 3741 * Static functions start here. 3742 */ 3743 3744 static void 3745 nxge_ldgv_setup(p_nxge_ldg_t *ldgp, p_nxge_ldv_t *ldvp, uint8_t ldv, 3746 uint8_t endldg, int *ngrps) 3747 { 3748 NXGE_DEBUG_MSG((NULL, INT_CTL, "==> nxge_ldgv_setup")); 3749 /* Assign the group number for each device. */ 3750 (*ldvp)->ldg_assigned = (*ldgp)->ldg; 3751 (*ldvp)->ldgp = *ldgp; 3752 (*ldvp)->ldv = ldv; 3753 3754 NXGE_DEBUG_MSG((NULL, INT_CTL, "==> nxge_ldgv_setup: " 3755 "ldv %d endldg %d ldg %d, ldvp $%p", 3756 ldv, endldg, (*ldgp)->ldg, (*ldgp)->ldvp)); 3757 3758 (*ldgp)->nldvs++; 3759 if ((*ldgp)->ldg == (endldg - 1)) { 3760 if ((*ldgp)->ldvp == NULL) { 3761 (*ldgp)->ldvp = *ldvp; 3762 *ngrps += 1; 3763 NXGE_DEBUG_MSG((NULL, INT_CTL, 3764 "==> nxge_ldgv_setup: ngrps %d", *ngrps)); 3765 } 3766 NXGE_DEBUG_MSG((NULL, INT_CTL, 3767 "==> nxge_ldgv_setup: ldvp $%p ngrps %d", 3768 *ldvp, *ngrps)); 3769 ++*ldvp; 3770 } else { 3771 (*ldgp)->ldvp = *ldvp; 3772 *ngrps += 1; 3773 NXGE_DEBUG_MSG((NULL, INT_CTL, "==> nxge_ldgv_setup(done): " 3774 "ldv %d endldg %d ldg %d, ldvp $%p", 3775 ldv, endldg, (*ldgp)->ldg, (*ldgp)->ldvp)); 3776 (*ldvp) = ++*ldvp; 3777 (*ldgp) = ++*ldgp; 3778 NXGE_DEBUG_MSG((NULL, INT_CTL, 3779 "==> nxge_ldgv_setup: new ngrps %d", *ngrps)); 3780 } 3781 3782 NXGE_DEBUG_MSG((NULL, INT_CTL, "==> nxge_ldgv_setup: " 3783 "ldv %d ldvp $%p endldg %d ngrps %d", 3784 ldv, ldvp, endldg, *ngrps)); 3785 3786 NXGE_DEBUG_MSG((NULL, INT_CTL, "<== nxge_ldgv_setup")); 3787 } 3788 3789 /* 3790 * Note: This function assumes the following distribution of mac 3791 * addresses among 4 ports in neptune: 3792 * 3793 * ------------- 3794 * 0| |0 - local-mac-address for fn 0 3795 * ------------- 3796 * 1| |1 - local-mac-address for fn 1 3797 * ------------- 3798 * 2| |2 - local-mac-address for fn 2 3799 * ------------- 3800 * 3| |3 - local-mac-address for fn 3 3801 * ------------- 3802 * | |4 - Start of alt. mac addr. for fn 0 3803 * | | 3804 * | | 3805 * | |10 3806 * -------------- 3807 * | |11 - Start of alt. mac addr. for fn 1 3808 * | | 3809 * | | 3810 * | |17 3811 * -------------- 3812 * | |18 - Start of alt. mac addr. for fn 2 3813 * | | 3814 * | | 3815 * | |24 3816 * -------------- 3817 * | |25 - Start of alt. mac addr. for fn 3 3818 * | | 3819 * | | 3820 * | |31 3821 * -------------- 3822 * 3823 * For N2/NIU the mac addresses is from XAUI card. 3824 * 3825 * When 'compute_addrs' is true, the alternate mac addresses are computed 3826 * using the unique mac address as base. Otherwise the alternate addresses 3827 * are assigned from the list read off the 'mac-addresses' property. 3828 */ 3829 3830 static void 3831 nxge_init_mmac(p_nxge_t nxgep, boolean_t compute_addrs) 3832 { 3833 int slot; 3834 uint8_t func_num; 3835 uint16_t *base_mmac_addr; 3836 uint32_t alt_mac_ls4b; 3837 uint16_t *mmac_addr; 3838 uint32_t base_mac_ls4b; /* least significant 4 bytes */ 3839 nxge_mmac_t *mmac_info; 3840 npi_mac_addr_t mac_addr; 3841 3842 func_num = nxgep->function_num; 3843 base_mmac_addr = (uint16_t *)&nxgep->factaddr; 3844 mmac_info = (nxge_mmac_t *)&nxgep->nxge_mmac_info; 3845 3846 if (compute_addrs) { 3847 base_mac_ls4b = ((uint32_t)base_mmac_addr[1]) << 16 | 3848 base_mmac_addr[2]; 3849 3850 if (nxgep->niu_type == N2_NIU) { 3851 /* ls4b of 1st altmac */ 3852 alt_mac_ls4b = base_mac_ls4b + 1; 3853 } else { /* Neptune */ 3854 alt_mac_ls4b = base_mac_ls4b + 3855 (nxgep->nports - func_num) + 3856 (func_num * (mmac_info->num_factory_mmac)); 3857 } 3858 } 3859 3860 /* Set flags for unique MAC */ 3861 mmac_info->mac_pool[0].flags |= MMAC_SLOT_USED | MMAC_VENDOR_ADDR; 3862 3863 /* Clear flags of all alternate MAC slots */ 3864 for (slot = 1; slot <= mmac_info->num_mmac; slot++) { 3865 if (slot <= mmac_info->num_factory_mmac) 3866 mmac_info->mac_pool[slot].flags = MMAC_VENDOR_ADDR; 3867 else 3868 mmac_info->mac_pool[slot].flags = 0; 3869 } 3870 3871 /* Generate and store factory alternate MACs */ 3872 for (slot = 1; slot <= mmac_info->num_factory_mmac; slot++) { 3873 mmac_addr = (uint16_t *)&mmac_info->factory_mac_pool[slot]; 3874 if (compute_addrs) { 3875 mmac_addr[0] = base_mmac_addr[0]; 3876 mac_addr.w2 = mmac_addr[0]; 3877 3878 mmac_addr[1] = (alt_mac_ls4b >> 16) & 0x0FFFF; 3879 mac_addr.w1 = mmac_addr[1]; 3880 3881 mmac_addr[2] = alt_mac_ls4b & 0x0FFFF; 3882 mac_addr.w0 = mmac_addr[2]; 3883 3884 alt_mac_ls4b++; 3885 } else { 3886 mac_addr.w2 = mmac_addr[0]; 3887 mac_addr.w1 = mmac_addr[1]; 3888 mac_addr.w0 = mmac_addr[2]; 3889 } 3890 3891 NXGE_DEBUG_MSG((nxgep, DDI_CTL, 3892 "mac_pool_addr[%2x:%2x:%2x:%2x:%2x:%2x] npi_addr[%x%x%x]", 3893 mmac_info->factory_mac_pool[slot][0], 3894 mmac_info->factory_mac_pool[slot][1], 3895 mmac_info->factory_mac_pool[slot][2], 3896 mmac_info->factory_mac_pool[slot][3], 3897 mmac_info->factory_mac_pool[slot][4], 3898 mmac_info->factory_mac_pool[slot][5], 3899 mac_addr.w0, mac_addr.w1, mac_addr.w2)); 3900 /* 3901 * slot minus 1 because npi_mac_altaddr_entry expects 0 3902 * for the first alternate mac address. 3903 */ 3904 (void) npi_mac_altaddr_entry(nxgep->npi_handle, OP_SET, 3905 NXGE_GET_PORT_NUM(func_num), slot - 1, &mac_addr); 3906 } 3907 /* Initialize the first two parameters for mmac kstat */ 3908 nxgep->statsp->mmac_stats.mmac_max_cnt = mmac_info->num_mmac; 3909 nxgep->statsp->mmac_stats.mmac_avail_cnt = mmac_info->num_mmac; 3910 } 3911