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