1675
* lpfc_sli4_bsg_set_link_diag_state - set sli4 link diag state
1676
* @phba: Pointer to HBA context object.
1677
* @diag: Flag for set link to diag or nomral operation state.
1679
* This function is responsible for issuing a sli4 mailbox command for setting
1680
* link to either diag state or normal operation state.
1683
lpfc_sli4_bsg_set_link_diag_state(struct lpfc_hba *phba, uint32_t diag)
1685
LPFC_MBOXQ_t *pmboxq;
1686
struct lpfc_mbx_set_link_diag_state *link_diag_state;
1687
uint32_t req_len, alloc_len;
1688
int mbxstatus = MBX_SUCCESS, rc;
1690
pmboxq = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL);
1694
req_len = (sizeof(struct lpfc_mbx_set_link_diag_state) -
1695
sizeof(struct lpfc_sli4_cfg_mhdr));
1696
alloc_len = lpfc_sli4_config(phba, pmboxq, LPFC_MBOX_SUBSYSTEM_FCOE,
1697
LPFC_MBOX_OPCODE_FCOE_LINK_DIAG_STATE,
1698
req_len, LPFC_SLI4_MBX_EMBED);
1699
if (alloc_len != req_len) {
1701
goto link_diag_state_set_out;
1703
link_diag_state = &pmboxq->u.mqe.un.link_diag_state;
1704
bf_set(lpfc_mbx_set_diag_state_link_num, &link_diag_state->u.req,
1705
phba->sli4_hba.link_state.number);
1706
bf_set(lpfc_mbx_set_diag_state_link_type, &link_diag_state->u.req,
1707
phba->sli4_hba.link_state.type);
1709
bf_set(lpfc_mbx_set_diag_state_diag,
1710
&link_diag_state->u.req, 1);
1712
bf_set(lpfc_mbx_set_diag_state_diag,
1713
&link_diag_state->u.req, 0);
1715
mbxstatus = lpfc_sli_issue_mbox_wait(phba, pmboxq, LPFC_MBOX_TMO);
1717
if ((mbxstatus == MBX_SUCCESS) && (pmboxq->u.mb.mbxStatus == 0))
1722
link_diag_state_set_out:
1723
if (pmboxq && (mbxstatus != MBX_TIMEOUT))
1724
mempool_free(pmboxq, phba->mbox_mem_pool);
1730
* lpfc_sli4_bsg_diag_loopback_mode - process an sli4 bsg vendor command
1731
* @phba: Pointer to HBA context object.
1732
* @job: LPFC_BSG_VENDOR_DIAG_MODE
1734
* This function is responsible for placing an sli4 port into diagnostic
1735
* loopback mode in order to perform a diagnostic loopback test.
1738
lpfc_sli4_bsg_diag_loopback_mode(struct lpfc_hba *phba, struct fc_bsg_job *job)
1740
struct diag_mode_set *loopback_mode;
1741
uint32_t link_flags, timeout, req_len, alloc_len;
1742
struct lpfc_mbx_set_link_diag_loopback *link_diag_loopback;
1743
LPFC_MBOXQ_t *pmboxq = NULL;
1744
int mbxstatus, i, rc = 0;
1746
/* no data to return just the return code */
1747
job->reply->reply_payload_rcv_len = 0;
1749
if (job->request_len < sizeof(struct fc_bsg_request) +
1750
sizeof(struct diag_mode_set)) {
1751
lpfc_printf_log(phba, KERN_WARNING, LOG_LIBDFC,
1752
"3011 Received DIAG MODE request size:%d "
1753
"below the minimum size:%d\n",
1755
(int)(sizeof(struct fc_bsg_request) +
1756
sizeof(struct diag_mode_set)));
1761
rc = lpfc_bsg_diag_mode_enter(phba, job);
1765
/* bring the link to diagnostic mode */
1766
loopback_mode = (struct diag_mode_set *)
1767
job->request->rqst_data.h_vendor.vendor_cmd;
1768
link_flags = loopback_mode->type;
1769
timeout = loopback_mode->timeout * 100;
1771
rc = lpfc_sli4_bsg_set_link_diag_state(phba, 1);
1773
goto loopback_mode_exit;
1775
/* wait for link down before proceeding */
1777
while (phba->link_state != LPFC_LINK_DOWN) {
1778
if (i++ > timeout) {
1780
goto loopback_mode_exit;
1784
/* set up loopback mode */
1785
pmboxq = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL);
1788
goto loopback_mode_exit;
1790
req_len = (sizeof(struct lpfc_mbx_set_link_diag_loopback) -
1791
sizeof(struct lpfc_sli4_cfg_mhdr));
1792
alloc_len = lpfc_sli4_config(phba, pmboxq, LPFC_MBOX_SUBSYSTEM_FCOE,
1793
LPFC_MBOX_OPCODE_FCOE_LINK_DIAG_LOOPBACK,
1794
req_len, LPFC_SLI4_MBX_EMBED);
1795
if (alloc_len != req_len) {
1797
goto loopback_mode_exit;
1799
link_diag_loopback = &pmboxq->u.mqe.un.link_diag_loopback;
1800
bf_set(lpfc_mbx_set_diag_state_link_num,
1801
&link_diag_loopback->u.req, phba->sli4_hba.link_state.number);
1802
bf_set(lpfc_mbx_set_diag_state_link_type,
1803
&link_diag_loopback->u.req, phba->sli4_hba.link_state.type);
1804
if (link_flags == INTERNAL_LOOP_BACK)
1805
bf_set(lpfc_mbx_set_diag_lpbk_type,
1806
&link_diag_loopback->u.req,
1807
LPFC_DIAG_LOOPBACK_TYPE_INTERNAL);
1809
bf_set(lpfc_mbx_set_diag_lpbk_type,
1810
&link_diag_loopback->u.req,
1811
LPFC_DIAG_LOOPBACK_TYPE_EXTERNAL);
1813
mbxstatus = lpfc_sli_issue_mbox_wait(phba, pmboxq, LPFC_MBOX_TMO);
1814
if ((mbxstatus != MBX_SUCCESS) || (pmboxq->u.mb.mbxStatus))
1817
phba->link_flag |= LS_LOOPBACK_MODE;
1818
/* wait for the link attention interrupt */
1821
while (phba->link_state != LPFC_HBA_READY) {
1822
if (i++ > timeout) {
1831
lpfc_bsg_diag_mode_exit(phba);
1834
* Let SLI layer release mboxq if mbox command completed after timeout.
1836
if (pmboxq && (mbxstatus != MBX_TIMEOUT))
1837
mempool_free(pmboxq, phba->mbox_mem_pool);
1840
/* make error code available to userspace */
1841
job->reply->result = rc;
1842
/* complete the job back to userspace if no error */
1849
* lpfc_bsg_diag_loopback_mode - bsg vendor command for diag loopback mode
1850
* @job: LPFC_BSG_VENDOR_DIAG_MODE
1852
* This function is responsible for responding to check and dispatch bsg diag
1853
* command from the user to proper driver action routines.
1856
lpfc_bsg_diag_loopback_mode(struct fc_bsg_job *job)
1858
struct Scsi_Host *shost;
1859
struct lpfc_vport *vport;
1860
struct lpfc_hba *phba;
1866
vport = (struct lpfc_vport *)job->shost->hostdata;
1873
if (phba->sli_rev < LPFC_SLI_REV4)
1874
rc = lpfc_sli3_bsg_diag_loopback_mode(phba, job);
1875
else if (bf_get(lpfc_sli_intf_if_type, &phba->sli4_hba.sli_intf) ==
1876
LPFC_SLI_INTF_IF_TYPE_2)
1877
rc = lpfc_sli4_bsg_diag_loopback_mode(phba, job);
1886
* lpfc_sli4_bsg_diag_mode_end - sli4 bsg vendor command for ending diag mode
1887
* @job: LPFC_BSG_VENDOR_DIAG_MODE_END
1889
* This function is responsible for responding to check and dispatch bsg diag
1890
* command from the user to proper driver action routines.
1893
lpfc_sli4_bsg_diag_mode_end(struct fc_bsg_job *job)
1895
struct Scsi_Host *shost;
1896
struct lpfc_vport *vport;
1897
struct lpfc_hba *phba;
1903
vport = (struct lpfc_vport *)job->shost->hostdata;
1910
if (phba->sli_rev < LPFC_SLI_REV4)
1912
if (bf_get(lpfc_sli_intf_if_type, &phba->sli4_hba.sli_intf) !=
1913
LPFC_SLI_INTF_IF_TYPE_2)
1916
rc = lpfc_sli4_bsg_set_link_diag_state(phba, 0);
1919
rc = phba->lpfc_hba_init_link(phba, MBX_NOWAIT);
1925
* lpfc_sli4_bsg_link_diag_test - sli4 bsg vendor command for diag link test
1926
* @job: LPFC_BSG_VENDOR_DIAG_LINK_TEST
1928
* This function is to perform SLI4 diag link test request from the user
1932
lpfc_sli4_bsg_link_diag_test(struct fc_bsg_job *job)
1934
struct Scsi_Host *shost;
1935
struct lpfc_vport *vport;
1936
struct lpfc_hba *phba;
1937
LPFC_MBOXQ_t *pmboxq;
1938
struct sli4_link_diag *link_diag_test_cmd;
1939
uint32_t req_len, alloc_len;
1941
struct lpfc_mbx_run_link_diag_test *run_link_diag_test;
1942
union lpfc_sli4_cfg_shdr *shdr;
1943
uint32_t shdr_status, shdr_add_status;
1944
struct diag_status *diag_status_reply;
1945
int mbxstatus, rc = 0;
1952
vport = (struct lpfc_vport *)job->shost->hostdata;
1963
if (phba->sli_rev < LPFC_SLI_REV4) {
1967
if (bf_get(lpfc_sli_intf_if_type, &phba->sli4_hba.sli_intf) !=
1968
LPFC_SLI_INTF_IF_TYPE_2) {
1973
if (job->request_len < sizeof(struct fc_bsg_request) +
1974
sizeof(struct sli4_link_diag)) {
1975
lpfc_printf_log(phba, KERN_WARNING, LOG_LIBDFC,
1976
"3013 Received LINK DIAG TEST request "
1977
" size:%d below the minimum size:%d\n",
1979
(int)(sizeof(struct fc_bsg_request) +
1980
sizeof(struct sli4_link_diag)));
1985
rc = lpfc_bsg_diag_mode_enter(phba, job);
1989
link_diag_test_cmd = (struct sli4_link_diag *)
1990
job->request->rqst_data.h_vendor.vendor_cmd;
1991
timeout = link_diag_test_cmd->timeout * 100;
1993
rc = lpfc_sli4_bsg_set_link_diag_state(phba, 1);
1998
pmboxq = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL);
2001
goto link_diag_test_exit;
2004
req_len = (sizeof(struct lpfc_mbx_set_link_diag_state) -
2005
sizeof(struct lpfc_sli4_cfg_mhdr));
2006
alloc_len = lpfc_sli4_config(phba, pmboxq, LPFC_MBOX_SUBSYSTEM_FCOE,
2007
LPFC_MBOX_OPCODE_FCOE_LINK_DIAG_STATE,
2008
req_len, LPFC_SLI4_MBX_EMBED);
2009
if (alloc_len != req_len) {
2011
goto link_diag_test_exit;
2013
run_link_diag_test = &pmboxq->u.mqe.un.link_diag_test;
2014
bf_set(lpfc_mbx_run_diag_test_link_num, &run_link_diag_test->u.req,
2015
phba->sli4_hba.link_state.number);
2016
bf_set(lpfc_mbx_run_diag_test_link_type, &run_link_diag_test->u.req,
2017
phba->sli4_hba.link_state.type);
2018
bf_set(lpfc_mbx_run_diag_test_test_id, &run_link_diag_test->u.req,
2019
link_diag_test_cmd->test_id);
2020
bf_set(lpfc_mbx_run_diag_test_loops, &run_link_diag_test->u.req,
2021
link_diag_test_cmd->loops);
2022
bf_set(lpfc_mbx_run_diag_test_test_ver, &run_link_diag_test->u.req,
2023
link_diag_test_cmd->test_version);
2024
bf_set(lpfc_mbx_run_diag_test_err_act, &run_link_diag_test->u.req,
2025
link_diag_test_cmd->error_action);
2027
mbxstatus = lpfc_sli_issue_mbox(phba, pmboxq, MBX_POLL);
2029
shdr = (union lpfc_sli4_cfg_shdr *)
2030
&pmboxq->u.mqe.un.sli4_config.header.cfg_shdr;
2031
shdr_status = bf_get(lpfc_mbox_hdr_status, &shdr->response);
2032
shdr_add_status = bf_get(lpfc_mbox_hdr_add_status, &shdr->response);
2033
if (shdr_status || shdr_add_status || mbxstatus) {
2034
lpfc_printf_log(phba, KERN_ERR, LOG_LIBDFC,
2035
"3010 Run link diag test mailbox failed with "
2036
"mbx_status x%x status x%x, add_status x%x\n",
2037
mbxstatus, shdr_status, shdr_add_status);
2040
diag_status_reply = (struct diag_status *)
2041
job->reply->reply_data.vendor_reply.vendor_rsp;
2043
if (job->reply_len <
2044
sizeof(struct fc_bsg_request) + sizeof(struct diag_status)) {
2045
lpfc_printf_log(phba, KERN_WARNING, LOG_LIBDFC,
2046
"3012 Received Run link diag test reply "
2047
"below minimum size (%d): reply_len:%d\n",
2048
(int)(sizeof(struct fc_bsg_request) +
2049
sizeof(struct diag_status)),
2055
diag_status_reply->mbox_status = mbxstatus;
2056
diag_status_reply->shdr_status = shdr_status;
2057
diag_status_reply->shdr_add_status = shdr_add_status;
2059
link_diag_test_exit:
2060
rc = lpfc_sli4_bsg_set_link_diag_state(phba, 0);
2063
mempool_free(pmboxq, phba->mbox_mem_pool);
2065
lpfc_bsg_diag_mode_exit(phba);
2068
/* make error code available to userspace */
2069
job->reply->result = rc;
2070
/* complete the job back to userspace if no error */
1625
2077
* lpfcdiag_loop_self_reg - obtains a remote port login id
1626
2078
* @phba: Pointer to HBA context object
1627
2079
* @rpi: Pointer to a remote port login id
3102
* lpfc_bsg_mbox_ext_cleanup - clean up context of multi-buffer mbox session
3103
* @phba: Pointer to HBA context object.
3105
* This is routine clean up and reset BSG handling of multi-buffer mbox
3109
lpfc_bsg_mbox_ext_session_reset(struct lpfc_hba *phba)
3111
if (phba->mbox_ext_buf_ctx.state == LPFC_BSG_MBOX_IDLE)
3114
/* free all memory, including dma buffers */
3115
lpfc_bsg_dma_page_list_free(phba,
3116
&phba->mbox_ext_buf_ctx.ext_dmabuf_list);
3117
lpfc_bsg_dma_page_free(phba, phba->mbox_ext_buf_ctx.mbx_dmabuf);
3118
/* multi-buffer write mailbox command pass-through complete */
3119
memset((char *)&phba->mbox_ext_buf_ctx, 0,
3120
sizeof(struct lpfc_mbox_ext_buf_ctx));
3121
INIT_LIST_HEAD(&phba->mbox_ext_buf_ctx.ext_dmabuf_list);
3127
* lpfc_bsg_issue_mbox_ext_handle_job - job handler for multi-buffer mbox cmpl
3128
* @phba: Pointer to HBA context object.
3129
* @pmboxq: Pointer to mailbox command.
3131
* This is routine handles BSG job for mailbox commands completions with
3132
* multiple external buffers.
3134
static struct fc_bsg_job *
3135
lpfc_bsg_issue_mbox_ext_handle_job(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmboxq)
3137
struct bsg_job_data *dd_data;
3138
struct fc_bsg_job *job;
3139
uint8_t *pmb, *pmb_buf;
3140
unsigned long flags;
3144
spin_lock_irqsave(&phba->ct_ev_lock, flags);
3145
dd_data = pmboxq->context1;
3146
/* has the job already timed out? */
3148
spin_unlock_irqrestore(&phba->ct_ev_lock, flags);
3154
* The outgoing buffer is readily referred from the dma buffer,
3155
* just need to get header part from mailboxq structure.
3157
pmb = (uint8_t *)&pmboxq->u.mb;
3158
pmb_buf = (uint8_t *)dd_data->context_un.mbox.mb;
3159
memcpy(pmb_buf, pmb, sizeof(MAILBOX_t));
3161
job = dd_data->context_un.mbox.set_job;
3163
size = job->reply_payload.payload_len;
3164
job->reply->reply_payload_rcv_len =
3165
sg_copy_from_buffer(job->reply_payload.sg_list,
3166
job->reply_payload.sg_cnt,
3168
/* result for successful */
3169
job->reply->result = 0;
3170
job->dd_data = NULL;
3171
/* need to hold the lock util we set job->dd_data to NULL
3172
* to hold off the timeout handler from midlayer to take
3175
spin_unlock_irqrestore(&phba->ct_ev_lock, flags);
3176
lpfc_printf_log(phba, KERN_INFO, LOG_LIBDFC,
3177
"2937 SLI_CONFIG ext-buffer maibox command "
3178
"(x%x/x%x) complete bsg job done, bsize:%d\n",
3179
phba->mbox_ext_buf_ctx.nembType,
3180
phba->mbox_ext_buf_ctx.mboxType, size);
3182
spin_unlock_irqrestore(&phba->ct_ev_lock, flags);
3186
lpfc_printf_log(phba, KERN_ERR, LOG_LIBDFC,
3187
"2938 SLI_CONFIG ext-buffer maibox "
3188
"command (x%x/x%x) failure, rc:x%x\n",
3189
phba->mbox_ext_buf_ctx.nembType,
3190
phba->mbox_ext_buf_ctx.mboxType, rc);
3192
phba->mbox_ext_buf_ctx.state = LPFC_BSG_MBOX_DONE;
3199
* lpfc_bsg_issue_read_mbox_ext_cmpl - compl handler for multi-buffer read mbox
3200
* @phba: Pointer to HBA context object.
3201
* @pmboxq: Pointer to mailbox command.
3203
* This is completion handler function for mailbox read commands with multiple
3207
lpfc_bsg_issue_read_mbox_ext_cmpl(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmboxq)
3209
struct fc_bsg_job *job;
3211
/* handle the BSG job with mailbox command */
3212
if (phba->mbox_ext_buf_ctx.state == LPFC_BSG_MBOX_ABTS)
3213
pmboxq->u.mb.mbxStatus = MBXERR_ERROR;
3215
lpfc_printf_log(phba, KERN_INFO, LOG_LIBDFC,
3216
"2939 SLI_CONFIG ext-buffer rd maibox command "
3217
"complete, ctxState:x%x, mbxStatus:x%x\n",
3218
phba->mbox_ext_buf_ctx.state, pmboxq->u.mb.mbxStatus);
3220
job = lpfc_bsg_issue_mbox_ext_handle_job(phba, pmboxq);
3222
if (pmboxq->u.mb.mbxStatus || phba->mbox_ext_buf_ctx.numBuf == 1)
3223
lpfc_bsg_mbox_ext_session_reset(phba);
3225
/* free base driver mailbox structure memory */
3226
mempool_free(pmboxq, phba->mbox_mem_pool);
3228
/* complete the bsg job if we have it */
3236
* lpfc_bsg_issue_write_mbox_ext_cmpl - cmpl handler for multi-buffer write mbox
3237
* @phba: Pointer to HBA context object.
3238
* @pmboxq: Pointer to mailbox command.
3240
* This is completion handler function for mailbox write commands with multiple
3244
lpfc_bsg_issue_write_mbox_ext_cmpl(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmboxq)
3246
struct fc_bsg_job *job;
3248
/* handle the BSG job with the mailbox command */
3249
if (phba->mbox_ext_buf_ctx.state == LPFC_BSG_MBOX_ABTS)
3250
pmboxq->u.mb.mbxStatus = MBXERR_ERROR;
3252
lpfc_printf_log(phba, KERN_INFO, LOG_LIBDFC,
3253
"2940 SLI_CONFIG ext-buffer wr maibox command "
3254
"complete, ctxState:x%x, mbxStatus:x%x\n",
3255
phba->mbox_ext_buf_ctx.state, pmboxq->u.mb.mbxStatus);
3257
job = lpfc_bsg_issue_mbox_ext_handle_job(phba, pmboxq);
3259
/* free all memory, including dma buffers */
3260
mempool_free(pmboxq, phba->mbox_mem_pool);
3261
lpfc_bsg_mbox_ext_session_reset(phba);
3263
/* complete the bsg job if we have it */
3271
lpfc_bsg_sli_cfg_dma_desc_setup(struct lpfc_hba *phba, enum nemb_type nemb_tp,
3272
uint32_t index, struct lpfc_dmabuf *mbx_dmabuf,
3273
struct lpfc_dmabuf *ext_dmabuf)
3275
struct lpfc_sli_config_mbox *sli_cfg_mbx;
3277
/* pointer to the start of mailbox command */
3278
sli_cfg_mbx = (struct lpfc_sli_config_mbox *)mbx_dmabuf->virt;
3280
if (nemb_tp == nemb_mse) {
3282
sli_cfg_mbx->un.sli_config_emb0_subsys.
3284
putPaddrHigh(mbx_dmabuf->phys +
3286
sli_cfg_mbx->un.sli_config_emb0_subsys.
3288
putPaddrLow(mbx_dmabuf->phys +
3290
lpfc_printf_log(phba, KERN_INFO, LOG_LIBDFC,
3291
"2943 SLI_CONFIG(mse)[%d], "
3292
"bufLen:%d, addrHi:x%x, addrLo:x%x\n",
3294
sli_cfg_mbx->un.sli_config_emb0_subsys.
3296
sli_cfg_mbx->un.sli_config_emb0_subsys.
3298
sli_cfg_mbx->un.sli_config_emb0_subsys.
3301
sli_cfg_mbx->un.sli_config_emb0_subsys.
3303
putPaddrHigh(ext_dmabuf->phys);
3304
sli_cfg_mbx->un.sli_config_emb0_subsys.
3306
putPaddrLow(ext_dmabuf->phys);
3307
lpfc_printf_log(phba, KERN_INFO, LOG_LIBDFC,
3308
"2944 SLI_CONFIG(mse)[%d], "
3309
"bufLen:%d, addrHi:x%x, addrLo:x%x\n",
3311
sli_cfg_mbx->un.sli_config_emb0_subsys.
3313
sli_cfg_mbx->un.sli_config_emb0_subsys.
3315
sli_cfg_mbx->un.sli_config_emb0_subsys.
3320
sli_cfg_mbx->un.sli_config_emb1_subsys.
3322
putPaddrHigh(mbx_dmabuf->phys +
3324
sli_cfg_mbx->un.sli_config_emb1_subsys.
3326
putPaddrLow(mbx_dmabuf->phys +
3328
lpfc_printf_log(phba, KERN_INFO, LOG_LIBDFC,
3329
"3007 SLI_CONFIG(hbd)[%d], "
3330
"bufLen:%d, addrHi:x%x, addrLo:x%x\n",
3332
bsg_bf_get(lpfc_mbox_sli_config_ecmn_hbd_len,
3334
sli_config_emb1_subsys.hbd[index]),
3335
sli_cfg_mbx->un.sli_config_emb1_subsys.
3337
sli_cfg_mbx->un.sli_config_emb1_subsys.
3341
sli_cfg_mbx->un.sli_config_emb1_subsys.
3343
putPaddrHigh(ext_dmabuf->phys);
3344
sli_cfg_mbx->un.sli_config_emb1_subsys.
3346
putPaddrLow(ext_dmabuf->phys);
3347
lpfc_printf_log(phba, KERN_INFO, LOG_LIBDFC,
3348
"3008 SLI_CONFIG(hbd)[%d], "
3349
"bufLen:%d, addrHi:x%x, addrLo:x%x\n",
3351
bsg_bf_get(lpfc_mbox_sli_config_ecmn_hbd_len,
3353
sli_config_emb1_subsys.hbd[index]),
3354
sli_cfg_mbx->un.sli_config_emb1_subsys.
3356
sli_cfg_mbx->un.sli_config_emb1_subsys.
3364
* lpfc_bsg_sli_cfg_mse_read_cmd_ext - sli_config non-embedded mailbox cmd read
3365
* @phba: Pointer to HBA context object.
3366
* @mb: Pointer to a BSG mailbox object.
3367
* @nemb_tp: Enumerate of non-embedded mailbox command type.
3368
* @dmabuff: Pointer to a DMA buffer descriptor.
3370
* This routine performs SLI_CONFIG (0x9B) read mailbox command operation with
3371
* non-embedded external bufffers.
3374
lpfc_bsg_sli_cfg_read_cmd_ext(struct lpfc_hba *phba, struct fc_bsg_job *job,
3375
enum nemb_type nemb_tp,
3376
struct lpfc_dmabuf *dmabuf)
3378
struct lpfc_sli_config_mbox *sli_cfg_mbx;
3379
struct dfc_mbox_req *mbox_req;
3380
struct lpfc_dmabuf *curr_dmabuf, *next_dmabuf;
3381
uint32_t ext_buf_cnt, ext_buf_index;
3382
struct lpfc_dmabuf *ext_dmabuf = NULL;
3383
struct bsg_job_data *dd_data = NULL;
3384
LPFC_MBOXQ_t *pmboxq = NULL;
3390
(struct dfc_mbox_req *)job->request->rqst_data.h_vendor.vendor_cmd;
3392
/* pointer to the start of mailbox command */
3393
sli_cfg_mbx = (struct lpfc_sli_config_mbox *)dmabuf->virt;
3395
if (nemb_tp == nemb_mse) {
3396
ext_buf_cnt = bsg_bf_get(lpfc_mbox_hdr_mse_cnt,
3397
&sli_cfg_mbx->un.sli_config_emb0_subsys.sli_config_hdr);
3398
if (ext_buf_cnt > LPFC_MBX_SLI_CONFIG_MAX_MSE) {
3399
lpfc_printf_log(phba, KERN_ERR, LOG_LIBDFC,
3400
"2945 Handled SLI_CONFIG(mse) rd, "
3401
"ext_buf_cnt(%d) out of range(%d)\n",
3403
LPFC_MBX_SLI_CONFIG_MAX_MSE);
3407
lpfc_printf_log(phba, KERN_INFO, LOG_LIBDFC,
3408
"2941 Handled SLI_CONFIG(mse) rd, "
3409
"ext_buf_cnt:%d\n", ext_buf_cnt);
3411
/* sanity check on interface type for support */
3412
if (bf_get(lpfc_sli_intf_if_type, &phba->sli4_hba.sli_intf) !=
3413
LPFC_SLI_INTF_IF_TYPE_2) {
3417
/* nemb_tp == nemb_hbd */
3418
ext_buf_cnt = sli_cfg_mbx->un.sli_config_emb1_subsys.hbd_count;
3419
if (ext_buf_cnt > LPFC_MBX_SLI_CONFIG_MAX_HBD) {
3420
lpfc_printf_log(phba, KERN_ERR, LOG_LIBDFC,
3421
"2946 Handled SLI_CONFIG(hbd) rd, "
3422
"ext_buf_cnt(%d) out of range(%d)\n",
3424
LPFC_MBX_SLI_CONFIG_MAX_HBD);
3428
lpfc_printf_log(phba, KERN_INFO, LOG_LIBDFC,
3429
"2942 Handled SLI_CONFIG(hbd) rd, "
3430
"ext_buf_cnt:%d\n", ext_buf_cnt);
3433
/* reject non-embedded mailbox command with none external buffer */
3434
if (ext_buf_cnt == 0) {
3437
} else if (ext_buf_cnt > 1) {
3438
/* additional external read buffers */
3439
for (i = 1; i < ext_buf_cnt; i++) {
3440
ext_dmabuf = lpfc_bsg_dma_page_alloc(phba);
3445
list_add_tail(&ext_dmabuf->list,
3446
&phba->mbox_ext_buf_ctx.ext_dmabuf_list);
3450
/* bsg tracking structure */
3451
dd_data = kmalloc(sizeof(struct bsg_job_data), GFP_KERNEL);
3457
/* mailbox command structure for base driver */
3458
pmboxq = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL);
3463
memset(pmboxq, 0, sizeof(LPFC_MBOXQ_t));
3465
/* for the first external buffer */
3466
lpfc_bsg_sli_cfg_dma_desc_setup(phba, nemb_tp, 0, dmabuf, dmabuf);
3468
/* for the rest of external buffer descriptors if any */
3469
if (ext_buf_cnt > 1) {
3471
list_for_each_entry_safe(curr_dmabuf, next_dmabuf,
3472
&phba->mbox_ext_buf_ctx.ext_dmabuf_list, list) {
3473
lpfc_bsg_sli_cfg_dma_desc_setup(phba, nemb_tp,
3474
ext_buf_index, dmabuf,
3480
/* construct base driver mbox command */
3481
pmb = &pmboxq->u.mb;
3482
pmbx = (uint8_t *)dmabuf->virt;
3483
memcpy(pmb, pmbx, sizeof(*pmb));
3484
pmb->mbxOwner = OWN_HOST;
3485
pmboxq->vport = phba->pport;
3487
/* multi-buffer handling context */
3488
phba->mbox_ext_buf_ctx.nembType = nemb_tp;
3489
phba->mbox_ext_buf_ctx.mboxType = mbox_rd;
3490
phba->mbox_ext_buf_ctx.numBuf = ext_buf_cnt;
3491
phba->mbox_ext_buf_ctx.mbxTag = mbox_req->extMboxTag;
3492
phba->mbox_ext_buf_ctx.seqNum = mbox_req->extSeqNum;
3493
phba->mbox_ext_buf_ctx.mbx_dmabuf = dmabuf;
3495
/* callback for multi-buffer read mailbox command */
3496
pmboxq->mbox_cmpl = lpfc_bsg_issue_read_mbox_ext_cmpl;
3498
/* context fields to callback function */
3499
pmboxq->context1 = dd_data;
3500
dd_data->type = TYPE_MBOX;
3501
dd_data->context_un.mbox.pmboxq = pmboxq;
3502
dd_data->context_un.mbox.mb = (MAILBOX_t *)pmbx;
3503
dd_data->context_un.mbox.set_job = job;
3504
job->dd_data = dd_data;
3507
phba->mbox_ext_buf_ctx.state = LPFC_BSG_MBOX_PORT;
3509
rc = lpfc_sli_issue_mbox(phba, pmboxq, MBX_NOWAIT);
3510
if ((rc == MBX_SUCCESS) || (rc == MBX_BUSY)) {
3511
lpfc_printf_log(phba, KERN_INFO, LOG_LIBDFC,
3512
"2947 Issued SLI_CONFIG ext-buffer "
3513
"maibox command, rc:x%x\n", rc);
3516
lpfc_printf_log(phba, KERN_ERR, LOG_LIBDFC,
3517
"2948 Failed to issue SLI_CONFIG ext-buffer "
3518
"maibox command, rc:x%x\n", rc);
3523
mempool_free(pmboxq, phba->mbox_mem_pool);
3524
lpfc_bsg_dma_page_list_free(phba,
3525
&phba->mbox_ext_buf_ctx.ext_dmabuf_list);
3527
phba->mbox_ext_buf_ctx.state = LPFC_BSG_MBOX_IDLE;
3532
* lpfc_bsg_sli_cfg_write_cmd_ext - sli_config non-embedded mailbox cmd write
3533
* @phba: Pointer to HBA context object.
3534
* @mb: Pointer to a BSG mailbox object.
3535
* @dmabuff: Pointer to a DMA buffer descriptor.
3537
* This routine performs SLI_CONFIG (0x9B) write mailbox command operation with
3538
* non-embedded external bufffers.
3541
lpfc_bsg_sli_cfg_write_cmd_ext(struct lpfc_hba *phba, struct fc_bsg_job *job,
3542
enum nemb_type nemb_tp,
3543
struct lpfc_dmabuf *dmabuf)
3545
struct dfc_mbox_req *mbox_req;
3546
struct lpfc_sli_config_mbox *sli_cfg_mbx;
3547
uint32_t ext_buf_cnt;
3548
struct bsg_job_data *dd_data = NULL;
3549
LPFC_MBOXQ_t *pmboxq = NULL;
3555
(struct dfc_mbox_req *)job->request->rqst_data.h_vendor.vendor_cmd;
3557
/* pointer to the start of mailbox command */
3558
sli_cfg_mbx = (struct lpfc_sli_config_mbox *)dmabuf->virt;
3560
if (nemb_tp == nemb_mse) {
3561
ext_buf_cnt = bsg_bf_get(lpfc_mbox_hdr_mse_cnt,
3562
&sli_cfg_mbx->un.sli_config_emb0_subsys.sli_config_hdr);
3563
if (ext_buf_cnt > LPFC_MBX_SLI_CONFIG_MAX_MSE) {
3564
lpfc_printf_log(phba, KERN_ERR, LOG_LIBDFC,
3565
"2953 Handled SLI_CONFIG(mse) wr, "
3566
"ext_buf_cnt(%d) out of range(%d)\n",
3568
LPFC_MBX_SLI_CONFIG_MAX_MSE);
3571
lpfc_printf_log(phba, KERN_INFO, LOG_LIBDFC,
3572
"2949 Handled SLI_CONFIG(mse) wr, "
3573
"ext_buf_cnt:%d\n", ext_buf_cnt);
3575
/* sanity check on interface type for support */
3576
if (bf_get(lpfc_sli_intf_if_type, &phba->sli4_hba.sli_intf) !=
3577
LPFC_SLI_INTF_IF_TYPE_2)
3579
/* nemb_tp == nemb_hbd */
3580
ext_buf_cnt = sli_cfg_mbx->un.sli_config_emb1_subsys.hbd_count;
3581
if (ext_buf_cnt > LPFC_MBX_SLI_CONFIG_MAX_HBD) {
3582
lpfc_printf_log(phba, KERN_ERR, LOG_LIBDFC,
3583
"2954 Handled SLI_CONFIG(hbd) wr, "
3584
"ext_buf_cnt(%d) out of range(%d)\n",
3586
LPFC_MBX_SLI_CONFIG_MAX_HBD);
3589
lpfc_printf_log(phba, KERN_INFO, LOG_LIBDFC,
3590
"2950 Handled SLI_CONFIG(hbd) wr, "
3591
"ext_buf_cnt:%d\n", ext_buf_cnt);
3594
if (ext_buf_cnt == 0)
3597
/* for the first external buffer */
3598
lpfc_bsg_sli_cfg_dma_desc_setup(phba, nemb_tp, 0, dmabuf, dmabuf);
3600
/* log for looking forward */
3601
for (i = 1; i < ext_buf_cnt; i++) {
3602
if (nemb_tp == nemb_mse)
3603
lpfc_printf_log(phba, KERN_INFO, LOG_LIBDFC,
3604
"2951 SLI_CONFIG(mse), buf[%d]-length:%d\n",
3605
i, sli_cfg_mbx->un.sli_config_emb0_subsys.
3608
lpfc_printf_log(phba, KERN_INFO, LOG_LIBDFC,
3609
"2952 SLI_CONFIG(hbd), buf[%d]-length:%d\n",
3610
i, bsg_bf_get(lpfc_mbox_sli_config_ecmn_hbd_len,
3611
&sli_cfg_mbx->un.sli_config_emb1_subsys.
3615
/* multi-buffer handling context */
3616
phba->mbox_ext_buf_ctx.nembType = nemb_tp;
3617
phba->mbox_ext_buf_ctx.mboxType = mbox_wr;
3618
phba->mbox_ext_buf_ctx.numBuf = ext_buf_cnt;
3619
phba->mbox_ext_buf_ctx.mbxTag = mbox_req->extMboxTag;
3620
phba->mbox_ext_buf_ctx.seqNum = mbox_req->extSeqNum;
3621
phba->mbox_ext_buf_ctx.mbx_dmabuf = dmabuf;
3623
if (ext_buf_cnt == 1) {
3624
/* bsg tracking structure */
3625
dd_data = kmalloc(sizeof(struct bsg_job_data), GFP_KERNEL);
3631
/* mailbox command structure for base driver */
3632
pmboxq = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL);
3637
memset(pmboxq, 0, sizeof(LPFC_MBOXQ_t));
3638
pmb = &pmboxq->u.mb;
3639
mbx = (uint8_t *)dmabuf->virt;
3640
memcpy(pmb, mbx, sizeof(*pmb));
3641
pmb->mbxOwner = OWN_HOST;
3642
pmboxq->vport = phba->pport;
3644
/* callback for multi-buffer read mailbox command */
3645
pmboxq->mbox_cmpl = lpfc_bsg_issue_write_mbox_ext_cmpl;
3647
/* context fields to callback function */
3648
pmboxq->context1 = dd_data;
3649
dd_data->type = TYPE_MBOX;
3650
dd_data->context_un.mbox.pmboxq = pmboxq;
3651
dd_data->context_un.mbox.mb = (MAILBOX_t *)mbx;
3652
dd_data->context_un.mbox.set_job = job;
3653
job->dd_data = dd_data;
3656
phba->mbox_ext_buf_ctx.state = LPFC_BSG_MBOX_PORT;
3658
rc = lpfc_sli_issue_mbox(phba, pmboxq, MBX_NOWAIT);
3659
if ((rc == MBX_SUCCESS) || (rc == MBX_BUSY)) {
3660
lpfc_printf_log(phba, KERN_INFO, LOG_LIBDFC,
3661
"2955 Issued SLI_CONFIG ext-buffer "
3662
"maibox command, rc:x%x\n", rc);
3665
lpfc_printf_log(phba, KERN_ERR, LOG_LIBDFC,
3666
"2956 Failed to issue SLI_CONFIG ext-buffer "
3667
"maibox command, rc:x%x\n", rc);
3673
mempool_free(pmboxq, phba->mbox_mem_pool);
3680
* lpfc_bsg_handle_sli_cfg_mbox - handle sli-cfg mailbox cmd with ext buffer
3681
* @phba: Pointer to HBA context object.
3682
* @mb: Pointer to a BSG mailbox object.
3683
* @dmabuff: Pointer to a DMA buffer descriptor.
3685
* This routine handles SLI_CONFIG (0x9B) mailbox command with non-embedded
3686
* external bufffers, including both 0x9B with non-embedded MSEs and 0x9B
3687
* with embedded sussystem 0x1 and opcodes with external HBDs.
3690
lpfc_bsg_handle_sli_cfg_mbox(struct lpfc_hba *phba, struct fc_bsg_job *job,
3691
struct lpfc_dmabuf *dmabuf)
3693
struct lpfc_sli_config_mbox *sli_cfg_mbx;
3696
int rc = SLI_CONFIG_NOT_HANDLED;
3699
phba->mbox_ext_buf_ctx.state = LPFC_BSG_MBOX_HOST;
3701
sli_cfg_mbx = (struct lpfc_sli_config_mbox *)dmabuf->virt;
3703
if (!bsg_bf_get(lpfc_mbox_hdr_emb,
3704
&sli_cfg_mbx->un.sli_config_emb0_subsys.sli_config_hdr)) {
3705
subsys = bsg_bf_get(lpfc_emb0_subcmnd_subsys,
3706
&sli_cfg_mbx->un.sli_config_emb0_subsys);
3707
opcode = bsg_bf_get(lpfc_emb0_subcmnd_opcode,
3708
&sli_cfg_mbx->un.sli_config_emb0_subsys);
3709
if (subsys == SLI_CONFIG_SUBSYS_FCOE) {
3711
case FCOE_OPCODE_READ_FCF:
3712
lpfc_printf_log(phba, KERN_INFO, LOG_LIBDFC,
3713
"2957 Handled SLI_CONFIG "
3714
"subsys_fcoe, opcode:x%x\n",
3716
rc = lpfc_bsg_sli_cfg_read_cmd_ext(phba, job,
3719
case FCOE_OPCODE_ADD_FCF:
3720
lpfc_printf_log(phba, KERN_INFO, LOG_LIBDFC,
3721
"2958 Handled SLI_CONFIG "
3722
"subsys_fcoe, opcode:x%x\n",
3724
rc = lpfc_bsg_sli_cfg_write_cmd_ext(phba, job,
3728
lpfc_printf_log(phba, KERN_INFO, LOG_LIBDFC,
3729
"2959 Not handled SLI_CONFIG "
3730
"subsys_fcoe, opcode:x%x\n",
3732
rc = SLI_CONFIG_NOT_HANDLED;
3736
lpfc_printf_log(phba, KERN_INFO, LOG_LIBDFC,
3737
"2977 Handled SLI_CONFIG "
3738
"subsys:x%d, opcode:x%x\n",
3740
rc = SLI_CONFIG_NOT_HANDLED;
3743
subsys = bsg_bf_get(lpfc_emb1_subcmnd_subsys,
3744
&sli_cfg_mbx->un.sli_config_emb1_subsys);
3745
opcode = bsg_bf_get(lpfc_emb1_subcmnd_opcode,
3746
&sli_cfg_mbx->un.sli_config_emb1_subsys);
3747
if (subsys == SLI_CONFIG_SUBSYS_COMN) {
3749
case COMN_OPCODE_READ_OBJECT:
3750
case COMN_OPCODE_READ_OBJECT_LIST:
3751
lpfc_printf_log(phba, KERN_INFO, LOG_LIBDFC,
3752
"2960 Handled SLI_CONFIG "
3753
"subsys_comn, opcode:x%x\n",
3755
rc = lpfc_bsg_sli_cfg_read_cmd_ext(phba, job,
3758
case COMN_OPCODE_WRITE_OBJECT:
3759
lpfc_printf_log(phba, KERN_INFO, LOG_LIBDFC,
3760
"2961 Handled SLI_CONFIG "
3761
"subsys_comn, opcode:x%x\n",
3763
rc = lpfc_bsg_sli_cfg_write_cmd_ext(phba, job,
3767
lpfc_printf_log(phba, KERN_INFO, LOG_LIBDFC,
3768
"2962 Not handled SLI_CONFIG "
3769
"subsys_comn, opcode:x%x\n",
3771
rc = SLI_CONFIG_NOT_HANDLED;
3775
lpfc_printf_log(phba, KERN_INFO, LOG_LIBDFC,
3776
"2978 Handled SLI_CONFIG "
3777
"subsys:x%d, opcode:x%x\n",
3779
rc = SLI_CONFIG_NOT_HANDLED;
3786
* lpfc_bsg_mbox_ext_abort_req - request to abort mbox command with ext buffers
3787
* @phba: Pointer to HBA context object.
3789
* This routine is for requesting to abort a pass-through mailbox command with
3790
* multiple external buffers due to error condition.
3793
lpfc_bsg_mbox_ext_abort(struct lpfc_hba *phba)
3795
if (phba->mbox_ext_buf_ctx.state == LPFC_BSG_MBOX_PORT)
3796
phba->mbox_ext_buf_ctx.state = LPFC_BSG_MBOX_ABTS;
3798
lpfc_bsg_mbox_ext_session_reset(phba);
3803
* lpfc_bsg_read_ebuf_get - get the next mailbox read external buffer
3804
* @phba: Pointer to HBA context object.
3805
* @dmabuf: Pointer to a DMA buffer descriptor.
3807
* This routine extracts the next mailbox read external buffer back to
3808
* user space through BSG.
3811
lpfc_bsg_read_ebuf_get(struct lpfc_hba *phba, struct fc_bsg_job *job)
3813
struct lpfc_sli_config_mbox *sli_cfg_mbx;
3814
struct lpfc_dmabuf *dmabuf;
3819
index = phba->mbox_ext_buf_ctx.seqNum;
3820
phba->mbox_ext_buf_ctx.seqNum++;
3822
sli_cfg_mbx = (struct lpfc_sli_config_mbox *)
3823
phba->mbox_ext_buf_ctx.mbx_dmabuf->virt;
3825
if (phba->mbox_ext_buf_ctx.nembType == nemb_mse) {
3826
size = bsg_bf_get(lpfc_mbox_sli_config_mse_len,
3827
&sli_cfg_mbx->un.sli_config_emb0_subsys.mse[index]);
3828
lpfc_printf_log(phba, KERN_INFO, LOG_LIBDFC,
3829
"2963 SLI_CONFIG (mse) ext-buffer rd get "
3830
"buffer[%d], size:%d\n", index, size);
3832
size = bsg_bf_get(lpfc_mbox_sli_config_ecmn_hbd_len,
3833
&sli_cfg_mbx->un.sli_config_emb1_subsys.hbd[index]);
3834
lpfc_printf_log(phba, KERN_INFO, LOG_LIBDFC,
3835
"2964 SLI_CONFIG (hbd) ext-buffer rd get "
3836
"buffer[%d], size:%d\n", index, size);
3838
if (list_empty(&phba->mbox_ext_buf_ctx.ext_dmabuf_list))
3840
dmabuf = list_first_entry(&phba->mbox_ext_buf_ctx.ext_dmabuf_list,
3841
struct lpfc_dmabuf, list);
3842
list_del_init(&dmabuf->list);
3843
pbuf = (uint8_t *)dmabuf->virt;
3844
job->reply->reply_payload_rcv_len =
3845
sg_copy_from_buffer(job->reply_payload.sg_list,
3846
job->reply_payload.sg_cnt,
3849
lpfc_bsg_dma_page_free(phba, dmabuf);
3851
if (phba->mbox_ext_buf_ctx.seqNum == phba->mbox_ext_buf_ctx.numBuf) {
3852
lpfc_printf_log(phba, KERN_INFO, LOG_LIBDFC,
3853
"2965 SLI_CONFIG (hbd) ext-buffer rd mbox "
3854
"command session done\n");
3855
lpfc_bsg_mbox_ext_session_reset(phba);
3858
job->reply->result = 0;
3861
return SLI_CONFIG_HANDLED;
3865
* lpfc_bsg_write_ebuf_set - set the next mailbox write external buffer
3866
* @phba: Pointer to HBA context object.
3867
* @dmabuf: Pointer to a DMA buffer descriptor.
3869
* This routine sets up the next mailbox read external buffer obtained
3870
* from user space through BSG.
3873
lpfc_bsg_write_ebuf_set(struct lpfc_hba *phba, struct fc_bsg_job *job,
3874
struct lpfc_dmabuf *dmabuf)
3876
struct lpfc_sli_config_mbox *sli_cfg_mbx;
3877
struct bsg_job_data *dd_data = NULL;
3878
LPFC_MBOXQ_t *pmboxq = NULL;
3880
enum nemb_type nemb_tp;
3886
index = phba->mbox_ext_buf_ctx.seqNum;
3887
phba->mbox_ext_buf_ctx.seqNum++;
3888
nemb_tp = phba->mbox_ext_buf_ctx.nembType;
3890
sli_cfg_mbx = (struct lpfc_sli_config_mbox *)
3891
phba->mbox_ext_buf_ctx.mbx_dmabuf->virt;
3893
dd_data = kmalloc(sizeof(struct bsg_job_data), GFP_KERNEL);
3899
pbuf = (uint8_t *)dmabuf->virt;
3900
size = job->request_payload.payload_len;
3901
sg_copy_to_buffer(job->request_payload.sg_list,
3902
job->request_payload.sg_cnt,
3905
if (phba->mbox_ext_buf_ctx.nembType == nemb_mse) {
3906
lpfc_printf_log(phba, KERN_INFO, LOG_LIBDFC,
3907
"2966 SLI_CONFIG (mse) ext-buffer wr set "
3908
"buffer[%d], size:%d\n",
3909
phba->mbox_ext_buf_ctx.seqNum, size);
3912
lpfc_printf_log(phba, KERN_INFO, LOG_LIBDFC,
3913
"2967 SLI_CONFIG (hbd) ext-buffer wr set "
3914
"buffer[%d], size:%d\n",
3915
phba->mbox_ext_buf_ctx.seqNum, size);
3919
/* set up external buffer descriptor and add to external buffer list */
3920
lpfc_bsg_sli_cfg_dma_desc_setup(phba, nemb_tp, index,
3921
phba->mbox_ext_buf_ctx.mbx_dmabuf,
3923
list_add_tail(&dmabuf->list, &phba->mbox_ext_buf_ctx.ext_dmabuf_list);
3925
if (phba->mbox_ext_buf_ctx.seqNum == phba->mbox_ext_buf_ctx.numBuf) {
3926
lpfc_printf_log(phba, KERN_INFO, LOG_LIBDFC,
3927
"2968 SLI_CONFIG ext-buffer wr all %d "
3928
"ebuffers received\n",
3929
phba->mbox_ext_buf_ctx.numBuf);
3930
/* mailbox command structure for base driver */
3931
pmboxq = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL);
3936
memset(pmboxq, 0, sizeof(LPFC_MBOXQ_t));
3937
pbuf = (uint8_t *)phba->mbox_ext_buf_ctx.mbx_dmabuf->virt;
3938
pmb = &pmboxq->u.mb;
3939
memcpy(pmb, pbuf, sizeof(*pmb));
3940
pmb->mbxOwner = OWN_HOST;
3941
pmboxq->vport = phba->pport;
3943
/* callback for multi-buffer write mailbox command */
3944
pmboxq->mbox_cmpl = lpfc_bsg_issue_write_mbox_ext_cmpl;
3946
/* context fields to callback function */
3947
pmboxq->context1 = dd_data;
3948
dd_data->type = TYPE_MBOX;
3949
dd_data->context_un.mbox.pmboxq = pmboxq;
3950
dd_data->context_un.mbox.mb = (MAILBOX_t *)pbuf;
3951
dd_data->context_un.mbox.set_job = job;
3952
job->dd_data = dd_data;
3955
phba->mbox_ext_buf_ctx.state = LPFC_BSG_MBOX_PORT;
3957
rc = lpfc_sli_issue_mbox(phba, pmboxq, MBX_NOWAIT);
3958
if ((rc == MBX_SUCCESS) || (rc == MBX_BUSY)) {
3959
lpfc_printf_log(phba, KERN_INFO, LOG_LIBDFC,
3960
"2969 Issued SLI_CONFIG ext-buffer "
3961
"maibox command, rc:x%x\n", rc);
3964
lpfc_printf_log(phba, KERN_ERR, LOG_LIBDFC,
3965
"2970 Failed to issue SLI_CONFIG ext-buffer "
3966
"maibox command, rc:x%x\n", rc);
3971
/* wait for additoinal external buffers */
3972
job->reply->result = 0;
3974
return SLI_CONFIG_HANDLED;
3977
lpfc_bsg_dma_page_free(phba, dmabuf);
3984
* lpfc_bsg_handle_sli_cfg_ebuf - handle ext buffer with sli-cfg mailbox cmd
3985
* @phba: Pointer to HBA context object.
3986
* @mb: Pointer to a BSG mailbox object.
3987
* @dmabuff: Pointer to a DMA buffer descriptor.
3989
* This routine handles the external buffer with SLI_CONFIG (0x9B) mailbox
3990
* command with multiple non-embedded external buffers.
3993
lpfc_bsg_handle_sli_cfg_ebuf(struct lpfc_hba *phba, struct fc_bsg_job *job,
3994
struct lpfc_dmabuf *dmabuf)
3998
lpfc_printf_log(phba, KERN_INFO, LOG_LIBDFC,
3999
"2971 SLI_CONFIG buffer (type:x%x)\n",
4000
phba->mbox_ext_buf_ctx.mboxType);
4002
if (phba->mbox_ext_buf_ctx.mboxType == mbox_rd) {
4003
if (phba->mbox_ext_buf_ctx.state != LPFC_BSG_MBOX_DONE) {
4004
lpfc_printf_log(phba, KERN_ERR, LOG_LIBDFC,
4005
"2972 SLI_CONFIG rd buffer state "
4007
phba->mbox_ext_buf_ctx.state);
4008
lpfc_bsg_mbox_ext_abort(phba);
4011
rc = lpfc_bsg_read_ebuf_get(phba, job);
4012
if (rc == SLI_CONFIG_HANDLED)
4013
lpfc_bsg_dma_page_free(phba, dmabuf);
4014
} else { /* phba->mbox_ext_buf_ctx.mboxType == mbox_wr */
4015
if (phba->mbox_ext_buf_ctx.state != LPFC_BSG_MBOX_HOST) {
4016
lpfc_printf_log(phba, KERN_ERR, LOG_LIBDFC,
4017
"2973 SLI_CONFIG wr buffer state "
4019
phba->mbox_ext_buf_ctx.state);
4020
lpfc_bsg_mbox_ext_abort(phba);
4023
rc = lpfc_bsg_write_ebuf_set(phba, job, dmabuf);
4029
* lpfc_bsg_handle_sli_cfg_ext - handle sli-cfg mailbox with external buffer
4030
* @phba: Pointer to HBA context object.
4031
* @mb: Pointer to a BSG mailbox object.
4032
* @dmabuff: Pointer to a DMA buffer descriptor.
4034
* This routine checkes and handles non-embedded multi-buffer SLI_CONFIG
4035
* (0x9B) mailbox commands and external buffers.
4038
lpfc_bsg_handle_sli_cfg_ext(struct lpfc_hba *phba, struct fc_bsg_job *job,
4039
struct lpfc_dmabuf *dmabuf)
4041
struct dfc_mbox_req *mbox_req;
4045
(struct dfc_mbox_req *)job->request->rqst_data.h_vendor.vendor_cmd;
4047
/* mbox command with/without single external buffer */
4048
if (mbox_req->extMboxTag == 0 && mbox_req->extSeqNum == 0)
4049
return SLI_CONFIG_NOT_HANDLED;
4051
/* mbox command and first external buffer */
4052
if (phba->mbox_ext_buf_ctx.state == LPFC_BSG_MBOX_IDLE) {
4053
if (mbox_req->extSeqNum == 1) {
4054
lpfc_printf_log(phba, KERN_INFO, LOG_LIBDFC,
4055
"2974 SLI_CONFIG mailbox: tag:%d, "
4056
"seq:%d\n", mbox_req->extMboxTag,
4057
mbox_req->extSeqNum);
4058
rc = lpfc_bsg_handle_sli_cfg_mbox(phba, job, dmabuf);
4061
goto sli_cfg_ext_error;
4065
* handle additional external buffers
4068
/* check broken pipe conditions */
4069
if (mbox_req->extMboxTag != phba->mbox_ext_buf_ctx.mbxTag)
4070
goto sli_cfg_ext_error;
4071
if (mbox_req->extSeqNum > phba->mbox_ext_buf_ctx.numBuf)
4072
goto sli_cfg_ext_error;
4073
if (mbox_req->extSeqNum != phba->mbox_ext_buf_ctx.seqNum + 1)
4074
goto sli_cfg_ext_error;
4076
lpfc_printf_log(phba, KERN_INFO, LOG_LIBDFC,
4077
"2975 SLI_CONFIG mailbox external buffer: "
4078
"extSta:x%x, tag:%d, seq:%d\n",
4079
phba->mbox_ext_buf_ctx.state, mbox_req->extMboxTag,
4080
mbox_req->extSeqNum);
4081
rc = lpfc_bsg_handle_sli_cfg_ebuf(phba, job, dmabuf);
4085
/* all other cases, broken pipe */
4086
lpfc_printf_log(phba, KERN_ERR, LOG_LIBDFC,
4087
"2976 SLI_CONFIG mailbox broken pipe: "
4088
"ctxSta:x%x, ctxNumBuf:%d "
4089
"ctxTag:%d, ctxSeq:%d, tag:%d, seq:%d\n",
4090
phba->mbox_ext_buf_ctx.state,
4091
phba->mbox_ext_buf_ctx.numBuf,
4092
phba->mbox_ext_buf_ctx.mbxTag,
4093
phba->mbox_ext_buf_ctx.seqNum,
4094
mbox_req->extMboxTag, mbox_req->extSeqNum);
4096
lpfc_bsg_mbox_ext_session_reset(phba);
2620
4102
* lpfc_bsg_issue_mbox - issues a mailbox command on behalf of an app
2621
4103
* @phba: Pointer to HBA context object.
2622
4104
* @mb: Pointer to a mailbox object.