diff options
author | James Smart <James.Smart@Emulex.Com> | 2009-10-02 15:16:45 -0400 |
---|---|---|
committer | James Bottomley <James.Bottomley@suse.de> | 2009-12-04 13:01:40 -0500 |
commit | 6669f9bb902b8c3f5e33cb8c32c8c0eec6ed68ed (patch) | |
tree | e143e916abc71ff3c7edb7a5508d480391efc1ee /drivers/scsi/lpfc | |
parent | 4d9ab994e214d35107017c342aca42477b137316 (diff) |
[SCSI] lpfc 8.3.5: fix VPI registration, error clean up and add support for vlink events
This patch includes the following fixes and new features:
- Fix mask size for CT field in WQE
- Fix VPI base not used when unregistering VPI on port 1.
- Fix UNREG_VPI mailbox command to unreg the correct VPI
- Fixed Check for aborted els command
- Fix error when trying to load driver with wrong firmware on FCoE HBA.
- Fix bug with probe_one routines not putting the Scsi_Host back upon error
- Add support for Clear Virtual Link Async Events
- Add support for unsolicited CT exchange sequence abort
- Add 0x0714 OCeXXXXX PCI ID
Signed-off-by: James Smart <james.smart@emulex.com>
Signed-off-by: James Bottomley <James.Bottomley@suse.de>
Diffstat (limited to 'drivers/scsi/lpfc')
-rw-r--r-- | drivers/scsi/lpfc/lpfc_crtn.h | 5 | ||||
-rw-r--r-- | drivers/scsi/lpfc/lpfc_ct.c | 34 | ||||
-rw-r--r-- | drivers/scsi/lpfc/lpfc_els.c | 12 | ||||
-rw-r--r-- | drivers/scsi/lpfc/lpfc_hbadisc.c | 2 | ||||
-rw-r--r-- | drivers/scsi/lpfc/lpfc_hw.h | 10 | ||||
-rw-r--r-- | drivers/scsi/lpfc/lpfc_hw4.h | 89 | ||||
-rw-r--r-- | drivers/scsi/lpfc/lpfc_init.c | 107 | ||||
-rw-r--r-- | drivers/scsi/lpfc/lpfc_mbox.c | 12 | ||||
-rw-r--r-- | drivers/scsi/lpfc/lpfc_sli.c | 267 | ||||
-rw-r--r-- | drivers/scsi/lpfc/lpfc_sli.h | 2 | ||||
-rw-r--r-- | drivers/scsi/lpfc/lpfc_sli4.h | 5 |
11 files changed, 498 insertions, 47 deletions
diff --git a/drivers/scsi/lpfc/lpfc_crtn.h b/drivers/scsi/lpfc/lpfc_crtn.h index 4438f8665a4a..0d450ae3a2d4 100644 --- a/drivers/scsi/lpfc/lpfc_crtn.h +++ b/drivers/scsi/lpfc/lpfc_crtn.h | |||
@@ -144,6 +144,8 @@ void lpfc_hb_timeout_handler(struct lpfc_hba *); | |||
144 | 144 | ||
145 | void lpfc_ct_unsol_event(struct lpfc_hba *, struct lpfc_sli_ring *, | 145 | void lpfc_ct_unsol_event(struct lpfc_hba *, struct lpfc_sli_ring *, |
146 | struct lpfc_iocbq *); | 146 | struct lpfc_iocbq *); |
147 | void lpfc_sli4_ct_abort_unsol_event(struct lpfc_hba *, struct lpfc_sli_ring *, | ||
148 | struct lpfc_iocbq *); | ||
147 | int lpfc_ns_cmd(struct lpfc_vport *, int, uint8_t, uint32_t); | 149 | int lpfc_ns_cmd(struct lpfc_vport *, int, uint8_t, uint32_t); |
148 | int lpfc_fdmi_cmd(struct lpfc_vport *, struct lpfc_nodelist *, int); | 150 | int lpfc_fdmi_cmd(struct lpfc_vport *, struct lpfc_nodelist *, int); |
149 | void lpfc_fdmi_tmo(unsigned long); | 151 | void lpfc_fdmi_tmo(unsigned long); |
@@ -188,7 +190,7 @@ int lpfc_mbox_tmo_val(struct lpfc_hba *, int); | |||
188 | void lpfc_init_vfi(struct lpfcMboxq *, struct lpfc_vport *); | 190 | void lpfc_init_vfi(struct lpfcMboxq *, struct lpfc_vport *); |
189 | void lpfc_reg_vfi(struct lpfcMboxq *, struct lpfc_vport *, dma_addr_t); | 191 | void lpfc_reg_vfi(struct lpfcMboxq *, struct lpfc_vport *, dma_addr_t); |
190 | void lpfc_init_vpi(struct lpfc_hba *, struct lpfcMboxq *, uint16_t); | 192 | void lpfc_init_vpi(struct lpfc_hba *, struct lpfcMboxq *, uint16_t); |
191 | void lpfc_unreg_vfi(struct lpfcMboxq *, uint16_t); | 193 | void lpfc_unreg_vfi(struct lpfcMboxq *, struct lpfc_vport *); |
192 | void lpfc_reg_fcfi(struct lpfc_hba *, struct lpfcMboxq *); | 194 | void lpfc_reg_fcfi(struct lpfc_hba *, struct lpfcMboxq *); |
193 | void lpfc_unreg_fcfi(struct lpfcMboxq *, uint16_t); | 195 | void lpfc_unreg_fcfi(struct lpfcMboxq *, uint16_t); |
194 | void lpfc_resume_rpi(struct lpfcMboxq *, struct lpfc_nodelist *); | 196 | void lpfc_resume_rpi(struct lpfcMboxq *, struct lpfc_nodelist *); |
@@ -361,6 +363,7 @@ void lpfc_stop_port(struct lpfc_hba *); | |||
361 | void lpfc_parse_fcoe_conf(struct lpfc_hba *, uint8_t *, uint32_t); | 363 | void lpfc_parse_fcoe_conf(struct lpfc_hba *, uint8_t *, uint32_t); |
362 | int lpfc_parse_vpd(struct lpfc_hba *, uint8_t *, int); | 364 | int lpfc_parse_vpd(struct lpfc_hba *, uint8_t *, int); |
363 | void lpfc_start_fdiscs(struct lpfc_hba *phba); | 365 | void lpfc_start_fdiscs(struct lpfc_hba *phba); |
366 | struct lpfc_vport *lpfc_find_vport_by_vpid(struct lpfc_hba *, uint16_t); | ||
364 | 367 | ||
365 | #define ScsiResult(host_code, scsi_code) (((host_code) << 16) | scsi_code) | 368 | #define ScsiResult(host_code, scsi_code) (((host_code) << 16) | scsi_code) |
366 | #define HBA_EVENT_RSCN 5 | 369 | #define HBA_EVENT_RSCN 5 |
diff --git a/drivers/scsi/lpfc/lpfc_ct.c b/drivers/scsi/lpfc/lpfc_ct.c index 9a1bd9534d74..e724048bf390 100644 --- a/drivers/scsi/lpfc/lpfc_ct.c +++ b/drivers/scsi/lpfc/lpfc_ct.c | |||
@@ -87,7 +87,6 @@ void | |||
87 | lpfc_ct_unsol_event(struct lpfc_hba *phba, struct lpfc_sli_ring *pring, | 87 | lpfc_ct_unsol_event(struct lpfc_hba *phba, struct lpfc_sli_ring *pring, |
88 | struct lpfc_iocbq *piocbq) | 88 | struct lpfc_iocbq *piocbq) |
89 | { | 89 | { |
90 | |||
91 | struct lpfc_dmabuf *mp = NULL; | 90 | struct lpfc_dmabuf *mp = NULL; |
92 | IOCB_t *icmd = &piocbq->iocb; | 91 | IOCB_t *icmd = &piocbq->iocb; |
93 | int i; | 92 | int i; |
@@ -160,6 +159,39 @@ lpfc_ct_unsol_event(struct lpfc_hba *phba, struct lpfc_sli_ring *pring, | |||
160 | } | 159 | } |
161 | } | 160 | } |
162 | 161 | ||
162 | /** | ||
163 | * lpfc_sli4_ct_abort_unsol_event - Default handle for sli4 unsol abort | ||
164 | * @phba: Pointer to HBA context object. | ||
165 | * @pring: Pointer to the driver internal I/O ring. | ||
166 | * @piocbq: Pointer to the IOCBQ. | ||
167 | * | ||
168 | * This function serves as the default handler for the sli4 unsolicited | ||
169 | * abort event. It shall be invoked when there is no application interface | ||
170 | * registered unsolicited abort handler. This handler does nothing but | ||
171 | * just simply releases the dma buffer used by the unsol abort event. | ||
172 | **/ | ||
173 | void | ||
174 | lpfc_sli4_ct_abort_unsol_event(struct lpfc_hba *phba, | ||
175 | struct lpfc_sli_ring *pring, | ||
176 | struct lpfc_iocbq *piocbq) | ||
177 | { | ||
178 | IOCB_t *icmd = &piocbq->iocb; | ||
179 | struct lpfc_dmabuf *bdeBuf; | ||
180 | uint32_t size; | ||
181 | |||
182 | /* Forward abort event to any process registered to receive ct event */ | ||
183 | lpfc_bsg_ct_unsol_event(phba, pring, piocbq); | ||
184 | |||
185 | /* If there is no BDE associated with IOCB, there is nothing to do */ | ||
186 | if (icmd->ulpBdeCount == 0) | ||
187 | return; | ||
188 | bdeBuf = piocbq->context2; | ||
189 | piocbq->context2 = NULL; | ||
190 | size = icmd->un.cont64[0].tus.f.bdeSize; | ||
191 | lpfc_ct_unsol_buffer(phba, piocbq, bdeBuf, size); | ||
192 | lpfc_in_buf_free(phba, bdeBuf); | ||
193 | } | ||
194 | |||
163 | static void | 195 | static void |
164 | lpfc_free_ct_rsp(struct lpfc_hba *phba, struct lpfc_dmabuf *mlist) | 196 | lpfc_free_ct_rsp(struct lpfc_hba *phba, struct lpfc_dmabuf *mlist) |
165 | { | 197 | { |
diff --git a/drivers/scsi/lpfc/lpfc_els.c b/drivers/scsi/lpfc/lpfc_els.c index 4ea863f50650..489ddcd4c584 100644 --- a/drivers/scsi/lpfc/lpfc_els.c +++ b/drivers/scsi/lpfc/lpfc_els.c | |||
@@ -2712,12 +2712,16 @@ lpfc_els_retry(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, | |||
2712 | !lpfc_error_lost_link(irsp)) { | 2712 | !lpfc_error_lost_link(irsp)) { |
2713 | /* FLOGI retry policy */ | 2713 | /* FLOGI retry policy */ |
2714 | retry = 1; | 2714 | retry = 1; |
2715 | maxretry = 48; | 2715 | /* retry forever */ |
2716 | if (cmdiocb->retry >= 32) | 2716 | maxretry = 0; |
2717 | if (cmdiocb->retry >= 100) | ||
2718 | delay = 5000; | ||
2719 | else if (cmdiocb->retry >= 32) | ||
2717 | delay = 1000; | 2720 | delay = 1000; |
2718 | } | 2721 | } |
2719 | 2722 | ||
2720 | if ((++cmdiocb->retry) >= maxretry) { | 2723 | cmdiocb->retry++; |
2724 | if (maxretry && (cmdiocb->retry >= maxretry)) { | ||
2721 | phba->fc_stat.elsRetryExceeded++; | 2725 | phba->fc_stat.elsRetryExceeded++; |
2722 | retry = 0; | 2726 | retry = 0; |
2723 | } | 2727 | } |
@@ -5671,7 +5675,7 @@ dropit: | |||
5671 | * NULL - No vport with the matching @vpi found | 5675 | * NULL - No vport with the matching @vpi found |
5672 | * Otherwise - Address to the vport with the matching @vpi. | 5676 | * Otherwise - Address to the vport with the matching @vpi. |
5673 | **/ | 5677 | **/ |
5674 | static struct lpfc_vport * | 5678 | struct lpfc_vport * |
5675 | lpfc_find_vport_by_vpid(struct lpfc_hba *phba, uint16_t vpi) | 5679 | lpfc_find_vport_by_vpid(struct lpfc_hba *phba, uint16_t vpi) |
5676 | { | 5680 | { |
5677 | struct lpfc_vport *vport; | 5681 | struct lpfc_vport *vport; |
diff --git a/drivers/scsi/lpfc/lpfc_hbadisc.c b/drivers/scsi/lpfc/lpfc_hbadisc.c index 5073c127bfe1..1b2771ac15f2 100644 --- a/drivers/scsi/lpfc/lpfc_hbadisc.c +++ b/drivers/scsi/lpfc/lpfc_hbadisc.c | |||
@@ -4474,7 +4474,7 @@ lpfc_unregister_unused_fcf(struct lpfc_hba *phba) | |||
4474 | return; | 4474 | return; |
4475 | } | 4475 | } |
4476 | 4476 | ||
4477 | lpfc_unreg_vfi(mbox, phba->pport->vfi); | 4477 | lpfc_unreg_vfi(mbox, phba->pport); |
4478 | mbox->vport = phba->pport; | 4478 | mbox->vport = phba->pport; |
4479 | mbox->mbox_cmpl = lpfc_unregister_vfi_cmpl; | 4479 | mbox->mbox_cmpl = lpfc_unregister_vfi_cmpl; |
4480 | 4480 | ||
diff --git a/drivers/scsi/lpfc/lpfc_hw.h b/drivers/scsi/lpfc/lpfc_hw.h index ccb26724dc53..74f9f028b45f 100644 --- a/drivers/scsi/lpfc/lpfc_hw.h +++ b/drivers/scsi/lpfc/lpfc_hw.h | |||
@@ -1183,6 +1183,7 @@ typedef struct { | |||
1183 | #define PCI_DEVICE_ID_ZEPHYR_DCSP 0xfe12 | 1183 | #define PCI_DEVICE_ID_ZEPHYR_DCSP 0xfe12 |
1184 | #define PCI_VENDOR_ID_SERVERENGINE 0x19a2 | 1184 | #define PCI_VENDOR_ID_SERVERENGINE 0x19a2 |
1185 | #define PCI_DEVICE_ID_TIGERSHARK 0x0704 | 1185 | #define PCI_DEVICE_ID_TIGERSHARK 0x0704 |
1186 | #define PCI_DEVICE_ID_TS_BE3 0x0714 | ||
1186 | 1187 | ||
1187 | #define JEDEC_ID_ADDRESS 0x0080001c | 1188 | #define JEDEC_ID_ADDRESS 0x0080001c |
1188 | #define FIREFLY_JEDEC_ID 0x1ACC | 1189 | #define FIREFLY_JEDEC_ID 0x1ACC |
@@ -1444,6 +1445,7 @@ typedef struct { /* FireFly BIU registers */ | |||
1444 | #define CMD_ABORT_MXRI64_CN 0x8C | 1445 | #define CMD_ABORT_MXRI64_CN 0x8C |
1445 | #define CMD_RCV_ELS_REQ64_CX 0x8D | 1446 | #define CMD_RCV_ELS_REQ64_CX 0x8D |
1446 | #define CMD_XMIT_ELS_RSP64_CX 0x95 | 1447 | #define CMD_XMIT_ELS_RSP64_CX 0x95 |
1448 | #define CMD_XMIT_BLS_RSP64_CX 0x97 | ||
1447 | #define CMD_FCP_IWRITE64_CR 0x98 | 1449 | #define CMD_FCP_IWRITE64_CR 0x98 |
1448 | #define CMD_FCP_IWRITE64_CX 0x99 | 1450 | #define CMD_FCP_IWRITE64_CX 0x99 |
1449 | #define CMD_FCP_IREAD64_CR 0x9A | 1451 | #define CMD_FCP_IREAD64_CR 0x9A |
@@ -2326,7 +2328,13 @@ typedef struct { | |||
2326 | /* Structure for MB Command UNREG_VPI (0x97) */ | 2328 | /* Structure for MB Command UNREG_VPI (0x97) */ |
2327 | typedef struct { | 2329 | typedef struct { |
2328 | uint32_t rsvd1; | 2330 | uint32_t rsvd1; |
2329 | uint32_t rsvd2; | 2331 | #ifdef __BIG_ENDIAN_BITFIELD |
2332 | uint16_t rsvd2; | ||
2333 | uint16_t sli4_vpi; | ||
2334 | #else /* __LITTLE_ENDIAN */ | ||
2335 | uint16_t sli4_vpi; | ||
2336 | uint16_t rsvd2; | ||
2337 | #endif | ||
2330 | uint32_t rsvd3; | 2338 | uint32_t rsvd3; |
2331 | uint32_t rsvd4; | 2339 | uint32_t rsvd4; |
2332 | uint32_t rsvd5; | 2340 | uint32_t rsvd5; |
diff --git a/drivers/scsi/lpfc/lpfc_hw4.h b/drivers/scsi/lpfc/lpfc_hw4.h index 3689eee04535..0c65091110cc 100644 --- a/drivers/scsi/lpfc/lpfc_hw4.h +++ b/drivers/scsi/lpfc/lpfc_hw4.h | |||
@@ -425,7 +425,7 @@ struct lpfc_wqe_generic{ | |||
425 | #define lpfc_wqe_gen_status_MASK 0x0000000F | 425 | #define lpfc_wqe_gen_status_MASK 0x0000000F |
426 | #define lpfc_wqe_gen_status_WORD word7 | 426 | #define lpfc_wqe_gen_status_WORD word7 |
427 | #define lpfc_wqe_gen_ct_SHIFT 2 | 427 | #define lpfc_wqe_gen_ct_SHIFT 2 |
428 | #define lpfc_wqe_gen_ct_MASK 0x00000007 | 428 | #define lpfc_wqe_gen_ct_MASK 0x00000003 |
429 | #define lpfc_wqe_gen_ct_WORD word7 | 429 | #define lpfc_wqe_gen_ct_WORD word7 |
430 | uint32_t abort_tag; | 430 | uint32_t abort_tag; |
431 | uint32_t word9; | 431 | uint32_t word9; |
@@ -760,6 +760,7 @@ struct mbox_header { | |||
760 | #define LPFC_MBOX_OPCODE_MQ_DESTROY 0x35 | 760 | #define LPFC_MBOX_OPCODE_MQ_DESTROY 0x35 |
761 | #define LPFC_MBOX_OPCODE_CQ_DESTROY 0x36 | 761 | #define LPFC_MBOX_OPCODE_CQ_DESTROY 0x36 |
762 | #define LPFC_MBOX_OPCODE_EQ_DESTROY 0x37 | 762 | #define LPFC_MBOX_OPCODE_EQ_DESTROY 0x37 |
763 | #define LPFC_MBOX_OPCODE_QUERY_FW_CFG 0x3A | ||
763 | #define LPFC_MBOX_OPCODE_FUNCTION_RESET 0x3D | 764 | #define LPFC_MBOX_OPCODE_FUNCTION_RESET 0x3D |
764 | 765 | ||
765 | /* FCoE Opcodes */ | 766 | /* FCoE Opcodes */ |
@@ -1273,6 +1274,51 @@ struct lpfc_mbx_del_fcf_tbl_entry { | |||
1273 | #define lpfc_mbx_del_fcf_tbl_index_WORD word10 | 1274 | #define lpfc_mbx_del_fcf_tbl_index_WORD word10 |
1274 | }; | 1275 | }; |
1275 | 1276 | ||
1277 | struct lpfc_mbx_query_fw_cfg { | ||
1278 | struct mbox_header header; | ||
1279 | uint32_t config_number; | ||
1280 | uint32_t asic_rev; | ||
1281 | uint32_t phys_port; | ||
1282 | uint32_t function_mode; | ||
1283 | /* firmware Function Mode */ | ||
1284 | #define lpfc_function_mode_toe_SHIFT 0 | ||
1285 | #define lpfc_function_mode_toe_MASK 0x00000001 | ||
1286 | #define lpfc_function_mode_toe_WORD function_mode | ||
1287 | #define lpfc_function_mode_nic_SHIFT 1 | ||
1288 | #define lpfc_function_mode_nic_MASK 0x00000001 | ||
1289 | #define lpfc_function_mode_nic_WORD function_mode | ||
1290 | #define lpfc_function_mode_rdma_SHIFT 2 | ||
1291 | #define lpfc_function_mode_rdma_MASK 0x00000001 | ||
1292 | #define lpfc_function_mode_rdma_WORD function_mode | ||
1293 | #define lpfc_function_mode_vm_SHIFT 3 | ||
1294 | #define lpfc_function_mode_vm_MASK 0x00000001 | ||
1295 | #define lpfc_function_mode_vm_WORD function_mode | ||
1296 | #define lpfc_function_mode_iscsi_i_SHIFT 4 | ||
1297 | #define lpfc_function_mode_iscsi_i_MASK 0x00000001 | ||
1298 | #define lpfc_function_mode_iscsi_i_WORD function_mode | ||
1299 | #define lpfc_function_mode_iscsi_t_SHIFT 5 | ||
1300 | #define lpfc_function_mode_iscsi_t_MASK 0x00000001 | ||
1301 | #define lpfc_function_mode_iscsi_t_WORD function_mode | ||
1302 | #define lpfc_function_mode_fcoe_i_SHIFT 6 | ||
1303 | #define lpfc_function_mode_fcoe_i_MASK 0x00000001 | ||
1304 | #define lpfc_function_mode_fcoe_i_WORD function_mode | ||
1305 | #define lpfc_function_mode_fcoe_t_SHIFT 7 | ||
1306 | #define lpfc_function_mode_fcoe_t_MASK 0x00000001 | ||
1307 | #define lpfc_function_mode_fcoe_t_WORD function_mode | ||
1308 | #define lpfc_function_mode_dal_SHIFT 8 | ||
1309 | #define lpfc_function_mode_dal_MASK 0x00000001 | ||
1310 | #define lpfc_function_mode_dal_WORD function_mode | ||
1311 | #define lpfc_function_mode_lro_SHIFT 9 | ||
1312 | #define lpfc_function_mode_lro_MASK 0x00000001 | ||
1313 | #define lpfc_function_mode_lro_WORD function_mode9 | ||
1314 | #define lpfc_function_mode_flex10_SHIFT 10 | ||
1315 | #define lpfc_function_mode_flex10_MASK 0x00000001 | ||
1316 | #define lpfc_function_mode_flex10_WORD function_mode | ||
1317 | #define lpfc_function_mode_ncsi_SHIFT 11 | ||
1318 | #define lpfc_function_mode_ncsi_MASK 0x00000001 | ||
1319 | #define lpfc_function_mode_ncsi_WORD function_mode | ||
1320 | }; | ||
1321 | |||
1276 | /* Status field for embedded SLI_CONFIG mailbox command */ | 1322 | /* Status field for embedded SLI_CONFIG mailbox command */ |
1277 | #define STATUS_SUCCESS 0x0 | 1323 | #define STATUS_SUCCESS 0x0 |
1278 | #define STATUS_FAILED 0x1 | 1324 | #define STATUS_FAILED 0x1 |
@@ -1804,6 +1850,7 @@ struct lpfc_mqe { | |||
1804 | struct lpfc_mbx_read_config rd_config; | 1850 | struct lpfc_mbx_read_config rd_config; |
1805 | struct lpfc_mbx_request_features req_ftrs; | 1851 | struct lpfc_mbx_request_features req_ftrs; |
1806 | struct lpfc_mbx_post_hdr_tmpl hdr_tmpl; | 1852 | struct lpfc_mbx_post_hdr_tmpl hdr_tmpl; |
1853 | struct lpfc_mbx_query_fw_cfg query_fw_cfg; | ||
1807 | struct lpfc_mbx_nop nop; | 1854 | struct lpfc_mbx_nop nop; |
1808 | } un; | 1855 | } un; |
1809 | }; | 1856 | }; |
@@ -1885,7 +1932,7 @@ struct lpfc_acqe_link { | |||
1885 | }; | 1932 | }; |
1886 | 1933 | ||
1887 | struct lpfc_acqe_fcoe { | 1934 | struct lpfc_acqe_fcoe { |
1888 | uint32_t fcf_index; | 1935 | uint32_t index; |
1889 | uint32_t word1; | 1936 | uint32_t word1; |
1890 | #define lpfc_acqe_fcoe_fcf_count_SHIFT 0 | 1937 | #define lpfc_acqe_fcoe_fcf_count_SHIFT 0 |
1891 | #define lpfc_acqe_fcoe_fcf_count_MASK 0x0000FFFF | 1938 | #define lpfc_acqe_fcoe_fcf_count_MASK 0x0000FFFF |
@@ -1896,6 +1943,7 @@ struct lpfc_acqe_fcoe { | |||
1896 | #define LPFC_FCOE_EVENT_TYPE_NEW_FCF 0x1 | 1943 | #define LPFC_FCOE_EVENT_TYPE_NEW_FCF 0x1 |
1897 | #define LPFC_FCOE_EVENT_TYPE_FCF_TABLE_FULL 0x2 | 1944 | #define LPFC_FCOE_EVENT_TYPE_FCF_TABLE_FULL 0x2 |
1898 | #define LPFC_FCOE_EVENT_TYPE_FCF_DEAD 0x3 | 1945 | #define LPFC_FCOE_EVENT_TYPE_FCF_DEAD 0x3 |
1946 | #define LPFC_FCOE_EVENT_TYPE_CVL 0x4 | ||
1899 | uint32_t event_tag; | 1947 | uint32_t event_tag; |
1900 | uint32_t trailer; | 1948 | uint32_t trailer; |
1901 | }; | 1949 | }; |
@@ -1924,9 +1972,9 @@ struct lpfc_bmbx_create { | |||
1924 | #define NO_XRI ((uint16_t)-1) | 1972 | #define NO_XRI ((uint16_t)-1) |
1925 | struct wqe_common { | 1973 | struct wqe_common { |
1926 | uint32_t word6; | 1974 | uint32_t word6; |
1927 | #define wqe_xri_SHIFT 0 | 1975 | #define wqe_xri_tag_SHIFT 0 |
1928 | #define wqe_xri_MASK 0x0000FFFF | 1976 | #define wqe_xri_tag_MASK 0x0000FFFF |
1929 | #define wqe_xri_WORD word6 | 1977 | #define wqe_xri_tag_WORD word6 |
1930 | #define wqe_ctxt_tag_SHIFT 16 | 1978 | #define wqe_ctxt_tag_SHIFT 16 |
1931 | #define wqe_ctxt_tag_MASK 0x0000FFFF | 1979 | #define wqe_ctxt_tag_MASK 0x0000FFFF |
1932 | #define wqe_ctxt_tag_WORD word6 | 1980 | #define wqe_ctxt_tag_WORD word6 |
@@ -1987,7 +2035,7 @@ struct wqe_common { | |||
1987 | #define wqe_wqec_MASK 0x00000001 | 2035 | #define wqe_wqec_MASK 0x00000001 |
1988 | #define wqe_wqec_WORD word11 | 2036 | #define wqe_wqec_WORD word11 |
1989 | #define wqe_cqid_SHIFT 16 | 2037 | #define wqe_cqid_SHIFT 16 |
1990 | #define wqe_cqid_MASK 0x000003ff | 2038 | #define wqe_cqid_MASK 0x0000ffff |
1991 | #define wqe_cqid_WORD word11 | 2039 | #define wqe_cqid_WORD word11 |
1992 | }; | 2040 | }; |
1993 | 2041 | ||
@@ -1996,6 +2044,9 @@ struct wqe_did { | |||
1996 | #define wqe_els_did_SHIFT 0 | 2044 | #define wqe_els_did_SHIFT 0 |
1997 | #define wqe_els_did_MASK 0x00FFFFFF | 2045 | #define wqe_els_did_MASK 0x00FFFFFF |
1998 | #define wqe_els_did_WORD word5 | 2046 | #define wqe_els_did_WORD word5 |
2047 | #define wqe_xmit_bls_pt_SHIFT 28 | ||
2048 | #define wqe_xmit_bls_pt_MASK 0x00000003 | ||
2049 | #define wqe_xmit_bls_pt_WORD word5 | ||
1999 | #define wqe_xmit_bls_ar_SHIFT 30 | 2050 | #define wqe_xmit_bls_ar_SHIFT 30 |
2000 | #define wqe_xmit_bls_ar_MASK 0x00000001 | 2051 | #define wqe_xmit_bls_ar_MASK 0x00000001 |
2001 | #define wqe_xmit_bls_ar_WORD word5 | 2052 | #define wqe_xmit_bls_ar_WORD word5 |
@@ -2044,6 +2095,23 @@ struct xmit_els_rsp64_wqe { | |||
2044 | 2095 | ||
2045 | struct xmit_bls_rsp64_wqe { | 2096 | struct xmit_bls_rsp64_wqe { |
2046 | uint32_t payload0; | 2097 | uint32_t payload0; |
2098 | /* Payload0 for BA_ACC */ | ||
2099 | #define xmit_bls_rsp64_acc_seq_id_SHIFT 16 | ||
2100 | #define xmit_bls_rsp64_acc_seq_id_MASK 0x000000ff | ||
2101 | #define xmit_bls_rsp64_acc_seq_id_WORD payload0 | ||
2102 | #define xmit_bls_rsp64_acc_seq_id_vald_SHIFT 24 | ||
2103 | #define xmit_bls_rsp64_acc_seq_id_vald_MASK 0x000000ff | ||
2104 | #define xmit_bls_rsp64_acc_seq_id_vald_WORD payload0 | ||
2105 | /* Payload0 for BA_RJT */ | ||
2106 | #define xmit_bls_rsp64_rjt_vspec_SHIFT 0 | ||
2107 | #define xmit_bls_rsp64_rjt_vspec_MASK 0x000000ff | ||
2108 | #define xmit_bls_rsp64_rjt_vspec_WORD payload0 | ||
2109 | #define xmit_bls_rsp64_rjt_expc_SHIFT 8 | ||
2110 | #define xmit_bls_rsp64_rjt_expc_MASK 0x000000ff | ||
2111 | #define xmit_bls_rsp64_rjt_expc_WORD payload0 | ||
2112 | #define xmit_bls_rsp64_rjt_rsnc_SHIFT 16 | ||
2113 | #define xmit_bls_rsp64_rjt_rsnc_MASK 0x000000ff | ||
2114 | #define xmit_bls_rsp64_rjt_rsnc_WORD payload0 | ||
2047 | uint32_t word1; | 2115 | uint32_t word1; |
2048 | #define xmit_bls_rsp64_rxid_SHIFT 0 | 2116 | #define xmit_bls_rsp64_rxid_SHIFT 0 |
2049 | #define xmit_bls_rsp64_rxid_MASK 0x0000ffff | 2117 | #define xmit_bls_rsp64_rxid_MASK 0x0000ffff |
@@ -2052,18 +2120,19 @@ struct xmit_bls_rsp64_wqe { | |||
2052 | #define xmit_bls_rsp64_oxid_MASK 0x0000ffff | 2120 | #define xmit_bls_rsp64_oxid_MASK 0x0000ffff |
2053 | #define xmit_bls_rsp64_oxid_WORD word1 | 2121 | #define xmit_bls_rsp64_oxid_WORD word1 |
2054 | uint32_t word2; | 2122 | uint32_t word2; |
2055 | #define xmit_bls_rsp64_seqcntlo_SHIFT 0 | 2123 | #define xmit_bls_rsp64_seqcnthi_SHIFT 0 |
2056 | #define xmit_bls_rsp64_seqcntlo_MASK 0x0000ffff | ||
2057 | #define xmit_bls_rsp64_seqcntlo_WORD word2 | ||
2058 | #define xmit_bls_rsp64_seqcnthi_SHIFT 16 | ||
2059 | #define xmit_bls_rsp64_seqcnthi_MASK 0x0000ffff | 2124 | #define xmit_bls_rsp64_seqcnthi_MASK 0x0000ffff |
2060 | #define xmit_bls_rsp64_seqcnthi_WORD word2 | 2125 | #define xmit_bls_rsp64_seqcnthi_WORD word2 |
2126 | #define xmit_bls_rsp64_seqcntlo_SHIFT 16 | ||
2127 | #define xmit_bls_rsp64_seqcntlo_MASK 0x0000ffff | ||
2128 | #define xmit_bls_rsp64_seqcntlo_WORD word2 | ||
2061 | uint32_t rsrvd3; | 2129 | uint32_t rsrvd3; |
2062 | uint32_t rsrvd4; | 2130 | uint32_t rsrvd4; |
2063 | struct wqe_did wqe_dest; | 2131 | struct wqe_did wqe_dest; |
2064 | struct wqe_common wqe_com; /* words 6-11 */ | 2132 | struct wqe_common wqe_com; /* words 6-11 */ |
2065 | uint32_t rsvd_12_15[4]; | 2133 | uint32_t rsvd_12_15[4]; |
2066 | }; | 2134 | }; |
2135 | |||
2067 | struct wqe_rctl_dfctl { | 2136 | struct wqe_rctl_dfctl { |
2068 | uint32_t word5; | 2137 | uint32_t word5; |
2069 | #define wqe_si_SHIFT 2 | 2138 | #define wqe_si_SHIFT 2 |
diff --git a/drivers/scsi/lpfc/lpfc_init.c b/drivers/scsi/lpfc/lpfc_init.c index d654c0e3db4d..a7b5566ea0b5 100644 --- a/drivers/scsi/lpfc/lpfc_init.c +++ b/drivers/scsi/lpfc/lpfc_init.c | |||
@@ -1669,6 +1669,10 @@ lpfc_get_hba_model_desc(struct lpfc_hba *phba, uint8_t *mdp, uint8_t *descp) | |||
1669 | oneConnect = 1; | 1669 | oneConnect = 1; |
1670 | m = (typeof(m)) {"OCe10100-F", max_speed, "PCIe"}; | 1670 | m = (typeof(m)) {"OCe10100-F", max_speed, "PCIe"}; |
1671 | break; | 1671 | break; |
1672 | case PCI_DEVICE_ID_TS_BE3: | ||
1673 | oneConnect = 1; | ||
1674 | m = (typeof(m)) {"OCeXXXXX-F", max_speed, "PCIe"}; | ||
1675 | break; | ||
1672 | default: | 1676 | default: |
1673 | m = (typeof(m)){ NULL }; | 1677 | m = (typeof(m)){ NULL }; |
1674 | break; | 1678 | break; |
@@ -2699,6 +2703,63 @@ lpfc_sli_remove_dflt_fcf(struct lpfc_hba *phba) | |||
2699 | } | 2703 | } |
2700 | 2704 | ||
2701 | /** | 2705 | /** |
2706 | * lpfc_sli4_fw_cfg_check - Read the firmware config and verify FCoE support | ||
2707 | * @phba: pointer to lpfc hba data structure. | ||
2708 | * | ||
2709 | * This function uses the QUERY_FW_CFG mailbox command to determine if the | ||
2710 | * firmware loaded supports FCoE. A return of zero indicates that the mailbox | ||
2711 | * was successful and the firmware supports FCoE. Any other return indicates | ||
2712 | * a error. It is assumed that this function will be called before interrupts | ||
2713 | * are enabled. | ||
2714 | **/ | ||
2715 | static int | ||
2716 | lpfc_sli4_fw_cfg_check(struct lpfc_hba *phba) | ||
2717 | { | ||
2718 | int rc = 0; | ||
2719 | LPFC_MBOXQ_t *mboxq; | ||
2720 | struct lpfc_mbx_query_fw_cfg *query_fw_cfg; | ||
2721 | uint32_t length; | ||
2722 | uint32_t shdr_status, shdr_add_status; | ||
2723 | |||
2724 | mboxq = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL); | ||
2725 | if (!mboxq) { | ||
2726 | lpfc_printf_log(phba, KERN_ERR, LOG_INIT, | ||
2727 | "2621 Failed to allocate mbox for " | ||
2728 | "query firmware config cmd\n"); | ||
2729 | return -ENOMEM; | ||
2730 | } | ||
2731 | query_fw_cfg = &mboxq->u.mqe.un.query_fw_cfg; | ||
2732 | length = (sizeof(struct lpfc_mbx_query_fw_cfg) - | ||
2733 | sizeof(struct lpfc_sli4_cfg_mhdr)); | ||
2734 | lpfc_sli4_config(phba, mboxq, LPFC_MBOX_SUBSYSTEM_COMMON, | ||
2735 | LPFC_MBOX_OPCODE_QUERY_FW_CFG, | ||
2736 | length, LPFC_SLI4_MBX_EMBED); | ||
2737 | rc = lpfc_sli_issue_mbox(phba, mboxq, MBX_POLL); | ||
2738 | /* The IOCTL status is embedded in the mailbox subheader. */ | ||
2739 | shdr_status = bf_get(lpfc_mbox_hdr_status, | ||
2740 | &query_fw_cfg->header.cfg_shdr.response); | ||
2741 | shdr_add_status = bf_get(lpfc_mbox_hdr_add_status, | ||
2742 | &query_fw_cfg->header.cfg_shdr.response); | ||
2743 | if (shdr_status || shdr_add_status || rc != MBX_SUCCESS) { | ||
2744 | lpfc_printf_log(phba, KERN_ERR, LOG_SLI, | ||
2745 | "2622 Query Firmware Config failed " | ||
2746 | "mbx status x%x, status x%x add_status x%x\n", | ||
2747 | rc, shdr_status, shdr_add_status); | ||
2748 | return -EINVAL; | ||
2749 | } | ||
2750 | if (!bf_get(lpfc_function_mode_fcoe_i, query_fw_cfg)) { | ||
2751 | lpfc_printf_log(phba, KERN_ERR, LOG_SLI, | ||
2752 | "2623 FCoE Function not supported by firmware. " | ||
2753 | "Function mode = %08x\n", | ||
2754 | query_fw_cfg->function_mode); | ||
2755 | return -EINVAL; | ||
2756 | } | ||
2757 | if (rc != MBX_TIMEOUT) | ||
2758 | mempool_free(mboxq, phba->mbox_mem_pool); | ||
2759 | return 0; | ||
2760 | } | ||
2761 | |||
2762 | /** | ||
2702 | * lpfc_sli4_parse_latt_fault - Parse sli4 link-attention link fault code | 2763 | * lpfc_sli4_parse_latt_fault - Parse sli4 link-attention link fault code |
2703 | * @phba: pointer to lpfc hba data structure. | 2764 | * @phba: pointer to lpfc hba data structure. |
2704 | * @acqe_link: pointer to the async link completion queue entry. | 2765 | * @acqe_link: pointer to the async link completion queue entry. |
@@ -2918,6 +2979,9 @@ lpfc_sli4_async_fcoe_evt(struct lpfc_hba *phba, | |||
2918 | { | 2979 | { |
2919 | uint8_t event_type = bf_get(lpfc_acqe_fcoe_event_type, acqe_fcoe); | 2980 | uint8_t event_type = bf_get(lpfc_acqe_fcoe_event_type, acqe_fcoe); |
2920 | int rc; | 2981 | int rc; |
2982 | struct lpfc_vport *vport; | ||
2983 | struct lpfc_nodelist *ndlp; | ||
2984 | struct Scsi_Host *shost; | ||
2921 | 2985 | ||
2922 | phba->fc_eventTag = acqe_fcoe->event_tag; | 2986 | phba->fc_eventTag = acqe_fcoe->event_tag; |
2923 | phba->fcoe_eventtag = acqe_fcoe->event_tag; | 2987 | phba->fcoe_eventtag = acqe_fcoe->event_tag; |
@@ -2925,7 +2989,7 @@ lpfc_sli4_async_fcoe_evt(struct lpfc_hba *phba, | |||
2925 | case LPFC_FCOE_EVENT_TYPE_NEW_FCF: | 2989 | case LPFC_FCOE_EVENT_TYPE_NEW_FCF: |
2926 | lpfc_printf_log(phba, KERN_ERR, LOG_DISCOVERY, | 2990 | lpfc_printf_log(phba, KERN_ERR, LOG_DISCOVERY, |
2927 | "2546 New FCF found index 0x%x tag 0x%x\n", | 2991 | "2546 New FCF found index 0x%x tag 0x%x\n", |
2928 | acqe_fcoe->fcf_index, | 2992 | acqe_fcoe->index, |
2929 | acqe_fcoe->event_tag); | 2993 | acqe_fcoe->event_tag); |
2930 | /* | 2994 | /* |
2931 | * If the current FCF is in discovered state, or | 2995 | * If the current FCF is in discovered state, or |
@@ -2958,10 +3022,10 @@ lpfc_sli4_async_fcoe_evt(struct lpfc_hba *phba, | |||
2958 | case LPFC_FCOE_EVENT_TYPE_FCF_DEAD: | 3022 | case LPFC_FCOE_EVENT_TYPE_FCF_DEAD: |
2959 | lpfc_printf_log(phba, KERN_ERR, LOG_DISCOVERY, | 3023 | lpfc_printf_log(phba, KERN_ERR, LOG_DISCOVERY, |
2960 | "2549 FCF disconnected fron network index 0x%x" | 3024 | "2549 FCF disconnected fron network index 0x%x" |
2961 | " tag 0x%x\n", acqe_fcoe->fcf_index, | 3025 | " tag 0x%x\n", acqe_fcoe->index, |
2962 | acqe_fcoe->event_tag); | 3026 | acqe_fcoe->event_tag); |
2963 | /* If the event is not for currently used fcf do nothing */ | 3027 | /* If the event is not for currently used fcf do nothing */ |
2964 | if (phba->fcf.fcf_indx != acqe_fcoe->fcf_index) | 3028 | if (phba->fcf.fcf_indx != acqe_fcoe->index) |
2965 | break; | 3029 | break; |
2966 | /* | 3030 | /* |
2967 | * Currently, driver support only one FCF - so treat this as | 3031 | * Currently, driver support only one FCF - so treat this as |
@@ -2971,7 +3035,28 @@ lpfc_sli4_async_fcoe_evt(struct lpfc_hba *phba, | |||
2971 | /* Unregister FCF if no devices connected to it */ | 3035 | /* Unregister FCF if no devices connected to it */ |
2972 | lpfc_unregister_unused_fcf(phba); | 3036 | lpfc_unregister_unused_fcf(phba); |
2973 | break; | 3037 | break; |
2974 | 3038 | case LPFC_FCOE_EVENT_TYPE_CVL: | |
3039 | lpfc_printf_log(phba, KERN_ERR, LOG_DISCOVERY, | ||
3040 | "2718 Clear Virtual Link Received for VPI 0x%x" | ||
3041 | " tag 0x%x\n", acqe_fcoe->index, acqe_fcoe->event_tag); | ||
3042 | vport = lpfc_find_vport_by_vpid(phba, | ||
3043 | acqe_fcoe->index /*- phba->vpi_base*/); | ||
3044 | if (!vport) | ||
3045 | break; | ||
3046 | ndlp = lpfc_findnode_did(vport, Fabric_DID); | ||
3047 | if (!ndlp) | ||
3048 | break; | ||
3049 | shost = lpfc_shost_from_vport(vport); | ||
3050 | lpfc_linkdown_port(vport); | ||
3051 | if (vport->port_type != LPFC_NPIV_PORT) { | ||
3052 | mod_timer(&ndlp->nlp_delayfunc, jiffies + HZ); | ||
3053 | spin_lock_irq(shost->host_lock); | ||
3054 | ndlp->nlp_flag |= NLP_DELAY_TMO; | ||
3055 | spin_unlock_irq(shost->host_lock); | ||
3056 | ndlp->nlp_last_elscmd = ELS_CMD_FLOGI; | ||
3057 | vport->port_state = LPFC_FLOGI; | ||
3058 | } | ||
3059 | break; | ||
2975 | default: | 3060 | default: |
2976 | lpfc_printf_log(phba, KERN_ERR, LOG_SLI, | 3061 | lpfc_printf_log(phba, KERN_ERR, LOG_SLI, |
2977 | "0288 Unknown FCoE event type 0x%x event tag " | 3062 | "0288 Unknown FCoE event type 0x%x event tag " |
@@ -3463,6 +3548,10 @@ lpfc_sli4_driver_resource_setup(struct lpfc_hba *phba) | |||
3463 | if (unlikely(rc)) | 3548 | if (unlikely(rc)) |
3464 | goto out_free_bsmbx; | 3549 | goto out_free_bsmbx; |
3465 | 3550 | ||
3551 | rc = lpfc_sli4_fw_cfg_check(phba); | ||
3552 | if (unlikely(rc)) | ||
3553 | goto out_free_bsmbx; | ||
3554 | |||
3466 | /* Set up the hba's configuration parameters. */ | 3555 | /* Set up the hba's configuration parameters. */ |
3467 | rc = lpfc_sli4_read_config(phba); | 3556 | rc = lpfc_sli4_read_config(phba); |
3468 | if (unlikely(rc)) | 3557 | if (unlikely(rc)) |
@@ -6687,6 +6776,7 @@ lpfc_pci_probe_one_s3(struct pci_dev *pdev, const struct pci_device_id *pid) | |||
6687 | { | 6776 | { |
6688 | struct lpfc_hba *phba; | 6777 | struct lpfc_hba *phba; |
6689 | struct lpfc_vport *vport = NULL; | 6778 | struct lpfc_vport *vport = NULL; |
6779 | struct Scsi_Host *shost = NULL; | ||
6690 | int error; | 6780 | int error; |
6691 | uint32_t cfg_mode, intr_mode; | 6781 | uint32_t cfg_mode, intr_mode; |
6692 | 6782 | ||
@@ -6765,6 +6855,7 @@ lpfc_pci_probe_one_s3(struct pci_dev *pdev, const struct pci_device_id *pid) | |||
6765 | goto out_destroy_shost; | 6855 | goto out_destroy_shost; |
6766 | } | 6856 | } |
6767 | 6857 | ||
6858 | shost = lpfc_shost_from_vport(vport); /* save shost for error cleanup */ | ||
6768 | /* Now, trying to enable interrupt and bring up the device */ | 6859 | /* Now, trying to enable interrupt and bring up the device */ |
6769 | cfg_mode = phba->cfg_use_msi; | 6860 | cfg_mode = phba->cfg_use_msi; |
6770 | while (true) { | 6861 | while (true) { |
@@ -6831,6 +6922,8 @@ out_unset_pci_mem_s3: | |||
6831 | lpfc_sli_pci_mem_unset(phba); | 6922 | lpfc_sli_pci_mem_unset(phba); |
6832 | out_disable_pci_dev: | 6923 | out_disable_pci_dev: |
6833 | lpfc_disable_pci_dev(phba); | 6924 | lpfc_disable_pci_dev(phba); |
6925 | if (shost) | ||
6926 | scsi_host_put(shost); | ||
6834 | out_free_phba: | 6927 | out_free_phba: |
6835 | lpfc_hba_free(phba); | 6928 | lpfc_hba_free(phba); |
6836 | return error; | 6929 | return error; |
@@ -7214,6 +7307,7 @@ lpfc_pci_probe_one_s4(struct pci_dev *pdev, const struct pci_device_id *pid) | |||
7214 | { | 7307 | { |
7215 | struct lpfc_hba *phba; | 7308 | struct lpfc_hba *phba; |
7216 | struct lpfc_vport *vport = NULL; | 7309 | struct lpfc_vport *vport = NULL; |
7310 | struct Scsi_Host *shost = NULL; | ||
7217 | int error; | 7311 | int error; |
7218 | uint32_t cfg_mode, intr_mode; | 7312 | uint32_t cfg_mode, intr_mode; |
7219 | int mcnt; | 7313 | int mcnt; |
@@ -7294,6 +7388,7 @@ lpfc_pci_probe_one_s4(struct pci_dev *pdev, const struct pci_device_id *pid) | |||
7294 | goto out_destroy_shost; | 7388 | goto out_destroy_shost; |
7295 | } | 7389 | } |
7296 | 7390 | ||
7391 | shost = lpfc_shost_from_vport(vport); /* save shost for error cleanup */ | ||
7297 | /* Now, trying to enable interrupt and bring up the device */ | 7392 | /* Now, trying to enable interrupt and bring up the device */ |
7298 | cfg_mode = phba->cfg_use_msi; | 7393 | cfg_mode = phba->cfg_use_msi; |
7299 | while (true) { | 7394 | while (true) { |
@@ -7362,6 +7457,8 @@ out_unset_pci_mem_s4: | |||
7362 | lpfc_sli4_pci_mem_unset(phba); | 7457 | lpfc_sli4_pci_mem_unset(phba); |
7363 | out_disable_pci_dev: | 7458 | out_disable_pci_dev: |
7364 | lpfc_disable_pci_dev(phba); | 7459 | lpfc_disable_pci_dev(phba); |
7460 | if (shost) | ||
7461 | scsi_host_put(shost); | ||
7365 | out_free_phba: | 7462 | out_free_phba: |
7366 | lpfc_hba_free(phba); | 7463 | lpfc_hba_free(phba); |
7367 | return error; | 7464 | return error; |
@@ -7936,6 +8033,8 @@ static struct pci_device_id lpfc_id_table[] = { | |||
7936 | PCI_ANY_ID, PCI_ANY_ID, }, | 8033 | PCI_ANY_ID, PCI_ANY_ID, }, |
7937 | {PCI_VENDOR_ID_SERVERENGINE, PCI_DEVICE_ID_TIGERSHARK, | 8034 | {PCI_VENDOR_ID_SERVERENGINE, PCI_DEVICE_ID_TIGERSHARK, |
7938 | PCI_ANY_ID, PCI_ANY_ID, }, | 8035 | PCI_ANY_ID, PCI_ANY_ID, }, |
8036 | {PCI_VENDOR_ID_SERVERENGINE, PCI_DEVICE_ID_TS_BE3, | ||
8037 | PCI_ANY_ID, PCI_ANY_ID, }, | ||
7939 | { 0 } | 8038 | { 0 } |
7940 | }; | 8039 | }; |
7941 | 8040 | ||
diff --git a/drivers/scsi/lpfc/lpfc_mbox.c b/drivers/scsi/lpfc/lpfc_mbox.c index 1ab405902a18..2a38d94654bc 100644 --- a/drivers/scsi/lpfc/lpfc_mbox.c +++ b/drivers/scsi/lpfc/lpfc_mbox.c | |||
@@ -849,7 +849,10 @@ lpfc_unreg_vpi(struct lpfc_hba *phba, uint16_t vpi, LPFC_MBOXQ_t *pmb) | |||
849 | MAILBOX_t *mb = &pmb->u.mb; | 849 | MAILBOX_t *mb = &pmb->u.mb; |
850 | memset(pmb, 0, sizeof (LPFC_MBOXQ_t)); | 850 | memset(pmb, 0, sizeof (LPFC_MBOXQ_t)); |
851 | 851 | ||
852 | mb->un.varUnregVpi.vpi = vpi + phba->vpi_base; | 852 | if (phba->sli_rev < LPFC_SLI_REV4) |
853 | mb->un.varUnregVpi.vpi = vpi + phba->vpi_base; | ||
854 | else | ||
855 | mb->un.varUnregVpi.sli4_vpi = vpi + phba->vpi_base; | ||
853 | 856 | ||
854 | mb->mbxCommand = MBX_UNREG_VPI; | 857 | mb->mbxCommand = MBX_UNREG_VPI; |
855 | mb->mbxOwner = OWN_HOST; | 858 | mb->mbxOwner = OWN_HOST; |
@@ -1850,7 +1853,7 @@ lpfc_init_vpi(struct lpfc_hba *phba, struct lpfcMboxq *mbox, uint16_t vpi) | |||
1850 | /** | 1853 | /** |
1851 | * lpfc_unreg_vfi - Initialize the UNREG_VFI mailbox command | 1854 | * lpfc_unreg_vfi - Initialize the UNREG_VFI mailbox command |
1852 | * @mbox: pointer to lpfc mbox command to initialize. | 1855 | * @mbox: pointer to lpfc mbox command to initialize. |
1853 | * @vfi: VFI to be unregistered. | 1856 | * @vport: vport associated with the VF. |
1854 | * | 1857 | * |
1855 | * The UNREG_VFI mailbox command causes the SLI Host to put a virtual fabric | 1858 | * The UNREG_VFI mailbox command causes the SLI Host to put a virtual fabric |
1856 | * (logical NPort) into the inactive state. The SLI Host must have logged out | 1859 | * (logical NPort) into the inactive state. The SLI Host must have logged out |
@@ -1859,11 +1862,12 @@ lpfc_init_vpi(struct lpfc_hba *phba, struct lpfcMboxq *mbox, uint16_t vpi) | |||
1859 | * fabric inactive. | 1862 | * fabric inactive. |
1860 | **/ | 1863 | **/ |
1861 | void | 1864 | void |
1862 | lpfc_unreg_vfi(struct lpfcMboxq *mbox, uint16_t vfi) | 1865 | lpfc_unreg_vfi(struct lpfcMboxq *mbox, struct lpfc_vport *vport) |
1863 | { | 1866 | { |
1864 | memset(mbox, 0, sizeof(*mbox)); | 1867 | memset(mbox, 0, sizeof(*mbox)); |
1865 | bf_set(lpfc_mqe_command, &mbox->u.mqe, MBX_UNREG_VFI); | 1868 | bf_set(lpfc_mqe_command, &mbox->u.mqe, MBX_UNREG_VFI); |
1866 | bf_set(lpfc_unreg_vfi_vfi, &mbox->u.mqe.un.unreg_vfi, vfi); | 1869 | bf_set(lpfc_unreg_vfi_vfi, &mbox->u.mqe.un.unreg_vfi, |
1870 | vport->vfi + vport->phba->vfi_base); | ||
1867 | } | 1871 | } |
1868 | 1872 | ||
1869 | /** | 1873 | /** |
diff --git a/drivers/scsi/lpfc/lpfc_sli.c b/drivers/scsi/lpfc/lpfc_sli.c index 8d884d8e18be..e8d3e4732a84 100644 --- a/drivers/scsi/lpfc/lpfc_sli.c +++ b/drivers/scsi/lpfc/lpfc_sli.c | |||
@@ -59,7 +59,8 @@ static int lpfc_sli_issue_mbox_s4(struct lpfc_hba *, LPFC_MBOXQ_t *, | |||
59 | uint32_t); | 59 | uint32_t); |
60 | static int lpfc_sli4_read_rev(struct lpfc_hba *, LPFC_MBOXQ_t *, | 60 | static int lpfc_sli4_read_rev(struct lpfc_hba *, LPFC_MBOXQ_t *, |
61 | uint8_t *, uint32_t *); | 61 | uint8_t *, uint32_t *); |
62 | 62 | static void lpfc_sli4_send_seq_to_ulp(struct lpfc_vport *, | |
63 | struct hbq_dmabuf *); | ||
63 | static IOCB_t * | 64 | static IOCB_t * |
64 | lpfc_get_iocb_from_iocbq(struct lpfc_iocbq *iocbq) | 65 | lpfc_get_iocb_from_iocbq(struct lpfc_iocbq *iocbq) |
65 | { | 66 | { |
@@ -572,9 +573,9 @@ __lpfc_sli_release_iocbq_s4(struct lpfc_hba *phba, struct lpfc_iocbq *iocbq) | |||
572 | sglq = __lpfc_clear_active_sglq(phba, iocbq->sli4_xritag); | 573 | sglq = __lpfc_clear_active_sglq(phba, iocbq->sli4_xritag); |
573 | if (sglq) { | 574 | if (sglq) { |
574 | if (iocbq->iocb_flag & LPFC_DRIVER_ABORTED | 575 | if (iocbq->iocb_flag & LPFC_DRIVER_ABORTED |
575 | || ((iocbq->iocb.ulpStatus == IOSTAT_LOCAL_REJECT) | 576 | && ((iocbq->iocb.ulpStatus == IOSTAT_LOCAL_REJECT) |
576 | && (iocbq->iocb.un.ulpWord[4] | 577 | && (iocbq->iocb.un.ulpWord[4] |
577 | == IOERR_SLI_ABORTED))) { | 578 | == IOERR_ABORT_REQUESTED))) { |
578 | spin_lock_irqsave(&phba->sli4_hba.abts_sgl_list_lock, | 579 | spin_lock_irqsave(&phba->sli4_hba.abts_sgl_list_lock, |
579 | iflag); | 580 | iflag); |
580 | list_add(&sglq->list, | 581 | list_add(&sglq->list, |
@@ -767,6 +768,7 @@ lpfc_sli_iocb_cmd_type(uint8_t iocb_cmnd) | |||
767 | case CMD_CLOSE_XRI_CX: | 768 | case CMD_CLOSE_XRI_CX: |
768 | case CMD_XRI_ABORTED_CX: | 769 | case CMD_XRI_ABORTED_CX: |
769 | case CMD_ABORT_MXRI64_CN: | 770 | case CMD_ABORT_MXRI64_CN: |
771 | case CMD_XMIT_BLS_RSP64_CX: | ||
770 | type = LPFC_ABORT_IOCB; | 772 | type = LPFC_ABORT_IOCB; |
771 | break; | 773 | break; |
772 | case CMD_RCV_SEQUENCE_CX: | 774 | case CMD_RCV_SEQUENCE_CX: |
@@ -6081,6 +6083,23 @@ lpfc_sli4_iocb2wqe(struct lpfc_hba *phba, struct lpfc_iocbq *iocbq, | |||
6081 | command_type = OTHER_COMMAND; | 6083 | command_type = OTHER_COMMAND; |
6082 | xritag = 0; | 6084 | xritag = 0; |
6083 | break; | 6085 | break; |
6086 | case CMD_XMIT_BLS_RSP64_CX: | ||
6087 | /* As BLS ABTS-ACC WQE is very different from other WQEs, | ||
6088 | * we re-construct this WQE here based on information in | ||
6089 | * iocbq from scratch. | ||
6090 | */ | ||
6091 | memset(wqe, 0, sizeof(union lpfc_wqe)); | ||
6092 | bf_set(xmit_bls_rsp64_oxid, &wqe->xmit_bls_rsp, | ||
6093 | iocbq->iocb.un.ulpWord[3]); | ||
6094 | bf_set(xmit_bls_rsp64_rxid, &wqe->xmit_bls_rsp, | ||
6095 | iocbq->sli4_xritag); | ||
6096 | bf_set(xmit_bls_rsp64_seqcnthi, &wqe->xmit_bls_rsp, 0xffff); | ||
6097 | bf_set(wqe_xmit_bls_pt, &wqe->xmit_bls_rsp.wqe_dest, 0x1); | ||
6098 | bf_set(wqe_ctxt_tag, &wqe->xmit_bls_rsp.wqe_com, | ||
6099 | iocbq->iocb.ulpContext); | ||
6100 | /* Overwrite the pre-set comnd type with OTHER_COMMAND */ | ||
6101 | command_type = OTHER_COMMAND; | ||
6102 | break; | ||
6084 | case CMD_XRI_ABORTED_CX: | 6103 | case CMD_XRI_ABORTED_CX: |
6085 | case CMD_CREATE_XRI_CR: /* Do we expect to use this? */ | 6104 | case CMD_CREATE_XRI_CR: /* Do we expect to use this? */ |
6086 | /* words0-2 are all 0's no bde */ | 6105 | /* words0-2 are all 0's no bde */ |
@@ -6139,7 +6158,7 @@ __lpfc_sli_issue_iocb_s4(struct lpfc_hba *phba, uint32_t ring_number, | |||
6139 | 6158 | ||
6140 | if (piocb->sli4_xritag == NO_XRI) { | 6159 | if (piocb->sli4_xritag == NO_XRI) { |
6141 | if (piocb->iocb.ulpCommand == CMD_ABORT_XRI_CN || | 6160 | if (piocb->iocb.ulpCommand == CMD_ABORT_XRI_CN || |
6142 | piocb->iocb.ulpCommand == CMD_CLOSE_XRI_CN) | 6161 | piocb->iocb.ulpCommand == CMD_CLOSE_XRI_CN) |
6143 | sglq = NULL; | 6162 | sglq = NULL; |
6144 | else { | 6163 | else { |
6145 | sglq = __lpfc_sli_get_sglq(phba); | 6164 | sglq = __lpfc_sli_get_sglq(phba); |
@@ -6464,7 +6483,7 @@ lpfc_sli_setup(struct lpfc_hba *phba) | |||
6464 | pring->iotag_max = 4096; | 6483 | pring->iotag_max = 4096; |
6465 | pring->lpfc_sli_rcv_async_status = | 6484 | pring->lpfc_sli_rcv_async_status = |
6466 | lpfc_sli_async_event_handler; | 6485 | lpfc_sli_async_event_handler; |
6467 | pring->num_mask = 4; | 6486 | pring->num_mask = LPFC_MAX_RING_MASK; |
6468 | pring->prt[0].profile = 0; /* Mask 0 */ | 6487 | pring->prt[0].profile = 0; /* Mask 0 */ |
6469 | pring->prt[0].rctl = FC_ELS_REQ; | 6488 | pring->prt[0].rctl = FC_ELS_REQ; |
6470 | pring->prt[0].type = FC_ELS_DATA; | 6489 | pring->prt[0].type = FC_ELS_DATA; |
@@ -6489,6 +6508,12 @@ lpfc_sli_setup(struct lpfc_hba *phba) | |||
6489 | pring->prt[3].type = FC_COMMON_TRANSPORT_ULP; | 6508 | pring->prt[3].type = FC_COMMON_TRANSPORT_ULP; |
6490 | pring->prt[3].lpfc_sli_rcv_unsol_event = | 6509 | pring->prt[3].lpfc_sli_rcv_unsol_event = |
6491 | lpfc_ct_unsol_event; | 6510 | lpfc_ct_unsol_event; |
6511 | /* abort unsolicited sequence */ | ||
6512 | pring->prt[4].profile = 0; /* Mask 4 */ | ||
6513 | pring->prt[4].rctl = FC_RCTL_BA_ABTS; | ||
6514 | pring->prt[4].type = FC_TYPE_BLS; | ||
6515 | pring->prt[4].lpfc_sli_rcv_unsol_event = | ||
6516 | lpfc_sli4_ct_abort_unsol_event; | ||
6492 | break; | 6517 | break; |
6493 | } | 6518 | } |
6494 | totiocbsize += (pring->numCiocb * pring->sizeCiocb) + | 6519 | totiocbsize += (pring->numCiocb * pring->sizeCiocb) + |
@@ -10870,6 +10895,177 @@ lpfc_fc_frame_add(struct lpfc_vport *vport, struct hbq_dmabuf *dmabuf) | |||
10870 | } | 10895 | } |
10871 | 10896 | ||
10872 | /** | 10897 | /** |
10898 | * lpfc_sli4_abort_partial_seq - Abort partially assembled unsol sequence | ||
10899 | * @vport: pointer to a vitural port | ||
10900 | * @dmabuf: pointer to a dmabuf that describes the FC sequence | ||
10901 | * | ||
10902 | * This function tries to abort from the partially assembed sequence, described | ||
10903 | * by the information from basic abbort @dmabuf. It checks to see whether such | ||
10904 | * partially assembled sequence held by the driver. If so, it shall free up all | ||
10905 | * the frames from the partially assembled sequence. | ||
10906 | * | ||
10907 | * Return | ||
10908 | * true -- if there is matching partially assembled sequence present and all | ||
10909 | * the frames freed with the sequence; | ||
10910 | * false -- if there is no matching partially assembled sequence present so | ||
10911 | * nothing got aborted in the lower layer driver | ||
10912 | **/ | ||
10913 | static bool | ||
10914 | lpfc_sli4_abort_partial_seq(struct lpfc_vport *vport, | ||
10915 | struct hbq_dmabuf *dmabuf) | ||
10916 | { | ||
10917 | struct fc_frame_header *new_hdr; | ||
10918 | struct fc_frame_header *temp_hdr; | ||
10919 | struct lpfc_dmabuf *d_buf, *n_buf, *h_buf; | ||
10920 | struct hbq_dmabuf *seq_dmabuf = NULL; | ||
10921 | |||
10922 | /* Use the hdr_buf to find the sequence that matches this frame */ | ||
10923 | INIT_LIST_HEAD(&dmabuf->dbuf.list); | ||
10924 | INIT_LIST_HEAD(&dmabuf->hbuf.list); | ||
10925 | new_hdr = (struct fc_frame_header *)dmabuf->hbuf.virt; | ||
10926 | list_for_each_entry(h_buf, &vport->rcv_buffer_list, list) { | ||
10927 | temp_hdr = (struct fc_frame_header *)h_buf->virt; | ||
10928 | if ((temp_hdr->fh_seq_id != new_hdr->fh_seq_id) || | ||
10929 | (temp_hdr->fh_ox_id != new_hdr->fh_ox_id) || | ||
10930 | (memcmp(&temp_hdr->fh_s_id, &new_hdr->fh_s_id, 3))) | ||
10931 | continue; | ||
10932 | /* found a pending sequence that matches this frame */ | ||
10933 | seq_dmabuf = container_of(h_buf, struct hbq_dmabuf, hbuf); | ||
10934 | break; | ||
10935 | } | ||
10936 | |||
10937 | /* Free up all the frames from the partially assembled sequence */ | ||
10938 | if (seq_dmabuf) { | ||
10939 | list_for_each_entry_safe(d_buf, n_buf, | ||
10940 | &seq_dmabuf->dbuf.list, list) { | ||
10941 | list_del_init(&d_buf->list); | ||
10942 | lpfc_in_buf_free(vport->phba, d_buf); | ||
10943 | } | ||
10944 | return true; | ||
10945 | } | ||
10946 | return false; | ||
10947 | } | ||
10948 | |||
10949 | /** | ||
10950 | * lpfc_sli4_seq_abort_acc_cmpl - Accept seq abort iocb complete handler | ||
10951 | * @phba: Pointer to HBA context object. | ||
10952 | * @cmd_iocbq: pointer to the command iocbq structure. | ||
10953 | * @rsp_iocbq: pointer to the response iocbq structure. | ||
10954 | * | ||
10955 | * This function handles the sequence abort accept iocb command complete | ||
10956 | * event. It properly releases the memory allocated to the sequence abort | ||
10957 | * accept iocb. | ||
10958 | **/ | ||
10959 | static void | ||
10960 | lpfc_sli4_seq_abort_acc_cmpl(struct lpfc_hba *phba, | ||
10961 | struct lpfc_iocbq *cmd_iocbq, | ||
10962 | struct lpfc_iocbq *rsp_iocbq) | ||
10963 | { | ||
10964 | if (cmd_iocbq) | ||
10965 | lpfc_sli_release_iocbq(phba, cmd_iocbq); | ||
10966 | } | ||
10967 | |||
10968 | /** | ||
10969 | * lpfc_sli4_seq_abort_acc - Accept sequence abort | ||
10970 | * @phba: Pointer to HBA context object. | ||
10971 | * @fc_hdr: pointer to a FC frame header. | ||
10972 | * | ||
10973 | * This function sends a basic accept to a previous unsol sequence abort | ||
10974 | * event after aborting the sequence handling. | ||
10975 | **/ | ||
10976 | static void | ||
10977 | lpfc_sli4_seq_abort_acc(struct lpfc_hba *phba, | ||
10978 | struct fc_frame_header *fc_hdr) | ||
10979 | { | ||
10980 | struct lpfc_iocbq *ctiocb = NULL; | ||
10981 | struct lpfc_nodelist *ndlp; | ||
10982 | uint16_t oxid; | ||
10983 | uint32_t sid; | ||
10984 | IOCB_t *icmd; | ||
10985 | |||
10986 | if (!lpfc_is_link_up(phba)) | ||
10987 | return; | ||
10988 | |||
10989 | sid = sli4_sid_from_fc_hdr(fc_hdr); | ||
10990 | oxid = be16_to_cpu(fc_hdr->fh_ox_id); | ||
10991 | |||
10992 | ndlp = lpfc_findnode_did(phba->pport, sid); | ||
10993 | if (!ndlp) { | ||
10994 | lpfc_printf_log(phba, KERN_WARNING, LOG_ELS, | ||
10995 | "1268 Find ndlp returned NULL for oxid:x%x " | ||
10996 | "SID:x%x\n", oxid, sid); | ||
10997 | return; | ||
10998 | } | ||
10999 | |||
11000 | /* Allocate buffer for acc iocb */ | ||
11001 | ctiocb = lpfc_sli_get_iocbq(phba); | ||
11002 | if (!ctiocb) | ||
11003 | return; | ||
11004 | |||
11005 | icmd = &ctiocb->iocb; | ||
11006 | icmd->un.xseq64.bdl.ulpIoTag32 = 0; | ||
11007 | icmd->un.xseq64.bdl.bdeSize = 0; | ||
11008 | icmd->un.xseq64.w5.hcsw.Dfctl = 0; | ||
11009 | icmd->un.xseq64.w5.hcsw.Rctl = FC_RCTL_BA_ACC; | ||
11010 | icmd->un.xseq64.w5.hcsw.Type = FC_TYPE_BLS; | ||
11011 | |||
11012 | /* Fill in the rest of iocb fields */ | ||
11013 | icmd->ulpCommand = CMD_XMIT_BLS_RSP64_CX; | ||
11014 | icmd->ulpBdeCount = 0; | ||
11015 | icmd->ulpLe = 1; | ||
11016 | icmd->ulpClass = CLASS3; | ||
11017 | icmd->ulpContext = ndlp->nlp_rpi; | ||
11018 | icmd->un.ulpWord[3] = oxid; | ||
11019 | |||
11020 | ctiocb->sli4_xritag = NO_XRI; | ||
11021 | ctiocb->iocb_cmpl = NULL; | ||
11022 | ctiocb->vport = phba->pport; | ||
11023 | ctiocb->iocb_cmpl = lpfc_sli4_seq_abort_acc_cmpl; | ||
11024 | |||
11025 | /* Xmit CT abts accept on exchange <xid> */ | ||
11026 | lpfc_printf_log(phba, KERN_INFO, LOG_ELS, | ||
11027 | "1200 Xmit CT ABTS ACC on exchange x%x Data: x%x\n", | ||
11028 | CMD_XMIT_BLS_RSP64_CX, phba->link_state); | ||
11029 | lpfc_sli_issue_iocb(phba, LPFC_ELS_RING, ctiocb, 0); | ||
11030 | } | ||
11031 | |||
11032 | /** | ||
11033 | * lpfc_sli4_handle_unsol_abort - Handle sli-4 unsolicited abort event | ||
11034 | * @vport: Pointer to the vport on which this sequence was received | ||
11035 | * @dmabuf: pointer to a dmabuf that describes the FC sequence | ||
11036 | * | ||
11037 | * This function handles an SLI-4 unsolicited abort event. If the unsolicited | ||
11038 | * receive sequence is only partially assembed by the driver, it shall abort | ||
11039 | * the partially assembled frames for the sequence. Otherwise, if the | ||
11040 | * unsolicited receive sequence has been completely assembled and passed to | ||
11041 | * the Upper Layer Protocol (UPL), it then mark the per oxid status for the | ||
11042 | * unsolicited sequence has been aborted. After that, it will issue a basic | ||
11043 | * accept to accept the abort. | ||
11044 | **/ | ||
11045 | void | ||
11046 | lpfc_sli4_handle_unsol_abort(struct lpfc_vport *vport, | ||
11047 | struct hbq_dmabuf *dmabuf) | ||
11048 | { | ||
11049 | struct lpfc_hba *phba = vport->phba; | ||
11050 | struct fc_frame_header fc_hdr; | ||
11051 | bool abts_par; | ||
11052 | |||
11053 | /* Try to abort partially assembled seq */ | ||
11054 | abts_par = lpfc_sli4_abort_partial_seq(vport, dmabuf); | ||
11055 | |||
11056 | /* Make a copy of fc_hdr before the dmabuf being released */ | ||
11057 | memcpy(&fc_hdr, dmabuf->hbuf.virt, sizeof(struct fc_frame_header)); | ||
11058 | |||
11059 | /* Send abort to ULP if partially seq abort failed */ | ||
11060 | if (abts_par == false) | ||
11061 | lpfc_sli4_send_seq_to_ulp(vport, dmabuf); | ||
11062 | else | ||
11063 | lpfc_in_buf_free(phba, &dmabuf->dbuf); | ||
11064 | /* Send basic accept (BA_ACC) to the abort requester */ | ||
11065 | lpfc_sli4_seq_abort_acc(phba, &fc_hdr); | ||
11066 | } | ||
11067 | |||
11068 | /** | ||
10873 | * lpfc_seq_complete - Indicates if a sequence is complete | 11069 | * lpfc_seq_complete - Indicates if a sequence is complete |
10874 | * @dmabuf: pointer to a dmabuf that describes the FC sequence | 11070 | * @dmabuf: pointer to a dmabuf that describes the FC sequence |
10875 | * | 11071 | * |
@@ -10941,9 +11137,7 @@ lpfc_prep_seq(struct lpfc_vport *vport, struct hbq_dmabuf *seq_dmabuf) | |||
10941 | /* remove from receive buffer list */ | 11137 | /* remove from receive buffer list */ |
10942 | list_del_init(&seq_dmabuf->hbuf.list); | 11138 | list_del_init(&seq_dmabuf->hbuf.list); |
10943 | /* get the Remote Port's SID */ | 11139 | /* get the Remote Port's SID */ |
10944 | sid = (fc_hdr->fh_s_id[0] << 16 | | 11140 | sid = sli4_sid_from_fc_hdr(fc_hdr); |
10945 | fc_hdr->fh_s_id[1] << 8 | | ||
10946 | fc_hdr->fh_s_id[2]); | ||
10947 | /* Get an iocbq struct to fill in. */ | 11141 | /* Get an iocbq struct to fill in. */ |
10948 | first_iocbq = lpfc_sli_get_iocbq(vport->phba); | 11142 | first_iocbq = lpfc_sli_get_iocbq(vport->phba); |
10949 | if (first_iocbq) { | 11143 | if (first_iocbq) { |
@@ -11010,6 +11204,43 @@ lpfc_prep_seq(struct lpfc_vport *vport, struct hbq_dmabuf *seq_dmabuf) | |||
11010 | return first_iocbq; | 11204 | return first_iocbq; |
11011 | } | 11205 | } |
11012 | 11206 | ||
11207 | static void | ||
11208 | lpfc_sli4_send_seq_to_ulp(struct lpfc_vport *vport, | ||
11209 | struct hbq_dmabuf *seq_dmabuf) | ||
11210 | { | ||
11211 | struct fc_frame_header *fc_hdr; | ||
11212 | struct lpfc_iocbq *iocbq, *curr_iocb, *next_iocb; | ||
11213 | struct lpfc_hba *phba = vport->phba; | ||
11214 | |||
11215 | fc_hdr = (struct fc_frame_header *)seq_dmabuf->hbuf.virt; | ||
11216 | iocbq = lpfc_prep_seq(vport, seq_dmabuf); | ||
11217 | if (!iocbq) { | ||
11218 | lpfc_printf_log(phba, KERN_ERR, LOG_SLI, | ||
11219 | "2707 Ring %d handler: Failed to allocate " | ||
11220 | "iocb Rctl x%x Type x%x received\n", | ||
11221 | LPFC_ELS_RING, | ||
11222 | fc_hdr->fh_r_ctl, fc_hdr->fh_type); | ||
11223 | return; | ||
11224 | } | ||
11225 | if (!lpfc_complete_unsol_iocb(phba, | ||
11226 | &phba->sli.ring[LPFC_ELS_RING], | ||
11227 | iocbq, fc_hdr->fh_r_ctl, | ||
11228 | fc_hdr->fh_type)) | ||
11229 | lpfc_printf_log(phba, KERN_WARNING, LOG_SLI, | ||
11230 | "2540 Ring %d handler: unexpected Rctl " | ||
11231 | "x%x Type x%x received\n", | ||
11232 | LPFC_ELS_RING, | ||
11233 | fc_hdr->fh_r_ctl, fc_hdr->fh_type); | ||
11234 | |||
11235 | /* Free iocb created in lpfc_prep_seq */ | ||
11236 | list_for_each_entry_safe(curr_iocb, next_iocb, | ||
11237 | &iocbq->list, list) { | ||
11238 | list_del_init(&curr_iocb->list); | ||
11239 | lpfc_sli_release_iocbq(phba, curr_iocb); | ||
11240 | } | ||
11241 | lpfc_sli_release_iocbq(phba, iocbq); | ||
11242 | } | ||
11243 | |||
11013 | /** | 11244 | /** |
11014 | * lpfc_sli4_handle_received_buffer - Handle received buffers from firmware | 11245 | * lpfc_sli4_handle_received_buffer - Handle received buffers from firmware |
11015 | * @phba: Pointer to HBA context object. | 11246 | * @phba: Pointer to HBA context object. |
@@ -11030,7 +11261,6 @@ lpfc_sli4_handle_received_buffer(struct lpfc_hba *phba, | |||
11030 | struct fc_frame_header *fc_hdr; | 11261 | struct fc_frame_header *fc_hdr; |
11031 | struct lpfc_vport *vport; | 11262 | struct lpfc_vport *vport; |
11032 | uint32_t fcfi; | 11263 | uint32_t fcfi; |
11033 | struct lpfc_iocbq *iocbq; | ||
11034 | 11264 | ||
11035 | /* Clear hba flag and get all received buffers into the cmplq */ | 11265 | /* Clear hba flag and get all received buffers into the cmplq */ |
11036 | spin_lock_irq(&phba->hbalock); | 11266 | spin_lock_irq(&phba->hbalock); |
@@ -11051,6 +11281,12 @@ lpfc_sli4_handle_received_buffer(struct lpfc_hba *phba, | |||
11051 | lpfc_in_buf_free(phba, &dmabuf->dbuf); | 11281 | lpfc_in_buf_free(phba, &dmabuf->dbuf); |
11052 | return; | 11282 | return; |
11053 | } | 11283 | } |
11284 | /* Handle the basic abort sequence (BA_ABTS) event */ | ||
11285 | if (fc_hdr->fh_r_ctl == FC_RCTL_BA_ABTS) { | ||
11286 | lpfc_sli4_handle_unsol_abort(vport, dmabuf); | ||
11287 | return; | ||
11288 | } | ||
11289 | |||
11054 | /* Link this frame */ | 11290 | /* Link this frame */ |
11055 | seq_dmabuf = lpfc_fc_frame_add(vport, dmabuf); | 11291 | seq_dmabuf = lpfc_fc_frame_add(vport, dmabuf); |
11056 | if (!seq_dmabuf) { | 11292 | if (!seq_dmabuf) { |
@@ -11068,17 +11304,8 @@ lpfc_sli4_handle_received_buffer(struct lpfc_hba *phba, | |||
11068 | dmabuf->tag = -1; | 11304 | dmabuf->tag = -1; |
11069 | return; | 11305 | return; |
11070 | } | 11306 | } |
11071 | fc_hdr = (struct fc_frame_header *)seq_dmabuf->hbuf.virt; | 11307 | /* Send the complete sequence to the upper layer protocol */ |
11072 | iocbq = lpfc_prep_seq(vport, seq_dmabuf); | 11308 | lpfc_sli4_send_seq_to_ulp(vport, seq_dmabuf); |
11073 | if (!lpfc_complete_unsol_iocb(phba, | ||
11074 | &phba->sli.ring[LPFC_ELS_RING], | ||
11075 | iocbq, fc_hdr->fh_r_ctl, | ||
11076 | fc_hdr->fh_type)) | ||
11077 | lpfc_printf_log(phba, KERN_WARNING, LOG_SLI, | ||
11078 | "2540 Ring %d handler: unexpected Rctl " | ||
11079 | "x%x Type x%x received\n", | ||
11080 | LPFC_ELS_RING, | ||
11081 | fc_hdr->fh_r_ctl, fc_hdr->fh_type); | ||
11082 | } | 11309 | } |
11083 | 11310 | ||
11084 | /** | 11311 | /** |
diff --git a/drivers/scsi/lpfc/lpfc_sli.h b/drivers/scsi/lpfc/lpfc_sli.h index ad8094966ff3..0e518b12f414 100644 --- a/drivers/scsi/lpfc/lpfc_sli.h +++ b/drivers/scsi/lpfc/lpfc_sli.h | |||
@@ -113,7 +113,7 @@ typedef struct lpfcMboxq { | |||
113 | return */ | 113 | return */ |
114 | #define MBX_NOWAIT 2 /* issue command then return immediately */ | 114 | #define MBX_NOWAIT 2 /* issue command then return immediately */ |
115 | 115 | ||
116 | #define LPFC_MAX_RING_MASK 4 /* max num of rctl/type masks allowed per | 116 | #define LPFC_MAX_RING_MASK 5 /* max num of rctl/type masks allowed per |
117 | ring */ | 117 | ring */ |
118 | #define LPFC_MAX_RING 4 /* max num of SLI rings used by driver */ | 118 | #define LPFC_MAX_RING 4 /* max num of SLI rings used by driver */ |
119 | 119 | ||
diff --git a/drivers/scsi/lpfc/lpfc_sli4.h b/drivers/scsi/lpfc/lpfc_sli4.h index 97da7589e038..fc3de6fdd709 100644 --- a/drivers/scsi/lpfc/lpfc_sli4.h +++ b/drivers/scsi/lpfc/lpfc_sli4.h | |||
@@ -58,6 +58,11 @@ | |||
58 | #define LPFC_FCOE_FKA_ADV_PER 0 | 58 | #define LPFC_FCOE_FKA_ADV_PER 0 |
59 | #define LPFC_FCOE_FIP_PRIORITY 0x80 | 59 | #define LPFC_FCOE_FIP_PRIORITY 0x80 |
60 | 60 | ||
61 | #define sli4_sid_from_fc_hdr(fc_hdr) \ | ||
62 | ((fc_hdr)->fh_s_id[0] << 16 | \ | ||
63 | (fc_hdr)->fh_s_id[1] << 8 | \ | ||
64 | (fc_hdr)->fh_s_id[2]) | ||
65 | |||
61 | enum lpfc_sli4_queue_type { | 66 | enum lpfc_sli4_queue_type { |
62 | LPFC_EQ, | 67 | LPFC_EQ, |
63 | LPFC_GCQ, | 68 | LPFC_GCQ, |