|
@@ -4691,6 +4691,175 @@ lpfc_sli4_read_rev(struct lpfc_hba *phba, LPFC_MBOXQ_t *mboxq,
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
+/**
|
|
|
+ * lpfc_sli4_retrieve_pport_name - Retrieve SLI4 device physical port name
|
|
|
+ * @phba: pointer to lpfc hba data structure.
|
|
|
+ *
|
|
|
+ * This routine retrieves SLI4 device physical port name this PCI function
|
|
|
+ * is attached to.
|
|
|
+ *
|
|
|
+ * Return codes
|
|
|
+ * 0 - sucessful
|
|
|
+ * otherwise - failed to retrieve physical port name
|
|
|
+ **/
|
|
|
+static int
|
|
|
+lpfc_sli4_retrieve_pport_name(struct lpfc_hba *phba)
|
|
|
+{
|
|
|
+ LPFC_MBOXQ_t *mboxq;
|
|
|
+ struct lpfc_mbx_read_config *rd_config;
|
|
|
+ struct lpfc_mbx_get_cntl_attributes *mbx_cntl_attr;
|
|
|
+ struct lpfc_controller_attribute *cntl_attr;
|
|
|
+ struct lpfc_mbx_get_port_name *get_port_name;
|
|
|
+ void *virtaddr = NULL;
|
|
|
+ uint32_t alloclen, reqlen;
|
|
|
+ uint32_t shdr_status, shdr_add_status;
|
|
|
+ union lpfc_sli4_cfg_shdr *shdr;
|
|
|
+ char cport_name = 0;
|
|
|
+ int rc;
|
|
|
+
|
|
|
+ /* We assume nothing at this point */
|
|
|
+ phba->sli4_hba.lnk_info.lnk_dv = LPFC_LNK_DAT_INVAL;
|
|
|
+ phba->sli4_hba.pport_name_sta = LPFC_SLI4_PPNAME_NON;
|
|
|
+
|
|
|
+ mboxq = (LPFC_MBOXQ_t *)mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL);
|
|
|
+ if (!mboxq)
|
|
|
+ return -ENOMEM;
|
|
|
+
|
|
|
+ /* obtain link type and link number via READ_CONFIG */
|
|
|
+ lpfc_read_config(phba, mboxq);
|
|
|
+ rc = lpfc_sli_issue_mbox(phba, mboxq, MBX_POLL);
|
|
|
+ if (rc == MBX_SUCCESS) {
|
|
|
+ rd_config = &mboxq->u.mqe.un.rd_config;
|
|
|
+ if (bf_get(lpfc_mbx_rd_conf_lnk_ldv, rd_config)) {
|
|
|
+ phba->sli4_hba.lnk_info.lnk_dv = LPFC_LNK_DAT_VAL;
|
|
|
+ phba->sli4_hba.lnk_info.lnk_tp =
|
|
|
+ bf_get(lpfc_mbx_rd_conf_lnk_type, rd_config);
|
|
|
+ phba->sli4_hba.lnk_info.lnk_no =
|
|
|
+ bf_get(lpfc_mbx_rd_conf_lnk_numb, rd_config);
|
|
|
+ lpfc_printf_log(phba, KERN_INFO, LOG_SLI,
|
|
|
+ "3081 lnk_type:%d, lnk_numb:%d\n",
|
|
|
+ phba->sli4_hba.lnk_info.lnk_tp,
|
|
|
+ phba->sli4_hba.lnk_info.lnk_no);
|
|
|
+ goto retrieve_ppname;
|
|
|
+ } else
|
|
|
+ lpfc_printf_log(phba, KERN_WARNING, LOG_SLI,
|
|
|
+ "3082 Mailbox (x%x) returned ldv:x0\n",
|
|
|
+ bf_get(lpfc_mqe_command,
|
|
|
+ &mboxq->u.mqe));
|
|
|
+ } else
|
|
|
+ lpfc_printf_log(phba, KERN_WARNING, LOG_SLI,
|
|
|
+ "3083 Mailbox (x%x) failed, status:x%x\n",
|
|
|
+ bf_get(lpfc_mqe_command, &mboxq->u.mqe),
|
|
|
+ bf_get(lpfc_mqe_status, &mboxq->u.mqe));
|
|
|
+
|
|
|
+ /* obtain link type and link number via COMMON_GET_CNTL_ATTRIBUTES */
|
|
|
+ reqlen = sizeof(struct lpfc_mbx_get_cntl_attributes);
|
|
|
+ alloclen = lpfc_sli4_config(phba, mboxq, LPFC_MBOX_SUBSYSTEM_COMMON,
|
|
|
+ LPFC_MBOX_OPCODE_GET_CNTL_ATTRIBUTES, reqlen,
|
|
|
+ LPFC_SLI4_MBX_NEMBED);
|
|
|
+ if (alloclen < reqlen) {
|
|
|
+ lpfc_printf_log(phba, KERN_ERR, LOG_SLI,
|
|
|
+ "3084 Allocated DMA memory size (%d) is "
|
|
|
+ "less than the requested DMA memory size "
|
|
|
+ "(%d)\n", alloclen, reqlen);
|
|
|
+ rc = -ENOMEM;
|
|
|
+ goto out_free_mboxq;
|
|
|
+ }
|
|
|
+ rc = lpfc_sli_issue_mbox(phba, mboxq, MBX_POLL);
|
|
|
+ virtaddr = mboxq->sge_array->addr[0];
|
|
|
+ mbx_cntl_attr = (struct lpfc_mbx_get_cntl_attributes *)virtaddr;
|
|
|
+ shdr = &mbx_cntl_attr->cfg_shdr;
|
|
|
+ shdr_status = bf_get(lpfc_mbox_hdr_status, &shdr->response);
|
|
|
+ shdr_add_status = bf_get(lpfc_mbox_hdr_add_status, &shdr->response);
|
|
|
+ if (shdr_status || shdr_add_status || rc) {
|
|
|
+ lpfc_printf_log(phba, KERN_WARNING, LOG_SLI,
|
|
|
+ "3085 Mailbox x%x (x%x/x%x) failed, "
|
|
|
+ "rc:x%x, status:x%x, add_status:x%x\n",
|
|
|
+ bf_get(lpfc_mqe_command, &mboxq->u.mqe),
|
|
|
+ lpfc_sli_config_mbox_subsys_get(phba, mboxq),
|
|
|
+ lpfc_sli_config_mbox_opcode_get(phba, mboxq),
|
|
|
+ rc, shdr_status, shdr_add_status);
|
|
|
+ rc = -ENXIO;
|
|
|
+ goto out_free_mboxq;
|
|
|
+ }
|
|
|
+ cntl_attr = &mbx_cntl_attr->cntl_attr;
|
|
|
+ phba->sli4_hba.lnk_info.lnk_dv = LPFC_LNK_DAT_VAL;
|
|
|
+ phba->sli4_hba.lnk_info.lnk_tp =
|
|
|
+ bf_get(lpfc_cntl_attr_lnk_type, cntl_attr);
|
|
|
+ phba->sli4_hba.lnk_info.lnk_no =
|
|
|
+ bf_get(lpfc_cntl_attr_lnk_numb, cntl_attr);
|
|
|
+ lpfc_printf_log(phba, KERN_INFO, LOG_SLI,
|
|
|
+ "3086 lnk_type:%d, lnk_numb:%d\n",
|
|
|
+ phba->sli4_hba.lnk_info.lnk_tp,
|
|
|
+ phba->sli4_hba.lnk_info.lnk_no);
|
|
|
+
|
|
|
+retrieve_ppname:
|
|
|
+ lpfc_sli4_config(phba, mboxq, LPFC_MBOX_SUBSYSTEM_COMMON,
|
|
|
+ LPFC_MBOX_OPCODE_GET_PORT_NAME,
|
|
|
+ sizeof(struct lpfc_mbx_get_port_name) -
|
|
|
+ sizeof(struct lpfc_sli4_cfg_mhdr),
|
|
|
+ LPFC_SLI4_MBX_EMBED);
|
|
|
+ get_port_name = &mboxq->u.mqe.un.get_port_name;
|
|
|
+ shdr = (union lpfc_sli4_cfg_shdr *)&get_port_name->header.cfg_shdr;
|
|
|
+ bf_set(lpfc_mbox_hdr_version, &shdr->request, LPFC_OPCODE_VERSION_1);
|
|
|
+ bf_set(lpfc_mbx_get_port_name_lnk_type, &get_port_name->u.request,
|
|
|
+ phba->sli4_hba.lnk_info.lnk_tp);
|
|
|
+ rc = lpfc_sli_issue_mbox(phba, mboxq, MBX_POLL);
|
|
|
+ shdr_status = bf_get(lpfc_mbox_hdr_status, &shdr->response);
|
|
|
+ shdr_add_status = bf_get(lpfc_mbox_hdr_add_status, &shdr->response);
|
|
|
+ if (shdr_status || shdr_add_status || rc) {
|
|
|
+ lpfc_printf_log(phba, KERN_WARNING, LOG_SLI,
|
|
|
+ "3087 Mailbox x%x (x%x/x%x) failed: "
|
|
|
+ "rc:x%x, status:x%x, add_status:x%x\n",
|
|
|
+ bf_get(lpfc_mqe_command, &mboxq->u.mqe),
|
|
|
+ lpfc_sli_config_mbox_subsys_get(phba, mboxq),
|
|
|
+ lpfc_sli_config_mbox_opcode_get(phba, mboxq),
|
|
|
+ rc, shdr_status, shdr_add_status);
|
|
|
+ rc = -ENXIO;
|
|
|
+ goto out_free_mboxq;
|
|
|
+ }
|
|
|
+ switch (phba->sli4_hba.lnk_info.lnk_no) {
|
|
|
+ case LPFC_LINK_NUMBER_0:
|
|
|
+ cport_name = bf_get(lpfc_mbx_get_port_name_name0,
|
|
|
+ &get_port_name->u.response);
|
|
|
+ phba->sli4_hba.pport_name_sta = LPFC_SLI4_PPNAME_GET;
|
|
|
+ break;
|
|
|
+ case LPFC_LINK_NUMBER_1:
|
|
|
+ cport_name = bf_get(lpfc_mbx_get_port_name_name1,
|
|
|
+ &get_port_name->u.response);
|
|
|
+ phba->sli4_hba.pport_name_sta = LPFC_SLI4_PPNAME_GET;
|
|
|
+ break;
|
|
|
+ case LPFC_LINK_NUMBER_2:
|
|
|
+ cport_name = bf_get(lpfc_mbx_get_port_name_name2,
|
|
|
+ &get_port_name->u.response);
|
|
|
+ phba->sli4_hba.pport_name_sta = LPFC_SLI4_PPNAME_GET;
|
|
|
+ break;
|
|
|
+ case LPFC_LINK_NUMBER_3:
|
|
|
+ cport_name = bf_get(lpfc_mbx_get_port_name_name3,
|
|
|
+ &get_port_name->u.response);
|
|
|
+ phba->sli4_hba.pport_name_sta = LPFC_SLI4_PPNAME_GET;
|
|
|
+ break;
|
|
|
+ default:
|
|
|
+ break;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (phba->sli4_hba.pport_name_sta == LPFC_SLI4_PPNAME_GET) {
|
|
|
+ phba->Port[0] = cport_name;
|
|
|
+ phba->Port[1] = '\0';
|
|
|
+ lpfc_printf_log(phba, KERN_INFO, LOG_SLI,
|
|
|
+ "3091 SLI get port name: %s\n", phba->Port);
|
|
|
+ }
|
|
|
+
|
|
|
+out_free_mboxq:
|
|
|
+ if (rc != MBX_TIMEOUT) {
|
|
|
+ if (bf_get(lpfc_mqe_command, &mboxq->u.mqe) == MBX_SLI4_CONFIG)
|
|
|
+ lpfc_sli4_mbox_cmd_free(phba, mboxq);
|
|
|
+ else
|
|
|
+ mempool_free(mboxq, phba->mbox_mem_pool);
|
|
|
+ }
|
|
|
+ return rc;
|
|
|
+}
|
|
|
+
|
|
|
/**
|
|
|
* lpfc_sli4_arm_cqeq_intr - Arm sli-4 device completion and event queues
|
|
|
* @phba: pointer to lpfc hba data structure.
|
|
@@ -5754,6 +5923,17 @@ lpfc_sli4_hba_setup(struct lpfc_hba *phba)
|
|
|
kfree(vpd);
|
|
|
goto out_free_mbox;
|
|
|
}
|
|
|
+
|
|
|
+ /*
|
|
|
+ * Retrieve sli4 device physical port name, failure of doing it
|
|
|
+ * is considered as non-fatal.
|
|
|
+ */
|
|
|
+ rc = lpfc_sli4_retrieve_pport_name(phba);
|
|
|
+ if (!rc)
|
|
|
+ lpfc_printf_log(phba, KERN_INFO, LOG_MBOX | LOG_SLI,
|
|
|
+ "3080 Successful retrieving SLI4 device "
|
|
|
+ "physical port name: %s.\n", phba->Port);
|
|
|
+
|
|
|
/*
|
|
|
* Evaluate the read rev and vpd data. Populate the driver
|
|
|
* state with the results. If this routine fails, the failure
|