1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 * or http://www.opensolaris.org/os/licensing. 10 * See the License for the specific language governing permissions 11 * and limitations under the License. 12 * 13 * When distributing Covered Code, include this CDDL HEADER in each 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 * If applicable, add the following below this CDDL HEADER, with the 16 * fields enclosed by brackets "[]" replaced with your own identifying 17 * information: Portions Copyright [yyyy] [name of copyright owner] 18 * 19 * CDDL HEADER END 20 */ 21 /* 22 * Copyright 2008 Sun Microsystems, Inc. All rights reserved. 23 * Use is subject to license terms. 24 */ 25 26 #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 (void) ddi_prop_update_int_array(DDI_DEV_T_NONE, 2223 nxgep->dip, prop, prop_val, prop_len); 2224 } 2225 ddi_prop_free(prop_val); 2226 } 2227 prop = param_arr[param_rxdma_intr_pkts].fcode_name; 2228 2229 if (ddi_prop_lookup_int_array(DDI_DEV_T_ANY, dip, 0, prop, 2230 &prop_val, &prop_len) == DDI_PROP_SUCCESS) { 2231 if ((prop_len > 0) && (prop_len <= p_cfgp->max_rdcs)) { 2232 (void) ddi_prop_update_int_array(DDI_DEV_T_NONE, 2233 nxgep->dip, prop, prop_val, prop_len); 2234 } 2235 ddi_prop_free(prop_val); 2236 } 2237 nxge_set_hw_dma_config(nxgep); 2238 2239 NXGE_DEBUG_MSG((nxgep, CFG_CTL, "<== nxge_use_cfg_dma_config: " 2240 "sTDC[%d] nTDC[%d] sRDC[%d] nRDC[%d]", 2241 p_cfgp->tdc.start, p_cfgp->tdc.count, 2242 p_cfgp->start_rdc, p_cfgp->max_rdcs)); 2243 2244 nxge_use_cfg_dma_config_exit: 2245 NXGE_DEBUG_MSG((nxgep, CFG_CTL, "<== nxge_use_cfg_dma_config")); 2246 } 2247 2248 void 2249 nxge_get_logical_props(p_nxge_t nxgep) 2250 { 2251 nxge_dma_pt_cfg_t *port = &nxgep->pt_config; 2252 nxge_hw_pt_cfg_t *hardware; 2253 nxge_rdc_grp_t *group; 2254 2255 (void) memset(port, 0, sizeof (*port)); 2256 2257 port->mac_port = nxgep->function_num; /* := function number */ 2258 2259 /* 2260 * alloc_buf_size: 2261 * dead variables. 2262 */ 2263 port->rbr_size = nxge_rbr_size; 2264 port->rcr_size = nxge_rcr_size; 2265 2266 port->tx_dma_map = 0; /* Transmit DMA channel bit map */ 2267 2268 nxge_set_rdc_intr_property(nxgep); 2269 2270 port->rcr_full_header = NXGE_RCR_FULL_HEADER; 2271 port->rx_drr_weight = PT_DRR_WT_DEFAULT_10G; 2272 2273 /* ----------------------------------------------------- */ 2274 hardware = &port->hw_config; 2275 2276 (void) memset(hardware, 0, sizeof (*hardware)); 2277 2278 /* 2279 * partition_id, read_write_mode: 2280 * dead variables. 2281 */ 2282 2283 /* 2284 * drr_wt, rx_full_header, *_ldg?, start_mac_entry, 2285 * mac_pref, def_mac_rxdma_grpid, start_vlan, max_vlans, 2286 * start_ldgs, max_ldgs, max_ldvs, 2287 * vlan_pref, def_vlan_rxdma_grpid are meaningful only 2288 * in the service domain. 2289 */ 2290 2291 group = &port->rdc_grps[0]; 2292 2293 group->flag = B_TRUE; /* configured */ 2294 group->config_method = RDC_TABLE_ENTRY_METHOD_REP; 2295 group->port = NXGE_GET_PORT_NUM(nxgep->function_num); 2296 2297 /* HIO futures: this is still an open question. */ 2298 hardware->max_macs = 1; 2299 } 2300 2301 static void 2302 nxge_use_cfg_vlan_class_config(p_nxge_t nxgep) 2303 { 2304 uint_t vlan_cnt; 2305 int *vlan_cfg_val; 2306 int status; 2307 p_nxge_param_t param_arr; 2308 char *prop; 2309 2310 NXGE_DEBUG_MSG((nxgep, CFG_CTL, " ==> nxge_use_cfg_vlan_config")); 2311 param_arr = nxgep->param_arr; 2312 prop = param_arr[param_vlan_2rdc_grp].fcode_name; 2313 2314 status = ddi_prop_lookup_int_array(DDI_DEV_T_ANY, nxgep->dip, 0, prop, 2315 &vlan_cfg_val, &vlan_cnt); 2316 if (status == DDI_PROP_SUCCESS) { 2317 status = ddi_prop_update_int_array(DDI_DEV_T_NONE, 2318 nxgep->dip, prop, vlan_cfg_val, vlan_cnt); 2319 ddi_prop_free(vlan_cfg_val); 2320 } 2321 nxge_set_hw_vlan_class_config(nxgep); 2322 NXGE_DEBUG_MSG((nxgep, CFG_CTL, " <== nxge_use_cfg_vlan_config")); 2323 } 2324 2325 static void 2326 nxge_use_cfg_mac_class_config(p_nxge_t nxgep) 2327 { 2328 p_nxge_dma_pt_cfg_t p_dma_cfgp; 2329 p_nxge_hw_pt_cfg_t p_cfgp; 2330 uint_t mac_cnt; 2331 int *mac_cfg_val; 2332 int status; 2333 p_nxge_param_t param_arr; 2334 char *prop; 2335 2336 NXGE_DEBUG_MSG((nxgep, CFG_CTL, "==> nxge_use_cfg_mac_class_config")); 2337 p_dma_cfgp = (p_nxge_dma_pt_cfg_t)&nxgep->pt_config; 2338 p_cfgp = (p_nxge_hw_pt_cfg_t)&p_dma_cfgp->hw_config; 2339 p_cfgp->start_mac_entry = 0; 2340 param_arr = nxgep->param_arr; 2341 prop = param_arr[param_mac_2rdc_grp].fcode_name; 2342 2343 switch (nxgep->function_num) { 2344 case 0: 2345 case 1: 2346 /* 10G ports */ 2347 p_cfgp->max_macs = NXGE_MAX_MACS_XMACS; 2348 break; 2349 case 2: 2350 case 3: 2351 /* 1G ports */ 2352 default: 2353 p_cfgp->max_macs = NXGE_MAX_MACS_BMACS; 2354 break; 2355 } 2356 2357 p_cfgp->mac_pref = 1; 2358 NXGE_DEBUG_MSG((nxgep, OBP_CTL, 2359 "== nxge_use_cfg_mac_class_config: " 2360 " mac_pref bit set def_mac_rxdma_grpid %d", 2361 p_cfgp->def_mac_rxdma_grpid)); 2362 2363 status = ddi_prop_lookup_int_array(DDI_DEV_T_ANY, nxgep->dip, 0, prop, 2364 &mac_cfg_val, &mac_cnt); 2365 if (status == DDI_PROP_SUCCESS) { 2366 if (mac_cnt <= p_cfgp->max_macs) 2367 status = ddi_prop_update_int_array(DDI_DEV_T_NONE, 2368 nxgep->dip, prop, mac_cfg_val, mac_cnt); 2369 ddi_prop_free(mac_cfg_val); 2370 } 2371 nxge_set_hw_mac_class_config(nxgep); 2372 NXGE_DEBUG_MSG((nxgep, CFG_CTL, " <== nxge_use_cfg_mac_class_config")); 2373 } 2374 2375 static void 2376 nxge_use_cfg_class_config(p_nxge_t nxgep) 2377 { 2378 nxge_set_hw_class_config(nxgep); 2379 } 2380 2381 static void 2382 nxge_set_rdc_intr_property(p_nxge_t nxgep) 2383 { 2384 int i; 2385 p_nxge_dma_pt_cfg_t p_dma_cfgp; 2386 2387 NXGE_DEBUG_MSG((nxgep, CFG_CTL, " ==> nxge_set_rdc_intr_property")); 2388 p_dma_cfgp = (p_nxge_dma_pt_cfg_t)&nxgep->pt_config; 2389 2390 for (i = 0; i < NXGE_MAX_RDCS; i++) { 2391 p_dma_cfgp->rcr_timeout[i] = nxge_rcr_timeout; 2392 p_dma_cfgp->rcr_threshold[i] = nxge_rcr_threshold; 2393 } 2394 2395 NXGE_DEBUG_MSG((nxgep, CFG_CTL, " <== nxge_set_rdc_intr_property")); 2396 } 2397 2398 static void 2399 nxge_set_hw_dma_config(p_nxge_t nxgep) 2400 { 2401 int i, j, ngrps, bitmap, end, st_rdc; 2402 p_nxge_dma_pt_cfg_t p_dma_cfgp; 2403 p_nxge_hw_pt_cfg_t p_cfgp; 2404 p_nxge_rdc_grp_t rdc_grp_p; 2405 p_nxge_tdc_grp_t tdc_grp_p; 2406 nxge_grp_t *group; 2407 uint8_t nrdcs; 2408 dc_map_t map = 0; 2409 2410 NXGE_DEBUG_MSG((nxgep, CFG_CTL, "==> nxge_set_hw_dma_config")); 2411 2412 p_dma_cfgp = (p_nxge_dma_pt_cfg_t)&nxgep->pt_config; 2413 p_cfgp = (p_nxge_hw_pt_cfg_t)&p_dma_cfgp->hw_config; 2414 2415 switch (nxgep->niu_type) { 2416 case NEPTUNE_4_1GC: 2417 case NEPTUNE_2_10GF_2_1GC: 2418 case NEPTUNE_1_10GF_3_1GC: 2419 case NEPTUNE_1_1GC_1_10GF_2_1GC: 2420 case NEPTUNE_2_10GF_2_1GRF: 2421 default: 2422 ngrps = 2; 2423 break; 2424 case NEPTUNE_2_10GF: 2425 case NEPTUNE_2_1GRF: 2426 case N2_NIU: 2427 ngrps = 4; 2428 break; 2429 } 2430 2431 /* 2432 * Setup TDC groups 2433 */ 2434 bitmap = 0; 2435 end = p_cfgp->tdc.start + p_cfgp->tdc.owned; 2436 for (i = p_cfgp->tdc.start; i < end; i++) { 2437 bitmap |= (1 << i); 2438 } 2439 2440 nxgep->tx_set.owned.map |= bitmap; /* Owned, & not shared. */ 2441 nxgep->tx_set.owned.count = p_cfgp->tdc.owned; 2442 p_dma_cfgp->tx_dma_map = bitmap; 2443 2444 for (i = 0; i < ngrps; i++) { 2445 group = (nxge_grp_t *)nxge_grp_add(nxgep, 2446 NXGE_TRANSMIT_GROUP); 2447 tdc_grp_p = &p_dma_cfgp->tdc_grps[ 2448 p_cfgp->def_mac_txdma_grpid + i]; 2449 if (i == 0) 2450 tdc_grp_p->map = bitmap; 2451 else 2452 tdc_grp_p->map = 0; 2453 /* no ring is associated with a group initially */ 2454 tdc_grp_p->start_tdc = 0; 2455 tdc_grp_p->max_tdcs = 0; 2456 tdc_grp_p->grp_index = group->index; 2457 } 2458 2459 for (i = 0; i < NXGE_MAX_RDCS; i++) { 2460 nxgep->rx_channel_started[i] = B_FALSE; 2461 } 2462 2463 /* 2464 * Setup RDC groups 2465 */ 2466 st_rdc = p_cfgp->start_rdc; 2467 for (i = 0; i < ngrps; i++) { 2468 /* 2469 * All rings are associated with the default group initially 2470 */ 2471 if (i == 0) { 2472 /* default group */ 2473 switch (nxgep->niu_type) { 2474 case NEPTUNE_4_1GC: 2475 nrdcs = rx_4_1G[nxgep->function_num]; 2476 break; 2477 case N2_NIU: 2478 case NEPTUNE_2_10GF: 2479 nrdcs = rx_2_10G[nxgep->function_num]; 2480 break; 2481 case NEPTUNE_2_10GF_2_1GC: 2482 nrdcs = rx_2_10G_2_1G[nxgep->function_num]; 2483 break; 2484 case NEPTUNE_1_10GF_3_1GC: 2485 nrdcs = rx_1_10G_3_1G[nxgep->function_num]; 2486 break; 2487 case NEPTUNE_1_1GC_1_10GF_2_1GC: 2488 nrdcs = rx_1_1G_1_10G_2_1G[nxgep->function_num]; 2489 break; 2490 default: 2491 switch (nxgep->platform_type) { 2492 case P_NEPTUNE_ALONSO: 2493 nrdcs = 2494 rx_2_10G_2_1G[nxgep->function_num]; 2495 break; 2496 default: 2497 nrdcs = rx_4_1G[nxgep->function_num]; 2498 break; 2499 } 2500 break; 2501 } 2502 } else { 2503 nrdcs = 0; 2504 } 2505 2506 rdc_grp_p = &p_dma_cfgp->rdc_grps[ 2507 p_cfgp->def_mac_rxdma_grpid + i]; 2508 rdc_grp_p->start_rdc = st_rdc; 2509 rdc_grp_p->max_rdcs = nrdcs; 2510 rdc_grp_p->def_rdc = rdc_grp_p->start_rdc; 2511 2512 /* default to: 0, 1, 2, 3, ...., 0, 1, 2, 3.... */ 2513 if (nrdcs != 0) { 2514 for (j = 0; j < nrdcs; j++) { 2515 map |= (1 << j); 2516 } 2517 map <<= rdc_grp_p->start_rdc; 2518 } else 2519 map = 0; 2520 rdc_grp_p->map = map; 2521 2522 nxgep->rx_set.owned.map |= map; /* Owned, & not shared. */ 2523 nxgep->rx_set.owned.count = nrdcs; 2524 2525 group = (nxge_grp_t *)nxge_grp_add(nxgep, NXGE_RECEIVE_GROUP); 2526 2527 rdc_grp_p->config_method = RDC_TABLE_ENTRY_METHOD_SEQ; 2528 rdc_grp_p->flag = B_TRUE; /* This group has been configured. */ 2529 rdc_grp_p->grp_index = group->index; 2530 rdc_grp_p->port = NXGE_GET_PORT_NUM(nxgep->function_num); 2531 2532 map = 0; 2533 } 2534 2535 2536 /* default RDC */ 2537 p_cfgp->def_rdc = p_cfgp->start_rdc; 2538 nxgep->def_rdc = p_cfgp->start_rdc; 2539 2540 /* full 18 byte header ? */ 2541 p_dma_cfgp->rcr_full_header = NXGE_RCR_FULL_HEADER; 2542 p_dma_cfgp->rx_drr_weight = PT_DRR_WT_DEFAULT_10G; 2543 if (nxgep->function_num > 1) 2544 p_dma_cfgp->rx_drr_weight = PT_DRR_WT_DEFAULT_1G; 2545 p_dma_cfgp->rbr_size = nxge_rbr_size; 2546 p_dma_cfgp->rcr_size = nxge_rcr_size; 2547 2548 nxge_set_rdc_intr_property(nxgep); 2549 NXGE_DEBUG_MSG((nxgep, CFG_CTL, " <== nxge_set_hw_dma_config")); 2550 } 2551 2552 boolean_t 2553 nxge_check_rxdma_port_member(p_nxge_t nxgep, uint8_t rdc) 2554 { 2555 p_nxge_dma_pt_cfg_t p_dma_cfgp; 2556 p_nxge_hw_pt_cfg_t p_cfgp; 2557 int status = B_TRUE; 2558 2559 NXGE_DEBUG_MSG((nxgep, CFG2_CTL, "==> nxge_check_rxdma_port_member")); 2560 2561 p_dma_cfgp = (p_nxge_dma_pt_cfg_t)&nxgep->pt_config; 2562 p_cfgp = (p_nxge_hw_pt_cfg_t)&p_dma_cfgp->hw_config; 2563 2564 /* Receive DMA Channels */ 2565 if (rdc < p_cfgp->max_rdcs) 2566 status = B_TRUE; 2567 NXGE_DEBUG_MSG((nxgep, CFG2_CTL, " <== nxge_check_rxdma_port_member")); 2568 return (status); 2569 } 2570 2571 boolean_t 2572 nxge_check_txdma_port_member(p_nxge_t nxgep, uint8_t tdc) 2573 { 2574 int status = B_FALSE; 2575 2576 NXGE_DEBUG_MSG((nxgep, CFG2_CTL, "==> nxge_check_txdma_port_member")); 2577 2578 if (tdc >= nxgep->pt_config.hw_config.tdc.start && 2579 tdc < nxgep->pt_config.hw_config.tdc.count) 2580 status = B_TRUE; 2581 2582 NXGE_DEBUG_MSG((nxgep, CFG2_CTL, " <== nxge_check_txdma_port_member")); 2583 return (status); 2584 } 2585 2586 boolean_t 2587 nxge_check_rxdma_rdcgrp_member(p_nxge_t nxgep, uint8_t rdc_grp, uint8_t rdc) 2588 { 2589 p_nxge_dma_pt_cfg_t p_dma_cfgp; 2590 int status = B_TRUE; 2591 p_nxge_rdc_grp_t rdc_grp_p; 2592 2593 NXGE_DEBUG_MSG((nxgep, CFG2_CTL, 2594 " ==> nxge_check_rxdma_rdcgrp_member")); 2595 NXGE_DEBUG_MSG((nxgep, CFG2_CTL, " nxge_check_rxdma_rdcgrp_member" 2596 " rdc %d group %d", rdc, rdc_grp)); 2597 p_dma_cfgp = (p_nxge_dma_pt_cfg_t)&nxgep->pt_config; 2598 2599 rdc_grp_p = &p_dma_cfgp->rdc_grps[rdc_grp]; 2600 NXGE_DEBUG_MSG((nxgep, CFG2_CTL, " max %d ", rdc_grp_p->max_rdcs)); 2601 if (rdc >= rdc_grp_p->max_rdcs) { 2602 status = B_FALSE; 2603 } 2604 NXGE_DEBUG_MSG((nxgep, CFG2_CTL, 2605 " <== nxge_check_rxdma_rdcgrp_member")); 2606 return (status); 2607 } 2608 2609 boolean_t 2610 nxge_check_rdcgrp_port_member(p_nxge_t nxgep, uint8_t rdc_grp) 2611 { 2612 p_nxge_dma_pt_cfg_t p_dma_cfgp; 2613 p_nxge_hw_pt_cfg_t p_cfgp; 2614 int status = B_TRUE; 2615 2616 NXGE_DEBUG_MSG((nxgep, CFG2_CTL, "==> nxge_check_rdcgrp_port_member")); 2617 2618 p_dma_cfgp = (p_nxge_dma_pt_cfg_t)&nxgep->pt_config; 2619 p_cfgp = (p_nxge_hw_pt_cfg_t)&p_dma_cfgp->hw_config; 2620 2621 if (rdc_grp >= p_cfgp->max_rdc_grpids) 2622 status = B_FALSE; 2623 NXGE_DEBUG_MSG((nxgep, CFG2_CTL, " <== nxge_check_rdcgrp_port_member")); 2624 return (status); 2625 } 2626 2627 static void 2628 nxge_set_hw_vlan_class_config(p_nxge_t nxgep) 2629 { 2630 int i; 2631 p_nxge_dma_pt_cfg_t p_dma_cfgp; 2632 p_nxge_hw_pt_cfg_t p_cfgp; 2633 p_nxge_param_t param_arr; 2634 uint_t vlan_cnt; 2635 int *vlan_cfg_val; 2636 nxge_param_map_t *vmap; 2637 char *prop; 2638 p_nxge_class_pt_cfg_t p_class_cfgp; 2639 uint32_t good_cfg[32]; 2640 int good_count = 0; 2641 nxge_mv_cfg_t *vlan_tbl; 2642 2643 NXGE_DEBUG_MSG((nxgep, CFG_CTL, " ==> nxge_set_hw_vlan_config")); 2644 p_dma_cfgp = (p_nxge_dma_pt_cfg_t)&nxgep->pt_config; 2645 p_cfgp = (p_nxge_hw_pt_cfg_t)&p_dma_cfgp->hw_config; 2646 p_class_cfgp = (p_nxge_class_pt_cfg_t)&nxgep->class_config; 2647 2648 param_arr = nxgep->param_arr; 2649 prop = param_arr[param_vlan_2rdc_grp].fcode_name; 2650 2651 /* 2652 * By default, VLAN to RDC group mapping is disabled Need to read HW or 2653 * .conf properties to find out if mapping is required 2654 * 2655 * Format 2656 * 2657 * uint32_t array, each array entry specifying the VLAN id and the 2658 * mapping 2659 * 2660 * bit[30] = add bit[29] = remove bit[28] = preference bits[23-16] = 2661 * rdcgrp bits[15-0] = VLAN ID ( ) 2662 */ 2663 2664 for (i = 0; i < NXGE_MAX_VLANS; i++) { 2665 p_class_cfgp->vlan_tbl[i].flag = 0; 2666 } 2667 2668 vlan_tbl = (nxge_mv_cfg_t *)&p_class_cfgp->vlan_tbl[0]; 2669 if (ddi_prop_lookup_int_array(DDI_DEV_T_ANY, nxgep->dip, 0, prop, 2670 &vlan_cfg_val, &vlan_cnt) == DDI_PROP_SUCCESS) { 2671 for (i = 0; i < vlan_cnt; i++) { 2672 vmap = (nxge_param_map_t *)&vlan_cfg_val[i]; 2673 if ((vmap->param_id) && 2674 (vmap->param_id < NXGE_MAX_VLANS) && 2675 (vmap->map_to < 2676 p_cfgp->max_rdc_grpids) && 2677 (vmap->map_to >= (uint8_t)0)) { 2678 NXGE_DEBUG_MSG((nxgep, CFG2_CTL, 2679 " nxge_vlan_config mapping" 2680 " id %d grp %d", 2681 vmap->param_id, vmap->map_to)); 2682 good_cfg[good_count] = vlan_cfg_val[i]; 2683 if (vlan_tbl[vmap->param_id].flag == 0) 2684 good_count++; 2685 vlan_tbl[vmap->param_id].flag = 1; 2686 vlan_tbl[vmap->param_id].rdctbl = 2687 vmap->map_to + p_cfgp->def_mac_rxdma_grpid; 2688 vlan_tbl[vmap->param_id].mpr_npr = vmap->pref; 2689 } 2690 } 2691 ddi_prop_free(vlan_cfg_val); 2692 if (good_count != vlan_cnt) { 2693 (void) ddi_prop_update_int_array(DDI_DEV_T_NONE, 2694 nxgep->dip, prop, (int *)good_cfg, good_count); 2695 } 2696 } 2697 NXGE_DEBUG_MSG((nxgep, CFG_CTL, "<== nxge_set_hw_vlan_config")); 2698 } 2699 2700 static void 2701 nxge_set_hw_mac_class_config(p_nxge_t nxgep) 2702 { 2703 int i; 2704 p_nxge_dma_pt_cfg_t p_dma_cfgp; 2705 p_nxge_hw_pt_cfg_t p_cfgp; 2706 p_nxge_param_t param_arr; 2707 uint_t mac_cnt; 2708 int *mac_cfg_val; 2709 nxge_param_map_t *mac_map; 2710 char *prop; 2711 p_nxge_class_pt_cfg_t p_class_cfgp; 2712 int good_count = 0; 2713 int good_cfg[NXGE_MAX_MACS]; 2714 nxge_mv_cfg_t *mac_host_info; 2715 2716 NXGE_DEBUG_MSG((nxgep, CFG_CTL, "==> nxge_set_hw_mac_config")); 2717 2718 p_dma_cfgp = (p_nxge_dma_pt_cfg_t)&nxgep->pt_config; 2719 p_cfgp = (p_nxge_hw_pt_cfg_t)&p_dma_cfgp->hw_config; 2720 p_class_cfgp = (p_nxge_class_pt_cfg_t)&nxgep->class_config; 2721 mac_host_info = (nxge_mv_cfg_t *)&p_class_cfgp->mac_host_info[0]; 2722 2723 param_arr = nxgep->param_arr; 2724 prop = param_arr[param_mac_2rdc_grp].fcode_name; 2725 2726 for (i = 0; i < NXGE_MAX_MACS; i++) { 2727 p_class_cfgp->mac_host_info[i].flag = 0; 2728 p_class_cfgp->mac_host_info[i].rdctbl = 2729 p_cfgp->def_mac_rxdma_grpid; 2730 } 2731 2732 if (ddi_prop_lookup_int_array(DDI_DEV_T_ANY, nxgep->dip, 0, prop, 2733 &mac_cfg_val, &mac_cnt) == DDI_PROP_SUCCESS) { 2734 for (i = 0; i < mac_cnt; i++) { 2735 mac_map = (nxge_param_map_t *)&mac_cfg_val[i]; 2736 if ((mac_map->param_id < p_cfgp->max_macs) && 2737 (mac_map->map_to < 2738 p_cfgp->max_rdc_grpids) && 2739 (mac_map->map_to >= (uint8_t)0)) { 2740 NXGE_DEBUG_MSG((nxgep, CFG2_CTL, 2741 " nxge_mac_config mapping" 2742 " id %d grp %d", 2743 mac_map->param_id, mac_map->map_to)); 2744 mac_host_info[mac_map->param_id].mpr_npr = 2745 p_cfgp->mac_pref; 2746 mac_host_info[mac_map->param_id].rdctbl = 2747 mac_map->map_to + 2748 p_cfgp->def_mac_rxdma_grpid; 2749 good_cfg[good_count] = mac_cfg_val[i]; 2750 if (mac_host_info[mac_map->param_id].flag == 0) 2751 good_count++; 2752 mac_host_info[mac_map->param_id].flag = 1; 2753 } 2754 } 2755 ddi_prop_free(mac_cfg_val); 2756 if (good_count != mac_cnt) { 2757 (void) ddi_prop_update_int_array(DDI_DEV_T_NONE, 2758 nxgep->dip, prop, good_cfg, good_count); 2759 } 2760 } 2761 NXGE_DEBUG_MSG((nxgep, CFG_CTL, "<== nxge_set_hw_mac_config")); 2762 } 2763 2764 static void 2765 nxge_set_hw_class_config(p_nxge_t nxgep) 2766 { 2767 int i; 2768 p_nxge_param_t param_arr; 2769 int *int_prop_val; 2770 uint32_t cfg_value; 2771 char *prop; 2772 p_nxge_class_pt_cfg_t p_class_cfgp; 2773 int start_prop, end_prop; 2774 uint_t prop_cnt; 2775 2776 NXGE_DEBUG_MSG((nxgep, CFG_CTL, " ==> nxge_set_hw_class_config")); 2777 2778 p_class_cfgp = (p_nxge_class_pt_cfg_t)&nxgep->class_config; 2779 param_arr = nxgep->param_arr; 2780 start_prop = param_class_opt_ip_usr4; 2781 end_prop = param_class_opt_ipv6_sctp; 2782 2783 for (i = start_prop; i <= end_prop; i++) { 2784 prop = param_arr[i].fcode_name; 2785 if (ddi_prop_lookup_int_array(DDI_DEV_T_ANY, nxgep->dip, 2786 0, prop, &int_prop_val, 2787 &prop_cnt) == DDI_PROP_SUCCESS) { 2788 cfg_value = (uint32_t)*int_prop_val; 2789 ddi_prop_free(int_prop_val); 2790 } else { 2791 cfg_value = (uint32_t)param_arr[i].value; 2792 } 2793 p_class_cfgp->class_cfg[i - start_prop] = cfg_value; 2794 } 2795 2796 prop = param_arr[param_h1_init_value].fcode_name; 2797 2798 if (ddi_prop_lookup_int_array(DDI_DEV_T_ANY, nxgep->dip, 0, prop, 2799 &int_prop_val, &prop_cnt) == DDI_PROP_SUCCESS) { 2800 cfg_value = (uint32_t)*int_prop_val; 2801 ddi_prop_free(int_prop_val); 2802 } else { 2803 cfg_value = (uint32_t)param_arr[param_h1_init_value].value; 2804 } 2805 2806 p_class_cfgp->init_h1 = (uint32_t)cfg_value; 2807 prop = param_arr[param_h2_init_value].fcode_name; 2808 2809 if (ddi_prop_lookup_int_array(DDI_DEV_T_ANY, nxgep->dip, 0, prop, 2810 &int_prop_val, &prop_cnt) == DDI_PROP_SUCCESS) { 2811 cfg_value = (uint32_t)*int_prop_val; 2812 ddi_prop_free(int_prop_val); 2813 } else { 2814 cfg_value = (uint32_t)param_arr[param_h2_init_value].value; 2815 } 2816 2817 p_class_cfgp->init_h2 = (uint16_t)cfg_value; 2818 NXGE_DEBUG_MSG((nxgep, CFG_CTL, " <== nxge_set_hw_class_config")); 2819 } 2820 2821 nxge_status_t 2822 nxge_ldgv_init_n2(p_nxge_t nxgep, int *navail_p, int *nrequired_p) 2823 { 2824 int i, maxldvs, maxldgs, nldvs; 2825 int ldv, endldg; 2826 uint8_t func; 2827 uint8_t channel; 2828 uint8_t chn_start; 2829 boolean_t own_sys_err = B_FALSE, own_fzc = B_FALSE; 2830 p_nxge_dma_pt_cfg_t p_dma_cfgp; 2831 p_nxge_hw_pt_cfg_t p_cfgp; 2832 p_nxge_ldgv_t ldgvp; 2833 p_nxge_ldg_t ldgp, ptr; 2834 p_nxge_ldv_t ldvp, sysldvp; 2835 nxge_status_t status = NXGE_OK; 2836 nxge_grp_set_t *set; 2837 2838 NXGE_DEBUG_MSG((nxgep, INT_CTL, "==> nxge_ldgv_init_n2")); 2839 if (!*navail_p) { 2840 *nrequired_p = 0; 2841 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 2842 "<== nxge_ldgv_init:no avail")); 2843 return (NXGE_ERROR); 2844 } 2845 /* 2846 * N2/NIU: one logical device owns one logical group. and each 2847 * device/group will be assigned one vector by Hypervisor. 2848 */ 2849 p_dma_cfgp = (p_nxge_dma_pt_cfg_t)&nxgep->pt_config; 2850 p_cfgp = (p_nxge_hw_pt_cfg_t)&p_dma_cfgp->hw_config; 2851 maxldgs = p_cfgp->max_ldgs; 2852 if (!maxldgs) { 2853 /* No devices configured. */ 2854 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, "<== nxge_ldgv_init_n2: " 2855 "no logical groups configured.")); 2856 return (NXGE_ERROR); 2857 } else { 2858 maxldvs = maxldgs + 1; 2859 } 2860 2861 /* 2862 * If function zero instance, it needs to handle the system and MIF 2863 * error interrupts. MIF interrupt may not be needed for N2/NIU. 2864 */ 2865 func = nxgep->function_num; 2866 if (func == 0) { 2867 own_sys_err = B_TRUE; 2868 if (!p_cfgp->ser_ldvid) { 2869 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 2870 "nxge_ldgv_init_n2: func 0, ERR ID not set!")); 2871 } 2872 /* MIF interrupt */ 2873 if (!p_cfgp->mif_ldvid) { 2874 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 2875 "nxge_ldgv_init_n2: func 0, MIF ID not set!")); 2876 } 2877 } 2878 2879 /* 2880 * Assume single partition, each function owns mac. 2881 */ 2882 if (!nxge_use_partition) 2883 own_fzc = B_TRUE; 2884 2885 ldgvp = nxgep->ldgvp; 2886 if (ldgvp == NULL) { 2887 ldgvp = KMEM_ZALLOC(sizeof (nxge_ldgv_t), KM_SLEEP); 2888 nxgep->ldgvp = ldgvp; 2889 ldgvp->maxldgs = (uint8_t)maxldgs; 2890 ldgvp->maxldvs = (uint8_t)maxldvs; 2891 ldgp = ldgvp->ldgp = KMEM_ZALLOC( 2892 sizeof (nxge_ldg_t) * maxldgs, KM_SLEEP); 2893 ldvp = ldgvp->ldvp = KMEM_ZALLOC( 2894 sizeof (nxge_ldv_t) * maxldvs, KM_SLEEP); 2895 } else { 2896 ldgp = ldgvp->ldgp; 2897 ldvp = ldgvp->ldvp; 2898 } 2899 2900 ldgvp->ndma_ldvs = p_cfgp->tdc.owned + p_cfgp->max_rdcs; 2901 ldgvp->tmres = NXGE_TIMER_RESO; 2902 2903 NXGE_DEBUG_MSG((nxgep, INT_CTL, 2904 "==> nxge_ldgv_init_n2: maxldvs %d maxldgs %d", 2905 maxldvs, maxldgs)); 2906 2907 /* logical start_ldg is ldv */ 2908 ptr = ldgp; 2909 for (i = 0; i < maxldgs; i++) { 2910 ptr->func = func; 2911 ptr->arm = B_TRUE; 2912 ptr->vldg_index = (uint8_t)i; 2913 ptr->ldg_timer = NXGE_TIMER_LDG; 2914 ptr->ldg = p_cfgp->ldg[i]; 2915 ptr->sys_intr_handler = nxge_intr; 2916 ptr->nldvs = 0; 2917 ptr->ldvp = NULL; 2918 ptr->nxgep = nxgep; 2919 NXGE_DEBUG_MSG((nxgep, INT_CTL, 2920 "==> nxge_ldgv_init_n2: maxldvs %d maxldgs %d " 2921 "ldg %d ldgptr $%p", 2922 maxldvs, maxldgs, ptr->ldg, ptr)); 2923 ptr++; 2924 } 2925 2926 endldg = NXGE_INT_MAX_LDG; 2927 nldvs = 0; 2928 ldgvp->nldvs = 0; 2929 ldgp->ldvp = NULL; 2930 *nrequired_p = 0; 2931 2932 /* 2933 * logical device group table is organized in the following order (same 2934 * as what interrupt property has). function 0: owns MAC, MIF, error, 2935 * rx, tx. function 1: owns MAC, rx, tx. 2936 */ 2937 2938 if (own_fzc && p_cfgp->mac_ldvid) { 2939 /* Each function should own MAC interrupt */ 2940 ldv = p_cfgp->mac_ldvid; 2941 ldvp->ldv = (uint8_t)ldv; 2942 ldvp->is_mac = B_TRUE; 2943 ldvp->ldv_intr_handler = nxge_mac_intr; 2944 ldvp->ldv_ldf_masks = 0; 2945 ldvp->nxgep = nxgep; 2946 NXGE_DEBUG_MSG((nxgep, INT_CTL, 2947 "==> nxge_ldgv_init_n2(mac): maxldvs %d ldv %d " 2948 "ldg %d ldgptr $%p ldvptr $%p", 2949 maxldvs, ldv, ldgp->ldg, ldgp, ldvp)); 2950 nxge_ldgv_setup(&ldgp, &ldvp, ldv, endldg, nrequired_p); 2951 nldvs++; 2952 } 2953 2954 if (own_fzc && p_cfgp->mif_ldvid) { 2955 ldv = p_cfgp->mif_ldvid; 2956 ldvp->ldv = (uint8_t)ldv; 2957 ldvp->is_mif = B_TRUE; 2958 ldvp->ldv_intr_handler = nxge_mif_intr; 2959 ldvp->ldv_ldf_masks = 0; 2960 ldvp->nxgep = nxgep; 2961 NXGE_DEBUG_MSG((nxgep, INT_CTL, 2962 "==> nxge_ldgv_init_n2(mif): maxldvs %d ldv %d " 2963 "ldg %d ldgptr $%p ldvptr $%p", 2964 maxldvs, ldv, ldgp->ldg, ldgp, ldvp)); 2965 nxge_ldgv_setup(&ldgp, &ldvp, ldv, endldg, nrequired_p); 2966 nldvs++; 2967 } 2968 2969 /* 2970 * HW based syserr interrupt for port0, and SW based syserr interrupt 2971 * for port1 2972 */ 2973 if (own_sys_err && p_cfgp->ser_ldvid) { 2974 ldv = p_cfgp->ser_ldvid; 2975 /* 2976 * Unmask the system interrupt states. 2977 */ 2978 (void) nxge_fzc_sys_err_mask_set(nxgep, SYS_ERR_SMX_MASK | 2979 SYS_ERR_IPP_MASK | SYS_ERR_TXC_MASK | 2980 SYS_ERR_ZCP_MASK); 2981 2982 ldvp->use_timer = B_TRUE; 2983 ldvp->ldv = (uint8_t)ldv; 2984 ldvp->is_syserr = B_TRUE; 2985 ldvp->ldv_intr_handler = nxge_syserr_intr; 2986 ldvp->ldv_ldf_masks = 0; 2987 ldvp->nxgep = nxgep; 2988 ldgvp->ldvp_syserr = ldvp; 2989 2990 NXGE_DEBUG_MSG((nxgep, INT_CTL, 2991 "==> nxge_ldgv_init_n2(syserr): maxldvs %d ldv %d " 2992 "ldg %d ldgptr $%p ldvptr p%p", 2993 maxldvs, ldv, ldgp->ldg, ldgp, ldvp)); 2994 nxge_ldgv_setup(&ldgp, &ldvp, ldv, endldg, nrequired_p); 2995 nldvs++; 2996 } else { 2997 /* 2998 * SW based: allocate the ldv for the syserr since the vector 2999 * should not be consumed for port1 3000 */ 3001 sysldvp = KMEM_ZALLOC(sizeof (nxge_ldv_t), KM_SLEEP); 3002 sysldvp->use_timer = B_TRUE; 3003 sysldvp->ldv = NXGE_SYS_ERROR_LD; 3004 sysldvp->is_syserr = B_TRUE; 3005 sysldvp->ldv_intr_handler = nxge_syserr_intr; 3006 sysldvp->ldv_ldf_masks = 0; 3007 sysldvp->nxgep = nxgep; 3008 ldgvp->ldvp_syserr = sysldvp; 3009 ldgvp->ldvp_syserr_alloced = B_TRUE; 3010 } 3011 3012 3013 NXGE_DEBUG_MSG((nxgep, INT_CTL, "==> nxge_ldgv_init_n2: " 3014 "(before rx) func %d nldvs %d navail %d nrequired %d", 3015 func, nldvs, *navail_p, *nrequired_p)); 3016 3017 /* 3018 * Start with RDC to configure logical devices for each group. 3019 */ 3020 chn_start = p_cfgp->ldg_chn_start; 3021 set = &nxgep->rx_set; 3022 for (channel = 0; channel < NXGE_MAX_RDCS; channel++) { 3023 if ((1 << channel) & set->owned.map) { 3024 ldvp->is_rxdma = B_TRUE; 3025 ldvp->ldv = (uint8_t)channel + NXGE_RDMA_LD_START; 3026 ldvp->channel = channel; 3027 ldvp->vdma_index = (uint8_t)channel; 3028 ldvp->ldv_intr_handler = nxge_rx_intr; 3029 ldvp->ldv_ldf_masks = 0; 3030 ldvp->nxgep = nxgep; 3031 ldgp->ldg = p_cfgp->ldg[chn_start]; 3032 3033 NXGE_DEBUG_MSG((nxgep, INT_CTL, 3034 "==> nxge_ldgv_init_n2(rx%d): maxldvs %d ldv %d " 3035 "ldg %d ldgptr 0x%016llx ldvptr 0x%016llx", 3036 i, maxldvs, ldv, ldgp->ldg, ldgp, ldvp)); 3037 nxge_ldgv_setup(&ldgp, &ldvp, ldvp->ldv, 3038 endldg, nrequired_p); 3039 nldvs++; 3040 chn_start++; 3041 } 3042 } 3043 3044 NXGE_DEBUG_MSG((nxgep, INT_CTL, "==> nxge_ldgv_init_n2: " 3045 "func %d nldvs %d navail %d nrequired %d", 3046 func, nldvs, *navail_p, *nrequired_p)); 3047 3048 NXGE_DEBUG_MSG((nxgep, INT_CTL, "==> nxge_ldgv_init_n2: " 3049 "func %d nldvs %d navail %d nrequired %d ldgp 0x%llx " 3050 "ldvp 0x%llx", 3051 func, nldvs, *navail_p, *nrequired_p, ldgp, ldvp)); 3052 /* 3053 * Transmit DMA channels. 3054 */ 3055 chn_start = p_cfgp->ldg_chn_start + 8; 3056 set = &nxgep->tx_set; 3057 for (channel = 0; channel < NXGE_MAX_TDCS; channel++) { 3058 if ((1 << channel) & set->owned.map) { 3059 ldvp->is_txdma = B_TRUE; 3060 ldvp->ldv = (uint8_t)channel + NXGE_TDMA_LD_START; 3061 ldvp->channel = channel; 3062 ldvp->vdma_index = (uint8_t)channel; 3063 ldvp->ldv_intr_handler = nxge_tx_intr; 3064 ldvp->ldv_ldf_masks = 0; 3065 ldgp->ldg = p_cfgp->ldg[chn_start]; 3066 ldvp->nxgep = nxgep; 3067 NXGE_DEBUG_MSG((nxgep, INT_CTL, 3068 "==> nxge_ldgv_init_n2(tx%d): maxldvs %d ldv %d " 3069 "ldg %d ldgptr %p ldvptr %p", 3070 channel, maxldvs, ldv, ldgp->ldg, ldgp, ldvp)); 3071 nxge_ldgv_setup(&ldgp, &ldvp, ldvp->ldv, 3072 endldg, nrequired_p); 3073 nldvs++; 3074 chn_start++; 3075 } 3076 } 3077 3078 ldgvp->ldg_intrs = *nrequired_p; 3079 ldgvp->nldvs = (uint8_t)nldvs; 3080 3081 NXGE_DEBUG_MSG((nxgep, INT_CTL, "==> nxge_ldgv_init_n2: " 3082 "func %d nldvs %d maxgrps %d navail %d nrequired %d", 3083 func, nldvs, maxldgs, *navail_p, *nrequired_p)); 3084 3085 NXGE_DEBUG_MSG((nxgep, INT_CTL, "<== nxge_ldgv_init_n2")); 3086 return (status); 3087 } 3088 3089 /* 3090 * Interrupts related interface functions. 3091 */ 3092 3093 nxge_status_t 3094 nxge_ldgv_init(p_nxge_t nxgep, int *navail_p, int *nrequired_p) 3095 { 3096 int i, maxldvs, maxldgs, nldvs; 3097 int ldv, ldg, endldg, ngrps; 3098 uint8_t func; 3099 uint8_t channel; 3100 boolean_t own_sys_err = B_FALSE, own_fzc = B_FALSE; 3101 p_nxge_dma_pt_cfg_t p_dma_cfgp; 3102 p_nxge_hw_pt_cfg_t p_cfgp; 3103 p_nxge_ldgv_t ldgvp; 3104 p_nxge_ldg_t ldgp, ptr; 3105 p_nxge_ldv_t ldvp; 3106 nxge_grp_set_t *set; 3107 3108 nxge_status_t status = NXGE_OK; 3109 3110 NXGE_DEBUG_MSG((nxgep, INT_CTL, "==> nxge_ldgv_init")); 3111 if (!*navail_p) { 3112 *nrequired_p = 0; 3113 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 3114 "<== nxge_ldgv_init:no avail")); 3115 return (NXGE_ERROR); 3116 } 3117 p_dma_cfgp = (p_nxge_dma_pt_cfg_t)&nxgep->pt_config; 3118 p_cfgp = (p_nxge_hw_pt_cfg_t)&p_dma_cfgp->hw_config; 3119 3120 nldvs = p_cfgp->tdc.owned + p_cfgp->max_rdcs; 3121 3122 /* 3123 * If function zero instance, it needs to handle the system error 3124 * interrupts. 3125 */ 3126 func = nxgep->function_num; 3127 if (func == 0) { 3128 nldvs++; 3129 own_sys_err = B_TRUE; 3130 } else { 3131 /* use timer */ 3132 nldvs++; 3133 } 3134 3135 /* 3136 * Assume single partition, each function owns mac. 3137 */ 3138 if (!nxge_use_partition) { 3139 /* mac */ 3140 nldvs++; 3141 /* MIF */ 3142 nldvs++; 3143 own_fzc = B_TRUE; 3144 } 3145 maxldvs = nldvs; 3146 maxldgs = p_cfgp->max_ldgs; 3147 if (!maxldvs || !maxldgs) { 3148 /* No devices configured. */ 3149 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, "<== nxge_ldgv_init: " 3150 "no logical devices or groups configured.")); 3151 return (NXGE_ERROR); 3152 } 3153 ldgvp = nxgep->ldgvp; 3154 if (ldgvp == NULL) { 3155 ldgvp = KMEM_ZALLOC(sizeof (nxge_ldgv_t), KM_SLEEP); 3156 nxgep->ldgvp = ldgvp; 3157 ldgvp->maxldgs = (uint8_t)maxldgs; 3158 ldgvp->maxldvs = (uint8_t)maxldvs; 3159 ldgp = ldgvp->ldgp = KMEM_ZALLOC(sizeof (nxge_ldg_t) * maxldgs, 3160 KM_SLEEP); 3161 ldvp = ldgvp->ldvp = KMEM_ZALLOC(sizeof (nxge_ldv_t) * maxldvs, 3162 KM_SLEEP); 3163 } 3164 ldgvp->ndma_ldvs = p_cfgp->tdc.owned + p_cfgp->max_rdcs; 3165 ldgvp->tmres = NXGE_TIMER_RESO; 3166 3167 NXGE_DEBUG_MSG((nxgep, INT_CTL, 3168 "==> nxge_ldgv_init: maxldvs %d maxldgs %d nldvs %d", 3169 maxldvs, maxldgs, nldvs)); 3170 ldg = p_cfgp->start_ldg; 3171 ptr = ldgp; 3172 for (i = 0; i < maxldgs; i++) { 3173 ptr->func = func; 3174 ptr->arm = B_TRUE; 3175 ptr->vldg_index = (uint8_t)i; 3176 ptr->ldg_timer = NXGE_TIMER_LDG; 3177 ptr->ldg = ldg++; 3178 ptr->sys_intr_handler = nxge_intr; 3179 ptr->nldvs = 0; 3180 ptr->nxgep = nxgep; 3181 NXGE_DEBUG_MSG((nxgep, INT_CTL, 3182 "==> nxge_ldgv_init: maxldvs %d maxldgs %d ldg %d", 3183 maxldvs, maxldgs, ptr->ldg)); 3184 ptr++; 3185 } 3186 3187 ldg = p_cfgp->start_ldg; 3188 if (maxldgs > *navail_p) { 3189 ngrps = *navail_p; 3190 } else { 3191 ngrps = maxldgs; 3192 } 3193 endldg = ldg + ngrps; 3194 3195 /* 3196 * Receive DMA channels. 3197 */ 3198 nldvs = 0; 3199 ldgvp->nldvs = 0; 3200 ldgp->ldvp = NULL; 3201 *nrequired_p = 0; 3202 3203 /* 3204 * Start with RDC to configure logical devices for each group. 3205 */ 3206 set = &nxgep->rx_set; 3207 for (channel = 0; channel < NXGE_MAX_RDCS; channel++) { 3208 if ((1 << channel) & set->owned.map) { 3209 /* For now, <channel & <vdma_index> are the same. */ 3210 ldvp->is_rxdma = B_TRUE; 3211 ldvp->ldv = (uint8_t)channel + NXGE_RDMA_LD_START; 3212 ldvp->channel = channel; 3213 ldvp->vdma_index = (uint8_t)channel; 3214 ldvp->ldv_intr_handler = nxge_rx_intr; 3215 ldvp->ldv_ldf_masks = 0; 3216 ldvp->use_timer = B_FALSE; 3217 ldvp->nxgep = nxgep; 3218 nxge_ldgv_setup(&ldgp, &ldvp, ldvp->ldv, 3219 endldg, nrequired_p); 3220 nldvs++; 3221 } 3222 } 3223 3224 /* 3225 * Transmit DMA channels. 3226 */ 3227 set = &nxgep->tx_set; 3228 for (channel = 0; channel < NXGE_MAX_TDCS; channel++) { 3229 if ((1 << channel) & set->owned.map) { 3230 /* For now, <channel & <vdma_index> are the same. */ 3231 ldvp->is_txdma = B_TRUE; 3232 ldvp->ldv = (uint8_t)channel + NXGE_TDMA_LD_START; 3233 ldvp->channel = channel; 3234 ldvp->vdma_index = (uint8_t)channel; 3235 ldvp->ldv_intr_handler = nxge_tx_intr; 3236 ldvp->ldv_ldf_masks = 0; 3237 ldvp->use_timer = B_FALSE; 3238 ldvp->nxgep = nxgep; 3239 nxge_ldgv_setup(&ldgp, &ldvp, ldvp->ldv, 3240 endldg, nrequired_p); 3241 nldvs++; 3242 } 3243 } 3244 3245 if (own_fzc) { 3246 ldv = NXGE_MIF_LD; 3247 ldvp->ldv = (uint8_t)ldv; 3248 ldvp->is_mif = B_TRUE; 3249 ldvp->ldv_intr_handler = nxge_mif_intr; 3250 ldvp->ldv_ldf_masks = 0; 3251 ldvp->use_timer = B_FALSE; 3252 ldvp->nxgep = nxgep; 3253 nxge_ldgv_setup(&ldgp, &ldvp, ldv, endldg, nrequired_p); 3254 nldvs++; 3255 } 3256 /* 3257 * MAC port (function zero control) 3258 */ 3259 if (own_fzc) { 3260 ldvp->is_mac = B_TRUE; 3261 ldvp->ldv_intr_handler = nxge_mac_intr; 3262 ldvp->ldv_ldf_masks = 0; 3263 ldv = func + NXGE_MAC_LD_START; 3264 ldvp->ldv = (uint8_t)ldv; 3265 ldvp->use_timer = B_FALSE; 3266 ldvp->nxgep = nxgep; 3267 nxge_ldgv_setup(&ldgp, &ldvp, ldv, endldg, nrequired_p); 3268 nldvs++; 3269 } 3270 NXGE_DEBUG_MSG((nxgep, INT_CTL, "==> nxge_ldgv_init: " 3271 "func %d nldvs %d navail %d nrequired %d", 3272 func, nldvs, *navail_p, *nrequired_p)); 3273 /* 3274 * Function 0 owns system error interrupts. 3275 */ 3276 ldvp->use_timer = B_TRUE; 3277 if (own_sys_err) { 3278 ldv = NXGE_SYS_ERROR_LD; 3279 ldvp->ldv = (uint8_t)ldv; 3280 ldvp->is_syserr = B_TRUE; 3281 ldvp->ldv_intr_handler = nxge_syserr_intr; 3282 ldvp->ldv_ldf_masks = 0; 3283 ldvp->nxgep = nxgep; 3284 ldgvp->ldvp_syserr = ldvp; 3285 /* 3286 * Unmask the system interrupt states. 3287 */ 3288 (void) nxge_fzc_sys_err_mask_set(nxgep, SYS_ERR_SMX_MASK | 3289 SYS_ERR_IPP_MASK | SYS_ERR_TXC_MASK | 3290 SYS_ERR_ZCP_MASK); 3291 3292 (void) nxge_ldgv_setup(&ldgp, &ldvp, ldv, endldg, nrequired_p); 3293 nldvs++; 3294 } else { 3295 ldv = NXGE_SYS_ERROR_LD; 3296 ldvp->ldv = (uint8_t)ldv; 3297 ldvp->is_syserr = B_TRUE; 3298 ldvp->ldv_intr_handler = nxge_syserr_intr; 3299 ldvp->nxgep = nxgep; 3300 ldvp->ldv_ldf_masks = 0; 3301 ldgvp->ldvp_syserr = ldvp; 3302 } 3303 3304 ldgvp->ldg_intrs = *nrequired_p; 3305 3306 NXGE_DEBUG_MSG((nxgep, INT_CTL, "==> nxge_ldgv_init: " 3307 "func %d nldvs %d navail %d nrequired %d", 3308 func, nldvs, *navail_p, *nrequired_p)); 3309 3310 NXGE_DEBUG_MSG((nxgep, INT_CTL, "<== nxge_ldgv_init")); 3311 return (status); 3312 } 3313 3314 nxge_status_t 3315 nxge_ldgv_uninit(p_nxge_t nxgep) 3316 { 3317 p_nxge_ldgv_t ldgvp; 3318 3319 NXGE_DEBUG_MSG((nxgep, INT_CTL, "==> nxge_ldgv_uninit")); 3320 ldgvp = nxgep->ldgvp; 3321 if (ldgvp == NULL) { 3322 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, "<== nxge_ldgv_uninit: " 3323 "no logical group configured.")); 3324 return (NXGE_OK); 3325 } 3326 if (ldgvp->ldvp_syserr_alloced == B_TRUE) { 3327 KMEM_FREE(ldgvp->ldvp_syserr, sizeof (nxge_ldv_t)); 3328 } 3329 if (ldgvp->ldgp) { 3330 KMEM_FREE(ldgvp->ldgp, sizeof (nxge_ldg_t) * ldgvp->maxldgs); 3331 } 3332 if (ldgvp->ldvp) { 3333 KMEM_FREE(ldgvp->ldvp, sizeof (nxge_ldv_t) * ldgvp->maxldvs); 3334 } 3335 KMEM_FREE(ldgvp, sizeof (nxge_ldgv_t)); 3336 nxgep->ldgvp = NULL; 3337 3338 NXGE_DEBUG_MSG((nxgep, INT_CTL, "<== nxge_ldgv_uninit")); 3339 return (NXGE_OK); 3340 } 3341 3342 nxge_status_t 3343 nxge_intr_ldgv_init(p_nxge_t nxgep) 3344 { 3345 nxge_status_t status = NXGE_OK; 3346 3347 NXGE_DEBUG_MSG((nxgep, INT_CTL, "==> nxge_intr_ldgv_init")); 3348 /* 3349 * Configure the logical device group numbers, state vectors and 3350 * interrupt masks for each logical device. 3351 */ 3352 status = nxge_fzc_intr_init(nxgep); 3353 3354 /* 3355 * Configure logical device masks and timers. 3356 */ 3357 status = nxge_intr_mask_mgmt(nxgep); 3358 3359 NXGE_DEBUG_MSG((nxgep, INT_CTL, "<== nxge_intr_ldgv_init")); 3360 return (status); 3361 } 3362 3363 nxge_status_t 3364 nxge_intr_mask_mgmt(p_nxge_t nxgep) 3365 { 3366 p_nxge_ldgv_t ldgvp; 3367 p_nxge_ldg_t ldgp; 3368 p_nxge_ldv_t ldvp; 3369 npi_handle_t handle; 3370 int i, j; 3371 npi_status_t rs = NPI_SUCCESS; 3372 3373 NXGE_DEBUG_MSG((nxgep, INT_CTL, "==> nxge_intr_mask_mgmt")); 3374 3375 if ((ldgvp = nxgep->ldgvp) == NULL) { 3376 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 3377 "<== nxge_intr_mask_mgmt: Null ldgvp")); 3378 return (NXGE_ERROR); 3379 } 3380 handle = NXGE_DEV_NPI_HANDLE(nxgep); 3381 ldgp = ldgvp->ldgp; 3382 ldvp = ldgvp->ldvp; 3383 if (ldgp == NULL || ldvp == NULL) { 3384 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 3385 "<== nxge_intr_mask_mgmt: Null ldgp or ldvp")); 3386 return (NXGE_ERROR); 3387 } 3388 NXGE_DEBUG_MSG((nxgep, INT_CTL, 3389 "==> nxge_intr_mask_mgmt: # of intrs %d ", ldgvp->ldg_intrs)); 3390 /* Initialize masks. */ 3391 if (nxgep->niu_type != N2_NIU) { 3392 NXGE_DEBUG_MSG((nxgep, INT_CTL, 3393 "==> nxge_intr_mask_mgmt(Neptune): # intrs %d ", 3394 ldgvp->ldg_intrs)); 3395 for (i = 0; i < ldgvp->ldg_intrs; i++, ldgp++) { 3396 NXGE_DEBUG_MSG((nxgep, INT_CTL, 3397 "==> nxge_intr_mask_mgmt(Neptune): # ldv %d " 3398 "in group %d", ldgp->nldvs, ldgp->ldg)); 3399 for (j = 0; j < ldgp->nldvs; j++, ldvp++) { 3400 NXGE_DEBUG_MSG((nxgep, INT_CTL, 3401 "==> nxge_intr_mask_mgmt: set ldv # %d " 3402 "for ldg %d", ldvp->ldv, ldgp->ldg)); 3403 rs = npi_intr_mask_set(handle, ldvp->ldv, 3404 ldvp->ldv_ldf_masks); 3405 if (rs != NPI_SUCCESS) { 3406 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 3407 "<== nxge_intr_mask_mgmt: " 3408 "set mask failed " 3409 " rs 0x%x ldv %d mask 0x%x", 3410 rs, ldvp->ldv, 3411 ldvp->ldv_ldf_masks)); 3412 return (NXGE_ERROR | rs); 3413 } 3414 NXGE_DEBUG_MSG((nxgep, INT_CTL, 3415 "==> nxge_intr_mask_mgmt: " 3416 "set mask OK " 3417 " rs 0x%x ldv %d mask 0x%x", 3418 rs, ldvp->ldv, 3419 ldvp->ldv_ldf_masks)); 3420 } 3421 } 3422 } 3423 ldgp = ldgvp->ldgp; 3424 /* Configure timer and arm bit */ 3425 for (i = 0; i < nxgep->ldgvp->ldg_intrs; i++, ldgp++) { 3426 rs = npi_intr_ldg_mgmt_set(handle, ldgp->ldg, 3427 ldgp->arm, ldgp->ldg_timer); 3428 if (rs != NPI_SUCCESS) { 3429 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 3430 "<== nxge_intr_mask_mgmt: " 3431 "set timer failed " 3432 " rs 0x%x dg %d timer 0x%x", 3433 rs, ldgp->ldg, ldgp->ldg_timer)); 3434 return (NXGE_ERROR | rs); 3435 } 3436 NXGE_DEBUG_MSG((nxgep, INT_CTL, 3437 "==> nxge_intr_mask_mgmt: " 3438 "set timer OK " 3439 " rs 0x%x ldg %d timer 0x%x", 3440 rs, ldgp->ldg, ldgp->ldg_timer)); 3441 } 3442 3443 NXGE_DEBUG_MSG((nxgep, INT_CTL, "<== nxge_fzc_intr_mask_mgmt")); 3444 return (NXGE_OK); 3445 } 3446 3447 nxge_status_t 3448 nxge_intr_mask_mgmt_set(p_nxge_t nxgep, boolean_t on) 3449 { 3450 p_nxge_ldgv_t ldgvp; 3451 p_nxge_ldg_t ldgp; 3452 p_nxge_ldv_t ldvp; 3453 npi_handle_t handle; 3454 int i, j; 3455 npi_status_t rs = NPI_SUCCESS; 3456 3457 NXGE_DEBUG_MSG((nxgep, INT_CTL, 3458 "==> nxge_intr_mask_mgmt_set (%d)", on)); 3459 3460 if (nxgep->niu_type == N2_NIU) { 3461 NXGE_DEBUG_MSG((nxgep, INT_CTL, 3462 "<== nxge_intr_mask_mgmt_set (%d) not set (N2/NIU)", 3463 on)); 3464 return (NXGE_ERROR); 3465 } 3466 3467 if ((ldgvp = nxgep->ldgvp) == NULL) { 3468 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 3469 "==> nxge_intr_mask_mgmt_set: Null ldgvp")); 3470 return (NXGE_ERROR); 3471 } 3472 3473 handle = NXGE_DEV_NPI_HANDLE(nxgep); 3474 ldgp = ldgvp->ldgp; 3475 ldvp = ldgvp->ldvp; 3476 if (ldgp == NULL || ldvp == NULL) { 3477 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 3478 "<== nxge_intr_mask_mgmt_set: Null ldgp or ldvp")); 3479 return (NXGE_ERROR); 3480 } 3481 /* set masks. */ 3482 for (i = 0; i < ldgvp->ldg_intrs; i++, ldgp++) { 3483 NXGE_DEBUG_MSG((nxgep, INT_CTL, 3484 "==> nxge_intr_mask_mgmt_set: flag %d ldg %d" 3485 "set mask nldvs %d", on, ldgp->ldg, ldgp->nldvs)); 3486 for (j = 0; j < ldgp->nldvs; j++, ldvp++) { 3487 NXGE_DEBUG_MSG((nxgep, INT_CTL, 3488 "==> nxge_intr_mask_mgmt_set: " 3489 "for %d %d flag %d", i, j, on)); 3490 if (on) { 3491 ldvp->ldv_ldf_masks = 0; 3492 NXGE_DEBUG_MSG((nxgep, INT_CTL, 3493 "==> nxge_intr_mask_mgmt_set: " 3494 "ON mask off")); 3495 } else if (!on) { 3496 ldvp->ldv_ldf_masks = (uint8_t)LD_IM1_MASK; 3497 NXGE_DEBUG_MSG((nxgep, INT_CTL, 3498 "==> nxge_intr_mask_mgmt_set:mask on")); 3499 } 3500 rs = npi_intr_mask_set(handle, ldvp->ldv, 3501 ldvp->ldv_ldf_masks); 3502 if (rs != NPI_SUCCESS) { 3503 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 3504 "==> nxge_intr_mask_mgmt_set: " 3505 "set mask failed " 3506 " rs 0x%x ldv %d mask 0x%x", 3507 rs, ldvp->ldv, ldvp->ldv_ldf_masks)); 3508 return (NXGE_ERROR | rs); 3509 } 3510 NXGE_DEBUG_MSG((nxgep, INT_CTL, 3511 "==> nxge_intr_mask_mgmt_set: flag %d" 3512 "set mask OK " 3513 " ldv %d mask 0x%x", 3514 on, ldvp->ldv, ldvp->ldv_ldf_masks)); 3515 } 3516 } 3517 3518 ldgp = ldgvp->ldgp; 3519 /* set the arm bit */ 3520 for (i = 0; i < nxgep->ldgvp->ldg_intrs; i++, ldgp++) { 3521 if (on && !ldgp->arm) { 3522 ldgp->arm = B_TRUE; 3523 } else if (!on && ldgp->arm) { 3524 ldgp->arm = B_FALSE; 3525 } 3526 rs = npi_intr_ldg_mgmt_set(handle, ldgp->ldg, 3527 ldgp->arm, ldgp->ldg_timer); 3528 if (rs != NPI_SUCCESS) { 3529 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 3530 "<== nxge_intr_mask_mgmt_set: " 3531 "set timer failed " 3532 " rs 0x%x ldg %d timer 0x%x", 3533 rs, ldgp->ldg, ldgp->ldg_timer)); 3534 return (NXGE_ERROR | rs); 3535 } 3536 NXGE_DEBUG_MSG((nxgep, INT_CTL, 3537 "==> nxge_intr_mask_mgmt_set: OK (flag %d) " 3538 "set timer " 3539 " ldg %d timer 0x%x", 3540 on, ldgp->ldg, ldgp->ldg_timer)); 3541 } 3542 3543 NXGE_DEBUG_MSG((nxgep, INT_CTL, "<== nxge_intr_mask_mgmt_set")); 3544 return (NXGE_OK); 3545 } 3546 3547 static nxge_status_t 3548 nxge_get_mac_addr_properties(p_nxge_t nxgep) 3549 { 3550 #if defined(_BIG_ENDIAN) 3551 uchar_t *prop_val; 3552 uint_t prop_len; 3553 uint_t j; 3554 #endif 3555 uint_t i; 3556 uint8_t func_num; 3557 boolean_t compute_macs = B_TRUE; 3558 3559 NXGE_DEBUG_MSG((nxgep, DDI_CTL, "==> nxge_get_mac_addr_properties ")); 3560 3561 #if defined(_BIG_ENDIAN) 3562 /* 3563 * Get the ethernet address. 3564 */ 3565 (void) localetheraddr((struct ether_addr *)NULL, &nxgep->ouraddr); 3566 3567 /* 3568 * Check if it is an adapter with its own local mac address If it is 3569 * present, override the system mac address. 3570 */ 3571 if (ddi_prop_lookup_byte_array(DDI_DEV_T_ANY, nxgep->dip, 0, 3572 "local-mac-address", &prop_val, 3573 &prop_len) == DDI_PROP_SUCCESS) { 3574 if (prop_len == ETHERADDRL) { 3575 nxgep->factaddr = *(p_ether_addr_t)prop_val; 3576 NXGE_DEBUG_MSG((nxgep, DDI_CTL, "Local mac address = " 3577 "%02x:%02x:%02x:%02x:%02x:%02x", 3578 prop_val[0], prop_val[1], prop_val[2], 3579 prop_val[3], prop_val[4], prop_val[5])); 3580 } 3581 ddi_prop_free(prop_val); 3582 } 3583 if (ddi_prop_lookup_byte_array(DDI_DEV_T_ANY, nxgep->dip, 0, 3584 "local-mac-address?", &prop_val, 3585 &prop_len) == DDI_PROP_SUCCESS) { 3586 if (strncmp("true", (caddr_t)prop_val, (size_t)prop_len) == 0) { 3587 nxgep->ouraddr = nxgep->factaddr; 3588 NXGE_DEBUG_MSG((nxgep, DDI_CTL, 3589 "Using local MAC address")); 3590 } 3591 ddi_prop_free(prop_val); 3592 } else { 3593 nxgep->ouraddr = nxgep->factaddr; 3594 } 3595 3596 if ((!nxgep->vpd_info.present) || 3597 (nxge_is_valid_local_mac(nxgep->factaddr))) 3598 goto got_mac_addr; 3599 3600 NXGE_DEBUG_MSG((nxgep, DDI_CTL, "nxge_get_mac_addr_properties: " 3601 "MAC address from properties is not valid...reading from PROM")); 3602 3603 #endif 3604 if (!nxgep->vpd_info.ver_valid) { 3605 (void) nxge_espc_mac_addrs_get(nxgep); 3606 if (!nxge_is_valid_local_mac(nxgep->factaddr)) { 3607 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, "Failed to get " 3608 "MAC address")); 3609 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, "EEPROM version " 3610 "[%s] invalid...please update", 3611 nxgep->vpd_info.ver)); 3612 return (NXGE_ERROR); 3613 } 3614 nxgep->ouraddr = nxgep->factaddr; 3615 goto got_mac_addr; 3616 } 3617 /* 3618 * First get the MAC address from the info in the VPD data read 3619 * from the EEPROM. 3620 */ 3621 nxge_espc_get_next_mac_addr(nxgep->vpd_info.mac_addr, 3622 nxgep->function_num, &nxgep->factaddr); 3623 3624 if (!nxge_is_valid_local_mac(nxgep->factaddr)) { 3625 NXGE_DEBUG_MSG((nxgep, DDI_CTL, 3626 "nxge_get_mac_addr_properties: " 3627 "MAC address in EEPROM VPD data not valid" 3628 "...reading from NCR registers")); 3629 (void) nxge_espc_mac_addrs_get(nxgep); 3630 if (!nxge_is_valid_local_mac(nxgep->factaddr)) { 3631 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, "Failed to get " 3632 "MAC address")); 3633 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, "EEPROM version " 3634 "[%s] invalid...please update", 3635 nxgep->vpd_info.ver)); 3636 return (NXGE_ERROR); 3637 } 3638 } 3639 3640 nxgep->ouraddr = nxgep->factaddr; 3641 3642 got_mac_addr: 3643 func_num = nxgep->function_num; 3644 3645 /* 3646 * Note: mac-addresses property is the list of mac addresses for a 3647 * port. NXGE_MAX_MMAC_ADDRS is the total number of MAC addresses 3648 * allocated for a board. 3649 */ 3650 nxgep->nxge_mmac_info.total_factory_macs = NXGE_MAX_MMAC_ADDRS; 3651 3652 #if defined(_BIG_ENDIAN) 3653 if (ddi_prop_lookup_byte_array(DDI_DEV_T_ANY, nxgep->dip, 0, 3654 "mac-addresses", &prop_val, &prop_len) == DDI_PROP_SUCCESS) { 3655 /* 3656 * XAUI may have up to 18 MACs, more than the XMAC can 3657 * use (1 unique MAC plus 16 alternate MACs) 3658 */ 3659 nxgep->nxge_mmac_info.num_factory_mmac = 3660 prop_len / ETHERADDRL - 1; 3661 if (nxgep->nxge_mmac_info.num_factory_mmac > 3662 XMAC_MAX_ALT_ADDR_ENTRY) { 3663 nxgep->nxge_mmac_info.num_factory_mmac = 3664 XMAC_MAX_ALT_ADDR_ENTRY; 3665 } 3666 3667 for (i = 1; i <= nxgep->nxge_mmac_info.num_factory_mmac; i++) { 3668 for (j = 0; j < ETHERADDRL; j++) { 3669 nxgep->nxge_mmac_info.factory_mac_pool[i][j] = 3670 *(prop_val + (i * ETHERADDRL) + j); 3671 } 3672 NXGE_DEBUG_MSG((nxgep, DDI_CTL, 3673 "nxge_get_mac_addr_properties: Alt mac[%d] from " 3674 "mac-addresses property[%2x:%2x:%2x:%2x:%2x:%2x]", 3675 i, nxgep->nxge_mmac_info.factory_mac_pool[i][0], 3676 nxgep->nxge_mmac_info.factory_mac_pool[i][1], 3677 nxgep->nxge_mmac_info.factory_mac_pool[i][2], 3678 nxgep->nxge_mmac_info.factory_mac_pool[i][3], 3679 nxgep->nxge_mmac_info.factory_mac_pool[i][4], 3680 nxgep->nxge_mmac_info.factory_mac_pool[i][5])); 3681 } 3682 3683 compute_macs = B_FALSE; 3684 ddi_prop_free(prop_val); 3685 goto got_mmac_info; 3686 } 3687 #endif 3688 /* 3689 * total_factory_macs = 32 3690 * num_factory_mmac = (32 >> (nports/2)) - 1 3691 * So if nports = 4, then num_factory_mmac = 7 3692 * if nports = 2, then num_factory_mmac = 15 3693 */ 3694 nxgep->nxge_mmac_info.num_factory_mmac = 3695 ((nxgep->nxge_mmac_info.total_factory_macs >> 3696 (nxgep->nports >> 1))) - 1; 3697 3698 got_mmac_info: 3699 3700 if ((nxgep->function_num < 2) && 3701 (nxgep->nxge_mmac_info.num_factory_mmac > 3702 XMAC_MAX_ALT_ADDR_ENTRY)) { 3703 nxgep->nxge_mmac_info.num_factory_mmac = 3704 XMAC_MAX_ALT_ADDR_ENTRY; 3705 } else if ((nxgep->function_num > 1) && 3706 (nxgep->nxge_mmac_info.num_factory_mmac > 3707 BMAC_MAX_ALT_ADDR_ENTRY)) { 3708 nxgep->nxge_mmac_info.num_factory_mmac = 3709 BMAC_MAX_ALT_ADDR_ENTRY; 3710 } 3711 3712 for (i = 0; i <= nxgep->nxge_mmac_info.num_mmac; i++) { 3713 (void) npi_mac_altaddr_disable(nxgep->npi_handle, 3714 NXGE_GET_PORT_NUM(func_num), i); 3715 } 3716 3717 (void) nxge_init_mmac(nxgep, compute_macs); 3718 return (NXGE_OK); 3719 } 3720 3721 void 3722 nxge_get_xcvr_properties(p_nxge_t nxgep) 3723 { 3724 uchar_t *prop_val; 3725 uint_t prop_len; 3726 3727 NXGE_DEBUG_MSG((nxgep, DDI_CTL, "==> nxge_get_xcvr_properties")); 3728 3729 /* 3730 * Read the type of physical layer interface being used. 3731 */ 3732 nxgep->statsp->mac_stats.xcvr_inuse = INT_MII_XCVR; 3733 if (ddi_prop_lookup_byte_array(DDI_DEV_T_ANY, nxgep->dip, 0, 3734 "phy-type", &prop_val, &prop_len) == DDI_PROP_SUCCESS) { 3735 if (strncmp("pcs", (caddr_t)prop_val, 3736 (size_t)prop_len) == 0) { 3737 nxgep->statsp->mac_stats.xcvr_inuse = PCS_XCVR; 3738 } else { 3739 nxgep->statsp->mac_stats.xcvr_inuse = INT_MII_XCVR; 3740 } 3741 ddi_prop_free(prop_val); 3742 } else if (ddi_prop_lookup_byte_array(DDI_DEV_T_ANY, nxgep->dip, 0, 3743 "phy-interface", &prop_val, 3744 &prop_len) == DDI_PROP_SUCCESS) { 3745 if (strncmp("pcs", (caddr_t)prop_val, (size_t)prop_len) == 0) { 3746 nxgep->statsp->mac_stats.xcvr_inuse = PCS_XCVR; 3747 } else { 3748 nxgep->statsp->mac_stats.xcvr_inuse = INT_MII_XCVR; 3749 } 3750 ddi_prop_free(prop_val); 3751 } 3752 } 3753 3754 /* 3755 * Static functions start here. 3756 */ 3757 3758 static void 3759 nxge_ldgv_setup(p_nxge_ldg_t *ldgp, p_nxge_ldv_t *ldvp, uint8_t ldv, 3760 uint8_t endldg, int *ngrps) 3761 { 3762 NXGE_DEBUG_MSG((NULL, INT_CTL, "==> nxge_ldgv_setup")); 3763 /* Assign the group number for each device. */ 3764 (*ldvp)->ldg_assigned = (*ldgp)->ldg; 3765 (*ldvp)->ldgp = *ldgp; 3766 (*ldvp)->ldv = ldv; 3767 3768 NXGE_DEBUG_MSG((NULL, INT_CTL, "==> nxge_ldgv_setup: " 3769 "ldv %d endldg %d ldg %d, ldvp $%p", 3770 ldv, endldg, (*ldgp)->ldg, (*ldgp)->ldvp)); 3771 3772 (*ldgp)->nldvs++; 3773 if ((*ldgp)->ldg == (endldg - 1)) { 3774 if ((*ldgp)->ldvp == NULL) { 3775 (*ldgp)->ldvp = *ldvp; 3776 *ngrps += 1; 3777 NXGE_DEBUG_MSG((NULL, INT_CTL, 3778 "==> nxge_ldgv_setup: ngrps %d", *ngrps)); 3779 } 3780 NXGE_DEBUG_MSG((NULL, INT_CTL, 3781 "==> nxge_ldgv_setup: ldvp $%p ngrps %d", 3782 *ldvp, *ngrps)); 3783 ++*ldvp; 3784 } else { 3785 (*ldgp)->ldvp = *ldvp; 3786 *ngrps += 1; 3787 NXGE_DEBUG_MSG((NULL, INT_CTL, "==> nxge_ldgv_setup(done): " 3788 "ldv %d endldg %d ldg %d, ldvp $%p", 3789 ldv, endldg, (*ldgp)->ldg, (*ldgp)->ldvp)); 3790 (*ldvp) = ++*ldvp; 3791 (*ldgp) = ++*ldgp; 3792 NXGE_DEBUG_MSG((NULL, INT_CTL, 3793 "==> nxge_ldgv_setup: new ngrps %d", *ngrps)); 3794 } 3795 3796 NXGE_DEBUG_MSG((NULL, INT_CTL, "==> nxge_ldgv_setup: " 3797 "ldv %d ldvp $%p endldg %d ngrps %d", 3798 ldv, ldvp, endldg, *ngrps)); 3799 3800 NXGE_DEBUG_MSG((NULL, INT_CTL, "<== nxge_ldgv_setup")); 3801 } 3802 3803 /* 3804 * Note: This function assumes the following distribution of mac 3805 * addresses among 4 ports in neptune: 3806 * 3807 * ------------- 3808 * 0| |0 - local-mac-address for fn 0 3809 * ------------- 3810 * 1| |1 - local-mac-address for fn 1 3811 * ------------- 3812 * 2| |2 - local-mac-address for fn 2 3813 * ------------- 3814 * 3| |3 - local-mac-address for fn 3 3815 * ------------- 3816 * | |4 - Start of alt. mac addr. for fn 0 3817 * | | 3818 * | | 3819 * | |10 3820 * -------------- 3821 * | |11 - Start of alt. mac addr. for fn 1 3822 * | | 3823 * | | 3824 * | |17 3825 * -------------- 3826 * | |18 - Start of alt. mac addr. for fn 2 3827 * | | 3828 * | | 3829 * | |24 3830 * -------------- 3831 * | |25 - Start of alt. mac addr. for fn 3 3832 * | | 3833 * | | 3834 * | |31 3835 * -------------- 3836 * 3837 * For N2/NIU the mac addresses is from XAUI card. 3838 * 3839 * When 'compute_addrs' is true, the alternate mac addresses are computed 3840 * using the unique mac address as base. Otherwise the alternate addresses 3841 * are assigned from the list read off the 'mac-addresses' property. 3842 */ 3843 3844 static void 3845 nxge_init_mmac(p_nxge_t nxgep, boolean_t compute_addrs) 3846 { 3847 int slot; 3848 uint8_t func_num; 3849 uint16_t *base_mmac_addr; 3850 uint32_t alt_mac_ls4b; 3851 uint16_t *mmac_addr; 3852 uint32_t base_mac_ls4b; /* least significant 4 bytes */ 3853 nxge_mmac_t *mmac_info; 3854 npi_mac_addr_t mac_addr; 3855 3856 func_num = nxgep->function_num; 3857 base_mmac_addr = (uint16_t *)&nxgep->factaddr; 3858 mmac_info = (nxge_mmac_t *)&nxgep->nxge_mmac_info; 3859 3860 if (compute_addrs) { 3861 base_mac_ls4b = ((uint32_t)base_mmac_addr[1]) << 16 | 3862 base_mmac_addr[2]; 3863 3864 if (nxgep->niu_type == N2_NIU) { 3865 /* ls4b of 1st altmac */ 3866 alt_mac_ls4b = base_mac_ls4b + 1; 3867 } else { /* Neptune */ 3868 alt_mac_ls4b = base_mac_ls4b + 3869 (nxgep->nports - func_num) + 3870 (func_num * (mmac_info->num_factory_mmac)); 3871 } 3872 } 3873 3874 /* Set flags for unique MAC */ 3875 mmac_info->mac_pool[0].flags |= MMAC_SLOT_USED | MMAC_VENDOR_ADDR; 3876 3877 /* Clear flags of all alternate MAC slots */ 3878 for (slot = 1; slot <= mmac_info->num_mmac; slot++) { 3879 if (slot <= mmac_info->num_factory_mmac) 3880 mmac_info->mac_pool[slot].flags = MMAC_VENDOR_ADDR; 3881 else 3882 mmac_info->mac_pool[slot].flags = 0; 3883 } 3884 3885 /* Generate and store factory alternate MACs */ 3886 for (slot = 1; slot <= mmac_info->num_factory_mmac; slot++) { 3887 mmac_addr = (uint16_t *)&mmac_info->factory_mac_pool[slot]; 3888 if (compute_addrs) { 3889 mmac_addr[0] = base_mmac_addr[0]; 3890 mac_addr.w2 = mmac_addr[0]; 3891 3892 mmac_addr[1] = (alt_mac_ls4b >> 16) & 0x0FFFF; 3893 mac_addr.w1 = mmac_addr[1]; 3894 3895 mmac_addr[2] = alt_mac_ls4b & 0x0FFFF; 3896 mac_addr.w0 = mmac_addr[2]; 3897 3898 alt_mac_ls4b++; 3899 } else { 3900 mac_addr.w2 = mmac_addr[0]; 3901 mac_addr.w1 = mmac_addr[1]; 3902 mac_addr.w0 = mmac_addr[2]; 3903 } 3904 3905 NXGE_DEBUG_MSG((nxgep, DDI_CTL, 3906 "mac_pool_addr[%2x:%2x:%2x:%2x:%2x:%2x] npi_addr[%x%x%x]", 3907 mmac_info->factory_mac_pool[slot][0], 3908 mmac_info->factory_mac_pool[slot][1], 3909 mmac_info->factory_mac_pool[slot][2], 3910 mmac_info->factory_mac_pool[slot][3], 3911 mmac_info->factory_mac_pool[slot][4], 3912 mmac_info->factory_mac_pool[slot][5], 3913 mac_addr.w0, mac_addr.w1, mac_addr.w2)); 3914 /* 3915 * slot minus 1 because npi_mac_altaddr_entry expects 0 3916 * for the first alternate mac address. 3917 */ 3918 (void) npi_mac_altaddr_entry(nxgep->npi_handle, OP_SET, 3919 NXGE_GET_PORT_NUM(func_num), slot - 1, &mac_addr); 3920 } 3921 /* Initialize the first two parameters for mmac kstat */ 3922 nxgep->statsp->mmac_stats.mmac_max_cnt = mmac_info->num_mmac; 3923 nxgep->statsp->mmac_stats.mmac_avail_cnt = mmac_info->num_mmac; 3924 } 3925 3926 /* 3927 * Convert an RDC group index into a port ring index. That is, map 3928 * <groupid> to an index into nxgep->rx_ring_handles. 3929 * (group ring index -> port ring index) 3930 */ 3931 int 3932 nxge_get_rxring_index(p_nxge_t nxgep, int groupid, int ringidx) 3933 { 3934 int i; 3935 int index = 0; 3936 p_nxge_rdc_grp_t rdc_grp_p; 3937 p_nxge_dma_pt_cfg_t p_dma_cfgp; 3938 p_nxge_hw_pt_cfg_t p_cfgp; 3939 3940 p_dma_cfgp = &nxgep->pt_config; 3941 p_cfgp = &p_dma_cfgp->hw_config; 3942 3943 for (i = 0; i < groupid; i++) { 3944 rdc_grp_p = 3945 &p_dma_cfgp->rdc_grps[p_cfgp->def_mac_rxdma_grpid + i]; 3946 index += rdc_grp_p->max_rdcs; 3947 } 3948 3949 return (index + ringidx); 3950 } 3951