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