RFC: beiscsi: Firmware Commands to chip
PATCH 4/6 RFC: beiscsi: Firmware Commands to chip
These files contain code for all supported Firmware commands to the chip. These routines are mostly accessed from be_main.c.
Signed-off-by Jayamohan Kallickal <[email protected]>
--- drivers/scsi/beiscsi/be_mgmt.c | 369 ++++++++++++++++++++++++++++++++++++++++ drivers/scsi/beiscsi/be_mgmt.h | 260 ++++++++++++++++++++++++++++ 2 files changed, 629 insertions(+), 0 deletions(-) create mode 100644 drivers/scsi/beiscsi/be_mgmt.c create mode 100644 drivers/scsi/beiscsi/be_mgmt.h
drivers/scsi/beiscsi/be_mgmt.c new file +369 -0
@@ -0,0 +1,369 @@ +/* +* Copyright (C) 2005 - 2009 ServerEngines +* 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. +* +* Written by: Jayamohan Kallickal ([email protected]) +* +* Contact Information: +* [email protected] +* +* ServerEngines +* 209 N. Fair Oaks Ave +* Sunnyvale, CA 94085 +* +*/ + +#include "be_mgmt.h" +#include "be_iscsi.h" + +/* All the mbox stuff */ + +unsigned char mgmt_get_fw_config (struct be_ctrl_info *ctrl, +struct beiscsi_hba *phba) +{ +struct be_mcc_wrb *wrb =wrb_from_mbox (&ctrl->mbox_mem); +struct be_fw_cfg *req =embedded_payload (wrb); +int status =0 ; + +spin_lock (&ctrl->mbox_lock); +memset (wrb,0 ,sizeof (*wrb)); + +be_wrb_hdr_prepare (wrb,sizeof (*req), true,0 ); + +be_cmd_hdr_prepare (&req->hdr,CMD_SUBSYSTEM_COMMON , +OPCODE_COMMON_QUERY_FIRMWARE_CONFIG ,sizeof (*req)); + + status =be_mbox_notify (ctrl); +if (!status) { +struct be_fw_cfg *pfw_cfg; + pfw_cfg = (struct be_fw_cfg *)req; + phba->fw_config.phys_port = pfw_cfg->phys_port; + phba->fw_config.iscsi_icd_start = + pfw_cfg->ulp[0 ].icd_base; + phba->fw_config.iscsi_icd_count = + pfw_cfg->ulp[0 ].icd_count; + phba->fw_config.iscsi_cid_start = + pfw_cfg->ulp[0 ].sq_base; + phba->fw_config.iscsi_cid_count = + pfw_cfg->ulp[0 ].sq_count; + }else { +dev_warn (&phba->pcidev->dev, +"Failed in mgmt_get_fw_config \n" ); + } + +spin_unlock (&ctrl->mbox_lock); +return status; +} +unsigned char mgmt_check_supported_fw (struct be_ctrl_info *ctrl) +{ +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 ) { +SE_DEBUG (DBG_LVL_1 , +"Failed to allocate memory for mgmt_check_supported_fw" +"\n" ); +return -1 ; + } + nonemb_cmd.size =sizeof (struct be_mgmt_controller_attributes ); + req = nonemb_cmd.va; +spin_lock (&ctrl->mbox_lock); +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; +SE_DEBUG (DBG_LVL_8 ,"Firmware version of CMD: %s\n" , + resp->params.hba_attribs.flashrom_version_string); +SE_DEBUG (DBG_LVL_8 ,"Firmware version is : %s\n" , + resp->params.hba_attribs.firmware_version_string); +SE_DEBUG (DBG_LVL_8 , +"Developer Build, not performing version check...\n" ); + + }else { +SE_DEBUG (DBG_LVL_1 , +" Failed in mgmt_check_supported_fw\n" ); + } +if (nonemb_cmd.va) +pci_free_consistent (ctrl->pdev, nonemb_cmd.size, + nonemb_cmd.va, nonemb_cmd.dma); + +spin_unlock (&ctrl->mbox_lock); +return status; +} + +unsigned char mgmt_set_fragnum_bits (struct beiscsi_hba *phba, +unsigned int num_bits) +{ +struct be_ctrl_info *ctrl = &phba->ctrl; +struct be_mcc_wrb *wrb =wrb_from_mbox (&ctrl->mbox_mem); +struct fragnum_bits_for_sgl_cra_in *req =embedded_payload (wrb); +int status =0 ; + +spin_lock (&ctrl->mbox_lock); +memset (wrb,0 ,sizeof (*wrb)); + +be_wrb_hdr_prepare (wrb,sizeof (*req), true,0 ); + +be_cmd_hdr_prepare (&req->hdr,CMD_SUBSYSTEM_COMMON , +OPCODE_COMMON_ISCSI_SET_FRAGNUM_BITS_FOR_SGL_CRA , +sizeof (*req)); + req->num_bits = num_bits; + status =be_mbox_notify (ctrl); +if (status) +dev_warn (&phba->pcidev->dev, +" mgmt_set_fragnum_bits , FAILED\n" ); + +spin_unlock (&ctrl->mbox_lock); +return status; + +} +unsigned char +mgmt_modify_eq_delay (struct beiscsi_hba *phba, +unsigned int eq_id,unsigned int new_delay) +{ +struct be_ctrl_info *ctrl = &phba->ctrl; +struct be_mcc_wrb *wrb =wrb_from_mbox (&ctrl->mbox_mem); +struct be_eq_delay_params_in *req =embedded_payload (wrb); +int status =0 ; + +spin_lock (&ctrl->mbox_lock); +memset (wrb,0 ,sizeof (*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 =1 ; + req->delay[0 ].eq_id = eq_id; + req->delay[0 ].phase =0 ; + req->delay[0 ].delay_multiplier = new_delay; + + status =be_mbox_notify (ctrl); +if (status) +dev_warn (&phba->pcidev->dev, +" mgmt_modify_eq_delay , FAILED\n" ); + +spin_unlock (&ctrl->mbox_lock); +return status; + +} +unsigned char mgmt_epfw_cleanup (struct beiscsi_hba *phba,unsigned short chute) +{ +struct be_ctrl_info *ctrl = &phba->ctrl; +struct be_mcc_wrb *wrb =wrb_from_mbox (&ctrl->mbox_mem); +struct iscsi_cleanup_req *req =embedded_payload (wrb); +int status =0 ; + +spin_lock (&ctrl->mbox_lock); +memset (wrb,0 ,sizeof (*wrb)); + +be_wrb_hdr_prepare (wrb,sizeof (*req), true,0 ); + +be_cmd_hdr_prepare (&req->hdr,CMD_SUBSYSTEM_ISCSI , +OPCODE_COMMON_ISCSI_CLEANUP ,sizeof (*req)); + + req->chute = chute; + req->hdr_ring_id =0 ; + req->data_ring_id =0 ; + + status =be_mbox_notify (ctrl); +if (status) +dev_warn (&phba->pcidev->dev, +" mgmt_epfw_cleanup , FAILED\n" ); + +spin_unlock (&ctrl->mbox_lock); +return status; +} + +unsigned char mgmt_invalidate_icds (struct beiscsi_hba *phba, +unsigned int icd,unsigned int cid) +{ +struct be_dma_mem nonemb_cmd; +struct be_ctrl_info *ctrl = &phba->ctrl; +struct be_mcc_wrb *wrb =wrb_from_mbox (&ctrl->mbox_mem); +struct be_sge *sge =nonembedded_sgl (wrb); +struct invalidate_commands_params_in *req; +int status =0 ; + + nonemb_cmd.va =pci_alloc_consistent (ctrl->pdev, +sizeof (struct invalidate_commands_params_in ), + &nonemb_cmd.dma); +if (nonemb_cmd.va ==NULL ) { +SE_DEBUG (DBG_LVL_1 , +"Failed to allocate memory for" +"mgmt_check_supported_fw \n" ); +return -1 ; + } + nonemb_cmd.size =sizeof (struct invalidate_commands_params_in ); + req = nonemb_cmd.va; +spin_lock (&ctrl->mbox_lock); +memset (wrb,0 ,sizeof (*wrb)); + +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 ; + req->icd_count =0 ; + req->table[req->icd_count].icd = icd; + req->table[req->icd_count].cid = cid; + 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) +SE_DEBUG (DBG_LVL_1 ,"ICDS Invalidation Failed\n" ); + +spin_unlock (&ctrl->mbox_lock); +if (nonemb_cmd.va) +pci_free_consistent (ctrl->pdev, nonemb_cmd.size, + nonemb_cmd.va, nonemb_cmd.dma); +return status; +} + +unsigned char mgmt_invalidate_connection (struct beiscsi_hba *phba, +struct beiscsi_endpoint *beiscsi_ep, +unsigned short cid, +unsigned short issue_reset, +unsigned short savecfg_flag) +{ +struct be_ctrl_info *ctrl = &phba->ctrl; +struct be_mcc_wrb *wrb =wrb_from_mbox (&ctrl->mbox_mem); +struct iscsi_invalidate_connection_params_in *req = +embedded_payload (wrb); +int status =0 ; + +spin_lock (&ctrl->mbox_lock); +memset (wrb,0 ,sizeof (*wrb)); + +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; + status =be_mbox_notify (ctrl); +if (status) +SE_DEBUG (DBG_LVL_1 ,"Invalidation Failed\n" ); + +spin_unlock (&ctrl->mbox_lock); +return status; +} + +unsigned char mgmt_upload_connection (struct beiscsi_hba *phba, +unsigned short cid,unsigned int upload_flag) +{ + +struct be_ctrl_info *ctrl = &phba->ctrl; +struct be_mcc_wrb *wrb =wrb_from_mbox (&ctrl->mbox_mem); +struct tcp_upload_params_in *req =embedded_payload (wrb); +int status =0 ; + +spin_lock (&ctrl->mbox_lock); +memset (wrb,0 ,sizeof (*wrb)); + +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; + status =be_mbox_notify (ctrl); +if (status) +SE_DEBUG (DBG_LVL_1 ,"mgmt_upload_connection Failed\n" ); + +spin_unlock (&ctrl->mbox_lock); +return status; + +} + +unsigned int mgmt_open_connection (struct beiscsi_hba *phba,__be32 s_addr, +__be16 sin_port,unsigned short cid) +{ +struct hwi_controller_ws *phwc; +struct hwi_context_memory *phwi_context; +struct be_ctrl_info *ctrl = &phba->ctrl; +struct be_mcc_wrb *wrb =wrb_from_mbox (&ctrl->mbox_mem); +struct tcp_connect_and_offload_in *req =embedded_payload (wrb); +unsigned short def_hdr_id; +unsigned short def_data_id; +struct phys_addr template_address = {0 ,0 }; +struct phys_addr *ptemplate_address; +int status =0 ; + + phwc =GET_HWI_CONTROLLER_WS (phba); + phwi_context = phwc->phwic; + def_hdr_id = (unsigned short )HWI_GET_DEF_HDRQ_ID (phba); + def_data_id = (unsigned short )HWI_GET_DEF_BUFQ_ID (phba); + + ptemplate_address = &template_address; +ISCSI_GET_PDU_TEMPLATE_ADDRESS (phba, ptemplate_address); +spin_lock (&ctrl->mbox_lock); +memset (wrb,0 ,sizeof (*wrb)); + +be_wrb_hdr_prepare (wrb,sizeof (*req), true,0 ); +be_cmd_hdr_prepare (&req->hdr,CMD_SUBSYSTEM_ISCSI , +OPCODE_COMMON_ISCSI_TCP_CONNECT_AND_OFFLOAD , +sizeof (*req)); + + req->ip_address.ip_type =1 ; + req->ip_address.ip_address[0 ] = s_addr &0x000000ff ; + req->ip_address.ip_address[1 ] = (s_addr &0x0000ff00 ) >>8 ; + req->ip_address.ip_address[2 ] = (s_addr &0x00ff0000 ) >>16 ; + req->ip_address.ip_address[3 ] = (s_addr &0xff000000 ) >>24 ; + req->tcp_port = sin_port; + req->cid = cid; + req->cq_id = phwi_context->be_cq.id; + 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; + status =be_mbox_notify (ctrl); +if (!status) { +struct iscsi_endpoint *ep; +struct beiscsi_endpoint *beiscsi_ep; +struct tcp_connect_and_offload_out *ptcpcnct_out = +embedded_payload (wrb); + ep = (struct iscsi_endpoint *)phba->ep_array[ptcpcnct_out->cid]; + beiscsi_ep = ep->dd_data; + beiscsi_ep->fw_handle =0 ; + beiscsi_ep->cid_vld =1 ; +SE_DEBUG (DBG_LVL_8 ,"mgmt_open_connection Success\n" ); + }else { +SE_DEBUG (DBG_LVL_1 ,"mgmt_open_connection Failed\n" ); + } +spin_unlock (&ctrl->mbox_lock); +return status; + +}
drivers/scsi/beiscsi/be_mgmt.h new file +260 -0
260 lines not on this page · raw message
Signature · 1 line
1.6.3