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