aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/bnx2i/bnx2i_hwi.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/scsi/bnx2i/bnx2i_hwi.c')
-rw-r--r--drivers/scsi/bnx2i/bnx2i_hwi.c125
1 files changed, 122 insertions, 3 deletions
diff --git a/drivers/scsi/bnx2i/bnx2i_hwi.c b/drivers/scsi/bnx2i/bnx2i_hwi.c
index 96505e3ab986..1da34c019b8a 100644
--- a/drivers/scsi/bnx2i/bnx2i_hwi.c
+++ b/drivers/scsi/bnx2i/bnx2i_hwi.c
@@ -445,6 +445,56 @@ int bnx2i_send_iscsi_tmf(struct bnx2i_conn *bnx2i_conn,
445} 445}
446 446
447/** 447/**
448 * bnx2i_send_iscsi_text - post iSCSI text WQE to hardware
449 * @conn: iscsi connection
450 * @mtask: driver command structure which is requesting
451 * a WQE to sent to chip for further processing
452 *
453 * prepare and post an iSCSI Text request WQE to CNIC firmware
454 */
455int bnx2i_send_iscsi_text(struct bnx2i_conn *bnx2i_conn,
456 struct iscsi_task *mtask)
457{
458 struct bnx2i_cmd *bnx2i_cmd;
459 struct bnx2i_text_request *text_wqe;
460 struct iscsi_text *text_hdr;
461 u32 dword;
462
463 bnx2i_cmd = (struct bnx2i_cmd *)mtask->dd_data;
464 text_hdr = (struct iscsi_text *)mtask->hdr;
465 text_wqe = (struct bnx2i_text_request *) bnx2i_conn->ep->qp.sq_prod_qe;
466
467 memset(text_wqe, 0, sizeof(struct bnx2i_text_request));
468
469 text_wqe->op_code = text_hdr->opcode;
470 text_wqe->op_attr = text_hdr->flags;
471 text_wqe->data_length = ntoh24(text_hdr->dlength);
472 text_wqe->itt = mtask->itt |
473 (ISCSI_TASK_TYPE_MPATH << ISCSI_TEXT_REQUEST_TYPE_SHIFT);
474 text_wqe->ttt = be32_to_cpu(text_hdr->ttt);
475
476 text_wqe->cmd_sn = be32_to_cpu(text_hdr->cmdsn);
477
478 text_wqe->resp_bd_list_addr_lo = (u32) bnx2i_conn->gen_pdu.resp_bd_dma;
479 text_wqe->resp_bd_list_addr_hi =
480 (u32) ((u64) bnx2i_conn->gen_pdu.resp_bd_dma >> 32);
481
482 dword = ((1 << ISCSI_TEXT_REQUEST_NUM_RESP_BDS_SHIFT) |
483 (bnx2i_conn->gen_pdu.resp_buf_size <<
484 ISCSI_TEXT_REQUEST_RESP_BUFFER_LENGTH_SHIFT));
485 text_wqe->resp_buffer = dword;
486 text_wqe->bd_list_addr_lo = (u32) bnx2i_conn->gen_pdu.req_bd_dma;
487 text_wqe->bd_list_addr_hi =
488 (u32) ((u64) bnx2i_conn->gen_pdu.req_bd_dma >> 32);
489 text_wqe->num_bds = 1;
490 text_wqe->cq_index = 0; /* CQ# used for completion, 5771x only */
491
492 bnx2i_ring_dbell_update_sq_params(bnx2i_conn, 1);
493 return 0;
494}
495
496
497/**
448 * bnx2i_send_iscsi_scsicmd - post iSCSI scsicmd request WQE to hardware 498 * bnx2i_send_iscsi_scsicmd - post iSCSI scsicmd request WQE to hardware
449 * @conn: iscsi connection 499 * @conn: iscsi connection
450 * @cmd: driver command structure which is requesting 500 * @cmd: driver command structure which is requesting
@@ -490,15 +540,18 @@ int bnx2i_send_iscsi_nopout(struct bnx2i_conn *bnx2i_conn,
490 bnx2i_cmd = (struct bnx2i_cmd *)task->dd_data; 540 bnx2i_cmd = (struct bnx2i_cmd *)task->dd_data;
491 nopout_hdr = (struct iscsi_nopout *)task->hdr; 541 nopout_hdr = (struct iscsi_nopout *)task->hdr;
492 nopout_wqe = (struct bnx2i_nop_out_request *)ep->qp.sq_prod_qe; 542 nopout_wqe = (struct bnx2i_nop_out_request *)ep->qp.sq_prod_qe;
543
544 memset(nopout_wqe, 0x00, sizeof(struct bnx2i_nop_out_request));
545
493 nopout_wqe->op_code = nopout_hdr->opcode; 546 nopout_wqe->op_code = nopout_hdr->opcode;
494 nopout_wqe->op_attr = ISCSI_FLAG_CMD_FINAL; 547 nopout_wqe->op_attr = ISCSI_FLAG_CMD_FINAL;
495 memcpy(nopout_wqe->lun, nopout_hdr->lun, 8); 548 memcpy(nopout_wqe->lun, nopout_hdr->lun, 8);
496 549
497 if (test_bit(BNX2I_NX2_DEV_57710, &ep->hba->cnic_dev_type)) { 550 if (test_bit(BNX2I_NX2_DEV_57710, &ep->hba->cnic_dev_type)) {
498 u32 tmp = nopout_hdr->lun[0]; 551 u32 tmp = nopout_wqe->lun[0];
499 /* 57710 requires LUN field to be swapped */ 552 /* 57710 requires LUN field to be swapped */
500 nopout_hdr->lun[0] = nopout_hdr->lun[1]; 553 nopout_wqe->lun[0] = nopout_wqe->lun[1];
501 nopout_hdr->lun[1] = tmp; 554 nopout_wqe->lun[1] = tmp;
502 } 555 }
503 556
504 nopout_wqe->itt = ((u16)task->itt | 557 nopout_wqe->itt = ((u16)task->itt |
@@ -1425,6 +1478,68 @@ done:
1425 return 0; 1478 return 0;
1426} 1479}
1427 1480
1481
1482/**
1483 * bnx2i_process_text_resp - this function handles iscsi text response
1484 * @session: iscsi session pointer
1485 * @bnx2i_conn: iscsi connection pointer
1486 * @cqe: pointer to newly DMA'ed CQE entry for processing
1487 *
1488 * process iSCSI Text Response CQE& complete it to open-iscsi user daemon
1489 */
1490static int bnx2i_process_text_resp(struct iscsi_session *session,
1491 struct bnx2i_conn *bnx2i_conn,
1492 struct cqe *cqe)
1493{
1494 struct iscsi_conn *conn = bnx2i_conn->cls_conn->dd_data;
1495 struct iscsi_task *task;
1496 struct bnx2i_text_response *text;
1497 struct iscsi_text_rsp *resp_hdr;
1498 int pld_len;
1499 int pad_len;
1500
1501 text = (struct bnx2i_text_response *) cqe;
1502 spin_lock(&session->lock);
1503 task = iscsi_itt_to_task(conn, text->itt & ISCSI_LOGIN_RESPONSE_INDEX);
1504 if (!task)
1505 goto done;
1506
1507 resp_hdr = (struct iscsi_text_rsp *)&bnx2i_conn->gen_pdu.resp_hdr;
1508 memset(resp_hdr, 0, sizeof(struct iscsi_hdr));
1509 resp_hdr->opcode = text->op_code;
1510 resp_hdr->flags = text->response_flags;
1511 resp_hdr->hlength = 0;
1512
1513 hton24(resp_hdr->dlength, text->data_length);
1514 resp_hdr->itt = task->hdr->itt;
1515 resp_hdr->ttt = cpu_to_be32(text->ttt);
1516 resp_hdr->statsn = task->hdr->exp_statsn;
1517 resp_hdr->exp_cmdsn = cpu_to_be32(text->exp_cmd_sn);
1518 resp_hdr->max_cmdsn = cpu_to_be32(text->max_cmd_sn);
1519 pld_len = text->data_length;
1520 bnx2i_conn->gen_pdu.resp_wr_ptr = bnx2i_conn->gen_pdu.resp_buf +
1521 pld_len;
1522 pad_len = 0;
1523 if (pld_len & 0x3)
1524 pad_len = 4 - (pld_len % 4);
1525
1526 if (pad_len) {
1527 int i = 0;
1528 for (i = 0; i < pad_len; i++) {
1529 bnx2i_conn->gen_pdu.resp_wr_ptr[0] = 0;
1530 bnx2i_conn->gen_pdu.resp_wr_ptr++;
1531 }
1532 }
1533 __iscsi_complete_pdu(conn, (struct iscsi_hdr *)resp_hdr,
1534 bnx2i_conn->gen_pdu.resp_buf,
1535 bnx2i_conn->gen_pdu.resp_wr_ptr -
1536 bnx2i_conn->gen_pdu.resp_buf);
1537done:
1538 spin_unlock(&session->lock);
1539 return 0;
1540}
1541
1542
1428/** 1543/**
1429 * bnx2i_process_tmf_resp - this function handles iscsi TMF response 1544 * bnx2i_process_tmf_resp - this function handles iscsi TMF response
1430 * @session: iscsi session pointer 1545 * @session: iscsi session pointer
@@ -1766,6 +1881,10 @@ static void bnx2i_process_new_cqes(struct bnx2i_conn *bnx2i_conn)
1766 bnx2i_process_tmf_resp(session, bnx2i_conn, 1881 bnx2i_process_tmf_resp(session, bnx2i_conn,
1767 qp->cq_cons_qe); 1882 qp->cq_cons_qe);
1768 break; 1883 break;
1884 case ISCSI_OP_TEXT_RSP:
1885 bnx2i_process_text_resp(session, bnx2i_conn,
1886 qp->cq_cons_qe);
1887 break;
1769 case ISCSI_OP_LOGOUT_RSP: 1888 case ISCSI_OP_LOGOUT_RSP:
1770 bnx2i_process_logout_resp(session, bnx2i_conn, 1889 bnx2i_process_logout_resp(session, bnx2i_conn,
1771 qp->cq_cons_qe); 1890 qp->cq_cons_qe);