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