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