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