Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit aeb3c817 authored by James Smart's avatar James Smart Committed by Christoph Hellwig
Browse files

Add Fabric assigned WWN support.



Adding support for Fabric assigned WWPN and WWNN.

Firmware sends first FLOGI to fabric with vendor version changes.
On link up driver gets updated service parameter with FAWWN assigned port
name.  Driver sends 2nd FLOGI with updated fawwpn and modifies the
vport->fc_portname in driver.

Note:
Soft wwpn will not be allowed when fawwpn is enabled.

Signed-off-by: default avatarDick Kennedy <dick.kennedy@broadcom.com>
Signed-off-by: default avatarJames Smart <james.smart@broadcom.com>
Reviewed-by: default avatarJohannes Thumshirn <jthumshirn@suse.de>
parent 4d4c4a4a
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -474,6 +474,8 @@ struct lpfc_vport {
	unsigned long rcv_buffer_time_stamp;
	uint32_t vport_flag;
#define STATIC_VPORT	1
#define FAWWPN_SET	2
#define FAWWPN_PARAM_CHG	4

	uint16_t fdmi_num_disc;
	uint32_t fdmi_hba_mask;
+8 −0
Original line number Diff line number Diff line
@@ -2292,6 +2292,8 @@ lpfc_soft_wwn_enable_store(struct device *dev, struct device_attribute *attr,
	struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;
	struct lpfc_hba   *phba = vport->phba;
	unsigned int cnt = count;
	uint8_t vvvl = vport->fc_sparam.cmn.valid_vendor_ver_level;
	u32 *fawwpn_key = (uint32_t *)&vport->fc_sparam.un.vendorVersion[0];

	/*
	 * We're doing a simple sanity check for soft_wwpn setting.
@@ -2305,6 +2307,12 @@ lpfc_soft_wwn_enable_store(struct device *dev, struct device_attribute *attr,
	 * here. The intent is to protect against the random user or
	 * application that is just writing attributes.
	 */
	if (vvvl == 1 && cpu_to_be32(*fawwpn_key) == FAPWWN_KEY_VENDOR) {
		lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
				 "0051 "LPFC_DRIVER_NAME" soft wwpn can not"
				 " be enabled: fawwpn is enabled\n");
		return -EINVAL;
	}

	/* count may include a LF at end of string */
	if (buf[cnt-1] == '\n')
+5 −3
Original line number Diff line number Diff line
@@ -603,9 +603,11 @@ lpfc_check_clean_addr_bit(struct lpfc_vport *vport,
		memcmp(&vport->fabric_portname, &sp->portName,
			sizeof(struct lpfc_name)) ||
		memcmp(&vport->fabric_nodename, &sp->nodeName,
			sizeof(struct lpfc_name)))
			sizeof(struct lpfc_name)) ||
		(vport->vport_flag & FAWWPN_PARAM_CHG)) {
		fabric_param_changed = 1;

		vport->vport_flag &= ~FAWWPN_PARAM_CHG;
	}
	/*
	 * Word 1 Bit 31 in common service parameter is overloaded.
	 * Word 1 Bit 31 in FLOGI request is multiple NPort request
@@ -8755,7 +8757,7 @@ lpfc_issue_els_fdisc(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
	pcmd += sizeof(uint32_t); /* Node Name */
	pcmd += sizeof(uint32_t); /* Node Name */
	memcpy(pcmd, &vport->fc_nodename, 8);

	memset(sp->un.vendorVersion, 0, sizeof(sp->un.vendorVersion));
	lpfc_set_disctmo(vport);

	phba->fc_stat.elsXmitFDISC++;
+18 −6
Original line number Diff line number Diff line
@@ -3002,6 +3002,7 @@ lpfc_mbx_cmpl_read_sparam(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb)
	MAILBOX_t *mb = &pmb->u.mb;
	struct lpfc_dmabuf *mp = (struct lpfc_dmabuf *) pmb->context1;
	struct lpfc_vport  *vport = pmb->vport;
	struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
	struct serv_parm *sp = &vport->fc_sparam;
	uint32_t ed_tov;

@@ -3031,6 +3032,7 @@ lpfc_mbx_cmpl_read_sparam(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb)
	}

	lpfc_update_vport_wwn(vport);
	fc_host_port_name(shost) = wwn_to_u64(vport->fc_portname.u.wwn);
	if (vport->port_type == LPFC_PHYSICAL_PORT) {
		memcpy(&phba->wwnn, &vport->fc_nodename, sizeof(phba->wwnn));
		memcpy(&phba->wwpn, &vport->fc_portname, sizeof(phba->wwnn));
@@ -3309,6 +3311,7 @@ lpfc_mbx_cmpl_read_topology(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb)
	struct lpfc_sli_ring *pring;
	MAILBOX_t *mb = &pmb->u.mb;
	struct lpfc_dmabuf *mp = (struct lpfc_dmabuf *) (pmb->context1);
	uint8_t attn_type;

	/* Unblock ELS traffic */
	pring = lpfc_phba_elsring(phba);
@@ -3325,6 +3328,7 @@ lpfc_mbx_cmpl_read_topology(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb)
	}

	la = (struct lpfc_mbx_read_top *) &pmb->u.mb.un.varReadTop;
	attn_type = bf_get(lpfc_mbx_read_top_att_type, la);

	memcpy(&phba->alpa_map[0], mp->virt, 128);

@@ -3337,7 +3341,7 @@ lpfc_mbx_cmpl_read_topology(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb)

	if (phba->fc_eventTag <= la->eventTag) {
		phba->fc_stat.LinkMultiEvent++;
		if (bf_get(lpfc_mbx_read_top_att_type, la) == LPFC_ATT_LINK_UP)
		if (attn_type == LPFC_ATT_LINK_UP)
			if (phba->fc_eventTag != 0)
				lpfc_linkdown(phba);
	}
@@ -3353,7 +3357,7 @@ lpfc_mbx_cmpl_read_topology(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb)
	}

	phba->link_events++;
	if ((bf_get(lpfc_mbx_read_top_att_type, la) == LPFC_ATT_LINK_UP) &&
	if ((attn_type == LPFC_ATT_LINK_UP) &&
	    !(phba->sli.sli_flag & LPFC_MENLO_MAINT)) {
		phba->fc_stat.LinkUp++;
		if (phba->link_flag & LS_LOOPBACK_MODE) {
@@ -3379,8 +3383,8 @@ lpfc_mbx_cmpl_read_topology(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb)
					phba->wait_4_mlo_maint_flg);
		}
		lpfc_mbx_process_link_up(phba, la);
	} else if (bf_get(lpfc_mbx_read_top_att_type, la) ==
		   LPFC_ATT_LINK_DOWN) {
	} else if (attn_type == LPFC_ATT_LINK_DOWN ||
		   attn_type == LPFC_ATT_UNEXP_WWPN) {
		phba->fc_stat.LinkDown++;
		if (phba->link_flag & LS_LOOPBACK_MODE)
			lpfc_printf_log(phba, KERN_ERR, LOG_LINK_EVENT,
@@ -3389,6 +3393,14 @@ lpfc_mbx_cmpl_read_topology(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb)
				"Data: x%x x%x x%x\n",
				la->eventTag, phba->fc_eventTag,
				phba->pport->port_state, vport->fc_flag);
		else if (attn_type == LPFC_ATT_UNEXP_WWPN)
			lpfc_printf_log(phba, KERN_ERR, LOG_LINK_EVENT,
				"1313 Link Down UNEXP WWPN Event x%x received "
				"Data: x%x x%x x%x x%x x%x\n",
				la->eventTag, phba->fc_eventTag,
				phba->pport->port_state, vport->fc_flag,
				bf_get(lpfc_mbx_read_top_mm, la),
				bf_get(lpfc_mbx_read_top_fa, la));
		else
			lpfc_printf_log(phba, KERN_ERR, LOG_LINK_EVENT,
				"1305 Link Down Event x%x received "
@@ -3399,8 +3411,8 @@ lpfc_mbx_cmpl_read_topology(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb)
				bf_get(lpfc_mbx_read_top_fa, la));
		lpfc_mbx_issue_link_down(phba);
	}
	if ((phba->sli.sli_flag & LPFC_MENLO_MAINT) &&
	    ((bf_get(lpfc_mbx_read_top_att_type, la) == LPFC_ATT_LINK_UP))) {
	if (phba->sli.sli_flag & LPFC_MENLO_MAINT &&
	    attn_type == LPFC_ATT_LINK_UP) {
		if (phba->link_state != LPFC_LINK_DOWN) {
			phba->fc_stat.LinkDown++;
			lpfc_printf_log(phba, KERN_ERR, LOG_LINK_EVENT,
+3 −0
Original line number Diff line number Diff line
@@ -509,6 +509,8 @@ struct class_parms {
	uint8_t word3Reserved2;	/* Fc Word 3, bit  0: 7 */
};

#define FAPWWN_KEY_VENDOR	0x42524344 /*valid vendor version fawwpn key*/

struct serv_parm {	/* Structure is in Big Endian format */
	struct csp cmn;
	struct lpfc_name portName;
@@ -2885,6 +2887,7 @@ struct lpfc_mbx_read_top {
#define LPFC_ATT_RESERVED    0x00	/* Reserved - attType */
#define LPFC_ATT_LINK_UP     0x01	/* Link is up */
#define LPFC_ATT_LINK_DOWN   0x02	/* Link is down */
#define LPFC_ATT_UNEXP_WWPN  0x06	/* Link is down Unexpected WWWPN */
	uint32_t word3;
#define lpfc_mbx_read_top_alpa_granted_SHIFT	24
#define lpfc_mbx_read_top_alpa_granted_MASK	0x000000FF
Loading