36 37#include "qlnx_os.h" 38#include "bcm_osal.h" 39 40#include "reg_addr.h" 41#include "ecore_gtt_reg_addr.h" 42#include "ecore.h" 43#include "ecore_chain.h" 44#include "ecore_status.h" 45#include "ecore_hw.h" 46#include "ecore_rt_defs.h" 47#include "ecore_init_ops.h" 48#include "ecore_int.h" 49#include "ecore_cxt.h" 50#include "ecore_spq.h" 51#include "ecore_init_fw_funcs.h" 52#include "ecore_sp_commands.h" 53#include "ecore_dev_api.h" 54#include "ecore_l2_api.h" 55#include "ecore_mcp.h" 56#include "ecore_hw_defs.h" 57#include "mcp_public.h" 58#include "ecore_iro.h" 59#include "nvm_cfg.h" 60#include "ecore_dev_api.h" 61#include "ecore_dbg_fw_funcs.h" 62 63#include "qlnx_ioctl.h" 64#include "qlnx_def.h" 65#include "qlnx_ver.h" 66#include <sys/smp.h> 67 68 69static int qlnx_eioctl(struct cdev *dev, u_long cmd, caddr_t data, int fflag, 70 struct thread *td); 71 72static struct cdevsw qlnx_cdevsw = { 73 .d_version = D_VERSION, 74 .d_ioctl = qlnx_eioctl, 75 .d_name = "qlnxioctl", 76}; 77 78int 79qlnx_make_cdev(qlnx_host_t *ha) 80{ 81 ha->ioctl_dev = make_dev(&qlnx_cdevsw, 82 ha->ifp->if_dunit, 83 UID_ROOT, 84 GID_WHEEL, 85 0600, 86 "%s", 87 if_name(ha->ifp)); 88 89 if (ha->ioctl_dev == NULL) 90 return (-1); 91 92 ha->ioctl_dev->si_drv1 = ha; 93 94 return (0); 95} 96 97void 98qlnx_del_cdev(qlnx_host_t *ha) 99{ 100 if (ha->ioctl_dev != NULL) 101 destroy_dev(ha->ioctl_dev); 102 return; 103} 104 105int 106qlnx_grc_dump(qlnx_host_t *ha, uint32_t *num_dumped_dwords, int hwfn_index) 107{ 108 int rval = EINVAL; 109 struct ecore_hwfn *p_hwfn; 110 struct ecore_ptt *p_ptt; 111 112 if (ha->grcdump_dwords[hwfn_index]) { 113 /* the grcdump is already available */ 114 *num_dumped_dwords = ha->grcdump_dwords[hwfn_index]; 115 return (0); 116 } 117 118 ecore_dbg_set_app_ver(ecore_dbg_get_fw_func_ver()); 119 120 p_hwfn = &ha->cdev.hwfns[hwfn_index]; 121 p_ptt = ecore_ptt_acquire(p_hwfn); 122 123 if (!p_ptt) { 124 QL_DPRINT1(ha, (ha->pci_dev, "%s : ecore_ptt_acquire failed\n", 125 __func__)); 126 return (rval); 127 } 128 129 if ((rval = ecore_dbg_grc_dump(p_hwfn, p_ptt, 130 ha->grcdump[hwfn_index], 131 (ha->grcdump_size[hwfn_index] >> 2), 132 num_dumped_dwords)) == DBG_STATUS_OK) { 133 rval = 0; 134 ha->grcdump_taken = 1; 135 } else 136 QL_DPRINT1(ha, (ha->pci_dev, 137 "%s : ecore_dbg_grc_dump failed [%d, 0x%x]\n", 138 __func__, hwfn_index, rval)); 139 140 ecore_ptt_release(p_hwfn, p_ptt); 141 142 return (rval); 143} 144 145static void 146qlnx_get_grc_dump_size(qlnx_host_t *ha, qlnx_grcdump_t *grcdump) 147{ 148 int i; 149 150 grcdump->pci_func = ha->pci_func; 151 152 for (i = 0; i < ha->cdev.num_hwfns; i++) 153 grcdump->grcdump_size[i] = ha->grcdump_size[i]; 154 155 return; 156} 157 158static int 159qlnx_get_grc_dump(qlnx_host_t *ha, qlnx_grcdump_t *grcdump) 160{ 161 int i; 162 int rval = 0; 163 uint32_t dwords = 0; 164 165 grcdump->pci_func = ha->pci_func; 166 167 for (i = 0; i < ha->cdev.num_hwfns; i++) { 168 169 if ((ha->grcdump[i] == NULL) || (grcdump->grcdump[i] == NULL) || 170 (grcdump->grcdump_size[i] < ha->grcdump_size[i])) 171 return (EINVAL); 172 173 rval = qlnx_grc_dump(ha, &dwords, i); 174 175 if (rval) 176 break; 177 178 grcdump->grcdump_dwords[i] = dwords; 179 180 QL_DPRINT1(ha, (ha->pci_dev, "%s: grcdump_dwords[%d] = 0x%x\n", 181 __func__, i, dwords)); 182 183 rval = copyout(ha->grcdump[i], grcdump->grcdump[i], 184 ha->grcdump_size[i]); 185 186 if (rval) 187 break; 188 189 ha->grcdump_dwords[i] = 0; 190 } 191 192 ha->grcdump_taken = 0; 193 194 return (rval); 195} 196 197int 198qlnx_idle_chk(qlnx_host_t *ha, uint32_t *num_dumped_dwords, int hwfn_index) 199{ 200 int rval = EINVAL; 201 struct ecore_hwfn *p_hwfn; 202 struct ecore_ptt *p_ptt; 203 204 if (ha->idle_chk_dwords[hwfn_index]) { 205 /* the idle check is already available */ 206 *num_dumped_dwords = ha->idle_chk_dwords[hwfn_index]; 207 return (0); 208 } 209 210 ecore_dbg_set_app_ver(ecore_dbg_get_fw_func_ver()); 211 212 p_hwfn = &ha->cdev.hwfns[hwfn_index]; 213 p_ptt = ecore_ptt_acquire(p_hwfn); 214 215 if (!p_ptt) { 216 QL_DPRINT1(ha, (ha->pci_dev, 217 "%s : ecore_ptt_acquire failed\n", __func__)); 218 return (rval); 219 } 220 221 if ((rval = ecore_dbg_idle_chk_dump(p_hwfn, p_ptt, 222 ha->idle_chk[hwfn_index], 223 (ha->idle_chk_size[hwfn_index] >> 2), 224 num_dumped_dwords)) == DBG_STATUS_OK) { 225 rval = 0; 226 ha->idle_chk_taken = 1; 227 } else 228 QL_DPRINT1(ha, (ha->pci_dev, 229 "%s : ecore_dbg_idle_chk_dump failed [%d, 0x%x]\n", 230 __func__, hwfn_index, rval)); 231 232 ecore_ptt_release(p_hwfn, p_ptt); 233 234 return (rval); 235} 236 237static void 238qlnx_get_idle_chk_size(qlnx_host_t *ha, qlnx_idle_chk_t *idle_chk) 239{ 240 int i; 241 242 idle_chk->pci_func = ha->pci_func; 243 244 for (i = 0; i < ha->cdev.num_hwfns; i++) 245 idle_chk->idle_chk_size[i] = ha->idle_chk_size[i]; 246 247 return; 248} 249 250static int 251qlnx_get_idle_chk(qlnx_host_t *ha, qlnx_idle_chk_t *idle_chk) 252{ 253 int i; 254 int rval = 0; 255 uint32_t dwords = 0; 256 257 idle_chk->pci_func = ha->pci_func; 258 259 for (i = 0; i < ha->cdev.num_hwfns; i++) { 260 261 if ((ha->idle_chk[i] == NULL) || 262 (idle_chk->idle_chk[i] == NULL) || 263 (idle_chk->idle_chk_size[i] < 264 ha->idle_chk_size[i])) 265 return (EINVAL); 266 267 rval = qlnx_idle_chk(ha, &dwords, i); 268 269 if (rval) 270 break; 271 272 idle_chk->idle_chk_dwords[i] = dwords; 273 274 QL_DPRINT1(ha, (ha->pci_dev, "%s: idle_chk_dwords[%d] = 0x%x\n", 275 __func__, i, dwords)); 276 277 rval = copyout(ha->idle_chk[i], idle_chk->idle_chk[i], 278 ha->idle_chk_size[i]); 279 280 if (rval) 281 break; 282 283 ha->idle_chk_dwords[i] = 0; 284 } 285 ha->idle_chk_taken = 0; 286 287 return (rval); 288} 289 290static uint32_t 291qlnx_get_trace_cmd_size(qlnx_host_t *ha, int hwfn_index, uint16_t cmd) 292{ 293 int rval = -1; 294 struct ecore_hwfn *p_hwfn; 295 struct ecore_ptt *p_ptt; 296 uint32_t num_dwords = 0; 297 298 p_hwfn = &ha->cdev.hwfns[hwfn_index]; 299 p_ptt = ecore_ptt_acquire(p_hwfn); 300 301 if (!p_ptt) { 302 QL_DPRINT1(ha, (ha->pci_dev, 303 "%s: ecore_ptt_acquire [%d, 0x%x]failed\n", 304 __func__, hwfn_index, cmd)); 305 return (0); 306 } 307 308 switch (cmd) { 309 310 case QLNX_MCP_TRACE: 311 rval = ecore_dbg_mcp_trace_get_dump_buf_size(p_hwfn, 312 p_ptt, &num_dwords); 313 break; 314 315 case QLNX_REG_FIFO: 316 rval = ecore_dbg_reg_fifo_get_dump_buf_size(p_hwfn, 317 p_ptt, &num_dwords); 318 break; 319 320 case QLNX_IGU_FIFO: 321 rval = ecore_dbg_igu_fifo_get_dump_buf_size(p_hwfn, 322 p_ptt, &num_dwords); 323 break; 324 325 case QLNX_PROTECTION_OVERRIDE: 326 rval = ecore_dbg_protection_override_get_dump_buf_size(p_hwfn, 327 p_ptt, &num_dwords); 328 break; 329 330 case QLNX_FW_ASSERTS: 331 rval = ecore_dbg_fw_asserts_get_dump_buf_size(p_hwfn, 332 p_ptt, &num_dwords); 333 break; 334 } 335 336 if (rval != DBG_STATUS_OK) { 337 QL_DPRINT1(ha, (ha->pci_dev, "%s : cmd = 0x%x failed [0x%x]\n", 338 __func__, cmd, rval)); 339 num_dwords = 0; 340 } 341 342 ecore_ptt_release(p_hwfn, p_ptt); 343 344 return ((num_dwords * sizeof (uint32_t))); 345} 346 347static void 348qlnx_get_trace_size(qlnx_host_t *ha, qlnx_trace_t *trace) 349{ 350 int i; 351 352 trace->pci_func = ha->pci_func; 353 354 for (i = 0; i < ha->cdev.num_hwfns; i++) { 355 trace->size[i] = qlnx_get_trace_cmd_size(ha, i, trace->cmd); 356 } 357 358 return; 359} 360 361static int 362qlnx_get_trace(qlnx_host_t *ha, int hwfn_index, qlnx_trace_t *trace) 363{ 364 int rval = -1; 365 struct ecore_hwfn *p_hwfn; 366 struct ecore_ptt *p_ptt; 367 uint32_t num_dwords = 0; 368 void *buffer; 369 370 buffer = qlnx_zalloc(trace->size[hwfn_index]); 371 if (buffer == NULL) { 372 QL_DPRINT1(ha, (ha->pci_dev, 373 "%s: qlnx_zalloc [%d, 0x%x]failed\n", 374 __func__, hwfn_index, trace->cmd)); 375 return (ENXIO); 376 } 377 ecore_dbg_set_app_ver(ecore_dbg_get_fw_func_ver()); 378 379 p_hwfn = &ha->cdev.hwfns[hwfn_index]; 380 p_ptt = ecore_ptt_acquire(p_hwfn); 381 382 if (!p_ptt) { 383 QL_DPRINT1(ha, (ha->pci_dev, 384 "%s: ecore_ptt_acquire [%d, 0x%x]failed\n", 385 __func__, hwfn_index, trace->cmd)); 386 return (ENXIO); 387 } 388 389 switch (trace->cmd) { 390 391 case QLNX_MCP_TRACE: 392 rval = ecore_dbg_mcp_trace_dump(p_hwfn, p_ptt, 393 buffer, (trace->size[hwfn_index] >> 2), 394 &num_dwords); 395 break; 396 397 case QLNX_REG_FIFO: 398 rval = ecore_dbg_reg_fifo_dump(p_hwfn, p_ptt, 399 buffer, (trace->size[hwfn_index] >> 2), 400 &num_dwords); 401 break; 402 403 case QLNX_IGU_FIFO: 404 rval = ecore_dbg_igu_fifo_dump(p_hwfn, p_ptt, 405 buffer, (trace->size[hwfn_index] >> 2), 406 &num_dwords); 407 break; 408 409 case QLNX_PROTECTION_OVERRIDE: 410 rval = ecore_dbg_protection_override_dump(p_hwfn, p_ptt, 411 buffer, (trace->size[hwfn_index] >> 2), 412 &num_dwords); 413 break; 414 415 case QLNX_FW_ASSERTS: 416 rval = ecore_dbg_fw_asserts_dump(p_hwfn, p_ptt, 417 buffer, (trace->size[hwfn_index] >> 2), 418 &num_dwords); 419 break; 420 } 421 422 if (rval != DBG_STATUS_OK) { 423 QL_DPRINT1(ha, (ha->pci_dev, "%s : cmd = 0x%x failed [0x%x]\n", 424 __func__, trace->cmd, rval)); 425 num_dwords = 0; 426 } 427 428 ecore_ptt_release(p_hwfn, p_ptt); 429 430 trace->dwords[hwfn_index] = num_dwords; 431 432 if (num_dwords) { 433 rval = copyout(buffer, trace->buffer[hwfn_index], 434 (num_dwords << 2)); 435 } 436 437 return (rval); 438} 439 440static int 441qlnx_reg_rd_wr(qlnx_host_t *ha, qlnx_reg_rd_wr_t *reg_rd_wr) 442{ 443 int rval = 0; 444 struct ecore_hwfn *p_hwfn; 445 446 if (reg_rd_wr->hwfn_index >= QLNX_MAX_HW_FUNCS) { 447 return (EINVAL); 448 } 449 450 p_hwfn = &ha->cdev.hwfns[reg_rd_wr->hwfn_index]; 451 452 switch (reg_rd_wr->cmd) { 453 454 case QLNX_REG_READ_CMD: 455 if (reg_rd_wr->access_type == QLNX_REG_ACCESS_DIRECT) { 456 reg_rd_wr->val = qlnx_reg_rd32(p_hwfn, 457 reg_rd_wr->addr); 458 } 459 break; 460 461 case QLNX_REG_WRITE_CMD: 462 if (reg_rd_wr->access_type == QLNX_REG_ACCESS_DIRECT) { 463 qlnx_reg_wr32(p_hwfn, reg_rd_wr->addr, 464 reg_rd_wr->val); 465 } 466 break; 467 468 default: 469 rval = EINVAL; 470 break; 471 } 472 473 return (rval); 474} 475 476static int 477qlnx_rd_wr_pci_config(qlnx_host_t *ha, qlnx_pcicfg_rd_wr_t *pci_cfg_rd_wr) 478{ 479 int rval = 0; 480 481 switch (pci_cfg_rd_wr->cmd) { 482 483 case QLNX_PCICFG_READ: 484 pci_cfg_rd_wr->val = pci_read_config(ha->pci_dev, 485 pci_cfg_rd_wr->reg, 486 pci_cfg_rd_wr->width); 487 break; 488 489 case QLNX_PCICFG_WRITE: 490 pci_write_config(ha->pci_dev, pci_cfg_rd_wr->reg, 491 pci_cfg_rd_wr->val, pci_cfg_rd_wr->width); 492 break; 493 494 default: 495 rval = EINVAL; 496 break; 497 } 498 499 return (rval); 500} 501 502static void 503qlnx_mac_addr(qlnx_host_t *ha, qlnx_perm_mac_addr_t *mac_addr) 504{ 505 bzero(mac_addr->addr, sizeof(mac_addr->addr)); 506 snprintf(mac_addr->addr, sizeof(mac_addr->addr), 507 "%02x:%02x:%02x:%02x:%02x:%02x", 508 ha->primary_mac[0], ha->primary_mac[1], ha->primary_mac[2], 509 ha->primary_mac[3], ha->primary_mac[4], ha->primary_mac[5]); 510 511 return; 512} 513 514static int 515qlnx_get_regs(qlnx_host_t *ha, qlnx_get_regs_t *regs) 516{ 517 int i; 518 int rval = 0; 519 uint32_t dwords = 0; 520 uint8_t *outb; 521 522 regs->reg_buf_len = 0; 523 outb = regs->reg_buf; 524 525 for (i = 0; i < ha->cdev.num_hwfns; i++) { 526 527 rval = qlnx_grc_dump(ha, &dwords, i); 528 529 if (rval) 530 break; 531 532 regs->reg_buf_len += (dwords << 2); 533 534 rval = copyout(ha->grcdump[i], outb, ha->grcdump_size[i]); 535 536 if (rval) 537 break; 538 539 ha->grcdump_dwords[i] = 0; 540 outb += regs->reg_buf_len; 541 } 542 543 ha->grcdump_taken = 0; 544 545 return (rval); 546} 547 548static int 549qlnx_drv_info(qlnx_host_t *ha, qlnx_drvinfo_t *drv_info) 550{ 551 int i; 552 extern char qlnx_name_str[]; 553 extern char qlnx_ver_str[]; 554 555 bzero(drv_info, sizeof(qlnx_drvinfo_t)); 556 557 snprintf(drv_info->drv_name, sizeof(drv_info->drv_name), "%s", 558 qlnx_name_str); 559 snprintf(drv_info->drv_version, sizeof(drv_info->drv_version), "%s", 560 qlnx_ver_str); 561 snprintf(drv_info->mfw_version, sizeof(drv_info->mfw_version), "%s", 562 ha->mfw_ver); 563 snprintf(drv_info->stormfw_version, sizeof(drv_info->stormfw_version), 564 "%s", ha->stormfw_ver); 565 566 drv_info->eeprom_dump_len = ha->flash_size; 567 568 for (i = 0; i < ha->cdev.num_hwfns; i++) { 569 drv_info->reg_dump_len += ha->grcdump_size[i]; 570 } 571 572 snprintf(drv_info->bus_info, sizeof(drv_info->bus_info), 573 "%d:%d:%d", pci_get_bus(ha->pci_dev), 574 pci_get_slot(ha->pci_dev), ha->pci_func); 575 576 return (0); 577} 578 579static int 580qlnx_dev_settings(qlnx_host_t *ha, qlnx_dev_setting_t *dev_info) 581{ 582 struct ecore_hwfn *p_hwfn; 583 struct qlnx_link_output if_link; 584 585 p_hwfn = &ha->cdev.hwfns[0]; 586 587 qlnx_fill_link(p_hwfn, &if_link); 588 589 dev_info->supported = if_link.supported_caps; 590 dev_info->advertising = if_link.advertised_caps; 591 dev_info->speed = if_link.speed; 592 dev_info->duplex = if_link.duplex; 593 dev_info->port = ha->pci_func & 0x1; 594 dev_info->autoneg = if_link.autoneg; 595 596 return (0); 597} 598 599static int 600qlnx_write_nvram(qlnx_host_t *ha, qlnx_nvram_t *nvram, uint32_t cmd) 601{ 602 uint8_t *buf; 603 int ret = 0; 604 605 if ((nvram->data == NULL) || (nvram->data_len == 0)) 606 return (EINVAL); 607 608 buf = qlnx_zalloc(nvram->data_len); 609 610 ret = copyin(nvram->data, buf, nvram->data_len); 611 612 QL_DPRINT9(ha, 613 (ha->pci_dev, "%s: issue cmd = 0x%x data = %p " 614 " data_len = 0x%x ret = 0x%x exit\n", __func__, 615 cmd, nvram->data, nvram->data_len, ret)); 616 617 if (ret == 0) { 618 ret = ecore_mcp_nvm_write(&ha->cdev, cmd, 619 nvram->offset, buf, nvram->data_len); 620 } 621 622 QL_DPRINT9(ha, 623 (ha->pci_dev, "%s: cmd = 0x%x data = %p " 624 " data_len = 0x%x resp = 0x%x ret = 0x%x exit\n", 625 __func__, cmd, nvram->data, nvram->data_len, 626 ha->cdev.mcp_nvm_resp, ret)); 627 628 free(buf, M_QLNXBUF); 629 630 return (ret); 631} 632 633static int 634qlnx_read_nvram(qlnx_host_t *ha, qlnx_nvram_t *nvram) 635{ 636 uint8_t *buf; 637 int ret = 0; 638 639 if ((nvram->data == NULL) || (nvram->data_len == 0)) 640 return (EINVAL); 641 642 buf = qlnx_zalloc(nvram->data_len); 643 644 ret = ecore_mcp_nvm_read(&ha->cdev, nvram->offset, buf, 645 nvram->data_len); 646 647 QL_DPRINT9(ha, (ha->pci_dev, "%s: data = %p data_len = 0x%x " 648 " resp = 0x%x ret = 0x%x exit\n", __func__, 649 nvram->data, nvram->data_len, 650 ha->cdev.mcp_nvm_resp, ret)); 651 652 if (ret == 0) { 653 ret = copyout(buf, nvram->data, nvram->data_len); 654 } 655 656 free(buf, M_QLNXBUF); 657 658 return (ret); 659} 660 661static int 662qlnx_get_nvram_resp(qlnx_host_t *ha, qlnx_nvram_t *nvram) 663{ 664 uint8_t *buf; 665 int ret = 0; 666 667 if ((nvram->data == NULL) || (nvram->data_len == 0)) 668 return (EINVAL); 669 670 buf = qlnx_zalloc(nvram->data_len); 671 672 673 ret = ecore_mcp_nvm_resp(&ha->cdev, buf); 674 675 QL_DPRINT9(ha, (ha->pci_dev, "%s: data = %p data_len = 0x%x " 676 " resp = 0x%x ret = 0x%x exit\n", __func__, 677 nvram->data, nvram->data_len, 678 ha->cdev.mcp_nvm_resp, ret)); 679 680 if (ret == 0) { 681 ret = copyout(buf, nvram->data, nvram->data_len); 682 } 683 684 free(buf, M_QLNXBUF); 685 686 return (ret); 687} 688 689static int 690qlnx_nvram(qlnx_host_t *ha, qlnx_nvram_t *nvram) 691{ 692 int ret = 0; 693 694 switch (nvram->cmd) { 695 696 case QLNX_NVRAM_CMD_WRITE_NVRAM: 697 ret = qlnx_write_nvram(ha, nvram, ECORE_NVM_WRITE_NVRAM); 698 break; 699 700 case QLNX_NVRAM_CMD_PUT_FILE_DATA: 701 ret = qlnx_write_nvram(ha, nvram, ECORE_PUT_FILE_DATA); 702 break; 703 704 case QLNX_NVRAM_CMD_READ_NVRAM: 705 ret = qlnx_read_nvram(ha, nvram); 706 break; 707 708 case QLNX_NVRAM_CMD_SET_SECURE_MODE: 709 ret = ecore_mcp_nvm_set_secure_mode(&ha->cdev, nvram->offset); 710 711 QL_DPRINT9(ha, (ha->pci_dev, 712 "%s: QLNX_NVRAM_CMD_SET_SECURE_MODE " 713 " resp = 0x%x ret = 0x%x exit\n", __func__, 714 ha->cdev.mcp_nvm_resp, ret)); 715 break; 716 717 case QLNX_NVRAM_CMD_DEL_FILE: 718 ret = ecore_mcp_nvm_del_file(&ha->cdev, nvram->offset); 719 720 QL_DPRINT9(ha, (ha->pci_dev, 721 "%s: QLNX_NVRAM_CMD_DEL_FILE " 722 " resp = 0x%x ret = 0x%x exit\n", __func__, 723 ha->cdev.mcp_nvm_resp, ret)); 724 break; 725 726 case QLNX_NVRAM_CMD_PUT_FILE_BEGIN: 727 ret = ecore_mcp_nvm_put_file_begin(&ha->cdev, nvram->offset); 728 729 QL_DPRINT9(ha, (ha->pci_dev, 730 "%s: QLNX_NVRAM_CMD_PUT_FILE_BEGIN " 731 " resp = 0x%x ret = 0x%x exit\n", __func__, 732 ha->cdev.mcp_nvm_resp, ret)); 733 break; 734 735 case QLNX_NVRAM_CMD_GET_NVRAM_RESP: 736 ret = qlnx_get_nvram_resp(ha, nvram); 737 break; 738 739 default: 740 ret = EINVAL; 741 break; 742 } 743 744 return (ret); 745} 746 747static void 748qlnx_storm_stats(qlnx_host_t *ha, qlnx_storm_stats_dump_t *s_stats) 749{ 750 int i; 751 int index; 752 int ret; 753 int stats_copied = 0; 754 755 s_stats->num_hwfns = ha->cdev.num_hwfns; 756 757// if (ha->storm_stats_index < QLNX_STORM_STATS_SAMPLES_PER_HWFN) 758// return; 759 760 s_stats->num_samples = ha->storm_stats_index; 761 762 for (i = 0; i < ha->cdev.num_hwfns; i++) { 763 764 index = (QLNX_STORM_STATS_SAMPLES_PER_HWFN * i); 765 766 if (s_stats->buffer[i]) { 767 768 ret = copyout(&ha->storm_stats[index], 769 s_stats->buffer[i], 770 QLNX_STORM_STATS_BYTES_PER_HWFN); 771 if (ret) { 772 printf("%s [%d]: failed\n", __func__, i); 773 } 774 775 if (s_stats->num_samples == 776 QLNX_STORM_STATS_SAMPLES_PER_HWFN) { 777 778 bzero((void *)&ha->storm_stats[i], 779 QLNX_STORM_STATS_BYTES_PER_HWFN); 780 781 stats_copied = 1; 782 } 783 } 784 } 785 786 if (stats_copied) 787 ha->storm_stats_index = 0; 788 789 return; 790} 791 792 793static int 794qlnx_eioctl(struct cdev *dev, u_long cmd, caddr_t data, int fflag, 795 struct thread *td) 796{ 797 qlnx_host_t *ha; 798 int rval = 0; 799 struct ifnet *ifp; 800 qlnx_trace_t *trace; 801 int i; 802 803 if ((ha = (qlnx_host_t *)dev->si_drv1) == NULL) 804 return ENXIO; 805 806 ifp = ha->ifp; 807 808 switch (cmd) { 809 810 case QLNX_GRC_DUMP_SIZE: 811 qlnx_get_grc_dump_size(ha, (qlnx_grcdump_t *)data); 812 break; 813 814 case QLNX_GRC_DUMP: 815 rval = qlnx_get_grc_dump(ha, (qlnx_grcdump_t *)data); 816 break; 817 818 case QLNX_IDLE_CHK_SIZE: 819 qlnx_get_idle_chk_size(ha, (qlnx_idle_chk_t *)data); 820 break; 821 822 case QLNX_IDLE_CHK: 823 rval = qlnx_get_idle_chk(ha, (qlnx_idle_chk_t *)data); 824 break; 825 826 case QLNX_DRV_INFO: 827 rval = qlnx_drv_info(ha, (qlnx_drvinfo_t *)data); 828 break; 829 830 case QLNX_DEV_SETTING: 831 rval = qlnx_dev_settings(ha, (qlnx_dev_setting_t *)data); 832 break; 833 834 case QLNX_GET_REGS: 835 rval = qlnx_get_regs(ha, (qlnx_get_regs_t *)data); 836 break; 837 838 case QLNX_NVRAM: 839 rval = qlnx_nvram(ha, (qlnx_nvram_t *)data); 840 break; 841 842 case QLNX_RD_WR_REG: 843 rval = qlnx_reg_rd_wr(ha, (qlnx_reg_rd_wr_t *)data); 844 break; 845 846 case QLNX_RD_WR_PCICFG: 847 rval = qlnx_rd_wr_pci_config(ha, (qlnx_pcicfg_rd_wr_t *)data); 848 break; 849 850 case QLNX_MAC_ADDR: 851 qlnx_mac_addr(ha, (qlnx_perm_mac_addr_t *)data); 852 break; 853 854 case QLNX_STORM_STATS: 855 qlnx_storm_stats(ha, (qlnx_storm_stats_dump_t *)data); 856 break; 857 858 case QLNX_TRACE_SIZE: 859 qlnx_get_trace_size(ha, (qlnx_trace_t *)data); 860 break; 861 862 case QLNX_TRACE: 863 trace = (qlnx_trace_t *)data; 864 865 for (i = 0; i < ha->cdev.num_hwfns; i++) { 866 867 if (trace->size[i] && trace->cmd && trace->buffer[i]) 868 rval = qlnx_get_trace(ha, i, trace); 869 870 if (rval) 871 break; 872 } 873 break; 874 875 default: 876 rval = EINVAL; 877 break; 878 } 879 880 return (rval); 881} 882
|