qla_misc.c (229423) | qla_misc.c (250340) |
---|---|
1/* | 1/* |
2 * Copyright (c) 2010-2011 Qlogic Corporation | 2 * Copyright (c) 2011-2013 Qlogic Corporation |
3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 9 * 1. Redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer. --- 14 unchanged lines hidden (view full) --- 25 * POSSIBILITY OF SUCH DAMAGE. 26 */ 27/* 28 * File : qla_misc.c 29 * Author : David C Somayajulu, Qlogic Corporation, Aliso Viejo, CA 92656. 30 */ 31 32#include <sys/cdefs.h> | 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 9 * 1. Redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer. --- 14 unchanged lines hidden (view full) --- 25 * POSSIBILITY OF SUCH DAMAGE. 26 */ 27/* 28 * File : qla_misc.c 29 * Author : David C Somayajulu, Qlogic Corporation, Aliso Viejo, CA 92656. 30 */ 31 32#include <sys/cdefs.h> |
33__FBSDID("$FreeBSD: head/sys/dev/qlxgb/qla_misc.c 229423 2012-01-03 20:51:26Z dim $"); | 33__FBSDID("$FreeBSD: head/sys/dev/qlxgb/qla_misc.c 250340 2013-05-07 22:58:42Z davidcs $"); |
34 35#include "qla_os.h" 36#include "qla_reg.h" 37#include "qla_hw.h" 38#include "qla_def.h" 39#include "qla_reg.h" 40#include "qla_inline.h" 41#include "qla_glbl.h" --- 297 unchanged lines hidden (view full) --- 339 QLA_USEC_DELAY(100); 340 341 qla_rdwr_indreg32(ha, Q8_ROM_RD_DATA, data, 1); 342 343 qla_sem_unlock(ha, Q8_SEM2_UNLOCK); 344 return 0; 345} 346 | 34 35#include "qla_os.h" 36#include "qla_reg.h" 37#include "qla_hw.h" 38#include "qla_def.h" 39#include "qla_reg.h" 40#include "qla_inline.h" 41#include "qla_glbl.h" --- 297 unchanged lines hidden (view full) --- 339 QLA_USEC_DELAY(100); 340 341 qla_rdwr_indreg32(ha, Q8_ROM_RD_DATA, data, 1); 342 343 qla_sem_unlock(ha, Q8_SEM2_UNLOCK); 344 return 0; 345} 346 |
347static int 348qla_p3p_sem_lock2(qla_host_t *ha) 349{ 350 if (qla_sem_lock(ha, Q8_SEM2_LOCK, 0, 0)) { 351 device_printf(ha->pci_dev, "%s: SEM2_LOCK failed\n", __func__); 352 return (-1); 353 } 354 WRITE_OFFSET32(ha, Q8_ROM_LOCKID, 0xa5a5a5a5); 355 return (0); 356} 357 |
|
347/* 348 * Name: qla_int_to_pci_addr_map 349 * Function: Convert's Internal(CRB) Address to Indirect Address 350 */ 351static uint32_t 352qla_int_to_pci_addr_map(qla_host_t *ha, uint32_t int_addr) 353{ 354 uint32_t crb_to_pci_table_size, i; --- 42 unchanged lines hidden (view full) --- 397 * Name: qla_crb_init 398 * Function: CRB Initialization - first step in the initialization after reset 399 * Essentially reads the address/value pairs from address = 0x00 and 400 * writes the value into address in the addr/value pair. 401 */ 402static int 403qla_crb_init(qla_host_t *ha) 404{ | 358/* 359 * Name: qla_int_to_pci_addr_map 360 * Function: Convert's Internal(CRB) Address to Indirect Address 361 */ 362static uint32_t 363qla_int_to_pci_addr_map(qla_host_t *ha, uint32_t int_addr) 364{ 365 uint32_t crb_to_pci_table_size, i; --- 42 unchanged lines hidden (view full) --- 408 * Name: qla_crb_init 409 * Function: CRB Initialization - first step in the initialization after reset 410 * Essentially reads the address/value pairs from address = 0x00 and 411 * writes the value into address in the addr/value pair. 412 */ 413static int 414qla_crb_init(qla_host_t *ha) 415{ |
405 uint32_t val, sig; | 416 uint32_t val = 0, sig = 0; |
406 uint32_t offset, count, i; 407 addr_val_t *addr_val_map, *avmap; 408 409 qla_rd_flash32(ha, 0, &sig); 410 QL_DPRINT2((ha->pci_dev, "%s: val[0] = 0x%08x\n", __func__, sig)); 411 412 qla_rd_flash32(ha, 4, &val); 413 QL_DPRINT2((ha->pci_dev, "%s: val[4] = 0x%08x\n", __func__, val)); --- 192 unchanged lines hidden (view full) --- 606 return (-1); 607 } 608 609 val = READ_OFFSET32(ha, Q8_CMDPEG_STATE); 610 611 if (val != CMDPEG_PHAN_INIT_COMPLETE) { 612 ret = qla_init_from_flash(ha); 613 qla_mdelay(__func__, 100); | 417 uint32_t offset, count, i; 418 addr_val_t *addr_val_map, *avmap; 419 420 qla_rd_flash32(ha, 0, &sig); 421 QL_DPRINT2((ha->pci_dev, "%s: val[0] = 0x%08x\n", __func__, sig)); 422 423 qla_rd_flash32(ha, 4, &val); 424 QL_DPRINT2((ha->pci_dev, "%s: val[4] = 0x%08x\n", __func__, val)); --- 192 unchanged lines hidden (view full) --- 617 return (-1); 618 } 619 620 val = READ_OFFSET32(ha, Q8_CMDPEG_STATE); 621 622 if (val != CMDPEG_PHAN_INIT_COMPLETE) { 623 ret = qla_init_from_flash(ha); 624 qla_mdelay(__func__, 100); |
625 } else { 626 ha->fw_ver_major = READ_OFFSET32(ha, Q8_FW_VER_MAJOR); 627 ha->fw_ver_minor = READ_OFFSET32(ha, Q8_FW_VER_MINOR); 628 ha->fw_ver_sub = READ_OFFSET32(ha, Q8_FW_VER_SUB); 629 630 if (qla_rd_flash32(ha, 0x100004, &val) == 0) { 631 632 if (((val & 0xFF) != ha->fw_ver_major) || 633 (((val >> 8) & 0xFF) != ha->fw_ver_minor) || 634 (((val >> 16) & 0xFF) != ha->fw_ver_sub)) { 635 636 ret = qla_init_from_flash(ha); 637 qla_mdelay(__func__, 100); 638 } 639 } |
|
614 } 615 616qla_init_exit: 617 ha->fw_ver_major = READ_OFFSET32(ha, Q8_FW_VER_MAJOR); 618 ha->fw_ver_minor = READ_OFFSET32(ha, Q8_FW_VER_MINOR); 619 ha->fw_ver_sub = READ_OFFSET32(ha, Q8_FW_VER_SUB); 620 ha->fw_ver_build = READ_OFFSET32(ha, Q8_FW_VER_BUILD); 621 622 return (ret); 623} 624 | 640 } 641 642qla_init_exit: 643 ha->fw_ver_major = READ_OFFSET32(ha, Q8_FW_VER_MAJOR); 644 ha->fw_ver_minor = READ_OFFSET32(ha, Q8_FW_VER_MINOR); 645 ha->fw_ver_sub = READ_OFFSET32(ha, Q8_FW_VER_SUB); 646 ha->fw_ver_build = READ_OFFSET32(ha, Q8_FW_VER_BUILD); 647 648 return (ret); 649} 650 |
651static int 652qla_wait_for_flash_busy(qla_host_t *ha) 653{ 654 uint32_t count = 100; 655 uint32_t val; 656 657 QLA_USEC_DELAY(100); 658 659 while (count--) { 660 val = READ_OFFSET32(ha, Q8_ROM_STATUS); 661 662 if (val & BIT_1) 663 return 0; 664 qla_mdelay(__func__, 1); 665 } 666 return -1; 667} 668 669static int 670qla_flash_write_enable(qla_host_t *ha) 671{ 672 uint32_t val, rval; 673 674 val = 0; 675 qla_rdwr_indreg32(ha, Q8_ROM_ADDR_BYTE_COUNT, &val, 0); 676 677 val = ROM_OPCODE_WR_ENABLE; 678 qla_rdwr_indreg32(ha, Q8_ROM_INSTR_OPCODE, &val, 0); 679 680 rval = qla_wait_for_flash_busy(ha); 681 682 if (rval) 683 device_printf(ha->pci_dev, "%s: failed \n", __func__); 684 685 return (rval); 686} 687 688static int 689qla_flash_unprotect(qla_host_t *ha) 690{ 691 uint32_t val, rval; 692 693 if (qla_flash_write_enable(ha) != 0) 694 return(-1); 695 696 val = 0; 697 qla_rdwr_indreg32(ha, Q8_ROM_WR_DATA, &val, 0); 698 699 val = ROM_OPCODE_WR_STATUS_REG; 700 qla_rdwr_indreg32(ha, Q8_ROM_INSTR_OPCODE, &val, 0); 701 702 rval = qla_wait_for_flash_busy(ha); 703 704 if (rval) { 705 device_printf(ha->pci_dev, "%s: failed \n", __func__); 706 return rval; 707 } 708 709 if (qla_flash_write_enable(ha) != 0) 710 return(-1); 711 712 val = 0; 713 qla_rdwr_indreg32(ha, Q8_ROM_WR_DATA, &val, 0); 714 715 val = ROM_OPCODE_WR_STATUS_REG; 716 qla_rdwr_indreg32(ha, Q8_ROM_INSTR_OPCODE, &val, 0); 717 718 rval = qla_wait_for_flash_busy(ha); 719 720 if (rval) 721 device_printf(ha->pci_dev, "%s: failed \n", __func__); 722 723 return rval; 724} 725 726static int 727qla_flash_protect(qla_host_t *ha) 728{ 729 uint32_t val, rval; 730 731 if (qla_flash_write_enable(ha) != 0) 732 return(-1); 733 734 val = 0x9C; 735 qla_rdwr_indreg32(ha, Q8_ROM_WR_DATA, &val, 0); 736 737 val = ROM_OPCODE_WR_STATUS_REG; 738 qla_rdwr_indreg32(ha, Q8_ROM_INSTR_OPCODE, &val, 0); 739 740 rval = qla_wait_for_flash_busy(ha); 741 742 if (rval) 743 device_printf(ha->pci_dev, "%s: failed \n", __func__); 744 745 return rval; 746} 747 748static uint32_t 749qla_flash_get_status(qla_host_t *ha) 750{ 751 uint32_t count = 1000; 752 uint32_t val, rval; 753 754 while (count--) { 755 val = 0; 756 qla_rdwr_indreg32(ha, Q8_ROM_ADDR_BYTE_COUNT, &val, 0); 757 758 val = ROM_OPCODE_RD_STATUS_REG; 759 qla_rdwr_indreg32(ha, Q8_ROM_INSTR_OPCODE, &val, 0); 760 761 rval = qla_wait_for_flash_busy(ha); 762 763 if (rval == 0) { 764 qla_rdwr_indreg32(ha, Q8_ROM_RD_DATA, &val, 1); 765 766 if ((val & BIT_0) == 0) 767 return (val); 768 } 769 qla_mdelay(__func__, 1); 770 } 771 return -1; 772} 773 774static int 775qla_wait_for_flash_unprotect(qla_host_t *ha) 776{ 777 uint32_t delay = 1000; 778 779 while (delay--) { 780 781 if (qla_flash_get_status(ha) == 0) 782 return 0; 783 784 qla_mdelay(__func__, 1); 785 } 786 787 return -1; 788} 789 790static int 791qla_wait_for_flash_protect(qla_host_t *ha) 792{ 793 uint32_t delay = 1000; 794 795 while (delay--) { 796 797 if (qla_flash_get_status(ha) == 0x9C) 798 return 0; 799 800 qla_mdelay(__func__, 1); 801 } 802 803 return -1; 804} 805 806static int 807qla_erase_flash_sector(qla_host_t *ha, uint32_t start) 808{ 809 uint32_t val; 810 int rval; 811 812 if (qla_flash_write_enable(ha) != 0) 813 return(-1); 814 815 val = start; 816 qla_rdwr_indreg32(ha, Q8_ROM_ADDRESS, &val, 0); 817 818 val = 3; 819 qla_rdwr_indreg32(ha, Q8_ROM_ADDR_BYTE_COUNT, &val, 0); 820 821 val = ROM_OPCODE_SECTOR_ERASE; 822 qla_rdwr_indreg32(ha, Q8_ROM_INSTR_OPCODE, &val, 0); 823 824 rval = qla_wait_for_flash_busy(ha); 825 826 if (rval) 827 device_printf(ha->pci_dev, "%s: failed \n", __func__); 828 return rval; 829} 830 831#define Q8_FLASH_SECTOR_SIZE 0x10000 832int 833qla_erase_flash(qla_host_t *ha, uint32_t off, uint32_t size) 834{ 835 int rval = 0; 836 uint32_t start; 837 838 if (off & (Q8_FLASH_SECTOR_SIZE -1)) 839 return -1; 840 841 if ((rval = qla_p3p_sem_lock2(ha))) 842 goto qla_erase_flash_exit; 843 844 if ((rval = qla_flash_unprotect(ha))) 845 goto qla_erase_flash_unlock_exit; 846 847 if ((rval = qla_wait_for_flash_unprotect(ha))) 848 goto qla_erase_flash_unlock_exit; 849 850 for (start = off; start < (off + size); start = start + 0x10000) { 851 if (qla_erase_flash_sector(ha, start)) { 852 rval = -1; 853 break; 854 } 855 } 856 857 rval = qla_flash_protect(ha); 858 859qla_erase_flash_unlock_exit: 860 qla_sem_unlock(ha, Q8_SEM2_UNLOCK); 861 862qla_erase_flash_exit: 863 return (rval); 864} 865 866static int 867qla_flash_write32(qla_host_t *ha, uint32_t off, uint32_t data) 868{ 869 uint32_t val; 870 int rval = 0; 871 872 val = data; 873 qla_rdwr_indreg32(ha, Q8_ROM_WR_DATA, &val, 0); 874 875 val = off; 876 qla_rdwr_indreg32(ha, Q8_ROM_ADDRESS, &val, 0); 877 878 val = 3; 879 qla_rdwr_indreg32(ha, Q8_ROM_ADDR_BYTE_COUNT, &val, 0); 880 881 val = ROM_OPCODE_PROG_PAGE; 882 qla_rdwr_indreg32(ha, Q8_ROM_INSTR_OPCODE, &val, 0); 883 884 rval = qla_wait_for_flash_busy(ha); 885 886 if (rval) 887 device_printf(ha->pci_dev, "%s: failed \n", __func__); 888 889 return rval; 890} 891 892static int 893qla_flash_wait_for_write_complete(qla_host_t *ha) 894{ 895 uint32_t val, count = 1000; 896 int rval = 0; 897 898 while (count--) { 899 900 val = 0; 901 qla_rdwr_indreg32(ha, Q8_ROM_ADDR_BYTE_COUNT, &val, 0); 902 903 val = ROM_OPCODE_RD_STATUS_REG; 904 qla_rdwr_indreg32(ha, Q8_ROM_INSTR_OPCODE, &val, 0); 905 906 907 rval = qla_wait_for_flash_busy(ha); 908 909 if (rval == 0) { 910 qla_rdwr_indreg32(ha, Q8_ROM_RD_DATA, &val, 1); 911 912 if ((val & BIT_0) == 0) 913 return (0); 914 } 915 qla_mdelay(__func__, 1); 916 } 917 return -1; 918} 919 920static int 921qla_flash_write(qla_host_t *ha, uint32_t off, uint32_t data) 922{ 923 if (qla_flash_write_enable(ha) != 0) 924 return(-1); 925 926 if (qla_flash_write32(ha, off, data) != 0) 927 return -1; 928 929 if (qla_flash_wait_for_write_complete(ha)) 930 return -1; 931 932 return 0; 933} 934 935 936static int 937qla_flash_write_pattern(qla_host_t *ha, uint32_t off, uint32_t size, 938 uint32_t pattern) 939{ 940 int rval = 0; 941 uint32_t start; 942 943 944 if ((rval = qla_p3p_sem_lock2(ha))) 945 goto qla_wr_pattern_exit; 946 947 if ((rval = qla_flash_unprotect(ha))) 948 goto qla_wr_pattern_unlock_exit; 949 950 if ((rval = qla_wait_for_flash_unprotect(ha))) 951 goto qla_wr_pattern_unlock_exit; 952 953 for (start = off; start < (off + size); start = start + 4) { 954 if (qla_flash_write(ha, start, pattern)) { 955 rval = -1; 956 break; 957 } 958 } 959 960 rval = qla_flash_protect(ha); 961 962 if (rval == 0) 963 rval = qla_wait_for_flash_protect(ha); 964 965qla_wr_pattern_unlock_exit: 966 qla_sem_unlock(ha, Q8_SEM2_UNLOCK); 967 968qla_wr_pattern_exit: 969 return (rval); 970} 971 972static int 973qla_flash_write_data(qla_host_t *ha, uint32_t off, uint32_t size, 974 void *data) 975{ 976 int rval = 0; 977 uint32_t start; 978 uint32_t *data32 = data; 979 980 981 if ((rval = qla_p3p_sem_lock2(ha))) 982 goto qla_wr_pattern_exit; 983 984 if ((rval = qla_flash_unprotect(ha))) 985 goto qla_wr_pattern_unlock_exit; 986 987 if ((rval = qla_wait_for_flash_unprotect(ha))) 988 goto qla_wr_pattern_unlock_exit; 989 990 for (start = off; start < (off + size); start = start + 4) { 991 992 if (*data32 != 0xFFFFFFFF) { 993 if (qla_flash_write(ha, start, *data32)) { 994 rval = -1; 995 break; 996 } 997 } 998 data32++; 999 } 1000 1001 rval = qla_flash_protect(ha); 1002 1003 if (rval == 0) 1004 rval = qla_wait_for_flash_protect(ha); 1005 1006qla_wr_pattern_unlock_exit: 1007 qla_sem_unlock(ha, Q8_SEM2_UNLOCK); 1008 1009qla_wr_pattern_exit: 1010 return (rval); 1011} 1012 1013int 1014qla_wr_flash_buffer(qla_host_t *ha, uint32_t off, uint32_t size, void *buf, 1015 uint32_t pattern) 1016{ 1017 int rval = 0; 1018 void *data; 1019 1020 1021 if (size == 0) 1022 return 0; 1023 1024 size = size << 2; 1025 1026 if (buf == NULL) { 1027 rval = qla_flash_write_pattern(ha, off, size, pattern); 1028 return (rval); 1029 } 1030 1031 if ((data = malloc(size, M_QLA8XXXBUF, M_NOWAIT)) == NULL) { 1032 device_printf(ha->pci_dev, "%s: malloc failed \n", __func__); 1033 rval = -1; 1034 goto qla_wr_flash_buffer_exit; 1035 } 1036 1037 if ((rval = copyin(buf, data, size))) { 1038 device_printf(ha->pci_dev, "%s copyin failed\n", __func__); 1039 goto qla_wr_flash_buffer_free_exit; 1040 } 1041 1042 rval = qla_flash_write_data(ha, off, size, data); 1043 1044qla_wr_flash_buffer_free_exit: 1045 free(data, M_QLA8XXXBUF); 1046 1047qla_wr_flash_buffer_exit: 1048 return (rval); 1049} 1050 |
|