Deleted Added
full compact
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