2009-09-05 06:06:35 +04:00
/**
2015-07-04 01:42:33 +03:00
* Copyright ( C ) 2005 - 2015 Emulex
2009-09-05 06:06:35 +04:00
* All rights reserved .
*
* This program is free software ; you can redistribute it and / or
* modify it under the terms of the GNU General Public License version 2
* as published by the Free Software Foundation . The full GNU General
* Public License is included in this distribution in the file called COPYING .
*
2015-05-15 09:16:17 +03:00
* Written by : Jayamohan Kallickal ( jayamohan . kallickal @ avagotech . com )
2009-09-05 06:06:35 +04:00
*
* Contact Information :
2015-05-15 09:16:17 +03:00
* linux - drivers @ avagotech . com
2009-09-05 06:06:35 +04:00
*
2015-07-04 01:42:33 +03:00
* Emulex
2011-03-26 00:23:57 +03:00
* 3333 Susan Street
* Costa Mesa , CA 92626
2009-09-05 06:06:35 +04:00
*/
2012-04-04 08:41:50 +04:00
# include <linux/bsg-lib.h>
# include <scsi/scsi_transport_iscsi.h>
# include <scsi/scsi_bsg_iscsi.h>
2009-09-05 06:06:35 +04:00
# include "be_mgmt.h"
# include "be_iscsi.h"
2012-10-20 03:15:51 +04:00
# include "be_main.h"
/* UE Status Low CSR */
static const char * const desc_ue_status_low [ ] = {
" CEV " ,
" CTX " ,
" DBUF " ,
" ERX " ,
" Host " ,
" MPU " ,
" NDMA " ,
" PTC " ,
" RDMA " ,
" RXF " ,
" RXIPS " ,
" RXULP0 " ,
" RXULP1 " ,
" RXULP2 " ,
" TIM " ,
" TPOST " ,
" TPRE " ,
" TXIPS " ,
" TXULP0 " ,
" TXULP1 " ,
" UC " ,
" WDMA " ,
" TXULP2 " ,
" HOST1 " ,
" P0_OB_LINK " ,
" P1_OB_LINK " ,
" HOST_GPIO " ,
" MBOX " ,
" AXGMAC0 " ,
" AXGMAC1 " ,
" JTAG " ,
" MPU_INTPEND "
} ;
/* UE Status High CSR */
static const char * const desc_ue_status_hi [ ] = {
" LPCMEMHOST " ,
" MGMT_MAC " ,
" PCS0ONLINE " ,
" MPU_IRAM " ,
" PCS1ONLINE " ,
" PCTL0 " ,
" PCTL1 " ,
" PMEM " ,
" RR " ,
" TXPB " ,
" RXPP " ,
" XAUI " ,
" TXP " ,
" ARM " ,
" IPC " ,
" HOST2 " ,
" HOST3 " ,
" HOST4 " ,
" HOST5 " ,
" HOST6 " ,
" HOST7 " ,
" HOST8 " ,
" HOST9 " ,
" NETC " ,
" Unknown " ,
" Unknown " ,
" Unknown " ,
" Unknown " ,
" Unknown " ,
" Unknown " ,
" Unknown " ,
" Unknown "
} ;
/*
* beiscsi_ue_detec ( ) - Detect Unrecoverable Error on adapter
* @ phba : Driver priv structure
*
* Read registers linked to UE and check for the UE status
* */
void beiscsi_ue_detect ( struct beiscsi_hba * phba )
{
uint32_t ue_hi = 0 , ue_lo = 0 ;
uint32_t ue_mask_hi = 0 , ue_mask_lo = 0 ;
uint8_t i = 0 ;
if ( phba - > ue_detected )
return ;
pci_read_config_dword ( phba - > pcidev ,
PCICFG_UE_STATUS_LOW , & ue_lo ) ;
pci_read_config_dword ( phba - > pcidev ,
PCICFG_UE_STATUS_MASK_LOW ,
& ue_mask_lo ) ;
pci_read_config_dword ( phba - > pcidev ,
PCICFG_UE_STATUS_HIGH ,
& ue_hi ) ;
pci_read_config_dword ( phba - > pcidev ,
PCICFG_UE_STATUS_MASK_HI ,
& ue_mask_hi ) ;
ue_lo = ( ue_lo & ~ ue_mask_lo ) ;
ue_hi = ( ue_hi & ~ ue_mask_hi ) ;
if ( ue_lo | | ue_hi ) {
phba - > ue_detected = true ;
beiscsi_log ( phba , KERN_ERR ,
BEISCSI_LOG_CONFIG | BEISCSI_LOG_MBOX ,
" BG_%d : Error detected on the adapter \n " ) ;
}
if ( ue_lo ) {
for ( i = 0 ; ue_lo ; ue_lo > > = 1 , i + + ) {
if ( ue_lo & 1 )
beiscsi_log ( phba , KERN_ERR ,
BEISCSI_LOG_CONFIG ,
" BG_%d : UE_LOW %s bit set \n " ,
desc_ue_status_low [ i ] ) ;
}
}
if ( ue_hi ) {
for ( i = 0 ; ue_hi ; ue_hi > > = 1 , i + + ) {
if ( ue_hi & 1 )
beiscsi_log ( phba , KERN_ERR ,
BEISCSI_LOG_CONFIG ,
" BG_%d : UE_HIGH %s bit set \n " ,
desc_ue_status_hi [ i ] ) ;
}
}
}
2010-07-22 02:59:18 +04:00
2014-05-06 05:41:26 +04:00
int be_cmd_modify_eq_delay ( struct beiscsi_hba * phba ,
struct be_set_eqd * set_eqd , int num )
{
struct be_ctrl_info * ctrl = & phba - > ctrl ;
struct be_mcc_wrb * wrb ;
struct be_cmd_req_modify_eq_delay * req ;
2016-02-04 13:19:17 +03:00
unsigned int tag ;
2014-05-06 05:41:26 +04:00
int i ;
2016-01-20 11:40:46 +03:00
mutex_lock ( & ctrl - > mbox_lock ) ;
2016-02-04 13:19:17 +03:00
wrb = alloc_mcc_wrb ( phba , & tag ) ;
if ( ! wrb ) {
2016-01-20 11:40:46 +03:00
mutex_unlock ( & ctrl - > mbox_lock ) ;
2016-02-04 13:19:17 +03:00
return 0 ;
2014-05-06 05:41:26 +04:00
}
req = embedded_payload ( wrb ) ;
be_wrb_hdr_prepare ( wrb , sizeof ( * req ) , true , 0 ) ;
be_cmd_hdr_prepare ( & req - > hdr , CMD_SUBSYSTEM_COMMON ,
OPCODE_COMMON_MODIFY_EQ_DELAY , sizeof ( * req ) ) ;
req - > num_eq = cpu_to_le32 ( num ) ;
for ( i = 0 ; i < num ; i + + ) {
req - > delay [ i ] . eq_id = cpu_to_le32 ( set_eqd [ i ] . eq_id ) ;
req - > delay [ i ] . phase = 0 ;
req - > delay [ i ] . delay_multiplier =
cpu_to_le32 ( set_eqd [ i ] . delay_multiplier ) ;
}
2016-01-20 11:40:47 +03:00
be_mcc_notify ( phba , tag ) ;
2016-01-20 11:40:46 +03:00
mutex_unlock ( & ctrl - > mbox_lock ) ;
2014-05-06 05:41:26 +04:00
return tag ;
}
2012-08-20 21:30:08 +04:00
/**
* mgmt_reopen_session ( ) - Reopen a session based on reopen_type
* @ phba : Device priv structure instance
* @ reopen_type : Type of reopen_session FW should do .
* @ sess_handle : Session Handle of the session to be re - opened
*
* return
* the TAG used for MBOX Command
*
* */
unsigned int mgmt_reopen_session ( struct beiscsi_hba * phba ,
unsigned int reopen_type ,
unsigned int sess_handle )
{
struct be_ctrl_info * ctrl = & phba - > ctrl ;
struct be_mcc_wrb * wrb ;
struct be_cmd_reopen_session_req * req ;
2016-02-04 13:19:17 +03:00
unsigned int tag ;
2012-08-20 21:30:08 +04:00
2012-08-20 21:30:18 +04:00
beiscsi_log ( phba , KERN_INFO ,
BEISCSI_LOG_CONFIG | BEISCSI_LOG_MBOX ,
" BG_%d : In bescsi_get_boot_target \n " ) ;
2016-01-20 11:40:46 +03:00
mutex_lock ( & ctrl - > mbox_lock ) ;
2016-02-04 13:19:17 +03:00
wrb = alloc_mcc_wrb ( phba , & tag ) ;
if ( ! wrb ) {
2016-01-20 11:40:46 +03:00
mutex_unlock ( & ctrl - > mbox_lock ) ;
2016-02-04 13:19:17 +03:00
return 0 ;
2012-08-20 21:30:08 +04:00
}
req = embedded_payload ( wrb ) ;
be_wrb_hdr_prepare ( wrb , sizeof ( * req ) , true , 0 ) ;
be_cmd_hdr_prepare ( & req - > hdr , CMD_SUBSYSTEM_ISCSI_INI ,
OPCODE_ISCSI_INI_DRIVER_REOPEN_ALL_SESSIONS ,
sizeof ( struct be_cmd_reopen_session_resp ) ) ;
/* set the reopen_type,sess_handle */
req - > reopen_type = reopen_type ;
req - > session_handle = sess_handle ;
2016-01-20 11:40:47 +03:00
be_mcc_notify ( phba , tag ) ;
2016-01-20 11:40:46 +03:00
mutex_unlock ( & ctrl - > mbox_lock ) ;
2012-08-20 21:30:08 +04:00
return tag ;
}
2012-04-04 08:41:51 +04:00
unsigned int mgmt_get_boot_target ( struct beiscsi_hba * phba )
2010-07-22 02:59:18 +04:00
{
struct be_ctrl_info * ctrl = & phba - > ctrl ;
struct be_mcc_wrb * wrb ;
2012-04-04 08:41:51 +04:00
struct be_cmd_get_boot_target_req * req ;
2016-02-04 13:19:17 +03:00
unsigned int tag ;
2010-07-22 02:59:18 +04:00
2012-08-20 21:30:18 +04:00
beiscsi_log ( phba , KERN_INFO ,
BEISCSI_LOG_CONFIG | BEISCSI_LOG_MBOX ,
" BG_%d : In bescsi_get_boot_target \n " ) ;
2016-01-20 11:40:46 +03:00
mutex_lock ( & ctrl - > mbox_lock ) ;
2016-02-04 13:19:17 +03:00
wrb = alloc_mcc_wrb ( phba , & tag ) ;
if ( ! wrb ) {
2016-01-20 11:40:46 +03:00
mutex_unlock ( & ctrl - > mbox_lock ) ;
2016-02-04 13:19:17 +03:00
return 0 ;
2010-07-22 02:59:18 +04:00
}
req = embedded_payload ( wrb ) ;
be_wrb_hdr_prepare ( wrb , sizeof ( * req ) , true , 0 ) ;
be_cmd_hdr_prepare ( & req - > hdr , CMD_SUBSYSTEM_ISCSI_INI ,
OPCODE_ISCSI_INI_BOOT_GET_BOOT_TARGET ,
2012-04-04 08:41:51 +04:00
sizeof ( struct be_cmd_get_boot_target_resp ) ) ;
2010-07-22 02:59:18 +04:00
2016-01-20 11:40:47 +03:00
be_mcc_notify ( phba , tag ) ;
2016-01-20 11:40:46 +03:00
mutex_unlock ( & ctrl - > mbox_lock ) ;
2010-07-22 02:59:18 +04:00
return tag ;
}
2012-04-04 08:41:51 +04:00
unsigned int mgmt_get_session_info ( struct beiscsi_hba * phba ,
u32 boot_session_handle ,
struct be_dma_mem * nonemb_cmd )
2010-07-22 02:59:18 +04:00
{
struct be_ctrl_info * ctrl = & phba - > ctrl ;
struct be_mcc_wrb * wrb ;
2016-02-04 13:19:17 +03:00
unsigned int tag ;
2012-04-04 08:41:51 +04:00
struct be_cmd_get_session_req * req ;
struct be_cmd_get_session_resp * resp ;
2010-07-22 02:59:18 +04:00
struct be_sge * sge ;
2012-08-20 21:30:18 +04:00
beiscsi_log ( phba , KERN_INFO ,
BEISCSI_LOG_CONFIG | BEISCSI_LOG_MBOX ,
" BG_%d : In beiscsi_get_session_info \n " ) ;
2016-01-20 11:40:46 +03:00
mutex_lock ( & ctrl - > mbox_lock ) ;
2016-02-04 13:19:17 +03:00
wrb = alloc_mcc_wrb ( phba , & tag ) ;
if ( ! wrb ) {
2016-01-20 11:40:46 +03:00
mutex_unlock ( & ctrl - > mbox_lock ) ;
2016-02-04 13:19:17 +03:00
return 0 ;
2010-07-22 02:59:18 +04:00
}
nonemb_cmd - > size = sizeof ( * resp ) ;
req = nonemb_cmd - > va ;
memset ( req , 0 , sizeof ( * req ) ) ;
sge = nonembedded_sgl ( wrb ) ;
be_wrb_hdr_prepare ( wrb , sizeof ( * req ) , false , 1 ) ;
be_cmd_hdr_prepare ( & req - > hdr , CMD_SUBSYSTEM_ISCSI_INI ,
OPCODE_ISCSI_INI_SESSION_GET_A_SESSION ,
sizeof ( * resp ) ) ;
req - > session_handle = boot_session_handle ;
sge - > pa_hi = cpu_to_le32 ( upper_32_bits ( nonemb_cmd - > dma ) ) ;
sge - > pa_lo = cpu_to_le32 ( nonemb_cmd - > dma & 0xFFFFFFFF ) ;
sge - > len = cpu_to_le32 ( nonemb_cmd - > size ) ;
2016-01-20 11:40:47 +03:00
be_mcc_notify ( phba , tag ) ;
2016-01-20 11:40:46 +03:00
mutex_unlock ( & ctrl - > mbox_lock ) ;
2010-07-22 02:59:18 +04:00
return tag ;
}
2009-09-05 06:06:35 +04:00
2016-01-20 11:40:53 +03:00
/**
* mgmt_get_port_name ( ) - Get port name for the function
* @ ctrl : ptr to Ctrl Info
* @ phba : ptr to the dev priv structure
*
* Get the alphanumeric character for port
*
* */
int mgmt_get_port_name ( struct be_ctrl_info * ctrl ,
struct beiscsi_hba * phba )
{
int ret = 0 ;
struct be_mcc_wrb * wrb ;
struct be_cmd_get_port_name * ioctl ;
mutex_lock ( & ctrl - > mbox_lock ) ;
wrb = wrb_from_mbox ( & ctrl - > mbox_mem ) ;
memset ( wrb , 0 , sizeof ( * wrb ) ) ;
ioctl = embedded_payload ( wrb ) ;
be_wrb_hdr_prepare ( wrb , sizeof ( * ioctl ) , true , 0 ) ;
be_cmd_hdr_prepare ( & ioctl - > h . req_hdr , CMD_SUBSYSTEM_COMMON ,
OPCODE_COMMON_GET_PORT_NAME ,
EMBED_MBX_MAX_PAYLOAD_SIZE ) ;
ret = be_mbox_notify ( ctrl ) ;
phba - > port_name = 0 ;
if ( ! ret ) {
phba - > port_name = ioctl - > p . resp . port_names > >
( phba - > fw_config . phys_port * 8 ) & 0xff ;
} else {
beiscsi_log ( phba , KERN_INFO , BEISCSI_LOG_INIT ,
" BG_%d : GET_PORT_NAME ret 0x%x status 0x%x \n " ,
ret , ioctl - > h . resp_hdr . status ) ;
}
if ( phba - > port_name = = 0 )
phba - > port_name = ' ? ' ;
mutex_unlock ( & ctrl - > mbox_lock ) ;
return ret ;
}
2013-09-29 02:35:44 +04:00
/**
* mgmt_get_fw_config ( ) - Get the FW config for the function
* @ ctrl : ptr to Ctrl Info
* @ phba : ptr to the dev priv structure
*
* Get the FW config and resources available for the function .
* The resources are created based on the count received here .
*
* return
* Success : 0
* Failure : Non - Zero Value
* */
2010-07-22 02:47:16 +04:00
int mgmt_get_fw_config ( struct be_ctrl_info * ctrl ,
2009-09-05 06:06:35 +04:00
struct beiscsi_hba * phba )
{
struct be_mcc_wrb * wrb = wrb_from_mbox ( & ctrl - > mbox_mem ) ;
2016-01-20 11:40:54 +03:00
struct be_fw_cfg * pfw_cfg = embedded_payload ( wrb ) ;
uint32_t cid_count , icd_count ;
int status = - EINVAL ;
uint8_t ulp_num = 0 ;
2009-09-05 06:06:35 +04:00
2016-01-20 11:40:46 +03:00
mutex_lock ( & ctrl - > mbox_lock ) ;
2009-09-05 06:06:35 +04:00
memset ( wrb , 0 , sizeof ( * wrb ) ) ;
2016-01-20 11:40:54 +03:00
be_wrb_hdr_prepare ( wrb , sizeof ( * pfw_cfg ) , true , 0 ) ;
2009-09-05 06:06:35 +04:00
2016-01-20 11:40:54 +03:00
be_cmd_hdr_prepare ( & pfw_cfg - > hdr , CMD_SUBSYSTEM_COMMON ,
2013-09-29 02:35:44 +04:00
OPCODE_COMMON_QUERY_FIRMWARE_CONFIG ,
EMBED_MBX_MAX_PAYLOAD_SIZE ) ;
2016-01-20 11:40:54 +03:00
if ( be_mbox_notify ( ctrl ) ) {
beiscsi_log ( phba , KERN_ERR , BEISCSI_LOG_INIT ,
" BG_%d : Failed in mgmt_get_fw_config \n " ) ;
goto fail_init ;
}
/* FW response formats depend on port id */
phba - > fw_config . phys_port = pfw_cfg - > phys_port ;
if ( phba - > fw_config . phys_port > = BEISCSI_PHYS_PORT_MAX ) {
beiscsi_log ( phba , KERN_ERR , BEISCSI_LOG_INIT ,
" BG_%d : invalid physical port id %d \n " ,
phba - > fw_config . phys_port ) ;
goto fail_init ;
}
/* populate and check FW config against min and max values */
if ( ! is_chip_be2_be3r ( phba ) ) {
phba - > fw_config . eqid_count = pfw_cfg - > eqid_count ;
phba - > fw_config . cqid_count = pfw_cfg - > cqid_count ;
if ( phba - > fw_config . eqid_count = = 0 | |
phba - > fw_config . eqid_count > 2048 ) {
beiscsi_log ( phba , KERN_ERR , BEISCSI_LOG_INIT ,
" BG_%d : invalid EQ count %d \n " ,
phba - > fw_config . eqid_count ) ;
goto fail_init ;
}
if ( phba - > fw_config . cqid_count = = 0 | |
phba - > fw_config . cqid_count > 4096 ) {
beiscsi_log ( phba , KERN_ERR , BEISCSI_LOG_INIT ,
" BG_%d : invalid CQ count %d \n " ,
2013-09-29 02:35:54 +04:00
phba - > fw_config . cqid_count ) ;
2016-01-20 11:40:54 +03:00
goto fail_init ;
2013-09-29 02:35:54 +04:00
}
2016-01-20 11:40:54 +03:00
beiscsi_log ( phba , KERN_INFO , BEISCSI_LOG_INIT ,
" BG_%d : EQ_Count : %d CQ_Count : %d \n " ,
phba - > fw_config . eqid_count ,
phba - > fw_config . cqid_count ) ;
}
2013-09-29 02:35:54 +04:00
2016-01-20 11:40:54 +03:00
/**
* Check on which all ULP iSCSI Protocol is loaded .
* Set the Bit for those ULP . This set flag is used
* at all places in the code to check on which ULP
* iSCSi Protocol is loaded
* */
for ( ulp_num = 0 ; ulp_num < BEISCSI_ULP_COUNT ; ulp_num + + ) {
if ( pfw_cfg - > ulp [ ulp_num ] . ulp_mode &
BEISCSI_ULP_ISCSI_INI_MODE ) {
set_bit ( ulp_num , & phba - > fw_config . ulp_supported ) ;
/* Get the CID, ICD and Chain count for each ULP */
phba - > fw_config . iscsi_cid_start [ ulp_num ] =
pfw_cfg - > ulp [ ulp_num ] . sq_base ;
phba - > fw_config . iscsi_cid_count [ ulp_num ] =
pfw_cfg - > ulp [ ulp_num ] . sq_count ;
phba - > fw_config . iscsi_icd_start [ ulp_num ] =
pfw_cfg - > ulp [ ulp_num ] . icd_base ;
phba - > fw_config . iscsi_icd_count [ ulp_num ] =
pfw_cfg - > ulp [ ulp_num ] . icd_count ;
phba - > fw_config . iscsi_chain_start [ ulp_num ] =
pfw_cfg - > chain_icd [ ulp_num ] . chain_base ;
phba - > fw_config . iscsi_chain_count [ ulp_num ] =
pfw_cfg - > chain_icd [ ulp_num ] . chain_count ;
beiscsi_log ( phba , KERN_INFO , BEISCSI_LOG_INIT ,
" BG_%d : Function loaded on ULP : %d \n "
" \t iscsi_cid_count : %d \n "
" \t iscsi_cid_start : %d \n "
" \t iscsi_icd_count : %d \n "
" \t iscsi_icd_start : %d \n " ,
ulp_num ,
phba - > fw_config .
iscsi_cid_count [ ulp_num ] ,
phba - > fw_config .
iscsi_cid_start [ ulp_num ] ,
phba - > fw_config .
iscsi_icd_count [ ulp_num ] ,
phba - > fw_config .
iscsi_icd_start [ ulp_num ] ) ;
2010-01-05 02:34:12 +03:00
}
2016-01-20 11:40:54 +03:00
}
2013-09-29 02:35:44 +04:00
2016-01-20 11:40:54 +03:00
if ( phba - > fw_config . ulp_supported = = 0 ) {
beiscsi_log ( phba , KERN_ERR , BEISCSI_LOG_INIT ,
" BG_%d : iSCSI initiator mode not set: ULP0 %x ULP1 %x \n " ,
pfw_cfg - > ulp [ BEISCSI_ULP0 ] . ulp_mode ,
pfw_cfg - > ulp [ BEISCSI_ULP1 ] . ulp_mode ) ;
goto fail_init ;
}
2013-09-29 02:35:44 +04:00
2016-01-20 11:40:54 +03:00
/**
* ICD is shared among ULPs . Use icd_count of any one loaded ULP
* */
for ( ulp_num = 0 ; ulp_num < BEISCSI_ULP_COUNT ; ulp_num + + )
if ( test_bit ( ulp_num , & phba - > fw_config . ulp_supported ) )
break ;
icd_count = phba - > fw_config . iscsi_icd_count [ ulp_num ] ;
if ( icd_count = = 0 | | icd_count > 65536 ) {
beiscsi_log ( phba , KERN_ERR , BEISCSI_LOG_INIT ,
" BG_%d: invalid ICD count %d \n " , icd_count ) ;
goto fail_init ;
}
2013-09-29 02:35:44 +04:00
2016-01-20 11:40:54 +03:00
cid_count = BEISCSI_GET_CID_COUNT ( phba , BEISCSI_ULP0 ) +
BEISCSI_GET_CID_COUNT ( phba , BEISCSI_ULP1 ) ;
if ( cid_count = = 0 | | cid_count > 4096 ) {
2013-09-29 02:35:44 +04:00
beiscsi_log ( phba , KERN_ERR , BEISCSI_LOG_INIT ,
2016-01-20 11:40:54 +03:00
" BG_%d: invalid CID count %d \n " , cid_count ) ;
goto fail_init ;
2009-09-05 06:06:35 +04:00
}
2016-01-20 11:40:54 +03:00
/**
* Check FW is dual ULP aware i . e . can handle either
* of the protocols .
*/
phba - > fw_config . dual_ulp_aware = ( pfw_cfg - > function_mode &
BEISCSI_FUNC_DUA_MODE ) ;
beiscsi_log ( phba , KERN_INFO , BEISCSI_LOG_INIT ,
" BG_%d : DUA Mode : 0x%x \n " ,
phba - > fw_config . dual_ulp_aware ) ;
/* all set, continue using this FW config */
status = 0 ;
fail_init :
2016-01-20 11:40:46 +03:00
mutex_unlock ( & ctrl - > mbox_lock ) ;
2009-09-05 06:06:35 +04:00
return status ;
}
2010-07-22 02:47:16 +04:00
int mgmt_check_supported_fw ( struct be_ctrl_info * ctrl ,
2009-10-23 10:22:33 +04:00
struct beiscsi_hba * phba )
2009-09-05 06:06:35 +04:00
{
struct be_dma_mem nonemb_cmd ;
struct be_mcc_wrb * wrb = wrb_from_mbox ( & ctrl - > mbox_mem ) ;
struct be_mgmt_controller_attributes * req ;
struct be_sge * sge = nonembedded_sgl ( wrb ) ;
int status = 0 ;
nonemb_cmd . va = pci_alloc_consistent ( ctrl - > pdev ,
sizeof ( struct be_mgmt_controller_attributes ) ,
& nonemb_cmd . dma ) ;
if ( nonemb_cmd . va = = NULL ) {
2012-08-20 21:30:18 +04:00
beiscsi_log ( phba , KERN_ERR , BEISCSI_LOG_INIT ,
" BG_%d : Failed to allocate memory for "
" mgmt_check_supported_fw \n " ) ;
2010-07-22 02:46:38 +04:00
return - ENOMEM ;
2009-09-05 06:06:35 +04:00
}
nonemb_cmd . size = sizeof ( struct be_mgmt_controller_attributes ) ;
req = nonemb_cmd . va ;
2010-02-11 02:41:15 +03:00
memset ( req , 0 , sizeof ( * req ) ) ;
2016-01-20 11:40:46 +03:00
mutex_lock ( & ctrl - > mbox_lock ) ;
2009-09-05 06:06:35 +04:00
memset ( wrb , 0 , sizeof ( * wrb ) ) ;
be_wrb_hdr_prepare ( wrb , sizeof ( * req ) , false , 1 ) ;
be_cmd_hdr_prepare ( & req - > hdr , CMD_SUBSYSTEM_COMMON ,
OPCODE_COMMON_GET_CNTL_ATTRIBUTES , sizeof ( * req ) ) ;
sge - > pa_hi = cpu_to_le32 ( upper_32_bits ( nonemb_cmd . dma ) ) ;
sge - > pa_lo = cpu_to_le32 ( nonemb_cmd . dma & 0xFFFFFFFF ) ;
sge - > len = cpu_to_le32 ( nonemb_cmd . size ) ;
status = be_mbox_notify ( ctrl ) ;
if ( ! status ) {
struct be_mgmt_controller_attributes_resp * resp = nonemb_cmd . va ;
2012-08-20 21:30:18 +04:00
beiscsi_log ( phba , KERN_INFO , BEISCSI_LOG_INIT ,
" BG_%d : Firmware Version of CMD : %s \n "
" Firmware Version is : %s \n "
" Developer Build, not performing version check... \n " ,
resp - > params . hba_attribs
. flashrom_version_string ,
resp - > params . hba_attribs .
firmware_version_string ) ;
2009-10-23 10:22:33 +04:00
phba - > fw_config . iscsi_features =
resp - > params . hba_attribs . iscsi_features ;
2012-08-20 21:30:18 +04:00
beiscsi_log ( phba , KERN_INFO , BEISCSI_LOG_INIT ,
" BM_%d : phba->fw_config.iscsi_features = %d \n " ,
phba - > fw_config . iscsi_features ) ;
2013-04-06 07:38:28 +04:00
memcpy ( phba - > fw_ver_str , resp - > params . hba_attribs .
firmware_version_string , BEISCSI_VER_STRLEN ) ;
2009-09-05 06:06:35 +04:00
} else
2012-08-20 21:30:18 +04:00
beiscsi_log ( phba , KERN_ERR , BEISCSI_LOG_INIT ,
" BG_%d : Failed in mgmt_check_supported_fw \n " ) ;
2016-01-20 11:40:46 +03:00
mutex_unlock ( & ctrl - > mbox_lock ) ;
2009-09-05 06:06:35 +04:00
if ( nonemb_cmd . va )
pci_free_consistent ( ctrl - > pdev , nonemb_cmd . size ,
nonemb_cmd . va , nonemb_cmd . dma ) ;
return status ;
}
2012-04-04 08:41:50 +04:00
unsigned int mgmt_vendor_specific_fw_cmd ( struct be_ctrl_info * ctrl ,
struct beiscsi_hba * phba ,
struct bsg_job * job ,
struct be_dma_mem * nonemb_cmd )
{
struct be_cmd_resp_hdr * resp ;
2014-05-06 05:41:24 +04:00
struct be_mcc_wrb * wrb ;
struct be_sge * mcc_sge ;
2012-04-04 08:41:50 +04:00
unsigned int tag = 0 ;
struct iscsi_bsg_request * bsg_req = job - > request ;
struct be_bsg_vendor_cmd * req = nonemb_cmd - > va ;
unsigned short region , sector_size , sector , offset ;
nonemb_cmd - > size = job - > request_payload . payload_len ;
memset ( nonemb_cmd - > va , 0 , nonemb_cmd - > size ) ;
resp = nonemb_cmd - > va ;
region = bsg_req - > rqst_data . h_vendor . vendor_cmd [ 1 ] ;
sector_size = bsg_req - > rqst_data . h_vendor . vendor_cmd [ 2 ] ;
sector = bsg_req - > rqst_data . h_vendor . vendor_cmd [ 3 ] ;
offset = bsg_req - > rqst_data . h_vendor . vendor_cmd [ 4 ] ;
req - > region = region ;
req - > sector = sector ;
req - > offset = offset ;
2016-01-20 11:40:46 +03:00
if ( mutex_lock_interruptible ( & ctrl - > mbox_lock ) )
return 0 ;
2012-04-04 08:41:50 +04:00
switch ( bsg_req - > rqst_data . h_vendor . vendor_cmd [ 0 ] ) {
case BEISCSI_WRITE_FLASH :
offset = sector * sector_size + offset ;
be_cmd_hdr_prepare ( & req - > hdr , CMD_SUBSYSTEM_ISCSI ,
OPCODE_COMMON_WRITE_FLASH , sizeof ( * req ) ) ;
sg_copy_to_buffer ( job - > request_payload . sg_list ,
job - > request_payload . sg_cnt ,
nonemb_cmd - > va + offset , job - > request_len ) ;
break ;
case BEISCSI_READ_FLASH :
be_cmd_hdr_prepare ( & req - > hdr , CMD_SUBSYSTEM_ISCSI ,
OPCODE_COMMON_READ_FLASH , sizeof ( * req ) ) ;
break ;
default :
2012-08-20 21:30:18 +04:00
beiscsi_log ( phba , KERN_WARNING , BEISCSI_LOG_CONFIG ,
" BG_%d : Unsupported cmd = 0x%x \n \n " ,
bsg_req - > rqst_data . h_vendor . vendor_cmd [ 0 ] ) ;
2016-01-20 11:40:46 +03:00
mutex_unlock ( & ctrl - > mbox_lock ) ;
2012-04-04 08:41:50 +04:00
return - ENOSYS ;
}
2016-02-04 13:19:17 +03:00
wrb = alloc_mcc_wrb ( phba , & tag ) ;
if ( ! wrb ) {
2016-01-20 11:40:46 +03:00
mutex_unlock ( & ctrl - > mbox_lock ) ;
2016-02-04 13:19:17 +03:00
return 0 ;
2012-04-04 08:41:50 +04:00
}
2014-05-06 05:41:24 +04:00
mcc_sge = nonembedded_sgl ( wrb ) ;
2012-04-04 08:41:50 +04:00
be_wrb_hdr_prepare ( wrb , nonemb_cmd - > size , false ,
job - > request_payload . sg_cnt ) ;
mcc_sge - > pa_hi = cpu_to_le32 ( upper_32_bits ( nonemb_cmd - > dma ) ) ;
mcc_sge - > pa_lo = cpu_to_le32 ( nonemb_cmd - > dma & 0xFFFFFFFF ) ;
mcc_sge - > len = cpu_to_le32 ( nonemb_cmd - > size ) ;
2016-01-20 11:40:47 +03:00
be_mcc_notify ( phba , tag ) ;
2012-04-04 08:41:50 +04:00
2016-01-20 11:40:46 +03:00
mutex_unlock ( & ctrl - > mbox_lock ) ;
2012-04-04 08:41:50 +04:00
return tag ;
}
2013-09-29 02:35:51 +04:00
/**
* mgmt_epfw_cleanup ( ) - Inform FW to cleanup data structures .
* @ phba : pointer to dev priv structure
* @ ulp_num : ULP number .
*
* return
* Success : 0
* Failure : Non - Zero Value
* */
int mgmt_epfw_cleanup ( struct beiscsi_hba * phba , unsigned short ulp_num )
2009-09-05 06:06:35 +04:00
{
struct be_ctrl_info * ctrl = & phba - > ctrl ;
2016-02-04 13:19:17 +03:00
struct be_mcc_wrb * wrb ;
struct iscsi_cleanup_req * req ;
2016-01-20 11:40:47 +03:00
unsigned int tag ;
int status ;
2009-09-05 06:06:35 +04:00
2016-01-20 11:40:46 +03:00
mutex_lock ( & ctrl - > mbox_lock ) ;
2016-02-04 13:19:17 +03:00
wrb = alloc_mcc_wrb ( phba , & tag ) ;
if ( ! wrb ) {
2016-01-20 11:40:47 +03:00
mutex_unlock ( & ctrl - > mbox_lock ) ;
return - EBUSY ;
}
2009-09-05 06:06:35 +04:00
2016-02-04 13:19:17 +03:00
req = embedded_payload ( wrb ) ;
2009-09-05 06:06:35 +04:00
be_wrb_hdr_prepare ( wrb , sizeof ( * req ) , true , 0 ) ;
be_cmd_hdr_prepare ( & req - > hdr , CMD_SUBSYSTEM_ISCSI ,
OPCODE_COMMON_ISCSI_CLEANUP , sizeof ( * req ) ) ;
2013-09-29 02:35:51 +04:00
req - > chute = ( 1 < < ulp_num ) ;
req - > hdr_ring_id = cpu_to_le16 ( HWI_GET_DEF_HDRQ_ID ( phba , ulp_num ) ) ;
req - > data_ring_id = cpu_to_le16 ( HWI_GET_DEF_BUFQ_ID ( phba , ulp_num ) ) ;
2009-09-05 06:06:35 +04:00
2016-02-04 13:19:11 +03:00
be_mcc_notify ( phba , tag ) ;
status = be_mcc_compl_poll ( phba , tag ) ;
2009-09-05 06:06:35 +04:00
if ( status )
2012-08-20 21:30:18 +04:00
beiscsi_log ( phba , KERN_WARNING , BEISCSI_LOG_INIT ,
" BG_%d : mgmt_epfw_cleanup , FAILED \n " ) ;
2016-01-20 11:40:46 +03:00
mutex_unlock ( & ctrl - > mbox_lock ) ;
2009-09-05 06:06:35 +04:00
return status ;
}
2010-07-22 02:47:16 +04:00
unsigned int mgmt_invalidate_icds ( struct beiscsi_hba * phba ,
2010-02-20 05:32:39 +03:00
struct invalidate_command_table * inv_tbl ,
2010-07-22 02:57:47 +04:00
unsigned int num_invalidate , unsigned int cid ,
struct be_dma_mem * nonemb_cmd )
2009-09-05 06:06:35 +04:00
{
struct be_ctrl_info * ctrl = & phba - > ctrl ;
2010-01-05 02:40:46 +03:00
struct be_mcc_wrb * wrb ;
struct be_sge * sge ;
2009-09-05 06:06:35 +04:00
struct invalidate_commands_params_in * req ;
2016-02-04 13:19:17 +03:00
unsigned int i , tag ;
2010-01-05 02:40:46 +03:00
2016-01-20 11:40:46 +03:00
mutex_lock ( & ctrl - > mbox_lock ) ;
2016-02-04 13:19:17 +03:00
wrb = alloc_mcc_wrb ( phba , & tag ) ;
if ( ! wrb ) {
2016-01-20 11:40:46 +03:00
mutex_unlock ( & ctrl - > mbox_lock ) ;
2016-02-04 13:19:17 +03:00
return 0 ;
2010-01-05 02:40:46 +03:00
}
2009-09-05 06:06:35 +04:00
2010-07-22 02:57:47 +04:00
req = nonemb_cmd - > va ;
2010-02-11 02:41:15 +03:00
memset ( req , 0 , sizeof ( * req ) ) ;
2010-01-05 02:40:46 +03:00
sge = nonembedded_sgl ( wrb ) ;
2009-09-05 06:06:35 +04:00
be_wrb_hdr_prepare ( wrb , sizeof ( * req ) , false , 1 ) ;
be_cmd_hdr_prepare ( & req - > hdr , CMD_SUBSYSTEM_ISCSI ,
OPCODE_COMMON_ISCSI_ERROR_RECOVERY_INVALIDATE_COMMANDS ,
sizeof ( * req ) ) ;
req - > ref_handle = 0 ;
req - > cleanup_type = CMD_ISCSI_COMMAND_INVALIDATE ;
2010-02-20 05:32:39 +03:00
for ( i = 0 ; i < num_invalidate ; i + + ) {
req - > table [ i ] . icd = inv_tbl - > icd ;
req - > table [ i ] . cid = inv_tbl - > cid ;
req - > icd_count + + ;
inv_tbl + + ;
}
2010-07-22 02:57:47 +04:00
sge - > pa_hi = cpu_to_le32 ( upper_32_bits ( nonemb_cmd - > dma ) ) ;
sge - > pa_lo = cpu_to_le32 ( nonemb_cmd - > dma & 0xFFFFFFFF ) ;
sge - > len = cpu_to_le32 ( nonemb_cmd - > size ) ;
2009-09-05 06:06:35 +04:00
2016-01-20 11:40:47 +03:00
be_mcc_notify ( phba , tag ) ;
2016-01-20 11:40:46 +03:00
mutex_unlock ( & ctrl - > mbox_lock ) ;
2010-01-05 02:40:46 +03:00
return tag ;
2009-09-05 06:06:35 +04:00
}
2010-07-22 02:47:16 +04:00
unsigned int mgmt_invalidate_connection ( struct beiscsi_hba * phba ,
2009-09-05 06:06:35 +04:00
struct beiscsi_endpoint * beiscsi_ep ,
unsigned short cid ,
unsigned short issue_reset ,
unsigned short savecfg_flag )
{
struct be_ctrl_info * ctrl = & phba - > ctrl ;
2010-01-05 02:40:46 +03:00
struct be_mcc_wrb * wrb ;
struct iscsi_invalidate_connection_params_in * req ;
unsigned int tag = 0 ;
2009-09-05 06:06:35 +04:00
2016-01-20 11:40:46 +03:00
mutex_lock ( & ctrl - > mbox_lock ) ;
2016-02-04 13:19:17 +03:00
wrb = alloc_mcc_wrb ( phba , & tag ) ;
if ( ! wrb ) {
2016-01-20 11:40:46 +03:00
mutex_unlock ( & ctrl - > mbox_lock ) ;
2016-02-04 13:19:17 +03:00
return 0 ;
2010-01-05 02:40:46 +03:00
}
2009-09-05 06:06:35 +04:00
2016-02-04 13:19:17 +03:00
req = embedded_payload ( wrb ) ;
2009-09-05 06:06:35 +04:00
be_wrb_hdr_prepare ( wrb , sizeof ( * req ) , true , 0 ) ;
be_cmd_hdr_prepare ( & req - > hdr , CMD_SUBSYSTEM_ISCSI_INI ,
OPCODE_ISCSI_INI_DRIVER_INVALIDATE_CONNECTION ,
sizeof ( * req ) ) ;
req - > session_handle = beiscsi_ep - > fw_handle ;
req - > cid = cid ;
if ( issue_reset )
req - > cleanup_type = CMD_ISCSI_CONNECTION_ISSUE_TCP_RST ;
else
req - > cleanup_type = CMD_ISCSI_CONNECTION_INVALIDATE ;
req - > save_cfg = savecfg_flag ;
2016-01-20 11:40:47 +03:00
be_mcc_notify ( phba , tag ) ;
2016-01-20 11:40:46 +03:00
mutex_unlock ( & ctrl - > mbox_lock ) ;
2010-01-05 02:40:46 +03:00
return tag ;
2009-09-05 06:06:35 +04:00
}
2010-07-22 02:47:16 +04:00
unsigned int mgmt_upload_connection ( struct beiscsi_hba * phba ,
2009-09-05 06:06:35 +04:00
unsigned short cid , unsigned int upload_flag )
{
struct be_ctrl_info * ctrl = & phba - > ctrl ;
2010-01-05 02:40:46 +03:00
struct be_mcc_wrb * wrb ;
struct tcp_upload_params_in * req ;
2016-02-04 13:19:17 +03:00
unsigned int tag ;
2009-09-05 06:06:35 +04:00
2016-01-20 11:40:46 +03:00
mutex_lock ( & ctrl - > mbox_lock ) ;
2016-02-04 13:19:17 +03:00
wrb = alloc_mcc_wrb ( phba , & tag ) ;
if ( ! wrb ) {
2016-01-20 11:40:46 +03:00
mutex_unlock ( & ctrl - > mbox_lock ) ;
2016-02-04 13:19:17 +03:00
return 0 ;
2010-01-05 02:40:46 +03:00
}
2009-09-05 06:06:35 +04:00
2016-02-04 13:19:17 +03:00
req = embedded_payload ( wrb ) ;
2009-09-05 06:06:35 +04:00
be_wrb_hdr_prepare ( wrb , sizeof ( * req ) , true , 0 ) ;
be_cmd_hdr_prepare ( & req - > hdr , CMD_COMMON_TCP_UPLOAD ,
OPCODE_COMMON_TCP_UPLOAD , sizeof ( * req ) ) ;
req - > id = ( unsigned short ) cid ;
req - > upload_type = ( unsigned char ) upload_flag ;
2016-01-20 11:40:47 +03:00
be_mcc_notify ( phba , tag ) ;
2016-01-20 11:40:46 +03:00
mutex_unlock ( & ctrl - > mbox_lock ) ;
2010-01-05 02:40:46 +03:00
return tag ;
2009-09-05 06:06:35 +04:00
}
2013-09-29 02:35:50 +04:00
/**
* mgmt_open_connection ( ) - Establish a TCP CXN
* @ dst_addr : Destination Address
* @ beiscsi_ep : ptr to device endpoint struct
* @ nonemb_cmd : ptr to memory allocated for command
*
* return
* Success : Tag number of the MBX Command issued
* Failure : Error code
* */
2009-09-05 06:06:35 +04:00
int mgmt_open_connection ( struct beiscsi_hba * phba ,
struct sockaddr * dst_addr ,
2010-07-22 02:57:47 +04:00
struct beiscsi_endpoint * beiscsi_ep ,
struct be_dma_mem * nonemb_cmd )
2009-09-05 06:06:35 +04:00
{
struct hwi_controller * phwi_ctrlr ;
struct hwi_context_memory * phwi_context ;
struct sockaddr_in * daddr_in = ( struct sockaddr_in * ) dst_addr ;
struct sockaddr_in6 * daddr_in6 = ( struct sockaddr_in6 * ) dst_addr ;
struct be_ctrl_info * ctrl = & phba - > ctrl ;
2010-01-05 02:40:46 +03:00
struct be_mcc_wrb * wrb ;
2014-05-06 05:41:27 +04:00
struct tcp_connect_and_offload_in_v1 * req ;
2009-09-05 06:06:35 +04:00
unsigned short def_hdr_id ;
unsigned short def_data_id ;
struct phys_addr template_address = { 0 , 0 } ;
struct phys_addr * ptemplate_address ;
2010-01-05 02:40:46 +03:00
unsigned int tag = 0 ;
2013-09-29 02:35:50 +04:00
unsigned int i , ulp_num ;
2009-09-05 06:06:35 +04:00
unsigned short cid = beiscsi_ep - > ep_cid ;
2010-07-22 02:57:47 +04:00
struct be_sge * sge ;
2009-09-05 06:06:35 +04:00
2016-02-04 13:19:16 +03:00
if ( dst_addr - > sa_family ! = PF_INET & & dst_addr - > sa_family ! = PF_INET6 ) {
beiscsi_log ( phba , KERN_ERR , BEISCSI_LOG_CONFIG ,
" BG_%d : unknown addr family %d \n " ,
dst_addr - > sa_family ) ;
return - EINVAL ;
}
2009-09-05 06:06:35 +04:00
phwi_ctrlr = phba - > phwi_ctrlr ;
phwi_context = phwi_ctrlr - > phwi_ctxt ;
2013-09-29 02:35:50 +04:00
ulp_num = phwi_ctrlr - > wrb_context [ BE_GET_CRI_FROM_CID ( cid ) ] . ulp_num ;
def_hdr_id = ( unsigned short ) HWI_GET_DEF_HDRQ_ID ( phba , ulp_num ) ;
def_data_id = ( unsigned short ) HWI_GET_DEF_BUFQ_ID ( phba , ulp_num ) ;
2009-09-05 06:06:35 +04:00
ptemplate_address = & template_address ;
ISCSI_GET_PDU_TEMPLATE_ADDRESS ( phba , ptemplate_address ) ;
2016-01-20 11:40:46 +03:00
if ( mutex_lock_interruptible ( & ctrl - > mbox_lock ) )
return 0 ;
2016-02-04 13:19:17 +03:00
wrb = alloc_mcc_wrb ( phba , & tag ) ;
if ( ! wrb ) {
2016-01-20 11:40:46 +03:00
mutex_unlock ( & ctrl - > mbox_lock ) ;
2016-02-04 13:19:17 +03:00
return 0 ;
2010-01-05 02:40:46 +03:00
}
2010-07-22 02:57:47 +04:00
2016-02-04 13:19:17 +03:00
sge = nonembedded_sgl ( wrb ) ;
2010-07-22 02:57:47 +04:00
req = nonemb_cmd - > va ;
memset ( req , 0 , sizeof ( * req ) ) ;
2009-09-05 06:06:35 +04:00
2014-05-06 05:41:27 +04:00
be_wrb_hdr_prepare ( wrb , nonemb_cmd - > size , false , 1 ) ;
2009-09-05 06:06:35 +04:00
be_cmd_hdr_prepare ( & req - > hdr , CMD_SUBSYSTEM_ISCSI ,
OPCODE_COMMON_ISCSI_TCP_CONNECT_AND_OFFLOAD ,
2014-05-06 05:41:27 +04:00
nonemb_cmd - > size ) ;
2009-09-05 06:06:35 +04:00
if ( dst_addr - > sa_family = = PF_INET ) {
__be32 s_addr = daddr_in - > sin_addr . s_addr ;
req - > ip_address . ip_type = BE2_IPV4 ;
2012-04-04 08:41:51 +04:00
req - > ip_address . addr [ 0 ] = s_addr & 0x000000ff ;
req - > ip_address . addr [ 1 ] = ( s_addr & 0x0000ff00 ) > > 8 ;
req - > ip_address . addr [ 2 ] = ( s_addr & 0x00ff0000 ) > > 16 ;
req - > ip_address . addr [ 3 ] = ( s_addr & 0xff000000 ) > > 24 ;
2009-09-05 06:06:35 +04:00
req - > tcp_port = ntohs ( daddr_in - > sin_port ) ;
beiscsi_ep - > dst_addr = daddr_in - > sin_addr . s_addr ;
beiscsi_ep - > dst_tcpport = ntohs ( daddr_in - > sin_port ) ;
beiscsi_ep - > ip_type = BE2_IPV4 ;
2016-02-04 13:19:16 +03:00
} else {
/* else its PF_INET6 family */
2009-09-05 06:06:35 +04:00
req - > ip_address . ip_type = BE2_IPV6 ;
2012-04-04 08:41:51 +04:00
memcpy ( & req - > ip_address . addr ,
2009-09-05 06:06:35 +04:00
& daddr_in6 - > sin6_addr . in6_u . u6_addr8 , 16 ) ;
req - > tcp_port = ntohs ( daddr_in6 - > sin6_port ) ;
beiscsi_ep - > dst_tcpport = ntohs ( daddr_in6 - > sin6_port ) ;
memcpy ( & beiscsi_ep - > dst6_addr ,
& daddr_in6 - > sin6_addr . in6_u . u6_addr8 , 16 ) ;
beiscsi_ep - > ip_type = BE2_IPV6 ;
}
req - > cid = cid ;
2009-10-23 10:22:33 +04:00
i = phba - > nxt_cqid + + ;
if ( phba - > nxt_cqid = = phba - > num_cpus )
phba - > nxt_cqid = 0 ;
req - > cq_id = phwi_context - > be_cq [ i ] . id ;
2012-08-20 21:30:18 +04:00
beiscsi_log ( phba , KERN_INFO , BEISCSI_LOG_CONFIG ,
" BG_%d : i=%d cq_id=%d \n " , i , req - > cq_id ) ;
2009-09-05 06:06:35 +04:00
req - > defq_id = def_hdr_id ;
req - > hdr_ring_id = def_hdr_id ;
req - > data_ring_id = def_data_id ;
req - > do_offload = 1 ;
req - > dataout_template_pa . lo = ptemplate_address - > lo ;
req - > dataout_template_pa . hi = ptemplate_address - > hi ;
2010-07-22 02:57:47 +04:00
sge - > pa_hi = cpu_to_le32 ( upper_32_bits ( nonemb_cmd - > dma ) ) ;
sge - > pa_lo = cpu_to_le32 ( nonemb_cmd - > dma & 0xFFFFFFFF ) ;
sge - > len = cpu_to_le32 ( nonemb_cmd - > size ) ;
2014-05-06 05:41:27 +04:00
if ( ! is_chip_be2_be3r ( phba ) ) {
req - > hdr . version = MBX_CMD_VER1 ;
req - > tcp_window_size = 0 ;
req - > tcp_window_scale_count = 2 ;
}
2016-01-20 11:40:47 +03:00
be_mcc_notify ( phba , tag ) ;
2016-01-20 11:40:46 +03:00
mutex_unlock ( & ctrl - > mbox_lock ) ;
2010-01-05 02:40:46 +03:00
return tag ;
2009-09-05 06:06:35 +04:00
}
2009-10-23 10:22:33 +04:00
2012-04-04 08:41:51 +04:00
unsigned int mgmt_get_all_if_id ( struct beiscsi_hba * phba )
2009-10-23 10:22:33 +04:00
{
struct be_ctrl_info * ctrl = & phba - > ctrl ;
2016-01-20 11:40:45 +03:00
struct be_mcc_wrb * wrb ;
struct be_cmd_get_all_if_id_req * req ;
struct be_cmd_get_all_if_id_req * pbe_allid ;
unsigned int tag ;
2012-04-04 08:41:51 +04:00
int status = 0 ;
2016-01-20 11:40:46 +03:00
if ( mutex_lock_interruptible ( & ctrl - > mbox_lock ) )
return - EINTR ;
2016-02-04 13:19:17 +03:00
wrb = alloc_mcc_wrb ( phba , & tag ) ;
if ( ! wrb ) {
2016-01-20 11:40:46 +03:00
mutex_unlock ( & ctrl - > mbox_lock ) ;
2016-01-20 11:40:45 +03:00
return - ENOMEM ;
}
req = embedded_payload ( wrb ) ;
2012-04-04 08:41:51 +04:00
be_wrb_hdr_prepare ( wrb , sizeof ( * req ) , true , 0 ) ;
be_cmd_hdr_prepare ( & req - > hdr , CMD_SUBSYSTEM_ISCSI ,
OPCODE_COMMON_ISCSI_NTWK_GET_ALL_IF_ID ,
sizeof ( * req ) ) ;
2016-01-20 11:40:47 +03:00
be_mcc_notify ( phba , tag ) ;
2016-01-20 11:40:46 +03:00
mutex_unlock ( & ctrl - > mbox_lock ) ;
2016-01-20 11:40:45 +03:00
2016-02-04 13:19:12 +03:00
status = beiscsi_mccq_compl_wait ( phba , tag , & wrb , NULL ) ;
2016-01-20 11:40:45 +03:00
if ( status ) {
2012-08-20 21:30:18 +04:00
beiscsi_log ( phba , KERN_WARNING , BEISCSI_LOG_CONFIG ,
" BG_%d : Failed in mgmt_get_all_if_id \n " ) ;
2016-01-20 11:40:45 +03:00
return - EBUSY ;
2012-04-04 08:41:51 +04:00
}
2016-01-20 11:40:45 +03:00
pbe_allid = embedded_payload ( wrb ) ;
phba - > interface_handle = pbe_allid - > if_hndl_list [ 0 ] ;
2012-04-04 08:41:51 +04:00
return status ;
}
2012-10-20 03:15:40 +04:00
/*
* mgmt_exec_nonemb_cmd ( ) - Execute Non Embedded MBX Cmd
* @ phba : Driver priv structure
* @ nonemb_cmd : Address of the MBX command issued
* @ resp_buf : Buffer to copy the MBX cmd response
* @ resp_buf_len : respone lenght to be copied
*
* */
2012-04-04 08:41:51 +04:00
static int mgmt_exec_nonemb_cmd ( struct beiscsi_hba * phba ,
struct be_dma_mem * nonemb_cmd , void * resp_buf ,
int resp_buf_len )
{
struct be_ctrl_info * ctrl = & phba - > ctrl ;
2014-05-06 05:41:24 +04:00
struct be_mcc_wrb * wrb ;
2012-04-04 08:41:51 +04:00
struct be_sge * sge ;
unsigned int tag ;
int rc = 0 ;
2009-10-23 10:22:33 +04:00
2016-01-20 11:40:46 +03:00
mutex_lock ( & ctrl - > mbox_lock ) ;
2016-02-04 13:19:17 +03:00
wrb = alloc_mcc_wrb ( phba , & tag ) ;
if ( ! wrb ) {
2016-01-20 11:40:46 +03:00
mutex_unlock ( & ctrl - > mbox_lock ) ;
2012-04-04 08:41:51 +04:00
rc = - ENOMEM ;
goto free_cmd ;
2010-01-05 02:40:46 +03:00
}
2014-05-06 05:41:24 +04:00
2012-04-04 08:41:51 +04:00
sge = nonembedded_sgl ( wrb ) ;
be_wrb_hdr_prepare ( wrb , nonemb_cmd - > size , false , 1 ) ;
sge - > pa_hi = cpu_to_le32 ( upper_32_bits ( nonemb_cmd - > dma ) ) ;
2012-10-20 03:15:40 +04:00
sge - > pa_lo = cpu_to_le32 ( lower_32_bits ( nonemb_cmd - > dma ) ) ;
2012-04-04 08:41:51 +04:00
sge - > len = cpu_to_le32 ( nonemb_cmd - > size ) ;
2009-10-23 10:22:33 +04:00
2016-01-20 11:40:47 +03:00
be_mcc_notify ( phba , tag ) ;
2016-01-20 11:40:46 +03:00
mutex_unlock ( & ctrl - > mbox_lock ) ;
2012-04-04 08:41:51 +04:00
2016-02-04 13:19:12 +03:00
rc = beiscsi_mccq_compl_wait ( phba , tag , NULL , nonemb_cmd ) ;
2014-01-29 11:16:39 +04:00
if ( resp_buf )
memcpy ( resp_buf , nonemb_cmd - > va , resp_buf_len ) ;
2012-10-20 03:15:40 +04:00
if ( rc ) {
2014-01-29 11:16:39 +04:00
/* Check if the MBX Cmd needs to be re-issued */
2013-09-29 02:35:56 +04:00
if ( rc = = - EAGAIN )
return rc ;
2014-01-29 11:16:39 +04:00
beiscsi_log ( phba , KERN_WARNING ,
2012-08-20 21:30:18 +04:00
BEISCSI_LOG_CONFIG | BEISCSI_LOG_MBOX ,
2012-10-20 03:15:40 +04:00
" BG_%d : mgmt_exec_nonemb_cmd Failed status \n " ) ;
2014-01-29 11:16:39 +04:00
if ( rc ! = - EBUSY )
goto free_cmd ;
else
return rc ;
2012-04-04 08:41:51 +04:00
}
free_cmd :
pci_free_consistent ( ctrl - > pdev , nonemb_cmd - > size ,
nonemb_cmd - > va , nonemb_cmd - > dma ) ;
return rc ;
}
static int mgmt_alloc_cmd_data ( struct beiscsi_hba * phba , struct be_dma_mem * cmd ,
int iscsi_cmd , int size )
{
2014-08-09 01:24:46 +04:00
cmd - > va = pci_zalloc_consistent ( phba - > ctrl . pdev , size , & cmd - > dma ) ;
2012-04-04 08:41:51 +04:00
if ( ! cmd - > va ) {
2012-08-20 21:30:18 +04:00
beiscsi_log ( phba , KERN_ERR , BEISCSI_LOG_CONFIG ,
" BG_%d : Failed to allocate memory for if info \n " ) ;
2012-04-04 08:41:51 +04:00
return - ENOMEM ;
}
cmd - > size = size ;
be_cmd_hdr_prepare ( cmd - > va , CMD_SUBSYSTEM_ISCSI , iscsi_cmd , size ) ;
2016-08-19 12:50:04 +03:00
beiscsi_log ( phba , KERN_INFO , BEISCSI_LOG_CONFIG ,
" BG_%d : subsystem iSCSI cmd %d size %d \n " ,
iscsi_cmd , size ) ;
2012-04-04 08:41:51 +04:00
return 0 ;
2009-10-23 10:22:33 +04:00
}
2016-08-19 12:50:02 +03:00
static int beiscsi_if_mod_gw ( struct beiscsi_hba * phba ,
u32 action , u32 ip_type , u8 * gw )
2012-04-04 08:41:51 +04:00
{
struct be_cmd_set_def_gateway_req * req ;
struct be_dma_mem nonemb_cmd ;
int rt_val ;
rt_val = mgmt_alloc_cmd_data ( phba , & nonemb_cmd ,
OPCODE_COMMON_ISCSI_NTWK_MODIFY_DEFAULT_GATEWAY ,
sizeof ( * req ) ) ;
if ( rt_val )
return rt_val ;
req = nonemb_cmd . va ;
2016-08-19 12:50:02 +03:00
req - > action = action ;
req - > ip_addr . ip_type = ip_type ;
memcpy ( req - > ip_addr . addr , gw ,
( ip_type = = BE2_IPV4 ) ? IP_V4_LEN : IP_V6_LEN ) ;
return mgmt_exec_nonemb_cmd ( phba , & nonemb_cmd , NULL , 0 ) ;
}
2012-04-04 08:41:51 +04:00
2016-08-19 12:50:02 +03:00
int beiscsi_if_set_gw ( struct beiscsi_hba * phba , u32 ip_type , u8 * gw )
{
struct be_cmd_get_def_gateway_resp gw_resp ;
int rt_val ;
2012-04-04 08:41:51 +04:00
2016-08-19 12:50:02 +03:00
memset ( & gw_resp , 0 , sizeof ( gw_resp ) ) ;
rt_val = beiscsi_if_get_gw ( phba , ip_type , & gw_resp ) ;
if ( rt_val ) {
beiscsi_log ( phba , KERN_WARNING , BEISCSI_LOG_CONFIG ,
" BG_%d : Failed to Get Gateway Addr \n " ) ;
return rt_val ;
}
rt_val = beiscsi_if_mod_gw ( phba , IP_ACTION_DEL , ip_type ,
gw_resp . ip_addr . addr ) ;
if ( rt_val ) {
beiscsi_log ( phba , KERN_WARNING , BEISCSI_LOG_CONFIG ,
" BG_%d : Failed to clear Gateway Addr Set \n " ) ;
return rt_val ;
}
rt_val = beiscsi_if_mod_gw ( phba , IP_ACTION_ADD , ip_type , gw ) ;
if ( rt_val )
beiscsi_log ( phba , KERN_WARNING , BEISCSI_LOG_CONFIG ,
" BG_%d : Failed to Set Gateway Addr \n " ) ;
return rt_val ;
}
int beiscsi_if_get_gw ( struct beiscsi_hba * phba , u32 ip_type ,
struct be_cmd_get_def_gateway_resp * resp )
{
struct be_cmd_get_def_gateway_req * req ;
struct be_dma_mem nonemb_cmd ;
int rc ;
rc = mgmt_alloc_cmd_data ( phba , & nonemb_cmd ,
OPCODE_COMMON_ISCSI_NTWK_GET_DEFAULT_GATEWAY ,
sizeof ( * resp ) ) ;
if ( rc )
return rc ;
req = nonemb_cmd . va ;
req - > ip_type = ip_type ;
return mgmt_exec_nonemb_cmd ( phba , & nonemb_cmd , resp ,
sizeof ( * resp ) ) ;
2012-04-04 08:41:51 +04:00
}
2016-08-19 12:50:03 +03:00
static int
beiscsi_if_clr_ip ( struct beiscsi_hba * phba ,
struct be_cmd_get_if_info_resp * if_info )
2012-04-04 08:41:51 +04:00
{
2016-08-19 12:50:03 +03:00
struct be_cmd_set_ip_addr_req * req ;
2012-04-04 08:41:51 +04:00
struct be_dma_mem nonemb_cmd ;
int rc ;
2016-08-19 12:50:03 +03:00
rc = mgmt_alloc_cmd_data ( phba , & nonemb_cmd ,
OPCODE_COMMON_ISCSI_NTWK_MODIFY_IP_ADDR ,
sizeof ( * req ) ) ;
2016-01-20 11:40:50 +03:00
if ( rc )
return rc ;
2012-04-04 08:41:51 +04:00
2016-08-19 12:50:03 +03:00
req = nonemb_cmd . va ;
req - > ip_params . record_entry_count = 1 ;
req - > ip_params . ip_record . action = IP_ACTION_DEL ;
req - > ip_params . ip_record . interface_hndl =
phba - > interface_handle ;
req - > ip_params . ip_record . ip_addr . size_of_structure =
sizeof ( struct be_ip_addr_subnet_format ) ;
req - > ip_params . ip_record . ip_addr . ip_type = if_info - > ip_addr . ip_type ;
memcpy ( req - > ip_params . ip_record . ip_addr . addr ,
if_info - > ip_addr . addr ,
sizeof ( if_info - > ip_addr . addr ) ) ;
memcpy ( req - > ip_params . ip_record . ip_addr . subnet_mask ,
if_info - > ip_addr . subnet_mask ,
sizeof ( if_info - > ip_addr . subnet_mask ) ) ;
rc = mgmt_exec_nonemb_cmd ( phba , & nonemb_cmd , NULL , 0 ) ;
if ( rc < 0 | | req - > ip_params . ip_record . status ) {
beiscsi_log ( phba , KERN_INFO , BEISCSI_LOG_CONFIG ,
" BG_%d : failed to clear IP: rc %d status %d \n " ,
rc , req - > ip_params . ip_record . status ) ;
}
return rc ;
}
2012-04-04 08:41:51 +04:00
2016-08-19 12:50:03 +03:00
static int
beiscsi_if_set_ip ( struct beiscsi_hba * phba , u8 * ip ,
u8 * subnet , u32 ip_type )
{
struct be_cmd_set_ip_addr_req * req ;
struct be_dma_mem nonemb_cmd ;
uint32_t ip_len ;
int rc ;
rc = mgmt_alloc_cmd_data ( phba , & nonemb_cmd ,
OPCODE_COMMON_ISCSI_NTWK_MODIFY_IP_ADDR ,
sizeof ( * req ) ) ;
2014-06-06 16:22:44 +04:00
if ( rc )
2012-04-04 08:41:51 +04:00
return rc ;
2016-08-19 12:50:03 +03:00
req = nonemb_cmd . va ;
req - > ip_params . record_entry_count = 1 ;
req - > ip_params . ip_record . action = IP_ACTION_ADD ;
req - > ip_params . ip_record . interface_hndl =
phba - > interface_handle ;
req - > ip_params . ip_record . ip_addr . size_of_structure =
sizeof ( struct be_ip_addr_subnet_format ) ;
req - > ip_params . ip_record . ip_addr . ip_type = ip_type ;
ip_len = ip_type = = BE2_IPV4 ? IP_V4_LEN : IP_V6_LEN ;
memcpy ( req - > ip_params . ip_record . ip_addr . addr , ip , ip_len ) ;
if ( subnet )
memcpy ( req - > ip_params . ip_record . ip_addr . subnet_mask ,
subnet , ip_len ) ;
2012-04-04 08:41:51 +04:00
2016-08-19 12:50:03 +03:00
rc = mgmt_exec_nonemb_cmd ( phba , & nonemb_cmd , NULL , 0 ) ;
/**
* In some cases , host needs to look into individual record status
* even though FW reported success for that IOCTL .
*/
if ( rc < 0 | | req - > ip_params . ip_record . status ) {
__beiscsi_log ( phba , KERN_ERR ,
" BG_%d : failed to set IP: rc %d status %d \n " ,
rc , req - > ip_params . ip_record . status ) ;
if ( req - > ip_params . ip_record . status )
rc = - EINVAL ;
}
return rc ;
}
2012-04-04 08:41:51 +04:00
2016-08-19 12:50:03 +03:00
int beiscsi_if_en_static ( struct beiscsi_hba * phba , u32 ip_type ,
u8 * ip , u8 * subnet )
{
struct be_cmd_get_if_info_resp * if_info ;
struct be_cmd_rel_dhcp_req * reldhcp ;
struct be_dma_mem nonemb_cmd ;
int rc ;
2012-04-04 08:41:51 +04:00
2016-08-19 12:50:03 +03:00
rc = mgmt_get_if_info ( phba , ip_type , & if_info ) ;
if ( rc )
return rc ;
2012-04-04 08:41:51 +04:00
2016-08-19 12:50:03 +03:00
if ( if_info - > dhcp_state ) {
rc = mgmt_alloc_cmd_data ( phba , & nonemb_cmd ,
OPCODE_COMMON_ISCSI_NTWK_REL_STATELESS_IP_ADDR ,
sizeof ( * reldhcp ) ) ;
2012-04-04 08:41:51 +04:00
if ( rc )
2014-06-27 16:55:20 +04:00
goto exit ;
2012-04-04 08:41:51 +04:00
2016-08-19 12:50:03 +03:00
reldhcp = nonemb_cmd . va ;
reldhcp - > interface_hndl = phba - > interface_handle ;
reldhcp - > ip_type = ip_type ;
rc = mgmt_exec_nonemb_cmd ( phba , & nonemb_cmd , NULL , 0 ) ;
if ( rc < 0 ) {
2012-08-20 21:30:18 +04:00
beiscsi_log ( phba , KERN_WARNING , BEISCSI_LOG_CONFIG ,
2016-08-19 12:50:03 +03:00
" BG_%d : failed to release existing DHCP: %d \n " ,
rc ) ;
2014-06-27 16:55:20 +04:00
goto exit ;
2012-04-04 08:41:51 +04:00
}
2016-08-19 12:50:03 +03:00
}
2012-04-04 08:41:51 +04:00
2016-08-19 12:50:03 +03:00
/* first delete any old IP set */
rc = beiscsi_if_clr_ip ( phba , if_info ) ;
if ( rc )
goto exit ;
2012-04-04 08:41:51 +04:00
2016-08-19 12:50:03 +03:00
/* if ip == NULL then this is called just to release DHCP IP */
if ( ip )
rc = beiscsi_if_set_ip ( phba , ip , subnet , ip_type ) ;
exit :
kfree ( if_info ) ;
return rc ;
}
int beiscsi_if_en_dhcp ( struct beiscsi_hba * phba , u32 ip_type )
{
struct be_cmd_get_def_gateway_resp gw_resp ;
struct be_cmd_get_if_info_resp * if_info ;
struct be_cmd_set_dhcp_req * dhcpreq ;
struct be_dma_mem nonemb_cmd ;
u8 * gw ;
int rc ;
rc = mgmt_get_if_info ( phba , ip_type , & if_info ) ;
if ( rc )
return rc ;
if ( if_info - > dhcp_state ) {
beiscsi_log ( phba , KERN_WARNING , BEISCSI_LOG_CONFIG ,
" BG_%d : DHCP Already Enabled \n " ) ;
goto exit ;
2012-04-04 08:41:51 +04:00
}
2016-08-19 12:50:03 +03:00
/* first delete any old static IP set */
rc = beiscsi_if_clr_ip ( phba , if_info ) ;
if ( rc )
goto exit ;
/* delete gateway settings if mode change is to DHCP */
memset ( & gw_resp , 0 , sizeof ( gw_resp ) ) ;
/* use ip_type provided in if_info */
rc = beiscsi_if_get_gw ( phba , if_info - > ip_addr . ip_type , & gw_resp ) ;
if ( rc ) {
beiscsi_log ( phba , KERN_WARNING , BEISCSI_LOG_CONFIG ,
" BG_%d : Failed to Get Gateway Addr \n " ) ;
goto exit ;
}
gw = ( u8 * ) & gw_resp . ip_addr . addr ;
rc = beiscsi_if_mod_gw ( phba , IP_ACTION_DEL ,
if_info - > ip_addr . ip_type , gw ) ;
if ( rc ) {
beiscsi_log ( phba , KERN_WARNING , BEISCSI_LOG_CONFIG ,
" BG_%d : Failed to clear Gateway Addr Set \n " ) ;
goto exit ;
}
rc = mgmt_alloc_cmd_data ( phba , & nonemb_cmd ,
2012-04-04 08:41:51 +04:00
OPCODE_COMMON_ISCSI_NTWK_CONFIG_STATELESS_IP_ADDR ,
sizeof ( * dhcpreq ) ) ;
2016-08-19 12:50:03 +03:00
if ( rc )
goto exit ;
2012-04-04 08:41:51 +04:00
2016-08-19 12:50:03 +03:00
dhcpreq = nonemb_cmd . va ;
dhcpreq - > flags = BLOCKING ;
dhcpreq - > retry_count = 1 ;
dhcpreq - > interface_hndl = phba - > interface_handle ;
dhcpreq - > ip_type = ip_type ;
rc = mgmt_exec_nonemb_cmd ( phba , & nonemb_cmd , NULL , 0 ) ;
2012-04-04 08:41:51 +04:00
2014-06-27 16:55:20 +04:00
exit :
kfree ( if_info ) ;
2012-04-04 08:41:51 +04:00
return rc ;
}
2016-08-19 12:50:04 +03:00
/**
* beiscsi_if_set_vlan ( ) - Issue and wait for CMD completion
* @ phba : device private structure instance
* @ vlan_tag : VLAN tag
*
* Issue the MBX Cmd and wait for the completion of the
* command .
*
* returns
* Success : 0
* Failure : Non - Xero Value
* */
int beiscsi_if_set_vlan ( struct beiscsi_hba * phba , uint16_t vlan_tag )
{
int rc ;
unsigned int tag ;
tag = be_cmd_set_vlan ( phba , vlan_tag ) ;
if ( ! tag ) {
beiscsi_log ( phba , KERN_ERR ,
( BEISCSI_LOG_CONFIG | BEISCSI_LOG_MBOX ) ,
" BG_%d : VLAN Setting Failed \n " ) ;
return - EBUSY ;
}
rc = beiscsi_mccq_compl_wait ( phba , tag , NULL , NULL ) ;
if ( rc ) {
beiscsi_log ( phba , KERN_ERR ,
( BEISCSI_LOG_CONFIG | BEISCSI_LOG_MBOX ) ,
" BS_%d : VLAN MBX Cmd Failed \n " ) ;
return rc ;
}
return rc ;
}
2012-04-04 08:41:51 +04:00
int mgmt_get_if_info ( struct beiscsi_hba * phba , int ip_type ,
2013-09-29 02:35:56 +04:00
struct be_cmd_get_if_info_resp * * if_info )
2012-04-04 08:41:51 +04:00
{
struct be_cmd_get_if_info_req * req ;
struct be_dma_mem nonemb_cmd ;
2013-09-29 02:35:56 +04:00
uint32_t ioctl_size = sizeof ( struct be_cmd_get_if_info_resp ) ;
2012-04-04 08:41:51 +04:00
int rc ;
2016-01-20 11:40:50 +03:00
rc = mgmt_get_all_if_id ( phba ) ;
if ( rc )
return rc ;
2012-04-04 08:41:51 +04:00
2013-09-29 02:35:56 +04:00
do {
rc = mgmt_alloc_cmd_data ( phba , & nonemb_cmd ,
OPCODE_COMMON_ISCSI_NTWK_GET_IF_INFO ,
ioctl_size ) ;
if ( rc )
return rc ;
2012-04-04 08:41:51 +04:00
2013-09-29 02:35:56 +04:00
req = nonemb_cmd . va ;
req - > interface_hndl = phba - > interface_handle ;
req - > ip_type = ip_type ;
/* Allocate memory for if_info */
* if_info = kzalloc ( ioctl_size , GFP_KERNEL ) ;
if ( ! * if_info ) {
beiscsi_log ( phba , KERN_ERR ,
BEISCSI_LOG_INIT | BEISCSI_LOG_CONFIG ,
" BG_%d : Memory Allocation Failure \n " ) ;
/* Free the DMA memory for the IOCTL issuing */
pci_free_consistent ( phba - > ctrl . pdev ,
nonemb_cmd . size ,
nonemb_cmd . va ,
nonemb_cmd . dma ) ;
return - ENOMEM ;
}
rc = mgmt_exec_nonemb_cmd ( phba , & nonemb_cmd , * if_info ,
ioctl_size ) ;
2012-04-04 08:41:51 +04:00
2013-09-29 02:35:56 +04:00
/* Check if the error is because of Insufficent_Buffer */
if ( rc = = - EAGAIN ) {
/* Get the new memory size */
ioctl_size = ( ( struct be_cmd_resp_hdr * )
nonemb_cmd . va ) - > actual_resp_len ;
ioctl_size + = sizeof ( struct be_cmd_req_hdr ) ;
/* Free the previous allocated DMA memory */
pci_free_consistent ( phba - > ctrl . pdev , nonemb_cmd . size ,
nonemb_cmd . va ,
nonemb_cmd . dma ) ;
/* Free the virtual memory */
kfree ( * if_info ) ;
} else
break ;
} while ( true ) ;
return rc ;
2012-04-04 08:41:51 +04:00
}
int mgmt_get_nic_conf ( struct beiscsi_hba * phba ,
struct be_cmd_get_nic_conf_resp * nic )
{
struct be_dma_mem nonemb_cmd ;
int rc ;
rc = mgmt_alloc_cmd_data ( phba , & nonemb_cmd ,
OPCODE_COMMON_ISCSI_NTWK_GET_NIC_CONFIG ,
sizeof ( * nic ) ) ;
if ( rc )
return rc ;
return mgmt_exec_nonemb_cmd ( phba , & nonemb_cmd , nic , sizeof ( * nic ) ) ;
}
2012-04-04 08:41:49 +04:00
unsigned int be_cmd_get_initname ( struct beiscsi_hba * phba )
{
2016-02-04 13:19:17 +03:00
unsigned int tag ;
2012-04-04 08:41:49 +04:00
struct be_mcc_wrb * wrb ;
struct be_cmd_hba_name * req ;
struct be_ctrl_info * ctrl = & phba - > ctrl ;
2016-01-20 11:40:46 +03:00
if ( mutex_lock_interruptible ( & ctrl - > mbox_lock ) )
return 0 ;
2016-02-04 13:19:17 +03:00
wrb = alloc_mcc_wrb ( phba , & tag ) ;
if ( ! wrb ) {
2016-01-20 11:40:46 +03:00
mutex_unlock ( & ctrl - > mbox_lock ) ;
2016-02-04 13:19:17 +03:00
return 0 ;
2012-04-04 08:41:49 +04:00
}
req = embedded_payload ( wrb ) ;
be_wrb_hdr_prepare ( wrb , sizeof ( * req ) , true , 0 ) ;
be_cmd_hdr_prepare ( & req - > hdr , CMD_SUBSYSTEM_ISCSI_INI ,
OPCODE_ISCSI_INI_CFG_GET_HBA_NAME ,
sizeof ( * req ) ) ;
2016-01-20 11:40:47 +03:00
be_mcc_notify ( phba , tag ) ;
2016-01-20 11:40:46 +03:00
mutex_unlock ( & ctrl - > mbox_lock ) ;
2012-04-04 08:41:49 +04:00
return tag ;
}
2012-04-04 08:41:52 +04:00
2012-08-20 21:30:08 +04:00
/**
* be_mgmt_get_boot_shandle ( ) - Get the session handle
* @ phba : device priv structure instance
* @ s_handle : session handle returned for boot session .
*
* Get the boot target session handle . In case of
* crashdump mode driver has to issue and MBX Cmd
* for FW to login to boot target
*
* return
* Success : 0
* Failure : Non - Zero value
*
* */
int be_mgmt_get_boot_shandle ( struct beiscsi_hba * phba ,
unsigned int * s_handle )
{
struct be_cmd_get_boot_target_resp * boot_resp ;
struct be_mcc_wrb * wrb ;
2012-10-20 03:15:40 +04:00
unsigned int tag ;
2012-08-20 21:30:08 +04:00
uint8_t boot_retry = 3 ;
2012-10-20 03:15:40 +04:00
int rc ;
2012-08-20 21:30:08 +04:00
do {
/* Get the Boot Target Session Handle and Count*/
tag = mgmt_get_boot_target ( phba ) ;
if ( ! tag ) {
2012-08-20 21:30:18 +04:00
beiscsi_log ( phba , KERN_ERR ,
BEISCSI_LOG_CONFIG | BEISCSI_LOG_INIT ,
" BG_%d : Getting Boot Target Info Failed \n " ) ;
2012-08-20 21:30:08 +04:00
return - EAGAIN ;
2012-10-20 03:15:40 +04:00
}
2016-02-04 13:19:12 +03:00
rc = beiscsi_mccq_compl_wait ( phba , tag , & wrb , NULL ) ;
2012-10-20 03:15:40 +04:00
if ( rc ) {
2012-08-20 21:30:18 +04:00
beiscsi_log ( phba , KERN_ERR ,
BEISCSI_LOG_INIT | BEISCSI_LOG_CONFIG ,
2012-10-20 03:15:40 +04:00
" BG_%d : MBX CMD get_boot_target Failed \n " ) ;
2012-08-20 21:30:08 +04:00
return - EBUSY ;
}
2012-10-20 03:15:40 +04:00
2012-08-20 21:30:08 +04:00
boot_resp = embedded_payload ( wrb ) ;
/* Check if the there are any Boot targets configured */
if ( ! boot_resp - > boot_session_count ) {
2012-08-20 21:30:18 +04:00
beiscsi_log ( phba , KERN_INFO ,
BEISCSI_LOG_INIT | BEISCSI_LOG_CONFIG ,
" BG_%d ;No boot targets configured \n " ) ;
2012-08-20 21:30:08 +04:00
return - ENXIO ;
}
/* FW returns the session handle of the boot session */
if ( boot_resp - > boot_session_handle ! = INVALID_SESS_HANDLE ) {
* s_handle = boot_resp - > boot_session_handle ;
return 0 ;
}
/* Issue MBX Cmd to FW to login to the boot target */
tag = mgmt_reopen_session ( phba , BE_REOPEN_BOOT_SESSIONS ,
INVALID_SESS_HANDLE ) ;
if ( ! tag ) {
2012-08-20 21:30:18 +04:00
beiscsi_log ( phba , KERN_ERR ,
BEISCSI_LOG_INIT | BEISCSI_LOG_CONFIG ,
" BG_%d : mgmt_reopen_session Failed \n " ) ;
2012-08-20 21:30:08 +04:00
return - EAGAIN ;
2012-10-20 03:15:40 +04:00
}
2016-02-04 13:19:12 +03:00
rc = beiscsi_mccq_compl_wait ( phba , tag , NULL , NULL ) ;
2012-10-20 03:15:40 +04:00
if ( rc ) {
2012-08-20 21:30:18 +04:00
beiscsi_log ( phba , KERN_ERR ,
BEISCSI_LOG_INIT | BEISCSI_LOG_CONFIG ,
2012-10-20 03:15:40 +04:00
" BG_%d : mgmt_reopen_session Failed " ) ;
return rc ;
2012-08-20 21:30:08 +04:00
}
} while ( - - boot_retry ) ;
/* Couldn't log into the boot target */
2012-08-20 21:30:18 +04:00
beiscsi_log ( phba , KERN_ERR ,
BEISCSI_LOG_INIT | BEISCSI_LOG_CONFIG ,
" BG_%d : Login to Boot Target Failed \n " ) ;
2012-08-20 21:30:08 +04:00
return - ENXIO ;
}
2012-08-20 21:30:43 +04:00
2012-10-20 03:12:25 +04:00
/**
* beiscsi_drvr_ver_disp ( ) - Display the driver Name and Version
* @ dev : ptr to device not used .
* @ attr : device attribute , not used .
* @ buf : contains formatted text driver name and version
*
* return
* size of the formatted string
* */
ssize_t
beiscsi_drvr_ver_disp ( struct device * dev , struct device_attribute * attr ,
char * buf )
{
return snprintf ( buf , PAGE_SIZE , BE_NAME " \n " ) ;
}
2012-10-20 03:14:35 +04:00
2013-04-06 07:38:28 +04:00
/**
* beiscsi_fw_ver_disp ( ) - Display Firmware Version
* @ dev : ptr to device not used .
* @ attr : device attribute , not used .
* @ buf : contains formatted text Firmware version
*
* return
* size of the formatted string
* */
ssize_t
beiscsi_fw_ver_disp ( struct device * dev , struct device_attribute * attr ,
char * buf )
{
struct Scsi_Host * shost = class_to_shost ( dev ) ;
struct beiscsi_hba * phba = iscsi_host_priv ( shost ) ;
return snprintf ( buf , PAGE_SIZE , " %s \n " , phba - > fw_ver_str ) ;
}
2013-04-06 07:38:29 +04:00
/**
2013-09-29 02:35:52 +04:00
* beiscsi_active_session_disp ( ) - Display Sessions Active
2013-04-06 07:38:29 +04:00
* @ dev : ptr to device not used .
* @ attr : device attribute , not used .
* @ buf : contains formatted text Session Count
*
* return
* size of the formatted string
* */
ssize_t
2013-09-29 02:35:52 +04:00
beiscsi_active_session_disp ( struct device * dev , struct device_attribute * attr ,
2013-04-06 07:38:29 +04:00
char * buf )
{
struct Scsi_Host * shost = class_to_shost ( dev ) ;
struct beiscsi_hba * phba = iscsi_host_priv ( shost ) ;
2013-09-29 02:35:49 +04:00
uint16_t avlbl_cids = 0 , ulp_num , len = 0 , total_cids = 0 ;
for ( ulp_num = 0 ; ulp_num < BEISCSI_ULP_COUNT ; ulp_num + + ) {
if ( test_bit ( ulp_num , ( void * ) & phba - > fw_config . ulp_supported ) ) {
avlbl_cids = BEISCSI_ULP_AVLBL_CID ( phba , ulp_num ) ;
total_cids = BEISCSI_GET_CID_COUNT ( phba , ulp_num ) ;
len + = snprintf ( buf + len , PAGE_SIZE - len ,
" ULP%d : %d \n " , ulp_num ,
( total_cids - avlbl_cids ) ) ;
} else
len + = snprintf ( buf + len , PAGE_SIZE - len ,
" ULP%d : %d \n " , ulp_num , 0 ) ;
}
2013-04-06 07:38:29 +04:00
2013-09-29 02:35:49 +04:00
return len ;
2013-04-06 07:38:29 +04:00
}
2013-09-29 02:35:52 +04:00
/**
* beiscsi_free_session_disp ( ) - Display Avaliable Session
* @ dev : ptr to device not used .
* @ attr : device attribute , not used .
* @ buf : contains formatted text Session Count
*
* return
* size of the formatted string
* */
ssize_t
beiscsi_free_session_disp ( struct device * dev , struct device_attribute * attr ,
char * buf )
{
struct Scsi_Host * shost = class_to_shost ( dev ) ;
struct beiscsi_hba * phba = iscsi_host_priv ( shost ) ;
uint16_t ulp_num , len = 0 ;
for ( ulp_num = 0 ; ulp_num < BEISCSI_ULP_COUNT ; ulp_num + + ) {
if ( test_bit ( ulp_num , ( void * ) & phba - > fw_config . ulp_supported ) )
len + = snprintf ( buf + len , PAGE_SIZE - len ,
" ULP%d : %d \n " , ulp_num ,
BEISCSI_ULP_AVLBL_CID ( phba , ulp_num ) ) ;
else
len + = snprintf ( buf + len , PAGE_SIZE - len ,
" ULP%d : %d \n " , ulp_num , 0 ) ;
}
return len ;
}
2012-10-20 03:15:06 +04:00
/**
* beiscsi_adap_family_disp ( ) - Display adapter family .
* @ dev : ptr to device to get priv structure
* @ attr : device attribute , not used .
* @ buf : contains formatted text driver name and version
*
* return
* size of the formatted string
* */
ssize_t
beiscsi_adap_family_disp ( struct device * dev , struct device_attribute * attr ,
char * buf )
{
uint16_t dev_id = 0 ;
struct Scsi_Host * shost = class_to_shost ( dev ) ;
struct beiscsi_hba * phba = iscsi_host_priv ( shost ) ;
dev_id = phba - > pcidev - > device ;
switch ( dev_id ) {
case BE_DEVICE_ID1 :
case OC_DEVICE_ID1 :
case OC_DEVICE_ID2 :
return snprintf ( buf , PAGE_SIZE , " BE2 Adapter Family \n " ) ;
break ;
case BE_DEVICE_ID2 :
case OC_DEVICE_ID3 :
return snprintf ( buf , PAGE_SIZE , " BE3-R Adapter Family \n " ) ;
break ;
case OC_SKH_ID1 :
return snprintf ( buf , PAGE_SIZE , " Skyhawk-R Adapter Family \n " ) ;
break ;
default :
return snprintf ( buf , PAGE_SIZE ,
2013-04-17 19:12:55 +04:00
" Unknown Adapter Family: 0x%x \n " , dev_id ) ;
2012-10-20 03:15:06 +04:00
break ;
}
}
2013-09-29 02:35:53 +04:00
/**
* beiscsi_phys_port ( ) - Display Physical Port Identifier
* @ dev : ptr to device not used .
* @ attr : device attribute , not used .
* @ buf : contains formatted text port identifier
*
* return
* size of the formatted string
* */
ssize_t
beiscsi_phys_port_disp ( struct device * dev , struct device_attribute * attr ,
char * buf )
{
struct Scsi_Host * shost = class_to_shost ( dev ) ;
struct beiscsi_hba * phba = iscsi_host_priv ( shost ) ;
return snprintf ( buf , PAGE_SIZE , " Port Identifier : %d \n " ,
phba - > fw_config . phys_port ) ;
}
2012-10-20 03:15:06 +04:00
2012-10-20 03:14:35 +04:00
void beiscsi_offload_cxn_v0 ( struct beiscsi_offload_params * params ,
struct wrb_handle * pwrb_handle ,
2015-08-20 02:14:30 +03:00
struct be_mem_descriptor * mem_descr ,
struct hwi_wrb_context * pwrb_context )
2012-10-20 03:14:35 +04:00
{
struct iscsi_wrb * pwrb = pwrb_handle - > pwrb ;
memset ( pwrb , 0 , sizeof ( * pwrb ) ) ;
AMAP_SET_BITS ( struct amap_iscsi_target_context_update_wrb ,
max_send_data_segment_length , pwrb ,
params - > dw [ offsetof ( struct amap_beiscsi_offload_params ,
max_send_data_segment_length ) / 32 ] ) ;
AMAP_SET_BITS ( struct amap_iscsi_target_context_update_wrb , type , pwrb ,
BE_TGT_CTX_UPDT_CMD ) ;
AMAP_SET_BITS ( struct amap_iscsi_target_context_update_wrb ,
first_burst_length ,
pwrb ,
params - > dw [ offsetof ( struct amap_beiscsi_offload_params ,
first_burst_length ) / 32 ] ) ;
AMAP_SET_BITS ( struct amap_iscsi_target_context_update_wrb , erl , pwrb ,
( params - > dw [ offsetof ( struct amap_beiscsi_offload_params ,
erl ) / 32 ] & OFFLD_PARAMS_ERL ) ) ;
AMAP_SET_BITS ( struct amap_iscsi_target_context_update_wrb , dde , pwrb ,
( params - > dw [ offsetof ( struct amap_beiscsi_offload_params ,
dde ) / 32 ] & OFFLD_PARAMS_DDE ) > > 2 ) ;
AMAP_SET_BITS ( struct amap_iscsi_target_context_update_wrb , hde , pwrb ,
( params - > dw [ offsetof ( struct amap_beiscsi_offload_params ,
hde ) / 32 ] & OFFLD_PARAMS_HDE ) > > 3 ) ;
AMAP_SET_BITS ( struct amap_iscsi_target_context_update_wrb , ir2t , pwrb ,
( params - > dw [ offsetof ( struct amap_beiscsi_offload_params ,
ir2t ) / 32 ] & OFFLD_PARAMS_IR2T ) > > 4 ) ;
AMAP_SET_BITS ( struct amap_iscsi_target_context_update_wrb , imd , pwrb ,
( params - > dw [ offsetof ( struct amap_beiscsi_offload_params ,
imd ) / 32 ] & OFFLD_PARAMS_IMD ) > > 5 ) ;
AMAP_SET_BITS ( struct amap_iscsi_target_context_update_wrb , stat_sn ,
pwrb ,
( params - > dw [ offsetof ( struct amap_beiscsi_offload_params ,
exp_statsn ) / 32 ] + 1 ) ) ;
AMAP_SET_BITS ( struct amap_iscsi_target_context_update_wrb , wrb_idx ,
pwrb , pwrb_handle - > wrb_index ) ;
AMAP_SET_BITS ( struct amap_iscsi_target_context_update_wrb ,
max_burst_length , pwrb , params - > dw [ offsetof
( struct amap_beiscsi_offload_params ,
max_burst_length ) / 32 ] ) ;
AMAP_SET_BITS ( struct amap_iscsi_target_context_update_wrb , ptr2nextwrb ,
2015-08-20 02:14:30 +03:00
pwrb , pwrb_handle - > wrb_index ) ;
if ( pwrb_context - > plast_wrb )
AMAP_SET_BITS ( struct amap_iscsi_target_context_update_wrb ,
ptr2nextwrb ,
pwrb_context - > plast_wrb ,
pwrb_handle - > wrb_index ) ;
pwrb_context - > plast_wrb = pwrb ;
2012-10-20 03:14:35 +04:00
AMAP_SET_BITS ( struct amap_iscsi_target_context_update_wrb ,
session_state , pwrb , 0 ) ;
AMAP_SET_BITS ( struct amap_iscsi_target_context_update_wrb , compltonack ,
pwrb , 1 ) ;
AMAP_SET_BITS ( struct amap_iscsi_target_context_update_wrb , notpredblq ,
pwrb , 0 ) ;
AMAP_SET_BITS ( struct amap_iscsi_target_context_update_wrb , mode , pwrb ,
0 ) ;
mem_descr + = ISCSI_MEM_GLOBAL_HEADER ;
AMAP_SET_BITS ( struct amap_iscsi_target_context_update_wrb ,
pad_buffer_addr_hi , pwrb ,
mem_descr - > mem_array [ 0 ] . bus_address . u . a32 . address_hi ) ;
AMAP_SET_BITS ( struct amap_iscsi_target_context_update_wrb ,
pad_buffer_addr_lo , pwrb ,
mem_descr - > mem_array [ 0 ] . bus_address . u . a32 . address_lo ) ;
}
void beiscsi_offload_cxn_v2 ( struct beiscsi_offload_params * params ,
2015-08-20 02:14:30 +03:00
struct wrb_handle * pwrb_handle ,
struct hwi_wrb_context * pwrb_context )
2012-10-20 03:14:35 +04:00
{
struct iscsi_wrb * pwrb = pwrb_handle - > pwrb ;
memset ( pwrb , 0 , sizeof ( * pwrb ) ) ;
AMAP_SET_BITS ( struct amap_iscsi_target_context_update_wrb_v2 ,
max_burst_length , pwrb , params - > dw [ offsetof
( struct amap_beiscsi_offload_params ,
max_burst_length ) / 32 ] ) ;
AMAP_SET_BITS ( struct amap_iscsi_target_context_update_wrb_v2 ,
type , pwrb ,
BE_TGT_CTX_UPDT_CMD ) ;
AMAP_SET_BITS ( struct amap_iscsi_target_context_update_wrb_v2 ,
ptr2nextwrb ,
2015-08-20 02:14:30 +03:00
pwrb , pwrb_handle - > wrb_index ) ;
if ( pwrb_context - > plast_wrb )
AMAP_SET_BITS ( struct amap_iscsi_target_context_update_wrb_v2 ,
ptr2nextwrb ,
pwrb_context - > plast_wrb ,
pwrb_handle - > wrb_index ) ;
pwrb_context - > plast_wrb = pwrb ;
2012-10-20 03:14:35 +04:00
AMAP_SET_BITS ( struct amap_iscsi_target_context_update_wrb_v2 , wrb_idx ,
pwrb , pwrb_handle - > wrb_index ) ;
AMAP_SET_BITS ( struct amap_iscsi_target_context_update_wrb_v2 ,
max_send_data_segment_length , pwrb ,
params - > dw [ offsetof ( struct amap_beiscsi_offload_params ,
max_send_data_segment_length ) / 32 ] ) ;
AMAP_SET_BITS ( struct amap_iscsi_target_context_update_wrb_v2 ,
first_burst_length , pwrb ,
params - > dw [ offsetof ( struct amap_beiscsi_offload_params ,
first_burst_length ) / 32 ] ) ;
AMAP_SET_BITS ( struct amap_iscsi_target_context_update_wrb_v2 ,
2013-09-29 02:35:41 +04:00
max_recv_dataseg_len , pwrb ,
params - > dw [ offsetof ( struct amap_beiscsi_offload_params ,
max_recv_data_segment_length ) / 32 ] ) ;
2012-10-20 03:14:35 +04:00
AMAP_SET_BITS ( struct amap_iscsi_target_context_update_wrb_v2 ,
max_cxns , pwrb , BEISCSI_MAX_CXNS ) ;
AMAP_SET_BITS ( struct amap_iscsi_target_context_update_wrb_v2 , erl , pwrb ,
( params - > dw [ offsetof ( struct amap_beiscsi_offload_params ,
erl ) / 32 ] & OFFLD_PARAMS_ERL ) ) ;
AMAP_SET_BITS ( struct amap_iscsi_target_context_update_wrb_v2 , dde , pwrb ,
( params - > dw [ offsetof ( struct amap_beiscsi_offload_params ,
dde ) / 32 ] & OFFLD_PARAMS_DDE ) > > 2 ) ;
AMAP_SET_BITS ( struct amap_iscsi_target_context_update_wrb_v2 , hde , pwrb ,
( params - > dw [ offsetof ( struct amap_beiscsi_offload_params ,
hde ) / 32 ] & OFFLD_PARAMS_HDE ) > > 3 ) ;
AMAP_SET_BITS ( struct amap_iscsi_target_context_update_wrb_v2 ,
ir2t , pwrb ,
( params - > dw [ offsetof ( struct amap_beiscsi_offload_params ,
ir2t ) / 32 ] & OFFLD_PARAMS_IR2T ) > > 4 ) ;
AMAP_SET_BITS ( struct amap_iscsi_target_context_update_wrb_v2 , imd , pwrb ,
( params - > dw [ offsetof ( struct amap_beiscsi_offload_params ,
imd ) / 32 ] & OFFLD_PARAMS_IMD ) > > 5 ) ;
AMAP_SET_BITS ( struct amap_iscsi_target_context_update_wrb_v2 ,
data_seq_inorder ,
pwrb ,
( params - > dw [ offsetof ( struct amap_beiscsi_offload_params ,
data_seq_inorder ) / 32 ] &
OFFLD_PARAMS_DATA_SEQ_INORDER ) > > 6 ) ;
AMAP_SET_BITS ( struct amap_iscsi_target_context_update_wrb_v2 ,
pdu_seq_inorder ,
pwrb ,
( params - > dw [ offsetof ( struct amap_beiscsi_offload_params ,
pdu_seq_inorder ) / 32 ] &
OFFLD_PARAMS_PDU_SEQ_INORDER ) > > 7 ) ;
AMAP_SET_BITS ( struct amap_iscsi_target_context_update_wrb_v2 , max_r2t ,
pwrb ,
( params - > dw [ offsetof ( struct amap_beiscsi_offload_params ,
max_r2t ) / 32 ] &
OFFLD_PARAMS_MAX_R2T ) > > 8 ) ;
AMAP_SET_BITS ( struct amap_iscsi_target_context_update_wrb_v2 , stat_sn ,
pwrb ,
( params - > dw [ offsetof ( struct amap_beiscsi_offload_params ,
exp_statsn ) / 32 ] + 1 ) ) ;
}
2015-04-25 05:48:13 +03:00
/**
* beiscsi_logout_fw_sess ( ) - Firmware Session Logout
* @ phba : Device priv structure instance
* @ fw_sess_handle : FW session handle
*
* Logout from the FW established sessions .
* returns
* Success : 0
* Failure : Non - Zero Value
*
*/
int beiscsi_logout_fw_sess ( struct beiscsi_hba * phba ,
uint32_t fw_sess_handle )
{
struct be_ctrl_info * ctrl = & phba - > ctrl ;
struct be_mcc_wrb * wrb ;
struct be_cmd_req_logout_fw_sess * req ;
struct be_cmd_resp_logout_fw_sess * resp ;
unsigned int tag ;
int rc ;
beiscsi_log ( phba , KERN_INFO ,
BEISCSI_LOG_CONFIG | BEISCSI_LOG_MBOX ,
" BG_%d : In bescsi_logout_fwboot_sess \n " ) ;
2016-01-20 11:40:46 +03:00
mutex_lock ( & ctrl - > mbox_lock ) ;
2016-02-04 13:19:17 +03:00
wrb = alloc_mcc_wrb ( phba , & tag ) ;
if ( ! wrb ) {
2016-01-20 11:40:46 +03:00
mutex_unlock ( & ctrl - > mbox_lock ) ;
2015-04-25 05:48:13 +03:00
beiscsi_log ( phba , KERN_INFO ,
BEISCSI_LOG_CONFIG | BEISCSI_LOG_MBOX ,
" BG_%d : MBX Tag Failure \n " ) ;
return - EINVAL ;
}
req = embedded_payload ( wrb ) ;
be_wrb_hdr_prepare ( wrb , sizeof ( * req ) , true , 0 ) ;
be_cmd_hdr_prepare ( & req - > hdr , CMD_SUBSYSTEM_ISCSI_INI ,
OPCODE_ISCSI_INI_SESSION_LOGOUT_TARGET ,
sizeof ( struct be_cmd_req_logout_fw_sess ) ) ;
/* Set the session handle */
req - > session_handle = fw_sess_handle ;
2016-01-20 11:40:47 +03:00
be_mcc_notify ( phba , tag ) ;
2016-01-20 11:40:46 +03:00
mutex_unlock ( & ctrl - > mbox_lock ) ;
2015-04-25 05:48:13 +03:00
2016-02-04 13:19:12 +03:00
rc = beiscsi_mccq_compl_wait ( phba , tag , & wrb , NULL ) ;
2015-04-25 05:48:13 +03:00
if ( rc ) {
beiscsi_log ( phba , KERN_ERR ,
BEISCSI_LOG_INIT | BEISCSI_LOG_CONFIG ,
" BG_%d : MBX CMD FW_SESSION_LOGOUT_TARGET Failed \n " ) ;
return - EBUSY ;
}
resp = embedded_payload ( wrb ) ;
if ( resp - > session_status ! =
BEISCSI_MGMT_SESSION_CLOSE ) {
beiscsi_log ( phba , KERN_ERR ,
BEISCSI_LOG_INIT | BEISCSI_LOG_CONFIG ,
" BG_%d : FW_SESSION_LOGOUT_TARGET resp : 0x%x \n " ,
resp - > session_status ) ;
rc = - EINVAL ;
}
return rc ;
}