diff options
author | Andrew Vasquez <andrew.vasquez@qlogic.com> | 2008-09-12 00:22:50 -0400 |
---|---|---|
committer | James Bottomley <James.Bottomley@HansenPartnership.com> | 2008-10-03 12:46:18 -0400 |
commit | 272976ca186982f7bbc4f22876c53d6c9f7b6e32 (patch) | |
tree | a0e3ecbf54d24da4ccccf881a60a2b788ac7c455 /drivers/scsi | |
parent | c00d8994d91e51aa6b891ad0e877f66cc1011de2 (diff) |
[SCSI] qla2xxx: Add NPIV-Config Table support.
To instatiate pre-configured vport entities defined within an
HBA's flash memory.
Signed-off-by: Andrew Vasquez <andrew.vasquez@qlogic.com>
Signed-off-by: James Bottomley <James.Bottomley@HansenPartnership.com>
Diffstat (limited to 'drivers/scsi')
-rw-r--r-- | drivers/scsi/qla2xxx/qla_def.h | 2 | ||||
-rw-r--r-- | drivers/scsi/qla2xxx/qla_fw.h | 26 | ||||
-rw-r--r-- | drivers/scsi/qla2xxx/qla_gbl.h | 2 | ||||
-rw-r--r-- | drivers/scsi/qla2xxx/qla_os.c | 7 | ||||
-rw-r--r-- | drivers/scsi/qla2xxx/qla_sup.c | 98 |
5 files changed, 133 insertions, 2 deletions
diff --git a/drivers/scsi/qla2xxx/qla_def.h b/drivers/scsi/qla2xxx/qla_def.h index 880e71127b73..83c819216771 100644 --- a/drivers/scsi/qla2xxx/qla_def.h +++ b/drivers/scsi/qla2xxx/qla_def.h | |||
@@ -2239,6 +2239,7 @@ typedef struct scsi_qla_host { | |||
2239 | #define FCPORT_UPDATE_NEEDED 27 | 2239 | #define FCPORT_UPDATE_NEEDED 27 |
2240 | #define VP_DPC_NEEDED 28 /* wake up for VP dpc handling */ | 2240 | #define VP_DPC_NEEDED 28 /* wake up for VP dpc handling */ |
2241 | #define UNLOADING 29 | 2241 | #define UNLOADING 29 |
2242 | #define NPIV_CONFIG_NEEDED 30 | ||
2242 | 2243 | ||
2243 | uint32_t device_flags; | 2244 | uint32_t device_flags; |
2244 | #define DFLG_LOCAL_DEVICES BIT_0 | 2245 | #define DFLG_LOCAL_DEVICES BIT_0 |
@@ -2559,6 +2560,7 @@ typedef struct scsi_qla_host { | |||
2559 | uint32_t flt_region_fw; | 2560 | uint32_t flt_region_fw; |
2560 | uint32_t flt_region_vpd_nvram; | 2561 | uint32_t flt_region_vpd_nvram; |
2561 | uint32_t flt_region_hw_event; | 2562 | uint32_t flt_region_hw_event; |
2563 | uint32_t flt_region_npiv_conf; | ||
2562 | 2564 | ||
2563 | /* Needed for BEACON */ | 2565 | /* Needed for BEACON */ |
2564 | uint16_t beacon_blink_led; | 2566 | uint16_t beacon_blink_led; |
diff --git a/drivers/scsi/qla2xxx/qla_fw.h b/drivers/scsi/qla2xxx/qla_fw.h index 2ec986bf8344..d1d14202575a 100644 --- a/drivers/scsi/qla2xxx/qla_fw.h +++ b/drivers/scsi/qla2xxx/qla_fw.h | |||
@@ -791,6 +791,8 @@ struct device_reg_24xx { | |||
791 | 791 | ||
792 | #define FA_FLASH_DESCR_ADDR_24 0x11000 | 792 | #define FA_FLASH_DESCR_ADDR_24 0x11000 |
793 | #define FA_FLASH_LAYOUT_ADDR_24 0x11400 | 793 | #define FA_FLASH_LAYOUT_ADDR_24 0x11400 |
794 | #define FA_NPIV_CONF0_ADDR_24 0x16000 | ||
795 | #define FA_NPIV_CONF1_ADDR_24 0x17000 | ||
794 | 796 | ||
795 | #define FA_FW_AREA_ADDR 0x40000 | 797 | #define FA_FW_AREA_ADDR 0x40000 |
796 | #define FA_VPD_NVRAM_ADDR 0x48000 | 798 | #define FA_VPD_NVRAM_ADDR 0x48000 |
@@ -801,6 +803,9 @@ struct device_reg_24xx { | |||
801 | #define FA_HW_EVENT1_ADDR 0x54400 | 803 | #define FA_HW_EVENT1_ADDR 0x54400 |
802 | #define FA_HW_EVENT_SIZE 0x200 | 804 | #define FA_HW_EVENT_SIZE 0x200 |
803 | #define FA_HW_EVENT_ENTRY_SIZE 4 | 805 | #define FA_HW_EVENT_ENTRY_SIZE 4 |
806 | #define FA_NPIV_CONF0_ADDR 0x5C000 | ||
807 | #define FA_NPIV_CONF1_ADDR 0x5D000 | ||
808 | |||
804 | /* | 809 | /* |
805 | * Flash Error Log Event Codes. | 810 | * Flash Error Log Event Codes. |
806 | */ | 811 | */ |
@@ -1230,6 +1235,8 @@ struct qla_flt_header { | |||
1230 | #define FLT_REG_FLT 0x1c | 1235 | #define FLT_REG_FLT 0x1c |
1231 | #define FLT_REG_HW_EVENT_0 0x1d | 1236 | #define FLT_REG_HW_EVENT_0 0x1d |
1232 | #define FLT_REG_HW_EVENT_1 0x1f | 1237 | #define FLT_REG_HW_EVENT_1 0x1f |
1238 | #define FLT_REG_NPIV_CONF_0 0x29 | ||
1239 | #define FLT_REG_NPIV_CONF_1 0x2a | ||
1233 | 1240 | ||
1234 | struct qla_flt_region { | 1241 | struct qla_flt_region { |
1235 | uint32_t code; | 1242 | uint32_t code; |
@@ -1238,6 +1245,25 @@ struct qla_flt_region { | |||
1238 | uint32_t end; | 1245 | uint32_t end; |
1239 | }; | 1246 | }; |
1240 | 1247 | ||
1248 | /* Flash NPIV Configuration Table ********************************************/ | ||
1249 | |||
1250 | struct qla_npiv_header { | ||
1251 | uint8_t sig[2]; | ||
1252 | uint16_t version; | ||
1253 | uint16_t entries; | ||
1254 | uint16_t unused[4]; | ||
1255 | uint16_t checksum; | ||
1256 | }; | ||
1257 | |||
1258 | struct qla_npiv_entry { | ||
1259 | uint16_t flags; | ||
1260 | uint16_t vf_id; | ||
1261 | uint16_t qos; | ||
1262 | uint16_t unused1; | ||
1263 | uint8_t port_name[WWN_SIZE]; | ||
1264 | uint8_t node_name[WWN_SIZE]; | ||
1265 | }; | ||
1266 | |||
1241 | /* 84XX Support **************************************************************/ | 1267 | /* 84XX Support **************************************************************/ |
1242 | 1268 | ||
1243 | #define MBA_ISP84XX_ALERT 0x800f /* Alert Notification. */ | 1269 | #define MBA_ISP84XX_ALERT 0x800f /* Alert Notification. */ |
diff --git a/drivers/scsi/qla2xxx/qla_gbl.h b/drivers/scsi/qla2xxx/qla_gbl.h index dbd9f93890e8..753dbe6cce6e 100644 --- a/drivers/scsi/qla2xxx/qla_gbl.h +++ b/drivers/scsi/qla2xxx/qla_gbl.h | |||
@@ -316,6 +316,8 @@ extern int qla2xxx_hw_event_log(scsi_qla_host_t *, uint16_t , uint16_t, | |||
316 | extern int qla2xxx_get_flash_info(scsi_qla_host_t *); | 316 | extern int qla2xxx_get_flash_info(scsi_qla_host_t *); |
317 | extern int qla2xxx_get_vpd_field(scsi_qla_host_t *, char *, char *, size_t); | 317 | extern int qla2xxx_get_vpd_field(scsi_qla_host_t *, char *, char *, size_t); |
318 | 318 | ||
319 | extern void qla2xxx_flash_npiv_conf(scsi_qla_host_t *); | ||
320 | |||
319 | /* | 321 | /* |
320 | * Global Function Prototypes in qla_dbg.c source file. | 322 | * Global Function Prototypes in qla_dbg.c source file. |
321 | */ | 323 | */ |
diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c index c1ffc3070ebe..3433441b956a 100644 --- a/drivers/scsi/qla2xxx/qla_os.c +++ b/drivers/scsi/qla2xxx/qla_os.c | |||
@@ -1517,6 +1517,7 @@ qla2xxx_scan_start(struct Scsi_Host *shost) | |||
1517 | set_bit(LOOP_RESYNC_NEEDED, &ha->dpc_flags); | 1517 | set_bit(LOOP_RESYNC_NEEDED, &ha->dpc_flags); |
1518 | set_bit(LOCAL_LOOP_UPDATE, &ha->dpc_flags); | 1518 | set_bit(LOCAL_LOOP_UPDATE, &ha->dpc_flags); |
1519 | set_bit(RSCN_UPDATE, &ha->dpc_flags); | 1519 | set_bit(RSCN_UPDATE, &ha->dpc_flags); |
1520 | set_bit(NPIV_CONFIG_NEEDED, &ha->dpc_flags); | ||
1520 | } | 1521 | } |
1521 | 1522 | ||
1522 | static int | 1523 | static int |
@@ -2431,6 +2432,12 @@ qla2x00_do_dpc(void *data) | |||
2431 | ha->host_no)); | 2432 | ha->host_no)); |
2432 | } | 2433 | } |
2433 | 2434 | ||
2435 | if (test_bit(NPIV_CONFIG_NEEDED, &ha->dpc_flags) && | ||
2436 | atomic_read(&ha->loop_state) == LOOP_READY) { | ||
2437 | clear_bit(NPIV_CONFIG_NEEDED, &ha->dpc_flags); | ||
2438 | qla2xxx_flash_npiv_conf(ha); | ||
2439 | } | ||
2440 | |||
2434 | if (!ha->interrupts_on) | 2441 | if (!ha->interrupts_on) |
2435 | ha->isp_ops->enable_intrs(ha); | 2442 | ha->isp_ops->enable_intrs(ha); |
2436 | 2443 | ||
diff --git a/drivers/scsi/qla2xxx/qla_sup.c b/drivers/scsi/qla2xxx/qla_sup.c index 6de1e3bc62a8..e2432ef1ecea 100644 --- a/drivers/scsi/qla2xxx/qla_sup.c +++ b/drivers/scsi/qla2xxx/qla_sup.c | |||
@@ -686,6 +686,14 @@ qla2xxx_get_flt_info(scsi_qla_host_t *ha, uint32_t flt_addr) | |||
686 | if (PCI_FUNC(ha->pdev->devfn)) | 686 | if (PCI_FUNC(ha->pdev->devfn)) |
687 | ha->flt_region_hw_event = start; | 687 | ha->flt_region_hw_event = start; |
688 | break; | 688 | break; |
689 | case FLT_REG_NPIV_CONF_0: | ||
690 | if (!PCI_FUNC(ha->pdev->devfn)) | ||
691 | ha->flt_region_npiv_conf = start; | ||
692 | break; | ||
693 | case FLT_REG_NPIV_CONF_1: | ||
694 | if (PCI_FUNC(ha->pdev->devfn)) | ||
695 | ha->flt_region_npiv_conf = start; | ||
696 | break; | ||
689 | } | 697 | } |
690 | } | 698 | } |
691 | goto done; | 699 | goto done; |
@@ -700,11 +708,15 @@ no_flash_data: | |||
700 | FA_FLASH_DESCR_ADDR; | 708 | FA_FLASH_DESCR_ADDR; |
701 | ha->flt_region_hw_event = !PCI_FUNC(ha->pdev->devfn) ? | 709 | ha->flt_region_hw_event = !PCI_FUNC(ha->pdev->devfn) ? |
702 | FA_HW_EVENT0_ADDR: FA_HW_EVENT1_ADDR; | 710 | FA_HW_EVENT0_ADDR: FA_HW_EVENT1_ADDR; |
711 | ha->flt_region_npiv_conf = !PCI_FUNC(ha->pdev->devfn) ? | ||
712 | (IS_QLA24XX_TYPE(ha) ? FA_NPIV_CONF0_ADDR_24: FA_NPIV_CONF0_ADDR): | ||
713 | (IS_QLA24XX_TYPE(ha) ? FA_NPIV_CONF1_ADDR_24: FA_NPIV_CONF1_ADDR); | ||
703 | done: | 714 | done: |
704 | DEBUG2(qla_printk(KERN_DEBUG, ha, "FLT[%s]: boot=0x%x fw=0x%x " | 715 | DEBUG2(qla_printk(KERN_DEBUG, ha, "FLT[%s]: boot=0x%x fw=0x%x " |
705 | "vpd_nvram=0x%x fdt=0x%x flt=0x%x hwe=0x%x.\n", loc, | 716 | "vpd_nvram=0x%x fdt=0x%x flt=0x%x hwe=0x%x npiv=0x%x.\n", loc, |
706 | ha->flt_region_boot, ha->flt_region_fw, ha->flt_region_vpd_nvram, | 717 | ha->flt_region_boot, ha->flt_region_fw, ha->flt_region_vpd_nvram, |
707 | ha->flt_region_fdt, ha->flt_region_flt, ha->flt_region_hw_event)); | 718 | ha->flt_region_fdt, ha->flt_region_flt, ha->flt_region_hw_event, |
719 | ha->flt_region_npiv_conf)); | ||
708 | } | 720 | } |
709 | 721 | ||
710 | static void | 722 | static void |
@@ -814,6 +826,88 @@ qla2xxx_get_flash_info(scsi_qla_host_t *ha) | |||
814 | return QLA_SUCCESS; | 826 | return QLA_SUCCESS; |
815 | } | 827 | } |
816 | 828 | ||
829 | void | ||
830 | qla2xxx_flash_npiv_conf(scsi_qla_host_t *ha) | ||
831 | { | ||
832 | #define NPIV_CONFIG_SIZE (16*1024) | ||
833 | void *data; | ||
834 | uint16_t *wptr; | ||
835 | uint16_t cnt, chksum; | ||
836 | struct qla_npiv_header hdr; | ||
837 | struct qla_npiv_entry *entry; | ||
838 | |||
839 | if (!IS_QLA24XX_TYPE(ha) && !IS_QLA25XX(ha)) | ||
840 | return; | ||
841 | |||
842 | ha->isp_ops->read_optrom(ha, (uint8_t *)&hdr, | ||
843 | ha->flt_region_npiv_conf << 2, sizeof(struct qla_npiv_header)); | ||
844 | if (hdr.version == __constant_cpu_to_le16(0xffff)) | ||
845 | return; | ||
846 | if (hdr.version != __constant_cpu_to_le16(1)) { | ||
847 | DEBUG2(qla_printk(KERN_INFO, ha, "Unsupported NPIV-Config " | ||
848 | "detected: version=0x%x entries=0x%x checksum=0x%x.\n", | ||
849 | le16_to_cpu(hdr.version), le16_to_cpu(hdr.entries), | ||
850 | le16_to_cpu(hdr.checksum))); | ||
851 | return; | ||
852 | } | ||
853 | |||
854 | data = kmalloc(NPIV_CONFIG_SIZE, GFP_KERNEL); | ||
855 | if (!data) { | ||
856 | DEBUG2(qla_printk(KERN_INFO, ha, "NPIV-Config: Unable to " | ||
857 | "allocate memory.\n")); | ||
858 | return; | ||
859 | } | ||
860 | |||
861 | ha->isp_ops->read_optrom(ha, (uint8_t *)data, | ||
862 | ha->flt_region_npiv_conf << 2, NPIV_CONFIG_SIZE); | ||
863 | |||
864 | cnt = (sizeof(struct qla_npiv_header) + le16_to_cpu(hdr.entries) * | ||
865 | sizeof(struct qla_npiv_entry)) >> 1; | ||
866 | for (wptr = data, chksum = 0; cnt; cnt--) | ||
867 | chksum += le16_to_cpu(*wptr++); | ||
868 | if (chksum) { | ||
869 | DEBUG2(qla_printk(KERN_INFO, ha, "Inconsistent NPIV-Config " | ||
870 | "detected: version=0x%x entries=0x%x checksum=0x%x.\n", | ||
871 | le16_to_cpu(hdr.version), le16_to_cpu(hdr.entries), | ||
872 | chksum)); | ||
873 | goto done; | ||
874 | } | ||
875 | |||
876 | entry = data + sizeof(struct qla_npiv_header); | ||
877 | cnt = le16_to_cpu(hdr.entries); | ||
878 | for ( ; cnt; cnt--, entry++) { | ||
879 | uint16_t flags; | ||
880 | struct fc_vport_identifiers vid; | ||
881 | struct fc_vport *vport; | ||
882 | |||
883 | flags = le16_to_cpu(entry->flags); | ||
884 | if (flags == 0xffff) | ||
885 | continue; | ||
886 | if ((flags & BIT_0) == 0) | ||
887 | continue; | ||
888 | |||
889 | memset(&vid, 0, sizeof(vid)); | ||
890 | vid.roles = FC_PORT_ROLE_FCP_INITIATOR; | ||
891 | vid.vport_type = FC_PORTTYPE_NPIV; | ||
892 | vid.disable = false; | ||
893 | vid.port_name = wwn_to_u64(entry->port_name); | ||
894 | vid.node_name = wwn_to_u64(entry->node_name); | ||
895 | |||
896 | DEBUG2(qla_printk(KERN_DEBUG, ha, "NPIV[%02x]: wwpn=%llx " | ||
897 | "wwnn=%llx vf_id=0x%x qos=0x%x.\n", cnt, vid.port_name, | ||
898 | vid.node_name, le16_to_cpu(entry->vf_id), | ||
899 | le16_to_cpu(entry->qos))); | ||
900 | |||
901 | vport = fc_vport_create(ha->host, 0, &vid); | ||
902 | if (!vport) | ||
903 | qla_printk(KERN_INFO, ha, "NPIV-Config: Failed to " | ||
904 | "create vport [%02x]: wwpn=%llx wwnn=%llx.\n", cnt, | ||
905 | vid.port_name, vid.node_name); | ||
906 | } | ||
907 | done: | ||
908 | kfree(data); | ||
909 | } | ||
910 | |||
817 | static void | 911 | static void |
818 | qla24xx_unprotect_flash(scsi_qla_host_t *ha) | 912 | qla24xx_unprotect_flash(scsi_qla_host_t *ha) |
819 | { | 913 | { |