diff options
author | James Smart <james.smart@emulex.com> | 2013-01-03 15:44:00 -0500 |
---|---|---|
committer | James Bottomley <JBottomley@Parallels.com> | 2013-01-29 19:32:41 -0500 |
commit | 962bc51b04b2725639c47c49404943516ac32b11 (patch) | |
tree | db534ab9510f851ac34f9e26b0d813c8a7db9b42 | |
parent | 8b455cf351bba1b9e46d6a1350888be9f6a289d2 (diff) |
[SCSI] lpfc 8.3.37: Provide support for FCoE protocol dual-chute (ULP) operation
Signed-off-by: James Smart <james.smart@emulex.com>
Signed-off-by: James Bottomley <JBottomley@Parallels.com>
-rw-r--r-- | drivers/scsi/lpfc/lpfc.h | 9 | ||||
-rw-r--r-- | drivers/scsi/lpfc/lpfc_hw4.h | 176 | ||||
-rw-r--r-- | drivers/scsi/lpfc/lpfc_init.c | 72 | ||||
-rw-r--r-- | drivers/scsi/lpfc/lpfc_sli.c | 188 | ||||
-rw-r--r-- | drivers/scsi/lpfc/lpfc_sli4.h | 8 |
5 files changed, 369 insertions, 84 deletions
diff --git a/drivers/scsi/lpfc/lpfc.h b/drivers/scsi/lpfc/lpfc.h index 9b7fbaf07a55..7706c99ec8bb 100644 --- a/drivers/scsi/lpfc/lpfc.h +++ b/drivers/scsi/lpfc/lpfc.h | |||
@@ -752,6 +752,15 @@ struct lpfc_hba { | |||
752 | void __iomem *ctrl_regs_memmap_p;/* Kernel memory mapped address for | 752 | void __iomem *ctrl_regs_memmap_p;/* Kernel memory mapped address for |
753 | PCI BAR2 */ | 753 | PCI BAR2 */ |
754 | 754 | ||
755 | void __iomem *pci_bar0_memmap_p; /* Kernel memory mapped address for | ||
756 | PCI BAR0 with dual-ULP support */ | ||
757 | void __iomem *pci_bar2_memmap_p; /* Kernel memory mapped address for | ||
758 | PCI BAR2 with dual-ULP support */ | ||
759 | void __iomem *pci_bar4_memmap_p; /* Kernel memory mapped address for | ||
760 | PCI BAR4 with dual-ULP support */ | ||
761 | #define PCI_64BIT_BAR0 0 | ||
762 | #define PCI_64BIT_BAR2 2 | ||
763 | #define PCI_64BIT_BAR4 4 | ||
755 | void __iomem *MBslimaddr; /* virtual address for mbox cmds */ | 764 | void __iomem *MBslimaddr; /* virtual address for mbox cmds */ |
756 | void __iomem *HAregaddr; /* virtual address for host attn reg */ | 765 | void __iomem *HAregaddr; /* virtual address for host attn reg */ |
757 | void __iomem *CAregaddr; /* virtual address for chip attn reg */ | 766 | void __iomem *CAregaddr; /* virtual address for chip attn reg */ |
diff --git a/drivers/scsi/lpfc/lpfc_hw4.h b/drivers/scsi/lpfc/lpfc_hw4.h index a47cfbdd05f2..6e93b886cd4d 100644 --- a/drivers/scsi/lpfc/lpfc_hw4.h +++ b/drivers/scsi/lpfc/lpfc_hw4.h | |||
@@ -106,6 +106,7 @@ struct lpfc_sli_intf { | |||
106 | 106 | ||
107 | #define LPFC_SLI4_MB_WORD_COUNT 64 | 107 | #define LPFC_SLI4_MB_WORD_COUNT 64 |
108 | #define LPFC_MAX_MQ_PAGE 8 | 108 | #define LPFC_MAX_MQ_PAGE 8 |
109 | #define LPFC_MAX_WQ_PAGE_V0 4 | ||
109 | #define LPFC_MAX_WQ_PAGE 8 | 110 | #define LPFC_MAX_WQ_PAGE 8 |
110 | #define LPFC_MAX_CQ_PAGE 4 | 111 | #define LPFC_MAX_CQ_PAGE 4 |
111 | #define LPFC_MAX_EQ_PAGE 8 | 112 | #define LPFC_MAX_EQ_PAGE 8 |
@@ -703,24 +704,41 @@ struct lpfc_register { | |||
703 | * BAR0. The offsets are the same so the driver must account for | 704 | * BAR0. The offsets are the same so the driver must account for |
704 | * any base address difference. | 705 | * any base address difference. |
705 | */ | 706 | */ |
706 | #define LPFC_RQ_DOORBELL 0x00A0 | 707 | #define LPFC_ULP0_RQ_DOORBELL 0x00A0 |
707 | #define lpfc_rq_doorbell_num_posted_SHIFT 16 | 708 | #define LPFC_ULP1_RQ_DOORBELL 0x00C0 |
708 | #define lpfc_rq_doorbell_num_posted_MASK 0x3FFF | 709 | #define lpfc_rq_db_list_fm_num_posted_SHIFT 24 |
709 | #define lpfc_rq_doorbell_num_posted_WORD word0 | 710 | #define lpfc_rq_db_list_fm_num_posted_MASK 0x00FF |
710 | #define lpfc_rq_doorbell_id_SHIFT 0 | 711 | #define lpfc_rq_db_list_fm_num_posted_WORD word0 |
711 | #define lpfc_rq_doorbell_id_MASK 0xFFFF | 712 | #define lpfc_rq_db_list_fm_index_SHIFT 16 |
712 | #define lpfc_rq_doorbell_id_WORD word0 | 713 | #define lpfc_rq_db_list_fm_index_MASK 0x00FF |
713 | 714 | #define lpfc_rq_db_list_fm_index_WORD word0 | |
714 | #define LPFC_WQ_DOORBELL 0x0040 | 715 | #define lpfc_rq_db_list_fm_id_SHIFT 0 |
715 | #define lpfc_wq_doorbell_num_posted_SHIFT 24 | 716 | #define lpfc_rq_db_list_fm_id_MASK 0xFFFF |
716 | #define lpfc_wq_doorbell_num_posted_MASK 0x00FF | 717 | #define lpfc_rq_db_list_fm_id_WORD word0 |
717 | #define lpfc_wq_doorbell_num_posted_WORD word0 | 718 | #define lpfc_rq_db_ring_fm_num_posted_SHIFT 16 |
718 | #define lpfc_wq_doorbell_index_SHIFT 16 | 719 | #define lpfc_rq_db_ring_fm_num_posted_MASK 0x3FFF |
719 | #define lpfc_wq_doorbell_index_MASK 0x00FF | 720 | #define lpfc_rq_db_ring_fm_num_posted_WORD word0 |
720 | #define lpfc_wq_doorbell_index_WORD word0 | 721 | #define lpfc_rq_db_ring_fm_id_SHIFT 0 |
721 | #define lpfc_wq_doorbell_id_SHIFT 0 | 722 | #define lpfc_rq_db_ring_fm_id_MASK 0xFFFF |
722 | #define lpfc_wq_doorbell_id_MASK 0xFFFF | 723 | #define lpfc_rq_db_ring_fm_id_WORD word0 |
723 | #define lpfc_wq_doorbell_id_WORD word0 | 724 | |
725 | #define LPFC_ULP0_WQ_DOORBELL 0x0040 | ||
726 | #define LPFC_ULP1_WQ_DOORBELL 0x0060 | ||
727 | #define lpfc_wq_db_list_fm_num_posted_SHIFT 24 | ||
728 | #define lpfc_wq_db_list_fm_num_posted_MASK 0x00FF | ||
729 | #define lpfc_wq_db_list_fm_num_posted_WORD word0 | ||
730 | #define lpfc_wq_db_list_fm_index_SHIFT 16 | ||
731 | #define lpfc_wq_db_list_fm_index_MASK 0x00FF | ||
732 | #define lpfc_wq_db_list_fm_index_WORD word0 | ||
733 | #define lpfc_wq_db_list_fm_id_SHIFT 0 | ||
734 | #define lpfc_wq_db_list_fm_id_MASK 0xFFFF | ||
735 | #define lpfc_wq_db_list_fm_id_WORD word0 | ||
736 | #define lpfc_wq_db_ring_fm_num_posted_SHIFT 16 | ||
737 | #define lpfc_wq_db_ring_fm_num_posted_MASK 0x3FFF | ||
738 | #define lpfc_wq_db_ring_fm_num_posted_WORD word0 | ||
739 | #define lpfc_wq_db_ring_fm_id_SHIFT 0 | ||
740 | #define lpfc_wq_db_ring_fm_id_MASK 0xFFFF | ||
741 | #define lpfc_wq_db_ring_fm_id_WORD word0 | ||
724 | 742 | ||
725 | #define LPFC_EQCQ_DOORBELL 0x0120 | 743 | #define LPFC_EQCQ_DOORBELL 0x0120 |
726 | #define lpfc_eqcq_doorbell_se_SHIFT 31 | 744 | #define lpfc_eqcq_doorbell_se_SHIFT 31 |
@@ -1131,12 +1149,22 @@ struct lpfc_mbx_wq_create { | |||
1131 | struct { /* Version 0 Request */ | 1149 | struct { /* Version 0 Request */ |
1132 | uint32_t word0; | 1150 | uint32_t word0; |
1133 | #define lpfc_mbx_wq_create_num_pages_SHIFT 0 | 1151 | #define lpfc_mbx_wq_create_num_pages_SHIFT 0 |
1134 | #define lpfc_mbx_wq_create_num_pages_MASK 0x0000FFFF | 1152 | #define lpfc_mbx_wq_create_num_pages_MASK 0x000000FF |
1135 | #define lpfc_mbx_wq_create_num_pages_WORD word0 | 1153 | #define lpfc_mbx_wq_create_num_pages_WORD word0 |
1154 | #define lpfc_mbx_wq_create_dua_SHIFT 8 | ||
1155 | #define lpfc_mbx_wq_create_dua_MASK 0x00000001 | ||
1156 | #define lpfc_mbx_wq_create_dua_WORD word0 | ||
1136 | #define lpfc_mbx_wq_create_cq_id_SHIFT 16 | 1157 | #define lpfc_mbx_wq_create_cq_id_SHIFT 16 |
1137 | #define lpfc_mbx_wq_create_cq_id_MASK 0x0000FFFF | 1158 | #define lpfc_mbx_wq_create_cq_id_MASK 0x0000FFFF |
1138 | #define lpfc_mbx_wq_create_cq_id_WORD word0 | 1159 | #define lpfc_mbx_wq_create_cq_id_WORD word0 |
1139 | struct dma_address page[LPFC_MAX_WQ_PAGE]; | 1160 | struct dma_address page[LPFC_MAX_WQ_PAGE_V0]; |
1161 | uint32_t word9; | ||
1162 | #define lpfc_mbx_wq_create_bua_SHIFT 0 | ||
1163 | #define lpfc_mbx_wq_create_bua_MASK 0x00000001 | ||
1164 | #define lpfc_mbx_wq_create_bua_WORD word9 | ||
1165 | #define lpfc_mbx_wq_create_ulp_num_SHIFT 8 | ||
1166 | #define lpfc_mbx_wq_create_ulp_num_MASK 0x000000FF | ||
1167 | #define lpfc_mbx_wq_create_ulp_num_WORD word9 | ||
1140 | } request; | 1168 | } request; |
1141 | struct { /* Version 1 Request */ | 1169 | struct { /* Version 1 Request */ |
1142 | uint32_t word0; /* Word 0 is the same as in v0 */ | 1170 | uint32_t word0; /* Word 0 is the same as in v0 */ |
@@ -1160,6 +1188,17 @@ struct lpfc_mbx_wq_create { | |||
1160 | #define lpfc_mbx_wq_create_q_id_SHIFT 0 | 1188 | #define lpfc_mbx_wq_create_q_id_SHIFT 0 |
1161 | #define lpfc_mbx_wq_create_q_id_MASK 0x0000FFFF | 1189 | #define lpfc_mbx_wq_create_q_id_MASK 0x0000FFFF |
1162 | #define lpfc_mbx_wq_create_q_id_WORD word0 | 1190 | #define lpfc_mbx_wq_create_q_id_WORD word0 |
1191 | uint32_t doorbell_offset; | ||
1192 | uint32_t word2; | ||
1193 | #define lpfc_mbx_wq_create_bar_set_SHIFT 0 | ||
1194 | #define lpfc_mbx_wq_create_bar_set_MASK 0x0000FFFF | ||
1195 | #define lpfc_mbx_wq_create_bar_set_WORD word2 | ||
1196 | #define WQ_PCI_BAR_0_AND_1 0x00 | ||
1197 | #define WQ_PCI_BAR_2_AND_3 0x01 | ||
1198 | #define WQ_PCI_BAR_4_AND_5 0x02 | ||
1199 | #define lpfc_mbx_wq_create_db_format_SHIFT 16 | ||
1200 | #define lpfc_mbx_wq_create_db_format_MASK 0x0000FFFF | ||
1201 | #define lpfc_mbx_wq_create_db_format_WORD word2 | ||
1163 | } response; | 1202 | } response; |
1164 | } u; | 1203 | } u; |
1165 | }; | 1204 | }; |
@@ -1223,14 +1262,31 @@ struct lpfc_mbx_rq_create { | |||
1223 | #define lpfc_mbx_rq_create_num_pages_SHIFT 0 | 1262 | #define lpfc_mbx_rq_create_num_pages_SHIFT 0 |
1224 | #define lpfc_mbx_rq_create_num_pages_MASK 0x0000FFFF | 1263 | #define lpfc_mbx_rq_create_num_pages_MASK 0x0000FFFF |
1225 | #define lpfc_mbx_rq_create_num_pages_WORD word0 | 1264 | #define lpfc_mbx_rq_create_num_pages_WORD word0 |
1265 | #define lpfc_mbx_rq_create_dua_SHIFT 16 | ||
1266 | #define lpfc_mbx_rq_create_dua_MASK 0x00000001 | ||
1267 | #define lpfc_mbx_rq_create_dua_WORD word0 | ||
1268 | #define lpfc_mbx_rq_create_bqu_SHIFT 17 | ||
1269 | #define lpfc_mbx_rq_create_bqu_MASK 0x00000001 | ||
1270 | #define lpfc_mbx_rq_create_bqu_WORD word0 | ||
1271 | #define lpfc_mbx_rq_create_ulp_num_SHIFT 24 | ||
1272 | #define lpfc_mbx_rq_create_ulp_num_MASK 0x000000FF | ||
1273 | #define lpfc_mbx_rq_create_ulp_num_WORD word0 | ||
1226 | struct rq_context context; | 1274 | struct rq_context context; |
1227 | struct dma_address page[LPFC_MAX_WQ_PAGE]; | 1275 | struct dma_address page[LPFC_MAX_WQ_PAGE]; |
1228 | } request; | 1276 | } request; |
1229 | struct { | 1277 | struct { |
1230 | uint32_t word0; | 1278 | uint32_t word0; |
1231 | #define lpfc_mbx_rq_create_q_id_SHIFT 0 | 1279 | #define lpfc_mbx_rq_create_q_id_SHIFT 0 |
1232 | #define lpfc_mbx_rq_create_q_id_MASK 0x0000FFFF | 1280 | #define lpfc_mbx_rq_create_q_id_MASK 0x0000FFFF |
1233 | #define lpfc_mbx_rq_create_q_id_WORD word0 | 1281 | #define lpfc_mbx_rq_create_q_id_WORD word0 |
1282 | uint32_t doorbell_offset; | ||
1283 | uint32_t word2; | ||
1284 | #define lpfc_mbx_rq_create_bar_set_SHIFT 0 | ||
1285 | #define lpfc_mbx_rq_create_bar_set_MASK 0x0000FFFF | ||
1286 | #define lpfc_mbx_rq_create_bar_set_WORD word2 | ||
1287 | #define lpfc_mbx_rq_create_db_format_SHIFT 16 | ||
1288 | #define lpfc_mbx_rq_create_db_format_MASK 0x0000FFFF | ||
1289 | #define lpfc_mbx_rq_create_db_format_WORD word2 | ||
1234 | } response; | 1290 | } response; |
1235 | } u; | 1291 | } u; |
1236 | }; | 1292 | }; |
@@ -1388,6 +1444,33 @@ struct lpfc_mbx_get_rsrc_extent_info { | |||
1388 | } u; | 1444 | } u; |
1389 | }; | 1445 | }; |
1390 | 1446 | ||
1447 | struct lpfc_mbx_query_fw_config { | ||
1448 | struct mbox_header header; | ||
1449 | struct { | ||
1450 | uint32_t config_number; | ||
1451 | #define LPFC_FC_FCOE 0x00000007 | ||
1452 | uint32_t asic_revision; | ||
1453 | uint32_t physical_port; | ||
1454 | uint32_t function_mode; | ||
1455 | #define LPFC_FCOE_INI_MODE 0x00000040 | ||
1456 | #define LPFC_FCOE_TGT_MODE 0x00000080 | ||
1457 | #define LPFC_DUA_MODE 0x00000800 | ||
1458 | uint32_t ulp0_mode; | ||
1459 | #define LPFC_ULP_FCOE_INIT_MODE 0x00000040 | ||
1460 | #define LPFC_ULP_FCOE_TGT_MODE 0x00000080 | ||
1461 | uint32_t ulp0_nap_words[12]; | ||
1462 | uint32_t ulp1_mode; | ||
1463 | uint32_t ulp1_nap_words[12]; | ||
1464 | uint32_t function_capabilities; | ||
1465 | uint32_t cqid_base; | ||
1466 | uint32_t cqid_tot; | ||
1467 | uint32_t eqid_base; | ||
1468 | uint32_t eqid_tot; | ||
1469 | uint32_t ulp0_nap2_words[2]; | ||
1470 | uint32_t ulp1_nap2_words[2]; | ||
1471 | } rsp; | ||
1472 | }; | ||
1473 | |||
1391 | struct lpfc_id_range { | 1474 | struct lpfc_id_range { |
1392 | uint32_t word5; | 1475 | uint32_t word5; |
1393 | #define lpfc_mbx_rsrc_id_word4_0_SHIFT 0 | 1476 | #define lpfc_mbx_rsrc_id_word4_0_SHIFT 0 |
@@ -1803,51 +1886,6 @@ struct lpfc_mbx_redisc_fcf_tbl { | |||
1803 | #define lpfc_mbx_redisc_fcf_index_WORD word12 | 1886 | #define lpfc_mbx_redisc_fcf_index_WORD word12 |
1804 | }; | 1887 | }; |
1805 | 1888 | ||
1806 | struct lpfc_mbx_query_fw_cfg { | ||
1807 | struct mbox_header header; | ||
1808 | uint32_t config_number; | ||
1809 | uint32_t asic_rev; | ||
1810 | uint32_t phys_port; | ||
1811 | uint32_t function_mode; | ||
1812 | /* firmware Function Mode */ | ||
1813 | #define lpfc_function_mode_toe_SHIFT 0 | ||
1814 | #define lpfc_function_mode_toe_MASK 0x00000001 | ||
1815 | #define lpfc_function_mode_toe_WORD function_mode | ||
1816 | #define lpfc_function_mode_nic_SHIFT 1 | ||
1817 | #define lpfc_function_mode_nic_MASK 0x00000001 | ||
1818 | #define lpfc_function_mode_nic_WORD function_mode | ||
1819 | #define lpfc_function_mode_rdma_SHIFT 2 | ||
1820 | #define lpfc_function_mode_rdma_MASK 0x00000001 | ||
1821 | #define lpfc_function_mode_rdma_WORD function_mode | ||
1822 | #define lpfc_function_mode_vm_SHIFT 3 | ||
1823 | #define lpfc_function_mode_vm_MASK 0x00000001 | ||
1824 | #define lpfc_function_mode_vm_WORD function_mode | ||
1825 | #define lpfc_function_mode_iscsi_i_SHIFT 4 | ||
1826 | #define lpfc_function_mode_iscsi_i_MASK 0x00000001 | ||
1827 | #define lpfc_function_mode_iscsi_i_WORD function_mode | ||
1828 | #define lpfc_function_mode_iscsi_t_SHIFT 5 | ||
1829 | #define lpfc_function_mode_iscsi_t_MASK 0x00000001 | ||
1830 | #define lpfc_function_mode_iscsi_t_WORD function_mode | ||
1831 | #define lpfc_function_mode_fcoe_i_SHIFT 6 | ||
1832 | #define lpfc_function_mode_fcoe_i_MASK 0x00000001 | ||
1833 | #define lpfc_function_mode_fcoe_i_WORD function_mode | ||
1834 | #define lpfc_function_mode_fcoe_t_SHIFT 7 | ||
1835 | #define lpfc_function_mode_fcoe_t_MASK 0x00000001 | ||
1836 | #define lpfc_function_mode_fcoe_t_WORD function_mode | ||
1837 | #define lpfc_function_mode_dal_SHIFT 8 | ||
1838 | #define lpfc_function_mode_dal_MASK 0x00000001 | ||
1839 | #define lpfc_function_mode_dal_WORD function_mode | ||
1840 | #define lpfc_function_mode_lro_SHIFT 9 | ||
1841 | #define lpfc_function_mode_lro_MASK 0x00000001 | ||
1842 | #define lpfc_function_mode_lro_WORD function_mode | ||
1843 | #define lpfc_function_mode_flex10_SHIFT 10 | ||
1844 | #define lpfc_function_mode_flex10_MASK 0x00000001 | ||
1845 | #define lpfc_function_mode_flex10_WORD function_mode | ||
1846 | #define lpfc_function_mode_ncsi_SHIFT 11 | ||
1847 | #define lpfc_function_mode_ncsi_MASK 0x00000001 | ||
1848 | #define lpfc_function_mode_ncsi_WORD function_mode | ||
1849 | }; | ||
1850 | |||
1851 | /* Status field for embedded SLI_CONFIG mailbox command */ | 1889 | /* Status field for embedded SLI_CONFIG mailbox command */ |
1852 | #define STATUS_SUCCESS 0x0 | 1890 | #define STATUS_SUCCESS 0x0 |
1853 | #define STATUS_FAILED 0x1 | 1891 | #define STATUS_FAILED 0x1 |
@@ -2965,7 +3003,7 @@ struct lpfc_mqe { | |||
2965 | struct lpfc_mbx_read_config rd_config; | 3003 | struct lpfc_mbx_read_config rd_config; |
2966 | struct lpfc_mbx_request_features req_ftrs; | 3004 | struct lpfc_mbx_request_features req_ftrs; |
2967 | struct lpfc_mbx_post_hdr_tmpl hdr_tmpl; | 3005 | struct lpfc_mbx_post_hdr_tmpl hdr_tmpl; |
2968 | struct lpfc_mbx_query_fw_cfg query_fw_cfg; | 3006 | struct lpfc_mbx_query_fw_config query_fw_cfg; |
2969 | struct lpfc_mbx_supp_pages supp_pages; | 3007 | struct lpfc_mbx_supp_pages supp_pages; |
2970 | struct lpfc_mbx_pc_sli4_params sli4_params; | 3008 | struct lpfc_mbx_pc_sli4_params sli4_params; |
2971 | struct lpfc_mbx_get_sli4_parameters get_sli4_parameters; | 3009 | struct lpfc_mbx_get_sli4_parameters get_sli4_parameters; |
diff --git a/drivers/scsi/lpfc/lpfc_init.c b/drivers/scsi/lpfc/lpfc_init.c index 5262049651ee..26ca2efa976e 100644 --- a/drivers/scsi/lpfc/lpfc_init.c +++ b/drivers/scsi/lpfc/lpfc_init.c | |||
@@ -6233,9 +6233,11 @@ lpfc_sli4_bar0_register_memmap(struct lpfc_hba *phba, uint32_t if_type) | |||
6233 | phba->sli4_hba.conf_regs_memmap_p + | 6233 | phba->sli4_hba.conf_regs_memmap_p + |
6234 | LPFC_CTL_PORT_SEM_OFFSET; | 6234 | LPFC_CTL_PORT_SEM_OFFSET; |
6235 | phba->sli4_hba.RQDBregaddr = | 6235 | phba->sli4_hba.RQDBregaddr = |
6236 | phba->sli4_hba.conf_regs_memmap_p + LPFC_RQ_DOORBELL; | 6236 | phba->sli4_hba.conf_regs_memmap_p + |
6237 | LPFC_ULP0_RQ_DOORBELL; | ||
6237 | phba->sli4_hba.WQDBregaddr = | 6238 | phba->sli4_hba.WQDBregaddr = |
6238 | phba->sli4_hba.conf_regs_memmap_p + LPFC_WQ_DOORBELL; | 6239 | phba->sli4_hba.conf_regs_memmap_p + |
6240 | LPFC_ULP0_WQ_DOORBELL; | ||
6239 | phba->sli4_hba.EQCQDBregaddr = | 6241 | phba->sli4_hba.EQCQDBregaddr = |
6240 | phba->sli4_hba.conf_regs_memmap_p + LPFC_EQCQ_DOORBELL; | 6242 | phba->sli4_hba.conf_regs_memmap_p + LPFC_EQCQ_DOORBELL; |
6241 | phba->sli4_hba.MQDBregaddr = | 6243 | phba->sli4_hba.MQDBregaddr = |
@@ -6289,9 +6291,11 @@ lpfc_sli4_bar2_register_memmap(struct lpfc_hba *phba, uint32_t vf) | |||
6289 | return -ENODEV; | 6291 | return -ENODEV; |
6290 | 6292 | ||
6291 | phba->sli4_hba.RQDBregaddr = (phba->sli4_hba.drbl_regs_memmap_p + | 6293 | phba->sli4_hba.RQDBregaddr = (phba->sli4_hba.drbl_regs_memmap_p + |
6292 | vf * LPFC_VFR_PAGE_SIZE + LPFC_RQ_DOORBELL); | 6294 | vf * LPFC_VFR_PAGE_SIZE + |
6295 | LPFC_ULP0_RQ_DOORBELL); | ||
6293 | phba->sli4_hba.WQDBregaddr = (phba->sli4_hba.drbl_regs_memmap_p + | 6296 | phba->sli4_hba.WQDBregaddr = (phba->sli4_hba.drbl_regs_memmap_p + |
6294 | vf * LPFC_VFR_PAGE_SIZE + LPFC_WQ_DOORBELL); | 6297 | vf * LPFC_VFR_PAGE_SIZE + |
6298 | LPFC_ULP0_WQ_DOORBELL); | ||
6295 | phba->sli4_hba.EQCQDBregaddr = (phba->sli4_hba.drbl_regs_memmap_p + | 6299 | phba->sli4_hba.EQCQDBregaddr = (phba->sli4_hba.drbl_regs_memmap_p + |
6296 | vf * LPFC_VFR_PAGE_SIZE + LPFC_EQCQ_DOORBELL); | 6300 | vf * LPFC_VFR_PAGE_SIZE + LPFC_EQCQ_DOORBELL); |
6297 | phba->sli4_hba.MQDBregaddr = (phba->sli4_hba.drbl_regs_memmap_p + | 6301 | phba->sli4_hba.MQDBregaddr = (phba->sli4_hba.drbl_regs_memmap_p + |
@@ -6987,6 +6991,19 @@ lpfc_sli4_queue_destroy(struct lpfc_hba *phba) | |||
6987 | phba->sli4_hba.fcp_wq = NULL; | 6991 | phba->sli4_hba.fcp_wq = NULL; |
6988 | } | 6992 | } |
6989 | 6993 | ||
6994 | if (phba->pci_bar0_memmap_p) { | ||
6995 | iounmap(phba->pci_bar0_memmap_p); | ||
6996 | phba->pci_bar0_memmap_p = NULL; | ||
6997 | } | ||
6998 | if (phba->pci_bar2_memmap_p) { | ||
6999 | iounmap(phba->pci_bar2_memmap_p); | ||
7000 | phba->pci_bar2_memmap_p = NULL; | ||
7001 | } | ||
7002 | if (phba->pci_bar4_memmap_p) { | ||
7003 | iounmap(phba->pci_bar4_memmap_p); | ||
7004 | phba->pci_bar4_memmap_p = NULL; | ||
7005 | } | ||
7006 | |||
6990 | /* Release FCP CQ mapping array */ | 7007 | /* Release FCP CQ mapping array */ |
6991 | if (phba->sli4_hba.fcp_cq_map != NULL) { | 7008 | if (phba->sli4_hba.fcp_cq_map != NULL) { |
6992 | kfree(phba->sli4_hba.fcp_cq_map); | 7009 | kfree(phba->sli4_hba.fcp_cq_map); |
@@ -7050,6 +7067,53 @@ lpfc_sli4_queue_setup(struct lpfc_hba *phba) | |||
7050 | int rc = -ENOMEM; | 7067 | int rc = -ENOMEM; |
7051 | int fcp_eqidx, fcp_cqidx, fcp_wqidx; | 7068 | int fcp_eqidx, fcp_cqidx, fcp_wqidx; |
7052 | int fcp_cq_index = 0; | 7069 | int fcp_cq_index = 0; |
7070 | uint32_t shdr_status, shdr_add_status; | ||
7071 | union lpfc_sli4_cfg_shdr *shdr; | ||
7072 | LPFC_MBOXQ_t *mboxq; | ||
7073 | uint32_t length; | ||
7074 | |||
7075 | /* Check for dual-ULP support */ | ||
7076 | mboxq = (LPFC_MBOXQ_t *)mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL); | ||
7077 | if (!mboxq) { | ||
7078 | lpfc_printf_log(phba, KERN_ERR, LOG_INIT, | ||
7079 | "3249 Unable to allocate memory for " | ||
7080 | "QUERY_FW_CFG mailbox command\n"); | ||
7081 | return -ENOMEM; | ||
7082 | } | ||
7083 | length = (sizeof(struct lpfc_mbx_query_fw_config) - | ||
7084 | sizeof(struct lpfc_sli4_cfg_mhdr)); | ||
7085 | lpfc_sli4_config(phba, mboxq, LPFC_MBOX_SUBSYSTEM_COMMON, | ||
7086 | LPFC_MBOX_OPCODE_QUERY_FW_CFG, | ||
7087 | length, LPFC_SLI4_MBX_EMBED); | ||
7088 | |||
7089 | rc = lpfc_sli_issue_mbox(phba, mboxq, MBX_POLL); | ||
7090 | |||
7091 | shdr = (union lpfc_sli4_cfg_shdr *) | ||
7092 | &mboxq->u.mqe.un.sli4_config.header.cfg_shdr; | ||
7093 | shdr_status = bf_get(lpfc_mbox_hdr_status, &shdr->response); | ||
7094 | shdr_add_status = bf_get(lpfc_mbox_hdr_add_status, &shdr->response); | ||
7095 | if (shdr_status || shdr_add_status || rc) { | ||
7096 | lpfc_printf_log(phba, KERN_ERR, LOG_INIT, | ||
7097 | "3250 QUERY_FW_CFG mailbox failed with status " | ||
7098 | "x%x add_status x%x, mbx status x%x\n", | ||
7099 | shdr_status, shdr_add_status, rc); | ||
7100 | if (rc != MBX_TIMEOUT) | ||
7101 | mempool_free(mboxq, phba->mbox_mem_pool); | ||
7102 | rc = -ENXIO; | ||
7103 | goto out_error; | ||
7104 | } | ||
7105 | |||
7106 | phba->sli4_hba.fw_func_mode = | ||
7107 | mboxq->u.mqe.un.query_fw_cfg.rsp.function_mode; | ||
7108 | phba->sli4_hba.ulp0_mode = mboxq->u.mqe.un.query_fw_cfg.rsp.ulp0_mode; | ||
7109 | phba->sli4_hba.ulp1_mode = mboxq->u.mqe.un.query_fw_cfg.rsp.ulp1_mode; | ||
7110 | lpfc_printf_log(phba, KERN_INFO, LOG_INIT, | ||
7111 | "3251 QUERY_FW_CFG: func_mode:x%x, ulp0_mode:x%x, " | ||
7112 | "ulp1_mode:x%x\n", phba->sli4_hba.fw_func_mode, | ||
7113 | phba->sli4_hba.ulp0_mode, phba->sli4_hba.ulp1_mode); | ||
7114 | |||
7115 | if (rc != MBX_TIMEOUT) | ||
7116 | mempool_free(mboxq, phba->mbox_mem_pool); | ||
7053 | 7117 | ||
7054 | /* | 7118 | /* |
7055 | * Set up HBA Event Queues (EQs) | 7119 | * Set up HBA Event Queues (EQs) |
diff --git a/drivers/scsi/lpfc/lpfc_sli.c b/drivers/scsi/lpfc/lpfc_sli.c index c997b919b6fe..0988b320d317 100644 --- a/drivers/scsi/lpfc/lpfc_sli.c +++ b/drivers/scsi/lpfc/lpfc_sli.c | |||
@@ -124,10 +124,17 @@ lpfc_sli4_wq_put(struct lpfc_queue *q, union lpfc_wqe *wqe) | |||
124 | 124 | ||
125 | /* Ring Doorbell */ | 125 | /* Ring Doorbell */ |
126 | doorbell.word0 = 0; | 126 | doorbell.word0 = 0; |
127 | bf_set(lpfc_wq_doorbell_num_posted, &doorbell, 1); | 127 | if (q->db_format == LPFC_DB_LIST_FORMAT) { |
128 | bf_set(lpfc_wq_doorbell_index, &doorbell, host_index); | 128 | bf_set(lpfc_wq_db_list_fm_num_posted, &doorbell, 1); |
129 | bf_set(lpfc_wq_doorbell_id, &doorbell, q->queue_id); | 129 | bf_set(lpfc_wq_db_list_fm_index, &doorbell, host_index); |
130 | writel(doorbell.word0, q->phba->sli4_hba.WQDBregaddr); | 130 | bf_set(lpfc_wq_db_list_fm_id, &doorbell, q->queue_id); |
131 | } else if (q->db_format == LPFC_DB_RING_FORMAT) { | ||
132 | bf_set(lpfc_wq_db_ring_fm_num_posted, &doorbell, 1); | ||
133 | bf_set(lpfc_wq_db_ring_fm_id, &doorbell, q->queue_id); | ||
134 | } else { | ||
135 | return -EINVAL; | ||
136 | } | ||
137 | writel(doorbell.word0, q->db_regaddr); | ||
131 | 138 | ||
132 | return 0; | 139 | return 0; |
133 | } | 140 | } |
@@ -456,10 +463,20 @@ lpfc_sli4_rq_put(struct lpfc_queue *hq, struct lpfc_queue *dq, | |||
456 | /* Ring The Header Receive Queue Doorbell */ | 463 | /* Ring The Header Receive Queue Doorbell */ |
457 | if (!(hq->host_index % hq->entry_repost)) { | 464 | if (!(hq->host_index % hq->entry_repost)) { |
458 | doorbell.word0 = 0; | 465 | doorbell.word0 = 0; |
459 | bf_set(lpfc_rq_doorbell_num_posted, &doorbell, | 466 | if (hq->db_format == LPFC_DB_RING_FORMAT) { |
460 | hq->entry_repost); | 467 | bf_set(lpfc_rq_db_ring_fm_num_posted, &doorbell, |
461 | bf_set(lpfc_rq_doorbell_id, &doorbell, hq->queue_id); | 468 | hq->entry_repost); |
462 | writel(doorbell.word0, hq->phba->sli4_hba.RQDBregaddr); | 469 | bf_set(lpfc_rq_db_ring_fm_id, &doorbell, hq->queue_id); |
470 | } else if (hq->db_format == LPFC_DB_LIST_FORMAT) { | ||
471 | bf_set(lpfc_rq_db_list_fm_num_posted, &doorbell, | ||
472 | hq->entry_repost); | ||
473 | bf_set(lpfc_rq_db_list_fm_index, &doorbell, | ||
474 | hq->host_index); | ||
475 | bf_set(lpfc_rq_db_list_fm_id, &doorbell, hq->queue_id); | ||
476 | } else { | ||
477 | return -EINVAL; | ||
478 | } | ||
479 | writel(doorbell.word0, hq->db_regaddr); | ||
463 | } | 480 | } |
464 | return put_index; | 481 | return put_index; |
465 | } | 482 | } |
@@ -4939,7 +4956,7 @@ out_free_mboxq: | |||
4939 | static void | 4956 | static void |
4940 | lpfc_sli4_arm_cqeq_intr(struct lpfc_hba *phba) | 4957 | lpfc_sli4_arm_cqeq_intr(struct lpfc_hba *phba) |
4941 | { | 4958 | { |
4942 | uint8_t fcp_eqidx; | 4959 | int fcp_eqidx; |
4943 | 4960 | ||
4944 | lpfc_sli4_cq_release(phba->sli4_hba.mbx_cq, LPFC_QUEUE_REARM); | 4961 | lpfc_sli4_cq_release(phba->sli4_hba.mbx_cq, LPFC_QUEUE_REARM); |
4945 | lpfc_sli4_cq_release(phba->sli4_hba.els_cq, LPFC_QUEUE_REARM); | 4962 | lpfc_sli4_cq_release(phba->sli4_hba.els_cq, LPFC_QUEUE_REARM); |
@@ -11867,7 +11884,7 @@ lpfc_sli4_hba_intr_handler(int irq, void *dev_id) | |||
11867 | struct lpfc_eqe *eqe; | 11884 | struct lpfc_eqe *eqe; |
11868 | unsigned long iflag; | 11885 | unsigned long iflag; |
11869 | int ecount = 0; | 11886 | int ecount = 0; |
11870 | uint32_t fcp_eqidx; | 11887 | int fcp_eqidx; |
11871 | 11888 | ||
11872 | /* Get the driver's phba structure from the dev_id */ | 11889 | /* Get the driver's phba structure from the dev_id */ |
11873 | fcp_eq_hdl = (struct lpfc_fcp_eq_hdl *)dev_id; | 11890 | fcp_eq_hdl = (struct lpfc_fcp_eq_hdl *)dev_id; |
@@ -11969,7 +11986,7 @@ lpfc_sli4_intr_handler(int irq, void *dev_id) | |||
11969 | struct lpfc_hba *phba; | 11986 | struct lpfc_hba *phba; |
11970 | irqreturn_t hba_irq_rc; | 11987 | irqreturn_t hba_irq_rc; |
11971 | bool hba_handled = false; | 11988 | bool hba_handled = false; |
11972 | uint32_t fcp_eqidx; | 11989 | int fcp_eqidx; |
11973 | 11990 | ||
11974 | /* Get the driver's phba structure from the dev_id */ | 11991 | /* Get the driver's phba structure from the dev_id */ |
11975 | phba = (struct lpfc_hba *)dev_id; | 11992 | phba = (struct lpfc_hba *)dev_id; |
@@ -12091,6 +12108,54 @@ out_fail: | |||
12091 | } | 12108 | } |
12092 | 12109 | ||
12093 | /** | 12110 | /** |
12111 | * lpfc_dual_chute_pci_bar_map - Map pci base address register to host memory | ||
12112 | * @phba: HBA structure that indicates port to create a queue on. | ||
12113 | * @pci_barset: PCI BAR set flag. | ||
12114 | * | ||
12115 | * This function shall perform iomap of the specified PCI BAR address to host | ||
12116 | * memory address if not already done so and return it. The returned host | ||
12117 | * memory address can be NULL. | ||
12118 | */ | ||
12119 | static void __iomem * | ||
12120 | lpfc_dual_chute_pci_bar_map(struct lpfc_hba *phba, uint16_t pci_barset) | ||
12121 | { | ||
12122 | struct pci_dev *pdev; | ||
12123 | unsigned long bar_map, bar_map_len; | ||
12124 | |||
12125 | if (!phba->pcidev) | ||
12126 | return NULL; | ||
12127 | else | ||
12128 | pdev = phba->pcidev; | ||
12129 | |||
12130 | switch (pci_barset) { | ||
12131 | case WQ_PCI_BAR_0_AND_1: | ||
12132 | if (!phba->pci_bar0_memmap_p) { | ||
12133 | bar_map = pci_resource_start(pdev, PCI_64BIT_BAR0); | ||
12134 | bar_map_len = pci_resource_len(pdev, PCI_64BIT_BAR0); | ||
12135 | phba->pci_bar0_memmap_p = ioremap(bar_map, bar_map_len); | ||
12136 | } | ||
12137 | return phba->pci_bar0_memmap_p; | ||
12138 | case WQ_PCI_BAR_2_AND_3: | ||
12139 | if (!phba->pci_bar2_memmap_p) { | ||
12140 | bar_map = pci_resource_start(pdev, PCI_64BIT_BAR2); | ||
12141 | bar_map_len = pci_resource_len(pdev, PCI_64BIT_BAR2); | ||
12142 | phba->pci_bar2_memmap_p = ioremap(bar_map, bar_map_len); | ||
12143 | } | ||
12144 | return phba->pci_bar2_memmap_p; | ||
12145 | case WQ_PCI_BAR_4_AND_5: | ||
12146 | if (!phba->pci_bar4_memmap_p) { | ||
12147 | bar_map = pci_resource_start(pdev, PCI_64BIT_BAR4); | ||
12148 | bar_map_len = pci_resource_len(pdev, PCI_64BIT_BAR4); | ||
12149 | phba->pci_bar4_memmap_p = ioremap(bar_map, bar_map_len); | ||
12150 | } | ||
12151 | return phba->pci_bar4_memmap_p; | ||
12152 | default: | ||
12153 | break; | ||
12154 | } | ||
12155 | return NULL; | ||
12156 | } | ||
12157 | |||
12158 | /** | ||
12094 | * lpfc_modify_fcp_eq_delay - Modify Delay Multiplier on FCP EQs | 12159 | * lpfc_modify_fcp_eq_delay - Modify Delay Multiplier on FCP EQs |
12095 | * @phba: HBA structure that indicates port to create a queue on. | 12160 | * @phba: HBA structure that indicates port to create a queue on. |
12096 | * @startq: The starting FCP EQ to modify | 12161 | * @startq: The starting FCP EQ to modify |
@@ -12667,6 +12732,9 @@ lpfc_wq_create(struct lpfc_hba *phba, struct lpfc_queue *wq, | |||
12667 | union lpfc_sli4_cfg_shdr *shdr; | 12732 | union lpfc_sli4_cfg_shdr *shdr; |
12668 | uint32_t hw_page_size = phba->sli4_hba.pc_sli4_params.if_page_sz; | 12733 | uint32_t hw_page_size = phba->sli4_hba.pc_sli4_params.if_page_sz; |
12669 | struct dma_address *page; | 12734 | struct dma_address *page; |
12735 | void __iomem *bar_memmap_p; | ||
12736 | uint32_t db_offset; | ||
12737 | uint16_t pci_barset; | ||
12670 | 12738 | ||
12671 | /* sanity check on queue memory */ | 12739 | /* sanity check on queue memory */ |
12672 | if (!wq || !cq) | 12740 | if (!wq || !cq) |
@@ -12690,6 +12758,7 @@ lpfc_wq_create(struct lpfc_hba *phba, struct lpfc_queue *wq, | |||
12690 | cq->queue_id); | 12758 | cq->queue_id); |
12691 | bf_set(lpfc_mbox_hdr_version, &shdr->request, | 12759 | bf_set(lpfc_mbox_hdr_version, &shdr->request, |
12692 | phba->sli4_hba.pc_sli4_params.wqv); | 12760 | phba->sli4_hba.pc_sli4_params.wqv); |
12761 | |||
12693 | if (phba->sli4_hba.pc_sli4_params.wqv == LPFC_Q_CREATE_VERSION_1) { | 12762 | if (phba->sli4_hba.pc_sli4_params.wqv == LPFC_Q_CREATE_VERSION_1) { |
12694 | bf_set(lpfc_mbx_wq_create_wqe_count, &wq_create->u.request_1, | 12763 | bf_set(lpfc_mbx_wq_create_wqe_count, &wq_create->u.request_1, |
12695 | wq->entry_count); | 12764 | wq->entry_count); |
@@ -12717,6 +12786,10 @@ lpfc_wq_create(struct lpfc_hba *phba, struct lpfc_queue *wq, | |||
12717 | page[dmabuf->buffer_tag].addr_lo = putPaddrLow(dmabuf->phys); | 12786 | page[dmabuf->buffer_tag].addr_lo = putPaddrLow(dmabuf->phys); |
12718 | page[dmabuf->buffer_tag].addr_hi = putPaddrHigh(dmabuf->phys); | 12787 | page[dmabuf->buffer_tag].addr_hi = putPaddrHigh(dmabuf->phys); |
12719 | } | 12788 | } |
12789 | |||
12790 | if (phba->sli4_hba.fw_func_mode & LPFC_DUA_MODE) | ||
12791 | bf_set(lpfc_mbx_wq_create_dua, &wq_create->u.request, 1); | ||
12792 | |||
12720 | rc = lpfc_sli_issue_mbox(phba, mbox, MBX_POLL); | 12793 | rc = lpfc_sli_issue_mbox(phba, mbox, MBX_POLL); |
12721 | /* The IOCTL status is embedded in the mailbox subheader. */ | 12794 | /* The IOCTL status is embedded in the mailbox subheader. */ |
12722 | shdr_status = bf_get(lpfc_mbox_hdr_status, &shdr->response); | 12795 | shdr_status = bf_get(lpfc_mbox_hdr_status, &shdr->response); |
@@ -12734,6 +12807,47 @@ lpfc_wq_create(struct lpfc_hba *phba, struct lpfc_queue *wq, | |||
12734 | status = -ENXIO; | 12807 | status = -ENXIO; |
12735 | goto out; | 12808 | goto out; |
12736 | } | 12809 | } |
12810 | if (phba->sli4_hba.fw_func_mode & LPFC_DUA_MODE) { | ||
12811 | wq->db_format = bf_get(lpfc_mbx_wq_create_db_format, | ||
12812 | &wq_create->u.response); | ||
12813 | if ((wq->db_format != LPFC_DB_LIST_FORMAT) && | ||
12814 | (wq->db_format != LPFC_DB_RING_FORMAT)) { | ||
12815 | lpfc_printf_log(phba, KERN_ERR, LOG_INIT, | ||
12816 | "3265 WQ[%d] doorbell format not " | ||
12817 | "supported: x%x\n", wq->queue_id, | ||
12818 | wq->db_format); | ||
12819 | status = -EINVAL; | ||
12820 | goto out; | ||
12821 | } | ||
12822 | pci_barset = bf_get(lpfc_mbx_wq_create_bar_set, | ||
12823 | &wq_create->u.response); | ||
12824 | bar_memmap_p = lpfc_dual_chute_pci_bar_map(phba, pci_barset); | ||
12825 | if (!bar_memmap_p) { | ||
12826 | lpfc_printf_log(phba, KERN_ERR, LOG_INIT, | ||
12827 | "3263 WQ[%d] failed to memmap pci " | ||
12828 | "barset:x%x\n", wq->queue_id, | ||
12829 | pci_barset); | ||
12830 | status = -ENOMEM; | ||
12831 | goto out; | ||
12832 | } | ||
12833 | db_offset = wq_create->u.response.doorbell_offset; | ||
12834 | if ((db_offset != LPFC_ULP0_WQ_DOORBELL) && | ||
12835 | (db_offset != LPFC_ULP1_WQ_DOORBELL)) { | ||
12836 | lpfc_printf_log(phba, KERN_ERR, LOG_INIT, | ||
12837 | "3252 WQ[%d] doorbell offset not " | ||
12838 | "supported: x%x\n", wq->queue_id, | ||
12839 | db_offset); | ||
12840 | status = -EINVAL; | ||
12841 | goto out; | ||
12842 | } | ||
12843 | wq->db_regaddr = bar_memmap_p + db_offset; | ||
12844 | lpfc_printf_log(phba, KERN_INFO, LOG_INIT, | ||
12845 | "3264 WQ[%d]: barset:x%x, offset:x%x\n", | ||
12846 | wq->queue_id, pci_barset, db_offset); | ||
12847 | } else { | ||
12848 | wq->db_format = LPFC_DB_LIST_FORMAT; | ||
12849 | wq->db_regaddr = phba->sli4_hba.WQDBregaddr; | ||
12850 | } | ||
12737 | wq->type = LPFC_WQ; | 12851 | wq->type = LPFC_WQ; |
12738 | wq->assoc_qid = cq->queue_id; | 12852 | wq->assoc_qid = cq->queue_id; |
12739 | wq->subtype = subtype; | 12853 | wq->subtype = subtype; |
@@ -12810,6 +12924,9 @@ lpfc_rq_create(struct lpfc_hba *phba, struct lpfc_queue *hrq, | |||
12810 | uint32_t shdr_status, shdr_add_status; | 12924 | uint32_t shdr_status, shdr_add_status; |
12811 | union lpfc_sli4_cfg_shdr *shdr; | 12925 | union lpfc_sli4_cfg_shdr *shdr; |
12812 | uint32_t hw_page_size = phba->sli4_hba.pc_sli4_params.if_page_sz; | 12926 | uint32_t hw_page_size = phba->sli4_hba.pc_sli4_params.if_page_sz; |
12927 | void __iomem *bar_memmap_p; | ||
12928 | uint32_t db_offset; | ||
12929 | uint16_t pci_barset; | ||
12813 | 12930 | ||
12814 | /* sanity check on queue memory */ | 12931 | /* sanity check on queue memory */ |
12815 | if (!hrq || !drq || !cq) | 12932 | if (!hrq || !drq || !cq) |
@@ -12888,6 +13005,9 @@ lpfc_rq_create(struct lpfc_hba *phba, struct lpfc_queue *hrq, | |||
12888 | rq_create->u.request.page[dmabuf->buffer_tag].addr_hi = | 13005 | rq_create->u.request.page[dmabuf->buffer_tag].addr_hi = |
12889 | putPaddrHigh(dmabuf->phys); | 13006 | putPaddrHigh(dmabuf->phys); |
12890 | } | 13007 | } |
13008 | if (phba->sli4_hba.fw_func_mode & LPFC_DUA_MODE) | ||
13009 | bf_set(lpfc_mbx_rq_create_dua, &rq_create->u.request, 1); | ||
13010 | |||
12891 | rc = lpfc_sli_issue_mbox(phba, mbox, MBX_POLL); | 13011 | rc = lpfc_sli_issue_mbox(phba, mbox, MBX_POLL); |
12892 | /* The IOCTL status is embedded in the mailbox subheader. */ | 13012 | /* The IOCTL status is embedded in the mailbox subheader. */ |
12893 | shdr_status = bf_get(lpfc_mbox_hdr_status, &shdr->response); | 13013 | shdr_status = bf_get(lpfc_mbox_hdr_status, &shdr->response); |
@@ -12905,6 +13025,50 @@ lpfc_rq_create(struct lpfc_hba *phba, struct lpfc_queue *hrq, | |||
12905 | status = -ENXIO; | 13025 | status = -ENXIO; |
12906 | goto out; | 13026 | goto out; |
12907 | } | 13027 | } |
13028 | |||
13029 | if (phba->sli4_hba.fw_func_mode & LPFC_DUA_MODE) { | ||
13030 | hrq->db_format = bf_get(lpfc_mbx_rq_create_db_format, | ||
13031 | &rq_create->u.response); | ||
13032 | if ((hrq->db_format != LPFC_DB_LIST_FORMAT) && | ||
13033 | (hrq->db_format != LPFC_DB_RING_FORMAT)) { | ||
13034 | lpfc_printf_log(phba, KERN_ERR, LOG_INIT, | ||
13035 | "3262 RQ [%d] doorbell format not " | ||
13036 | "supported: x%x\n", hrq->queue_id, | ||
13037 | hrq->db_format); | ||
13038 | status = -EINVAL; | ||
13039 | goto out; | ||
13040 | } | ||
13041 | |||
13042 | pci_barset = bf_get(lpfc_mbx_rq_create_bar_set, | ||
13043 | &rq_create->u.response); | ||
13044 | bar_memmap_p = lpfc_dual_chute_pci_bar_map(phba, pci_barset); | ||
13045 | if (!bar_memmap_p) { | ||
13046 | lpfc_printf_log(phba, KERN_ERR, LOG_INIT, | ||
13047 | "3269 RQ[%d] failed to memmap pci " | ||
13048 | "barset:x%x\n", hrq->queue_id, | ||
13049 | pci_barset); | ||
13050 | status = -ENOMEM; | ||
13051 | goto out; | ||
13052 | } | ||
13053 | |||
13054 | db_offset = rq_create->u.response.doorbell_offset; | ||
13055 | if ((db_offset != LPFC_ULP0_RQ_DOORBELL) && | ||
13056 | (db_offset != LPFC_ULP1_RQ_DOORBELL)) { | ||
13057 | lpfc_printf_log(phba, KERN_ERR, LOG_INIT, | ||
13058 | "3270 RQ[%d] doorbell offset not " | ||
13059 | "supported: x%x\n", hrq->queue_id, | ||
13060 | db_offset); | ||
13061 | status = -EINVAL; | ||
13062 | goto out; | ||
13063 | } | ||
13064 | hrq->db_regaddr = bar_memmap_p + db_offset; | ||
13065 | lpfc_printf_log(phba, KERN_INFO, LOG_INIT, | ||
13066 | "3266 RQ[qid:%d]: barset:x%x, offset:x%x\n", | ||
13067 | hrq->queue_id, pci_barset, db_offset); | ||
13068 | } else { | ||
13069 | hrq->db_format = LPFC_DB_RING_FORMAT; | ||
13070 | hrq->db_regaddr = phba->sli4_hba.RQDBregaddr; | ||
13071 | } | ||
12908 | hrq->type = LPFC_HRQ; | 13072 | hrq->type = LPFC_HRQ; |
12909 | hrq->assoc_qid = cq->queue_id; | 13073 | hrq->assoc_qid = cq->queue_id; |
12910 | hrq->subtype = subtype; | 13074 | hrq->subtype = subtype; |
@@ -12970,6 +13134,8 @@ lpfc_rq_create(struct lpfc_hba *phba, struct lpfc_queue *hrq, | |||
12970 | rq_create->u.request.page[dmabuf->buffer_tag].addr_hi = | 13134 | rq_create->u.request.page[dmabuf->buffer_tag].addr_hi = |
12971 | putPaddrHigh(dmabuf->phys); | 13135 | putPaddrHigh(dmabuf->phys); |
12972 | } | 13136 | } |
13137 | if (phba->sli4_hba.fw_func_mode & LPFC_DUA_MODE) | ||
13138 | bf_set(lpfc_mbx_rq_create_dua, &rq_create->u.request, 1); | ||
12973 | rc = lpfc_sli_issue_mbox(phba, mbox, MBX_POLL); | 13139 | rc = lpfc_sli_issue_mbox(phba, mbox, MBX_POLL); |
12974 | /* The IOCTL status is embedded in the mailbox subheader. */ | 13140 | /* The IOCTL status is embedded in the mailbox subheader. */ |
12975 | shdr = (union lpfc_sli4_cfg_shdr *) &rq_create->header.cfg_shdr; | 13141 | shdr = (union lpfc_sli4_cfg_shdr *) &rq_create->header.cfg_shdr; |
diff --git a/drivers/scsi/lpfc/lpfc_sli4.h b/drivers/scsi/lpfc/lpfc_sli4.h index 44c427a45d66..be02b59ea279 100644 --- a/drivers/scsi/lpfc/lpfc_sli4.h +++ b/drivers/scsi/lpfc/lpfc_sli4.h | |||
@@ -139,6 +139,10 @@ struct lpfc_queue { | |||
139 | 139 | ||
140 | struct lpfc_sli_ring *pring; /* ptr to io ring associated with q */ | 140 | struct lpfc_sli_ring *pring; /* ptr to io ring associated with q */ |
141 | 141 | ||
142 | uint16_t db_format; | ||
143 | #define LPFC_DB_RING_FORMAT 0x01 | ||
144 | #define LPFC_DB_LIST_FORMAT 0x02 | ||
145 | void __iomem *db_regaddr; | ||
142 | /* For q stats */ | 146 | /* For q stats */ |
143 | uint32_t q_cnt_1; | 147 | uint32_t q_cnt_1; |
144 | uint32_t q_cnt_2; | 148 | uint32_t q_cnt_2; |
@@ -508,6 +512,10 @@ struct lpfc_sli4_hba { | |||
508 | struct lpfc_queue *hdr_rq; /* Slow-path Header Receive queue */ | 512 | struct lpfc_queue *hdr_rq; /* Slow-path Header Receive queue */ |
509 | struct lpfc_queue *dat_rq; /* Slow-path Data Receive queue */ | 513 | struct lpfc_queue *dat_rq; /* Slow-path Data Receive queue */ |
510 | 514 | ||
515 | uint8_t fw_func_mode; /* FW function protocol mode */ | ||
516 | uint32_t ulp0_mode; /* ULP0 protocol mode */ | ||
517 | uint32_t ulp1_mode; /* ULP1 protocol mode */ | ||
518 | |||
511 | /* Setup information for various queue parameters */ | 519 | /* Setup information for various queue parameters */ |
512 | int eq_esize; | 520 | int eq_esize; |
513 | int eq_ecount; | 521 | int eq_ecount; |