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, v.1, (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://opensource.org/licenses/CDDL-1.0. 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 /* 23 * Copyright 2014-2017 Cavium, Inc. 24 * Copyright 2018 Joyent, Inc. 25 * Copyright 2025 Oxide Computer Company 26 */ 27 28 #include "qede.h" 29 30 #define FP_LOCK(ptr) \ 31 mutex_enter(&ptr->fp_lock); 32 #define FP_UNLOCK(ptr) \ 33 mutex_exit(&ptr->fp_lock); 34 35 int 36 qede_ucst_find(qede_t *qede, const uint8_t *mac_addr) 37 { 38 int slot; 39 40 for(slot = 0; slot < qede->ucst_total; slot++) { 41 if (bcmp(qede->ucst_mac[slot].mac_addr.ether_addr_octet, 42 mac_addr, ETHERADDRL) == 0) { 43 return (slot); 44 } 45 } 46 return (-1); 47 48 } 49 50 static int 51 qede_set_mac_addr(qede_t *qede, uint8_t *mac_addr, uint8_t fl) 52 { 53 struct ecore_filter_ucast params; 54 55 memset(¶ms, 0, sizeof (params)); 56 57 params.opcode = fl; 58 params.type = ECORE_FILTER_MAC; 59 params.is_rx_filter = true; 60 params.is_tx_filter = true; 61 COPY_ETH_ADDRESS(mac_addr, params.mac); 62 63 return (ecore_filter_ucast_cmd(&qede->edev, 64 ¶ms, ECORE_SPQ_MODE_EBLOCK, NULL)); 65 66 67 } 68 static int 69 qede_add_macaddr(qede_t *qede, uint8_t *mac_addr) 70 { 71 int i, ret = 0; 72 73 i = qede_ucst_find(qede, mac_addr); 74 if (i != -1) { 75 /* LINTED E_ARGUMENT_MISMATCH */ 76 qede_info(qede, "mac addr already added %d\n", 77 qede->ucst_avail); 78 return (0); 79 } 80 if (qede->ucst_avail == 0) { 81 qede_info(qede, "add macaddr ignored \n"); 82 return (ENOSPC); 83 } 84 for (i = 0; i < qede->ucst_total; i++) { 85 if (qede->ucst_mac[i].set == 0) { 86 break; 87 } 88 } 89 if (i >= qede->ucst_total) { 90 qede_info(qede, "add macaddr ignored no space"); 91 return (ENOSPC); 92 } 93 ret = qede_set_mac_addr(qede, (uint8_t *)mac_addr, ECORE_FILTER_ADD); 94 if (ret == 0) { 95 bcopy(mac_addr, 96 qede->ucst_mac[i].mac_addr.ether_addr_octet, 97 ETHERADDRL); 98 qede->ucst_mac[i].set = 1; 99 qede->ucst_avail--; 100 /* LINTED E_ARGUMENT_MISMATCH */ 101 qede_info(qede, " add macaddr passed for addr " 102 "%02x:%02x:%02x:%02x:%02x:%02x", 103 mac_addr[0], mac_addr[1], 104 mac_addr[2], mac_addr[3], mac_addr[4], mac_addr[5]); 105 } else { 106 /* LINTED E_ARGUMENT_MISMATCH */ 107 qede_info(qede, "add macaddr failed for addr " 108 "%02x:%02x:%02x:%02x:%02x:%02x", 109 mac_addr[0], mac_addr[1], 110 mac_addr[2], mac_addr[3], mac_addr[4], mac_addr[5]); 111 112 } 113 if (qede->ucst_avail == (qede->ucst_total -1)) { 114 u8 bcast_addr[] = 115 { 116 0xff, 0xff, 0xff, 0xff, 0xff, 117 0xff 118 }; 119 for (i = 0; i < qede->ucst_total; i++) { 120 if (qede->ucst_mac[i].set == 0) 121 break; 122 } 123 ret = qede_set_mac_addr(qede, 124 (uint8_t *)bcast_addr, ECORE_FILTER_ADD); 125 if (ret == 0) { 126 bcopy(bcast_addr, 127 qede->ucst_mac[i].mac_addr.ether_addr_octet, 128 ETHERADDRL); 129 qede->ucst_mac[i].set = 1; 130 qede->ucst_avail--; 131 } else { 132 133 /* LINTED E_ARGUMENT_MISMATCH */ 134 qede_info(qede, "add macaddr failed for addr " 135 "%02x:%02x:%02x:%02x:%02x:%02x", 136 mac_addr[0], mac_addr[1], 137 mac_addr[2], mac_addr[3], mac_addr[4], 138 mac_addr[5]); 139 } 140 141 } 142 143 return (ret); 144 145 } 146 147 #ifndef ILLUMOS 148 static int 149 qede_add_mac_addr(void *arg, const uint8_t *mac_addr, const uint64_t flags) 150 #else 151 static int 152 qede_add_mac_addr(void *arg, const uint8_t *mac_addr) 153 #endif 154 { 155 qede_mac_group_t *rx_group = (qede_mac_group_t *)arg; 156 qede_t *qede = rx_group->qede; 157 int ret = DDI_SUCCESS; 158 159 /* LINTED E_ARGUMENT_MISMATCH */ 160 qede_info(qede, " mac addr :" MAC_STRING, MACTOSTR(mac_addr)); 161 162 mutex_enter(&qede->gld_lock); 163 if (qede->qede_state == QEDE_STATE_SUSPENDED) { 164 mutex_exit(&qede->gld_lock); 165 return (ECANCELED); 166 } 167 ret = qede_add_macaddr(qede, (uint8_t *)mac_addr); 168 169 mutex_exit(&qede->gld_lock); 170 171 172 return (ret); 173 } 174 175 static int 176 qede_rem_macaddr(qede_t *qede, uint8_t *mac_addr) 177 { 178 int ret = 0; 179 int i; 180 181 i = qede_ucst_find(qede, mac_addr); 182 if (i == -1) { 183 /* LINTED E_ARGUMENT_MISMATCH */ 184 qede_info(qede, 185 "mac addr not there to remove", 186 MAC_STRING, MACTOSTR(mac_addr)); 187 return (0); 188 } 189 if (qede->ucst_mac[i].set == 0) { 190 return (EINVAL); 191 } 192 ret = qede_set_mac_addr(qede, (uint8_t *)mac_addr, ECORE_FILTER_REMOVE); 193 if (ret == 0) { 194 bzero(qede->ucst_mac[i].mac_addr.ether_addr_octet,ETHERADDRL); 195 qede->ucst_mac[i].set = 0; 196 qede->ucst_avail++; 197 } else { 198 /* LINTED E_ARGUMENT_MISMATCH */ 199 qede_info(qede, "mac addr remove failed", 200 MAC_STRING, MACTOSTR(mac_addr)); 201 } 202 return (ret); 203 204 } 205 206 207 static int 208 qede_rem_mac_addr(void *arg, const uint8_t *mac_addr) 209 { 210 qede_mac_group_t *rx_group = (qede_mac_group_t *)arg; 211 qede_t *qede = rx_group->qede; 212 int ret = DDI_SUCCESS; 213 214 /* LINTED E_ARGUMENT_MISMATCH */ 215 qede_info(qede, "mac addr remove:" MAC_STRING, MACTOSTR(mac_addr)); 216 mutex_enter(&qede->gld_lock); 217 if (qede->qede_state == QEDE_STATE_SUSPENDED) { 218 mutex_exit(&qede->gld_lock); 219 return (ECANCELED); 220 } 221 ret = qede_rem_macaddr(qede, (uint8_t *)mac_addr); 222 mutex_exit(&qede->gld_lock); 223 return (ret); 224 } 225 226 227 static int 228 qede_tx_ring_stat(mac_ring_driver_t rh, uint_t stat, uint64_t *val) 229 { 230 int ret = 0; 231 232 qede_fastpath_t *fp = (qede_fastpath_t *)rh; 233 qede_tx_ring_t *tx_ring = fp->tx_ring[0]; 234 qede_t *qede = fp->qede; 235 236 237 if (qede->qede_state == QEDE_STATE_SUSPENDED) 238 return (ECANCELED); 239 240 switch (stat) { 241 case MAC_STAT_OBYTES: 242 *val = tx_ring->tx_byte_count; 243 break; 244 245 case MAC_STAT_OPACKETS: 246 *val = tx_ring->tx_pkt_count; 247 break; 248 249 default: 250 *val = 0; 251 ret = ENOTSUP; 252 } 253 254 return (ret); 255 } 256 257 #ifndef ILLUMOS 258 static mblk_t * 259 qede_rx_ring_poll(void *arg, int poll_bytes, int poll_pkts) 260 { 261 #else 262 static mblk_t * 263 qede_rx_ring_poll(void *arg, int poll_bytes) 264 { 265 /* XXX pick a value at the moment */ 266 int poll_pkts = 100; 267 #endif 268 qede_fastpath_t *fp = (qede_fastpath_t *)arg; 269 mblk_t *mp = NULL; 270 int work_done = 0; 271 qede_t *qede = fp->qede; 272 273 if (poll_bytes == 0) { 274 return (NULL); 275 } 276 277 mutex_enter(&fp->fp_lock); 278 qede->intrSbPollCnt[fp->vect_info->vect_index]++; 279 280 mp = qede_process_fastpath(fp, poll_bytes, poll_pkts, &work_done); 281 if (mp != NULL) { 282 fp->rx_ring->rx_poll_cnt++; 283 } else if ((mp == NULL) && (work_done == 0)) { 284 qede->intrSbPollNoChangeCnt[fp->vect_info->vect_index]++; 285 } 286 287 mutex_exit(&fp->fp_lock); 288 return (mp); 289 } 290 291 #ifndef ILLUMOS 292 static int 293 qede_rx_ring_intr_enable(mac_ring_driver_t rh) 294 #else 295 static int 296 qede_rx_ring_intr_enable(mac_intr_handle_t rh) 297 #endif 298 { 299 qede_fastpath_t *fp = (qede_fastpath_t *)rh; 300 301 mutex_enter(&fp->qede->drv_lock); 302 if (!fp->sb_phys && (fp->sb_dma_handle == NULL)) { 303 mutex_exit(&fp->qede->drv_lock); 304 return (DDI_FAILURE); 305 } 306 307 fp->rx_ring->intrEnableCnt++; 308 qede_enable_hw_intr(fp); 309 fp->disabled_by_poll = 0; 310 mutex_exit(&fp->qede->drv_lock); 311 312 return (DDI_SUCCESS); 313 } 314 315 #ifndef ILLUMOS 316 static int 317 qede_rx_ring_intr_disable(mac_ring_driver_t rh) 318 #else 319 static int 320 qede_rx_ring_intr_disable(mac_intr_handle_t rh) 321 #endif 322 { 323 qede_fastpath_t *fp = (qede_fastpath_t *)rh; 324 325 mutex_enter(&fp->qede->drv_lock); 326 if (!fp->sb_phys && (fp->sb_dma_handle == NULL)) { 327 mutex_exit(&fp->qede->drv_lock); 328 return (DDI_FAILURE); 329 } 330 fp->rx_ring->intrDisableCnt++; 331 qede_disable_hw_intr(fp); 332 fp->disabled_by_poll = 1; 333 mutex_exit(&fp->qede->drv_lock); 334 return (DDI_SUCCESS); 335 } 336 337 static int 338 qede_rx_ring_stat(mac_ring_driver_t rh, uint_t stat, uint64_t *val) 339 { 340 341 int ret = 0; 342 343 qede_fastpath_t *fp = (qede_fastpath_t *)rh; 344 qede_t *qede = fp->qede; 345 qede_rx_ring_t *rx_ring = fp->rx_ring; 346 347 if (qede->qede_state == QEDE_STATE_SUSPENDED) { 348 return (ECANCELED); 349 } 350 351 switch (stat) { 352 case MAC_STAT_RBYTES: 353 *val = rx_ring->rx_byte_cnt; 354 break; 355 case MAC_STAT_IPACKETS: 356 *val = rx_ring->rx_pkt_cnt; 357 break; 358 default: 359 *val = 0; 360 ret = ENOTSUP; 361 break; 362 } 363 364 return (ret); 365 } 366 367 static int 368 qede_get_global_ring_index(qede_t *qede, int gindex, int rindex) 369 { 370 qede_fastpath_t *fp; 371 qede_rx_ring_t *rx_ring; 372 int i = 0; 373 374 for (i = 0; i < qede->num_fp; i++) { 375 fp = &qede->fp_array[i]; 376 rx_ring = fp->rx_ring; 377 378 if (rx_ring->group_index == gindex) { 379 rindex--; 380 } 381 if (rindex < 0) { 382 return (i); 383 } 384 } 385 386 return (-1); 387 } 388 389 static void 390 qede_rx_ring_stop(mac_ring_driver_t rh) 391 { 392 qede_fastpath_t *fp = (qede_fastpath_t *)rh; 393 qede_rx_ring_t *rx_ring = fp->rx_ring; 394 395 qede_print("!%s(%d): called", __func__,fp->qede->instance); 396 mutex_enter(&fp->fp_lock); 397 rx_ring->mac_ring_started = B_FALSE; 398 mutex_exit(&fp->fp_lock); 399 } 400 401 static int 402 qede_rx_ring_start(mac_ring_driver_t rh, u64 mr_gen_num) 403 { 404 qede_fastpath_t *fp = (qede_fastpath_t *)rh; 405 qede_rx_ring_t *rx_ring = fp->rx_ring; 406 407 qede_print("!%s(%d): called", __func__,fp->qede->instance); 408 mutex_enter(&fp->fp_lock); 409 rx_ring->mr_gen_num = mr_gen_num; 410 rx_ring->mac_ring_started = B_TRUE; 411 rx_ring->intrDisableCnt = 0; 412 rx_ring->intrEnableCnt = 0; 413 fp->disabled_by_poll = 0; 414 415 mutex_exit(&fp->fp_lock); 416 417 return (DDI_SUCCESS); 418 } 419 420 /* Callback function from mac layer to register rings */ 421 void 422 qede_fill_ring(void *arg, mac_ring_type_t rtype, const int group_index, 423 const int ring_index, mac_ring_info_t *infop, mac_ring_handle_t rh) 424 { 425 qede_t *qede = (qede_t *)arg; 426 mac_intr_t *mintr = &infop->mri_intr; 427 428 switch (rtype) { 429 case MAC_RING_TYPE_RX: { 430 /* 431 * Index passed as a param is the ring index within the 432 * given group index. If multiple groups are supported 433 * then need to search into all groups to find out the 434 * global ring index for the passed group relative 435 * ring index 436 */ 437 int global_ring_index = qede_get_global_ring_index(qede, 438 group_index, ring_index); 439 qede_fastpath_t *fp; 440 qede_rx_ring_t *rx_ring; 441 int i; 442 443 /* 444 * global_ring_index < 0 means group index passed 445 * was registered by our driver 446 */ 447 ASSERT(global_ring_index >= 0); 448 449 if (rh == NULL) { 450 cmn_err(CE_WARN, "!rx ring(%d) ring handle NULL", 451 global_ring_index); 452 } 453 454 fp = &qede->fp_array[global_ring_index]; 455 rx_ring = fp->rx_ring; 456 fp->qede = qede; 457 458 rx_ring->mac_ring_handle = rh; 459 460 qede_info(qede, "rx_ring %d mac_ring_handle %p", 461 rx_ring->rss_id, rh); 462 463 /* mri_driver passed as arg to mac_ring* callbacks */ 464 infop->mri_driver = (mac_ring_driver_t)fp; 465 /* 466 * mri_start callback will supply a mac rings generation 467 * number which is needed while indicating packets 468 * upstream via mac_rx_ring() call 469 */ 470 infop->mri_start = qede_rx_ring_start; 471 infop->mri_stop = qede_rx_ring_stop; 472 infop->mri_poll = qede_rx_ring_poll; 473 infop->mri_stat = qede_rx_ring_stat; 474 475 mintr->mi_handle = (mac_intr_handle_t)fp; 476 mintr->mi_enable = qede_rx_ring_intr_enable; 477 mintr->mi_disable = qede_rx_ring_intr_disable; 478 if (qede->intr_ctx.intr_type_in_use & 479 (DDI_INTR_TYPE_MSIX | DDI_INTR_TYPE_MSI)) { 480 mintr->mi_ddi_handle = 481 qede->intr_ctx. 482 intr_hdl_array[global_ring_index + qede->num_hwfns]; 483 } 484 break; 485 } 486 case MAC_RING_TYPE_TX: { 487 qede_fastpath_t *fp; 488 qede_tx_ring_t *tx_ring; 489 int i, tc; 490 491 ASSERT(ring_index < qede->num_fp); 492 493 fp = &qede->fp_array[ring_index]; 494 fp->qede = qede; 495 tx_ring = fp->tx_ring[0]; 496 tx_ring->mac_ring_handle = rh; 497 qede_info(qede, "tx_ring %d mac_ring_handle %p", 498 tx_ring->tx_queue_index, rh); 499 infop->mri_driver = (mac_ring_driver_t)fp; 500 infop->mri_start = NULL; 501 infop->mri_stop = NULL; 502 infop->mri_tx = qede_ring_tx; 503 infop->mri_stat = qede_tx_ring_stat; 504 if (qede->intr_ctx.intr_type_in_use & 505 (DDI_INTR_TYPE_MSIX | DDI_INTR_TYPE_MSI)) { 506 mintr->mi_ddi_handle = 507 qede->intr_ctx. 508 intr_hdl_array[ring_index + qede->num_hwfns]; 509 } 510 break; 511 } 512 default: 513 break; 514 } 515 } 516 517 /* 518 * Callback function from mac layer to register group 519 */ 520 void 521 qede_fill_group(void *arg, mac_ring_type_t rtype, const int index, 522 mac_group_info_t *infop, mac_group_handle_t gh) 523 { 524 qede_t *qede = (qede_t *)arg; 525 526 switch (rtype) { 527 case MAC_RING_TYPE_RX: { 528 qede_mac_group_t *rx_group; 529 530 rx_group = &qede->rx_groups[index]; 531 rx_group->group_handle = gh; 532 rx_group->group_index = index; 533 rx_group->qede = qede; 534 infop->mgi_driver = (mac_group_driver_t)rx_group; 535 infop->mgi_start = NULL; 536 infop->mgi_stop = NULL; 537 #ifndef ILLUMOS 538 infop->mgi_addvlan = NULL; 539 infop->mgi_remvlan = NULL; 540 infop->mgi_getsriov_info = NULL; 541 infop->mgi_setmtu = NULL; 542 #endif 543 infop->mgi_addmac = qede_add_mac_addr; 544 infop->mgi_remmac = qede_rem_mac_addr; 545 infop->mgi_count = qede->num_fp; 546 #ifndef ILLUMOS 547 if (index == 0) { 548 infop->mgi_flags = MAC_GROUP_DEFAULT; 549 } 550 #endif 551 552 break; 553 } 554 case MAC_RING_TYPE_TX: { 555 qede_mac_group_t *tx_group; 556 557 tx_group = &qede->tx_groups[index]; 558 tx_group->group_handle = gh; 559 tx_group->group_index = index; 560 tx_group->qede = qede; 561 562 infop->mgi_driver = (mac_group_driver_t)tx_group; 563 infop->mgi_start = NULL; 564 infop->mgi_stop = NULL; 565 infop->mgi_addmac = NULL; 566 infop->mgi_remmac = NULL; 567 #ifndef ILLUMOS 568 infop->mgi_addvlan = NULL; 569 infop->mgi_remvlan = NULL; 570 infop->mgi_setmtu = NULL; 571 infop->mgi_getsriov_info = NULL; 572 #endif 573 574 infop->mgi_count = qede->num_fp; 575 576 #ifndef ILLUMOS 577 if (index == 0) { 578 infop->mgi_flags = MAC_GROUP_DEFAULT; 579 } 580 #endif 581 break; 582 } 583 default: 584 break; 585 } 586 } 587 588 #ifdef ILLUMOS 589 static int 590 qede_transceiver_info(void *arg, uint_t id, mac_transceiver_info_t *infop) 591 { 592 qede_t *qede = arg; 593 struct ecore_dev *edev = &qede->edev; 594 struct ecore_hwfn *hwfn; 595 struct ecore_ptt *ptt; 596 uint32_t transceiver_state; 597 598 if (id >= edev->num_hwfns || arg == NULL || infop == NULL) 599 return (EINVAL); 600 601 hwfn = &edev->hwfns[id]; 602 ptt = ecore_ptt_acquire(hwfn); 603 if (ptt == NULL) { 604 return (EIO); 605 } 606 /* 607 * Use the underlying raw API to get this information. While the 608 * ecore_phy routines have some ways of getting to this information, it 609 * ends up writing the raw data as ASCII characters which doesn't help 610 * us one bit. 611 */ 612 transceiver_state = ecore_rd(hwfn, ptt, hwfn->mcp_info->port_addr + 613 offsetof(struct public_port, transceiver_data)); 614 transceiver_state = GET_FIELD(transceiver_state, ETH_TRANSCEIVER_STATE); 615 ecore_ptt_release(hwfn, ptt); 616 617 if ((transceiver_state & ETH_TRANSCEIVER_STATE_PRESENT) != 0) { 618 mac_transceiver_info_set_present(infop, B_TRUE); 619 /* 620 * Based on our testing, the ETH_TRANSCEIVER_STATE_VALID flag is 621 * not set, so we cannot rely on it. Instead, we have found that 622 * the ETH_TRANSCEIVER_STATE_UPDATING will be set when we cannot 623 * use the transceiver. 624 */ 625 if ((transceiver_state & ETH_TRANSCEIVER_STATE_UPDATING) != 0) { 626 mac_transceiver_info_set_usable(infop, B_FALSE); 627 } else { 628 mac_transceiver_info_set_usable(infop, B_TRUE); 629 } 630 } else { 631 mac_transceiver_info_set_present(infop, B_FALSE); 632 mac_transceiver_info_set_usable(infop, B_FALSE); 633 } 634 635 return (0); 636 } 637 638 static int 639 qede_transceiver_read(void *arg, uint_t id, uint_t page, void *buf, 640 size_t nbytes, off_t offset, size_t *nread) 641 { 642 qede_t *qede = arg; 643 struct ecore_dev *edev = &qede->edev; 644 struct ecore_hwfn *hwfn; 645 uint32_t port, lane; 646 struct ecore_ptt *ptt; 647 enum _ecore_status_t ret; 648 649 if (id >= edev->num_hwfns || buf == NULL || nbytes == 0 || nread == NULL || 650 (page != 0xa0 && page != 0xa2) || offset < 0) 651 return (EINVAL); 652 653 /* 654 * Both supported pages have a length of 256 bytes, ensure nothing asks 655 * us to go beyond that. 656 */ 657 if (nbytes > 256 || offset >= 256 || (offset + nbytes > 256)) { 658 return (EINVAL); 659 } 660 661 hwfn = &edev->hwfns[id]; 662 ptt = ecore_ptt_acquire(hwfn); 663 if (ptt == NULL) { 664 return (EIO); 665 } 666 667 ret = ecore_mcp_phy_sfp_read(hwfn, ptt, hwfn->port_id, page, offset, 668 nbytes, buf); 669 ecore_ptt_release(hwfn, ptt); 670 if (ret != ECORE_SUCCESS) { 671 return (EIO); 672 } 673 *nread = nbytes; 674 return (0); 675 } 676 #endif /* ILLUMOS */ 677 678 679 static int 680 qede_mac_stats(void * arg, 681 uint_t stat, 682 uint64_t * value) 683 { 684 qede_t * qede = (qede_t *)arg; 685 struct ecore_eth_stats vstats; 686 struct ecore_dev *edev = &qede->edev; 687 struct qede_link_cfg lnkcfg; 688 int rc = 0; 689 qede_fastpath_t *fp = &qede->fp_array[0]; 690 qede_rx_ring_t *rx_ring; 691 qede_tx_ring_t *tx_ring; 692 693 if ((qede == NULL) || (value == NULL)) { 694 return EINVAL; 695 } 696 697 698 mutex_enter(&qede->gld_lock); 699 700 if(qede->qede_state != QEDE_STATE_STARTED) { 701 mutex_exit(&qede->gld_lock); 702 return EAGAIN; 703 } 704 705 *value = 0; 706 707 memset(&vstats, 0, sizeof(struct ecore_eth_stats)); 708 ecore_get_vport_stats(edev, &vstats); 709 710 711 memset(&qede->curcfg, 0, sizeof(struct qede_link_cfg)); 712 qede_get_link_info(&edev->hwfns[0], &qede->curcfg); 713 714 715 716 switch (stat) 717 { 718 case MAC_STAT_IFSPEED: 719 *value = (qede->props.link_speed * 1000000ULL); 720 break; 721 case MAC_STAT_MULTIRCV: 722 *value = vstats.common.rx_mcast_pkts; 723 break; 724 case MAC_STAT_BRDCSTRCV: 725 *value = vstats.common.rx_bcast_pkts; 726 break; 727 case MAC_STAT_MULTIXMT: 728 *value = vstats.common.tx_mcast_pkts; 729 break; 730 case MAC_STAT_BRDCSTXMT: 731 *value = vstats.common.tx_bcast_pkts; 732 break; 733 case MAC_STAT_NORCVBUF: 734 *value = vstats.common.no_buff_discards; 735 break; 736 case MAC_STAT_NOXMTBUF: 737 *value = 0; 738 break; 739 case MAC_STAT_IERRORS: 740 case ETHER_STAT_MACRCV_ERRORS: 741 *value = vstats.common.mac_filter_discards + 742 vstats.common.packet_too_big_discard + 743 vstats.common.rx_crc_errors; 744 break; 745 746 case MAC_STAT_OERRORS: 747 break; 748 749 case MAC_STAT_COLLISIONS: 750 *value = vstats.bb.tx_total_collisions; 751 break; 752 753 case MAC_STAT_RBYTES: 754 *value = vstats.common.rx_ucast_bytes + 755 vstats.common.rx_mcast_bytes + 756 vstats.common.rx_bcast_bytes; 757 break; 758 759 case MAC_STAT_IPACKETS: 760 *value = vstats.common.rx_ucast_pkts + 761 vstats.common.rx_mcast_pkts + 762 vstats.common.rx_bcast_pkts; 763 break; 764 765 case MAC_STAT_OBYTES: 766 *value = vstats.common.tx_ucast_bytes + 767 vstats.common.tx_mcast_bytes + 768 vstats.common.tx_bcast_bytes; 769 break; 770 771 case MAC_STAT_OPACKETS: 772 *value = vstats.common.tx_ucast_pkts + 773 vstats.common.tx_mcast_pkts + 774 vstats.common.tx_bcast_pkts; 775 break; 776 777 case ETHER_STAT_ALIGN_ERRORS: 778 *value = vstats.common.rx_align_errors; 779 break; 780 781 case ETHER_STAT_FCS_ERRORS: 782 *value = vstats.common.rx_crc_errors; 783 break; 784 785 case ETHER_STAT_FIRST_COLLISIONS: 786 break; 787 788 case ETHER_STAT_MULTI_COLLISIONS: 789 break; 790 791 case ETHER_STAT_DEFER_XMTS: 792 break; 793 794 case ETHER_STAT_TX_LATE_COLLISIONS: 795 break; 796 797 case ETHER_STAT_EX_COLLISIONS: 798 break; 799 800 case ETHER_STAT_MACXMT_ERRORS: 801 *value = 0; 802 break; 803 804 case ETHER_STAT_CARRIER_ERRORS: 805 break; 806 807 case ETHER_STAT_TOOLONG_ERRORS: 808 *value = vstats.common.rx_oversize_packets; 809 break; 810 811 #if (MAC_VERSION > 1) 812 case ETHER_STAT_TOOSHORT_ERRORS: 813 *value = vstats.common.rx_undersize_packets; 814 break; 815 #endif 816 817 case ETHER_STAT_XCVR_ADDR: 818 *value = 0; 819 break; 820 821 case ETHER_STAT_XCVR_ID: 822 *value = 0; 823 break; 824 825 case ETHER_STAT_XCVR_INUSE: 826 *value = (uint64_t)qede_link_to_media(&qede->curcfg, 827 qede->props.link_speed); 828 break; 829 830 #if (MAC_VERSION > 1) 831 case ETHER_STAT_CAP_10GFDX: 832 *value = 0; 833 break; 834 #endif 835 case ETHER_STAT_CAP_100FDX: 836 *value = 0; 837 break; 838 case ETHER_STAT_CAP_100HDX: 839 *value = 0; 840 break; 841 case ETHER_STAT_CAP_ASMPAUSE: 842 *value = 1; 843 break; 844 case ETHER_STAT_CAP_PAUSE: 845 *value = 1; 846 break; 847 case ETHER_STAT_CAP_AUTONEG: 848 *value = 1; 849 break; 850 851 #if (MAC_VERSION > 1) 852 case ETHER_STAT_CAP_REMFAULT: 853 *value = 0; 854 break; 855 #endif 856 857 #if (MAC_VERSION > 1) 858 case ETHER_STAT_ADV_CAP_10GFDX: 859 *value = 0; 860 break; 861 #endif 862 case ETHER_STAT_ADV_CAP_ASMPAUSE: 863 *value = 1; 864 break; 865 866 case ETHER_STAT_ADV_CAP_PAUSE: 867 *value = 1; 868 break; 869 870 case ETHER_STAT_ADV_CAP_AUTONEG: 871 *value = qede->curcfg.adv_capab.autoneg; 872 break; 873 874 #if (MAC_VERSION > 1) 875 case ETHER_STAT_ADV_REMFAULT: 876 *value = 0; 877 break; 878 #endif 879 880 case ETHER_STAT_LINK_AUTONEG: 881 *value = qede->curcfg.autoneg; 882 break; 883 884 case ETHER_STAT_LINK_DUPLEX: 885 *value = (qede->props.link_duplex == DUPLEX_FULL) ? 886 LINK_DUPLEX_FULL : LINK_DUPLEX_HALF; 887 break; 888 /* 889 * Supported speeds. These indicate what hardware is capable of. 890 */ 891 case ETHER_STAT_CAP_1000HDX: 892 *value = qede->curcfg.supp_capab.param_1000hdx; 893 break; 894 895 case ETHER_STAT_CAP_1000FDX: 896 *value = qede->curcfg.supp_capab.param_1000fdx; 897 break; 898 899 case ETHER_STAT_CAP_10GFDX: 900 *value = qede->curcfg.supp_capab.param_10000fdx; 901 break; 902 903 case ETHER_STAT_CAP_25GFDX: 904 *value = qede->curcfg.supp_capab.param_25000fdx; 905 break; 906 907 case ETHER_STAT_CAP_40GFDX: 908 *value = qede->curcfg.supp_capab.param_40000fdx; 909 break; 910 911 case ETHER_STAT_CAP_50GFDX: 912 *value = qede->curcfg.supp_capab.param_50000fdx; 913 break; 914 915 case ETHER_STAT_CAP_100GFDX: 916 *value = qede->curcfg.supp_capab.param_100000fdx; 917 break; 918 919 /* 920 * Advertised speeds. These indicate what hardware is currently sending. 921 */ 922 case ETHER_STAT_ADV_CAP_1000HDX: 923 *value = qede->curcfg.adv_capab.param_1000hdx; 924 break; 925 926 case ETHER_STAT_ADV_CAP_1000FDX: 927 *value = qede->curcfg.adv_capab.param_1000fdx; 928 break; 929 930 case ETHER_STAT_ADV_CAP_10GFDX: 931 *value = qede->curcfg.adv_capab.param_10000fdx; 932 break; 933 934 case ETHER_STAT_ADV_CAP_25GFDX: 935 *value = qede->curcfg.adv_capab.param_25000fdx; 936 break; 937 938 case ETHER_STAT_ADV_CAP_40GFDX: 939 *value = qede->curcfg.adv_capab.param_40000fdx; 940 break; 941 942 case ETHER_STAT_ADV_CAP_50GFDX: 943 *value = qede->curcfg.adv_capab.param_50000fdx; 944 break; 945 946 case ETHER_STAT_ADV_CAP_100GFDX: 947 *value = qede->curcfg.adv_capab.param_100000fdx; 948 break; 949 950 default: 951 rc = ENOTSUP; 952 } 953 954 mutex_exit(&qede->gld_lock); 955 return (rc); 956 } 957 958 /* (flag) TRUE = on, FALSE = off */ 959 static int 960 qede_mac_promiscuous(void *arg, 961 boolean_t on) 962 { 963 qede_t *qede = (qede_t *)arg; 964 qede_print("!%s(%d): called", __func__,qede->instance); 965 int ret = DDI_SUCCESS; 966 enum qede_filter_rx_mode_type mode; 967 968 mutex_enter(&qede->drv_lock); 969 970 if (qede->qede_state == QEDE_STATE_SUSPENDED) { 971 ret = ECANCELED; 972 goto exit; 973 } 974 975 if (on) { 976 qede_info(qede, "Entering promiscuous mode"); 977 mode = QEDE_FILTER_RX_MODE_PROMISC; 978 qede->params.promisc_fl = B_TRUE; 979 } else { 980 qede_info(qede, "Leaving promiscuous mode"); 981 if(qede->params.multi_promisc_fl == B_TRUE) { 982 mode = QEDE_FILTER_RX_MODE_MULTI_PROMISC; 983 } else { 984 mode = QEDE_FILTER_RX_MODE_REGULAR; 985 } 986 qede->params.promisc_fl = B_FALSE; 987 } 988 989 ret = qede_set_filter_rx_mode(qede, mode); 990 991 exit: 992 mutex_exit(&qede->drv_lock); 993 return (ret); 994 } 995 996 int qede_set_rx_mac_mcast(qede_t *qede, enum ecore_filter_opcode opcode, 997 uint8_t *mac, int mc_cnt) 998 { 999 struct ecore_filter_mcast cmd; 1000 int i; 1001 memset(&cmd, 0, sizeof(cmd)); 1002 cmd.opcode = opcode; 1003 cmd.num_mc_addrs = mc_cnt; 1004 1005 for (i = 0; i < mc_cnt; i++, mac += ETH_ALLEN) { 1006 COPY_ETH_ADDRESS(mac, cmd.mac[i]); 1007 } 1008 1009 1010 return (ecore_filter_mcast_cmd(&qede->edev, &cmd, 1011 ECORE_SPQ_MODE_CB, NULL)); 1012 1013 } 1014 1015 int 1016 qede_set_filter_rx_mode(qede_t * qede, enum qede_filter_rx_mode_type type) 1017 { 1018 struct ecore_filter_accept_flags flg; 1019 1020 memset(&flg, 0, sizeof(flg)); 1021 1022 flg.update_rx_mode_config = 1; 1023 flg.update_tx_mode_config = 1; 1024 flg.rx_accept_filter = ECORE_ACCEPT_UCAST_MATCHED | 1025 ECORE_ACCEPT_MCAST_MATCHED | ECORE_ACCEPT_BCAST; 1026 flg.tx_accept_filter = ECORE_ACCEPT_UCAST_MATCHED | 1027 ECORE_ACCEPT_MCAST_MATCHED | ECORE_ACCEPT_BCAST; 1028 1029 if (type == QEDE_FILTER_RX_MODE_PROMISC) 1030 flg.rx_accept_filter |= ECORE_ACCEPT_UCAST_UNMATCHED | 1031 ECORE_ACCEPT_MCAST_UNMATCHED; 1032 else if (type == QEDE_FILTER_RX_MODE_MULTI_PROMISC) 1033 flg.rx_accept_filter |= ECORE_ACCEPT_MCAST_UNMATCHED; 1034 qede_info(qede, "rx_mode rx_filter=0x%x tx_filter=0x%x type=0x%x\n", 1035 flg.rx_accept_filter, flg.tx_accept_filter, type); 1036 return (ecore_filter_accept_cmd(&qede->edev, 0, flg, 1037 0, /* update_accept_any_vlan */ 1038 0, /* accept_any_vlan */ 1039 ECORE_SPQ_MODE_CB, NULL)); 1040 } 1041 1042 int 1043 qede_multicast(qede_t *qede, boolean_t flag, const uint8_t *ptr_mcaddr) 1044 { 1045 int i, ret = DDI_SUCCESS; 1046 qede_mcast_list_entry_t *ptr_mlist; 1047 qede_mcast_list_entry_t *ptr_entry; 1048 int mc_cnt; 1049 unsigned char *mc_macs, *tmpmc; 1050 size_t size; 1051 boolean_t mcmac_exists = B_FALSE; 1052 enum qede_filter_rx_mode_type mode; 1053 1054 if (!ptr_mcaddr) { 1055 cmn_err(CE_NOTE, "Removing all multicast"); 1056 } else { 1057 cmn_err(CE_NOTE, 1058 "qede=%p %s multicast: %02x:%02x:%02x:%02x:%02x:%02x", 1059 qede, (flag) ? "Adding" : "Removing", ptr_mcaddr[0], 1060 ptr_mcaddr[1],ptr_mcaddr[2],ptr_mcaddr[3],ptr_mcaddr[4], 1061 ptr_mcaddr[5]); 1062 } 1063 1064 1065 if (flag && (ptr_mcaddr == NULL)) { 1066 cmn_err(CE_WARN, "ERROR: Multicast address not specified"); 1067 return EINVAL; 1068 } 1069 1070 1071 /* exceeds addition of mcaddr above limit */ 1072 if (flag && (qede->mc_cnt >= MAX_MC_SOFT_LIMIT)) { 1073 qede_info(qede, "Cannot add more than MAX_MC_SOFT_LIMIT"); 1074 return ENOENT; 1075 } 1076 1077 size = MAX_MC_SOFT_LIMIT * ETH_ALLEN; 1078 1079 mc_macs = kmem_zalloc(size, KM_NOSLEEP); 1080 if (!mc_macs) { 1081 cmn_err(CE_WARN, "ERROR: Failed to allocate for mc_macs"); 1082 return EINVAL; 1083 } 1084 1085 tmpmc = mc_macs; 1086 1087 /* remove all multicast - as flag not set and mcaddr not specified*/ 1088 if (!flag && (ptr_mcaddr == NULL)) { 1089 QEDE_LIST_FOR_EACH_ENTRY(ptr_entry, 1090 &qede->mclist.head, qede_mcast_list_entry_t, mclist_entry) 1091 { 1092 if (ptr_entry != NULL) { 1093 QEDE_LIST_REMOVE(&ptr_entry->mclist_entry, 1094 &qede->mclist.head); 1095 kmem_free(ptr_entry, 1096 sizeof (qede_mcast_list_entry_t) + ETH_ALLEN); 1097 } 1098 } 1099 1100 ret = qede_set_rx_mac_mcast(qede, 1101 ECORE_FILTER_REMOVE, mc_macs, 1); 1102 qede->mc_cnt = 0; 1103 goto exit; 1104 } 1105 1106 QEDE_LIST_FOR_EACH_ENTRY(ptr_entry, 1107 &qede->mclist.head, qede_mcast_list_entry_t, mclist_entry) 1108 { 1109 if ((ptr_entry != NULL) && 1110 IS_ETH_ADDRESS_EQUAL(ptr_mcaddr, ptr_entry->mac)) { 1111 mcmac_exists = B_TRUE; 1112 break; 1113 } 1114 } 1115 if (flag && mcmac_exists) { 1116 ret = DDI_SUCCESS; 1117 goto exit; 1118 } else if (!flag && !mcmac_exists) { 1119 ret = DDI_SUCCESS; 1120 goto exit; 1121 } 1122 1123 if (flag) { 1124 ptr_entry = kmem_zalloc((sizeof (qede_mcast_list_entry_t) + 1125 ETH_ALLEN), KM_NOSLEEP); 1126 ptr_entry->mac = (uint8_t *)ptr_entry + 1127 sizeof (qede_mcast_list_entry_t); 1128 COPY_ETH_ADDRESS(ptr_mcaddr, ptr_entry->mac); 1129 QEDE_LIST_ADD(&ptr_entry->mclist_entry, &qede->mclist.head); 1130 } else { 1131 QEDE_LIST_REMOVE(&ptr_entry->mclist_entry, &qede->mclist.head); 1132 kmem_free(ptr_entry, sizeof(qede_mcast_list_entry_t) + 1133 ETH_ALLEN); 1134 } 1135 1136 mc_cnt = 0; 1137 QEDE_LIST_FOR_EACH_ENTRY(ptr_entry, &qede->mclist.head, 1138 qede_mcast_list_entry_t, mclist_entry) { 1139 COPY_ETH_ADDRESS(ptr_entry->mac, tmpmc); 1140 tmpmc += ETH_ALLEN; 1141 mc_cnt++; 1142 } 1143 qede->mc_cnt = mc_cnt; 1144 if (mc_cnt <=64) { 1145 ret = qede_set_rx_mac_mcast(qede, ECORE_FILTER_ADD, 1146 (unsigned char *)mc_macs, mc_cnt); 1147 if ((qede->params.multi_promisc_fl == B_TRUE) && 1148 (qede->params.promisc_fl == B_FALSE)) { 1149 mode = QEDE_FILTER_RX_MODE_REGULAR; 1150 ret = qede_set_filter_rx_mode(qede, mode); 1151 } 1152 qede->params.multi_promisc_fl = B_FALSE; 1153 } else { 1154 if ((qede->params.multi_promisc_fl == B_FALSE) && 1155 (qede->params.promisc_fl == B_FALSE)) { 1156 ret = qede_set_filter_rx_mode(qede, 1157 QEDE_FILTER_RX_MODE_MULTI_PROMISC); 1158 } 1159 qede->params.multi_promisc_fl = B_TRUE; 1160 qede_info(qede, "mode is MULTI_PROMISC"); 1161 } 1162 exit: 1163 kmem_free(mc_macs, size); 1164 qede_info(qede, "multicast ret %d mc_cnt %d\n", ret, qede->mc_cnt); 1165 return (ret); 1166 } 1167 1168 /* 1169 * This function is used to enable or disable multicast packet reception for 1170 * particular multicast addresses. 1171 * (flag) TRUE = add, FALSE = remove 1172 */ 1173 static int 1174 qede_mac_multicast(void *arg, 1175 boolean_t flag, 1176 const uint8_t * mcast_addr) 1177 { 1178 qede_t *qede = (qede_t *)arg; 1179 int ret = DDI_SUCCESS; 1180 1181 1182 mutex_enter(&qede->gld_lock); 1183 if(qede->qede_state != QEDE_STATE_STARTED) { 1184 mutex_exit(&qede->gld_lock); 1185 return (EAGAIN); 1186 } 1187 ret = qede_multicast(qede, flag, mcast_addr); 1188 1189 mutex_exit(&qede->gld_lock); 1190 1191 return (ret); 1192 } 1193 int 1194 qede_clear_filters(qede_t *qede) 1195 { 1196 int ret = 0; 1197 int i; 1198 if ((qede->params.promisc_fl == B_TRUE) || 1199 (qede->params.multi_promisc_fl == B_TRUE)) { 1200 ret = qede_set_filter_rx_mode(qede, 1201 QEDE_FILTER_RX_MODE_REGULAR); 1202 if (ret) { 1203 qede_info(qede, 1204 "qede_clear_filters failed to set rx_mode"); 1205 } 1206 } 1207 for (i=0; i < qede->ucst_total; i++) 1208 { 1209 if (qede->ucst_mac[i].set) { 1210 qede_rem_macaddr(qede, 1211 qede->ucst_mac[i].mac_addr.ether_addr_octet); 1212 } 1213 } 1214 qede_multicast(qede, B_FALSE, NULL); 1215 return (ret); 1216 } 1217 1218 1219 #ifdef NO_CROSSBOW 1220 static int 1221 qede_mac_unicast(void *arg, 1222 const uint8_t * mac_addr) 1223 { 1224 qede_t *qede = (qede_t *)arg; 1225 return 0; 1226 } 1227 1228 1229 static mblk_t * 1230 qede_mac_tx(void *arg, 1231 mblk_t * mblk) 1232 { 1233 qede_t *qede = (qede_t *)arg; 1234 qede_fastpath_t *fp = &qede->fp_array[0]; 1235 1236 mblk = qede_ring_tx((void *)fp, mblk); 1237 1238 return (mblk); 1239 } 1240 #endif /* NO_CROSSBOW */ 1241 1242 1243 static lb_property_t loopmodes[] = { 1244 { normal, "normal", QEDE_LOOP_NONE }, 1245 { internal, "internal", QEDE_LOOP_INTERNAL }, 1246 { external, "external", QEDE_LOOP_EXTERNAL }, 1247 }; 1248 1249 /* 1250 * Set Loopback mode 1251 */ 1252 1253 static enum ioc_reply 1254 qede_set_loopback_mode(qede_t *qede, uint32_t mode) 1255 { 1256 int i = 0; 1257 struct ecore_dev *edev = &qede->edev; 1258 struct ecore_hwfn *hwfn; 1259 struct ecore_ptt *ptt = NULL; 1260 struct ecore_mcp_link_params *link_params; 1261 1262 hwfn = &edev->hwfns[0]; 1263 link_params = ecore_mcp_get_link_params(hwfn); 1264 ptt = ecore_ptt_acquire(hwfn); 1265 1266 switch(mode) { 1267 default: 1268 qede_info(qede, "unknown loopback mode !!"); 1269 ecore_ptt_release(hwfn, ptt); 1270 return IOC_INVAL; 1271 1272 case QEDE_LOOP_NONE: 1273 ecore_mcp_set_link(hwfn, ptt, 0); 1274 1275 while (qede->params.link_state && i < 5000) { 1276 OSAL_MSLEEP(1); 1277 i++; 1278 } 1279 i = 0; 1280 1281 link_params->loopback_mode = ETH_LOOPBACK_NONE; 1282 qede->loop_back_mode = QEDE_LOOP_NONE; 1283 (void) ecore_mcp_set_link(hwfn, ptt, 1); 1284 ecore_ptt_release(hwfn, ptt); 1285 1286 while (!qede->params.link_state && i < 5000) { 1287 OSAL_MSLEEP(1); 1288 i++; 1289 } 1290 return IOC_REPLY; 1291 1292 case QEDE_LOOP_INTERNAL: 1293 qede_print("!%s(%d) : loopback mode (INTERNAL) is set!", 1294 __func__, qede->instance); 1295 ecore_mcp_set_link(hwfn, ptt, 0); 1296 1297 while(qede->params.link_state && i < 5000) { 1298 OSAL_MSLEEP(1); 1299 i++; 1300 } 1301 i = 0; 1302 link_params->loopback_mode = ETH_LOOPBACK_INT_PHY; 1303 qede->loop_back_mode = QEDE_LOOP_INTERNAL; 1304 (void) ecore_mcp_set_link(hwfn, ptt, 1); 1305 ecore_ptt_release(hwfn, ptt); 1306 1307 while(!qede->params.link_state && i < 5000) { 1308 OSAL_MSLEEP(1); 1309 i++; 1310 } 1311 return IOC_REPLY; 1312 1313 case QEDE_LOOP_EXTERNAL: 1314 qede_print("!%s(%d) : External loopback mode is not supported", 1315 __func__, qede->instance); 1316 ecore_ptt_release(hwfn, ptt); 1317 return IOC_INVAL; 1318 } 1319 } 1320 1321 static int 1322 qede_ioctl_pcicfg_rd(qede_t *qede, u32 addr, void *data, 1323 int len) 1324 { 1325 u32 crb, actual_crb; 1326 uint32_t ret = 0; 1327 int cap_offset = 0, cap_id = 0, next_cap = 0; 1328 ddi_acc_handle_t pci_cfg_handle = qede->pci_cfg_handle; 1329 qede_ioctl_data_t * data1 = (qede_ioctl_data_t *) data; 1330 1331 cap_offset = pci_config_get8(pci_cfg_handle, PCI_CONF_CAP_PTR); 1332 while (cap_offset != 0) { 1333 /* Check for an invalid PCI read. */ 1334 if (cap_offset == PCI_EINVAL8) { 1335 return DDI_FAILURE; 1336 } 1337 cap_id = pci_config_get8(pci_cfg_handle, cap_offset); 1338 if (cap_id == PCI_CAP_ID_PCI_E) { 1339 /* PCIe expr capab struct found */ 1340 break; 1341 } else { 1342 next_cap = pci_config_get8(pci_cfg_handle, 1343 cap_offset + 1); 1344 cap_offset = next_cap; 1345 } 1346 } 1347 1348 switch (len) { 1349 case 1: 1350 ret = pci_config_get8(qede->pci_cfg_handle, addr); 1351 (void) memcpy(data, &ret, sizeof(uint8_t)); 1352 break; 1353 case 2: 1354 ret = pci_config_get16(qede->pci_cfg_handle, addr); 1355 (void) memcpy(data, &ret, sizeof(uint16_t)); 1356 break; 1357 case 4: 1358 ret = pci_config_get32(qede->pci_cfg_handle, addr); 1359 (void) memcpy(data, &ret, sizeof(uint32_t)); 1360 break; 1361 default: 1362 cmn_err(CE_WARN, "bad length for pci config read\n"); 1363 return (1); 1364 } 1365 return (0); 1366 } 1367 1368 static int 1369 qede_ioctl_pcicfg_wr(qede_t *qede, u32 addr, void *data, 1370 int len) 1371 { 1372 uint16_t ret = 0; 1373 int cap_offset = 0, cap_id = 0, next_cap = 0; 1374 qede_ioctl_data_t * data1 = (qede_ioctl_data_t *) data; 1375 ddi_acc_handle_t pci_cfg_handle = qede->pci_cfg_handle; 1376 #if 1 1377 cap_offset = pci_config_get8(pci_cfg_handle, PCI_CONF_CAP_PTR); 1378 while (cap_offset != 0) { 1379 cap_id = pci_config_get8(pci_cfg_handle, cap_offset); 1380 if (cap_id == PCI_CAP_ID_PCI_E) { 1381 /* PCIe expr capab struct found */ 1382 break; 1383 } else { 1384 next_cap = pci_config_get8(pci_cfg_handle, 1385 cap_offset + 1); 1386 cap_offset = next_cap; 1387 } 1388 } 1389 #endif 1390 1391 switch(len) { 1392 case 1: 1393 pci_config_put8(qede->pci_cfg_handle, addr, 1394 *(char *)&(data)); 1395 break; 1396 case 2: 1397 ret = pci_config_get16(qede->pci_cfg_handle, addr); 1398 ret = ret | *(uint16_t *)data1->uabc; 1399 1400 pci_config_put16(qede->pci_cfg_handle, addr, 1401 ret); 1402 break; 1403 case 4: 1404 pci_config_put32(qede->pci_cfg_handle, addr, *(uint32_t *)data1->uabc); 1405 break; 1406 1407 default: 1408 return (1); 1409 } 1410 return (0); 1411 } 1412 1413 static int 1414 qede_ioctl_rd_wr_reg(qede_t *qede, void *data) 1415 { 1416 struct ecore_hwfn *p_hwfn; 1417 struct ecore_dev *edev = &qede->edev; 1418 struct ecore_ptt *ptt; 1419 qede_ioctl_data_t *data1 = (qede_ioctl_data_t *)data; 1420 uint32_t ret = 0; 1421 uint8_t cmd = (uint8_t) data1->unused1; 1422 uint32_t addr = data1->off; 1423 uint32_t val = *(uint32_t *)&data1->uabc[1]; 1424 uint32_t hwfn_index = *(uint32_t *)&data1->uabc[5]; 1425 uint32_t *reg_addr; 1426 1427 if (hwfn_index > qede->num_hwfns) { 1428 cmn_err(CE_WARN, "invalid hwfn index from application\n"); 1429 return (EINVAL); 1430 } 1431 p_hwfn = &edev->hwfns[hwfn_index]; 1432 1433 switch(cmd) { 1434 case QEDE_REG_READ: 1435 ret = ecore_rd(p_hwfn, p_hwfn->p_main_ptt, addr); 1436 (void) memcpy(data1->uabc, &ret, sizeof(uint32_t)); 1437 break; 1438 1439 case QEDE_REG_WRITE: 1440 ecore_wr(p_hwfn, p_hwfn->p_main_ptt, addr, val); 1441 break; 1442 1443 default: 1444 cmn_err(CE_WARN, 1445 "wrong command in register read/write from application\n"); 1446 break; 1447 } 1448 return (ret); 1449 } 1450 1451 static int 1452 qede_ioctl_rd_wr_nvram(qede_t *qede, mblk_t *mp) 1453 { 1454 qede_nvram_data_t *data1 = (qede_nvram_data_t *)(mp->b_cont->b_rptr); 1455 qede_nvram_data_t *data2, *next_data; 1456 struct ecore_dev *edev = &qede->edev; 1457 uint32_t hdr_size = 24, bytes_to_copy, copy_len = 0; 1458 uint32_t copy_len1 = 0; 1459 uint32_t addr = data1->off; 1460 uint32_t size = data1->size, i, buf_size; 1461 uint8_t cmd, cmd2; 1462 uint8_t *buf, *tmp_buf; 1463 mblk_t *mp1; 1464 1465 cmd = (uint8_t)data1->unused1; 1466 1467 switch(cmd) { 1468 case QEDE_NVRAM_CMD_READ: 1469 buf = kmem_zalloc(size, GFP_KERNEL); 1470 if(buf == NULL) { 1471 cmn_err(CE_WARN, "memory allocation failed" 1472 " in nvram read ioctl\n"); 1473 return (DDI_FAILURE); 1474 } 1475 (void) ecore_mcp_nvm_read(edev, addr, buf, data1->size); 1476 1477 copy_len = (MBLKL(mp->b_cont)) - hdr_size; 1478 if(copy_len > size) { 1479 (void) memcpy(data1->uabc, buf, size); 1480 kmem_free(buf, size); 1481 //OSAL_FREE(edev, buf); 1482 break; 1483 } 1484 (void) memcpy(data1->uabc, buf, copy_len); 1485 bytes_to_copy = size - copy_len; 1486 tmp_buf = ((uint8_t *)buf) + copy_len; 1487 copy_len1 = copy_len; 1488 mp1 = mp->b_cont; 1489 mp1 = mp1->b_cont; 1490 1491 while (mp1) { 1492 copy_len = MBLKL(mp1); 1493 if(mp1->b_cont == NULL) { 1494 copy_len = MBLKL(mp1) - 4; 1495 } 1496 data2 = (qede_nvram_data_t *)mp1->b_rptr; 1497 if (copy_len > bytes_to_copy) { 1498 (void) memcpy(data2->uabc, tmp_buf, 1499 bytes_to_copy); 1500 kmem_free(buf, size); 1501 //OSAL_FREE(edev, buf); 1502 break; 1503 } 1504 (void) memcpy(data2->uabc, tmp_buf, copy_len); 1505 tmp_buf = tmp_buf + copy_len; 1506 copy_len += copy_len; 1507 mp1 = mp1->b_cont; 1508 bytes_to_copy = bytes_to_copy - copy_len; 1509 } 1510 1511 kmem_free(buf, size); 1512 //OSAL_FREE(edev, buf); 1513 break; 1514 1515 case QEDE_NVRAM_CMD_WRITE: 1516 cmd2 = (uint8_t )data1->cmd2; 1517 size = data1->size; 1518 addr = data1->off; 1519 buf_size = size; //data1->buf_size; 1520 //buf_size = data1->buf_size; 1521 1522 switch(cmd2){ 1523 case START_NVM_WRITE: 1524 buf = kmem_zalloc(size, GFP_KERNEL); 1525 //buf = qede->reserved_buf; 1526 qede->nvm_buf_size = data1->size; 1527 if(buf == NULL) { 1528 cmn_err(CE_WARN, 1529 "memory allocation failed in START_NVM_WRITE\n"); 1530 return DDI_FAILURE; 1531 } 1532 qede->nvm_buf_start = buf; 1533 cmn_err(CE_NOTE, 1534 "buf = %p, size = %x\n", qede->nvm_buf_start, size); 1535 qede->nvm_buf = buf; 1536 qede->copy_len = 0; 1537 //tmp_buf = buf + addr; 1538 break; 1539 1540 case ACCUMULATE_NVM_BUF: 1541 tmp_buf = qede->nvm_buf; 1542 copy_len = MBLKL(mp->b_cont) - hdr_size; 1543 if(copy_len > buf_size) { 1544 if (buf_size < qede->nvm_buf_size) { 1545 (void) memcpy(tmp_buf, data1->uabc, buf_size); 1546 qede->copy_len = qede->copy_len + 1547 buf_size; 1548 } else { 1549 (void) memcpy(tmp_buf, 1550 data1->uabc, qede->nvm_buf_size); 1551 qede->copy_len = 1552 qede->copy_len + qede->nvm_buf_size; 1553 } 1554 tmp_buf = tmp_buf + buf_size; 1555 qede->nvm_buf = tmp_buf; 1556 //qede->copy_len = qede->copy_len + buf_size; 1557 cmn_err(CE_NOTE, 1558 "buf_size from app = %x\n", copy_len); 1559 break; 1560 } 1561 (void) memcpy(tmp_buf, data1->uabc, copy_len); 1562 tmp_buf = tmp_buf + copy_len; 1563 bytes_to_copy = buf_size - copy_len; 1564 mp1 = mp->b_cont; 1565 mp1 = mp1->b_cont; 1566 copy_len1 = copy_len; 1567 1568 while (mp1) { 1569 copy_len = MBLKL(mp1); 1570 if (mp1->b_cont == NULL) { 1571 copy_len = MBLKL(mp1) - 4; 1572 } 1573 next_data = (qede_nvram_data_t *) mp1->b_rptr; 1574 if (copy_len > bytes_to_copy){ 1575 (void) memcpy(tmp_buf, next_data->uabc, 1576 bytes_to_copy); 1577 qede->copy_len = qede->copy_len + 1578 bytes_to_copy; 1579 break; 1580 } 1581 (void) memcpy(tmp_buf, next_data->uabc, 1582 copy_len); 1583 qede->copy_len = qede->copy_len + copy_len; 1584 tmp_buf = tmp_buf + copy_len; 1585 copy_len = copy_len1 + copy_len; 1586 bytes_to_copy = bytes_to_copy - copy_len; 1587 mp1 = mp1->b_cont; 1588 } 1589 qede->nvm_buf = tmp_buf; 1590 break; 1591 1592 case STOP_NVM_WRITE: 1593 //qede->nvm_buf = tmp_buf; 1594 break; 1595 case READ_BUF: 1596 tmp_buf = (uint8_t *)qede->nvm_buf_start; 1597 for(i = 0; i < size ; i++){ 1598 cmn_err(CE_NOTE, 1599 "buff (%d) : %d\n", i, *tmp_buf); 1600 tmp_buf ++; 1601 } 1602 break; 1603 } 1604 break; 1605 case QEDE_NVRAM_CMD_PUT_FILE_DATA: 1606 tmp_buf = qede->nvm_buf_start; 1607 (void) ecore_mcp_nvm_write(edev, ECORE_PUT_FILE_DATA, 1608 addr, tmp_buf, size); 1609 kmem_free(qede->nvm_buf_start, size); 1610 //OSAL_FREE(edev, tmp_buf); 1611 cmn_err(CE_NOTE, "total size = %x, copied size = %x\n", 1612 qede->nvm_buf_size, qede->copy_len); 1613 tmp_buf = NULL; 1614 qede->nvm_buf = NULL; 1615 qede->nvm_buf_start = NULL; 1616 break; 1617 1618 case QEDE_NVRAM_CMD_SET_SECURE_MODE: 1619 (void) ecore_mcp_nvm_set_secure_mode(edev, addr); 1620 break; 1621 1622 case QEDE_NVRAM_CMD_DEL_FILE: 1623 (void) ecore_mcp_nvm_del_file(edev, addr); 1624 break; 1625 1626 case QEDE_NVRAM_CMD_PUT_FILE_BEGIN: 1627 (void) ecore_mcp_nvm_put_file_begin(edev, addr); 1628 break; 1629 1630 case QEDE_NVRAM_CMD_GET_NVRAM_RESP: 1631 buf = kmem_zalloc(size, KM_SLEEP); 1632 (void) ecore_mcp_nvm_resp(edev, buf); 1633 (void)memcpy(data1->uabc, buf, size); 1634 kmem_free(buf, size); 1635 break; 1636 1637 default: 1638 cmn_err(CE_WARN, 1639 "wrong command in NVRAM read/write from application\n"); 1640 break; 1641 } 1642 return (DDI_SUCCESS); 1643 } 1644 1645 static int 1646 qede_get_func_info(qede_t *qede, void *data) 1647 { 1648 qede_link_output_t link_op; 1649 qede_func_info_t func_info; 1650 qede_ioctl_data_t *data1 = (qede_ioctl_data_t *)data; 1651 struct ecore_dev *edev = &qede->edev; 1652 struct ecore_hwfn *hwfn; 1653 struct ecore_mcp_link_params params; 1654 struct ecore_mcp_link_state link; 1655 1656 hwfn = &edev->hwfns[0]; 1657 1658 if(hwfn == NULL){ 1659 cmn_err(CE_WARN, "(%s) : cannot acquire hwfn\n", 1660 __func__); 1661 return (DDI_FAILURE); 1662 } 1663 memcpy(¶ms, &hwfn->mcp_info->link_input, sizeof(params)); 1664 memcpy(&link, &hwfn->mcp_info->link_output, sizeof(link)); 1665 1666 if(link.link_up) { 1667 link_op.link_up = true; 1668 } 1669 1670 link_op.supported_caps = SUPPORTED_FIBRE; 1671 if(params.speed.autoneg) { 1672 link_op.supported_caps |= SUPPORTED_Autoneg; 1673 } 1674 1675 if(params.pause.autoneg || 1676 (params.pause.forced_rx && params.pause.forced_tx)) { 1677 link_op.supported_caps |= SUPPORTED_Asym_Pause; 1678 } 1679 1680 if (params.pause.autoneg || params.pause.forced_rx || 1681 params.pause.forced_tx) { 1682 link_op.supported_caps |= SUPPORTED_Pause; 1683 } 1684 1685 if (params.speed.advertised_speeds & 1686 NVM_CFG1_PORT_DRV_SPEED_CAPABILITY_MASK_1G) { 1687 link_op.supported_caps |= SUPPORTED_1000baseT_Half | 1688 SUPPORTED_1000baseT_Full; 1689 } 1690 1691 if (params.speed.advertised_speeds & 1692 NVM_CFG1_PORT_DRV_SPEED_CAPABILITY_MASK_10G) { 1693 link_op.supported_caps |= SUPPORTED_10000baseKR_Full; 1694 } 1695 1696 if (params.speed.advertised_speeds & 1697 NVM_CFG1_PORT_DRV_LINK_SPEED_40G) { 1698 link_op.supported_caps |= SUPPORTED_40000baseLR4_Full; 1699 } 1700 1701 link_op.advertised_caps = link_op.supported_caps; 1702 1703 if(link.link_up) { 1704 link_op.speed = link.speed; 1705 } else { 1706 link_op.speed = 0; 1707 } 1708 1709 link_op.duplex = DUPLEX_FULL; 1710 link_op.port = PORT_FIBRE; 1711 1712 link_op.autoneg = params.speed.autoneg; 1713 1714 /* Link partner capabilities */ 1715 if (link.partner_adv_speed & 1716 ECORE_LINK_PARTNER_SPEED_1G_HD) { 1717 link_op.lp_caps |= SUPPORTED_1000baseT_Half; 1718 } 1719 1720 if (link.partner_adv_speed & 1721 ECORE_LINK_PARTNER_SPEED_1G_FD) { 1722 link_op.lp_caps |= SUPPORTED_1000baseT_Full; 1723 } 1724 1725 if (link.partner_adv_speed & 1726 ECORE_LINK_PARTNER_SPEED_10G) { 1727 link_op.lp_caps |= SUPPORTED_10000baseKR_Full; 1728 } 1729 1730 if (link.partner_adv_speed & 1731 ECORE_LINK_PARTNER_SPEED_20G) { 1732 link_op.lp_caps |= SUPPORTED_20000baseKR2_Full; 1733 } 1734 1735 if (link.partner_adv_speed & 1736 ECORE_LINK_PARTNER_SPEED_40G) { 1737 link_op.lp_caps |= SUPPORTED_40000baseLR4_Full; 1738 } 1739 1740 if (link.an_complete) { 1741 link_op.lp_caps |= SUPPORTED_Autoneg; 1742 } 1743 1744 if (link.partner_adv_pause) { 1745 link_op.lp_caps |= SUPPORTED_Pause; 1746 } 1747 1748 if (link.partner_adv_pause == ECORE_LINK_PARTNER_ASYMMETRIC_PAUSE || 1749 link.partner_adv_pause == ECORE_LINK_PARTNER_BOTH_PAUSE) { 1750 link_op.lp_caps |= SUPPORTED_Asym_Pause; 1751 } 1752 1753 func_info.supported = link_op.supported_caps; 1754 func_info.advertising = link_op.advertised_caps; 1755 func_info.speed = link_op.speed; 1756 func_info.duplex = link_op.duplex; 1757 func_info.port = qede->pci_func & 0x1; 1758 func_info.autoneg = link_op.autoneg; 1759 1760 (void) memcpy(data1->uabc, &func_info, sizeof(qede_func_info_t)); 1761 1762 return (0); 1763 } 1764 1765 static int 1766 qede_do_ioctl(qede_t *qede, queue_t *q, mblk_t *mp) 1767 { 1768 qede_ioctl_data_t *up_data; 1769 qede_driver_info_t driver_info; 1770 struct ecore_dev *edev = &qede->edev; 1771 struct ecore_hwfn *hwfn; 1772 struct ecore_ptt *ptt = NULL; 1773 struct mcp_file_att attrib; 1774 uint32_t flash_size; 1775 uint32_t mcp_resp, mcp_param, txn_size; 1776 uint32_t cmd, size, ret = 0; 1777 uint64_t off; 1778 int * up_data1; 1779 void * ptr; 1780 mblk_t *mp1 = mp; 1781 char mac_addr[32]; 1782 1783 up_data = (qede_ioctl_data_t *)(mp->b_cont->b_rptr); 1784 1785 cmd = up_data->cmd; 1786 off = up_data->off; 1787 size = up_data->size; 1788 1789 switch (cmd) { 1790 case QEDE_DRV_INFO: 1791 hwfn = &edev->hwfns[0]; 1792 ptt = ecore_ptt_acquire(hwfn); 1793 1794 snprintf(driver_info.drv_name, MAX_QEDE_NAME_LEN, "%s", "qede"); 1795 snprintf(driver_info.drv_version, QEDE_STR_SIZE, 1796 "v:%s", qede->version); 1797 snprintf(driver_info.mfw_version, QEDE_STR_SIZE, 1798 "%s", qede->versionMFW); 1799 snprintf(driver_info.stormfw_version, QEDE_STR_SIZE, 1800 "%s", qede->versionFW); 1801 snprintf(driver_info.bus_info, QEDE_STR_SIZE, 1802 "%s", qede->bus_dev_func); 1803 1804 1805 /* 1806 * calling ecore_mcp_nvm_rd_cmd to find the flash length, i 1807 * 0x08 is equivalent of NVM_TYPE_MFW_TRACE1 1808 */ 1809 ecore_mcp_get_flash_size(hwfn, ptt, &flash_size); 1810 driver_info.eeprom_dump_len = flash_size; 1811 (void) memcpy(up_data->uabc, &driver_info, 1812 sizeof (qede_driver_info_t)); 1813 up_data->size = sizeof (qede_driver_info_t); 1814 1815 ecore_ptt_release(hwfn, ptt); 1816 break; 1817 1818 case QEDE_RD_PCICFG: 1819 ret = qede_ioctl_pcicfg_rd(qede, off, up_data->uabc, size); 1820 break; 1821 1822 case QEDE_WR_PCICFG: 1823 ret = qede_ioctl_pcicfg_wr(qede, off, up_data, size); 1824 break; 1825 1826 case QEDE_RW_REG: 1827 ret = qede_ioctl_rd_wr_reg(qede, (void *)up_data); 1828 break; 1829 1830 case QEDE_RW_NVRAM: 1831 ret = qede_ioctl_rd_wr_nvram(qede, mp1); 1832 break; 1833 1834 case QEDE_FUNC_INFO: 1835 ret = qede_get_func_info(qede, (void *)up_data); 1836 break; 1837 1838 case QEDE_MAC_ADDR: 1839 snprintf(mac_addr, sizeof(mac_addr), 1840 "%02x:%02x:%02x:%02x:%02x:%02x", 1841 qede->ether_addr[0], qede->ether_addr[1], 1842 qede->ether_addr[2], qede->ether_addr[3], 1843 qede->ether_addr[4], qede->ether_addr[5]); 1844 (void) memcpy(up_data->uabc, &mac_addr, sizeof(mac_addr)); 1845 break; 1846 1847 } 1848 //if (cmd == QEDE_RW_NVRAM) { 1849 // miocack (q, mp, (sizeof(qede_ioctl_data_t)), 0); 1850 // return IOC_REPLY; 1851 //} 1852 miocack (q, mp, (sizeof(qede_ioctl_data_t)), ret); 1853 //miocack (q, mp, 0, ret); 1854 return (IOC_REPLY); 1855 } 1856 1857 static void 1858 qede_ioctl(qede_t *qede, int cmd, queue_t *q, mblk_t *mp) 1859 { 1860 void *ptr; 1861 1862 switch(cmd) { 1863 case QEDE_CMD: 1864 (void) qede_do_ioctl(qede, q, mp); 1865 break; 1866 default : 1867 cmn_err(CE_WARN, "qede ioctl command %x not supported\n", cmd); 1868 break; 1869 } 1870 return; 1871 } 1872 enum ioc_reply 1873 qede_loopback_ioctl(qede_t *qede, queue_t *wq, mblk_t *mp, 1874 struct iocblk *iocp) 1875 { 1876 lb_info_sz_t *lb_info_size; 1877 lb_property_t *lb_prop; 1878 uint32_t *lb_mode; 1879 int cmd; 1880 1881 /* 1882 * Validate format of ioctl 1883 */ 1884 if(mp->b_cont == NULL) { 1885 return IOC_INVAL; 1886 } 1887 1888 cmd = iocp->ioc_cmd; 1889 1890 switch(cmd) { 1891 default: 1892 qede_print("!%s(%d): unknown ioctl command %x\n", 1893 __func__, qede->instance, cmd); 1894 return IOC_INVAL; 1895 case LB_GET_INFO_SIZE: 1896 if (iocp->ioc_count != sizeof(lb_info_sz_t)) { 1897 qede_info(qede, "error: ioc_count %d, sizeof %d", 1898 iocp->ioc_count, sizeof(lb_info_sz_t)); 1899 return IOC_INVAL; 1900 } 1901 lb_info_size = (void *)mp->b_cont->b_rptr; 1902 *lb_info_size = sizeof(loopmodes); 1903 return IOC_REPLY; 1904 case LB_GET_INFO: 1905 if (iocp->ioc_count != sizeof (loopmodes)) { 1906 qede_info(qede, "error: iocp->ioc_count %d, sizepof %d", 1907 iocp->ioc_count, sizeof (loopmodes)); 1908 return (IOC_INVAL); 1909 } 1910 lb_prop = (void *)mp->b_cont->b_rptr; 1911 bcopy(loopmodes, lb_prop, sizeof (loopmodes)); 1912 return IOC_REPLY; 1913 case LB_GET_MODE: 1914 if (iocp->ioc_count != sizeof (uint32_t)) { 1915 qede_info(qede, "iocp->ioc_count %d, sizeof : %d\n", 1916 iocp->ioc_count, sizeof (uint32_t)); 1917 return (IOC_INVAL); 1918 } 1919 lb_mode = (void *)mp->b_cont->b_rptr; 1920 *lb_mode = qede->loop_back_mode; 1921 return IOC_REPLY; 1922 case LB_SET_MODE: 1923 if (iocp->ioc_count != sizeof (uint32_t)) { 1924 qede_info(qede, "iocp->ioc_count %d, sizeof : %d\n", 1925 iocp->ioc_count, sizeof (uint32_t)); 1926 return (IOC_INVAL); 1927 } 1928 lb_mode = (void *)mp->b_cont->b_rptr; 1929 return (qede_set_loopback_mode(qede,*lb_mode)); 1930 } 1931 } 1932 1933 static void 1934 qede_mac_ioctl(void * arg, 1935 queue_t * wq, 1936 mblk_t * mp) 1937 { 1938 int err, cmd; 1939 qede_t * qede = (qede_t *)arg; 1940 struct iocblk *iocp = (struct iocblk *) (uintptr_t)mp->b_rptr; 1941 enum ioc_reply status = IOC_DONE; 1942 boolean_t need_privilege = B_TRUE; 1943 1944 iocp->ioc_error = 0; 1945 cmd = iocp->ioc_cmd; 1946 1947 mutex_enter(&qede->drv_lock); 1948 if ((qede->qede_state == QEDE_STATE_SUSPENDING) || 1949 (qede->qede_state == QEDE_STATE_SUSPENDED)) { 1950 mutex_exit(&qede->drv_lock); 1951 miocnak(wq, mp, 0, EINVAL); 1952 return; 1953 } 1954 1955 switch(cmd) { 1956 case QEDE_CMD: 1957 break; 1958 case LB_GET_INFO_SIZE: 1959 case LB_GET_INFO: 1960 case LB_GET_MODE: 1961 need_privilege = B_FALSE; 1962 case LB_SET_MODE: 1963 break; 1964 default: 1965 qede_print("!%s(%d) unknown ioctl command %x\n", 1966 __func__, qede->instance, cmd); 1967 miocnak(wq, mp, 0, EINVAL); 1968 mutex_exit(&qede->drv_lock); 1969 return; 1970 } 1971 1972 if(need_privilege) { 1973 err = secpolicy_net_config(iocp->ioc_cr, B_FALSE); 1974 if(err){ 1975 qede_info(qede, "secpolicy() failed"); 1976 miocnak(wq, mp, 0, err); 1977 mutex_exit(&qede->drv_lock); 1978 return; 1979 } 1980 } 1981 1982 switch (cmd) { 1983 default: 1984 qede_print("!%s(%d) : unknown ioctl command %x\n", 1985 __func__, qede->instance, cmd); 1986 status = IOC_INVAL; 1987 mutex_exit(&qede->drv_lock); 1988 return; 1989 case LB_GET_INFO_SIZE: 1990 case LB_GET_INFO: 1991 case LB_GET_MODE: 1992 case LB_SET_MODE: 1993 status = qede_loopback_ioctl(qede, wq, mp, iocp); 1994 break; 1995 case QEDE_CMD: 1996 qede_ioctl(qede, cmd, wq, mp); 1997 status = IOC_DONE; 1998 break; 1999 } 2000 2001 switch(status){ 2002 default: 2003 qede_print("!%s(%d) : invalid status from ioctl", 2004 __func__,qede->instance); 2005 break; 2006 case IOC_DONE: 2007 /* 2008 * OK, Reply already sent 2009 */ 2010 2011 break; 2012 case IOC_REPLY: 2013 mp->b_datap->db_type = iocp->ioc_error == 0 ? 2014 M_IOCACK : M_IOCNAK; 2015 qreply(wq, mp); 2016 break; 2017 case IOC_INVAL: 2018 mutex_exit(&qede->drv_lock); 2019 //miocack(wq, mp, 0, 0); 2020 miocnak(wq, mp, 0, iocp->ioc_error == 0 ? 2021 EINVAL : iocp->ioc_error); 2022 return; 2023 } 2024 mutex_exit(&qede->drv_lock); 2025 } 2026 2027 extern ddi_dma_attr_t qede_buf2k_dma_attr_txbuf; 2028 extern ddi_dma_attr_t qede_dma_attr_rxbuf; 2029 extern ddi_dma_attr_t qede_dma_attr_desc; 2030 2031 static boolean_t 2032 qede_mac_get_capability(void *arg, 2033 mac_capab_t capability, 2034 void * cap_data) 2035 { 2036 qede_t * qede = (qede_t *)arg; 2037 uint32_t *txflags = cap_data; 2038 boolean_t ret = B_FALSE; 2039 2040 switch (capability) { 2041 case MAC_CAPAB_HCKSUM: { 2042 u32 *tx_flags = cap_data; 2043 /* 2044 * Check if checksum is enabled on 2045 * tx and advertise the cksum capab 2046 * to mac layer accordingly. On Rx 2047 * side checksummed packets are 2048 * reveiced anyway 2049 */ 2050 qede_info(qede, "%s tx checksum offload", 2051 (qede->checksum == DEFAULT_CKSUM_OFFLOAD) ? 2052 "Enabling": 2053 "Disabling"); 2054 2055 if (qede->checksum != DEFAULT_CKSUM_OFFLOAD) { 2056 ret = B_FALSE; 2057 break; 2058 } 2059 /* 2060 * Hardware does not support ICMPv6 checksumming. Right now the 2061 * GLDv3 doesn't provide us a way to specify that we don't 2062 * support that. As such, we cannot indicate 2063 * HCKSUM_INET_FULL_V6. 2064 */ 2065 2066 *tx_flags = HCKSUM_INET_FULL_V4 | 2067 HCKSUM_IPHDRCKSUM; 2068 ret = B_TRUE; 2069 break; 2070 } 2071 case MAC_CAPAB_LSO: { 2072 mac_capab_lso_t *cap_lso = (mac_capab_lso_t *)cap_data; 2073 2074 qede_info(qede, "%s large segmentation offload", 2075 qede->lso_enable ? "Enabling": "Disabling"); 2076 if (qede->lso_enable) { 2077 cap_lso->lso_flags = LSO_TX_BASIC_TCP_IPV4; 2078 cap_lso->lso_basic_tcp_ipv4.lso_max = QEDE_LSO_MAXLEN; 2079 ret = B_TRUE; 2080 } 2081 break; 2082 } 2083 case MAC_CAPAB_RINGS: { 2084 #ifndef NO_CROSSBOW 2085 mac_capab_rings_t *cap_rings = cap_data; 2086 #ifndef ILLUMOS 2087 cap_rings->mr_version = MAC_RINGS_VERSION_1; 2088 #endif 2089 2090 switch (cap_rings->mr_type) { 2091 case MAC_RING_TYPE_RX: 2092 #ifndef ILLUMOS 2093 cap_rings->mr_flags = MAC_RINGS_VLAN_TRANSPARENT; 2094 #endif 2095 cap_rings->mr_group_type = MAC_GROUP_TYPE_STATIC; 2096 //cap_rings->mr_rnum = 1; /* qede variable */ 2097 cap_rings->mr_rnum = qede->num_fp; /* qede variable */ 2098 cap_rings->mr_gnum = 1; 2099 cap_rings->mr_rget = qede_fill_ring; 2100 cap_rings->mr_gget = qede_fill_group; 2101 cap_rings->mr_gaddring = NULL; 2102 cap_rings->mr_gremring = NULL; 2103 #ifndef ILLUMOS 2104 cap_rings->mr_ggetringtc = NULL; 2105 #endif 2106 ret = B_TRUE; 2107 break; 2108 case MAC_RING_TYPE_TX: 2109 #ifndef ILLUMOS 2110 cap_rings->mr_flags = MAC_RINGS_VLAN_TRANSPARENT; 2111 #endif 2112 cap_rings->mr_group_type = MAC_GROUP_TYPE_STATIC; 2113 //cap_rings->mr_rnum = 1; 2114 cap_rings->mr_rnum = qede->num_fp; 2115 cap_rings->mr_gnum = 0; 2116 cap_rings->mr_rget = qede_fill_ring; 2117 cap_rings->mr_gget = qede_fill_group; 2118 cap_rings->mr_gaddring = NULL; 2119 cap_rings->mr_gremring = NULL; 2120 #ifndef ILLUMOS 2121 cap_rings->mr_ggetringtc = NULL; 2122 #endif 2123 ret = B_TRUE; 2124 break; 2125 default: 2126 ret = B_FALSE; 2127 break; 2128 } 2129 #endif 2130 break; /* CASE MAC_CAPAB_RINGS */ 2131 } 2132 #ifdef ILLUMOS 2133 case MAC_CAPAB_TRANSCEIVER: { 2134 mac_capab_transceiver_t *mct = cap_data; 2135 2136 mct->mct_flags = 0; 2137 mct->mct_ntransceivers = qede->edev.num_hwfns; 2138 mct->mct_info = qede_transceiver_info; 2139 mct->mct_read = qede_transceiver_read; 2140 2141 ret = B_TRUE; 2142 break; 2143 } 2144 #endif 2145 default: 2146 break; 2147 } 2148 2149 return (ret); 2150 } 2151 2152 int 2153 qede_configure_link(qede_t *qede, bool op); 2154 2155 static int 2156 qede_mac_set_property(void * arg, 2157 const char * pr_name, 2158 mac_prop_id_t pr_num, 2159 uint_t pr_valsize, 2160 const void * pr_val) 2161 { 2162 qede_t * qede = (qede_t *)arg; 2163 struct ecore_mcp_link_params *link_params; 2164 struct ecore_dev *edev = &qede->edev; 2165 struct ecore_hwfn *hwfn; 2166 int ret_val = 0, i; 2167 uint32_t option; 2168 2169 mutex_enter(&qede->gld_lock); 2170 switch (pr_num) 2171 { 2172 case MAC_PROP_MTU: 2173 bcopy(pr_val, &option, sizeof (option)); 2174 2175 if(option == qede->mtu) { 2176 ret_val = 0; 2177 break; 2178 } 2179 if ((option != DEFAULT_JUMBO_MTU) && 2180 (option != DEFAULT_MTU)) { 2181 ret_val = EINVAL; 2182 break; 2183 } 2184 if(qede->qede_state == QEDE_STATE_STARTED) { 2185 ret_val = EBUSY; 2186 break; 2187 } 2188 2189 ret_val = mac_maxsdu_update(qede->mac_handle, qede->mtu); 2190 if (ret_val == 0) { 2191 2192 qede->mtu = option; 2193 if (option == DEFAULT_JUMBO_MTU) { 2194 qede->jumbo_enable = B_TRUE; 2195 } else { 2196 qede->jumbo_enable = B_FALSE; 2197 } 2198 2199 hwfn = ECORE_LEADING_HWFN(edev); 2200 hwfn->hw_info.mtu = qede->mtu; 2201 ret_val = ecore_mcp_ov_update_mtu(hwfn, 2202 hwfn->p_main_ptt, 2203 hwfn->hw_info.mtu); 2204 if (ret_val != ECORE_SUCCESS) { 2205 qede_print("!%s(%d): MTU change %d option %d" 2206 "FAILED", 2207 __func__,qede->instance, qede->mtu, option); 2208 break; 2209 } 2210 qede_print("!%s(%d): MTU changed %d MTU option" 2211 " %d hwfn %d", 2212 __func__,qede->instance, qede->mtu, 2213 option, hwfn->hw_info.mtu); 2214 } 2215 break; 2216 2217 case MAC_PROP_EN_10GFDX_CAP: 2218 hwfn = &edev->hwfns[0]; 2219 link_params = ecore_mcp_get_link_params(hwfn); 2220 if (*(uint8_t *) pr_val) { 2221 link_params->speed.autoneg = 0; 2222 link_params->speed.forced_speed = 10000; 2223 link_params->speed.advertised_speeds = 2224 NVM_CFG1_PORT_DRV_SPEED_CAPABILITY_MASK_10G; 2225 qede->forced_speed_10G = *(uint8_t *)pr_val; 2226 } 2227 else { 2228 memcpy(link_params, 2229 &qede->link_input_params.default_link_params, 2230 sizeof (struct ecore_mcp_link_params)); 2231 qede->forced_speed_10G = *(uint8_t *)pr_val; 2232 } 2233 if (qede->qede_state == QEDE_STATE_STARTED) { 2234 qede_configure_link(qede, true); 2235 } else { 2236 mutex_exit(&qede->gld_lock); 2237 return (0); 2238 } 2239 break; 2240 default: 2241 ret_val = ENOTSUP; 2242 break; 2243 } 2244 mutex_exit(&qede->gld_lock); 2245 return (ret_val); 2246 } 2247 2248 static void 2249 qede_mac_stop(void *arg) 2250 { 2251 qede_t *qede = (qede_t *)arg; 2252 int status; 2253 2254 qede_print("!%s(%d): called", 2255 __func__,qede->instance); 2256 mutex_enter(&qede->drv_lock); 2257 status = qede_stop(qede); 2258 if (status != DDI_SUCCESS) { 2259 qede_print("!%s(%d): qede_stop " 2260 "FAILED", 2261 __func__,qede->instance); 2262 } 2263 2264 mac_link_update(qede->mac_handle, LINK_STATE_UNKNOWN); 2265 mutex_exit(&qede->drv_lock); 2266 } 2267 2268 static int 2269 qede_mac_start(void *arg) 2270 { 2271 qede_t *qede = (qede_t *)arg; 2272 int status; 2273 2274 qede_print("!%s(%d): called", __func__,qede->instance); 2275 if (!mutex_tryenter(&qede->drv_lock)) { 2276 return (EAGAIN); 2277 } 2278 2279 if (qede->qede_state == QEDE_STATE_SUSPENDED) { 2280 mutex_exit(&qede->drv_lock); 2281 return (ECANCELED); 2282 } 2283 2284 status = qede_start(qede); 2285 if (status != DDI_SUCCESS) { 2286 mutex_exit(&qede->drv_lock); 2287 return (EIO); 2288 } 2289 2290 mutex_exit(&qede->drv_lock); 2291 2292 #ifdef DBLK_DMA_PREMAP 2293 qede->pm_handle = mac_pmh_tx_get(qede->mac_handle); 2294 #endif 2295 return (0); 2296 } 2297 2298 static int 2299 qede_mac_get_property(void *arg, 2300 const char *pr_name, 2301 mac_prop_id_t pr_num, 2302 uint_t pr_valsize, 2303 void *pr_val) 2304 { 2305 qede_t *qede = (qede_t *)arg; 2306 struct ecore_dev *edev = &qede->edev; 2307 link_state_t link_state; 2308 link_duplex_t link_duplex; 2309 uint64_t link_speed; 2310 link_flowctrl_t link_flowctrl; 2311 struct qede_link_cfg link_cfg; 2312 mac_ether_media_t media; 2313 qede_link_cfg_t *hw_cfg = &qede->hwinit; 2314 int ret_val = 0; 2315 2316 memset(&link_cfg, 0, sizeof (struct qede_link_cfg)); 2317 qede_get_link_info(&edev->hwfns[0], &link_cfg); 2318 2319 2320 2321 switch (pr_num) 2322 { 2323 case MAC_PROP_MTU: 2324 2325 ASSERT(pr_valsize >= sizeof(uint32_t)); 2326 bcopy(&qede->mtu, pr_val, sizeof(uint32_t)); 2327 break; 2328 2329 case MAC_PROP_DUPLEX: 2330 2331 ASSERT(pr_valsize >= sizeof(link_duplex_t)); 2332 link_duplex = (qede->props.link_duplex) ? 2333 LINK_DUPLEX_FULL : LINK_DUPLEX_HALF; 2334 bcopy(&link_duplex, pr_val, sizeof(link_duplex_t)); 2335 break; 2336 2337 case MAC_PROP_SPEED: 2338 2339 ASSERT(pr_valsize >= sizeof(link_speed)); 2340 2341 link_speed = (qede->props.link_speed * 1000000ULL); 2342 bcopy(&link_speed, pr_val, sizeof(link_speed)); 2343 break; 2344 2345 case MAC_PROP_STATUS: 2346 2347 ASSERT(pr_valsize >= sizeof(link_state_t)); 2348 2349 link_state = (qede->params.link_state) ? 2350 LINK_STATE_UP : LINK_STATE_DOWN; 2351 bcopy(&link_state, pr_val, sizeof(link_state_t)); 2352 qede_info(qede, "mac_prop_status %d\n", link_state); 2353 break; 2354 2355 case MAC_PROP_MEDIA: 2356 2357 ASSERT(pr_valsize >= sizeof(mac_ether_media_t)); 2358 media = qede_link_to_media(&link_cfg, qede->props.link_speed); 2359 bcopy(&media, pr_val, sizeof(mac_ether_media_t)); 2360 break; 2361 2362 case MAC_PROP_AUTONEG: 2363 2364 *(uint8_t *)pr_val = link_cfg.autoneg; 2365 break; 2366 2367 case MAC_PROP_FLOWCTRL: 2368 2369 ASSERT(pr_valsize >= sizeof(link_flowctrl_t)); 2370 2371 /* 2372 * illumos does not have the notion of LINK_FLOWCTRL_AUTO at this time. 2373 */ 2374 #ifndef ILLUMOS 2375 if (link_cfg.pause_cfg & QEDE_LINK_PAUSE_AUTONEG_ENABLE) { 2376 link_flowctrl = LINK_FLOWCTRL_AUTO; 2377 } 2378 #endif 2379 2380 if (!(link_cfg.pause_cfg & QEDE_LINK_PAUSE_RX_ENABLE) && 2381 !(link_cfg.pause_cfg & QEDE_LINK_PAUSE_TX_ENABLE)) { 2382 link_flowctrl = LINK_FLOWCTRL_NONE; 2383 } 2384 if ((link_cfg.pause_cfg & QEDE_LINK_PAUSE_RX_ENABLE) && 2385 !(link_cfg.pause_cfg & QEDE_LINK_PAUSE_TX_ENABLE)) { 2386 link_flowctrl = LINK_FLOWCTRL_RX; 2387 } 2388 if (!(link_cfg.pause_cfg & QEDE_LINK_PAUSE_RX_ENABLE) && 2389 (link_cfg.pause_cfg & QEDE_LINK_PAUSE_TX_ENABLE)) { 2390 link_flowctrl = LINK_FLOWCTRL_TX; 2391 } 2392 if ((link_cfg.pause_cfg & QEDE_LINK_PAUSE_RX_ENABLE) && 2393 (link_cfg.pause_cfg & QEDE_LINK_PAUSE_TX_ENABLE)) { 2394 link_flowctrl = LINK_FLOWCTRL_BI; 2395 } 2396 2397 bcopy(&link_flowctrl, pr_val, sizeof (link_flowctrl_t)); 2398 break; 2399 2400 case MAC_PROP_ADV_10GFDX_CAP: 2401 *(uint8_t *)pr_val = link_cfg.adv_capab.param_10000fdx; 2402 break; 2403 2404 case MAC_PROP_EN_10GFDX_CAP: 2405 *(uint8_t *)pr_val = qede->forced_speed_10G; 2406 break; 2407 2408 case MAC_PROP_PRIVATE: 2409 default: 2410 return (ENOTSUP); 2411 2412 } 2413 2414 return (0); 2415 } 2416 2417 static void 2418 qede_mac_property_info(void *arg, 2419 const char *pr_name, 2420 mac_prop_id_t pr_num, 2421 mac_prop_info_handle_t prh) 2422 { 2423 qede_t *qede = (qede_t *)arg; 2424 qede_link_props_t *def_cfg = &qede_def_link_props; 2425 link_flowctrl_t link_flowctrl; 2426 2427 2428 switch (pr_num) 2429 { 2430 2431 case MAC_PROP_STATUS: 2432 case MAC_PROP_SPEED: 2433 case MAC_PROP_DUPLEX: 2434 mac_prop_info_set_perm(prh, MAC_PROP_PERM_READ); 2435 break; 2436 2437 case MAC_PROP_MTU: 2438 2439 mac_prop_info_set_range_uint32(prh, 2440 MIN_MTU, 2441 MAX_MTU); 2442 break; 2443 2444 case MAC_PROP_AUTONEG: 2445 2446 mac_prop_info_set_default_uint8(prh, def_cfg->autoneg); 2447 break; 2448 2449 case MAC_PROP_FLOWCTRL: 2450 2451 if (!def_cfg->pause) { 2452 link_flowctrl = LINK_FLOWCTRL_NONE; 2453 } else { 2454 link_flowctrl = LINK_FLOWCTRL_BI; 2455 } 2456 2457 mac_prop_info_set_default_link_flowctrl(prh, link_flowctrl); 2458 break; 2459 2460 case MAC_PROP_EN_10GFDX_CAP: 2461 mac_prop_info_set_perm(prh, MAC_PROP_PERM_RW); 2462 break; 2463 2464 case MAC_PROP_ADV_10GFDX_CAP: 2465 mac_prop_info_set_perm(prh, MAC_PROP_PERM_READ); 2466 break; 2467 2468 default: 2469 mac_prop_info_set_perm(prh, MAC_PROP_PERM_READ); 2470 break; 2471 2472 } 2473 } 2474 2475 static mac_callbacks_t qede_callbacks = 2476 { 2477 ( 2478 MC_IOCTL 2479 /* | MC_RESOURCES */ 2480 | MC_SETPROP 2481 | MC_GETPROP 2482 | MC_PROPINFO 2483 | MC_GETCAPAB 2484 ), 2485 qede_mac_stats, 2486 qede_mac_start, 2487 qede_mac_stop, 2488 qede_mac_promiscuous, 2489 qede_mac_multicast, 2490 NULL, 2491 #ifndef NO_CROSSBOW 2492 NULL, 2493 #else 2494 qede_mac_tx, 2495 #endif 2496 NULL, /* qede_mac_resources, */ 2497 qede_mac_ioctl, 2498 qede_mac_get_capability, 2499 NULL, 2500 NULL, 2501 qede_mac_set_property, 2502 qede_mac_get_property, 2503 #ifdef MC_PROPINFO 2504 qede_mac_property_info 2505 #endif 2506 }; 2507 2508 boolean_t 2509 qede_gld_init(qede_t *qede) 2510 { 2511 int status, ret; 2512 mac_register_t *macp; 2513 2514 macp = mac_alloc(MAC_VERSION); 2515 if (macp == NULL) { 2516 cmn_err(CE_NOTE, "%s: mac_alloc() failed\n", __func__); 2517 return (B_FALSE); 2518 } 2519 2520 macp->m_driver = qede; 2521 macp->m_dip = qede->dip; 2522 macp->m_instance = qede->instance; 2523 macp->m_priv_props = NULL; 2524 macp->m_type_ident = MAC_PLUGIN_IDENT_ETHER; 2525 macp->m_src_addr = qede->ether_addr; 2526 macp->m_callbacks = &qede_callbacks; 2527 macp->m_min_sdu = 0; 2528 macp->m_max_sdu = qede->mtu; 2529 macp->m_margin = VLAN_TAGSZ; 2530 #ifdef ILLUMOS 2531 macp->m_v12n = MAC_VIRT_LEVEL1; 2532 #endif 2533 2534 status = mac_register(macp, &qede->mac_handle); 2535 if (status != 0) { 2536 cmn_err(CE_NOTE, "%s: mac_register() failed\n", __func__); 2537 } 2538 2539 mac_free(macp); 2540 if (status == 0) { 2541 return (B_TRUE); 2542 } 2543 return (B_FALSE); 2544 } 2545 2546 boolean_t qede_gld_fini(qede_t * qede) 2547 { 2548 return (B_TRUE); 2549 } 2550 2551 2552 void qede_link_update(qede_t * qede, 2553 link_state_t state) 2554 { 2555 mac_link_update(qede->mac_handle, state); 2556 } 2557 2558