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