aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/qla2xxx
diff options
context:
space:
mode:
authorAndrew Vasquez <andrew.vasquez@qlogic.com>2008-09-12 00:22:50 -0400
committerJames Bottomley <James.Bottomley@HansenPartnership.com>2008-10-03 12:46:18 -0400
commit272976ca186982f7bbc4f22876c53d6c9f7b6e32 (patch)
treea0e3ecbf54d24da4ccccf881a60a2b788ac7c455 /drivers/scsi/qla2xxx
parentc00d8994d91e51aa6b891ad0e877f66cc1011de2 (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/qla2xxx')
-rw-r--r--drivers/scsi/qla2xxx/qla_def.h2
-rw-r--r--drivers/scsi/qla2xxx/qla_fw.h26
-rw-r--r--drivers/scsi/qla2xxx/qla_gbl.h2
-rw-r--r--drivers/scsi/qla2xxx/qla_os.c7
-rw-r--r--drivers/scsi/qla2xxx/qla_sup.c98
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
1234struct qla_flt_region { 1241struct 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
1250struct 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
1258struct 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,
316extern int qla2xxx_get_flash_info(scsi_qla_host_t *); 316extern int qla2xxx_get_flash_info(scsi_qla_host_t *);
317extern int qla2xxx_get_vpd_field(scsi_qla_host_t *, char *, char *, size_t); 317extern int qla2xxx_get_vpd_field(scsi_qla_host_t *, char *, char *, size_t);
318 318
319extern 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
1522static int 1523static 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);
703done: 714done:
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
710static void 722static 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
829void
830qla2xxx_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 }
907done:
908 kfree(data);
909}
910
817static void 911static void
818qla24xx_unprotect_flash(scsi_qla_host_t *ha) 912qla24xx_unprotect_flash(scsi_qla_host_t *ha)
819{ 913{