diff options
Diffstat (limited to 'drivers/scsi/be2iscsi')
-rw-r--r-- | drivers/scsi/be2iscsi/be.h | 2 | ||||
-rw-r--r-- | drivers/scsi/be2iscsi/be_cmds.c | 200 | ||||
-rw-r--r-- | drivers/scsi/be2iscsi/be_cmds.h | 65 | ||||
-rw-r--r-- | drivers/scsi/be2iscsi/be_iscsi.c | 175 | ||||
-rw-r--r-- | drivers/scsi/be2iscsi/be_main.c | 1331 | ||||
-rw-r--r-- | drivers/scsi/be2iscsi/be_main.h | 182 | ||||
-rw-r--r-- | drivers/scsi/be2iscsi/be_mgmt.c | 290 | ||||
-rw-r--r-- | drivers/scsi/be2iscsi/be_mgmt.h | 13 |
8 files changed, 1700 insertions, 558 deletions
diff --git a/drivers/scsi/be2iscsi/be.h b/drivers/scsi/be2iscsi/be.h index 777e7c0bbb4b..2e28f6c419fe 100644 --- a/drivers/scsi/be2iscsi/be.h +++ b/drivers/scsi/be2iscsi/be.h | |||
@@ -128,7 +128,7 @@ struct be_ctrl_info { | |||
128 | 128 | ||
129 | #define PAGE_SHIFT_4K 12 | 129 | #define PAGE_SHIFT_4K 12 |
130 | #define PAGE_SIZE_4K (1 << PAGE_SHIFT_4K) | 130 | #define PAGE_SIZE_4K (1 << PAGE_SHIFT_4K) |
131 | #define mcc_timeout 120000 /* 5s timeout */ | 131 | #define mcc_timeout 120000 /* 12s timeout */ |
132 | 132 | ||
133 | /* Returns number of pages spanned by the data starting at the given addr */ | 133 | /* Returns number of pages spanned by the data starting at the given addr */ |
134 | #define PAGES_4K_SPANNED(_address, size) \ | 134 | #define PAGES_4K_SPANNED(_address, size) \ |
diff --git a/drivers/scsi/be2iscsi/be_cmds.c b/drivers/scsi/be2iscsi/be_cmds.c index e66aa7c11a8a..3338391b64de 100644 --- a/drivers/scsi/be2iscsi/be_cmds.c +++ b/drivers/scsi/be2iscsi/be_cmds.c | |||
@@ -17,9 +17,9 @@ | |||
17 | 17 | ||
18 | #include <scsi/iscsi_proto.h> | 18 | #include <scsi/iscsi_proto.h> |
19 | 19 | ||
20 | #include "be_main.h" | ||
20 | #include "be.h" | 21 | #include "be.h" |
21 | #include "be_mgmt.h" | 22 | #include "be_mgmt.h" |
22 | #include "be_main.h" | ||
23 | 23 | ||
24 | int beiscsi_pci_soft_reset(struct beiscsi_hba *phba) | 24 | int beiscsi_pci_soft_reset(struct beiscsi_hba *phba) |
25 | { | 25 | { |
@@ -158,8 +158,10 @@ int beiscsi_mccq_compl(struct beiscsi_hba *phba, | |||
158 | struct be_cmd_resp_hdr *ioctl_resp_hdr; | 158 | struct be_cmd_resp_hdr *ioctl_resp_hdr; |
159 | struct be_queue_info *mccq = &phba->ctrl.mcc_obj.q; | 159 | struct be_queue_info *mccq = &phba->ctrl.mcc_obj.q; |
160 | 160 | ||
161 | if (beiscsi_error(phba)) | 161 | if (beiscsi_error(phba)) { |
162 | free_mcc_tag(&phba->ctrl, tag); | ||
162 | return -EIO; | 163 | return -EIO; |
164 | } | ||
163 | 165 | ||
164 | /* wait for the mccq completion */ | 166 | /* wait for the mccq completion */ |
165 | rc = wait_event_interruptible_timeout( | 167 | rc = wait_event_interruptible_timeout( |
@@ -173,7 +175,11 @@ int beiscsi_mccq_compl(struct beiscsi_hba *phba, | |||
173 | BEISCSI_LOG_INIT | BEISCSI_LOG_EH | | 175 | BEISCSI_LOG_INIT | BEISCSI_LOG_EH | |
174 | BEISCSI_LOG_CONFIG, | 176 | BEISCSI_LOG_CONFIG, |
175 | "BC_%d : MBX Cmd Completion timed out\n"); | 177 | "BC_%d : MBX Cmd Completion timed out\n"); |
176 | rc = -EAGAIN; | 178 | rc = -EBUSY; |
179 | |||
180 | /* decrement the mccq used count */ | ||
181 | atomic_dec(&phba->ctrl.mcc_obj.q.used); | ||
182 | |||
177 | goto release_mcc_tag; | 183 | goto release_mcc_tag; |
178 | } else | 184 | } else |
179 | rc = 0; | 185 | rc = 0; |
@@ -208,10 +214,18 @@ int beiscsi_mccq_compl(struct beiscsi_hba *phba, | |||
208 | 214 | ||
209 | if (status == MCC_STATUS_INSUFFICIENT_BUFFER) { | 215 | if (status == MCC_STATUS_INSUFFICIENT_BUFFER) { |
210 | ioctl_resp_hdr = (struct be_cmd_resp_hdr *) ioctl_hdr; | 216 | ioctl_resp_hdr = (struct be_cmd_resp_hdr *) ioctl_hdr; |
211 | if (ioctl_resp_hdr->response_length) | 217 | beiscsi_log(phba, KERN_WARNING, |
212 | goto release_mcc_tag; | 218 | BEISCSI_LOG_INIT | BEISCSI_LOG_EH | |
219 | BEISCSI_LOG_CONFIG, | ||
220 | "BC_%d : Insufficent Buffer Error " | ||
221 | "Resp_Len : %d Actual_Resp_Len : %d\n", | ||
222 | ioctl_resp_hdr->response_length, | ||
223 | ioctl_resp_hdr->actual_resp_len); | ||
224 | |||
225 | rc = -EAGAIN; | ||
226 | goto release_mcc_tag; | ||
213 | } | 227 | } |
214 | rc = -EAGAIN; | 228 | rc = -EIO; |
215 | } | 229 | } |
216 | 230 | ||
217 | release_mcc_tag: | 231 | release_mcc_tag: |
@@ -363,7 +377,7 @@ void beiscsi_async_link_state_process(struct beiscsi_hba *phba, | |||
363 | } else if ((evt->port_link_status & ASYNC_EVENT_LINK_UP) || | 377 | } else if ((evt->port_link_status & ASYNC_EVENT_LINK_UP) || |
364 | ((evt->port_link_status & ASYNC_EVENT_LOGICAL) && | 378 | ((evt->port_link_status & ASYNC_EVENT_LOGICAL) && |
365 | (evt->port_fault == BEISCSI_PHY_LINK_FAULT_NONE))) { | 379 | (evt->port_fault == BEISCSI_PHY_LINK_FAULT_NONE))) { |
366 | phba->state = BE_ADAPTER_UP; | 380 | phba->state = BE_ADAPTER_LINK_UP; |
367 | 381 | ||
368 | beiscsi_log(phba, KERN_ERR, | 382 | beiscsi_log(phba, KERN_ERR, |
369 | BEISCSI_LOG_CONFIG | BEISCSI_LOG_INIT, | 383 | BEISCSI_LOG_CONFIG | BEISCSI_LOG_INIT, |
@@ -486,33 +500,47 @@ int be_mcc_notify_wait(struct beiscsi_hba *phba) | |||
486 | **/ | 500 | **/ |
487 | static int be_mbox_db_ready_wait(struct be_ctrl_info *ctrl) | 501 | static int be_mbox_db_ready_wait(struct be_ctrl_info *ctrl) |
488 | { | 502 | { |
503 | #define BEISCSI_MBX_RDY_BIT_TIMEOUT 4000 /* 4sec */ | ||
489 | void __iomem *db = ctrl->db + MPU_MAILBOX_DB_OFFSET; | 504 | void __iomem *db = ctrl->db + MPU_MAILBOX_DB_OFFSET; |
490 | struct beiscsi_hba *phba = pci_get_drvdata(ctrl->pdev); | 505 | struct beiscsi_hba *phba = pci_get_drvdata(ctrl->pdev); |
491 | uint32_t wait = 0; | 506 | unsigned long timeout; |
507 | bool read_flag = false; | ||
508 | int ret = 0, i; | ||
492 | u32 ready; | 509 | u32 ready; |
510 | DECLARE_WAIT_QUEUE_HEAD_ONSTACK(rdybit_check_q); | ||
493 | 511 | ||
494 | do { | 512 | if (beiscsi_error(phba)) |
513 | return -EIO; | ||
495 | 514 | ||
496 | if (beiscsi_error(phba)) | 515 | timeout = jiffies + (HZ * 110); |
497 | return -EIO; | ||
498 | 516 | ||
499 | ready = ioread32(db) & MPU_MAILBOX_DB_RDY_MASK; | 517 | do { |
500 | if (ready) | 518 | for (i = 0; i < BEISCSI_MBX_RDY_BIT_TIMEOUT; i++) { |
501 | break; | 519 | ready = ioread32(db) & MPU_MAILBOX_DB_RDY_MASK; |
520 | if (ready) { | ||
521 | read_flag = true; | ||
522 | break; | ||
523 | } | ||
524 | mdelay(1); | ||
525 | } | ||
502 | 526 | ||
503 | if (wait > BEISCSI_HOST_MBX_TIMEOUT) { | 527 | if (!read_flag) { |
504 | beiscsi_log(phba, KERN_ERR, | 528 | wait_event_timeout(rdybit_check_q, |
505 | BEISCSI_LOG_CONFIG | BEISCSI_LOG_MBOX, | 529 | (read_flag != true), |
506 | "BC_%d : FW Timed Out\n"); | 530 | HZ * 5); |
531 | } | ||
532 | } while ((time_before(jiffies, timeout)) && !read_flag); | ||
533 | |||
534 | if (!read_flag) { | ||
535 | beiscsi_log(phba, KERN_ERR, | ||
536 | BEISCSI_LOG_CONFIG | BEISCSI_LOG_MBOX, | ||
537 | "BC_%d : FW Timed Out\n"); | ||
507 | phba->fw_timeout = true; | 538 | phba->fw_timeout = true; |
508 | beiscsi_ue_detect(phba); | 539 | beiscsi_ue_detect(phba); |
509 | return -EBUSY; | 540 | ret = -EBUSY; |
510 | } | 541 | } |
511 | 542 | ||
512 | mdelay(1); | 543 | return ret; |
513 | wait++; | ||
514 | } while (true); | ||
515 | return 0; | ||
516 | } | 544 | } |
517 | 545 | ||
518 | /* | 546 | /* |
@@ -699,7 +727,7 @@ struct be_mcc_wrb *wrb_from_mccq(struct beiscsi_hba *phba) | |||
699 | struct be_queue_info *mccq = &phba->ctrl.mcc_obj.q; | 727 | struct be_queue_info *mccq = &phba->ctrl.mcc_obj.q; |
700 | struct be_mcc_wrb *wrb; | 728 | struct be_mcc_wrb *wrb; |
701 | 729 | ||
702 | BUG_ON(atomic_read(&mccq->used) >= mccq->len); | 730 | WARN_ON(atomic_read(&mccq->used) >= mccq->len); |
703 | wrb = queue_head_node(mccq); | 731 | wrb = queue_head_node(mccq); |
704 | memset(wrb, 0, sizeof(*wrb)); | 732 | memset(wrb, 0, sizeof(*wrb)); |
705 | wrb->tag0 = (mccq->head & 0x000000FF) << 16; | 733 | wrb->tag0 = (mccq->head & 0x000000FF) << 16; |
@@ -1009,10 +1037,29 @@ int beiscsi_cmd_q_destroy(struct be_ctrl_info *ctrl, struct be_queue_info *q, | |||
1009 | return status; | 1037 | return status; |
1010 | } | 1038 | } |
1011 | 1039 | ||
1040 | /** | ||
1041 | * be_cmd_create_default_pdu_queue()- Create DEFQ for the adapter | ||
1042 | * @ctrl: ptr to ctrl_info | ||
1043 | * @cq: Completion Queue | ||
1044 | * @dq: Default Queue | ||
1045 | * @lenght: ring size | ||
1046 | * @entry_size: size of each entry in DEFQ | ||
1047 | * @is_header: Header or Data DEFQ | ||
1048 | * @ulp_num: Bind to which ULP | ||
1049 | * | ||
1050 | * Create HDR/Data DEFQ for the passed ULP. Unsol PDU are posted | ||
1051 | * on this queue by the FW | ||
1052 | * | ||
1053 | * return | ||
1054 | * Success: 0 | ||
1055 | * Failure: Non-Zero Value | ||
1056 | * | ||
1057 | **/ | ||
1012 | int be_cmd_create_default_pdu_queue(struct be_ctrl_info *ctrl, | 1058 | int be_cmd_create_default_pdu_queue(struct be_ctrl_info *ctrl, |
1013 | struct be_queue_info *cq, | 1059 | struct be_queue_info *cq, |
1014 | struct be_queue_info *dq, int length, | 1060 | struct be_queue_info *dq, int length, |
1015 | int entry_size) | 1061 | int entry_size, uint8_t is_header, |
1062 | uint8_t ulp_num) | ||
1016 | { | 1063 | { |
1017 | struct be_mcc_wrb *wrb = wrb_from_mbox(&ctrl->mbox_mem); | 1064 | struct be_mcc_wrb *wrb = wrb_from_mbox(&ctrl->mbox_mem); |
1018 | struct be_defq_create_req *req = embedded_payload(wrb); | 1065 | struct be_defq_create_req *req = embedded_payload(wrb); |
@@ -1030,6 +1077,11 @@ int be_cmd_create_default_pdu_queue(struct be_ctrl_info *ctrl, | |||
1030 | OPCODE_COMMON_ISCSI_DEFQ_CREATE, sizeof(*req)); | 1077 | OPCODE_COMMON_ISCSI_DEFQ_CREATE, sizeof(*req)); |
1031 | 1078 | ||
1032 | req->num_pages = PAGES_4K_SPANNED(q_mem->va, q_mem->size); | 1079 | req->num_pages = PAGES_4K_SPANNED(q_mem->va, q_mem->size); |
1080 | if (phba->fw_config.dual_ulp_aware) { | ||
1081 | req->ulp_num = ulp_num; | ||
1082 | req->dua_feature |= (1 << BEISCSI_DUAL_ULP_AWARE_BIT); | ||
1083 | req->dua_feature |= (1 << BEISCSI_BIND_Q_TO_ULP_BIT); | ||
1084 | } | ||
1033 | 1085 | ||
1034 | if (is_chip_be2_be3r(phba)) { | 1086 | if (is_chip_be2_be3r(phba)) { |
1035 | AMAP_SET_BITS(struct amap_be_default_pdu_context, | 1087 | AMAP_SET_BITS(struct amap_be_default_pdu_context, |
@@ -1067,22 +1119,53 @@ int be_cmd_create_default_pdu_queue(struct be_ctrl_info *ctrl, | |||
1067 | 1119 | ||
1068 | status = be_mbox_notify(ctrl); | 1120 | status = be_mbox_notify(ctrl); |
1069 | if (!status) { | 1121 | if (!status) { |
1122 | struct be_ring *defq_ring; | ||
1070 | struct be_defq_create_resp *resp = embedded_payload(wrb); | 1123 | struct be_defq_create_resp *resp = embedded_payload(wrb); |
1071 | 1124 | ||
1072 | dq->id = le16_to_cpu(resp->id); | 1125 | dq->id = le16_to_cpu(resp->id); |
1073 | dq->created = true; | 1126 | dq->created = true; |
1127 | if (is_header) | ||
1128 | defq_ring = &phba->phwi_ctrlr->default_pdu_hdr[ulp_num]; | ||
1129 | else | ||
1130 | defq_ring = &phba->phwi_ctrlr-> | ||
1131 | default_pdu_data[ulp_num]; | ||
1132 | |||
1133 | defq_ring->id = dq->id; | ||
1134 | |||
1135 | if (!phba->fw_config.dual_ulp_aware) { | ||
1136 | defq_ring->ulp_num = BEISCSI_ULP0; | ||
1137 | defq_ring->doorbell_offset = DB_RXULP0_OFFSET; | ||
1138 | } else { | ||
1139 | defq_ring->ulp_num = resp->ulp_num; | ||
1140 | defq_ring->doorbell_offset = resp->doorbell_offset; | ||
1141 | } | ||
1074 | } | 1142 | } |
1075 | spin_unlock(&ctrl->mbox_lock); | 1143 | spin_unlock(&ctrl->mbox_lock); |
1076 | 1144 | ||
1077 | return status; | 1145 | return status; |
1078 | } | 1146 | } |
1079 | 1147 | ||
1080 | int be_cmd_wrbq_create(struct be_ctrl_info *ctrl, struct be_dma_mem *q_mem, | 1148 | /** |
1081 | struct be_queue_info *wrbq) | 1149 | * be_cmd_wrbq_create()- Create WRBQ |
1150 | * @ctrl: ptr to ctrl_info | ||
1151 | * @q_mem: memory details for the queue | ||
1152 | * @wrbq: queue info | ||
1153 | * @pwrb_context: ptr to wrb_context | ||
1154 | * @ulp_num: ULP on which the WRBQ is to be created | ||
1155 | * | ||
1156 | * Create WRBQ on the passed ULP_NUM. | ||
1157 | * | ||
1158 | **/ | ||
1159 | int be_cmd_wrbq_create(struct be_ctrl_info *ctrl, | ||
1160 | struct be_dma_mem *q_mem, | ||
1161 | struct be_queue_info *wrbq, | ||
1162 | struct hwi_wrb_context *pwrb_context, | ||
1163 | uint8_t ulp_num) | ||
1082 | { | 1164 | { |
1083 | struct be_mcc_wrb *wrb = wrb_from_mbox(&ctrl->mbox_mem); | 1165 | struct be_mcc_wrb *wrb = wrb_from_mbox(&ctrl->mbox_mem); |
1084 | struct be_wrbq_create_req *req = embedded_payload(wrb); | 1166 | struct be_wrbq_create_req *req = embedded_payload(wrb); |
1085 | struct be_wrbq_create_resp *resp = embedded_payload(wrb); | 1167 | struct be_wrbq_create_resp *resp = embedded_payload(wrb); |
1168 | struct beiscsi_hba *phba = pci_get_drvdata(ctrl->pdev); | ||
1086 | int status; | 1169 | int status; |
1087 | 1170 | ||
1088 | spin_lock(&ctrl->mbox_lock); | 1171 | spin_lock(&ctrl->mbox_lock); |
@@ -1093,17 +1176,78 @@ int be_cmd_wrbq_create(struct be_ctrl_info *ctrl, struct be_dma_mem *q_mem, | |||
1093 | be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_ISCSI, | 1176 | be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_ISCSI, |
1094 | OPCODE_COMMON_ISCSI_WRBQ_CREATE, sizeof(*req)); | 1177 | OPCODE_COMMON_ISCSI_WRBQ_CREATE, sizeof(*req)); |
1095 | req->num_pages = PAGES_4K_SPANNED(q_mem->va, q_mem->size); | 1178 | req->num_pages = PAGES_4K_SPANNED(q_mem->va, q_mem->size); |
1179 | |||
1180 | if (phba->fw_config.dual_ulp_aware) { | ||
1181 | req->ulp_num = ulp_num; | ||
1182 | req->dua_feature |= (1 << BEISCSI_DUAL_ULP_AWARE_BIT); | ||
1183 | req->dua_feature |= (1 << BEISCSI_BIND_Q_TO_ULP_BIT); | ||
1184 | } | ||
1185 | |||
1096 | be_cmd_page_addrs_prepare(req->pages, ARRAY_SIZE(req->pages), q_mem); | 1186 | be_cmd_page_addrs_prepare(req->pages, ARRAY_SIZE(req->pages), q_mem); |
1097 | 1187 | ||
1098 | status = be_mbox_notify(ctrl); | 1188 | status = be_mbox_notify(ctrl); |
1099 | if (!status) { | 1189 | if (!status) { |
1100 | wrbq->id = le16_to_cpu(resp->cid); | 1190 | wrbq->id = le16_to_cpu(resp->cid); |
1101 | wrbq->created = true; | 1191 | wrbq->created = true; |
1192 | |||
1193 | pwrb_context->cid = wrbq->id; | ||
1194 | if (!phba->fw_config.dual_ulp_aware) { | ||
1195 | pwrb_context->doorbell_offset = DB_TXULP0_OFFSET; | ||
1196 | pwrb_context->ulp_num = BEISCSI_ULP0; | ||
1197 | } else { | ||
1198 | pwrb_context->ulp_num = resp->ulp_num; | ||
1199 | pwrb_context->doorbell_offset = resp->doorbell_offset; | ||
1200 | } | ||
1102 | } | 1201 | } |
1103 | spin_unlock(&ctrl->mbox_lock); | 1202 | spin_unlock(&ctrl->mbox_lock); |
1104 | return status; | 1203 | return status; |
1105 | } | 1204 | } |
1106 | 1205 | ||
1206 | int be_cmd_iscsi_post_template_hdr(struct be_ctrl_info *ctrl, | ||
1207 | struct be_dma_mem *q_mem) | ||
1208 | { | ||
1209 | struct be_mcc_wrb *wrb = wrb_from_mbox(&ctrl->mbox_mem); | ||
1210 | struct be_post_template_pages_req *req = embedded_payload(wrb); | ||
1211 | int status; | ||
1212 | |||
1213 | spin_lock(&ctrl->mbox_lock); | ||
1214 | |||
1215 | memset(wrb, 0, sizeof(*wrb)); | ||
1216 | be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0); | ||
1217 | be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON, | ||
1218 | OPCODE_COMMON_ADD_TEMPLATE_HEADER_BUFFERS, | ||
1219 | sizeof(*req)); | ||
1220 | |||
1221 | req->num_pages = PAGES_4K_SPANNED(q_mem->va, q_mem->size); | ||
1222 | req->type = BEISCSI_TEMPLATE_HDR_TYPE_ISCSI; | ||
1223 | be_cmd_page_addrs_prepare(req->pages, ARRAY_SIZE(req->pages), q_mem); | ||
1224 | |||
1225 | status = be_mbox_notify(ctrl); | ||
1226 | spin_unlock(&ctrl->mbox_lock); | ||
1227 | return status; | ||
1228 | } | ||
1229 | |||
1230 | int be_cmd_iscsi_remove_template_hdr(struct be_ctrl_info *ctrl) | ||
1231 | { | ||
1232 | struct be_mcc_wrb *wrb = wrb_from_mbox(&ctrl->mbox_mem); | ||
1233 | struct be_remove_template_pages_req *req = embedded_payload(wrb); | ||
1234 | int status; | ||
1235 | |||
1236 | spin_lock(&ctrl->mbox_lock); | ||
1237 | |||
1238 | memset(wrb, 0, sizeof(*wrb)); | ||
1239 | be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0); | ||
1240 | be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON, | ||
1241 | OPCODE_COMMON_REMOVE_TEMPLATE_HEADER_BUFFERS, | ||
1242 | sizeof(*req)); | ||
1243 | |||
1244 | req->type = BEISCSI_TEMPLATE_HDR_TYPE_ISCSI; | ||
1245 | |||
1246 | status = be_mbox_notify(ctrl); | ||
1247 | spin_unlock(&ctrl->mbox_lock); | ||
1248 | return status; | ||
1249 | } | ||
1250 | |||
1107 | int be_cmd_iscsi_post_sgl_pages(struct be_ctrl_info *ctrl, | 1251 | int be_cmd_iscsi_post_sgl_pages(struct be_ctrl_info *ctrl, |
1108 | struct be_dma_mem *q_mem, | 1252 | struct be_dma_mem *q_mem, |
1109 | u32 page_offset, u32 num_pages) | 1253 | u32 page_offset, u32 num_pages) |
diff --git a/drivers/scsi/be2iscsi/be_cmds.h b/drivers/scsi/be2iscsi/be_cmds.h index 99073086dfe0..627ebbe0172c 100644 --- a/drivers/scsi/be2iscsi/be_cmds.h +++ b/drivers/scsi/be2iscsi/be_cmds.h | |||
@@ -40,6 +40,7 @@ struct be_mcc_wrb { | |||
40 | u32 tag1; /* dword 3 */ | 40 | u32 tag1; /* dword 3 */ |
41 | u32 rsvd; /* dword 4 */ | 41 | u32 rsvd; /* dword 4 */ |
42 | union { | 42 | union { |
43 | #define EMBED_MBX_MAX_PAYLOAD_SIZE 220 | ||
43 | u8 embedded_payload[236]; /* used by embedded cmds */ | 44 | u8 embedded_payload[236]; /* used by embedded cmds */ |
44 | struct be_sge sgl[19]; /* used by non-embedded cmds */ | 45 | struct be_sge sgl[19]; /* used by non-embedded cmds */ |
45 | } payload; | 46 | } payload; |
@@ -162,6 +163,8 @@ struct be_mcc_mailbox { | |||
162 | #define OPCODE_COMMON_CQ_CREATE 12 | 163 | #define OPCODE_COMMON_CQ_CREATE 12 |
163 | #define OPCODE_COMMON_EQ_CREATE 13 | 164 | #define OPCODE_COMMON_EQ_CREATE 13 |
164 | #define OPCODE_COMMON_MCC_CREATE 21 | 165 | #define OPCODE_COMMON_MCC_CREATE 21 |
166 | #define OPCODE_COMMON_ADD_TEMPLATE_HEADER_BUFFERS 24 | ||
167 | #define OPCODE_COMMON_REMOVE_TEMPLATE_HEADER_BUFFERS 25 | ||
165 | #define OPCODE_COMMON_GET_CNTL_ATTRIBUTES 32 | 168 | #define OPCODE_COMMON_GET_CNTL_ATTRIBUTES 32 |
166 | #define OPCODE_COMMON_GET_FW_VERSION 35 | 169 | #define OPCODE_COMMON_GET_FW_VERSION 35 |
167 | #define OPCODE_COMMON_MODIFY_EQ_DELAY 41 | 170 | #define OPCODE_COMMON_MODIFY_EQ_DELAY 41 |
@@ -217,6 +220,10 @@ struct phys_addr { | |||
217 | u32 hi; | 220 | u32 hi; |
218 | }; | 221 | }; |
219 | 222 | ||
223 | struct virt_addr { | ||
224 | u32 lo; | ||
225 | u32 hi; | ||
226 | }; | ||
220 | /************************** | 227 | /************************** |
221 | * BE Command definitions * | 228 | * BE Command definitions * |
222 | **************************/ | 229 | **************************/ |
@@ -722,7 +729,13 @@ int be_mbox_notify(struct be_ctrl_info *ctrl); | |||
722 | int be_cmd_create_default_pdu_queue(struct be_ctrl_info *ctrl, | 729 | int be_cmd_create_default_pdu_queue(struct be_ctrl_info *ctrl, |
723 | struct be_queue_info *cq, | 730 | struct be_queue_info *cq, |
724 | struct be_queue_info *dq, int length, | 731 | struct be_queue_info *dq, int length, |
725 | int entry_size); | 732 | int entry_size, uint8_t is_header, |
733 | uint8_t ulp_num); | ||
734 | |||
735 | int be_cmd_iscsi_post_template_hdr(struct be_ctrl_info *ctrl, | ||
736 | struct be_dma_mem *q_mem); | ||
737 | |||
738 | int be_cmd_iscsi_remove_template_hdr(struct be_ctrl_info *ctrl); | ||
726 | 739 | ||
727 | int be_cmd_iscsi_post_sgl_pages(struct be_ctrl_info *ctrl, | 740 | int be_cmd_iscsi_post_sgl_pages(struct be_ctrl_info *ctrl, |
728 | struct be_dma_mem *q_mem, u32 page_offset, | 741 | struct be_dma_mem *q_mem, u32 page_offset, |
@@ -731,7 +744,9 @@ int be_cmd_iscsi_post_sgl_pages(struct be_ctrl_info *ctrl, | |||
731 | int beiscsi_cmd_reset_function(struct beiscsi_hba *phba); | 744 | int beiscsi_cmd_reset_function(struct beiscsi_hba *phba); |
732 | 745 | ||
733 | int be_cmd_wrbq_create(struct be_ctrl_info *ctrl, struct be_dma_mem *q_mem, | 746 | int be_cmd_wrbq_create(struct be_ctrl_info *ctrl, struct be_dma_mem *q_mem, |
734 | struct be_queue_info *wrbq); | 747 | struct be_queue_info *wrbq, |
748 | struct hwi_wrb_context *pwrb_context, | ||
749 | uint8_t ulp_num); | ||
735 | 750 | ||
736 | bool is_link_state_evt(u32 trailer); | 751 | bool is_link_state_evt(u32 trailer); |
737 | 752 | ||
@@ -776,7 +791,9 @@ struct be_defq_create_req { | |||
776 | struct be_cmd_req_hdr hdr; | 791 | struct be_cmd_req_hdr hdr; |
777 | u16 num_pages; | 792 | u16 num_pages; |
778 | u8 ulp_num; | 793 | u8 ulp_num; |
779 | u8 rsvd0; | 794 | #define BEISCSI_DUAL_ULP_AWARE_BIT 0 /* Byte 3 - Bit 0 */ |
795 | #define BEISCSI_BIND_Q_TO_ULP_BIT 1 /* Byte 3 - Bit 1 */ | ||
796 | u8 dua_feature; | ||
780 | struct be_default_pdu_context context; | 797 | struct be_default_pdu_context context; |
781 | struct phys_addr pages[8]; | 798 | struct phys_addr pages[8]; |
782 | } __packed; | 799 | } __packed; |
@@ -784,6 +801,27 @@ struct be_defq_create_req { | |||
784 | struct be_defq_create_resp { | 801 | struct be_defq_create_resp { |
785 | struct be_cmd_req_hdr hdr; | 802 | struct be_cmd_req_hdr hdr; |
786 | u16 id; | 803 | u16 id; |
804 | u8 rsvd0; | ||
805 | u8 ulp_num; | ||
806 | u32 doorbell_offset; | ||
807 | u16 register_set; | ||
808 | u16 doorbell_format; | ||
809 | } __packed; | ||
810 | |||
811 | struct be_post_template_pages_req { | ||
812 | struct be_cmd_req_hdr hdr; | ||
813 | u16 num_pages; | ||
814 | #define BEISCSI_TEMPLATE_HDR_TYPE_ISCSI 0x1 | ||
815 | u16 type; | ||
816 | struct phys_addr scratch_pa; | ||
817 | struct virt_addr scratch_va; | ||
818 | struct virt_addr pages_va; | ||
819 | struct phys_addr pages[16]; | ||
820 | } __packed; | ||
821 | |||
822 | struct be_remove_template_pages_req { | ||
823 | struct be_cmd_req_hdr hdr; | ||
824 | u16 type; | ||
787 | u16 rsvd0; | 825 | u16 rsvd0; |
788 | } __packed; | 826 | } __packed; |
789 | 827 | ||
@@ -800,14 +838,18 @@ struct be_wrbq_create_req { | |||
800 | struct be_cmd_req_hdr hdr; | 838 | struct be_cmd_req_hdr hdr; |
801 | u16 num_pages; | 839 | u16 num_pages; |
802 | u8 ulp_num; | 840 | u8 ulp_num; |
803 | u8 rsvd0; | 841 | u8 dua_feature; |
804 | struct phys_addr pages[8]; | 842 | struct phys_addr pages[8]; |
805 | } __packed; | 843 | } __packed; |
806 | 844 | ||
807 | struct be_wrbq_create_resp { | 845 | struct be_wrbq_create_resp { |
808 | struct be_cmd_resp_hdr resp_hdr; | 846 | struct be_cmd_resp_hdr resp_hdr; |
809 | u16 cid; | 847 | u16 cid; |
810 | u16 rsvd0; | 848 | u8 rsvd0; |
849 | u8 ulp_num; | ||
850 | u32 doorbell_offset; | ||
851 | u16 register_set; | ||
852 | u16 doorbell_format; | ||
811 | } __packed; | 853 | } __packed; |
812 | 854 | ||
813 | #define SOL_CID_MASK 0x0000FFC0 | 855 | #define SOL_CID_MASK 0x0000FFC0 |
@@ -1002,6 +1044,7 @@ union tcp_upload_params { | |||
1002 | } __packed; | 1044 | } __packed; |
1003 | 1045 | ||
1004 | struct be_ulp_fw_cfg { | 1046 | struct be_ulp_fw_cfg { |
1047 | #define BEISCSI_ULP_ISCSI_INI_MODE 0x10 | ||
1005 | u32 ulp_mode; | 1048 | u32 ulp_mode; |
1006 | u32 etx_base; | 1049 | u32 etx_base; |
1007 | u32 etx_count; | 1050 | u32 etx_count; |
@@ -1017,14 +1060,26 @@ struct be_ulp_fw_cfg { | |||
1017 | u32 icd_count; | 1060 | u32 icd_count; |
1018 | }; | 1061 | }; |
1019 | 1062 | ||
1063 | struct be_ulp_chain_icd { | ||
1064 | u32 chain_base; | ||
1065 | u32 chain_count; | ||
1066 | }; | ||
1067 | |||
1020 | struct be_fw_cfg { | 1068 | struct be_fw_cfg { |
1021 | struct be_cmd_req_hdr hdr; | 1069 | struct be_cmd_req_hdr hdr; |
1022 | u32 be_config_number; | 1070 | u32 be_config_number; |
1023 | u32 asic_revision; | 1071 | u32 asic_revision; |
1024 | u32 phys_port; | 1072 | u32 phys_port; |
1073 | #define BEISCSI_FUNC_ISCSI_INI_MODE 0x10 | ||
1074 | #define BEISCSI_FUNC_DUA_MODE 0x800 | ||
1025 | u32 function_mode; | 1075 | u32 function_mode; |
1026 | struct be_ulp_fw_cfg ulp[2]; | 1076 | struct be_ulp_fw_cfg ulp[2]; |
1027 | u32 function_caps; | 1077 | u32 function_caps; |
1078 | u32 cqid_base; | ||
1079 | u32 cqid_count; | ||
1080 | u32 eqid_base; | ||
1081 | u32 eqid_count; | ||
1082 | struct be_ulp_chain_icd chain_icd[2]; | ||
1028 | } __packed; | 1083 | } __packed; |
1029 | 1084 | ||
1030 | struct be_cmd_get_all_if_id_req { | 1085 | struct be_cmd_get_all_if_id_req { |
diff --git a/drivers/scsi/be2iscsi/be_iscsi.c b/drivers/scsi/be2iscsi/be_iscsi.c index ef36be003f67..ffadbee0b4d9 100644 --- a/drivers/scsi/be2iscsi/be_iscsi.c +++ b/drivers/scsi/be2iscsi/be_iscsi.c | |||
@@ -58,10 +58,15 @@ struct iscsi_cls_session *beiscsi_session_create(struct iscsi_endpoint *ep, | |||
58 | } | 58 | } |
59 | beiscsi_ep = ep->dd_data; | 59 | beiscsi_ep = ep->dd_data; |
60 | phba = beiscsi_ep->phba; | 60 | phba = beiscsi_ep->phba; |
61 | shost = phba->shost; | ||
62 | 61 | ||
63 | beiscsi_log(phba, KERN_INFO, BEISCSI_LOG_CONFIG, | 62 | if (phba->state & BE_ADAPTER_PCI_ERR) { |
64 | "BS_%d : In beiscsi_session_create\n"); | 63 | beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_CONFIG, |
64 | "BS_%d : PCI_ERROR Recovery\n"); | ||
65 | return NULL; | ||
66 | } else { | ||
67 | beiscsi_log(phba, KERN_INFO, BEISCSI_LOG_CONFIG, | ||
68 | "BS_%d : In beiscsi_session_create\n"); | ||
69 | } | ||
65 | 70 | ||
66 | if (cmds_max > beiscsi_ep->phba->params.wrbs_per_cxn) { | 71 | if (cmds_max > beiscsi_ep->phba->params.wrbs_per_cxn) { |
67 | beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_CONFIG, | 72 | beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_CONFIG, |
@@ -74,6 +79,7 @@ struct iscsi_cls_session *beiscsi_session_create(struct iscsi_endpoint *ep, | |||
74 | cmds_max = beiscsi_ep->phba->params.wrbs_per_cxn; | 79 | cmds_max = beiscsi_ep->phba->params.wrbs_per_cxn; |
75 | } | 80 | } |
76 | 81 | ||
82 | shost = phba->shost; | ||
77 | cls_session = iscsi_session_setup(&beiscsi_iscsi_transport, | 83 | cls_session = iscsi_session_setup(&beiscsi_iscsi_transport, |
78 | shost, cmds_max, | 84 | shost, cmds_max, |
79 | sizeof(*beiscsi_sess), | 85 | sizeof(*beiscsi_sess), |
@@ -194,6 +200,8 @@ int beiscsi_conn_bind(struct iscsi_cls_session *cls_session, | |||
194 | struct beiscsi_conn *beiscsi_conn = conn->dd_data; | 200 | struct beiscsi_conn *beiscsi_conn = conn->dd_data; |
195 | struct Scsi_Host *shost = iscsi_session_to_shost(cls_session); | 201 | struct Scsi_Host *shost = iscsi_session_to_shost(cls_session); |
196 | struct beiscsi_hba *phba = iscsi_host_priv(shost); | 202 | struct beiscsi_hba *phba = iscsi_host_priv(shost); |
203 | struct hwi_controller *phwi_ctrlr = phba->phwi_ctrlr; | ||
204 | struct hwi_wrb_context *pwrb_context; | ||
197 | struct beiscsi_endpoint *beiscsi_ep; | 205 | struct beiscsi_endpoint *beiscsi_ep; |
198 | struct iscsi_endpoint *ep; | 206 | struct iscsi_endpoint *ep; |
199 | 207 | ||
@@ -214,9 +222,13 @@ int beiscsi_conn_bind(struct iscsi_cls_session *cls_session, | |||
214 | return -EEXIST; | 222 | return -EEXIST; |
215 | } | 223 | } |
216 | 224 | ||
225 | pwrb_context = &phwi_ctrlr->wrb_context[BE_GET_CRI_FROM_CID( | ||
226 | beiscsi_ep->ep_cid)]; | ||
227 | |||
217 | beiscsi_conn->beiscsi_conn_cid = beiscsi_ep->ep_cid; | 228 | beiscsi_conn->beiscsi_conn_cid = beiscsi_ep->ep_cid; |
218 | beiscsi_conn->ep = beiscsi_ep; | 229 | beiscsi_conn->ep = beiscsi_ep; |
219 | beiscsi_ep->conn = beiscsi_conn; | 230 | beiscsi_ep->conn = beiscsi_conn; |
231 | beiscsi_conn->doorbell_offset = pwrb_context->doorbell_offset; | ||
220 | 232 | ||
221 | beiscsi_log(phba, KERN_INFO, BEISCSI_LOG_CONFIG, | 233 | beiscsi_log(phba, KERN_INFO, BEISCSI_LOG_CONFIG, |
222 | "BS_%d : beiscsi_conn=%p conn=%p ep_cid=%d\n", | 234 | "BS_%d : beiscsi_conn=%p conn=%p ep_cid=%d\n", |
@@ -265,13 +277,17 @@ static int beiscsi_create_ipv6_iface(struct beiscsi_hba *phba) | |||
265 | 277 | ||
266 | void beiscsi_create_def_ifaces(struct beiscsi_hba *phba) | 278 | void beiscsi_create_def_ifaces(struct beiscsi_hba *phba) |
267 | { | 279 | { |
268 | struct be_cmd_get_if_info_resp if_info; | 280 | struct be_cmd_get_if_info_resp *if_info; |
269 | 281 | ||
270 | if (!mgmt_get_if_info(phba, BE2_IPV4, &if_info)) | 282 | if (!mgmt_get_if_info(phba, BE2_IPV4, &if_info)) { |
271 | beiscsi_create_ipv4_iface(phba); | 283 | beiscsi_create_ipv4_iface(phba); |
284 | kfree(if_info); | ||
285 | } | ||
272 | 286 | ||
273 | if (!mgmt_get_if_info(phba, BE2_IPV6, &if_info)) | 287 | if (!mgmt_get_if_info(phba, BE2_IPV6, &if_info)) { |
274 | beiscsi_create_ipv6_iface(phba); | 288 | beiscsi_create_ipv6_iface(phba); |
289 | kfree(if_info); | ||
290 | } | ||
275 | } | 291 | } |
276 | 292 | ||
277 | void beiscsi_destroy_def_ifaces(struct beiscsi_hba *phba) | 293 | void beiscsi_destroy_def_ifaces(struct beiscsi_hba *phba) |
@@ -467,6 +483,12 @@ int be2iscsi_iface_set_param(struct Scsi_Host *shost, | |||
467 | uint32_t rm_len = dt_len; | 483 | uint32_t rm_len = dt_len; |
468 | int ret = 0 ; | 484 | int ret = 0 ; |
469 | 485 | ||
486 | if (phba->state & BE_ADAPTER_PCI_ERR) { | ||
487 | beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_CONFIG, | ||
488 | "BS_%d : In PCI_ERROR Recovery\n"); | ||
489 | return -EBUSY; | ||
490 | } | ||
491 | |||
470 | nla_for_each_attr(attrib, data, dt_len, rm_len) { | 492 | nla_for_each_attr(attrib, data, dt_len, rm_len) { |
471 | iface_param = nla_data(attrib); | 493 | iface_param = nla_data(attrib); |
472 | 494 | ||
@@ -512,59 +534,60 @@ static int be2iscsi_get_if_param(struct beiscsi_hba *phba, | |||
512 | struct iscsi_iface *iface, int param, | 534 | struct iscsi_iface *iface, int param, |
513 | char *buf) | 535 | char *buf) |
514 | { | 536 | { |
515 | struct be_cmd_get_if_info_resp if_info; | 537 | struct be_cmd_get_if_info_resp *if_info; |
516 | int len, ip_type = BE2_IPV4; | 538 | int len, ip_type = BE2_IPV4; |
517 | 539 | ||
518 | memset(&if_info, 0, sizeof(if_info)); | ||
519 | |||
520 | if (iface->iface_type == ISCSI_IFACE_TYPE_IPV6) | 540 | if (iface->iface_type == ISCSI_IFACE_TYPE_IPV6) |
521 | ip_type = BE2_IPV6; | 541 | ip_type = BE2_IPV6; |
522 | 542 | ||
523 | len = mgmt_get_if_info(phba, ip_type, &if_info); | 543 | len = mgmt_get_if_info(phba, ip_type, &if_info); |
524 | if (len) | 544 | if (len) { |
545 | kfree(if_info); | ||
525 | return len; | 546 | return len; |
547 | } | ||
526 | 548 | ||
527 | switch (param) { | 549 | switch (param) { |
528 | case ISCSI_NET_PARAM_IPV4_ADDR: | 550 | case ISCSI_NET_PARAM_IPV4_ADDR: |
529 | len = sprintf(buf, "%pI4\n", &if_info.ip_addr.addr); | 551 | len = sprintf(buf, "%pI4\n", if_info->ip_addr.addr); |
530 | break; | 552 | break; |
531 | case ISCSI_NET_PARAM_IPV6_ADDR: | 553 | case ISCSI_NET_PARAM_IPV6_ADDR: |
532 | len = sprintf(buf, "%pI6\n", &if_info.ip_addr.addr); | 554 | len = sprintf(buf, "%pI6\n", if_info->ip_addr.addr); |
533 | break; | 555 | break; |
534 | case ISCSI_NET_PARAM_IPV4_BOOTPROTO: | 556 | case ISCSI_NET_PARAM_IPV4_BOOTPROTO: |
535 | if (!if_info.dhcp_state) | 557 | if (!if_info->dhcp_state) |
536 | len = sprintf(buf, "static\n"); | 558 | len = sprintf(buf, "static\n"); |
537 | else | 559 | else |
538 | len = sprintf(buf, "dhcp\n"); | 560 | len = sprintf(buf, "dhcp\n"); |
539 | break; | 561 | break; |
540 | case ISCSI_NET_PARAM_IPV4_SUBNET: | 562 | case ISCSI_NET_PARAM_IPV4_SUBNET: |
541 | len = sprintf(buf, "%pI4\n", &if_info.ip_addr.subnet_mask); | 563 | len = sprintf(buf, "%pI4\n", if_info->ip_addr.subnet_mask); |
542 | break; | 564 | break; |
543 | case ISCSI_NET_PARAM_VLAN_ENABLED: | 565 | case ISCSI_NET_PARAM_VLAN_ENABLED: |
544 | len = sprintf(buf, "%s\n", | 566 | len = sprintf(buf, "%s\n", |
545 | (if_info.vlan_priority == BEISCSI_VLAN_DISABLE) | 567 | (if_info->vlan_priority == BEISCSI_VLAN_DISABLE) |
546 | ? "Disabled\n" : "Enabled\n"); | 568 | ? "Disabled\n" : "Enabled\n"); |
547 | break; | 569 | break; |
548 | case ISCSI_NET_PARAM_VLAN_ID: | 570 | case ISCSI_NET_PARAM_VLAN_ID: |
549 | if (if_info.vlan_priority == BEISCSI_VLAN_DISABLE) | 571 | if (if_info->vlan_priority == BEISCSI_VLAN_DISABLE) |
550 | return -EINVAL; | 572 | return -EINVAL; |
551 | else | 573 | else |
552 | len = sprintf(buf, "%d\n", | 574 | len = sprintf(buf, "%d\n", |
553 | (if_info.vlan_priority & | 575 | (if_info->vlan_priority & |
554 | ISCSI_MAX_VLAN_ID)); | 576 | ISCSI_MAX_VLAN_ID)); |
555 | break; | 577 | break; |
556 | case ISCSI_NET_PARAM_VLAN_PRIORITY: | 578 | case ISCSI_NET_PARAM_VLAN_PRIORITY: |
557 | if (if_info.vlan_priority == BEISCSI_VLAN_DISABLE) | 579 | if (if_info->vlan_priority == BEISCSI_VLAN_DISABLE) |
558 | return -EINVAL; | 580 | return -EINVAL; |
559 | else | 581 | else |
560 | len = sprintf(buf, "%d\n", | 582 | len = sprintf(buf, "%d\n", |
561 | ((if_info.vlan_priority >> 13) & | 583 | ((if_info->vlan_priority >> 13) & |
562 | ISCSI_MAX_VLAN_PRIORITY)); | 584 | ISCSI_MAX_VLAN_PRIORITY)); |
563 | break; | 585 | break; |
564 | default: | 586 | default: |
565 | WARN_ON(1); | 587 | WARN_ON(1); |
566 | } | 588 | } |
567 | 589 | ||
590 | kfree(if_info); | ||
568 | return len; | 591 | return len; |
569 | } | 592 | } |
570 | 593 | ||
@@ -577,6 +600,12 @@ int be2iscsi_iface_get_param(struct iscsi_iface *iface, | |||
577 | struct be_cmd_get_def_gateway_resp gateway; | 600 | struct be_cmd_get_def_gateway_resp gateway; |
578 | int len = -ENOSYS; | 601 | int len = -ENOSYS; |
579 | 602 | ||
603 | if (phba->state & BE_ADAPTER_PCI_ERR) { | ||
604 | beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_CONFIG, | ||
605 | "BS_%d : In PCI_ERROR Recovery\n"); | ||
606 | return -EBUSY; | ||
607 | } | ||
608 | |||
580 | switch (param) { | 609 | switch (param) { |
581 | case ISCSI_NET_PARAM_IPV4_ADDR: | 610 | case ISCSI_NET_PARAM_IPV4_ADDR: |
582 | case ISCSI_NET_PARAM_IPV4_SUBNET: | 611 | case ISCSI_NET_PARAM_IPV4_SUBNET: |
@@ -672,8 +701,7 @@ int beiscsi_set_param(struct iscsi_cls_conn *cls_conn, | |||
672 | session->max_burst = 262144; | 701 | session->max_burst = 262144; |
673 | break; | 702 | break; |
674 | case ISCSI_PARAM_MAX_XMIT_DLENGTH: | 703 | case ISCSI_PARAM_MAX_XMIT_DLENGTH: |
675 | if ((conn->max_xmit_dlength > 65536) || | 704 | if (conn->max_xmit_dlength > 65536) |
676 | (conn->max_xmit_dlength == 0)) | ||
677 | conn->max_xmit_dlength = 65536; | 705 | conn->max_xmit_dlength = 65536; |
678 | default: | 706 | default: |
679 | return 0; | 707 | return 0; |
@@ -727,7 +755,7 @@ static void beiscsi_get_port_state(struct Scsi_Host *shost) | |||
727 | struct beiscsi_hba *phba = iscsi_host_priv(shost); | 755 | struct beiscsi_hba *phba = iscsi_host_priv(shost); |
728 | struct iscsi_cls_host *ihost = shost->shost_data; | 756 | struct iscsi_cls_host *ihost = shost->shost_data; |
729 | 757 | ||
730 | ihost->port_state = (phba->state == BE_ADAPTER_UP) ? | 758 | ihost->port_state = (phba->state == BE_ADAPTER_LINK_UP) ? |
731 | ISCSI_PORT_STATE_UP : ISCSI_PORT_STATE_DOWN; | 759 | ISCSI_PORT_STATE_UP : ISCSI_PORT_STATE_DOWN; |
732 | } | 760 | } |
733 | 761 | ||
@@ -795,9 +823,16 @@ int beiscsi_get_host_param(struct Scsi_Host *shost, | |||
795 | struct beiscsi_hba *phba = iscsi_host_priv(shost); | 823 | struct beiscsi_hba *phba = iscsi_host_priv(shost); |
796 | int status = 0; | 824 | int status = 0; |
797 | 825 | ||
798 | beiscsi_log(phba, KERN_INFO, BEISCSI_LOG_CONFIG, | 826 | |
799 | "BS_%d : In beiscsi_get_host_param," | 827 | if (phba->state & BE_ADAPTER_PCI_ERR) { |
800 | " param= %d\n", param); | 828 | beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_CONFIG, |
829 | "BS_%d : In PCI_ERROR Recovery\n"); | ||
830 | return -EBUSY; | ||
831 | } else { | ||
832 | beiscsi_log(phba, KERN_INFO, BEISCSI_LOG_CONFIG, | ||
833 | "BS_%d : In beiscsi_get_host_param," | ||
834 | " param = %d\n", param); | ||
835 | } | ||
801 | 836 | ||
802 | switch (param) { | 837 | switch (param) { |
803 | case ISCSI_HOST_PARAM_HWADDRESS: | 838 | case ISCSI_HOST_PARAM_HWADDRESS: |
@@ -840,7 +875,7 @@ int beiscsi_get_macaddr(char *buf, struct beiscsi_hba *phba) | |||
840 | struct be_cmd_get_nic_conf_resp resp; | 875 | struct be_cmd_get_nic_conf_resp resp; |
841 | int rc; | 876 | int rc; |
842 | 877 | ||
843 | if (strlen(phba->mac_address)) | 878 | if (phba->mac_addr_set) |
844 | return sysfs_format_mac(buf, phba->mac_address, ETH_ALEN); | 879 | return sysfs_format_mac(buf, phba->mac_address, ETH_ALEN); |
845 | 880 | ||
846 | memset(&resp, 0, sizeof(resp)); | 881 | memset(&resp, 0, sizeof(resp)); |
@@ -848,6 +883,7 @@ int beiscsi_get_macaddr(char *buf, struct beiscsi_hba *phba) | |||
848 | if (rc) | 883 | if (rc) |
849 | return rc; | 884 | return rc; |
850 | 885 | ||
886 | phba->mac_addr_set = true; | ||
851 | memcpy(phba->mac_address, resp.mac_address, ETH_ALEN); | 887 | memcpy(phba->mac_address, resp.mac_address, ETH_ALEN); |
852 | return sysfs_format_mac(buf, phba->mac_address, ETH_ALEN); | 888 | return sysfs_format_mac(buf, phba->mac_address, ETH_ALEN); |
853 | } | 889 | } |
@@ -923,6 +959,10 @@ static void beiscsi_set_params_for_offld(struct beiscsi_conn *beiscsi_conn, | |||
923 | session->max_r2t); | 959 | session->max_r2t); |
924 | AMAP_SET_BITS(struct amap_beiscsi_offload_params, exp_statsn, params, | 960 | AMAP_SET_BITS(struct amap_beiscsi_offload_params, exp_statsn, params, |
925 | (conn->exp_statsn - 1)); | 961 | (conn->exp_statsn - 1)); |
962 | AMAP_SET_BITS(struct amap_beiscsi_offload_params, | ||
963 | max_recv_data_segment_length, params, | ||
964 | conn->max_recv_dlength); | ||
965 | |||
926 | } | 966 | } |
927 | 967 | ||
928 | /** | 968 | /** |
@@ -935,10 +975,19 @@ int beiscsi_conn_start(struct iscsi_cls_conn *cls_conn) | |||
935 | struct beiscsi_conn *beiscsi_conn = conn->dd_data; | 975 | struct beiscsi_conn *beiscsi_conn = conn->dd_data; |
936 | struct beiscsi_endpoint *beiscsi_ep; | 976 | struct beiscsi_endpoint *beiscsi_ep; |
937 | struct beiscsi_offload_params params; | 977 | struct beiscsi_offload_params params; |
978 | struct beiscsi_hba *phba; | ||
938 | 979 | ||
939 | beiscsi_log(beiscsi_conn->phba, KERN_INFO, | 980 | phba = ((struct beiscsi_conn *)conn->dd_data)->phba; |
940 | BEISCSI_LOG_CONFIG, | 981 | |
941 | "BS_%d : In beiscsi_conn_start\n"); | 982 | if (phba->state & BE_ADAPTER_PCI_ERR) { |
983 | beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_CONFIG, | ||
984 | "BS_%d : In PCI_ERROR Recovery\n"); | ||
985 | return -EBUSY; | ||
986 | } else { | ||
987 | beiscsi_log(beiscsi_conn->phba, KERN_INFO, | ||
988 | BEISCSI_LOG_CONFIG, | ||
989 | "BS_%d : In beiscsi_conn_start\n"); | ||
990 | } | ||
942 | 991 | ||
943 | memset(¶ms, 0, sizeof(struct beiscsi_offload_params)); | 992 | memset(¶ms, 0, sizeof(struct beiscsi_offload_params)); |
944 | beiscsi_ep = beiscsi_conn->ep; | 993 | beiscsi_ep = beiscsi_conn->ep; |
@@ -960,15 +1009,31 @@ int beiscsi_conn_start(struct iscsi_cls_conn *cls_conn) | |||
960 | */ | 1009 | */ |
961 | static int beiscsi_get_cid(struct beiscsi_hba *phba) | 1010 | static int beiscsi_get_cid(struct beiscsi_hba *phba) |
962 | { | 1011 | { |
963 | unsigned short cid = 0xFFFF; | 1012 | unsigned short cid = 0xFFFF, cid_from_ulp; |
964 | 1013 | struct ulp_cid_info *cid_info = NULL; | |
965 | if (!phba->avlbl_cids) | 1014 | uint16_t cid_avlbl_ulp0, cid_avlbl_ulp1; |
966 | return cid; | 1015 | |
967 | 1016 | /* Find the ULP which has more CID available */ | |
968 | cid = phba->cid_array[phba->cid_alloc++]; | 1017 | cid_avlbl_ulp0 = (phba->cid_array_info[BEISCSI_ULP0]) ? |
969 | if (phba->cid_alloc == phba->params.cxns_per_ctrl) | 1018 | BEISCSI_ULP0_AVLBL_CID(phba) : 0; |
970 | phba->cid_alloc = 0; | 1019 | cid_avlbl_ulp1 = (phba->cid_array_info[BEISCSI_ULP1]) ? |
971 | phba->avlbl_cids--; | 1020 | BEISCSI_ULP1_AVLBL_CID(phba) : 0; |
1021 | cid_from_ulp = (cid_avlbl_ulp0 > cid_avlbl_ulp1) ? | ||
1022 | BEISCSI_ULP0 : BEISCSI_ULP1; | ||
1023 | |||
1024 | if (test_bit(cid_from_ulp, (void *)&phba->fw_config.ulp_supported)) { | ||
1025 | cid_info = phba->cid_array_info[cid_from_ulp]; | ||
1026 | if (!cid_info->avlbl_cids) | ||
1027 | return cid; | ||
1028 | |||
1029 | cid = cid_info->cid_array[cid_info->cid_alloc++]; | ||
1030 | |||
1031 | if (cid_info->cid_alloc == BEISCSI_GET_CID_COUNT( | ||
1032 | phba, cid_from_ulp)) | ||
1033 | cid_info->cid_alloc = 0; | ||
1034 | |||
1035 | cid_info->avlbl_cids--; | ||
1036 | } | ||
972 | return cid; | 1037 | return cid; |
973 | } | 1038 | } |
974 | 1039 | ||
@@ -979,10 +1044,22 @@ static int beiscsi_get_cid(struct beiscsi_hba *phba) | |||
979 | */ | 1044 | */ |
980 | static void beiscsi_put_cid(struct beiscsi_hba *phba, unsigned short cid) | 1045 | static void beiscsi_put_cid(struct beiscsi_hba *phba, unsigned short cid) |
981 | { | 1046 | { |
982 | phba->avlbl_cids++; | 1047 | uint16_t cid_post_ulp; |
983 | phba->cid_array[phba->cid_free++] = cid; | 1048 | struct hwi_controller *phwi_ctrlr; |
984 | if (phba->cid_free == phba->params.cxns_per_ctrl) | 1049 | struct hwi_wrb_context *pwrb_context; |
985 | phba->cid_free = 0; | 1050 | struct ulp_cid_info *cid_info = NULL; |
1051 | uint16_t cri_index = BE_GET_CRI_FROM_CID(cid); | ||
1052 | |||
1053 | phwi_ctrlr = phba->phwi_ctrlr; | ||
1054 | pwrb_context = &phwi_ctrlr->wrb_context[cri_index]; | ||
1055 | cid_post_ulp = pwrb_context->ulp_num; | ||
1056 | |||
1057 | cid_info = phba->cid_array_info[cid_post_ulp]; | ||
1058 | cid_info->avlbl_cids++; | ||
1059 | |||
1060 | cid_info->cid_array[cid_info->cid_free++] = cid; | ||
1061 | if (cid_info->cid_free == BEISCSI_GET_CID_COUNT(phba, cid_post_ulp)) | ||
1062 | cid_info->cid_free = 0; | ||
986 | } | 1063 | } |
987 | 1064 | ||
988 | /** | 1065 | /** |
@@ -1135,7 +1212,12 @@ beiscsi_ep_connect(struct Scsi_Host *shost, struct sockaddr *dst_addr, | |||
1135 | return ERR_PTR(ret); | 1212 | return ERR_PTR(ret); |
1136 | } | 1213 | } |
1137 | 1214 | ||
1138 | if (phba->state != BE_ADAPTER_UP) { | 1215 | if (phba->state & BE_ADAPTER_PCI_ERR) { |
1216 | ret = -EBUSY; | ||
1217 | beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_CONFIG, | ||
1218 | "BS_%d : In PCI_ERROR Recovery\n"); | ||
1219 | return ERR_PTR(ret); | ||
1220 | } else if (phba->state & BE_ADAPTER_LINK_DOWN) { | ||
1139 | ret = -EBUSY; | 1221 | ret = -EBUSY; |
1140 | beiscsi_log(phba, KERN_WARNING, BEISCSI_LOG_CONFIG, | 1222 | beiscsi_log(phba, KERN_WARNING, BEISCSI_LOG_CONFIG, |
1141 | "BS_%d : The Adapter Port state is Down!!!\n"); | 1223 | "BS_%d : The Adapter Port state is Down!!!\n"); |
@@ -1260,6 +1342,12 @@ void beiscsi_ep_disconnect(struct iscsi_endpoint *ep) | |||
1260 | tcp_upload_flag = CONNECTION_UPLOAD_ABORT; | 1342 | tcp_upload_flag = CONNECTION_UPLOAD_ABORT; |
1261 | } | 1343 | } |
1262 | 1344 | ||
1345 | if (phba->state & BE_ADAPTER_PCI_ERR) { | ||
1346 | beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_CONFIG, | ||
1347 | "BS_%d : PCI_ERROR Recovery\n"); | ||
1348 | goto free_ep; | ||
1349 | } | ||
1350 | |||
1263 | tag = mgmt_invalidate_connection(phba, beiscsi_ep, | 1351 | tag = mgmt_invalidate_connection(phba, beiscsi_ep, |
1264 | beiscsi_ep->ep_cid, | 1352 | beiscsi_ep->ep_cid, |
1265 | mgmt_invalidate_flag, | 1353 | mgmt_invalidate_flag, |
@@ -1272,6 +1360,7 @@ void beiscsi_ep_disconnect(struct iscsi_endpoint *ep) | |||
1272 | 1360 | ||
1273 | beiscsi_mccq_compl(phba, tag, NULL, NULL); | 1361 | beiscsi_mccq_compl(phba, tag, NULL, NULL); |
1274 | beiscsi_close_conn(beiscsi_ep, tcp_upload_flag); | 1362 | beiscsi_close_conn(beiscsi_ep, tcp_upload_flag); |
1363 | free_ep: | ||
1275 | beiscsi_free_ep(beiscsi_ep); | 1364 | beiscsi_free_ep(beiscsi_ep); |
1276 | beiscsi_unbind_conn_to_cid(phba, beiscsi_ep->ep_cid); | 1365 | beiscsi_unbind_conn_to_cid(phba, beiscsi_ep->ep_cid); |
1277 | iscsi_destroy_endpoint(beiscsi_ep->openiscsi_ep); | 1366 | iscsi_destroy_endpoint(beiscsi_ep->openiscsi_ep); |
diff --git a/drivers/scsi/be2iscsi/be_main.c b/drivers/scsi/be2iscsi/be_main.c index a1f5ac7a9806..1f375051483a 100644 --- a/drivers/scsi/be2iscsi/be_main.c +++ b/drivers/scsi/be2iscsi/be_main.c | |||
@@ -149,18 +149,25 @@ BEISCSI_RW_ATTR(log_enable, 0x00, | |||
149 | "\t\t\t\tMiscellaneous Events : 0x04\n" | 149 | "\t\t\t\tMiscellaneous Events : 0x04\n" |
150 | "\t\t\t\tError Handling : 0x08\n" | 150 | "\t\t\t\tError Handling : 0x08\n" |
151 | "\t\t\t\tIO Path Events : 0x10\n" | 151 | "\t\t\t\tIO Path Events : 0x10\n" |
152 | "\t\t\t\tConfiguration Path : 0x20\n"); | 152 | "\t\t\t\tConfiguration Path : 0x20\n" |
153 | "\t\t\t\tiSCSI Protocol : 0x40\n"); | ||
153 | 154 | ||
154 | DEVICE_ATTR(beiscsi_drvr_ver, S_IRUGO, beiscsi_drvr_ver_disp, NULL); | 155 | DEVICE_ATTR(beiscsi_drvr_ver, S_IRUGO, beiscsi_drvr_ver_disp, NULL); |
155 | DEVICE_ATTR(beiscsi_adapter_family, S_IRUGO, beiscsi_adap_family_disp, NULL); | 156 | DEVICE_ATTR(beiscsi_adapter_family, S_IRUGO, beiscsi_adap_family_disp, NULL); |
156 | DEVICE_ATTR(beiscsi_fw_ver, S_IRUGO, beiscsi_fw_ver_disp, NULL); | 157 | DEVICE_ATTR(beiscsi_fw_ver, S_IRUGO, beiscsi_fw_ver_disp, NULL); |
157 | DEVICE_ATTR(beiscsi_active_cid_count, S_IRUGO, beiscsi_active_cid_disp, NULL); | 158 | DEVICE_ATTR(beiscsi_phys_port, S_IRUGO, beiscsi_phys_port_disp, NULL); |
159 | DEVICE_ATTR(beiscsi_active_session_count, S_IRUGO, | ||
160 | beiscsi_active_session_disp, NULL); | ||
161 | DEVICE_ATTR(beiscsi_free_session_count, S_IRUGO, | ||
162 | beiscsi_free_session_disp, NULL); | ||
158 | struct device_attribute *beiscsi_attrs[] = { | 163 | struct device_attribute *beiscsi_attrs[] = { |
159 | &dev_attr_beiscsi_log_enable, | 164 | &dev_attr_beiscsi_log_enable, |
160 | &dev_attr_beiscsi_drvr_ver, | 165 | &dev_attr_beiscsi_drvr_ver, |
161 | &dev_attr_beiscsi_adapter_family, | 166 | &dev_attr_beiscsi_adapter_family, |
162 | &dev_attr_beiscsi_fw_ver, | 167 | &dev_attr_beiscsi_fw_ver, |
163 | &dev_attr_beiscsi_active_cid_count, | 168 | &dev_attr_beiscsi_active_session_count, |
169 | &dev_attr_beiscsi_free_session_count, | ||
170 | &dev_attr_beiscsi_phys_port, | ||
164 | NULL, | 171 | NULL, |
165 | }; | 172 | }; |
166 | 173 | ||
@@ -239,6 +246,11 @@ static int beiscsi_eh_abort(struct scsi_cmnd *sc) | |||
239 | return SUCCESS; | 246 | return SUCCESS; |
240 | } | 247 | } |
241 | spin_unlock_bh(&session->lock); | 248 | spin_unlock_bh(&session->lock); |
249 | /* Invalidate WRB Posted for this Task */ | ||
250 | AMAP_SET_BITS(struct amap_iscsi_wrb, invld, | ||
251 | aborted_io_task->pwrb_handle->pwrb, | ||
252 | 1); | ||
253 | |||
242 | conn = aborted_task->conn; | 254 | conn = aborted_task->conn; |
243 | beiscsi_conn = conn->dd_data; | 255 | beiscsi_conn = conn->dd_data; |
244 | phba = beiscsi_conn->phba; | 256 | phba = beiscsi_conn->phba; |
@@ -316,6 +328,11 @@ static int beiscsi_eh_device_reset(struct scsi_cmnd *sc) | |||
316 | if (abrt_task->sc->device->lun != abrt_task->sc->device->lun) | 328 | if (abrt_task->sc->device->lun != abrt_task->sc->device->lun) |
317 | continue; | 329 | continue; |
318 | 330 | ||
331 | /* Invalidate WRB Posted for this Task */ | ||
332 | AMAP_SET_BITS(struct amap_iscsi_wrb, invld, | ||
333 | abrt_io_task->pwrb_handle->pwrb, | ||
334 | 1); | ||
335 | |||
319 | inv_tbl->cid = cid; | 336 | inv_tbl->cid = cid; |
320 | inv_tbl->icd = abrt_io_task->psgl_handle->sgl_index; | 337 | inv_tbl->icd = abrt_io_task->psgl_handle->sgl_index; |
321 | num_invalidate++; | 338 | num_invalidate++; |
@@ -699,30 +716,85 @@ static int be_ctrl_init(struct beiscsi_hba *phba, struct pci_dev *pdev) | |||
699 | return status; | 716 | return status; |
700 | } | 717 | } |
701 | 718 | ||
719 | /** | ||
720 | * beiscsi_get_params()- Set the config paramters | ||
721 | * @phba: ptr device priv structure | ||
722 | **/ | ||
702 | static void beiscsi_get_params(struct beiscsi_hba *phba) | 723 | static void beiscsi_get_params(struct beiscsi_hba *phba) |
703 | { | 724 | { |
704 | phba->params.ios_per_ctrl = (phba->fw_config.iscsi_icd_count | 725 | uint32_t total_cid_count = 0; |
705 | - (phba->fw_config.iscsi_cid_count | 726 | uint32_t total_icd_count = 0; |
706 | + BE2_TMFS | 727 | uint8_t ulp_num = 0; |
707 | + BE2_NOPOUT_REQ)); | 728 | |
708 | phba->params.cxns_per_ctrl = phba->fw_config.iscsi_cid_count; | 729 | total_cid_count = BEISCSI_GET_CID_COUNT(phba, BEISCSI_ULP0) + |
709 | phba->params.asyncpdus_per_ctrl = phba->fw_config.iscsi_cid_count; | 730 | BEISCSI_GET_CID_COUNT(phba, BEISCSI_ULP1); |
710 | phba->params.icds_per_ctrl = phba->fw_config.iscsi_icd_count; | 731 | |
732 | for (ulp_num = 0; ulp_num < BEISCSI_ULP_COUNT; ulp_num++) { | ||
733 | uint32_t align_mask = 0; | ||
734 | uint32_t icd_post_per_page = 0; | ||
735 | uint32_t icd_count_unavailable = 0; | ||
736 | uint32_t icd_start = 0, icd_count = 0; | ||
737 | uint32_t icd_start_align = 0, icd_count_align = 0; | ||
738 | |||
739 | if (test_bit(ulp_num, &phba->fw_config.ulp_supported)) { | ||
740 | icd_start = phba->fw_config.iscsi_icd_start[ulp_num]; | ||
741 | icd_count = phba->fw_config.iscsi_icd_count[ulp_num]; | ||
742 | |||
743 | /* Get ICD count that can be posted on each page */ | ||
744 | icd_post_per_page = (PAGE_SIZE / (BE2_SGE * | ||
745 | sizeof(struct iscsi_sge))); | ||
746 | align_mask = (icd_post_per_page - 1); | ||
747 | |||
748 | /* Check if icd_start is aligned ICD per page posting */ | ||
749 | if (icd_start % icd_post_per_page) { | ||
750 | icd_start_align = ((icd_start + | ||
751 | icd_post_per_page) & | ||
752 | ~(align_mask)); | ||
753 | phba->fw_config. | ||
754 | iscsi_icd_start[ulp_num] = | ||
755 | icd_start_align; | ||
756 | } | ||
757 | |||
758 | icd_count_align = (icd_count & ~align_mask); | ||
759 | |||
760 | /* ICD discarded in the process of alignment */ | ||
761 | if (icd_start_align) | ||
762 | icd_count_unavailable = ((icd_start_align - | ||
763 | icd_start) + | ||
764 | (icd_count - | ||
765 | icd_count_align)); | ||
766 | |||
767 | /* Updated ICD count available */ | ||
768 | phba->fw_config.iscsi_icd_count[ulp_num] = (icd_count - | ||
769 | icd_count_unavailable); | ||
770 | |||
771 | beiscsi_log(phba, KERN_INFO, BEISCSI_LOG_INIT, | ||
772 | "BM_%d : Aligned ICD values\n" | ||
773 | "\t ICD Start : %d\n" | ||
774 | "\t ICD Count : %d\n" | ||
775 | "\t ICD Discarded : %d\n", | ||
776 | phba->fw_config. | ||
777 | iscsi_icd_start[ulp_num], | ||
778 | phba->fw_config. | ||
779 | iscsi_icd_count[ulp_num], | ||
780 | icd_count_unavailable); | ||
781 | break; | ||
782 | } | ||
783 | } | ||
784 | |||
785 | total_icd_count = phba->fw_config.iscsi_icd_count[ulp_num]; | ||
786 | phba->params.ios_per_ctrl = (total_icd_count - | ||
787 | (total_cid_count + | ||
788 | BE2_TMFS + BE2_NOPOUT_REQ)); | ||
789 | phba->params.cxns_per_ctrl = total_cid_count; | ||
790 | phba->params.asyncpdus_per_ctrl = total_cid_count; | ||
791 | phba->params.icds_per_ctrl = total_icd_count; | ||
711 | phba->params.num_sge_per_io = BE2_SGE; | 792 | phba->params.num_sge_per_io = BE2_SGE; |
712 | phba->params.defpdu_hdr_sz = BE2_DEFPDU_HDR_SZ; | 793 | phba->params.defpdu_hdr_sz = BE2_DEFPDU_HDR_SZ; |
713 | phba->params.defpdu_data_sz = BE2_DEFPDU_DATA_SZ; | 794 | phba->params.defpdu_data_sz = BE2_DEFPDU_DATA_SZ; |
714 | phba->params.eq_timer = 64; | 795 | phba->params.eq_timer = 64; |
715 | phba->params.num_eq_entries = | 796 | phba->params.num_eq_entries = 1024; |
716 | (((BE2_CMDS_PER_CXN * 2 + phba->fw_config.iscsi_cid_count * 2 | 797 | phba->params.num_cq_entries = 1024; |
717 | + BE2_TMFS) / 512) + 1) * 512; | ||
718 | phba->params.num_eq_entries = (phba->params.num_eq_entries < 1024) | ||
719 | ? 1024 : phba->params.num_eq_entries; | ||
720 | beiscsi_log(phba, KERN_INFO, BEISCSI_LOG_INIT, | ||
721 | "BM_%d : phba->params.num_eq_entries=%d\n", | ||
722 | phba->params.num_eq_entries); | ||
723 | phba->params.num_cq_entries = | ||
724 | (((BE2_CMDS_PER_CXN * 2 + phba->fw_config.iscsi_cid_count * 2 | ||
725 | + BE2_TMFS) / 512) + 1) * 512; | ||
726 | phba->params.wrbs_per_cxn = 256; | 798 | phba->params.wrbs_per_cxn = 256; |
727 | } | 799 | } |
728 | 800 | ||
@@ -1613,8 +1685,8 @@ hwi_get_async_handle(struct beiscsi_hba *phba, | |||
1613 | 1685 | ||
1614 | WARN_ON(!pasync_handle); | 1686 | WARN_ON(!pasync_handle); |
1615 | 1687 | ||
1616 | pasync_handle->cri = | 1688 | pasync_handle->cri = BE_GET_ASYNC_CRI_FROM_CID( |
1617 | BE_GET_CRI_FROM_CID(beiscsi_conn->beiscsi_conn_cid); | 1689 | beiscsi_conn->beiscsi_conn_cid); |
1618 | pasync_handle->is_header = is_header; | 1690 | pasync_handle->is_header = is_header; |
1619 | pasync_handle->buffer_len = dpl; | 1691 | pasync_handle->buffer_len = dpl; |
1620 | *pcq_index = index; | 1692 | *pcq_index = index; |
@@ -1674,18 +1746,13 @@ hwi_update_async_writables(struct beiscsi_hba *phba, | |||
1674 | } | 1746 | } |
1675 | 1747 | ||
1676 | static void hwi_free_async_msg(struct beiscsi_hba *phba, | 1748 | static void hwi_free_async_msg(struct beiscsi_hba *phba, |
1677 | unsigned int cri) | 1749 | struct hwi_async_pdu_context *pasync_ctx, |
1750 | unsigned int cri) | ||
1678 | { | 1751 | { |
1679 | struct hwi_controller *phwi_ctrlr; | ||
1680 | struct hwi_async_pdu_context *pasync_ctx; | ||
1681 | struct async_pdu_handle *pasync_handle, *tmp_handle; | 1752 | struct async_pdu_handle *pasync_handle, *tmp_handle; |
1682 | struct list_head *plist; | 1753 | struct list_head *plist; |
1683 | 1754 | ||
1684 | phwi_ctrlr = phba->phwi_ctrlr; | ||
1685 | pasync_ctx = HWI_GET_ASYNC_PDU_CTX(phwi_ctrlr); | ||
1686 | |||
1687 | plist = &pasync_ctx->async_entry[cri].wait_queue.list; | 1755 | plist = &pasync_ctx->async_entry[cri].wait_queue.list; |
1688 | |||
1689 | list_for_each_entry_safe(pasync_handle, tmp_handle, plist, link) { | 1756 | list_for_each_entry_safe(pasync_handle, tmp_handle, plist, link) { |
1690 | list_del(&pasync_handle->link); | 1757 | list_del(&pasync_handle->link); |
1691 | 1758 | ||
@@ -1720,7 +1787,7 @@ hwi_get_ring_address(struct hwi_async_pdu_context *pasync_ctx, | |||
1720 | } | 1787 | } |
1721 | 1788 | ||
1722 | static void hwi_post_async_buffers(struct beiscsi_hba *phba, | 1789 | static void hwi_post_async_buffers(struct beiscsi_hba *phba, |
1723 | unsigned int is_header) | 1790 | unsigned int is_header, uint8_t ulp_num) |
1724 | { | 1791 | { |
1725 | struct hwi_controller *phwi_ctrlr; | 1792 | struct hwi_controller *phwi_ctrlr; |
1726 | struct hwi_async_pdu_context *pasync_ctx; | 1793 | struct hwi_async_pdu_context *pasync_ctx; |
@@ -1728,13 +1795,13 @@ static void hwi_post_async_buffers(struct beiscsi_hba *phba, | |||
1728 | struct list_head *pfree_link, *pbusy_list; | 1795 | struct list_head *pfree_link, *pbusy_list; |
1729 | struct phys_addr *pasync_sge; | 1796 | struct phys_addr *pasync_sge; |
1730 | unsigned int ring_id, num_entries; | 1797 | unsigned int ring_id, num_entries; |
1731 | unsigned int host_write_num; | 1798 | unsigned int host_write_num, doorbell_offset; |
1732 | unsigned int writables; | 1799 | unsigned int writables; |
1733 | unsigned int i = 0; | 1800 | unsigned int i = 0; |
1734 | u32 doorbell = 0; | 1801 | u32 doorbell = 0; |
1735 | 1802 | ||
1736 | phwi_ctrlr = phba->phwi_ctrlr; | 1803 | phwi_ctrlr = phba->phwi_ctrlr; |
1737 | pasync_ctx = HWI_GET_ASYNC_PDU_CTX(phwi_ctrlr); | 1804 | pasync_ctx = HWI_GET_ASYNC_PDU_CTX(phwi_ctrlr, ulp_num); |
1738 | num_entries = pasync_ctx->num_entries; | 1805 | num_entries = pasync_ctx->num_entries; |
1739 | 1806 | ||
1740 | if (is_header) { | 1807 | if (is_header) { |
@@ -1742,13 +1809,17 @@ static void hwi_post_async_buffers(struct beiscsi_hba *phba, | |||
1742 | pasync_ctx->async_header.free_entries); | 1809 | pasync_ctx->async_header.free_entries); |
1743 | pfree_link = pasync_ctx->async_header.free_list.next; | 1810 | pfree_link = pasync_ctx->async_header.free_list.next; |
1744 | host_write_num = pasync_ctx->async_header.host_write_ptr; | 1811 | host_write_num = pasync_ctx->async_header.host_write_ptr; |
1745 | ring_id = phwi_ctrlr->default_pdu_hdr.id; | 1812 | ring_id = phwi_ctrlr->default_pdu_hdr[ulp_num].id; |
1813 | doorbell_offset = phwi_ctrlr->default_pdu_hdr[ulp_num]. | ||
1814 | doorbell_offset; | ||
1746 | } else { | 1815 | } else { |
1747 | writables = min(pasync_ctx->async_data.writables, | 1816 | writables = min(pasync_ctx->async_data.writables, |
1748 | pasync_ctx->async_data.free_entries); | 1817 | pasync_ctx->async_data.free_entries); |
1749 | pfree_link = pasync_ctx->async_data.free_list.next; | 1818 | pfree_link = pasync_ctx->async_data.free_list.next; |
1750 | host_write_num = pasync_ctx->async_data.host_write_ptr; | 1819 | host_write_num = pasync_ctx->async_data.host_write_ptr; |
1751 | ring_id = phwi_ctrlr->default_pdu_data.id; | 1820 | ring_id = phwi_ctrlr->default_pdu_data[ulp_num].id; |
1821 | doorbell_offset = phwi_ctrlr->default_pdu_data[ulp_num]. | ||
1822 | doorbell_offset; | ||
1752 | } | 1823 | } |
1753 | 1824 | ||
1754 | writables = (writables / 8) * 8; | 1825 | writables = (writables / 8) * 8; |
@@ -1796,7 +1867,7 @@ static void hwi_post_async_buffers(struct beiscsi_hba *phba, | |||
1796 | doorbell |= (writables & DB_DEF_PDU_CQPROC_MASK) | 1867 | doorbell |= (writables & DB_DEF_PDU_CQPROC_MASK) |
1797 | << DB_DEF_PDU_CQPROC_SHIFT; | 1868 | << DB_DEF_PDU_CQPROC_SHIFT; |
1798 | 1869 | ||
1799 | iowrite32(doorbell, phba->db_va + DB_RXULP0_OFFSET); | 1870 | iowrite32(doorbell, phba->db_va + doorbell_offset); |
1800 | } | 1871 | } |
1801 | } | 1872 | } |
1802 | 1873 | ||
@@ -1808,9 +1879,13 @@ static void hwi_flush_default_pdu_buffer(struct beiscsi_hba *phba, | |||
1808 | struct hwi_async_pdu_context *pasync_ctx; | 1879 | struct hwi_async_pdu_context *pasync_ctx; |
1809 | struct async_pdu_handle *pasync_handle = NULL; | 1880 | struct async_pdu_handle *pasync_handle = NULL; |
1810 | unsigned int cq_index = -1; | 1881 | unsigned int cq_index = -1; |
1882 | uint16_t cri_index = BE_GET_CRI_FROM_CID( | ||
1883 | beiscsi_conn->beiscsi_conn_cid); | ||
1811 | 1884 | ||
1812 | phwi_ctrlr = phba->phwi_ctrlr; | 1885 | phwi_ctrlr = phba->phwi_ctrlr; |
1813 | pasync_ctx = HWI_GET_ASYNC_PDU_CTX(phwi_ctrlr); | 1886 | pasync_ctx = HWI_GET_ASYNC_PDU_CTX(phwi_ctrlr, |
1887 | BEISCSI_GET_ULP_FROM_CRI(phwi_ctrlr, | ||
1888 | cri_index)); | ||
1814 | 1889 | ||
1815 | pasync_handle = hwi_get_async_handle(phba, beiscsi_conn, pasync_ctx, | 1890 | pasync_handle = hwi_get_async_handle(phba, beiscsi_conn, pasync_ctx, |
1816 | pdpdu_cqe, &cq_index); | 1891 | pdpdu_cqe, &cq_index); |
@@ -1819,8 +1894,10 @@ static void hwi_flush_default_pdu_buffer(struct beiscsi_hba *phba, | |||
1819 | hwi_update_async_writables(phba, pasync_ctx, | 1894 | hwi_update_async_writables(phba, pasync_ctx, |
1820 | pasync_handle->is_header, cq_index); | 1895 | pasync_handle->is_header, cq_index); |
1821 | 1896 | ||
1822 | hwi_free_async_msg(phba, pasync_handle->cri); | 1897 | hwi_free_async_msg(phba, pasync_ctx, pasync_handle->cri); |
1823 | hwi_post_async_buffers(phba, pasync_handle->is_header); | 1898 | hwi_post_async_buffers(phba, pasync_handle->is_header, |
1899 | BEISCSI_GET_ULP_FROM_CRI(phwi_ctrlr, | ||
1900 | cri_index)); | ||
1824 | } | 1901 | } |
1825 | 1902 | ||
1826 | static unsigned int | 1903 | static unsigned int |
@@ -1859,7 +1936,7 @@ hwi_fwd_async_msg(struct beiscsi_conn *beiscsi_conn, | |||
1859 | phdr, hdr_len, pfirst_buffer, | 1936 | phdr, hdr_len, pfirst_buffer, |
1860 | offset); | 1937 | offset); |
1861 | 1938 | ||
1862 | hwi_free_async_msg(phba, cri); | 1939 | hwi_free_async_msg(phba, pasync_ctx, cri); |
1863 | return 0; | 1940 | return 0; |
1864 | } | 1941 | } |
1865 | 1942 | ||
@@ -1875,13 +1952,16 @@ hwi_gather_async_pdu(struct beiscsi_conn *beiscsi_conn, | |||
1875 | struct pdu_base *ppdu; | 1952 | struct pdu_base *ppdu; |
1876 | 1953 | ||
1877 | phwi_ctrlr = phba->phwi_ctrlr; | 1954 | phwi_ctrlr = phba->phwi_ctrlr; |
1878 | pasync_ctx = HWI_GET_ASYNC_PDU_CTX(phwi_ctrlr); | 1955 | pasync_ctx = HWI_GET_ASYNC_PDU_CTX(phwi_ctrlr, |
1956 | BEISCSI_GET_ULP_FROM_CRI(phwi_ctrlr, | ||
1957 | BE_GET_CRI_FROM_CID(beiscsi_conn-> | ||
1958 | beiscsi_conn_cid))); | ||
1879 | 1959 | ||
1880 | list_del(&pasync_handle->link); | 1960 | list_del(&pasync_handle->link); |
1881 | if (pasync_handle->is_header) { | 1961 | if (pasync_handle->is_header) { |
1882 | pasync_ctx->async_header.busy_entries--; | 1962 | pasync_ctx->async_header.busy_entries--; |
1883 | if (pasync_ctx->async_entry[cri].wait_queue.hdr_received) { | 1963 | if (pasync_ctx->async_entry[cri].wait_queue.hdr_received) { |
1884 | hwi_free_async_msg(phba, cri); | 1964 | hwi_free_async_msg(phba, pasync_ctx, cri); |
1885 | BUG(); | 1965 | BUG(); |
1886 | } | 1966 | } |
1887 | 1967 | ||
@@ -1936,9 +2016,14 @@ static void hwi_process_default_pdu_ring(struct beiscsi_conn *beiscsi_conn, | |||
1936 | struct hwi_async_pdu_context *pasync_ctx; | 2016 | struct hwi_async_pdu_context *pasync_ctx; |
1937 | struct async_pdu_handle *pasync_handle = NULL; | 2017 | struct async_pdu_handle *pasync_handle = NULL; |
1938 | unsigned int cq_index = -1; | 2018 | unsigned int cq_index = -1; |
2019 | uint16_t cri_index = BE_GET_CRI_FROM_CID( | ||
2020 | beiscsi_conn->beiscsi_conn_cid); | ||
1939 | 2021 | ||
1940 | phwi_ctrlr = phba->phwi_ctrlr; | 2022 | phwi_ctrlr = phba->phwi_ctrlr; |
1941 | pasync_ctx = HWI_GET_ASYNC_PDU_CTX(phwi_ctrlr); | 2023 | pasync_ctx = HWI_GET_ASYNC_PDU_CTX(phwi_ctrlr, |
2024 | BEISCSI_GET_ULP_FROM_CRI(phwi_ctrlr, | ||
2025 | cri_index)); | ||
2026 | |||
1942 | pasync_handle = hwi_get_async_handle(phba, beiscsi_conn, pasync_ctx, | 2027 | pasync_handle = hwi_get_async_handle(phba, beiscsi_conn, pasync_ctx, |
1943 | pdpdu_cqe, &cq_index); | 2028 | pdpdu_cqe, &cq_index); |
1944 | 2029 | ||
@@ -1947,7 +2032,9 @@ static void hwi_process_default_pdu_ring(struct beiscsi_conn *beiscsi_conn, | |||
1947 | pasync_handle->is_header, cq_index); | 2032 | pasync_handle->is_header, cq_index); |
1948 | 2033 | ||
1949 | hwi_gather_async_pdu(beiscsi_conn, phba, pasync_handle); | 2034 | hwi_gather_async_pdu(beiscsi_conn, phba, pasync_handle); |
1950 | hwi_post_async_buffers(phba, pasync_handle->is_header); | 2035 | hwi_post_async_buffers(phba, pasync_handle->is_header, |
2036 | BEISCSI_GET_ULP_FROM_CRI( | ||
2037 | phwi_ctrlr, cri_index)); | ||
1951 | } | 2038 | } |
1952 | 2039 | ||
1953 | static void beiscsi_process_mcc_isr(struct beiscsi_hba *phba) | 2040 | static void beiscsi_process_mcc_isr(struct beiscsi_hba *phba) |
@@ -2072,8 +2159,10 @@ static unsigned int beiscsi_process_cq(struct be_eq_obj *pbe_eq) | |||
2072 | "BM_%d : Received %s[%d] on CID : %d\n", | 2159 | "BM_%d : Received %s[%d] on CID : %d\n", |
2073 | cqe_desc[code], code, cid); | 2160 | cqe_desc[code], code, cid); |
2074 | 2161 | ||
2162 | spin_lock_bh(&phba->async_pdu_lock); | ||
2075 | hwi_process_default_pdu_ring(beiscsi_conn, phba, | 2163 | hwi_process_default_pdu_ring(beiscsi_conn, phba, |
2076 | (struct i_t_dpdu_cqe *)sol); | 2164 | (struct i_t_dpdu_cqe *)sol); |
2165 | spin_unlock_bh(&phba->async_pdu_lock); | ||
2077 | break; | 2166 | break; |
2078 | case UNSOL_DATA_NOTIFY: | 2167 | case UNSOL_DATA_NOTIFY: |
2079 | beiscsi_log(phba, KERN_INFO, | 2168 | beiscsi_log(phba, KERN_INFO, |
@@ -2081,8 +2170,10 @@ static unsigned int beiscsi_process_cq(struct be_eq_obj *pbe_eq) | |||
2081 | "BM_%d : Received %s[%d] on CID : %d\n", | 2170 | "BM_%d : Received %s[%d] on CID : %d\n", |
2082 | cqe_desc[code], code, cid); | 2171 | cqe_desc[code], code, cid); |
2083 | 2172 | ||
2173 | spin_lock_bh(&phba->async_pdu_lock); | ||
2084 | hwi_process_default_pdu_ring(beiscsi_conn, phba, | 2174 | hwi_process_default_pdu_ring(beiscsi_conn, phba, |
2085 | (struct i_t_dpdu_cqe *)sol); | 2175 | (struct i_t_dpdu_cqe *)sol); |
2176 | spin_unlock_bh(&phba->async_pdu_lock); | ||
2086 | break; | 2177 | break; |
2087 | case CXN_INVALIDATE_INDEX_NOTIFY: | 2178 | case CXN_INVALIDATE_INDEX_NOTIFY: |
2088 | case CMD_INVALIDATED_NOTIFY: | 2179 | case CMD_INVALIDATED_NOTIFY: |
@@ -2110,8 +2201,10 @@ static unsigned int beiscsi_process_cq(struct be_eq_obj *pbe_eq) | |||
2110 | BEISCSI_LOG_IO | BEISCSI_LOG_CONFIG, | 2201 | BEISCSI_LOG_IO | BEISCSI_LOG_CONFIG, |
2111 | "BM_%d : Dropping %s[%d] on DPDU ring on CID : %d\n", | 2202 | "BM_%d : Dropping %s[%d] on DPDU ring on CID : %d\n", |
2112 | cqe_desc[code], code, cid); | 2203 | cqe_desc[code], code, cid); |
2204 | spin_lock_bh(&phba->async_pdu_lock); | ||
2113 | hwi_flush_default_pdu_buffer(phba, beiscsi_conn, | 2205 | hwi_flush_default_pdu_buffer(phba, beiscsi_conn, |
2114 | (struct i_t_dpdu_cqe *) sol); | 2206 | (struct i_t_dpdu_cqe *) sol); |
2207 | spin_unlock_bh(&phba->async_pdu_lock); | ||
2115 | break; | 2208 | break; |
2116 | case CXN_KILLED_PDU_SIZE_EXCEEDS_DSL: | 2209 | case CXN_KILLED_PDU_SIZE_EXCEEDS_DSL: |
2117 | case CXN_KILLED_BURST_LEN_MISMATCH: | 2210 | case CXN_KILLED_BURST_LEN_MISMATCH: |
@@ -2476,26 +2569,19 @@ static void hwi_write_buffer(struct iscsi_wrb *pwrb, struct iscsi_task *task) | |||
2476 | AMAP_SET_BITS(struct amap_iscsi_sge, last_sge, psgl, 1); | 2569 | AMAP_SET_BITS(struct amap_iscsi_sge, last_sge, psgl, 1); |
2477 | } | 2570 | } |
2478 | 2571 | ||
2572 | /** | ||
2573 | * beiscsi_find_mem_req()- Find mem needed | ||
2574 | * @phba: ptr to HBA struct | ||
2575 | **/ | ||
2479 | static void beiscsi_find_mem_req(struct beiscsi_hba *phba) | 2576 | static void beiscsi_find_mem_req(struct beiscsi_hba *phba) |
2480 | { | 2577 | { |
2578 | uint8_t mem_descr_index, ulp_num; | ||
2481 | unsigned int num_cq_pages, num_async_pdu_buf_pages; | 2579 | unsigned int num_cq_pages, num_async_pdu_buf_pages; |
2482 | unsigned int num_async_pdu_data_pages, wrb_sz_per_cxn; | 2580 | unsigned int num_async_pdu_data_pages, wrb_sz_per_cxn; |
2483 | unsigned int num_async_pdu_buf_sgl_pages, num_async_pdu_data_sgl_pages; | 2581 | unsigned int num_async_pdu_buf_sgl_pages, num_async_pdu_data_sgl_pages; |
2484 | 2582 | ||
2485 | num_cq_pages = PAGES_REQUIRED(phba->params.num_cq_entries * \ | 2583 | num_cq_pages = PAGES_REQUIRED(phba->params.num_cq_entries * \ |
2486 | sizeof(struct sol_cqe)); | 2584 | sizeof(struct sol_cqe)); |
2487 | num_async_pdu_buf_pages = | ||
2488 | PAGES_REQUIRED(phba->params.asyncpdus_per_ctrl * \ | ||
2489 | phba->params.defpdu_hdr_sz); | ||
2490 | num_async_pdu_buf_sgl_pages = | ||
2491 | PAGES_REQUIRED(phba->params.asyncpdus_per_ctrl * \ | ||
2492 | sizeof(struct phys_addr)); | ||
2493 | num_async_pdu_data_pages = | ||
2494 | PAGES_REQUIRED(phba->params.asyncpdus_per_ctrl * \ | ||
2495 | phba->params.defpdu_data_sz); | ||
2496 | num_async_pdu_data_sgl_pages = | ||
2497 | PAGES_REQUIRED(phba->params.asyncpdus_per_ctrl * \ | ||
2498 | sizeof(struct phys_addr)); | ||
2499 | 2585 | ||
2500 | phba->params.hwi_ws_sz = sizeof(struct hwi_controller); | 2586 | phba->params.hwi_ws_sz = sizeof(struct hwi_controller); |
2501 | 2587 | ||
@@ -2517,24 +2603,79 @@ static void beiscsi_find_mem_req(struct beiscsi_hba *phba) | |||
2517 | phba->params.icds_per_ctrl; | 2603 | phba->params.icds_per_ctrl; |
2518 | phba->mem_req[HWI_MEM_SGE] = sizeof(struct iscsi_sge) * | 2604 | phba->mem_req[HWI_MEM_SGE] = sizeof(struct iscsi_sge) * |
2519 | phba->params.num_sge_per_io * phba->params.icds_per_ctrl; | 2605 | phba->params.num_sge_per_io * phba->params.icds_per_ctrl; |
2520 | 2606 | for (ulp_num = 0; ulp_num < BEISCSI_ULP_COUNT; ulp_num++) { | |
2521 | phba->mem_req[HWI_MEM_ASYNC_HEADER_BUF] = | 2607 | if (test_bit(ulp_num, &phba->fw_config.ulp_supported)) { |
2522 | num_async_pdu_buf_pages * PAGE_SIZE; | 2608 | |
2523 | phba->mem_req[HWI_MEM_ASYNC_DATA_BUF] = | 2609 | num_async_pdu_buf_sgl_pages = |
2524 | num_async_pdu_data_pages * PAGE_SIZE; | 2610 | PAGES_REQUIRED(BEISCSI_GET_CID_COUNT( |
2525 | phba->mem_req[HWI_MEM_ASYNC_HEADER_RING] = | 2611 | phba, ulp_num) * |
2526 | num_async_pdu_buf_sgl_pages * PAGE_SIZE; | 2612 | sizeof(struct phys_addr)); |
2527 | phba->mem_req[HWI_MEM_ASYNC_DATA_RING] = | 2613 | |
2528 | num_async_pdu_data_sgl_pages * PAGE_SIZE; | 2614 | num_async_pdu_buf_pages = |
2529 | phba->mem_req[HWI_MEM_ASYNC_HEADER_HANDLE] = | 2615 | PAGES_REQUIRED(BEISCSI_GET_CID_COUNT( |
2530 | phba->params.asyncpdus_per_ctrl * | 2616 | phba, ulp_num) * |
2531 | sizeof(struct async_pdu_handle); | 2617 | phba->params.defpdu_hdr_sz); |
2532 | phba->mem_req[HWI_MEM_ASYNC_DATA_HANDLE] = | 2618 | |
2533 | phba->params.asyncpdus_per_ctrl * | 2619 | num_async_pdu_data_pages = |
2534 | sizeof(struct async_pdu_handle); | 2620 | PAGES_REQUIRED(BEISCSI_GET_CID_COUNT( |
2535 | phba->mem_req[HWI_MEM_ASYNC_PDU_CONTEXT] = | 2621 | phba, ulp_num) * |
2536 | sizeof(struct hwi_async_pdu_context) + | 2622 | phba->params.defpdu_data_sz); |
2537 | (phba->params.cxns_per_ctrl * sizeof(struct hwi_async_entry)); | 2623 | |
2624 | num_async_pdu_data_sgl_pages = | ||
2625 | PAGES_REQUIRED(BEISCSI_GET_CID_COUNT( | ||
2626 | phba, ulp_num) * | ||
2627 | sizeof(struct phys_addr)); | ||
2628 | |||
2629 | mem_descr_index = (HWI_MEM_TEMPLATE_HDR_ULP0 + | ||
2630 | (ulp_num * MEM_DESCR_OFFSET)); | ||
2631 | phba->mem_req[mem_descr_index] = | ||
2632 | BEISCSI_GET_CID_COUNT(phba, ulp_num) * | ||
2633 | BEISCSI_TEMPLATE_HDR_PER_CXN_SIZE; | ||
2634 | |||
2635 | mem_descr_index = (HWI_MEM_ASYNC_HEADER_BUF_ULP0 + | ||
2636 | (ulp_num * MEM_DESCR_OFFSET)); | ||
2637 | phba->mem_req[mem_descr_index] = | ||
2638 | num_async_pdu_buf_pages * | ||
2639 | PAGE_SIZE; | ||
2640 | |||
2641 | mem_descr_index = (HWI_MEM_ASYNC_DATA_BUF_ULP0 + | ||
2642 | (ulp_num * MEM_DESCR_OFFSET)); | ||
2643 | phba->mem_req[mem_descr_index] = | ||
2644 | num_async_pdu_data_pages * | ||
2645 | PAGE_SIZE; | ||
2646 | |||
2647 | mem_descr_index = (HWI_MEM_ASYNC_HEADER_RING_ULP0 + | ||
2648 | (ulp_num * MEM_DESCR_OFFSET)); | ||
2649 | phba->mem_req[mem_descr_index] = | ||
2650 | num_async_pdu_buf_sgl_pages * | ||
2651 | PAGE_SIZE; | ||
2652 | |||
2653 | mem_descr_index = (HWI_MEM_ASYNC_DATA_RING_ULP0 + | ||
2654 | (ulp_num * MEM_DESCR_OFFSET)); | ||
2655 | phba->mem_req[mem_descr_index] = | ||
2656 | num_async_pdu_data_sgl_pages * | ||
2657 | PAGE_SIZE; | ||
2658 | |||
2659 | mem_descr_index = (HWI_MEM_ASYNC_HEADER_HANDLE_ULP0 + | ||
2660 | (ulp_num * MEM_DESCR_OFFSET)); | ||
2661 | phba->mem_req[mem_descr_index] = | ||
2662 | BEISCSI_GET_CID_COUNT(phba, ulp_num) * | ||
2663 | sizeof(struct async_pdu_handle); | ||
2664 | |||
2665 | mem_descr_index = (HWI_MEM_ASYNC_DATA_HANDLE_ULP0 + | ||
2666 | (ulp_num * MEM_DESCR_OFFSET)); | ||
2667 | phba->mem_req[mem_descr_index] = | ||
2668 | BEISCSI_GET_CID_COUNT(phba, ulp_num) * | ||
2669 | sizeof(struct async_pdu_handle); | ||
2670 | |||
2671 | mem_descr_index = (HWI_MEM_ASYNC_PDU_CONTEXT_ULP0 + | ||
2672 | (ulp_num * MEM_DESCR_OFFSET)); | ||
2673 | phba->mem_req[mem_descr_index] = | ||
2674 | sizeof(struct hwi_async_pdu_context) + | ||
2675 | (BEISCSI_GET_CID_COUNT(phba, ulp_num) * | ||
2676 | sizeof(struct hwi_async_entry)); | ||
2677 | } | ||
2678 | } | ||
2538 | } | 2679 | } |
2539 | 2680 | ||
2540 | static int beiscsi_alloc_mem(struct beiscsi_hba *phba) | 2681 | static int beiscsi_alloc_mem(struct beiscsi_hba *phba) |
@@ -2576,6 +2717,12 @@ static int beiscsi_alloc_mem(struct beiscsi_hba *phba) | |||
2576 | 2717 | ||
2577 | mem_descr = phba->init_mem; | 2718 | mem_descr = phba->init_mem; |
2578 | for (i = 0; i < SE_MEM_MAX; i++) { | 2719 | for (i = 0; i < SE_MEM_MAX; i++) { |
2720 | if (!phba->mem_req[i]) { | ||
2721 | mem_descr->mem_array = NULL; | ||
2722 | mem_descr++; | ||
2723 | continue; | ||
2724 | } | ||
2725 | |||
2579 | j = 0; | 2726 | j = 0; |
2580 | mem_arr = mem_arr_orig; | 2727 | mem_arr = mem_arr_orig; |
2581 | alloc_size = phba->mem_req[i]; | 2728 | alloc_size = phba->mem_req[i]; |
@@ -2697,7 +2844,7 @@ static int beiscsi_init_wrb_handle(struct beiscsi_hba *phba) | |||
2697 | /* Allocate memory for WRBQ */ | 2844 | /* Allocate memory for WRBQ */ |
2698 | phwi_ctxt = phwi_ctrlr->phwi_ctxt; | 2845 | phwi_ctxt = phwi_ctrlr->phwi_ctxt; |
2699 | phwi_ctxt->be_wrbq = kzalloc(sizeof(struct be_queue_info) * | 2846 | phwi_ctxt->be_wrbq = kzalloc(sizeof(struct be_queue_info) * |
2700 | phba->fw_config.iscsi_cid_count, | 2847 | phba->params.cxns_per_ctrl, |
2701 | GFP_KERNEL); | 2848 | GFP_KERNEL); |
2702 | if (!phwi_ctxt->be_wrbq) { | 2849 | if (!phwi_ctxt->be_wrbq) { |
2703 | beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_INIT, | 2850 | beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_INIT, |
@@ -2779,6 +2926,7 @@ init_wrb_hndl_failed: | |||
2779 | 2926 | ||
2780 | static int hwi_init_async_pdu_ctx(struct beiscsi_hba *phba) | 2927 | static int hwi_init_async_pdu_ctx(struct beiscsi_hba *phba) |
2781 | { | 2928 | { |
2929 | uint8_t ulp_num; | ||
2782 | struct hwi_controller *phwi_ctrlr; | 2930 | struct hwi_controller *phwi_ctrlr; |
2783 | struct hba_parameters *p = &phba->params; | 2931 | struct hba_parameters *p = &phba->params; |
2784 | struct hwi_async_pdu_context *pasync_ctx; | 2932 | struct hwi_async_pdu_context *pasync_ctx; |
@@ -2786,155 +2934,150 @@ static int hwi_init_async_pdu_ctx(struct beiscsi_hba *phba) | |||
2786 | unsigned int index, idx, num_per_mem, num_async_data; | 2934 | unsigned int index, idx, num_per_mem, num_async_data; |
2787 | struct be_mem_descriptor *mem_descr; | 2935 | struct be_mem_descriptor *mem_descr; |
2788 | 2936 | ||
2789 | mem_descr = (struct be_mem_descriptor *)phba->init_mem; | 2937 | for (ulp_num = 0; ulp_num < BEISCSI_ULP_COUNT; ulp_num++) { |
2790 | mem_descr += HWI_MEM_ASYNC_PDU_CONTEXT; | 2938 | if (test_bit(ulp_num, &phba->fw_config.ulp_supported)) { |
2791 | 2939 | ||
2792 | phwi_ctrlr = phba->phwi_ctrlr; | 2940 | mem_descr = (struct be_mem_descriptor *)phba->init_mem; |
2793 | phwi_ctrlr->phwi_ctxt->pasync_ctx = (struct hwi_async_pdu_context *) | 2941 | mem_descr += (HWI_MEM_ASYNC_PDU_CONTEXT_ULP0 + |
2942 | (ulp_num * MEM_DESCR_OFFSET)); | ||
2943 | |||
2944 | phwi_ctrlr = phba->phwi_ctrlr; | ||
2945 | phwi_ctrlr->phwi_ctxt->pasync_ctx[ulp_num] = | ||
2946 | (struct hwi_async_pdu_context *) | ||
2947 | mem_descr->mem_array[0].virtual_address; | ||
2948 | |||
2949 | pasync_ctx = phwi_ctrlr->phwi_ctxt->pasync_ctx[ulp_num]; | ||
2950 | memset(pasync_ctx, 0, sizeof(*pasync_ctx)); | ||
2951 | |||
2952 | pasync_ctx->async_entry = | ||
2953 | (struct hwi_async_entry *) | ||
2954 | ((long unsigned int)pasync_ctx + | ||
2955 | sizeof(struct hwi_async_pdu_context)); | ||
2956 | |||
2957 | pasync_ctx->num_entries = BEISCSI_GET_CID_COUNT(phba, | ||
2958 | ulp_num); | ||
2959 | pasync_ctx->buffer_size = p->defpdu_hdr_sz; | ||
2960 | |||
2961 | mem_descr = (struct be_mem_descriptor *)phba->init_mem; | ||
2962 | mem_descr += HWI_MEM_ASYNC_HEADER_BUF_ULP0 + | ||
2963 | (ulp_num * MEM_DESCR_OFFSET); | ||
2964 | if (mem_descr->mem_array[0].virtual_address) { | ||
2965 | beiscsi_log(phba, KERN_INFO, BEISCSI_LOG_INIT, | ||
2966 | "BM_%d : hwi_init_async_pdu_ctx" | ||
2967 | " HWI_MEM_ASYNC_HEADER_BUF_ULP%d va=%p\n", | ||
2968 | ulp_num, | ||
2969 | mem_descr->mem_array[0]. | ||
2970 | virtual_address); | ||
2971 | } else | ||
2972 | beiscsi_log(phba, KERN_WARNING, | ||
2973 | BEISCSI_LOG_INIT, | ||
2974 | "BM_%d : No Virtual address for ULP : %d\n", | ||
2975 | ulp_num); | ||
2976 | |||
2977 | pasync_ctx->async_header.va_base = | ||
2794 | mem_descr->mem_array[0].virtual_address; | 2978 | mem_descr->mem_array[0].virtual_address; |
2795 | pasync_ctx = phwi_ctrlr->phwi_ctxt->pasync_ctx; | ||
2796 | memset(pasync_ctx, 0, sizeof(*pasync_ctx)); | ||
2797 | 2979 | ||
2798 | pasync_ctx->async_entry = kzalloc(sizeof(struct hwi_async_entry) * | 2980 | pasync_ctx->async_header.pa_base.u.a64.address = |
2799 | phba->fw_config.iscsi_cid_count, | 2981 | mem_descr->mem_array[0]. |
2800 | GFP_KERNEL); | 2982 | bus_address.u.a64.address; |
2801 | if (!pasync_ctx->async_entry) { | ||
2802 | beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_INIT, | ||
2803 | "BM_%d : hwi_init_async_pdu_ctx Mem Alloc Failed\n"); | ||
2804 | return -ENOMEM; | ||
2805 | } | ||
2806 | |||
2807 | pasync_ctx->num_entries = p->asyncpdus_per_ctrl; | ||
2808 | pasync_ctx->buffer_size = p->defpdu_hdr_sz; | ||
2809 | |||
2810 | mem_descr = (struct be_mem_descriptor *)phba->init_mem; | ||
2811 | mem_descr += HWI_MEM_ASYNC_HEADER_BUF; | ||
2812 | if (mem_descr->mem_array[0].virtual_address) { | ||
2813 | beiscsi_log(phba, KERN_INFO, BEISCSI_LOG_INIT, | ||
2814 | "BM_%d : hwi_init_async_pdu_ctx" | ||
2815 | " HWI_MEM_ASYNC_HEADER_BUF va=%p\n", | ||
2816 | mem_descr->mem_array[0].virtual_address); | ||
2817 | } else | ||
2818 | beiscsi_log(phba, KERN_WARNING, BEISCSI_LOG_INIT, | ||
2819 | "BM_%d : No Virtual address\n"); | ||
2820 | |||
2821 | pasync_ctx->async_header.va_base = | ||
2822 | mem_descr->mem_array[0].virtual_address; | ||
2823 | |||
2824 | pasync_ctx->async_header.pa_base.u.a64.address = | ||
2825 | mem_descr->mem_array[0].bus_address.u.a64.address; | ||
2826 | |||
2827 | mem_descr = (struct be_mem_descriptor *)phba->init_mem; | ||
2828 | mem_descr += HWI_MEM_ASYNC_HEADER_RING; | ||
2829 | if (mem_descr->mem_array[0].virtual_address) { | ||
2830 | beiscsi_log(phba, KERN_INFO, BEISCSI_LOG_INIT, | ||
2831 | "BM_%d : hwi_init_async_pdu_ctx" | ||
2832 | " HWI_MEM_ASYNC_HEADER_RING va=%p\n", | ||
2833 | mem_descr->mem_array[0].virtual_address); | ||
2834 | } else | ||
2835 | beiscsi_log(phba, KERN_WARNING, BEISCSI_LOG_INIT, | ||
2836 | "BM_%d : No Virtual address\n"); | ||
2837 | |||
2838 | pasync_ctx->async_header.ring_base = | ||
2839 | mem_descr->mem_array[0].virtual_address; | ||
2840 | |||
2841 | mem_descr = (struct be_mem_descriptor *)phba->init_mem; | ||
2842 | mem_descr += HWI_MEM_ASYNC_HEADER_HANDLE; | ||
2843 | if (mem_descr->mem_array[0].virtual_address) { | ||
2844 | beiscsi_log(phba, KERN_INFO, BEISCSI_LOG_INIT, | ||
2845 | "BM_%d : hwi_init_async_pdu_ctx" | ||
2846 | " HWI_MEM_ASYNC_HEADER_HANDLE va=%p\n", | ||
2847 | mem_descr->mem_array[0].virtual_address); | ||
2848 | } else | ||
2849 | beiscsi_log(phba, KERN_WARNING, BEISCSI_LOG_INIT, | ||
2850 | "BM_%d : No Virtual address\n"); | ||
2851 | |||
2852 | pasync_ctx->async_header.handle_base = | ||
2853 | mem_descr->mem_array[0].virtual_address; | ||
2854 | pasync_ctx->async_header.writables = 0; | ||
2855 | INIT_LIST_HEAD(&pasync_ctx->async_header.free_list); | ||
2856 | |||
2857 | |||
2858 | mem_descr = (struct be_mem_descriptor *)phba->init_mem; | ||
2859 | mem_descr += HWI_MEM_ASYNC_DATA_RING; | ||
2860 | if (mem_descr->mem_array[0].virtual_address) { | ||
2861 | beiscsi_log(phba, KERN_INFO, BEISCSI_LOG_INIT, | ||
2862 | "BM_%d : hwi_init_async_pdu_ctx" | ||
2863 | " HWI_MEM_ASYNC_DATA_RING va=%p\n", | ||
2864 | mem_descr->mem_array[0].virtual_address); | ||
2865 | } else | ||
2866 | beiscsi_log(phba, KERN_WARNING, BEISCSI_LOG_INIT, | ||
2867 | "BM_%d : No Virtual address\n"); | ||
2868 | |||
2869 | pasync_ctx->async_data.ring_base = | ||
2870 | mem_descr->mem_array[0].virtual_address; | ||
2871 | |||
2872 | mem_descr = (struct be_mem_descriptor *)phba->init_mem; | ||
2873 | mem_descr += HWI_MEM_ASYNC_DATA_HANDLE; | ||
2874 | if (!mem_descr->mem_array[0].virtual_address) | ||
2875 | beiscsi_log(phba, KERN_WARNING, BEISCSI_LOG_INIT, | ||
2876 | "BM_%d : No Virtual address\n"); | ||
2877 | 2983 | ||
2878 | pasync_ctx->async_data.handle_base = | 2984 | mem_descr = (struct be_mem_descriptor *)phba->init_mem; |
2879 | mem_descr->mem_array[0].virtual_address; | 2985 | mem_descr += HWI_MEM_ASYNC_HEADER_RING_ULP0 + |
2880 | pasync_ctx->async_data.writables = 0; | 2986 | (ulp_num * MEM_DESCR_OFFSET); |
2881 | INIT_LIST_HEAD(&pasync_ctx->async_data.free_list); | 2987 | if (mem_descr->mem_array[0].virtual_address) { |
2988 | beiscsi_log(phba, KERN_INFO, BEISCSI_LOG_INIT, | ||
2989 | "BM_%d : hwi_init_async_pdu_ctx" | ||
2990 | " HWI_MEM_ASYNC_HEADER_RING_ULP%d va=%p\n", | ||
2991 | ulp_num, | ||
2992 | mem_descr->mem_array[0]. | ||
2993 | virtual_address); | ||
2994 | } else | ||
2995 | beiscsi_log(phba, KERN_WARNING, | ||
2996 | BEISCSI_LOG_INIT, | ||
2997 | "BM_%d : No Virtual address for ULP : %d\n", | ||
2998 | ulp_num); | ||
2999 | |||
3000 | pasync_ctx->async_header.ring_base = | ||
3001 | mem_descr->mem_array[0].virtual_address; | ||
2882 | 3002 | ||
2883 | pasync_header_h = | 3003 | mem_descr = (struct be_mem_descriptor *)phba->init_mem; |
2884 | (struct async_pdu_handle *)pasync_ctx->async_header.handle_base; | 3004 | mem_descr += HWI_MEM_ASYNC_HEADER_HANDLE_ULP0 + |
2885 | pasync_data_h = | 3005 | (ulp_num * MEM_DESCR_OFFSET); |
2886 | (struct async_pdu_handle *)pasync_ctx->async_data.handle_base; | 3006 | if (mem_descr->mem_array[0].virtual_address) { |
3007 | beiscsi_log(phba, KERN_INFO, BEISCSI_LOG_INIT, | ||
3008 | "BM_%d : hwi_init_async_pdu_ctx" | ||
3009 | " HWI_MEM_ASYNC_HEADER_HANDLE_ULP%d va=%p\n", | ||
3010 | ulp_num, | ||
3011 | mem_descr->mem_array[0]. | ||
3012 | virtual_address); | ||
3013 | } else | ||
3014 | beiscsi_log(phba, KERN_WARNING, | ||
3015 | BEISCSI_LOG_INIT, | ||
3016 | "BM_%d : No Virtual address for ULP : %d\n", | ||
3017 | ulp_num); | ||
3018 | |||
3019 | pasync_ctx->async_header.handle_base = | ||
3020 | mem_descr->mem_array[0].virtual_address; | ||
3021 | pasync_ctx->async_header.writables = 0; | ||
3022 | INIT_LIST_HEAD(&pasync_ctx->async_header.free_list); | ||
3023 | |||
3024 | mem_descr = (struct be_mem_descriptor *)phba->init_mem; | ||
3025 | mem_descr += HWI_MEM_ASYNC_DATA_RING_ULP0 + | ||
3026 | (ulp_num * MEM_DESCR_OFFSET); | ||
3027 | if (mem_descr->mem_array[0].virtual_address) { | ||
3028 | beiscsi_log(phba, KERN_INFO, BEISCSI_LOG_INIT, | ||
3029 | "BM_%d : hwi_init_async_pdu_ctx" | ||
3030 | " HWI_MEM_ASYNC_DATA_RING_ULP%d va=%p\n", | ||
3031 | ulp_num, | ||
3032 | mem_descr->mem_array[0]. | ||
3033 | virtual_address); | ||
3034 | } else | ||
3035 | beiscsi_log(phba, KERN_WARNING, | ||
3036 | BEISCSI_LOG_INIT, | ||
3037 | "BM_%d : No Virtual address for ULP : %d\n", | ||
3038 | ulp_num); | ||
3039 | |||
3040 | pasync_ctx->async_data.ring_base = | ||
3041 | mem_descr->mem_array[0].virtual_address; | ||
2887 | 3042 | ||
2888 | mem_descr = (struct be_mem_descriptor *)phba->init_mem; | 3043 | mem_descr = (struct be_mem_descriptor *)phba->init_mem; |
2889 | mem_descr += HWI_MEM_ASYNC_DATA_BUF; | 3044 | mem_descr += HWI_MEM_ASYNC_DATA_HANDLE_ULP0 + |
2890 | if (mem_descr->mem_array[0].virtual_address) { | 3045 | (ulp_num * MEM_DESCR_OFFSET); |
2891 | beiscsi_log(phba, KERN_INFO, BEISCSI_LOG_INIT, | 3046 | if (!mem_descr->mem_array[0].virtual_address) |
2892 | "BM_%d : hwi_init_async_pdu_ctx" | 3047 | beiscsi_log(phba, KERN_WARNING, |
2893 | " HWI_MEM_ASYNC_DATA_BUF va=%p\n", | 3048 | BEISCSI_LOG_INIT, |
2894 | mem_descr->mem_array[0].virtual_address); | 3049 | "BM_%d : No Virtual address for ULP : %d\n", |
2895 | } else | 3050 | ulp_num); |
2896 | beiscsi_log(phba, KERN_WARNING, BEISCSI_LOG_INIT, | ||
2897 | "BM_%d : No Virtual address\n"); | ||
2898 | 3051 | ||
2899 | idx = 0; | 3052 | pasync_ctx->async_data.handle_base = |
2900 | pasync_ctx->async_data.va_base = | 3053 | mem_descr->mem_array[0].virtual_address; |
2901 | mem_descr->mem_array[idx].virtual_address; | 3054 | pasync_ctx->async_data.writables = 0; |
2902 | pasync_ctx->async_data.pa_base.u.a64.address = | 3055 | INIT_LIST_HEAD(&pasync_ctx->async_data.free_list); |
2903 | mem_descr->mem_array[idx].bus_address.u.a64.address; | 3056 | |
2904 | 3057 | pasync_header_h = | |
2905 | num_async_data = ((mem_descr->mem_array[idx].size) / | 3058 | (struct async_pdu_handle *) |
2906 | phba->params.defpdu_data_sz); | 3059 | pasync_ctx->async_header.handle_base; |
2907 | num_per_mem = 0; | 3060 | pasync_data_h = |
2908 | 3061 | (struct async_pdu_handle *) | |
2909 | for (index = 0; index < p->asyncpdus_per_ctrl; index++) { | 3062 | pasync_ctx->async_data.handle_base; |
2910 | pasync_header_h->cri = -1; | 3063 | |
2911 | pasync_header_h->index = (char)index; | 3064 | mem_descr = (struct be_mem_descriptor *)phba->init_mem; |
2912 | INIT_LIST_HEAD(&pasync_header_h->link); | 3065 | mem_descr += HWI_MEM_ASYNC_DATA_BUF_ULP0 + |
2913 | pasync_header_h->pbuffer = | 3066 | (ulp_num * MEM_DESCR_OFFSET); |
2914 | (void *)((unsigned long) | 3067 | if (mem_descr->mem_array[0].virtual_address) { |
2915 | (pasync_ctx->async_header.va_base) + | 3068 | beiscsi_log(phba, KERN_INFO, BEISCSI_LOG_INIT, |
2916 | (p->defpdu_hdr_sz * index)); | 3069 | "BM_%d : hwi_init_async_pdu_ctx" |
2917 | 3070 | " HWI_MEM_ASYNC_DATA_BUF_ULP%d va=%p\n", | |
2918 | pasync_header_h->pa.u.a64.address = | 3071 | ulp_num, |
2919 | pasync_ctx->async_header.pa_base.u.a64.address + | 3072 | mem_descr->mem_array[0]. |
2920 | (p->defpdu_hdr_sz * index); | 3073 | virtual_address); |
2921 | 3074 | } else | |
2922 | list_add_tail(&pasync_header_h->link, | 3075 | beiscsi_log(phba, KERN_WARNING, |
2923 | &pasync_ctx->async_header.free_list); | 3076 | BEISCSI_LOG_INIT, |
2924 | pasync_header_h++; | 3077 | "BM_%d : No Virtual address for ULP : %d\n", |
2925 | pasync_ctx->async_header.free_entries++; | 3078 | ulp_num); |
2926 | pasync_ctx->async_header.writables++; | 3079 | |
2927 | 3080 | idx = 0; | |
2928 | INIT_LIST_HEAD(&pasync_ctx->async_entry[index].wait_queue.list); | ||
2929 | INIT_LIST_HEAD(&pasync_ctx->async_entry[index]. | ||
2930 | header_busy_list); | ||
2931 | pasync_data_h->cri = -1; | ||
2932 | pasync_data_h->index = (char)index; | ||
2933 | INIT_LIST_HEAD(&pasync_data_h->link); | ||
2934 | |||
2935 | if (!num_async_data) { | ||
2936 | num_per_mem = 0; | ||
2937 | idx++; | ||
2938 | pasync_ctx->async_data.va_base = | 3081 | pasync_ctx->async_data.va_base = |
2939 | mem_descr->mem_array[idx].virtual_address; | 3082 | mem_descr->mem_array[idx].virtual_address; |
2940 | pasync_ctx->async_data.pa_base.u.a64.address = | 3083 | pasync_ctx->async_data.pa_base.u.a64.address = |
@@ -2943,32 +3086,83 @@ static int hwi_init_async_pdu_ctx(struct beiscsi_hba *phba) | |||
2943 | 3086 | ||
2944 | num_async_data = ((mem_descr->mem_array[idx].size) / | 3087 | num_async_data = ((mem_descr->mem_array[idx].size) / |
2945 | phba->params.defpdu_data_sz); | 3088 | phba->params.defpdu_data_sz); |
2946 | } | 3089 | num_per_mem = 0; |
2947 | pasync_data_h->pbuffer = | ||
2948 | (void *)((unsigned long) | ||
2949 | (pasync_ctx->async_data.va_base) + | ||
2950 | (p->defpdu_data_sz * num_per_mem)); | ||
2951 | |||
2952 | pasync_data_h->pa.u.a64.address = | ||
2953 | pasync_ctx->async_data.pa_base.u.a64.address + | ||
2954 | (p->defpdu_data_sz * num_per_mem); | ||
2955 | num_per_mem++; | ||
2956 | num_async_data--; | ||
2957 | 3090 | ||
2958 | list_add_tail(&pasync_data_h->link, | 3091 | for (index = 0; index < BEISCSI_GET_CID_COUNT |
2959 | &pasync_ctx->async_data.free_list); | 3092 | (phba, ulp_num); index++) { |
2960 | pasync_data_h++; | 3093 | pasync_header_h->cri = -1; |
2961 | pasync_ctx->async_data.free_entries++; | 3094 | pasync_header_h->index = (char)index; |
2962 | pasync_ctx->async_data.writables++; | 3095 | INIT_LIST_HEAD(&pasync_header_h->link); |
3096 | pasync_header_h->pbuffer = | ||
3097 | (void *)((unsigned long) | ||
3098 | (pasync_ctx-> | ||
3099 | async_header.va_base) + | ||
3100 | (p->defpdu_hdr_sz * index)); | ||
3101 | |||
3102 | pasync_header_h->pa.u.a64.address = | ||
3103 | pasync_ctx->async_header.pa_base.u.a64. | ||
3104 | address + (p->defpdu_hdr_sz * index); | ||
3105 | |||
3106 | list_add_tail(&pasync_header_h->link, | ||
3107 | &pasync_ctx->async_header. | ||
3108 | free_list); | ||
3109 | pasync_header_h++; | ||
3110 | pasync_ctx->async_header.free_entries++; | ||
3111 | pasync_ctx->async_header.writables++; | ||
3112 | |||
3113 | INIT_LIST_HEAD(&pasync_ctx->async_entry[index]. | ||
3114 | wait_queue.list); | ||
3115 | INIT_LIST_HEAD(&pasync_ctx->async_entry[index]. | ||
3116 | header_busy_list); | ||
3117 | pasync_data_h->cri = -1; | ||
3118 | pasync_data_h->index = (char)index; | ||
3119 | INIT_LIST_HEAD(&pasync_data_h->link); | ||
3120 | |||
3121 | if (!num_async_data) { | ||
3122 | num_per_mem = 0; | ||
3123 | idx++; | ||
3124 | pasync_ctx->async_data.va_base = | ||
3125 | mem_descr->mem_array[idx]. | ||
3126 | virtual_address; | ||
3127 | pasync_ctx->async_data.pa_base.u. | ||
3128 | a64.address = | ||
3129 | mem_descr->mem_array[idx]. | ||
3130 | bus_address.u.a64.address; | ||
3131 | num_async_data = | ||
3132 | ((mem_descr->mem_array[idx]. | ||
3133 | size) / | ||
3134 | phba->params.defpdu_data_sz); | ||
3135 | } | ||
3136 | pasync_data_h->pbuffer = | ||
3137 | (void *)((unsigned long) | ||
3138 | (pasync_ctx->async_data.va_base) + | ||
3139 | (p->defpdu_data_sz * num_per_mem)); | ||
3140 | |||
3141 | pasync_data_h->pa.u.a64.address = | ||
3142 | pasync_ctx->async_data.pa_base.u.a64. | ||
3143 | address + (p->defpdu_data_sz * | ||
3144 | num_per_mem); | ||
3145 | num_per_mem++; | ||
3146 | num_async_data--; | ||
3147 | |||
3148 | list_add_tail(&pasync_data_h->link, | ||
3149 | &pasync_ctx->async_data. | ||
3150 | free_list); | ||
3151 | pasync_data_h++; | ||
3152 | pasync_ctx->async_data.free_entries++; | ||
3153 | pasync_ctx->async_data.writables++; | ||
3154 | |||
3155 | INIT_LIST_HEAD(&pasync_ctx->async_entry[index]. | ||
3156 | data_busy_list); | ||
3157 | } | ||
2963 | 3158 | ||
2964 | INIT_LIST_HEAD(&pasync_ctx->async_entry[index].data_busy_list); | 3159 | pasync_ctx->async_header.host_write_ptr = 0; |
3160 | pasync_ctx->async_header.ep_read_ptr = -1; | ||
3161 | pasync_ctx->async_data.host_write_ptr = 0; | ||
3162 | pasync_ctx->async_data.ep_read_ptr = -1; | ||
3163 | } | ||
2965 | } | 3164 | } |
2966 | 3165 | ||
2967 | pasync_ctx->async_header.host_write_ptr = 0; | ||
2968 | pasync_ctx->async_header.ep_read_ptr = -1; | ||
2969 | pasync_ctx->async_data.host_write_ptr = 0; | ||
2970 | pasync_ctx->async_data.ep_read_ptr = -1; | ||
2971 | |||
2972 | return 0; | 3166 | return 0; |
2973 | } | 3167 | } |
2974 | 3168 | ||
@@ -3164,7 +3358,7 @@ static int | |||
3164 | beiscsi_create_def_hdr(struct beiscsi_hba *phba, | 3358 | beiscsi_create_def_hdr(struct beiscsi_hba *phba, |
3165 | struct hwi_context_memory *phwi_context, | 3359 | struct hwi_context_memory *phwi_context, |
3166 | struct hwi_controller *phwi_ctrlr, | 3360 | struct hwi_controller *phwi_ctrlr, |
3167 | unsigned int def_pdu_ring_sz) | 3361 | unsigned int def_pdu_ring_sz, uint8_t ulp_num) |
3168 | { | 3362 | { |
3169 | unsigned int idx; | 3363 | unsigned int idx; |
3170 | int ret; | 3364 | int ret; |
@@ -3174,36 +3368,42 @@ beiscsi_create_def_hdr(struct beiscsi_hba *phba, | |||
3174 | void *dq_vaddress; | 3368 | void *dq_vaddress; |
3175 | 3369 | ||
3176 | idx = 0; | 3370 | idx = 0; |
3177 | dq = &phwi_context->be_def_hdrq; | 3371 | dq = &phwi_context->be_def_hdrq[ulp_num]; |
3178 | cq = &phwi_context->be_cq[0]; | 3372 | cq = &phwi_context->be_cq[0]; |
3179 | mem = &dq->dma_mem; | 3373 | mem = &dq->dma_mem; |
3180 | mem_descr = phba->init_mem; | 3374 | mem_descr = phba->init_mem; |
3181 | mem_descr += HWI_MEM_ASYNC_HEADER_RING; | 3375 | mem_descr += HWI_MEM_ASYNC_HEADER_RING_ULP0 + |
3376 | (ulp_num * MEM_DESCR_OFFSET); | ||
3182 | dq_vaddress = mem_descr->mem_array[idx].virtual_address; | 3377 | dq_vaddress = mem_descr->mem_array[idx].virtual_address; |
3183 | ret = be_fill_queue(dq, mem_descr->mem_array[0].size / | 3378 | ret = be_fill_queue(dq, mem_descr->mem_array[0].size / |
3184 | sizeof(struct phys_addr), | 3379 | sizeof(struct phys_addr), |
3185 | sizeof(struct phys_addr), dq_vaddress); | 3380 | sizeof(struct phys_addr), dq_vaddress); |
3186 | if (ret) { | 3381 | if (ret) { |
3187 | beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_INIT, | 3382 | beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_INIT, |
3188 | "BM_%d : be_fill_queue Failed for DEF PDU HDR\n"); | 3383 | "BM_%d : be_fill_queue Failed for DEF PDU HDR on ULP : %d\n", |
3384 | ulp_num); | ||
3385 | |||
3189 | return ret; | 3386 | return ret; |
3190 | } | 3387 | } |
3191 | mem->dma = (unsigned long)mem_descr->mem_array[idx]. | 3388 | mem->dma = (unsigned long)mem_descr->mem_array[idx]. |
3192 | bus_address.u.a64.address; | 3389 | bus_address.u.a64.address; |
3193 | ret = be_cmd_create_default_pdu_queue(&phba->ctrl, cq, dq, | 3390 | ret = be_cmd_create_default_pdu_queue(&phba->ctrl, cq, dq, |
3194 | def_pdu_ring_sz, | 3391 | def_pdu_ring_sz, |
3195 | phba->params.defpdu_hdr_sz); | 3392 | phba->params.defpdu_hdr_sz, |
3393 | BEISCSI_DEFQ_HDR, ulp_num); | ||
3196 | if (ret) { | 3394 | if (ret) { |
3197 | beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_INIT, | 3395 | beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_INIT, |
3198 | "BM_%d : be_cmd_create_default_pdu_queue Failed DEFHDR\n"); | 3396 | "BM_%d : be_cmd_create_default_pdu_queue Failed DEFHDR on ULP : %d\n", |
3397 | ulp_num); | ||
3398 | |||
3199 | return ret; | 3399 | return ret; |
3200 | } | 3400 | } |
3201 | phwi_ctrlr->default_pdu_hdr.id = phwi_context->be_def_hdrq.id; | ||
3202 | beiscsi_log(phba, KERN_INFO, BEISCSI_LOG_INIT, | ||
3203 | "BM_%d : iscsi def pdu id is %d\n", | ||
3204 | phwi_context->be_def_hdrq.id); | ||
3205 | 3401 | ||
3206 | hwi_post_async_buffers(phba, 1); | 3402 | beiscsi_log(phba, KERN_INFO, BEISCSI_LOG_INIT, |
3403 | "BM_%d : iscsi hdr def pdu id for ULP : %d is %d\n", | ||
3404 | ulp_num, | ||
3405 | phwi_context->be_def_hdrq[ulp_num].id); | ||
3406 | hwi_post_async_buffers(phba, BEISCSI_DEFQ_HDR, ulp_num); | ||
3207 | return 0; | 3407 | return 0; |
3208 | } | 3408 | } |
3209 | 3409 | ||
@@ -3211,7 +3411,7 @@ static int | |||
3211 | beiscsi_create_def_data(struct beiscsi_hba *phba, | 3411 | beiscsi_create_def_data(struct beiscsi_hba *phba, |
3212 | struct hwi_context_memory *phwi_context, | 3412 | struct hwi_context_memory *phwi_context, |
3213 | struct hwi_controller *phwi_ctrlr, | 3413 | struct hwi_controller *phwi_ctrlr, |
3214 | unsigned int def_pdu_ring_sz) | 3414 | unsigned int def_pdu_ring_sz, uint8_t ulp_num) |
3215 | { | 3415 | { |
3216 | unsigned int idx; | 3416 | unsigned int idx; |
3217 | int ret; | 3417 | int ret; |
@@ -3221,43 +3421,86 @@ beiscsi_create_def_data(struct beiscsi_hba *phba, | |||
3221 | void *dq_vaddress; | 3421 | void *dq_vaddress; |
3222 | 3422 | ||
3223 | idx = 0; | 3423 | idx = 0; |
3224 | dataq = &phwi_context->be_def_dataq; | 3424 | dataq = &phwi_context->be_def_dataq[ulp_num]; |
3225 | cq = &phwi_context->be_cq[0]; | 3425 | cq = &phwi_context->be_cq[0]; |
3226 | mem = &dataq->dma_mem; | 3426 | mem = &dataq->dma_mem; |
3227 | mem_descr = phba->init_mem; | 3427 | mem_descr = phba->init_mem; |
3228 | mem_descr += HWI_MEM_ASYNC_DATA_RING; | 3428 | mem_descr += HWI_MEM_ASYNC_DATA_RING_ULP0 + |
3429 | (ulp_num * MEM_DESCR_OFFSET); | ||
3229 | dq_vaddress = mem_descr->mem_array[idx].virtual_address; | 3430 | dq_vaddress = mem_descr->mem_array[idx].virtual_address; |
3230 | ret = be_fill_queue(dataq, mem_descr->mem_array[0].size / | 3431 | ret = be_fill_queue(dataq, mem_descr->mem_array[0].size / |
3231 | sizeof(struct phys_addr), | 3432 | sizeof(struct phys_addr), |
3232 | sizeof(struct phys_addr), dq_vaddress); | 3433 | sizeof(struct phys_addr), dq_vaddress); |
3233 | if (ret) { | 3434 | if (ret) { |
3234 | beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_INIT, | 3435 | beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_INIT, |
3235 | "BM_%d : be_fill_queue Failed for DEF PDU DATA\n"); | 3436 | "BM_%d : be_fill_queue Failed for DEF PDU " |
3437 | "DATA on ULP : %d\n", | ||
3438 | ulp_num); | ||
3439 | |||
3236 | return ret; | 3440 | return ret; |
3237 | } | 3441 | } |
3238 | mem->dma = (unsigned long)mem_descr->mem_array[idx]. | 3442 | mem->dma = (unsigned long)mem_descr->mem_array[idx]. |
3239 | bus_address.u.a64.address; | 3443 | bus_address.u.a64.address; |
3240 | ret = be_cmd_create_default_pdu_queue(&phba->ctrl, cq, dataq, | 3444 | ret = be_cmd_create_default_pdu_queue(&phba->ctrl, cq, dataq, |
3241 | def_pdu_ring_sz, | 3445 | def_pdu_ring_sz, |
3242 | phba->params.defpdu_data_sz); | 3446 | phba->params.defpdu_data_sz, |
3447 | BEISCSI_DEFQ_DATA, ulp_num); | ||
3243 | if (ret) { | 3448 | if (ret) { |
3244 | beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_INIT, | 3449 | beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_INIT, |
3245 | "BM_%d be_cmd_create_default_pdu_queue" | 3450 | "BM_%d be_cmd_create_default_pdu_queue" |
3246 | " Failed for DEF PDU DATA\n"); | 3451 | " Failed for DEF PDU DATA on ULP : %d\n", |
3452 | ulp_num); | ||
3247 | return ret; | 3453 | return ret; |
3248 | } | 3454 | } |
3249 | phwi_ctrlr->default_pdu_data.id = phwi_context->be_def_dataq.id; | 3455 | |
3250 | beiscsi_log(phba, KERN_INFO, BEISCSI_LOG_INIT, | 3456 | beiscsi_log(phba, KERN_INFO, BEISCSI_LOG_INIT, |
3251 | "BM_%d : iscsi def data id is %d\n", | 3457 | "BM_%d : iscsi def data id on ULP : %d is %d\n", |
3252 | phwi_context->be_def_dataq.id); | 3458 | ulp_num, |
3459 | phwi_context->be_def_dataq[ulp_num].id); | ||
3253 | 3460 | ||
3254 | hwi_post_async_buffers(phba, 0); | 3461 | hwi_post_async_buffers(phba, BEISCSI_DEFQ_DATA, ulp_num); |
3255 | beiscsi_log(phba, KERN_INFO, BEISCSI_LOG_INIT, | 3462 | beiscsi_log(phba, KERN_INFO, BEISCSI_LOG_INIT, |
3256 | "BM_%d : DEFAULT PDU DATA RING CREATED\n"); | 3463 | "BM_%d : DEFAULT PDU DATA RING CREATED" |
3464 | "on ULP : %d\n", ulp_num); | ||
3257 | 3465 | ||
3258 | return 0; | 3466 | return 0; |
3259 | } | 3467 | } |
3260 | 3468 | ||
3469 | |||
3470 | static int | ||
3471 | beiscsi_post_template_hdr(struct beiscsi_hba *phba) | ||
3472 | { | ||
3473 | struct be_mem_descriptor *mem_descr; | ||
3474 | struct mem_array *pm_arr; | ||
3475 | struct be_dma_mem sgl; | ||
3476 | int status, ulp_num; | ||
3477 | |||
3478 | for (ulp_num = 0; ulp_num < BEISCSI_ULP_COUNT; ulp_num++) { | ||
3479 | if (test_bit(ulp_num, &phba->fw_config.ulp_supported)) { | ||
3480 | mem_descr = (struct be_mem_descriptor *)phba->init_mem; | ||
3481 | mem_descr += HWI_MEM_TEMPLATE_HDR_ULP0 + | ||
3482 | (ulp_num * MEM_DESCR_OFFSET); | ||
3483 | pm_arr = mem_descr->mem_array; | ||
3484 | |||
3485 | hwi_build_be_sgl_arr(phba, pm_arr, &sgl); | ||
3486 | status = be_cmd_iscsi_post_template_hdr( | ||
3487 | &phba->ctrl, &sgl); | ||
3488 | |||
3489 | if (status != 0) { | ||
3490 | beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_INIT, | ||
3491 | "BM_%d : Post Template HDR Failed for" | ||
3492 | "ULP_%d\n", ulp_num); | ||
3493 | return status; | ||
3494 | } | ||
3495 | |||
3496 | beiscsi_log(phba, KERN_INFO, BEISCSI_LOG_INIT, | ||
3497 | "BM_%d : Template HDR Pages Posted for" | ||
3498 | "ULP_%d\n", ulp_num); | ||
3499 | } | ||
3500 | } | ||
3501 | return 0; | ||
3502 | } | ||
3503 | |||
3261 | static int | 3504 | static int |
3262 | beiscsi_post_pages(struct beiscsi_hba *phba) | 3505 | beiscsi_post_pages(struct beiscsi_hba *phba) |
3263 | { | 3506 | { |
@@ -3265,14 +3508,18 @@ beiscsi_post_pages(struct beiscsi_hba *phba) | |||
3265 | struct mem_array *pm_arr; | 3508 | struct mem_array *pm_arr; |
3266 | unsigned int page_offset, i; | 3509 | unsigned int page_offset, i; |
3267 | struct be_dma_mem sgl; | 3510 | struct be_dma_mem sgl; |
3268 | int status; | 3511 | int status, ulp_num = 0; |
3269 | 3512 | ||
3270 | mem_descr = phba->init_mem; | 3513 | mem_descr = phba->init_mem; |
3271 | mem_descr += HWI_MEM_SGE; | 3514 | mem_descr += HWI_MEM_SGE; |
3272 | pm_arr = mem_descr->mem_array; | 3515 | pm_arr = mem_descr->mem_array; |
3273 | 3516 | ||
3517 | for (ulp_num = 0; ulp_num < BEISCSI_ULP_COUNT; ulp_num++) | ||
3518 | if (test_bit(ulp_num, &phba->fw_config.ulp_supported)) | ||
3519 | break; | ||
3520 | |||
3274 | page_offset = (sizeof(struct iscsi_sge) * phba->params.num_sge_per_io * | 3521 | page_offset = (sizeof(struct iscsi_sge) * phba->params.num_sge_per_io * |
3275 | phba->fw_config.iscsi_icd_start) / PAGE_SIZE; | 3522 | phba->fw_config.iscsi_icd_start[ulp_num]) / PAGE_SIZE; |
3276 | for (i = 0; i < mem_descr->num_elements; i++) { | 3523 | for (i = 0; i < mem_descr->num_elements; i++) { |
3277 | hwi_build_be_sgl_arr(phba, pm_arr, &sgl); | 3524 | hwi_build_be_sgl_arr(phba, pm_arr, &sgl); |
3278 | status = be_cmd_iscsi_post_sgl_pages(&phba->ctrl, &sgl, | 3525 | status = be_cmd_iscsi_post_sgl_pages(&phba->ctrl, &sgl, |
@@ -3324,13 +3571,15 @@ beiscsi_create_wrb_rings(struct beiscsi_hba *phba, | |||
3324 | { | 3571 | { |
3325 | unsigned int wrb_mem_index, offset, size, num_wrb_rings; | 3572 | unsigned int wrb_mem_index, offset, size, num_wrb_rings; |
3326 | u64 pa_addr_lo; | 3573 | u64 pa_addr_lo; |
3327 | unsigned int idx, num, i; | 3574 | unsigned int idx, num, i, ulp_num; |
3328 | struct mem_array *pwrb_arr; | 3575 | struct mem_array *pwrb_arr; |
3329 | void *wrb_vaddr; | 3576 | void *wrb_vaddr; |
3330 | struct be_dma_mem sgl; | 3577 | struct be_dma_mem sgl; |
3331 | struct be_mem_descriptor *mem_descr; | 3578 | struct be_mem_descriptor *mem_descr; |
3332 | struct hwi_wrb_context *pwrb_context; | 3579 | struct hwi_wrb_context *pwrb_context; |
3333 | int status; | 3580 | int status; |
3581 | uint8_t ulp_count = 0, ulp_base_num = 0; | ||
3582 | uint16_t cid_count_ulp[BEISCSI_ULP_COUNT] = { 0 }; | ||
3334 | 3583 | ||
3335 | idx = 0; | 3584 | idx = 0; |
3336 | mem_descr = phba->init_mem; | 3585 | mem_descr = phba->init_mem; |
@@ -3374,14 +3623,37 @@ beiscsi_create_wrb_rings(struct beiscsi_hba *phba, | |||
3374 | num_wrb_rings--; | 3623 | num_wrb_rings--; |
3375 | } | 3624 | } |
3376 | } | 3625 | } |
3626 | |||
3627 | /* Get the ULP Count */ | ||
3628 | for (ulp_num = 0; ulp_num < BEISCSI_ULP_COUNT; ulp_num++) | ||
3629 | if (test_bit(ulp_num, &phba->fw_config.ulp_supported)) { | ||
3630 | ulp_count++; | ||
3631 | ulp_base_num = ulp_num; | ||
3632 | cid_count_ulp[ulp_num] = | ||
3633 | BEISCSI_GET_CID_COUNT(phba, ulp_num); | ||
3634 | } | ||
3635 | |||
3377 | for (i = 0; i < phba->params.cxns_per_ctrl; i++) { | 3636 | for (i = 0; i < phba->params.cxns_per_ctrl; i++) { |
3378 | wrb_mem_index = 0; | 3637 | wrb_mem_index = 0; |
3379 | offset = 0; | 3638 | offset = 0; |
3380 | size = 0; | 3639 | size = 0; |
3381 | 3640 | ||
3641 | if (ulp_count > 1) { | ||
3642 | ulp_base_num = (ulp_base_num + 1) % BEISCSI_ULP_COUNT; | ||
3643 | |||
3644 | if (!cid_count_ulp[ulp_base_num]) | ||
3645 | ulp_base_num = (ulp_base_num + 1) % | ||
3646 | BEISCSI_ULP_COUNT; | ||
3647 | |||
3648 | cid_count_ulp[ulp_base_num]--; | ||
3649 | } | ||
3650 | |||
3651 | |||
3382 | hwi_build_be_sgl_by_offset(phba, &pwrb_arr[i], &sgl); | 3652 | hwi_build_be_sgl_by_offset(phba, &pwrb_arr[i], &sgl); |
3383 | status = be_cmd_wrbq_create(&phba->ctrl, &sgl, | 3653 | status = be_cmd_wrbq_create(&phba->ctrl, &sgl, |
3384 | &phwi_context->be_wrbq[i]); | 3654 | &phwi_context->be_wrbq[i], |
3655 | &phwi_ctrlr->wrb_context[i], | ||
3656 | ulp_base_num); | ||
3385 | if (status != 0) { | 3657 | if (status != 0) { |
3386 | beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_INIT, | 3658 | beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_INIT, |
3387 | "BM_%d : wrbq create failed."); | 3659 | "BM_%d : wrbq create failed."); |
@@ -3389,7 +3661,6 @@ beiscsi_create_wrb_rings(struct beiscsi_hba *phba, | |||
3389 | return status; | 3661 | return status; |
3390 | } | 3662 | } |
3391 | pwrb_context = &phwi_ctrlr->wrb_context[i]; | 3663 | pwrb_context = &phwi_ctrlr->wrb_context[i]; |
3392 | pwrb_context->cid = phwi_context->be_wrbq[i].id; | ||
3393 | BE_SET_CID_TO_CRI(i, pwrb_context->cid); | 3664 | BE_SET_CID_TO_CRI(i, pwrb_context->cid); |
3394 | } | 3665 | } |
3395 | kfree(pwrb_arr); | 3666 | kfree(pwrb_arr); |
@@ -3433,10 +3704,13 @@ static void hwi_cleanup(struct beiscsi_hba *phba) | |||
3433 | struct hwi_controller *phwi_ctrlr; | 3704 | struct hwi_controller *phwi_ctrlr; |
3434 | struct hwi_context_memory *phwi_context; | 3705 | struct hwi_context_memory *phwi_context; |
3435 | struct hwi_async_pdu_context *pasync_ctx; | 3706 | struct hwi_async_pdu_context *pasync_ctx; |
3436 | int i, eq_num; | 3707 | int i, eq_num, ulp_num; |
3437 | 3708 | ||
3438 | phwi_ctrlr = phba->phwi_ctrlr; | 3709 | phwi_ctrlr = phba->phwi_ctrlr; |
3439 | phwi_context = phwi_ctrlr->phwi_ctxt; | 3710 | phwi_context = phwi_ctrlr->phwi_ctxt; |
3711 | |||
3712 | be_cmd_iscsi_remove_template_hdr(ctrl); | ||
3713 | |||
3440 | for (i = 0; i < phba->params.cxns_per_ctrl; i++) { | 3714 | for (i = 0; i < phba->params.cxns_per_ctrl; i++) { |
3441 | q = &phwi_context->be_wrbq[i]; | 3715 | q = &phwi_context->be_wrbq[i]; |
3442 | if (q->created) | 3716 | if (q->created) |
@@ -3445,13 +3719,20 @@ static void hwi_cleanup(struct beiscsi_hba *phba) | |||
3445 | kfree(phwi_context->be_wrbq); | 3719 | kfree(phwi_context->be_wrbq); |
3446 | free_wrb_handles(phba); | 3720 | free_wrb_handles(phba); |
3447 | 3721 | ||
3448 | q = &phwi_context->be_def_hdrq; | 3722 | for (ulp_num = 0; ulp_num < BEISCSI_ULP_COUNT; ulp_num++) { |
3449 | if (q->created) | 3723 | if (test_bit(ulp_num, &phba->fw_config.ulp_supported)) { |
3450 | beiscsi_cmd_q_destroy(ctrl, q, QTYPE_DPDUQ); | ||
3451 | 3724 | ||
3452 | q = &phwi_context->be_def_dataq; | 3725 | q = &phwi_context->be_def_hdrq[ulp_num]; |
3453 | if (q->created) | 3726 | if (q->created) |
3454 | beiscsi_cmd_q_destroy(ctrl, q, QTYPE_DPDUQ); | 3727 | beiscsi_cmd_q_destroy(ctrl, q, QTYPE_DPDUQ); |
3728 | |||
3729 | q = &phwi_context->be_def_dataq[ulp_num]; | ||
3730 | if (q->created) | ||
3731 | beiscsi_cmd_q_destroy(ctrl, q, QTYPE_DPDUQ); | ||
3732 | |||
3733 | pasync_ctx = phwi_ctrlr->phwi_ctxt->pasync_ctx[ulp_num]; | ||
3734 | } | ||
3735 | } | ||
3455 | 3736 | ||
3456 | beiscsi_cmd_q_destroy(ctrl, NULL, QTYPE_SGL); | 3737 | beiscsi_cmd_q_destroy(ctrl, NULL, QTYPE_SGL); |
3457 | 3738 | ||
@@ -3470,9 +3751,6 @@ static void hwi_cleanup(struct beiscsi_hba *phba) | |||
3470 | beiscsi_cmd_q_destroy(ctrl, q, QTYPE_EQ); | 3751 | beiscsi_cmd_q_destroy(ctrl, q, QTYPE_EQ); |
3471 | } | 3752 | } |
3472 | be_mcc_queues_destroy(phba); | 3753 | be_mcc_queues_destroy(phba); |
3473 | |||
3474 | pasync_ctx = phwi_ctrlr->phwi_ctxt->pasync_ctx; | ||
3475 | kfree(pasync_ctx->async_entry); | ||
3476 | be_cmd_fw_uninit(ctrl); | 3754 | be_cmd_fw_uninit(ctrl); |
3477 | } | 3755 | } |
3478 | 3756 | ||
@@ -3538,8 +3816,19 @@ static void find_num_cpus(struct beiscsi_hba *phba) | |||
3538 | BEISCSI_MAX_NUM_CPUS : num_cpus; | 3816 | BEISCSI_MAX_NUM_CPUS : num_cpus; |
3539 | break; | 3817 | break; |
3540 | case BE_GEN4: | 3818 | case BE_GEN4: |
3541 | phba->num_cpus = (num_cpus > OC_SKH_MAX_NUM_CPUS) ? | 3819 | /* |
3542 | OC_SKH_MAX_NUM_CPUS : num_cpus; | 3820 | * If eqid_count == 1 fall back to |
3821 | * INTX mechanism | ||
3822 | **/ | ||
3823 | if (phba->fw_config.eqid_count == 1) { | ||
3824 | enable_msix = 0; | ||
3825 | phba->num_cpus = 1; | ||
3826 | return; | ||
3827 | } | ||
3828 | |||
3829 | phba->num_cpus = | ||
3830 | (num_cpus > (phba->fw_config.eqid_count - 1)) ? | ||
3831 | (phba->fw_config.eqid_count - 1) : num_cpus; | ||
3543 | break; | 3832 | break; |
3544 | default: | 3833 | default: |
3545 | phba->num_cpus = 1; | 3834 | phba->num_cpus = 1; |
@@ -3552,10 +3841,8 @@ static int hwi_init_port(struct beiscsi_hba *phba) | |||
3552 | struct hwi_context_memory *phwi_context; | 3841 | struct hwi_context_memory *phwi_context; |
3553 | unsigned int def_pdu_ring_sz; | 3842 | unsigned int def_pdu_ring_sz; |
3554 | struct be_ctrl_info *ctrl = &phba->ctrl; | 3843 | struct be_ctrl_info *ctrl = &phba->ctrl; |
3555 | int status; | 3844 | int status, ulp_num; |
3556 | 3845 | ||
3557 | def_pdu_ring_sz = | ||
3558 | phba->params.asyncpdus_per_ctrl * sizeof(struct phys_addr); | ||
3559 | phwi_ctrlr = phba->phwi_ctrlr; | 3846 | phwi_ctrlr = phba->phwi_ctrlr; |
3560 | phwi_context = phwi_ctrlr->phwi_ctxt; | 3847 | phwi_context = phwi_ctrlr->phwi_ctxt; |
3561 | phwi_context->max_eqd = 0; | 3848 | phwi_context->max_eqd = 0; |
@@ -3588,27 +3875,48 @@ static int hwi_init_port(struct beiscsi_hba *phba) | |||
3588 | goto error; | 3875 | goto error; |
3589 | } | 3876 | } |
3590 | 3877 | ||
3591 | status = beiscsi_create_def_hdr(phba, phwi_context, phwi_ctrlr, | 3878 | for (ulp_num = 0; ulp_num < BEISCSI_ULP_COUNT; ulp_num++) { |
3592 | def_pdu_ring_sz); | 3879 | if (test_bit(ulp_num, &phba->fw_config.ulp_supported)) { |
3593 | if (status != 0) { | 3880 | |
3594 | beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_INIT, | 3881 | def_pdu_ring_sz = |
3595 | "BM_%d : Default Header not created\n"); | 3882 | BEISCSI_GET_CID_COUNT(phba, ulp_num) * |
3596 | goto error; | 3883 | sizeof(struct phys_addr); |
3884 | |||
3885 | status = beiscsi_create_def_hdr(phba, phwi_context, | ||
3886 | phwi_ctrlr, | ||
3887 | def_pdu_ring_sz, | ||
3888 | ulp_num); | ||
3889 | if (status != 0) { | ||
3890 | beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_INIT, | ||
3891 | "BM_%d : Default Header not created for ULP : %d\n", | ||
3892 | ulp_num); | ||
3893 | goto error; | ||
3894 | } | ||
3895 | |||
3896 | status = beiscsi_create_def_data(phba, phwi_context, | ||
3897 | phwi_ctrlr, | ||
3898 | def_pdu_ring_sz, | ||
3899 | ulp_num); | ||
3900 | if (status != 0) { | ||
3901 | beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_INIT, | ||
3902 | "BM_%d : Default Data not created for ULP : %d\n", | ||
3903 | ulp_num); | ||
3904 | goto error; | ||
3905 | } | ||
3906 | } | ||
3597 | } | 3907 | } |
3598 | 3908 | ||
3599 | status = beiscsi_create_def_data(phba, phwi_context, | 3909 | status = beiscsi_post_pages(phba); |
3600 | phwi_ctrlr, def_pdu_ring_sz); | ||
3601 | if (status != 0) { | 3910 | if (status != 0) { |
3602 | beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_INIT, | 3911 | beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_INIT, |
3603 | "BM_%d : Default Data not created\n"); | 3912 | "BM_%d : Post SGL Pages Failed\n"); |
3604 | goto error; | 3913 | goto error; |
3605 | } | 3914 | } |
3606 | 3915 | ||
3607 | status = beiscsi_post_pages(phba); | 3916 | status = beiscsi_post_template_hdr(phba); |
3608 | if (status != 0) { | 3917 | if (status != 0) { |
3609 | beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_INIT, | 3918 | beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_INIT, |
3610 | "BM_%d : Post SGL Pages Failed\n"); | 3919 | "BM_%d : Template HDR Posting for CXN Failed\n"); |
3611 | goto error; | ||
3612 | } | 3920 | } |
3613 | 3921 | ||
3614 | status = beiscsi_create_wrb_rings(phba, phwi_context, phwi_ctrlr); | 3922 | status = beiscsi_create_wrb_rings(phba, phwi_context, phwi_ctrlr); |
@@ -3618,6 +3926,26 @@ static int hwi_init_port(struct beiscsi_hba *phba) | |||
3618 | goto error; | 3926 | goto error; |
3619 | } | 3927 | } |
3620 | 3928 | ||
3929 | for (ulp_num = 0; ulp_num < BEISCSI_ULP_COUNT; ulp_num++) { | ||
3930 | uint16_t async_arr_idx = 0; | ||
3931 | |||
3932 | if (test_bit(ulp_num, &phba->fw_config.ulp_supported)) { | ||
3933 | uint16_t cri = 0; | ||
3934 | struct hwi_async_pdu_context *pasync_ctx; | ||
3935 | |||
3936 | pasync_ctx = HWI_GET_ASYNC_PDU_CTX( | ||
3937 | phwi_ctrlr, ulp_num); | ||
3938 | for (cri = 0; cri < | ||
3939 | phba->params.cxns_per_ctrl; cri++) { | ||
3940 | if (ulp_num == BEISCSI_GET_ULP_FROM_CRI | ||
3941 | (phwi_ctrlr, cri)) | ||
3942 | pasync_ctx->cid_to_async_cri_map[ | ||
3943 | phwi_ctrlr->wrb_context[cri].cid] = | ||
3944 | async_arr_idx++; | ||
3945 | } | ||
3946 | } | ||
3947 | } | ||
3948 | |||
3621 | beiscsi_log(phba, KERN_INFO, BEISCSI_LOG_INIT, | 3949 | beiscsi_log(phba, KERN_INFO, BEISCSI_LOG_INIT, |
3622 | "BM_%d : hwi_init_port success\n"); | 3950 | "BM_%d : hwi_init_port success\n"); |
3623 | return 0; | 3951 | return 0; |
@@ -3682,6 +4010,7 @@ static void beiscsi_free_mem(struct beiscsi_hba *phba) | |||
3682 | (unsigned long)mem_descr->mem_array[j - 1]. | 4010 | (unsigned long)mem_descr->mem_array[j - 1]. |
3683 | bus_address.u.a64.address); | 4011 | bus_address.u.a64.address); |
3684 | } | 4012 | } |
4013 | |||
3685 | kfree(mem_descr->mem_array); | 4014 | kfree(mem_descr->mem_array); |
3686 | mem_descr++; | 4015 | mem_descr++; |
3687 | } | 4016 | } |
@@ -3721,6 +4050,7 @@ static int beiscsi_init_sgl_handle(struct beiscsi_hba *phba) | |||
3721 | struct sgl_handle *psgl_handle; | 4050 | struct sgl_handle *psgl_handle; |
3722 | struct iscsi_sge *pfrag; | 4051 | struct iscsi_sge *pfrag; |
3723 | unsigned int arr_index, i, idx; | 4052 | unsigned int arr_index, i, idx; |
4053 | unsigned int ulp_icd_start, ulp_num = 0; | ||
3724 | 4054 | ||
3725 | phba->io_sgl_hndl_avbl = 0; | 4055 | phba->io_sgl_hndl_avbl = 0; |
3726 | phba->eh_sgl_hndl_avbl = 0; | 4056 | phba->eh_sgl_hndl_avbl = 0; |
@@ -3787,6 +4117,12 @@ static int beiscsi_init_sgl_handle(struct beiscsi_hba *phba) | |||
3787 | "\n BM_%d : mem_descr_sg->num_elements=%d\n", | 4117 | "\n BM_%d : mem_descr_sg->num_elements=%d\n", |
3788 | mem_descr_sg->num_elements); | 4118 | mem_descr_sg->num_elements); |
3789 | 4119 | ||
4120 | for (ulp_num = 0; ulp_num < BEISCSI_ULP_COUNT; ulp_num++) | ||
4121 | if (test_bit(ulp_num, &phba->fw_config.ulp_supported)) | ||
4122 | break; | ||
4123 | |||
4124 | ulp_icd_start = phba->fw_config.iscsi_icd_start[ulp_num]; | ||
4125 | |||
3790 | arr_index = 0; | 4126 | arr_index = 0; |
3791 | idx = 0; | 4127 | idx = 0; |
3792 | while (idx < mem_descr_sg->num_elements) { | 4128 | while (idx < mem_descr_sg->num_elements) { |
@@ -3805,8 +4141,7 @@ static int beiscsi_init_sgl_handle(struct beiscsi_hba *phba) | |||
3805 | AMAP_SET_BITS(struct amap_iscsi_sge, addr_hi, pfrag, 0); | 4141 | AMAP_SET_BITS(struct amap_iscsi_sge, addr_hi, pfrag, 0); |
3806 | AMAP_SET_BITS(struct amap_iscsi_sge, addr_lo, pfrag, 0); | 4142 | AMAP_SET_BITS(struct amap_iscsi_sge, addr_lo, pfrag, 0); |
3807 | pfrag += phba->params.num_sge_per_io; | 4143 | pfrag += phba->params.num_sge_per_io; |
3808 | psgl_handle->sgl_index = | 4144 | psgl_handle->sgl_index = ulp_icd_start + arr_index++; |
3809 | phba->fw_config.iscsi_icd_start + arr_index++; | ||
3810 | } | 4145 | } |
3811 | idx++; | 4146 | idx++; |
3812 | } | 4147 | } |
@@ -3819,15 +4154,46 @@ static int beiscsi_init_sgl_handle(struct beiscsi_hba *phba) | |||
3819 | 4154 | ||
3820 | static int hba_setup_cid_tbls(struct beiscsi_hba *phba) | 4155 | static int hba_setup_cid_tbls(struct beiscsi_hba *phba) |
3821 | { | 4156 | { |
3822 | int i; | 4157 | int ret; |
4158 | uint16_t i, ulp_num; | ||
4159 | struct ulp_cid_info *ptr_cid_info = NULL; | ||
3823 | 4160 | ||
3824 | phba->cid_array = kzalloc(sizeof(void *) * phba->params.cxns_per_ctrl, | 4161 | for (ulp_num = 0; ulp_num < BEISCSI_ULP_COUNT; ulp_num++) { |
3825 | GFP_KERNEL); | 4162 | if (test_bit(ulp_num, (void *)&phba->fw_config.ulp_supported)) { |
3826 | if (!phba->cid_array) { | 4163 | ptr_cid_info = kzalloc(sizeof(struct ulp_cid_info), |
3827 | beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_INIT, | 4164 | GFP_KERNEL); |
3828 | "BM_%d : Failed to allocate memory in " | 4165 | |
3829 | "hba_setup_cid_tbls\n"); | 4166 | if (!ptr_cid_info) { |
3830 | return -ENOMEM; | 4167 | beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_INIT, |
4168 | "BM_%d : Failed to allocate memory" | ||
4169 | "for ULP_CID_INFO for ULP : %d\n", | ||
4170 | ulp_num); | ||
4171 | ret = -ENOMEM; | ||
4172 | goto free_memory; | ||
4173 | |||
4174 | } | ||
4175 | |||
4176 | /* Allocate memory for CID array */ | ||
4177 | ptr_cid_info->cid_array = kzalloc(sizeof(void *) * | ||
4178 | BEISCSI_GET_CID_COUNT(phba, | ||
4179 | ulp_num), GFP_KERNEL); | ||
4180 | if (!ptr_cid_info->cid_array) { | ||
4181 | beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_INIT, | ||
4182 | "BM_%d : Failed to allocate memory" | ||
4183 | "for CID_ARRAY for ULP : %d\n", | ||
4184 | ulp_num); | ||
4185 | kfree(ptr_cid_info); | ||
4186 | ptr_cid_info = NULL; | ||
4187 | ret = -ENOMEM; | ||
4188 | |||
4189 | goto free_memory; | ||
4190 | } | ||
4191 | ptr_cid_info->avlbl_cids = BEISCSI_GET_CID_COUNT( | ||
4192 | phba, ulp_num); | ||
4193 | |||
4194 | /* Save the cid_info_array ptr */ | ||
4195 | phba->cid_array_info[ulp_num] = ptr_cid_info; | ||
4196 | } | ||
3831 | } | 4197 | } |
3832 | phba->ep_array = kzalloc(sizeof(struct iscsi_endpoint *) * | 4198 | phba->ep_array = kzalloc(sizeof(struct iscsi_endpoint *) * |
3833 | phba->params.cxns_per_ctrl, GFP_KERNEL); | 4199 | phba->params.cxns_per_ctrl, GFP_KERNEL); |
@@ -3835,9 +4201,9 @@ static int hba_setup_cid_tbls(struct beiscsi_hba *phba) | |||
3835 | beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_INIT, | 4201 | beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_INIT, |
3836 | "BM_%d : Failed to allocate memory in " | 4202 | "BM_%d : Failed to allocate memory in " |
3837 | "hba_setup_cid_tbls\n"); | 4203 | "hba_setup_cid_tbls\n"); |
3838 | kfree(phba->cid_array); | 4204 | ret = -ENOMEM; |
3839 | phba->cid_array = NULL; | 4205 | |
3840 | return -ENOMEM; | 4206 | goto free_memory; |
3841 | } | 4207 | } |
3842 | 4208 | ||
3843 | phba->conn_table = kzalloc(sizeof(struct beiscsi_conn *) * | 4209 | phba->conn_table = kzalloc(sizeof(struct beiscsi_conn *) * |
@@ -3847,18 +4213,44 @@ static int hba_setup_cid_tbls(struct beiscsi_hba *phba) | |||
3847 | "BM_%d : Failed to allocate memory in" | 4213 | "BM_%d : Failed to allocate memory in" |
3848 | "hba_setup_cid_tbls\n"); | 4214 | "hba_setup_cid_tbls\n"); |
3849 | 4215 | ||
3850 | kfree(phba->cid_array); | ||
3851 | kfree(phba->ep_array); | 4216 | kfree(phba->ep_array); |
3852 | phba->cid_array = NULL; | ||
3853 | phba->ep_array = NULL; | 4217 | phba->ep_array = NULL; |
3854 | return -ENOMEM; | 4218 | ret = -ENOMEM; |
4219 | } | ||
4220 | |||
4221 | for (i = 0; i < phba->params.cxns_per_ctrl; i++) { | ||
4222 | ulp_num = phba->phwi_ctrlr->wrb_context[i].ulp_num; | ||
4223 | |||
4224 | ptr_cid_info = phba->cid_array_info[ulp_num]; | ||
4225 | ptr_cid_info->cid_array[ptr_cid_info->cid_alloc++] = | ||
4226 | phba->phwi_ctrlr->wrb_context[i].cid; | ||
4227 | |||
3855 | } | 4228 | } |
3856 | 4229 | ||
3857 | for (i = 0; i < phba->params.cxns_per_ctrl; i++) | 4230 | for (ulp_num = 0; ulp_num < BEISCSI_ULP_COUNT; ulp_num++) { |
3858 | phba->cid_array[i] = phba->phwi_ctrlr->wrb_context[i].cid; | 4231 | if (test_bit(ulp_num, (void *)&phba->fw_config.ulp_supported)) { |
4232 | ptr_cid_info = phba->cid_array_info[ulp_num]; | ||
3859 | 4233 | ||
3860 | phba->avlbl_cids = phba->params.cxns_per_ctrl; | 4234 | ptr_cid_info->cid_alloc = 0; |
4235 | ptr_cid_info->cid_free = 0; | ||
4236 | } | ||
4237 | } | ||
3861 | return 0; | 4238 | return 0; |
4239 | |||
4240 | free_memory: | ||
4241 | for (ulp_num = 0; ulp_num < BEISCSI_ULP_COUNT; ulp_num++) { | ||
4242 | if (test_bit(ulp_num, (void *)&phba->fw_config.ulp_supported)) { | ||
4243 | ptr_cid_info = phba->cid_array_info[ulp_num]; | ||
4244 | |||
4245 | if (ptr_cid_info) { | ||
4246 | kfree(ptr_cid_info->cid_array); | ||
4247 | kfree(ptr_cid_info); | ||
4248 | phba->cid_array_info[ulp_num] = NULL; | ||
4249 | } | ||
4250 | } | ||
4251 | } | ||
4252 | |||
4253 | return ret; | ||
3862 | } | 4254 | } |
3863 | 4255 | ||
3864 | static void hwi_enable_intr(struct beiscsi_hba *phba) | 4256 | static void hwi_enable_intr(struct beiscsi_hba *phba) |
@@ -4113,20 +4505,39 @@ static void hwi_purge_eq(struct beiscsi_hba *phba) | |||
4113 | 4505 | ||
4114 | static void beiscsi_clean_port(struct beiscsi_hba *phba) | 4506 | static void beiscsi_clean_port(struct beiscsi_hba *phba) |
4115 | { | 4507 | { |
4116 | int mgmt_status; | 4508 | int mgmt_status, ulp_num; |
4117 | 4509 | struct ulp_cid_info *ptr_cid_info = NULL; | |
4118 | mgmt_status = mgmt_epfw_cleanup(phba, CMD_CONNECTION_CHUTE_0); | 4510 | |
4119 | if (mgmt_status) | 4511 | for (ulp_num = 0; ulp_num < BEISCSI_ULP_COUNT; ulp_num++) { |
4120 | beiscsi_log(phba, KERN_WARNING, BEISCSI_LOG_INIT, | 4512 | if (test_bit(ulp_num, (void *)&phba->fw_config.ulp_supported)) { |
4121 | "BM_%d : mgmt_epfw_cleanup FAILED\n"); | 4513 | mgmt_status = mgmt_epfw_cleanup(phba, ulp_num); |
4514 | if (mgmt_status) | ||
4515 | beiscsi_log(phba, KERN_WARNING, | ||
4516 | BEISCSI_LOG_INIT, | ||
4517 | "BM_%d : mgmt_epfw_cleanup FAILED" | ||
4518 | " for ULP_%d\n", ulp_num); | ||
4519 | } | ||
4520 | } | ||
4122 | 4521 | ||
4123 | hwi_purge_eq(phba); | 4522 | hwi_purge_eq(phba); |
4124 | hwi_cleanup(phba); | 4523 | hwi_cleanup(phba); |
4125 | kfree(phba->io_sgl_hndl_base); | 4524 | kfree(phba->io_sgl_hndl_base); |
4126 | kfree(phba->eh_sgl_hndl_base); | 4525 | kfree(phba->eh_sgl_hndl_base); |
4127 | kfree(phba->cid_array); | ||
4128 | kfree(phba->ep_array); | 4526 | kfree(phba->ep_array); |
4129 | kfree(phba->conn_table); | 4527 | kfree(phba->conn_table); |
4528 | |||
4529 | for (ulp_num = 0; ulp_num < BEISCSI_ULP_COUNT; ulp_num++) { | ||
4530 | if (test_bit(ulp_num, (void *)&phba->fw_config.ulp_supported)) { | ||
4531 | ptr_cid_info = phba->cid_array_info[ulp_num]; | ||
4532 | |||
4533 | if (ptr_cid_info) { | ||
4534 | kfree(ptr_cid_info->cid_array); | ||
4535 | kfree(ptr_cid_info); | ||
4536 | phba->cid_array_info[ulp_num] = NULL; | ||
4537 | } | ||
4538 | } | ||
4539 | } | ||
4540 | |||
4130 | } | 4541 | } |
4131 | 4542 | ||
4132 | /** | 4543 | /** |
@@ -4255,8 +4666,8 @@ beiscsi_offload_connection(struct beiscsi_conn *beiscsi_conn, | |||
4255 | doorbell |= (pwrb_handle->wrb_index & DB_DEF_PDU_WRB_INDEX_MASK) | 4666 | doorbell |= (pwrb_handle->wrb_index & DB_DEF_PDU_WRB_INDEX_MASK) |
4256 | << DB_DEF_PDU_WRB_INDEX_SHIFT; | 4667 | << DB_DEF_PDU_WRB_INDEX_SHIFT; |
4257 | doorbell |= 1 << DB_DEF_PDU_NUM_POSTED_SHIFT; | 4668 | doorbell |= 1 << DB_DEF_PDU_NUM_POSTED_SHIFT; |
4258 | 4669 | iowrite32(doorbell, phba->db_va + | |
4259 | iowrite32(doorbell, phba->db_va + DB_TXULP0_OFFSET); | 4670 | beiscsi_conn->doorbell_offset); |
4260 | } | 4671 | } |
4261 | 4672 | ||
4262 | static void beiscsi_parse_pdu(struct iscsi_conn *conn, itt_t itt, | 4673 | static void beiscsi_parse_pdu(struct iscsi_conn *conn, itt_t itt, |
@@ -4481,7 +4892,8 @@ int beiscsi_iotask_v2(struct iscsi_task *task, struct scatterlist *sg, | |||
4481 | DB_DEF_PDU_WRB_INDEX_MASK) << | 4892 | DB_DEF_PDU_WRB_INDEX_MASK) << |
4482 | DB_DEF_PDU_WRB_INDEX_SHIFT; | 4893 | DB_DEF_PDU_WRB_INDEX_SHIFT; |
4483 | doorbell |= 1 << DB_DEF_PDU_NUM_POSTED_SHIFT; | 4894 | doorbell |= 1 << DB_DEF_PDU_NUM_POSTED_SHIFT; |
4484 | iowrite32(doorbell, phba->db_va + DB_TXULP0_OFFSET); | 4895 | iowrite32(doorbell, phba->db_va + |
4896 | beiscsi_conn->doorbell_offset); | ||
4485 | return 0; | 4897 | return 0; |
4486 | } | 4898 | } |
4487 | 4899 | ||
@@ -4536,7 +4948,8 @@ static int beiscsi_iotask(struct iscsi_task *task, struct scatterlist *sg, | |||
4536 | DB_DEF_PDU_WRB_INDEX_MASK) << DB_DEF_PDU_WRB_INDEX_SHIFT; | 4948 | DB_DEF_PDU_WRB_INDEX_MASK) << DB_DEF_PDU_WRB_INDEX_SHIFT; |
4537 | doorbell |= 1 << DB_DEF_PDU_NUM_POSTED_SHIFT; | 4949 | doorbell |= 1 << DB_DEF_PDU_NUM_POSTED_SHIFT; |
4538 | 4950 | ||
4539 | iowrite32(doorbell, phba->db_va + DB_TXULP0_OFFSET); | 4951 | iowrite32(doorbell, phba->db_va + |
4952 | beiscsi_conn->doorbell_offset); | ||
4540 | return 0; | 4953 | return 0; |
4541 | } | 4954 | } |
4542 | 4955 | ||
@@ -4638,7 +5051,8 @@ static int beiscsi_mtask(struct iscsi_task *task) | |||
4638 | doorbell |= (io_task->pwrb_handle->wrb_index & | 5051 | doorbell |= (io_task->pwrb_handle->wrb_index & |
4639 | DB_DEF_PDU_WRB_INDEX_MASK) << DB_DEF_PDU_WRB_INDEX_SHIFT; | 5052 | DB_DEF_PDU_WRB_INDEX_MASK) << DB_DEF_PDU_WRB_INDEX_SHIFT; |
4640 | doorbell |= 1 << DB_DEF_PDU_NUM_POSTED_SHIFT; | 5053 | doorbell |= 1 << DB_DEF_PDU_NUM_POSTED_SHIFT; |
4641 | iowrite32(doorbell, phba->db_va + DB_TXULP0_OFFSET); | 5054 | iowrite32(doorbell, phba->db_va + |
5055 | beiscsi_conn->doorbell_offset); | ||
4642 | return 0; | 5056 | return 0; |
4643 | } | 5057 | } |
4644 | 5058 | ||
@@ -4663,8 +5077,12 @@ static int beiscsi_task_xmit(struct iscsi_task *task) | |||
4663 | struct beiscsi_hba *phba = NULL; | 5077 | struct beiscsi_hba *phba = NULL; |
4664 | 5078 | ||
4665 | phba = ((struct beiscsi_conn *)conn->dd_data)->phba; | 5079 | phba = ((struct beiscsi_conn *)conn->dd_data)->phba; |
4666 | beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_IO, | 5080 | beiscsi_log(phba, KERN_ERR, |
4667 | "BM_%d : scsi_dma_map Failed\n"); | 5081 | BEISCSI_LOG_IO | BEISCSI_LOG_ISCSI, |
5082 | "BM_%d : scsi_dma_map Failed " | ||
5083 | "Driver_ITT : 0x%x ITT : 0x%x Xferlen : 0x%x\n", | ||
5084 | be32_to_cpu(io_task->cmd_bhs->iscsi_hdr.itt), | ||
5085 | io_task->libiscsi_itt, scsi_bufflen(sc)); | ||
4668 | 5086 | ||
4669 | return num_sg; | 5087 | return num_sg; |
4670 | } | 5088 | } |
@@ -4769,10 +5187,12 @@ void beiscsi_hba_attrs_init(struct beiscsi_hba *phba) | |||
4769 | /* | 5187 | /* |
4770 | * beiscsi_quiesce()- Cleanup Driver resources | 5188 | * beiscsi_quiesce()- Cleanup Driver resources |
4771 | * @phba: Instance Priv structure | 5189 | * @phba: Instance Priv structure |
5190 | * @unload_state:i Clean or EEH unload state | ||
4772 | * | 5191 | * |
4773 | * Free the OS and HW resources held by the driver | 5192 | * Free the OS and HW resources held by the driver |
4774 | **/ | 5193 | **/ |
4775 | static void beiscsi_quiesce(struct beiscsi_hba *phba) | 5194 | static void beiscsi_quiesce(struct beiscsi_hba *phba, |
5195 | uint32_t unload_state) | ||
4776 | { | 5196 | { |
4777 | struct hwi_controller *phwi_ctrlr; | 5197 | struct hwi_controller *phwi_ctrlr; |
4778 | struct hwi_context_memory *phwi_context; | 5198 | struct hwi_context_memory *phwi_context; |
@@ -4785,28 +5205,37 @@ static void beiscsi_quiesce(struct beiscsi_hba *phba) | |||
4785 | if (phba->msix_enabled) { | 5205 | if (phba->msix_enabled) { |
4786 | for (i = 0; i <= phba->num_cpus; i++) { | 5206 | for (i = 0; i <= phba->num_cpus; i++) { |
4787 | msix_vec = phba->msix_entries[i].vector; | 5207 | msix_vec = phba->msix_entries[i].vector; |
5208 | synchronize_irq(msix_vec); | ||
4788 | free_irq(msix_vec, &phwi_context->be_eq[i]); | 5209 | free_irq(msix_vec, &phwi_context->be_eq[i]); |
4789 | kfree(phba->msi_name[i]); | 5210 | kfree(phba->msi_name[i]); |
4790 | } | 5211 | } |
4791 | } else | 5212 | } else |
4792 | if (phba->pcidev->irq) | 5213 | if (phba->pcidev->irq) { |
5214 | synchronize_irq(phba->pcidev->irq); | ||
4793 | free_irq(phba->pcidev->irq, phba); | 5215 | free_irq(phba->pcidev->irq, phba); |
5216 | } | ||
4794 | pci_disable_msix(phba->pcidev); | 5217 | pci_disable_msix(phba->pcidev); |
4795 | destroy_workqueue(phba->wq); | 5218 | |
4796 | if (blk_iopoll_enabled) | 5219 | if (blk_iopoll_enabled) |
4797 | for (i = 0; i < phba->num_cpus; i++) { | 5220 | for (i = 0; i < phba->num_cpus; i++) { |
4798 | pbe_eq = &phwi_context->be_eq[i]; | 5221 | pbe_eq = &phwi_context->be_eq[i]; |
4799 | blk_iopoll_disable(&pbe_eq->iopoll); | 5222 | blk_iopoll_disable(&pbe_eq->iopoll); |
4800 | } | 5223 | } |
4801 | 5224 | ||
4802 | beiscsi_clean_port(phba); | 5225 | if (unload_state == BEISCSI_CLEAN_UNLOAD) { |
4803 | beiscsi_free_mem(phba); | 5226 | destroy_workqueue(phba->wq); |
5227 | beiscsi_clean_port(phba); | ||
5228 | beiscsi_free_mem(phba); | ||
4804 | 5229 | ||
4805 | beiscsi_unmap_pci_function(phba); | 5230 | beiscsi_unmap_pci_function(phba); |
4806 | pci_free_consistent(phba->pcidev, | 5231 | pci_free_consistent(phba->pcidev, |
4807 | phba->ctrl.mbox_mem_alloced.size, | 5232 | phba->ctrl.mbox_mem_alloced.size, |
4808 | phba->ctrl.mbox_mem_alloced.va, | 5233 | phba->ctrl.mbox_mem_alloced.va, |
4809 | phba->ctrl.mbox_mem_alloced.dma); | 5234 | phba->ctrl.mbox_mem_alloced.dma); |
5235 | } else { | ||
5236 | hwi_purge_eq(phba); | ||
5237 | hwi_cleanup(phba); | ||
5238 | } | ||
4810 | 5239 | ||
4811 | cancel_delayed_work_sync(&phba->beiscsi_hw_check_task); | 5240 | cancel_delayed_work_sync(&phba->beiscsi_hw_check_task); |
4812 | } | 5241 | } |
@@ -4823,11 +5252,13 @@ static void beiscsi_remove(struct pci_dev *pcidev) | |||
4823 | } | 5252 | } |
4824 | 5253 | ||
4825 | beiscsi_destroy_def_ifaces(phba); | 5254 | beiscsi_destroy_def_ifaces(phba); |
4826 | beiscsi_quiesce(phba); | 5255 | beiscsi_quiesce(phba, BEISCSI_CLEAN_UNLOAD); |
4827 | iscsi_boot_destroy_kset(phba->boot_kset); | 5256 | iscsi_boot_destroy_kset(phba->boot_kset); |
4828 | iscsi_host_remove(phba->shost); | 5257 | iscsi_host_remove(phba->shost); |
4829 | pci_dev_put(phba->pcidev); | 5258 | pci_dev_put(phba->pcidev); |
4830 | iscsi_host_free(phba->shost); | 5259 | iscsi_host_free(phba->shost); |
5260 | pci_disable_pcie_error_reporting(pcidev); | ||
5261 | pci_set_drvdata(pcidev, NULL); | ||
4831 | pci_disable_device(pcidev); | 5262 | pci_disable_device(pcidev); |
4832 | } | 5263 | } |
4833 | 5264 | ||
@@ -4842,7 +5273,7 @@ static void beiscsi_shutdown(struct pci_dev *pcidev) | |||
4842 | return; | 5273 | return; |
4843 | } | 5274 | } |
4844 | 5275 | ||
4845 | beiscsi_quiesce(phba); | 5276 | beiscsi_quiesce(phba, BEISCSI_CLEAN_UNLOAD); |
4846 | pci_disable_device(pcidev); | 5277 | pci_disable_device(pcidev); |
4847 | } | 5278 | } |
4848 | 5279 | ||
@@ -4880,6 +5311,167 @@ beiscsi_hw_health_check(struct work_struct *work) | |||
4880 | msecs_to_jiffies(1000)); | 5311 | msecs_to_jiffies(1000)); |
4881 | } | 5312 | } |
4882 | 5313 | ||
5314 | |||
5315 | static pci_ers_result_t beiscsi_eeh_err_detected(struct pci_dev *pdev, | ||
5316 | pci_channel_state_t state) | ||
5317 | { | ||
5318 | struct beiscsi_hba *phba = NULL; | ||
5319 | |||
5320 | phba = (struct beiscsi_hba *)pci_get_drvdata(pdev); | ||
5321 | phba->state |= BE_ADAPTER_PCI_ERR; | ||
5322 | |||
5323 | beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_INIT, | ||
5324 | "BM_%d : EEH error detected\n"); | ||
5325 | |||
5326 | beiscsi_quiesce(phba, BEISCSI_EEH_UNLOAD); | ||
5327 | |||
5328 | if (state == pci_channel_io_perm_failure) { | ||
5329 | beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_INIT, | ||
5330 | "BM_%d : EEH : State PERM Failure"); | ||
5331 | return PCI_ERS_RESULT_DISCONNECT; | ||
5332 | } | ||
5333 | |||
5334 | pci_disable_device(pdev); | ||
5335 | |||
5336 | /* The error could cause the FW to trigger a flash debug dump. | ||
5337 | * Resetting the card while flash dump is in progress | ||
5338 | * can cause it not to recover; wait for it to finish. | ||
5339 | * Wait only for first function as it is needed only once per | ||
5340 | * adapter. | ||
5341 | **/ | ||
5342 | if (pdev->devfn == 0) | ||
5343 | ssleep(30); | ||
5344 | |||
5345 | return PCI_ERS_RESULT_NEED_RESET; | ||
5346 | } | ||
5347 | |||
5348 | static pci_ers_result_t beiscsi_eeh_reset(struct pci_dev *pdev) | ||
5349 | { | ||
5350 | struct beiscsi_hba *phba = NULL; | ||
5351 | int status = 0; | ||
5352 | |||
5353 | phba = (struct beiscsi_hba *)pci_get_drvdata(pdev); | ||
5354 | |||
5355 | beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_INIT, | ||
5356 | "BM_%d : EEH Reset\n"); | ||
5357 | |||
5358 | status = pci_enable_device(pdev); | ||
5359 | if (status) | ||
5360 | return PCI_ERS_RESULT_DISCONNECT; | ||
5361 | |||
5362 | pci_set_master(pdev); | ||
5363 | pci_set_power_state(pdev, PCI_D0); | ||
5364 | pci_restore_state(pdev); | ||
5365 | |||
5366 | /* Wait for the CHIP Reset to complete */ | ||
5367 | status = be_chk_reset_complete(phba); | ||
5368 | if (!status) { | ||
5369 | beiscsi_log(phba, KERN_WARNING, BEISCSI_LOG_INIT, | ||
5370 | "BM_%d : EEH Reset Completed\n"); | ||
5371 | } else { | ||
5372 | beiscsi_log(phba, KERN_WARNING, BEISCSI_LOG_INIT, | ||
5373 | "BM_%d : EEH Reset Completion Failure\n"); | ||
5374 | return PCI_ERS_RESULT_DISCONNECT; | ||
5375 | } | ||
5376 | |||
5377 | pci_cleanup_aer_uncorrect_error_status(pdev); | ||
5378 | return PCI_ERS_RESULT_RECOVERED; | ||
5379 | } | ||
5380 | |||
5381 | static void beiscsi_eeh_resume(struct pci_dev *pdev) | ||
5382 | { | ||
5383 | int ret = 0, i; | ||
5384 | struct be_eq_obj *pbe_eq; | ||
5385 | struct beiscsi_hba *phba = NULL; | ||
5386 | struct hwi_controller *phwi_ctrlr; | ||
5387 | struct hwi_context_memory *phwi_context; | ||
5388 | |||
5389 | phba = (struct beiscsi_hba *)pci_get_drvdata(pdev); | ||
5390 | pci_save_state(pdev); | ||
5391 | |||
5392 | if (enable_msix) | ||
5393 | find_num_cpus(phba); | ||
5394 | else | ||
5395 | phba->num_cpus = 1; | ||
5396 | |||
5397 | if (enable_msix) { | ||
5398 | beiscsi_msix_enable(phba); | ||
5399 | if (!phba->msix_enabled) | ||
5400 | phba->num_cpus = 1; | ||
5401 | } | ||
5402 | |||
5403 | ret = beiscsi_cmd_reset_function(phba); | ||
5404 | if (ret) { | ||
5405 | beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_INIT, | ||
5406 | "BM_%d : Reset Failed\n"); | ||
5407 | goto ret_err; | ||
5408 | } | ||
5409 | |||
5410 | ret = be_chk_reset_complete(phba); | ||
5411 | if (ret) { | ||
5412 | beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_INIT, | ||
5413 | "BM_%d : Failed to get out of reset.\n"); | ||
5414 | goto ret_err; | ||
5415 | } | ||
5416 | |||
5417 | beiscsi_get_params(phba); | ||
5418 | phba->shost->max_id = phba->params.cxns_per_ctrl; | ||
5419 | phba->shost->can_queue = phba->params.ios_per_ctrl; | ||
5420 | ret = hwi_init_controller(phba); | ||
5421 | |||
5422 | for (i = 0; i < MAX_MCC_CMD; i++) { | ||
5423 | init_waitqueue_head(&phba->ctrl.mcc_wait[i + 1]); | ||
5424 | phba->ctrl.mcc_tag[i] = i + 1; | ||
5425 | phba->ctrl.mcc_numtag[i + 1] = 0; | ||
5426 | phba->ctrl.mcc_tag_available++; | ||
5427 | } | ||
5428 | |||
5429 | phwi_ctrlr = phba->phwi_ctrlr; | ||
5430 | phwi_context = phwi_ctrlr->phwi_ctxt; | ||
5431 | |||
5432 | if (blk_iopoll_enabled) { | ||
5433 | for (i = 0; i < phba->num_cpus; i++) { | ||
5434 | pbe_eq = &phwi_context->be_eq[i]; | ||
5435 | blk_iopoll_init(&pbe_eq->iopoll, be_iopoll_budget, | ||
5436 | be_iopoll); | ||
5437 | blk_iopoll_enable(&pbe_eq->iopoll); | ||
5438 | } | ||
5439 | |||
5440 | i = (phba->msix_enabled) ? i : 0; | ||
5441 | /* Work item for MCC handling */ | ||
5442 | pbe_eq = &phwi_context->be_eq[i]; | ||
5443 | INIT_WORK(&pbe_eq->work_cqs, beiscsi_process_all_cqs); | ||
5444 | } else { | ||
5445 | if (phba->msix_enabled) { | ||
5446 | for (i = 0; i <= phba->num_cpus; i++) { | ||
5447 | pbe_eq = &phwi_context->be_eq[i]; | ||
5448 | INIT_WORK(&pbe_eq->work_cqs, | ||
5449 | beiscsi_process_all_cqs); | ||
5450 | } | ||
5451 | } else { | ||
5452 | pbe_eq = &phwi_context->be_eq[0]; | ||
5453 | INIT_WORK(&pbe_eq->work_cqs, | ||
5454 | beiscsi_process_all_cqs); | ||
5455 | } | ||
5456 | } | ||
5457 | |||
5458 | ret = beiscsi_init_irqs(phba); | ||
5459 | if (ret < 0) { | ||
5460 | beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_INIT, | ||
5461 | "BM_%d : beiscsi_eeh_resume - " | ||
5462 | "Failed to beiscsi_init_irqs\n"); | ||
5463 | goto ret_err; | ||
5464 | } | ||
5465 | |||
5466 | hwi_enable_intr(phba); | ||
5467 | phba->state &= ~BE_ADAPTER_PCI_ERR; | ||
5468 | |||
5469 | return; | ||
5470 | ret_err: | ||
5471 | beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_INIT, | ||
5472 | "BM_%d : AER EEH Resume Failed\n"); | ||
5473 | } | ||
5474 | |||
4883 | static int beiscsi_dev_probe(struct pci_dev *pcidev, | 5475 | static int beiscsi_dev_probe(struct pci_dev *pcidev, |
4884 | const struct pci_device_id *id) | 5476 | const struct pci_device_id *id) |
4885 | { | 5477 | { |
@@ -4887,7 +5479,7 @@ static int beiscsi_dev_probe(struct pci_dev *pcidev, | |||
4887 | struct hwi_controller *phwi_ctrlr; | 5479 | struct hwi_controller *phwi_ctrlr; |
4888 | struct hwi_context_memory *phwi_context; | 5480 | struct hwi_context_memory *phwi_context; |
4889 | struct be_eq_obj *pbe_eq; | 5481 | struct be_eq_obj *pbe_eq; |
4890 | int ret, i; | 5482 | int ret = 0, i; |
4891 | 5483 | ||
4892 | ret = beiscsi_enable_pci(pcidev); | 5484 | ret = beiscsi_enable_pci(pcidev); |
4893 | if (ret < 0) { | 5485 | if (ret < 0) { |
@@ -4903,10 +5495,20 @@ static int beiscsi_dev_probe(struct pci_dev *pcidev, | |||
4903 | goto disable_pci; | 5495 | goto disable_pci; |
4904 | } | 5496 | } |
4905 | 5497 | ||
5498 | /* Enable EEH reporting */ | ||
5499 | ret = pci_enable_pcie_error_reporting(pcidev); | ||
5500 | if (ret) | ||
5501 | beiscsi_log(phba, KERN_WARNING, BEISCSI_LOG_INIT, | ||
5502 | "BM_%d : PCIe Error Reporting " | ||
5503 | "Enabling Failed\n"); | ||
5504 | |||
5505 | pci_save_state(pcidev); | ||
5506 | |||
4906 | /* Initialize Driver configuration Paramters */ | 5507 | /* Initialize Driver configuration Paramters */ |
4907 | beiscsi_hba_attrs_init(phba); | 5508 | beiscsi_hba_attrs_init(phba); |
4908 | 5509 | ||
4909 | phba->fw_timeout = false; | 5510 | phba->fw_timeout = false; |
5511 | phba->mac_addr_set = false; | ||
4910 | 5512 | ||
4911 | 5513 | ||
4912 | switch (pcidev->device) { | 5514 | switch (pcidev->device) { |
@@ -4929,20 +5531,6 @@ static int beiscsi_dev_probe(struct pci_dev *pcidev, | |||
4929 | phba->generation = 0; | 5531 | phba->generation = 0; |
4930 | } | 5532 | } |
4931 | 5533 | ||
4932 | if (enable_msix) | ||
4933 | find_num_cpus(phba); | ||
4934 | else | ||
4935 | phba->num_cpus = 1; | ||
4936 | |||
4937 | beiscsi_log(phba, KERN_INFO, BEISCSI_LOG_INIT, | ||
4938 | "BM_%d : num_cpus = %d\n", | ||
4939 | phba->num_cpus); | ||
4940 | |||
4941 | if (enable_msix) { | ||
4942 | beiscsi_msix_enable(phba); | ||
4943 | if (!phba->msix_enabled) | ||
4944 | phba->num_cpus = 1; | ||
4945 | } | ||
4946 | ret = be_ctrl_init(phba, pcidev); | 5534 | ret = be_ctrl_init(phba, pcidev); |
4947 | if (ret) { | 5535 | if (ret) { |
4948 | beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_INIT, | 5536 | beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_INIT, |
@@ -4954,27 +5542,43 @@ static int beiscsi_dev_probe(struct pci_dev *pcidev, | |||
4954 | ret = beiscsi_cmd_reset_function(phba); | 5542 | ret = beiscsi_cmd_reset_function(phba); |
4955 | if (ret) { | 5543 | if (ret) { |
4956 | beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_INIT, | 5544 | beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_INIT, |
4957 | "BM_%d : Reset Failed. Aborting Crashdump\n"); | 5545 | "BM_%d : Reset Failed\n"); |
4958 | goto hba_free; | 5546 | goto hba_free; |
4959 | } | 5547 | } |
4960 | ret = be_chk_reset_complete(phba); | 5548 | ret = be_chk_reset_complete(phba); |
4961 | if (ret) { | 5549 | if (ret) { |
4962 | beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_INIT, | 5550 | beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_INIT, |
4963 | "BM_%d : Failed to get out of reset." | 5551 | "BM_%d : Failed to get out of reset.\n"); |
4964 | "Aborting Crashdump\n"); | ||
4965 | goto hba_free; | 5552 | goto hba_free; |
4966 | } | 5553 | } |
4967 | 5554 | ||
4968 | spin_lock_init(&phba->io_sgl_lock); | 5555 | spin_lock_init(&phba->io_sgl_lock); |
4969 | spin_lock_init(&phba->mgmt_sgl_lock); | 5556 | spin_lock_init(&phba->mgmt_sgl_lock); |
4970 | spin_lock_init(&phba->isr_lock); | 5557 | spin_lock_init(&phba->isr_lock); |
5558 | spin_lock_init(&phba->async_pdu_lock); | ||
4971 | ret = mgmt_get_fw_config(&phba->ctrl, phba); | 5559 | ret = mgmt_get_fw_config(&phba->ctrl, phba); |
4972 | if (ret != 0) { | 5560 | if (ret != 0) { |
4973 | beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_INIT, | 5561 | beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_INIT, |
4974 | "BM_%d : Error getting fw config\n"); | 5562 | "BM_%d : Error getting fw config\n"); |
4975 | goto free_port; | 5563 | goto free_port; |
4976 | } | 5564 | } |
4977 | phba->shost->max_id = phba->fw_config.iscsi_cid_count; | 5565 | |
5566 | if (enable_msix) | ||
5567 | find_num_cpus(phba); | ||
5568 | else | ||
5569 | phba->num_cpus = 1; | ||
5570 | |||
5571 | beiscsi_log(phba, KERN_INFO, BEISCSI_LOG_INIT, | ||
5572 | "BM_%d : num_cpus = %d\n", | ||
5573 | phba->num_cpus); | ||
5574 | |||
5575 | if (enable_msix) { | ||
5576 | beiscsi_msix_enable(phba); | ||
5577 | if (!phba->msix_enabled) | ||
5578 | phba->num_cpus = 1; | ||
5579 | } | ||
5580 | |||
5581 | phba->shost->max_id = phba->params.cxns_per_ctrl; | ||
4978 | beiscsi_get_params(phba); | 5582 | beiscsi_get_params(phba); |
4979 | phba->shost->can_queue = phba->params.ios_per_ctrl; | 5583 | phba->shost->can_queue = phba->params.ios_per_ctrl; |
4980 | ret = beiscsi_init_port(phba); | 5584 | ret = beiscsi_init_port(phba); |
@@ -4985,7 +5589,7 @@ static int beiscsi_dev_probe(struct pci_dev *pcidev, | |||
4985 | goto free_port; | 5589 | goto free_port; |
4986 | } | 5590 | } |
4987 | 5591 | ||
4988 | for (i = 0; i < MAX_MCC_CMD ; i++) { | 5592 | for (i = 0; i < MAX_MCC_CMD; i++) { |
4989 | init_waitqueue_head(&phba->ctrl.mcc_wait[i + 1]); | 5593 | init_waitqueue_head(&phba->ctrl.mcc_wait[i + 1]); |
4990 | phba->ctrl.mcc_tag[i] = i + 1; | 5594 | phba->ctrl.mcc_tag[i] = i + 1; |
4991 | phba->ctrl.mcc_numtag[i + 1] = 0; | 5595 | phba->ctrl.mcc_numtag[i + 1] = 0; |
@@ -5089,6 +5693,12 @@ disable_pci: | |||
5089 | return ret; | 5693 | return ret; |
5090 | } | 5694 | } |
5091 | 5695 | ||
5696 | static struct pci_error_handlers beiscsi_eeh_handlers = { | ||
5697 | .error_detected = beiscsi_eeh_err_detected, | ||
5698 | .slot_reset = beiscsi_eeh_reset, | ||
5699 | .resume = beiscsi_eeh_resume, | ||
5700 | }; | ||
5701 | |||
5092 | struct iscsi_transport beiscsi_iscsi_transport = { | 5702 | struct iscsi_transport beiscsi_iscsi_transport = { |
5093 | .owner = THIS_MODULE, | 5703 | .owner = THIS_MODULE, |
5094 | .name = DRV_NAME, | 5704 | .name = DRV_NAME, |
@@ -5127,7 +5737,8 @@ static struct pci_driver beiscsi_pci_driver = { | |||
5127 | .probe = beiscsi_dev_probe, | 5737 | .probe = beiscsi_dev_probe, |
5128 | .remove = beiscsi_remove, | 5738 | .remove = beiscsi_remove, |
5129 | .shutdown = beiscsi_shutdown, | 5739 | .shutdown = beiscsi_shutdown, |
5130 | .id_table = beiscsi_pci_id_table | 5740 | .id_table = beiscsi_pci_id_table, |
5741 | .err_handler = &beiscsi_eeh_handlers | ||
5131 | }; | 5742 | }; |
5132 | 5743 | ||
5133 | 5744 | ||
diff --git a/drivers/scsi/be2iscsi/be_main.h b/drivers/scsi/be2iscsi/be_main.h index 2c06ef3c02ac..31fa27b4a9b2 100644 --- a/drivers/scsi/be2iscsi/be_main.h +++ b/drivers/scsi/be2iscsi/be_main.h | |||
@@ -26,6 +26,7 @@ | |||
26 | #include <linux/in.h> | 26 | #include <linux/in.h> |
27 | #include <linux/ctype.h> | 27 | #include <linux/ctype.h> |
28 | #include <linux/module.h> | 28 | #include <linux/module.h> |
29 | #include <linux/aer.h> | ||
29 | #include <scsi/scsi.h> | 30 | #include <scsi/scsi.h> |
30 | #include <scsi/scsi_cmnd.h> | 31 | #include <scsi/scsi_cmnd.h> |
31 | #include <scsi/scsi_device.h> | 32 | #include <scsi/scsi_device.h> |
@@ -34,9 +35,8 @@ | |||
34 | #include <scsi/libiscsi.h> | 35 | #include <scsi/libiscsi.h> |
35 | #include <scsi/scsi_transport_iscsi.h> | 36 | #include <scsi/scsi_transport_iscsi.h> |
36 | 37 | ||
37 | #include "be.h" | ||
38 | #define DRV_NAME "be2iscsi" | 38 | #define DRV_NAME "be2iscsi" |
39 | #define BUILD_STR "10.0.467.0" | 39 | #define BUILD_STR "10.0.659.0" |
40 | #define BE_NAME "Emulex OneConnect" \ | 40 | #define BE_NAME "Emulex OneConnect" \ |
41 | "Open-iSCSI Driver version" BUILD_STR | 41 | "Open-iSCSI Driver version" BUILD_STR |
42 | #define DRV_DESC BE_NAME " " "Driver" | 42 | #define DRV_DESC BE_NAME " " "Driver" |
@@ -66,7 +66,6 @@ | |||
66 | 66 | ||
67 | #define MAX_CPUS 64 | 67 | #define MAX_CPUS 64 |
68 | #define BEISCSI_MAX_NUM_CPUS 7 | 68 | #define BEISCSI_MAX_NUM_CPUS 7 |
69 | #define OC_SKH_MAX_NUM_CPUS 31 | ||
70 | 69 | ||
71 | #define BEISCSI_VER_STRLEN 32 | 70 | #define BEISCSI_VER_STRLEN 32 |
72 | 71 | ||
@@ -74,6 +73,7 @@ | |||
74 | 73 | ||
75 | #define BEISCSI_CMD_PER_LUN 128 /* scsi_host->cmd_per_lun */ | 74 | #define BEISCSI_CMD_PER_LUN 128 /* scsi_host->cmd_per_lun */ |
76 | #define BEISCSI_MAX_SECTORS 2048 /* scsi_host->max_sectors */ | 75 | #define BEISCSI_MAX_SECTORS 2048 /* scsi_host->max_sectors */ |
76 | #define BEISCSI_TEMPLATE_HDR_PER_CXN_SIZE 128 /* Template size per cxn */ | ||
77 | 77 | ||
78 | #define BEISCSI_MAX_CMD_LEN 16 /* scsi_host->max_cmd_len */ | 78 | #define BEISCSI_MAX_CMD_LEN 16 /* scsi_host->max_cmd_len */ |
79 | #define BEISCSI_NUM_MAX_LUN 256 /* scsi_host->max_lun */ | 79 | #define BEISCSI_NUM_MAX_LUN 256 /* scsi_host->max_lun */ |
@@ -97,14 +97,19 @@ | |||
97 | 97 | ||
98 | #define INVALID_SESS_HANDLE 0xFFFFFFFF | 98 | #define INVALID_SESS_HANDLE 0xFFFFFFFF |
99 | 99 | ||
100 | #define BE_ADAPTER_UP 0x00000000 | 100 | #define BE_ADAPTER_LINK_UP 0x001 |
101 | #define BE_ADAPTER_LINK_DOWN 0x00000001 | 101 | #define BE_ADAPTER_LINK_DOWN 0x002 |
102 | #define BE_ADAPTER_PCI_ERR 0x004 | ||
103 | |||
104 | #define BEISCSI_CLEAN_UNLOAD 0x01 | ||
105 | #define BEISCSI_EEH_UNLOAD 0x02 | ||
102 | /** | 106 | /** |
103 | * hardware needs the async PDU buffers to be posted in multiples of 8 | 107 | * hardware needs the async PDU buffers to be posted in multiples of 8 |
104 | * So have atleast 8 of them by default | 108 | * So have atleast 8 of them by default |
105 | */ | 109 | */ |
106 | 110 | ||
107 | #define HWI_GET_ASYNC_PDU_CTX(phwi) (phwi->phwi_ctxt->pasync_ctx) | 111 | #define HWI_GET_ASYNC_PDU_CTX(phwi, ulp_num) \ |
112 | (phwi->phwi_ctxt->pasync_ctx[ulp_num]) | ||
108 | 113 | ||
109 | /********* Memory BAR register ************/ | 114 | /********* Memory BAR register ************/ |
110 | #define PCICFG_MEMBAR_CTRL_INT_CTRL_OFFSET 0xfc | 115 | #define PCICFG_MEMBAR_CTRL_INT_CTRL_OFFSET 0xfc |
@@ -149,29 +154,41 @@ | |||
149 | #define DB_CQ_REARM_SHIFT (29) /* bit 29 */ | 154 | #define DB_CQ_REARM_SHIFT (29) /* bit 29 */ |
150 | 155 | ||
151 | #define GET_HWI_CONTROLLER_WS(pc) (pc->phwi_ctrlr) | 156 | #define GET_HWI_CONTROLLER_WS(pc) (pc->phwi_ctrlr) |
152 | #define HWI_GET_DEF_BUFQ_ID(pc) (((struct hwi_controller *)\ | 157 | #define HWI_GET_DEF_BUFQ_ID(pc, ulp_num) (((struct hwi_controller *)\ |
153 | (GET_HWI_CONTROLLER_WS(pc)))->default_pdu_data.id) | 158 | (GET_HWI_CONTROLLER_WS(pc)))->default_pdu_data[ulp_num].id) |
154 | #define HWI_GET_DEF_HDRQ_ID(pc) (((struct hwi_controller *)\ | 159 | #define HWI_GET_DEF_HDRQ_ID(pc, ulp_num) (((struct hwi_controller *)\ |
155 | (GET_HWI_CONTROLLER_WS(pc)))->default_pdu_hdr.id) | 160 | (GET_HWI_CONTROLLER_WS(pc)))->default_pdu_hdr[ulp_num].id) |
156 | 161 | ||
157 | #define PAGES_REQUIRED(x) \ | 162 | #define PAGES_REQUIRED(x) \ |
158 | ((x < PAGE_SIZE) ? 1 : ((x + PAGE_SIZE - 1) / PAGE_SIZE)) | 163 | ((x < PAGE_SIZE) ? 1 : ((x + PAGE_SIZE - 1) / PAGE_SIZE)) |
159 | 164 | ||
160 | #define BEISCSI_MSI_NAME 20 /* size of msi_name string */ | 165 | #define BEISCSI_MSI_NAME 20 /* size of msi_name string */ |
161 | 166 | ||
167 | #define MEM_DESCR_OFFSET 8 | ||
168 | #define BEISCSI_DEFQ_HDR 1 | ||
169 | #define BEISCSI_DEFQ_DATA 0 | ||
162 | enum be_mem_enum { | 170 | enum be_mem_enum { |
163 | HWI_MEM_ADDN_CONTEXT, | 171 | HWI_MEM_ADDN_CONTEXT, |
164 | HWI_MEM_WRB, | 172 | HWI_MEM_WRB, |
165 | HWI_MEM_WRBH, | 173 | HWI_MEM_WRBH, |
166 | HWI_MEM_SGLH, | 174 | HWI_MEM_SGLH, |
167 | HWI_MEM_SGE, | 175 | HWI_MEM_SGE, |
168 | HWI_MEM_ASYNC_HEADER_BUF, /* 5 */ | 176 | HWI_MEM_TEMPLATE_HDR_ULP0, |
169 | HWI_MEM_ASYNC_DATA_BUF, | 177 | HWI_MEM_ASYNC_HEADER_BUF_ULP0, /* 6 */ |
170 | HWI_MEM_ASYNC_HEADER_RING, | 178 | HWI_MEM_ASYNC_DATA_BUF_ULP0, |
171 | HWI_MEM_ASYNC_DATA_RING, | 179 | HWI_MEM_ASYNC_HEADER_RING_ULP0, |
172 | HWI_MEM_ASYNC_HEADER_HANDLE, | 180 | HWI_MEM_ASYNC_DATA_RING_ULP0, |
173 | HWI_MEM_ASYNC_DATA_HANDLE, /* 10 */ | 181 | HWI_MEM_ASYNC_HEADER_HANDLE_ULP0, |
174 | HWI_MEM_ASYNC_PDU_CONTEXT, | 182 | HWI_MEM_ASYNC_DATA_HANDLE_ULP0, /* 11 */ |
183 | HWI_MEM_ASYNC_PDU_CONTEXT_ULP0, | ||
184 | HWI_MEM_TEMPLATE_HDR_ULP1, | ||
185 | HWI_MEM_ASYNC_HEADER_BUF_ULP1, /* 14 */ | ||
186 | HWI_MEM_ASYNC_DATA_BUF_ULP1, | ||
187 | HWI_MEM_ASYNC_HEADER_RING_ULP1, | ||
188 | HWI_MEM_ASYNC_DATA_RING_ULP1, | ||
189 | HWI_MEM_ASYNC_HEADER_HANDLE_ULP1, | ||
190 | HWI_MEM_ASYNC_DATA_HANDLE_ULP1, /* 19 */ | ||
191 | HWI_MEM_ASYNC_PDU_CONTEXT_ULP1, | ||
175 | ISCSI_MEM_GLOBAL_HEADER, | 192 | ISCSI_MEM_GLOBAL_HEADER, |
176 | SE_MEM_MAX | 193 | SE_MEM_MAX |
177 | }; | 194 | }; |
@@ -266,9 +283,49 @@ struct invalidate_command_table { | |||
266 | unsigned short cid; | 283 | unsigned short cid; |
267 | } __packed; | 284 | } __packed; |
268 | 285 | ||
286 | #define BEISCSI_GET_ULP_FROM_CRI(phwi_ctrlr, cri) \ | ||
287 | (phwi_ctrlr->wrb_context[cri].ulp_num) | ||
288 | struct hwi_wrb_context { | ||
289 | struct list_head wrb_handle_list; | ||
290 | struct list_head wrb_handle_drvr_list; | ||
291 | struct wrb_handle **pwrb_handle_base; | ||
292 | struct wrb_handle **pwrb_handle_basestd; | ||
293 | struct iscsi_wrb *plast_wrb; | ||
294 | unsigned short alloc_index; | ||
295 | unsigned short free_index; | ||
296 | unsigned short wrb_handles_available; | ||
297 | unsigned short cid; | ||
298 | uint8_t ulp_num; /* ULP to which CID binded */ | ||
299 | uint16_t register_set; | ||
300 | uint16_t doorbell_format; | ||
301 | uint32_t doorbell_offset; | ||
302 | }; | ||
303 | |||
304 | struct ulp_cid_info { | ||
305 | unsigned short *cid_array; | ||
306 | unsigned short avlbl_cids; | ||
307 | unsigned short cid_alloc; | ||
308 | unsigned short cid_free; | ||
309 | }; | ||
310 | |||
311 | #include "be.h" | ||
269 | #define chip_be2(phba) (phba->generation == BE_GEN2) | 312 | #define chip_be2(phba) (phba->generation == BE_GEN2) |
270 | #define chip_be3_r(phba) (phba->generation == BE_GEN3) | 313 | #define chip_be3_r(phba) (phba->generation == BE_GEN3) |
271 | #define is_chip_be2_be3r(phba) (chip_be3_r(phba) || (chip_be2(phba))) | 314 | #define is_chip_be2_be3r(phba) (chip_be3_r(phba) || (chip_be2(phba))) |
315 | |||
316 | #define BEISCSI_ULP0 0 | ||
317 | #define BEISCSI_ULP1 1 | ||
318 | #define BEISCSI_ULP_COUNT 2 | ||
319 | #define BEISCSI_ULP0_LOADED 0x01 | ||
320 | #define BEISCSI_ULP1_LOADED 0x02 | ||
321 | |||
322 | #define BEISCSI_ULP_AVLBL_CID(phba, ulp_num) \ | ||
323 | (((struct ulp_cid_info *)phba->cid_array_info[ulp_num])->avlbl_cids) | ||
324 | #define BEISCSI_ULP0_AVLBL_CID(phba) \ | ||
325 | BEISCSI_ULP_AVLBL_CID(phba, BEISCSI_ULP0) | ||
326 | #define BEISCSI_ULP1_AVLBL_CID(phba) \ | ||
327 | BEISCSI_ULP_AVLBL_CID(phba, BEISCSI_ULP1) | ||
328 | |||
272 | struct beiscsi_hba { | 329 | struct beiscsi_hba { |
273 | struct hba_parameters params; | 330 | struct hba_parameters params; |
274 | struct hwi_controller *phwi_ctrlr; | 331 | struct hwi_controller *phwi_ctrlr; |
@@ -303,17 +360,15 @@ struct beiscsi_hba { | |||
303 | spinlock_t io_sgl_lock; | 360 | spinlock_t io_sgl_lock; |
304 | spinlock_t mgmt_sgl_lock; | 361 | spinlock_t mgmt_sgl_lock; |
305 | spinlock_t isr_lock; | 362 | spinlock_t isr_lock; |
363 | spinlock_t async_pdu_lock; | ||
306 | unsigned int age; | 364 | unsigned int age; |
307 | unsigned short avlbl_cids; | ||
308 | unsigned short cid_alloc; | ||
309 | unsigned short cid_free; | ||
310 | struct list_head hba_queue; | 365 | struct list_head hba_queue; |
311 | #define BE_MAX_SESSION 2048 | 366 | #define BE_MAX_SESSION 2048 |
312 | #define BE_SET_CID_TO_CRI(cri_index, cid) \ | 367 | #define BE_SET_CID_TO_CRI(cri_index, cid) \ |
313 | (phba->cid_to_cri_map[cid] = cri_index) | 368 | (phba->cid_to_cri_map[cid] = cri_index) |
314 | #define BE_GET_CRI_FROM_CID(cid) (phba->cid_to_cri_map[cid]) | 369 | #define BE_GET_CRI_FROM_CID(cid) (phba->cid_to_cri_map[cid]) |
315 | unsigned short cid_to_cri_map[BE_MAX_SESSION]; | 370 | unsigned short cid_to_cri_map[BE_MAX_SESSION]; |
316 | unsigned short *cid_array; | 371 | struct ulp_cid_info *cid_array_info[BEISCSI_ULP_COUNT]; |
317 | struct iscsi_endpoint **ep_array; | 372 | struct iscsi_endpoint **ep_array; |
318 | struct beiscsi_conn **conn_table; | 373 | struct beiscsi_conn **conn_table; |
319 | struct iscsi_boot_kset *boot_kset; | 374 | struct iscsi_boot_kset *boot_kset; |
@@ -325,20 +380,21 @@ struct beiscsi_hba { | |||
325 | * group together since they are used most frequently | 380 | * group together since they are used most frequently |
326 | * for cid to cri conversion | 381 | * for cid to cri conversion |
327 | */ | 382 | */ |
328 | unsigned int iscsi_cid_start; | ||
329 | unsigned int phys_port; | 383 | unsigned int phys_port; |
384 | unsigned int eqid_count; | ||
385 | unsigned int cqid_count; | ||
386 | unsigned int iscsi_cid_start[BEISCSI_ULP_COUNT]; | ||
387 | #define BEISCSI_GET_CID_COUNT(phba, ulp_num) \ | ||
388 | (phba->fw_config.iscsi_cid_count[ulp_num]) | ||
389 | unsigned int iscsi_cid_count[BEISCSI_ULP_COUNT]; | ||
390 | unsigned int iscsi_icd_count[BEISCSI_ULP_COUNT]; | ||
391 | unsigned int iscsi_icd_start[BEISCSI_ULP_COUNT]; | ||
392 | unsigned int iscsi_chain_start[BEISCSI_ULP_COUNT]; | ||
393 | unsigned int iscsi_chain_count[BEISCSI_ULP_COUNT]; | ||
330 | 394 | ||
331 | unsigned int isr_offset; | ||
332 | unsigned int iscsi_icd_start; | ||
333 | unsigned int iscsi_cid_count; | ||
334 | unsigned int iscsi_icd_count; | ||
335 | unsigned int pci_function; | ||
336 | |||
337 | unsigned short cid_alloc; | ||
338 | unsigned short cid_free; | ||
339 | unsigned short avlbl_cids; | ||
340 | unsigned short iscsi_features; | 395 | unsigned short iscsi_features; |
341 | spinlock_t cid_lock; | 396 | uint16_t dual_ulp_aware; |
397 | unsigned long ulp_supported; | ||
342 | } fw_config; | 398 | } fw_config; |
343 | 399 | ||
344 | unsigned int state; | 400 | unsigned int state; |
@@ -346,6 +402,7 @@ struct beiscsi_hba { | |||
346 | bool ue_detected; | 402 | bool ue_detected; |
347 | struct delayed_work beiscsi_hw_check_task; | 403 | struct delayed_work beiscsi_hw_check_task; |
348 | 404 | ||
405 | bool mac_addr_set; | ||
349 | u8 mac_address[ETH_ALEN]; | 406 | u8 mac_address[ETH_ALEN]; |
350 | char fw_ver_str[BEISCSI_VER_STRLEN]; | 407 | char fw_ver_str[BEISCSI_VER_STRLEN]; |
351 | char wq_name[20]; | 408 | char wq_name[20]; |
@@ -374,6 +431,7 @@ struct beiscsi_conn { | |||
374 | struct iscsi_conn *conn; | 431 | struct iscsi_conn *conn; |
375 | struct beiscsi_hba *phba; | 432 | struct beiscsi_hba *phba; |
376 | u32 exp_statsn; | 433 | u32 exp_statsn; |
434 | u32 doorbell_offset; | ||
377 | u32 beiscsi_conn_cid; | 435 | u32 beiscsi_conn_cid; |
378 | struct beiscsi_endpoint *ep; | 436 | struct beiscsi_endpoint *ep; |
379 | unsigned short login_in_progress; | 437 | unsigned short login_in_progress; |
@@ -474,7 +532,7 @@ struct amap_iscsi_sge { | |||
474 | }; | 532 | }; |
475 | 533 | ||
476 | struct beiscsi_offload_params { | 534 | struct beiscsi_offload_params { |
477 | u32 dw[5]; | 535 | u32 dw[6]; |
478 | }; | 536 | }; |
479 | 537 | ||
480 | #define OFFLD_PARAMS_ERL 0x00000003 | 538 | #define OFFLD_PARAMS_ERL 0x00000003 |
@@ -504,6 +562,7 @@ struct amap_beiscsi_offload_params { | |||
504 | u8 max_r2t[16]; | 562 | u8 max_r2t[16]; |
505 | u8 pad[8]; | 563 | u8 pad[8]; |
506 | u8 exp_statsn[32]; | 564 | u8 exp_statsn[32]; |
565 | u8 max_recv_data_segment_length[32]; | ||
507 | }; | 566 | }; |
508 | 567 | ||
509 | /* void hwi_complete_drvr_msgs(struct beiscsi_conn *beiscsi_conn, | 568 | /* void hwi_complete_drvr_msgs(struct beiscsi_conn *beiscsi_conn, |
@@ -567,7 +626,8 @@ struct hwi_async_pdu_context { | |||
567 | 626 | ||
568 | unsigned int buffer_size; | 627 | unsigned int buffer_size; |
569 | unsigned int num_entries; | 628 | unsigned int num_entries; |
570 | 629 | #define BE_GET_ASYNC_CRI_FROM_CID(cid) (pasync_ctx->cid_to_async_cri_map[cid]) | |
630 | unsigned short cid_to_async_cri_map[BE_MAX_SESSION]; | ||
571 | /** | 631 | /** |
572 | * This is a varying size list! Do not add anything | 632 | * This is a varying size list! Do not add anything |
573 | * after this entry!! | 633 | * after this entry!! |
@@ -885,30 +945,32 @@ struct amap_iscsi_target_context_update_wrb_v2 { | |||
885 | u8 first_burst_length[24]; /* DWORD 3 */ | 945 | u8 first_burst_length[24]; /* DWORD 3 */ |
886 | u8 rsvd3[8]; /* DOWRD 3 */ | 946 | u8 rsvd3[8]; /* DOWRD 3 */ |
887 | u8 max_r2t[16]; /* DWORD 4 */ | 947 | u8 max_r2t[16]; /* DWORD 4 */ |
888 | u8 rsvd4[10]; /* DWORD 4 */ | 948 | u8 rsvd4; /* DWORD 4 */ |
889 | u8 hde; /* DWORD 4 */ | 949 | u8 hde; /* DWORD 4 */ |
890 | u8 dde; /* DWORD 4 */ | 950 | u8 dde; /* DWORD 4 */ |
891 | u8 erl[2]; /* DWORD 4 */ | 951 | u8 erl[2]; /* DWORD 4 */ |
952 | u8 rsvd5[6]; /* DWORD 4 */ | ||
892 | u8 imd; /* DWORD 4 */ | 953 | u8 imd; /* DWORD 4 */ |
893 | u8 ir2t; /* DWORD 4 */ | 954 | u8 ir2t; /* DWORD 4 */ |
955 | u8 rsvd6[3]; /* DWORD 4 */ | ||
894 | u8 stat_sn[32]; /* DWORD 5 */ | 956 | u8 stat_sn[32]; /* DWORD 5 */ |
895 | u8 rsvd5[32]; /* DWORD 6 */ | 957 | u8 rsvd7[32]; /* DWORD 6 */ |
896 | u8 rsvd6[32]; /* DWORD 7 */ | 958 | u8 rsvd8[32]; /* DWORD 7 */ |
897 | u8 max_recv_dataseg_len[24]; /* DWORD 8 */ | 959 | u8 max_recv_dataseg_len[24]; /* DWORD 8 */ |
898 | u8 rsvd7[8]; /* DWORD 8 */ | 960 | u8 rsvd9[8]; /* DWORD 8 */ |
899 | u8 rsvd8[32]; /* DWORD 9 */ | 961 | u8 rsvd10[32]; /* DWORD 9 */ |
900 | u8 rsvd9[32]; /* DWORD 10 */ | 962 | u8 rsvd11[32]; /* DWORD 10 */ |
901 | u8 max_cxns[16]; /* DWORD 11 */ | 963 | u8 max_cxns[16]; /* DWORD 11 */ |
902 | u8 rsvd10[11]; /* DWORD 11*/ | 964 | u8 rsvd12[11]; /* DWORD 11*/ |
903 | u8 invld; /* DWORD 11 */ | 965 | u8 invld; /* DWORD 11 */ |
904 | u8 rsvd11;/* DWORD 11*/ | 966 | u8 rsvd13;/* DWORD 11*/ |
905 | u8 dmsg; /* DWORD 11 */ | 967 | u8 dmsg; /* DWORD 11 */ |
906 | u8 data_seq_inorder; /* DWORD 11 */ | 968 | u8 data_seq_inorder; /* DWORD 11 */ |
907 | u8 pdu_seq_inorder; /* DWORD 11 */ | 969 | u8 pdu_seq_inorder; /* DWORD 11 */ |
908 | u8 rsvd12[32]; /*DWORD 12 */ | 970 | u8 rsvd14[32]; /*DWORD 12 */ |
909 | u8 rsvd13[32]; /* DWORD 13 */ | 971 | u8 rsvd15[32]; /* DWORD 13 */ |
910 | u8 rsvd14[32]; /* DWORD 14 */ | 972 | u8 rsvd16[32]; /* DWORD 14 */ |
911 | u8 rsvd15[32]; /* DWORD 15 */ | 973 | u8 rsvd17[32]; /* DWORD 15 */ |
912 | } __packed; | 974 | } __packed; |
913 | 975 | ||
914 | 976 | ||
@@ -919,6 +981,10 @@ struct be_ring { | |||
919 | u32 cidx; /* consumer index */ | 981 | u32 cidx; /* consumer index */ |
920 | u32 pidx; /* producer index -- not used by most rings */ | 982 | u32 pidx; /* producer index -- not used by most rings */ |
921 | u32 item_size; /* size in bytes of one object */ | 983 | u32 item_size; /* size in bytes of one object */ |
984 | u8 ulp_num; /* ULP to which CID binded */ | ||
985 | u16 register_set; | ||
986 | u16 doorbell_format; | ||
987 | u32 doorbell_offset; | ||
922 | 988 | ||
923 | void *va; /* The virtual address of the ring. This | 989 | void *va; /* The virtual address of the ring. This |
924 | * should be last to allow 32 & 64 bit debugger | 990 | * should be last to allow 32 & 64 bit debugger |
@@ -926,18 +992,6 @@ struct be_ring { | |||
926 | */ | 992 | */ |
927 | }; | 993 | }; |
928 | 994 | ||
929 | struct hwi_wrb_context { | ||
930 | struct list_head wrb_handle_list; | ||
931 | struct list_head wrb_handle_drvr_list; | ||
932 | struct wrb_handle **pwrb_handle_base; | ||
933 | struct wrb_handle **pwrb_handle_basestd; | ||
934 | struct iscsi_wrb *plast_wrb; | ||
935 | unsigned short alloc_index; | ||
936 | unsigned short free_index; | ||
937 | unsigned short wrb_handles_available; | ||
938 | unsigned short cid; | ||
939 | }; | ||
940 | |||
941 | struct hwi_controller { | 995 | struct hwi_controller { |
942 | struct list_head io_sgl_list; | 996 | struct list_head io_sgl_list; |
943 | struct list_head eh_sgl_list; | 997 | struct list_head eh_sgl_list; |
@@ -946,8 +1000,8 @@ struct hwi_controller { | |||
946 | 1000 | ||
947 | struct hwi_wrb_context *wrb_context; | 1001 | struct hwi_wrb_context *wrb_context; |
948 | struct mcc_wrb *pmcc_wrb_base; | 1002 | struct mcc_wrb *pmcc_wrb_base; |
949 | struct be_ring default_pdu_hdr; | 1003 | struct be_ring default_pdu_hdr[BEISCSI_ULP_COUNT]; |
950 | struct be_ring default_pdu_data; | 1004 | struct be_ring default_pdu_data[BEISCSI_ULP_COUNT]; |
951 | struct hwi_context_memory *phwi_ctxt; | 1005 | struct hwi_context_memory *phwi_ctxt; |
952 | }; | 1006 | }; |
953 | 1007 | ||
@@ -978,11 +1032,10 @@ struct hwi_context_memory { | |||
978 | struct be_eq_obj be_eq[MAX_CPUS]; | 1032 | struct be_eq_obj be_eq[MAX_CPUS]; |
979 | struct be_queue_info be_cq[MAX_CPUS - 1]; | 1033 | struct be_queue_info be_cq[MAX_CPUS - 1]; |
980 | 1034 | ||
981 | struct be_queue_info be_def_hdrq; | ||
982 | struct be_queue_info be_def_dataq; | ||
983 | |||
984 | struct be_queue_info *be_wrbq; | 1035 | struct be_queue_info *be_wrbq; |
985 | struct hwi_async_pdu_context *pasync_ctx; | 1036 | struct be_queue_info be_def_hdrq[BEISCSI_ULP_COUNT]; |
1037 | struct be_queue_info be_def_dataq[BEISCSI_ULP_COUNT]; | ||
1038 | struct hwi_async_pdu_context *pasync_ctx[BEISCSI_ULP_COUNT]; | ||
986 | }; | 1039 | }; |
987 | 1040 | ||
988 | /* Logging related definitions */ | 1041 | /* Logging related definitions */ |
@@ -992,6 +1045,7 @@ struct hwi_context_memory { | |||
992 | #define BEISCSI_LOG_EH 0x0008 /* Error Handler */ | 1045 | #define BEISCSI_LOG_EH 0x0008 /* Error Handler */ |
993 | #define BEISCSI_LOG_IO 0x0010 /* IO Code Path */ | 1046 | #define BEISCSI_LOG_IO 0x0010 /* IO Code Path */ |
994 | #define BEISCSI_LOG_CONFIG 0x0020 /* CONFIG Code Path */ | 1047 | #define BEISCSI_LOG_CONFIG 0x0020 /* CONFIG Code Path */ |
1048 | #define BEISCSI_LOG_ISCSI 0x0040 /* SCSI/iSCSI Protocol related Logs */ | ||
995 | 1049 | ||
996 | #define beiscsi_log(phba, level, mask, fmt, arg...) \ | 1050 | #define beiscsi_log(phba, level, mask, fmt, arg...) \ |
997 | do { \ | 1051 | do { \ |
diff --git a/drivers/scsi/be2iscsi/be_mgmt.c b/drivers/scsi/be2iscsi/be_mgmt.c index 245a9595a93a..b2fcac78feaa 100644 --- a/drivers/scsi/be2iscsi/be_mgmt.c +++ b/drivers/scsi/be2iscsi/be_mgmt.c | |||
@@ -278,6 +278,18 @@ unsigned int mgmt_get_session_info(struct beiscsi_hba *phba, | |||
278 | return tag; | 278 | return tag; |
279 | } | 279 | } |
280 | 280 | ||
281 | /** | ||
282 | * mgmt_get_fw_config()- Get the FW config for the function | ||
283 | * @ctrl: ptr to Ctrl Info | ||
284 | * @phba: ptr to the dev priv structure | ||
285 | * | ||
286 | * Get the FW config and resources available for the function. | ||
287 | * The resources are created based on the count received here. | ||
288 | * | ||
289 | * return | ||
290 | * Success: 0 | ||
291 | * Failure: Non-Zero Value | ||
292 | **/ | ||
281 | int mgmt_get_fw_config(struct be_ctrl_info *ctrl, | 293 | int mgmt_get_fw_config(struct be_ctrl_info *ctrl, |
282 | struct beiscsi_hba *phba) | 294 | struct beiscsi_hba *phba) |
283 | { | 295 | { |
@@ -291,31 +303,79 @@ int mgmt_get_fw_config(struct be_ctrl_info *ctrl, | |||
291 | be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0); | 303 | be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0); |
292 | 304 | ||
293 | be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON, | 305 | be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON, |
294 | OPCODE_COMMON_QUERY_FIRMWARE_CONFIG, sizeof(*req)); | 306 | OPCODE_COMMON_QUERY_FIRMWARE_CONFIG, |
307 | EMBED_MBX_MAX_PAYLOAD_SIZE); | ||
295 | status = be_mbox_notify(ctrl); | 308 | status = be_mbox_notify(ctrl); |
296 | if (!status) { | 309 | if (!status) { |
310 | uint8_t ulp_num = 0; | ||
297 | struct be_fw_cfg *pfw_cfg; | 311 | struct be_fw_cfg *pfw_cfg; |
298 | pfw_cfg = req; | 312 | pfw_cfg = req; |
313 | |||
314 | if (!is_chip_be2_be3r(phba)) { | ||
315 | phba->fw_config.eqid_count = pfw_cfg->eqid_count; | ||
316 | phba->fw_config.cqid_count = pfw_cfg->cqid_count; | ||
317 | |||
318 | beiscsi_log(phba, KERN_INFO, | ||
319 | BEISCSI_LOG_INIT, | ||
320 | "BG_%d : EQ_Count : %d CQ_Count : %d\n", | ||
321 | phba->fw_config.eqid_count, | ||
322 | phba->fw_config.cqid_count); | ||
323 | } | ||
324 | |||
325 | for (ulp_num = 0; ulp_num < BEISCSI_ULP_COUNT; ulp_num++) | ||
326 | if (pfw_cfg->ulp[ulp_num].ulp_mode & | ||
327 | BEISCSI_ULP_ISCSI_INI_MODE) | ||
328 | set_bit(ulp_num, | ||
329 | &phba->fw_config.ulp_supported); | ||
330 | |||
299 | phba->fw_config.phys_port = pfw_cfg->phys_port; | 331 | phba->fw_config.phys_port = pfw_cfg->phys_port; |
300 | phba->fw_config.iscsi_icd_start = | 332 | for (ulp_num = 0; ulp_num < BEISCSI_ULP_COUNT; ulp_num++) { |
301 | pfw_cfg->ulp[0].icd_base; | 333 | if (test_bit(ulp_num, &phba->fw_config.ulp_supported)) { |
302 | phba->fw_config.iscsi_icd_count = | 334 | |
303 | pfw_cfg->ulp[0].icd_count; | 335 | phba->fw_config.iscsi_cid_start[ulp_num] = |
304 | phba->fw_config.iscsi_cid_start = | 336 | pfw_cfg->ulp[ulp_num].sq_base; |
305 | pfw_cfg->ulp[0].sq_base; | 337 | phba->fw_config.iscsi_cid_count[ulp_num] = |
306 | phba->fw_config.iscsi_cid_count = | 338 | pfw_cfg->ulp[ulp_num].sq_count; |
307 | pfw_cfg->ulp[0].sq_count; | 339 | |
308 | if (phba->fw_config.iscsi_cid_count > (BE2_MAX_SESSIONS / 2)) { | 340 | phba->fw_config.iscsi_icd_start[ulp_num] = |
309 | beiscsi_log(phba, KERN_INFO, BEISCSI_LOG_INIT, | 341 | pfw_cfg->ulp[ulp_num].icd_base; |
310 | "BG_%d : FW reported MAX CXNS as %d\t" | 342 | phba->fw_config.iscsi_icd_count[ulp_num] = |
311 | "Max Supported = %d.\n", | 343 | pfw_cfg->ulp[ulp_num].icd_count; |
312 | phba->fw_config.iscsi_cid_count, | 344 | |
313 | BE2_MAX_SESSIONS); | 345 | phba->fw_config.iscsi_chain_start[ulp_num] = |
314 | phba->fw_config.iscsi_cid_count = BE2_MAX_SESSIONS / 2; | 346 | pfw_cfg->chain_icd[ulp_num].chain_base; |
347 | phba->fw_config.iscsi_chain_count[ulp_num] = | ||
348 | pfw_cfg->chain_icd[ulp_num].chain_count; | ||
349 | |||
350 | beiscsi_log(phba, KERN_INFO, BEISCSI_LOG_INIT, | ||
351 | "BG_%d : Function loaded on ULP : %d\n" | ||
352 | "\tiscsi_cid_count : %d\n" | ||
353 | "\tiscsi_cid_start : %d\n" | ||
354 | "\t iscsi_icd_count : %d\n" | ||
355 | "\t iscsi_icd_start : %d\n", | ||
356 | ulp_num, | ||
357 | phba->fw_config. | ||
358 | iscsi_cid_count[ulp_num], | ||
359 | phba->fw_config. | ||
360 | iscsi_cid_start[ulp_num], | ||
361 | phba->fw_config. | ||
362 | iscsi_icd_count[ulp_num], | ||
363 | phba->fw_config. | ||
364 | iscsi_icd_start[ulp_num]); | ||
365 | } | ||
315 | } | 366 | } |
367 | |||
368 | phba->fw_config.dual_ulp_aware = (pfw_cfg->function_mode & | ||
369 | BEISCSI_FUNC_DUA_MODE); | ||
370 | |||
371 | beiscsi_log(phba, KERN_INFO, BEISCSI_LOG_INIT, | ||
372 | "BG_%d : DUA Mode : 0x%x\n", | ||
373 | phba->fw_config.dual_ulp_aware); | ||
374 | |||
316 | } else { | 375 | } else { |
317 | beiscsi_log(phba, KERN_WARNING, BEISCSI_LOG_INIT, | 376 | beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_INIT, |
318 | "BG_%d : Failed in mgmt_get_fw_config\n"); | 377 | "BG_%d : Failed in mgmt_get_fw_config\n"); |
378 | status = -EINVAL; | ||
319 | } | 379 | } |
320 | 380 | ||
321 | spin_unlock(&ctrl->mbox_lock); | 381 | spin_unlock(&ctrl->mbox_lock); |
@@ -448,7 +508,16 @@ unsigned int mgmt_vendor_specific_fw_cmd(struct be_ctrl_info *ctrl, | |||
448 | return tag; | 508 | return tag; |
449 | } | 509 | } |
450 | 510 | ||
451 | int mgmt_epfw_cleanup(struct beiscsi_hba *phba, unsigned short chute) | 511 | /** |
512 | * mgmt_epfw_cleanup()- Inform FW to cleanup data structures. | ||
513 | * @phba: pointer to dev priv structure | ||
514 | * @ulp_num: ULP number. | ||
515 | * | ||
516 | * return | ||
517 | * Success: 0 | ||
518 | * Failure: Non-Zero Value | ||
519 | **/ | ||
520 | int mgmt_epfw_cleanup(struct beiscsi_hba *phba, unsigned short ulp_num) | ||
452 | { | 521 | { |
453 | struct be_ctrl_info *ctrl = &phba->ctrl; | 522 | struct be_ctrl_info *ctrl = &phba->ctrl; |
454 | struct be_mcc_wrb *wrb = wrb_from_mccq(phba); | 523 | struct be_mcc_wrb *wrb = wrb_from_mccq(phba); |
@@ -462,9 +531,9 @@ int mgmt_epfw_cleanup(struct beiscsi_hba *phba, unsigned short chute) | |||
462 | be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_ISCSI, | 531 | be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_ISCSI, |
463 | OPCODE_COMMON_ISCSI_CLEANUP, sizeof(*req)); | 532 | OPCODE_COMMON_ISCSI_CLEANUP, sizeof(*req)); |
464 | 533 | ||
465 | req->chute = chute; | 534 | req->chute = (1 << ulp_num); |
466 | req->hdr_ring_id = cpu_to_le16(HWI_GET_DEF_HDRQ_ID(phba)); | 535 | req->hdr_ring_id = cpu_to_le16(HWI_GET_DEF_HDRQ_ID(phba, ulp_num)); |
467 | req->data_ring_id = cpu_to_le16(HWI_GET_DEF_BUFQ_ID(phba)); | 536 | req->data_ring_id = cpu_to_le16(HWI_GET_DEF_BUFQ_ID(phba, ulp_num)); |
468 | 537 | ||
469 | status = be_mcc_notify_wait(phba); | 538 | status = be_mcc_notify_wait(phba); |
470 | if (status) | 539 | if (status) |
@@ -585,6 +654,16 @@ unsigned int mgmt_upload_connection(struct beiscsi_hba *phba, | |||
585 | return tag; | 654 | return tag; |
586 | } | 655 | } |
587 | 656 | ||
657 | /** | ||
658 | * mgmt_open_connection()- Establish a TCP CXN | ||
659 | * @dst_addr: Destination Address | ||
660 | * @beiscsi_ep: ptr to device endpoint struct | ||
661 | * @nonemb_cmd: ptr to memory allocated for command | ||
662 | * | ||
663 | * return | ||
664 | * Success: Tag number of the MBX Command issued | ||
665 | * Failure: Error code | ||
666 | **/ | ||
588 | int mgmt_open_connection(struct beiscsi_hba *phba, | 667 | int mgmt_open_connection(struct beiscsi_hba *phba, |
589 | struct sockaddr *dst_addr, | 668 | struct sockaddr *dst_addr, |
590 | struct beiscsi_endpoint *beiscsi_ep, | 669 | struct beiscsi_endpoint *beiscsi_ep, |
@@ -602,14 +681,17 @@ int mgmt_open_connection(struct beiscsi_hba *phba, | |||
602 | struct phys_addr template_address = { 0, 0 }; | 681 | struct phys_addr template_address = { 0, 0 }; |
603 | struct phys_addr *ptemplate_address; | 682 | struct phys_addr *ptemplate_address; |
604 | unsigned int tag = 0; | 683 | unsigned int tag = 0; |
605 | unsigned int i; | 684 | unsigned int i, ulp_num; |
606 | unsigned short cid = beiscsi_ep->ep_cid; | 685 | unsigned short cid = beiscsi_ep->ep_cid; |
607 | struct be_sge *sge; | 686 | struct be_sge *sge; |
608 | 687 | ||
609 | phwi_ctrlr = phba->phwi_ctrlr; | 688 | phwi_ctrlr = phba->phwi_ctrlr; |
610 | phwi_context = phwi_ctrlr->phwi_ctxt; | 689 | phwi_context = phwi_ctrlr->phwi_ctxt; |
611 | def_hdr_id = (unsigned short)HWI_GET_DEF_HDRQ_ID(phba); | 690 | |
612 | def_data_id = (unsigned short)HWI_GET_DEF_BUFQ_ID(phba); | 691 | ulp_num = phwi_ctrlr->wrb_context[BE_GET_CRI_FROM_CID(cid)].ulp_num; |
692 | |||
693 | def_hdr_id = (unsigned short)HWI_GET_DEF_HDRQ_ID(phba, ulp_num); | ||
694 | def_data_id = (unsigned short)HWI_GET_DEF_BUFQ_ID(phba, ulp_num); | ||
613 | 695 | ||
614 | ptemplate_address = &template_address; | 696 | ptemplate_address = &template_address; |
615 | ISCSI_GET_PDU_TEMPLATE_ADDRESS(phba, ptemplate_address); | 697 | ISCSI_GET_PDU_TEMPLATE_ADDRESS(phba, ptemplate_address); |
@@ -748,11 +830,14 @@ static int mgmt_exec_nonemb_cmd(struct beiscsi_hba *phba, | |||
748 | 830 | ||
749 | rc = beiscsi_mccq_compl(phba, tag, NULL, nonemb_cmd->va); | 831 | rc = beiscsi_mccq_compl(phba, tag, NULL, nonemb_cmd->va); |
750 | if (rc) { | 832 | if (rc) { |
833 | /* Check if the IOCTL needs to be re-issued */ | ||
834 | if (rc == -EAGAIN) | ||
835 | return rc; | ||
836 | |||
751 | beiscsi_log(phba, KERN_ERR, | 837 | beiscsi_log(phba, KERN_ERR, |
752 | BEISCSI_LOG_CONFIG | BEISCSI_LOG_MBOX, | 838 | BEISCSI_LOG_CONFIG | BEISCSI_LOG_MBOX, |
753 | "BG_%d : mgmt_exec_nonemb_cmd Failed status\n"); | 839 | "BG_%d : mgmt_exec_nonemb_cmd Failed status\n"); |
754 | 840 | ||
755 | rc = -EIO; | ||
756 | goto free_cmd; | 841 | goto free_cmd; |
757 | } | 842 | } |
758 | 843 | ||
@@ -861,7 +946,7 @@ int mgmt_set_ip(struct beiscsi_hba *phba, | |||
861 | uint32_t boot_proto) | 946 | uint32_t boot_proto) |
862 | { | 947 | { |
863 | struct be_cmd_get_def_gateway_resp gtway_addr_set; | 948 | struct be_cmd_get_def_gateway_resp gtway_addr_set; |
864 | struct be_cmd_get_if_info_resp if_info; | 949 | struct be_cmd_get_if_info_resp *if_info; |
865 | struct be_cmd_set_dhcp_req *dhcpreq; | 950 | struct be_cmd_set_dhcp_req *dhcpreq; |
866 | struct be_cmd_rel_dhcp_req *reldhcp; | 951 | struct be_cmd_rel_dhcp_req *reldhcp; |
867 | struct be_dma_mem nonemb_cmd; | 952 | struct be_dma_mem nonemb_cmd; |
@@ -872,16 +957,17 @@ int mgmt_set_ip(struct beiscsi_hba *phba, | |||
872 | if (mgmt_get_all_if_id(phba)) | 957 | if (mgmt_get_all_if_id(phba)) |
873 | return -EIO; | 958 | return -EIO; |
874 | 959 | ||
875 | memset(&if_info, 0, sizeof(if_info)); | ||
876 | ip_type = (ip_param->param == ISCSI_NET_PARAM_IPV6_ADDR) ? | 960 | ip_type = (ip_param->param == ISCSI_NET_PARAM_IPV6_ADDR) ? |
877 | BE2_IPV6 : BE2_IPV4 ; | 961 | BE2_IPV6 : BE2_IPV4 ; |
878 | 962 | ||
879 | rc = mgmt_get_if_info(phba, ip_type, &if_info); | 963 | rc = mgmt_get_if_info(phba, ip_type, &if_info); |
880 | if (rc) | 964 | if (rc) { |
965 | kfree(if_info); | ||
881 | return rc; | 966 | return rc; |
967 | } | ||
882 | 968 | ||
883 | if (boot_proto == ISCSI_BOOTPROTO_DHCP) { | 969 | if (boot_proto == ISCSI_BOOTPROTO_DHCP) { |
884 | if (if_info.dhcp_state) { | 970 | if (if_info->dhcp_state) { |
885 | beiscsi_log(phba, KERN_WARNING, BEISCSI_LOG_CONFIG, | 971 | beiscsi_log(phba, KERN_WARNING, BEISCSI_LOG_CONFIG, |
886 | "BG_%d : DHCP Already Enabled\n"); | 972 | "BG_%d : DHCP Already Enabled\n"); |
887 | return 0; | 973 | return 0; |
@@ -894,9 +980,9 @@ int mgmt_set_ip(struct beiscsi_hba *phba, | |||
894 | IP_V6_LEN : IP_V4_LEN; | 980 | IP_V6_LEN : IP_V4_LEN; |
895 | 981 | ||
896 | } else { | 982 | } else { |
897 | if (if_info.dhcp_state) { | 983 | if (if_info->dhcp_state) { |
898 | 984 | ||
899 | memset(&if_info, 0, sizeof(if_info)); | 985 | memset(if_info, 0, sizeof(*if_info)); |
900 | rc = mgmt_alloc_cmd_data(phba, &nonemb_cmd, | 986 | rc = mgmt_alloc_cmd_data(phba, &nonemb_cmd, |
901 | OPCODE_COMMON_ISCSI_NTWK_REL_STATELESS_IP_ADDR, | 987 | OPCODE_COMMON_ISCSI_NTWK_REL_STATELESS_IP_ADDR, |
902 | sizeof(*reldhcp)); | 988 | sizeof(*reldhcp)); |
@@ -919,8 +1005,8 @@ int mgmt_set_ip(struct beiscsi_hba *phba, | |||
919 | } | 1005 | } |
920 | 1006 | ||
921 | /* Delete the Static IP Set */ | 1007 | /* Delete the Static IP Set */ |
922 | if (if_info.ip_addr.addr[0]) { | 1008 | if (if_info->ip_addr.addr[0]) { |
923 | rc = mgmt_static_ip_modify(phba, &if_info, ip_param, NULL, | 1009 | rc = mgmt_static_ip_modify(phba, if_info, ip_param, NULL, |
924 | IP_ACTION_DEL); | 1010 | IP_ACTION_DEL); |
925 | if (rc) | 1011 | if (rc) |
926 | return rc; | 1012 | return rc; |
@@ -966,7 +1052,7 @@ int mgmt_set_ip(struct beiscsi_hba *phba, | |||
966 | 1052 | ||
967 | return mgmt_exec_nonemb_cmd(phba, &nonemb_cmd, NULL, 0); | 1053 | return mgmt_exec_nonemb_cmd(phba, &nonemb_cmd, NULL, 0); |
968 | } else { | 1054 | } else { |
969 | return mgmt_static_ip_modify(phba, &if_info, ip_param, | 1055 | return mgmt_static_ip_modify(phba, if_info, ip_param, |
970 | subnet_param, IP_ACTION_ADD); | 1056 | subnet_param, IP_ACTION_ADD); |
971 | } | 1057 | } |
972 | 1058 | ||
@@ -1031,27 +1117,64 @@ int mgmt_get_gateway(struct beiscsi_hba *phba, int ip_type, | |||
1031 | } | 1117 | } |
1032 | 1118 | ||
1033 | int mgmt_get_if_info(struct beiscsi_hba *phba, int ip_type, | 1119 | int mgmt_get_if_info(struct beiscsi_hba *phba, int ip_type, |
1034 | struct be_cmd_get_if_info_resp *if_info) | 1120 | struct be_cmd_get_if_info_resp **if_info) |
1035 | { | 1121 | { |
1036 | struct be_cmd_get_if_info_req *req; | 1122 | struct be_cmd_get_if_info_req *req; |
1037 | struct be_dma_mem nonemb_cmd; | 1123 | struct be_dma_mem nonemb_cmd; |
1124 | uint32_t ioctl_size = sizeof(struct be_cmd_get_if_info_resp); | ||
1038 | int rc; | 1125 | int rc; |
1039 | 1126 | ||
1040 | if (mgmt_get_all_if_id(phba)) | 1127 | if (mgmt_get_all_if_id(phba)) |
1041 | return -EIO; | 1128 | return -EIO; |
1042 | 1129 | ||
1043 | rc = mgmt_alloc_cmd_data(phba, &nonemb_cmd, | 1130 | do { |
1044 | OPCODE_COMMON_ISCSI_NTWK_GET_IF_INFO, | 1131 | rc = mgmt_alloc_cmd_data(phba, &nonemb_cmd, |
1045 | sizeof(*if_info)); | 1132 | OPCODE_COMMON_ISCSI_NTWK_GET_IF_INFO, |
1046 | if (rc) | 1133 | ioctl_size); |
1047 | return rc; | 1134 | if (rc) |
1135 | return rc; | ||
1048 | 1136 | ||
1049 | req = nonemb_cmd.va; | 1137 | req = nonemb_cmd.va; |
1050 | req->interface_hndl = phba->interface_handle; | 1138 | req->interface_hndl = phba->interface_handle; |
1051 | req->ip_type = ip_type; | 1139 | req->ip_type = ip_type; |
1140 | |||
1141 | /* Allocate memory for if_info */ | ||
1142 | *if_info = kzalloc(ioctl_size, GFP_KERNEL); | ||
1143 | if (!*if_info) { | ||
1144 | beiscsi_log(phba, KERN_ERR, | ||
1145 | BEISCSI_LOG_INIT | BEISCSI_LOG_CONFIG, | ||
1146 | "BG_%d : Memory Allocation Failure\n"); | ||
1147 | |||
1148 | /* Free the DMA memory for the IOCTL issuing */ | ||
1149 | pci_free_consistent(phba->ctrl.pdev, | ||
1150 | nonemb_cmd.size, | ||
1151 | nonemb_cmd.va, | ||
1152 | nonemb_cmd.dma); | ||
1153 | return -ENOMEM; | ||
1154 | } | ||
1155 | |||
1156 | rc = mgmt_exec_nonemb_cmd(phba, &nonemb_cmd, *if_info, | ||
1157 | ioctl_size); | ||
1158 | |||
1159 | /* Check if the error is because of Insufficent_Buffer */ | ||
1160 | if (rc == -EAGAIN) { | ||
1161 | |||
1162 | /* Get the new memory size */ | ||
1163 | ioctl_size = ((struct be_cmd_resp_hdr *) | ||
1164 | nonemb_cmd.va)->actual_resp_len; | ||
1165 | ioctl_size += sizeof(struct be_cmd_req_hdr); | ||
1052 | 1166 | ||
1053 | return mgmt_exec_nonemb_cmd(phba, &nonemb_cmd, if_info, | 1167 | /* Free the previous allocated DMA memory */ |
1054 | sizeof(*if_info)); | 1168 | pci_free_consistent(phba->ctrl.pdev, nonemb_cmd.size, |
1169 | nonemb_cmd.va, | ||
1170 | nonemb_cmd.dma); | ||
1171 | |||
1172 | /* Free the virtual memory */ | ||
1173 | kfree(*if_info); | ||
1174 | } else | ||
1175 | break; | ||
1176 | } while (true); | ||
1177 | return rc; | ||
1055 | } | 1178 | } |
1056 | 1179 | ||
1057 | int mgmt_get_nic_conf(struct beiscsi_hba *phba, | 1180 | int mgmt_get_nic_conf(struct beiscsi_hba *phba, |
@@ -1281,7 +1404,7 @@ beiscsi_fw_ver_disp(struct device *dev, struct device_attribute *attr, | |||
1281 | } | 1404 | } |
1282 | 1405 | ||
1283 | /** | 1406 | /** |
1284 | * beiscsi_active_cid_disp()- Display Sessions Active | 1407 | * beiscsi_active_session_disp()- Display Sessions Active |
1285 | * @dev: ptr to device not used. | 1408 | * @dev: ptr to device not used. |
1286 | * @attr: device attribute, not used. | 1409 | * @attr: device attribute, not used. |
1287 | * @buf: contains formatted text Session Count | 1410 | * @buf: contains formatted text Session Count |
@@ -1290,14 +1413,56 @@ beiscsi_fw_ver_disp(struct device *dev, struct device_attribute *attr, | |||
1290 | * size of the formatted string | 1413 | * size of the formatted string |
1291 | **/ | 1414 | **/ |
1292 | ssize_t | 1415 | ssize_t |
1293 | beiscsi_active_cid_disp(struct device *dev, struct device_attribute *attr, | 1416 | beiscsi_active_session_disp(struct device *dev, struct device_attribute *attr, |
1294 | char *buf) | 1417 | char *buf) |
1295 | { | 1418 | { |
1296 | struct Scsi_Host *shost = class_to_shost(dev); | 1419 | struct Scsi_Host *shost = class_to_shost(dev); |
1297 | struct beiscsi_hba *phba = iscsi_host_priv(shost); | 1420 | struct beiscsi_hba *phba = iscsi_host_priv(shost); |
1421 | uint16_t avlbl_cids = 0, ulp_num, len = 0, total_cids = 0; | ||
1422 | |||
1423 | for (ulp_num = 0; ulp_num < BEISCSI_ULP_COUNT; ulp_num++) { | ||
1424 | if (test_bit(ulp_num, (void *)&phba->fw_config.ulp_supported)) { | ||
1425 | avlbl_cids = BEISCSI_ULP_AVLBL_CID(phba, ulp_num); | ||
1426 | total_cids = BEISCSI_GET_CID_COUNT(phba, ulp_num); | ||
1427 | len += snprintf(buf+len, PAGE_SIZE - len, | ||
1428 | "ULP%d : %d\n", ulp_num, | ||
1429 | (total_cids - avlbl_cids)); | ||
1430 | } else | ||
1431 | len += snprintf(buf+len, PAGE_SIZE - len, | ||
1432 | "ULP%d : %d\n", ulp_num, 0); | ||
1433 | } | ||
1298 | 1434 | ||
1299 | return snprintf(buf, PAGE_SIZE, "%d\n", | 1435 | return len; |
1300 | (phba->params.cxns_per_ctrl - phba->avlbl_cids)); | 1436 | } |
1437 | |||
1438 | /** | ||
1439 | * beiscsi_free_session_disp()- Display Avaliable Session | ||
1440 | * @dev: ptr to device not used. | ||
1441 | * @attr: device attribute, not used. | ||
1442 | * @buf: contains formatted text Session Count | ||
1443 | * | ||
1444 | * return | ||
1445 | * size of the formatted string | ||
1446 | **/ | ||
1447 | ssize_t | ||
1448 | beiscsi_free_session_disp(struct device *dev, struct device_attribute *attr, | ||
1449 | char *buf) | ||
1450 | { | ||
1451 | struct Scsi_Host *shost = class_to_shost(dev); | ||
1452 | struct beiscsi_hba *phba = iscsi_host_priv(shost); | ||
1453 | uint16_t ulp_num, len = 0; | ||
1454 | |||
1455 | for (ulp_num = 0; ulp_num < BEISCSI_ULP_COUNT; ulp_num++) { | ||
1456 | if (test_bit(ulp_num, (void *)&phba->fw_config.ulp_supported)) | ||
1457 | len += snprintf(buf+len, PAGE_SIZE - len, | ||
1458 | "ULP%d : %d\n", ulp_num, | ||
1459 | BEISCSI_ULP_AVLBL_CID(phba, ulp_num)); | ||
1460 | else | ||
1461 | len += snprintf(buf+len, PAGE_SIZE - len, | ||
1462 | "ULP%d : %d\n", ulp_num, 0); | ||
1463 | } | ||
1464 | |||
1465 | return len; | ||
1301 | } | 1466 | } |
1302 | 1467 | ||
1303 | /** | 1468 | /** |
@@ -1338,6 +1503,25 @@ beiscsi_adap_family_disp(struct device *dev, struct device_attribute *attr, | |||
1338 | } | 1503 | } |
1339 | } | 1504 | } |
1340 | 1505 | ||
1506 | /** | ||
1507 | * beiscsi_phys_port()- Display Physical Port Identifier | ||
1508 | * @dev: ptr to device not used. | ||
1509 | * @attr: device attribute, not used. | ||
1510 | * @buf: contains formatted text port identifier | ||
1511 | * | ||
1512 | * return | ||
1513 | * size of the formatted string | ||
1514 | **/ | ||
1515 | ssize_t | ||
1516 | beiscsi_phys_port_disp(struct device *dev, struct device_attribute *attr, | ||
1517 | char *buf) | ||
1518 | { | ||
1519 | struct Scsi_Host *shost = class_to_shost(dev); | ||
1520 | struct beiscsi_hba *phba = iscsi_host_priv(shost); | ||
1521 | |||
1522 | return snprintf(buf, PAGE_SIZE, "Port Identifier : %d\n", | ||
1523 | phba->fw_config.phys_port); | ||
1524 | } | ||
1341 | 1525 | ||
1342 | void beiscsi_offload_cxn_v0(struct beiscsi_offload_params *params, | 1526 | void beiscsi_offload_cxn_v0(struct beiscsi_offload_params *params, |
1343 | struct wrb_handle *pwrb_handle, | 1527 | struct wrb_handle *pwrb_handle, |
@@ -1411,10 +1595,6 @@ void beiscsi_offload_cxn_v2(struct beiscsi_offload_params *params, | |||
1411 | 1595 | ||
1412 | memset(pwrb, 0, sizeof(*pwrb)); | 1596 | memset(pwrb, 0, sizeof(*pwrb)); |
1413 | 1597 | ||
1414 | AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb, | ||
1415 | max_burst_length, pwrb, params->dw[offsetof | ||
1416 | (struct amap_beiscsi_offload_params, | ||
1417 | max_burst_length) / 32]); | ||
1418 | AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb_v2, | 1598 | AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb_v2, |
1419 | max_burst_length, pwrb, params->dw[offsetof | 1599 | max_burst_length, pwrb, params->dw[offsetof |
1420 | (struct amap_beiscsi_offload_params, | 1600 | (struct amap_beiscsi_offload_params, |
@@ -1436,7 +1616,9 @@ void beiscsi_offload_cxn_v2(struct beiscsi_offload_params *params, | |||
1436 | params->dw[offsetof(struct amap_beiscsi_offload_params, | 1616 | params->dw[offsetof(struct amap_beiscsi_offload_params, |
1437 | first_burst_length) / 32]); | 1617 | first_burst_length) / 32]); |
1438 | AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb_v2, | 1618 | AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb_v2, |
1439 | max_recv_dataseg_len, pwrb, BEISCSI_MAX_RECV_DATASEG_LEN); | 1619 | max_recv_dataseg_len, pwrb, |
1620 | params->dw[offsetof(struct amap_beiscsi_offload_params, | ||
1621 | max_recv_data_segment_length) / 32]); | ||
1440 | AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb_v2, | 1622 | AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb_v2, |
1441 | max_cxns, pwrb, BEISCSI_MAX_CXNS); | 1623 | max_cxns, pwrb, BEISCSI_MAX_CXNS); |
1442 | AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb_v2, erl, pwrb, | 1624 | AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb_v2, erl, pwrb, |
diff --git a/drivers/scsi/be2iscsi/be_mgmt.h b/drivers/scsi/be2iscsi/be_mgmt.h index 04af7e74fe48..01b8c97284c0 100644 --- a/drivers/scsi/be2iscsi/be_mgmt.h +++ b/drivers/scsi/be2iscsi/be_mgmt.h | |||
@@ -294,7 +294,7 @@ int mgmt_get_nic_conf(struct beiscsi_hba *phba, | |||
294 | struct be_cmd_get_nic_conf_resp *mac); | 294 | struct be_cmd_get_nic_conf_resp *mac); |
295 | 295 | ||
296 | int mgmt_get_if_info(struct beiscsi_hba *phba, int ip_type, | 296 | int mgmt_get_if_info(struct beiscsi_hba *phba, int ip_type, |
297 | struct be_cmd_get_if_info_resp *if_info); | 297 | struct be_cmd_get_if_info_resp **if_info); |
298 | 298 | ||
299 | int mgmt_get_gateway(struct beiscsi_hba *phba, int ip_type, | 299 | int mgmt_get_gateway(struct beiscsi_hba *phba, int ip_type, |
300 | struct be_cmd_get_def_gateway_resp *gateway); | 300 | struct be_cmd_get_def_gateway_resp *gateway); |
@@ -315,12 +315,19 @@ ssize_t beiscsi_drvr_ver_disp(struct device *dev, | |||
315 | ssize_t beiscsi_fw_ver_disp(struct device *dev, | 315 | ssize_t beiscsi_fw_ver_disp(struct device *dev, |
316 | struct device_attribute *attr, char *buf); | 316 | struct device_attribute *attr, char *buf); |
317 | 317 | ||
318 | ssize_t beiscsi_active_cid_disp(struct device *dev, | 318 | ssize_t beiscsi_active_session_disp(struct device *dev, |
319 | struct device_attribute *attr, char *buf); | 319 | struct device_attribute *attr, char *buf); |
320 | 320 | ||
321 | ssize_t beiscsi_adap_family_disp(struct device *dev, | 321 | ssize_t beiscsi_adap_family_disp(struct device *dev, |
322 | struct device_attribute *attr, char *buf); | 322 | struct device_attribute *attr, char *buf); |
323 | 323 | ||
324 | |||
325 | ssize_t beiscsi_free_session_disp(struct device *dev, | ||
326 | struct device_attribute *attr, char *buf); | ||
327 | |||
328 | ssize_t beiscsi_phys_port_disp(struct device *dev, | ||
329 | struct device_attribute *attr, char *buf); | ||
330 | |||
324 | void beiscsi_offload_cxn_v0(struct beiscsi_offload_params *params, | 331 | void beiscsi_offload_cxn_v0(struct beiscsi_offload_params *params, |
325 | struct wrb_handle *pwrb_handle, | 332 | struct wrb_handle *pwrb_handle, |
326 | struct be_mem_descriptor *mem_descr); | 333 | struct be_mem_descriptor *mem_descr); |