/**
- * Copyright (C) 2005 - 2015 Emulex
+ * Copyright (C) 2005 - 2016 Broadcom
* All rights reserved.
*
* This program is free software; you can redistribute it and/or
* 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 (jayamohan.kallickal@avagotech.com)
+ * Written by: Jayamohan Kallickal (jayamohan.kallickal@broadcom.com)
*
* Contact Information:
- * linux-drivers@avagotech.com
+ * linux-drivers@broadcom.com
*
* Emulex
* 3333 Susan Street
#include "be_iscsi.h"
#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_detect()- 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;
-
- 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) {
- set_bit(BEISCSI_HBA_IN_UE, &phba->state);
- 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]);
- }
- }
-}
-
int beiscsi_modify_eq_delay(struct beiscsi_hba *phba,
struct be_set_eqd *set_eqd,
int num)
return tag;
}
-/**
- * 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;
-}
-
-/**
- * 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
- **/
-int 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 *pfw_cfg = embedded_payload(wrb);
- uint32_t cid_count, icd_count;
- int status = -EINVAL;
- uint8_t ulp_num = 0;
-
- mutex_lock(&ctrl->mbox_lock);
- memset(wrb, 0, sizeof(*wrb));
- be_wrb_hdr_prepare(wrb, sizeof(*pfw_cfg), true, 0);
-
- be_cmd_hdr_prepare(&pfw_cfg->hdr, CMD_SUBSYSTEM_COMMON,
- OPCODE_COMMON_QUERY_FIRMWARE_CONFIG,
- EMBED_MBX_MAX_PAYLOAD_SIZE);
-
- 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",
- phba->fw_config.cqid_count);
- goto fail_init;
- }
- 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);
- }
-
- /**
- * 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"
- "\tiscsi_cid_count : %d\n"
- "\tiscsi_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]);
- }
- }
-
- 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;
- }
-
- /**
- * 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;
- }
-
- cid_count = BEISCSI_GET_CID_COUNT(phba, BEISCSI_ULP0) +
- BEISCSI_GET_CID_COUNT(phba, BEISCSI_ULP1);
- if (cid_count == 0 || cid_count > 4096) {
- beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_INIT,
- "BG_%d: invalid CID count %d\n", cid_count);
- goto fail_init;
- }
-
- /**
- * 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:
- mutex_unlock(&ctrl->mbox_lock);
- return status;
-}
-
-int mgmt_check_supported_fw(struct be_ctrl_info *ctrl,
- struct beiscsi_hba *phba)
-{
- 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) {
- beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_INIT,
- "BG_%d : Failed to allocate memory for "
- "mgmt_check_supported_fw\n");
- return -ENOMEM;
- }
- nonemb_cmd.size = sizeof(struct be_mgmt_controller_attributes);
- req = nonemb_cmd.va;
- memset(req, 0, sizeof(*req));
- mutex_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;
- 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);
-
- phba->fw_config.iscsi_features =
- resp->params.hba_attribs.iscsi_features;
- beiscsi_log(phba, KERN_INFO, BEISCSI_LOG_INIT,
- "BM_%d : phba->fw_config.iscsi_features = %d\n",
- phba->fw_config.iscsi_features);
- memcpy(phba->fw_ver_str, resp->params.hba_attribs.
- firmware_version_string, BEISCSI_VER_STRLEN);
- } else
- beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_INIT,
- "BG_%d : Failed in mgmt_check_supported_fw\n");
- mutex_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 int mgmt_vendor_specific_fw_cmd(struct be_ctrl_info *ctrl,
struct beiscsi_hba *phba,
struct bsg_job *job,
return tag;
}
-/**
- * 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)
-{
- struct be_ctrl_info *ctrl = &phba->ctrl;
- struct be_mcc_wrb *wrb;
- struct iscsi_cleanup_req *req;
- unsigned int tag;
- int status;
-
- mutex_lock(&ctrl->mbox_lock);
- wrb = alloc_mcc_wrb(phba, &tag);
- if (!wrb) {
- mutex_unlock(&ctrl->mbox_lock);
- return -EBUSY;
- }
-
- req = embedded_payload(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 = (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));
-
- be_mcc_notify(phba, tag);
- status = be_mcc_compl_poll(phba, tag);
- if (status)
- beiscsi_log(phba, KERN_WARNING, BEISCSI_LOG_INIT,
- "BG_%d : mgmt_epfw_cleanup , FAILED\n");
- mutex_unlock(&ctrl->mbox_lock);
- return status;
-}
-
unsigned int mgmt_invalidate_icds(struct beiscsi_hba *phba,
struct invalidate_command_table *inv_tbl,
unsigned int num_invalidate, unsigned int cid,
if (!is_chip_be2_be3r(phba)) {
req->hdr.version = MBX_CMD_VER1;
- req->tcp_window_size = 0;
+ req->tcp_window_size = 0x8000;
req->tcp_window_scale_count = 2;
}
nonemb_cmd->va = pci_alloc_consistent(phba->ctrl.pdev,
sizeof(nonemb_cmd->size),
&nonemb_cmd->dma);
- if (!nonemb_cmd->va)
+ if (!nonemb_cmd->va) {
+ mutex_unlock(&ctrl->mbox_lock);
return 0;
+ }
req = nonemb_cmd->va;
memset(req, 0, sizeof(*req));
{
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,
{
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,