Commit 76a95d75 authored by James Smart's avatar James Smart Committed by James Bottomley
Browse files

[SCSI] lpfc 8.3.19: Add SLI4 FC Discovery support



Add SLI4 FC Discovery support

- Replace READ_LA and READ_LA64 with READ_TOPOLOGY mailbox command.
- Converted the old READ_LA structure to use bf_set/get instead of bit fields.
- Rename HBA_FCOE_SUPPORT flag to HBA_FCOE_MODE. Flag now indicates function
  is running as SLI-4 FC or FCoE port. Make sure flag reset each time
  READ_REV completed as it can dynamically change.
- Removed BDE union in the READ_TOPOLOGY mailbox command and added a define to
  define the ALPA MAP SIZE. Added FC Code for async events.
- Added code to support new 16G link speed.
- Define new set of values to keep track of valid user settable link speeds.
- Used new link speed definitions to define link speed max and bitmap.
- Redefined FDMI Port sppeds to be hax values and added the 16G value.
- Added new CQE trailer code for FC Events.
- Add lpfc_issue_init_vfi and lpfc_init_vfi_cmpl routines.
- Replace many calls to the initial_flogi routine with lpfc_issue_init_vfi.
- Add vp and vpi fields to the INIT_VFI mailbox command.
- Addapt lpfc_hba_init_link routine for SLI4 use.
- Use lpfc_hba_init_link call from lpfc_sli4_hba_setup.
- Add a check for FC mode to register the FCFI before init link.
- Convert lpfc_sli4_init_vpi to be called without a vpi (get it from vport).

Signed-off-by: default avatarAlex Iannicelli <alex.iannicelli@emulex.com>
Signed-off-by: default avatarJames Smart <james.smart@emulex.com>
Signed-off-by: default avatarJames Bottomley <James.Bottomley@suse.de>
parent 085c647c
Loading
Loading
Loading
Loading
+18 −1
Original line number Diff line number Diff line
@@ -464,6 +464,23 @@ struct unsol_rcv_ct_ctx {
#define UNSOL_VALID	0x00000001
};

#define LPFC_USER_LINK_SPEED_AUTO	0	/* auto select (default)*/
#define LPFC_USER_LINK_SPEED_1G		1	/* 1 Gigabaud */
#define LPFC_USER_LINK_SPEED_2G		2	/* 2 Gigabaud */
#define LPFC_USER_LINK_SPEED_4G		4	/* 4 Gigabaud */
#define LPFC_USER_LINK_SPEED_8G		8	/* 8 Gigabaud */
#define LPFC_USER_LINK_SPEED_10G	10	/* 10 Gigabaud */
#define LPFC_USER_LINK_SPEED_16G	16	/* 16 Gigabaud */
#define LPFC_USER_LINK_SPEED_MAX	LPFC_USER_LINK_SPEED_16G
#define LPFC_USER_LINK_SPEED_BITMAP ((1 << LPFC_USER_LINK_SPEED_16G) | \
				     (1 << LPFC_USER_LINK_SPEED_10G) | \
				     (1 << LPFC_USER_LINK_SPEED_8G) | \
				     (1 << LPFC_USER_LINK_SPEED_4G) | \
				     (1 << LPFC_USER_LINK_SPEED_2G) | \
				     (1 << LPFC_USER_LINK_SPEED_1G) | \
				     (1 << LPFC_USER_LINK_SPEED_AUTO))
#define LPFC_LINK_SPEED_STRING "0, 1, 2, 4, 8, 10, 16"

struct lpfc_hba {
	/* SCSI interface function jump table entries */
	int (*lpfc_new_scsi_buf)
@@ -545,7 +562,7 @@ struct lpfc_hba {
	uint32_t hba_flag;	/* hba generic flags */
#define HBA_ERATT_HANDLED	0x1 /* This flag is set when eratt handled */
#define DEFER_ERATT		0x2 /* Deferred error attention in progress */
#define HBA_FCOE_SUPPORT	0x4 /* HBA function supports FCOE */
#define HBA_FCOE_MODE		0x4 /* HBA function in FCoE Mode */
#define HBA_SP_QUEUE_EVT	0x8 /* Slow-path qevt posted to worker thread*/
#define HBA_POST_RECEIVE_BUFFER 0x10 /* Rcv buffers need to be posted */
#define FCP_XRI_ABORT_EVENT	0x20
+43 −48
Original line number Diff line number Diff line
@@ -52,10 +52,6 @@
#define LPFC_MIN_DEVLOSS_TMO 1
#define LPFC_MAX_DEVLOSS_TMO 255

#define LPFC_MAX_LINK_SPEED 8
#define LPFC_LINK_SPEED_BITMAP 0x00000117
#define LPFC_LINK_SPEED_STRING "0, 1, 2, 4, 8"

/**
 * lpfc_jedec_to_ascii - Hex to ascii convertor according to JEDEC rules
 * @incr: integer to convert.
@@ -463,7 +459,7 @@ lpfc_link_state_show(struct device *dev, struct device_attribute *attr,
		if (phba->sli.sli_flag & LPFC_MENLO_MAINT)
			len += snprintf(buf + len, PAGE_SIZE-len,
					"   Menlo Maint Mode\n");
		else if (phba->fc_topology == TOPOLOGY_LOOP) {
		else if (phba->fc_topology == LPFC_TOPOLOGY_LOOP) {
			if (vport->fc_flag & FC_PUBLIC_LOOP)
				len += snprintf(buf + len, PAGE_SIZE-len,
						"   Public Loop\n");
@@ -2837,14 +2833,8 @@ static struct bin_attribute sysfs_drvr_stat_data_attr = {
/*
# lpfc_link_speed: Link speed selection for initializing the Fibre Channel
# connection.
#       0  = auto select (default)
#       1  = 1 Gigabaud
#       2  = 2 Gigabaud
#       4  = 4 Gigabaud
#       8  = 8 Gigabaud
# Value range is [0,8]. Default value is 0.
# Value range is [0,16]. Default value is 0.
*/

/**
 * lpfc_link_speed_set - Set the adapters link speed
 * @phba: lpfc_hba pointer.
@@ -2869,7 +2859,7 @@ lpfc_link_speed_store(struct device *dev, struct device_attribute *attr,
	struct Scsi_Host  *shost = class_to_shost(dev);
	struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;
	struct lpfc_hba   *phba = vport->phba;
	int val = 0;
	int val = LPFC_USER_LINK_SPEED_AUTO;
	int nolip = 0;
	const char *val_buf = buf;
	int err;
@@ -2885,15 +2875,20 @@ lpfc_link_speed_store(struct device *dev, struct device_attribute *attr,
	if (sscanf(val_buf, "%i", &val) != 1)
		return -EINVAL;

	if (((val == LINK_SPEED_1G) && !(phba->lmt & LMT_1Gb)) ||
		((val == LINK_SPEED_2G) && !(phba->lmt & LMT_2Gb)) ||
		((val == LINK_SPEED_4G) && !(phba->lmt & LMT_4Gb)) ||
		((val == LINK_SPEED_8G) && !(phba->lmt & LMT_8Gb)) ||
		((val == LINK_SPEED_10G) && !(phba->lmt & LMT_10Gb)))
	if (((val == LPFC_USER_LINK_SPEED_1G) && !(phba->lmt & LMT_1Gb)) ||
	    ((val == LPFC_USER_LINK_SPEED_2G) && !(phba->lmt & LMT_2Gb)) ||
	    ((val == LPFC_USER_LINK_SPEED_4G) && !(phba->lmt & LMT_4Gb)) ||
	    ((val == LPFC_USER_LINK_SPEED_8G) && !(phba->lmt & LMT_8Gb)) ||
	    ((val == LPFC_USER_LINK_SPEED_10G) && !(phba->lmt & LMT_10Gb)) ||
	    ((val == LPFC_USER_LINK_SPEED_16G) && !(phba->lmt & LMT_16Gb))) {
		lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
				"2879 lpfc_link_speed attribute cannot be set "
				"to %d. Speed is not supported by this port.\n",
				val);
		return -EINVAL;

	if ((val >= 0 && val <= 8)
		&& (LPFC_LINK_SPEED_BITMAP & (1 << val))) {
	}
	if ((val >= 0) && (val <= LPFC_USER_LINK_SPEED_MAX) &&
	    (LPFC_USER_LINK_SPEED_BITMAP & (1 << val))) {
		prev_val = phba->cfg_link_speed;
		phba->cfg_link_speed = val;
		if (nolip)
@@ -2906,11 +2901,9 @@ lpfc_link_speed_store(struct device *dev, struct device_attribute *attr,
		} else
			return strlen(buf);
	}

	lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
		"%d:0469 lpfc_link_speed attribute cannot be set to %d, "
		"allowed range is [0, 8]\n",
		phba->brd_no, val);
		"0469 lpfc_link_speed attribute cannot be set to %d, "
		"allowed values are ["LPFC_LINK_SPEED_STRING"]\n", val);
	return -EINVAL;
}

@@ -2938,8 +2931,8 @@ lpfc_param_show(link_speed)
static int
lpfc_link_speed_init(struct lpfc_hba *phba, int val)
{
	if ((val >= 0 && val <= LPFC_MAX_LINK_SPEED)
		&& (LPFC_LINK_SPEED_BITMAP & (1 << val))) {
	if ((val >= 0) && (val <= LPFC_USER_LINK_SPEED_MAX) &&
	    (LPFC_USER_LINK_SPEED_BITMAP & (1 << val))) {
		phba->cfg_link_speed = val;
		return 0;
	}
@@ -2947,7 +2940,7 @@ lpfc_link_speed_init(struct lpfc_hba *phba, int val)
			"0405 lpfc_link_speed attribute cannot "
			"be set to %d, allowed values are "
			"["LPFC_LINK_SPEED_STRING"]\n", val);
	phba->cfg_link_speed = 0;
	phba->cfg_link_speed = LPFC_USER_LINK_SPEED_AUTO;
	return -EINVAL;
}

@@ -3798,8 +3791,7 @@ sysfs_mbox_read(struct file *filp, struct kobject *kobj,
			}
			break;
		case MBX_READ_SPARM64:
		case MBX_READ_LA:
		case MBX_READ_LA64:
		case MBX_READ_TOPOLOGY:
		case MBX_REG_LOGIN:
		case MBX_REG_LOGIN64:
		case MBX_CONFIG_PORT:
@@ -3989,7 +3981,7 @@ lpfc_get_host_port_type(struct Scsi_Host *shost)
	if (vport->port_type == LPFC_NPIV_PORT) {
		fc_host_port_type(shost) = FC_PORTTYPE_NPIV;
	} else if (lpfc_is_link_up(phba)) {
		if (phba->fc_topology == TOPOLOGY_LOOP) {
		if (phba->fc_topology == LPFC_TOPOLOGY_LOOP) {
			if (vport->fc_flag & FC_PUBLIC_LOOP)
				fc_host_port_type(shost) = FC_PORTTYPE_NLPORT;
			else
@@ -4058,21 +4050,24 @@ lpfc_get_host_speed(struct Scsi_Host *shost)

	if (lpfc_is_link_up(phba)) {
		switch(phba->fc_linkspeed) {
			case LA_1GHZ_LINK:
		case LPFC_LINK_SPEED_1GHZ:
			fc_host_speed(shost) = FC_PORTSPEED_1GBIT;
			break;
			case LA_2GHZ_LINK:
		case LPFC_LINK_SPEED_2GHZ:
			fc_host_speed(shost) = FC_PORTSPEED_2GBIT;
			break;
			case LA_4GHZ_LINK:
		case LPFC_LINK_SPEED_4GHZ:
			fc_host_speed(shost) = FC_PORTSPEED_4GBIT;
			break;
			case LA_8GHZ_LINK:
		case LPFC_LINK_SPEED_8GHZ:
			fc_host_speed(shost) = FC_PORTSPEED_8GBIT;
			break;
			case LA_10GHZ_LINK:
		case LPFC_LINK_SPEED_10GHZ:
			fc_host_speed(shost) = FC_PORTSPEED_10GBIT;
			break;
		case LPFC_LINK_SPEED_16GHZ:
			fc_host_speed(shost) = FC_PORTSPEED_16GBIT;
			break;
		default:
			fc_host_speed(shost) = FC_PORTSPEED_UNKNOWN;
			break;
@@ -4097,7 +4092,7 @@ lpfc_get_host_fabric_name (struct Scsi_Host *shost)
	spin_lock_irq(shost->host_lock);

	if ((vport->fc_flag & FC_FABRIC) ||
	    ((phba->fc_topology == TOPOLOGY_LOOP) &&
	    ((phba->fc_topology == LPFC_TOPOLOGY_LOOP) &&
	     (vport->fc_flag & FC_PUBLIC_LOOP)))
		node_name = wwn_to_u64(phba->fc_fabparam.nodeName.u.wwn);
	else
@@ -4208,11 +4203,11 @@ lpfc_get_stats(struct Scsi_Host *shost)
	hs->invalid_crc_count -= lso->invalid_crc_count;
	hs->error_frames -= lso->error_frames;

	if (phba->hba_flag & HBA_FCOE_SUPPORT) {
	if (phba->hba_flag & HBA_FCOE_MODE) {
		hs->lip_count = -1;
		hs->nos_count = (phba->link_events >> 1);
		hs->nos_count -= lso->link_events;
	} else if (phba->fc_topology == TOPOLOGY_LOOP) {
	} else if (phba->fc_topology == LPFC_TOPOLOGY_LOOP) {
		hs->lip_count = (phba->fc_eventTag >> 1);
		hs->lip_count -= lso->link_events;
		hs->nos_count = -1;
@@ -4303,7 +4298,7 @@ lpfc_reset_stats(struct Scsi_Host *shost)
	lso->invalid_tx_word_count = pmb->un.varRdLnk.invalidXmitWord;
	lso->invalid_crc_count = pmb->un.varRdLnk.crcCnt;
	lso->error_frames = pmb->un.varRdLnk.crcCnt;
	if (phba->hba_flag & HBA_FCOE_SUPPORT)
	if (phba->hba_flag & HBA_FCOE_MODE)
		lso->link_events = (phba->link_events >> 1);
	else
		lso->link_events = (phba->fc_eventTag >> 1);
+2 −3
Original line number Diff line number Diff line
@@ -2601,12 +2601,11 @@ static int lpfc_bsg_check_cmd_access(struct lpfc_hba *phba,
			phba->wait_4_mlo_maint_flg = 1;
		} else if (mb->un.varWords[0] == SETVAR_MLORST) {
			phba->link_flag &= ~LS_LOOPBACK_MODE;
			phba->fc_topology = TOPOLOGY_PT_PT;
			phba->fc_topology = LPFC_TOPOLOGY_PT_PT;
		}
		break;
	case MBX_READ_SPARM64:
	case MBX_READ_LA:
	case MBX_READ_LA64:
	case MBX_READ_TOPOLOGY:
	case MBX_REG_LOGIN:
	case MBX_REG_LOGIN64:
	case MBX_CONFIG_PORT:
+3 −2
Original line number Diff line number Diff line
@@ -31,7 +31,7 @@ void lpfc_read_nv(struct lpfc_hba *, LPFC_MBOXQ_t *);
void lpfc_config_async(struct lpfc_hba *, LPFC_MBOXQ_t *, uint32_t);

void lpfc_heart_beat(struct lpfc_hba *, LPFC_MBOXQ_t *);
int lpfc_read_la(struct lpfc_hba *, LPFC_MBOXQ_t *, struct lpfc_dmabuf *);
int lpfc_read_topology(struct lpfc_hba *, LPFC_MBOXQ_t *, struct lpfc_dmabuf *);
void lpfc_clear_la(struct lpfc_hba *, LPFC_MBOXQ_t *);
void lpfc_issue_clear_la(struct lpfc_hba *, struct lpfc_vport *);
void lpfc_config_link(struct lpfc_hba *, LPFC_MBOXQ_t *);
@@ -64,7 +64,7 @@ void lpfc_cleanup_pending_mbox(struct lpfc_vport *);
int lpfc_linkdown(struct lpfc_hba *);
void lpfc_linkdown_port(struct lpfc_vport *);
void lpfc_port_link_failure(struct lpfc_vport *);
void lpfc_mbx_cmpl_read_la(struct lpfc_hba *, LPFC_MBOXQ_t *);
void lpfc_mbx_cmpl_read_topology(struct lpfc_hba *, LPFC_MBOXQ_t *);
void lpfc_init_vpi_cmpl(struct lpfc_hba *, LPFC_MBOXQ_t *);
void lpfc_cancel_all_vport_retry_delay_timer(struct lpfc_hba *);
void lpfc_retry_pport_discovery(struct lpfc_hba *);
@@ -121,6 +121,7 @@ void lpfc_end_rscn(struct lpfc_vport *);
int lpfc_els_chk_latt(struct lpfc_vport *);
int lpfc_els_abort_flogi(struct lpfc_hba *);
int lpfc_initial_flogi(struct lpfc_vport *);
void lpfc_issue_init_vfi(struct lpfc_vport *);
int lpfc_initial_fdisc(struct lpfc_vport *);
int lpfc_issue_els_plogi(struct lpfc_vport *, uint32_t, uint8_t);
int lpfc_issue_els_prli(struct lpfc_vport *, struct lpfc_nodelist *, uint8_t);
+26 −22
Original line number Diff line number Diff line
@@ -48,14 +48,14 @@
#include "lpfc_vport.h"
#include "lpfc_debugfs.h"

#define HBA_PORTSPEED_UNKNOWN               0	/* Unknown - transceiver
						 * incapable of reporting */
#define HBA_PORTSPEED_1GBIT                 1	/* 1 GBit/sec */
#define HBA_PORTSPEED_2GBIT                 2	/* 2 GBit/sec */
#define HBA_PORTSPEED_4GBIT                 8   /* 4 GBit/sec */
#define HBA_PORTSPEED_8GBIT                16   /* 8 GBit/sec */
#define HBA_PORTSPEED_10GBIT                4	/* 10 GBit/sec */
#define HBA_PORTSPEED_NOT_NEGOTIATED        5	/* Speed not established */
/* FDMI Port Speed definitions */
#define HBA_PORTSPEED_1GBIT		0x0001	/* 1 GBit/sec */
#define HBA_PORTSPEED_2GBIT		0x0002	/* 2 GBit/sec */
#define HBA_PORTSPEED_4GBIT		0x0008	/* 4 GBit/sec */
#define HBA_PORTSPEED_10GBIT		0x0004	/* 10 GBit/sec */
#define HBA_PORTSPEED_8GBIT		0x0010	/* 8 GBit/sec */
#define HBA_PORTSPEED_16GBIT		0x0020	/* 16 GBit/sec */
#define HBA_PORTSPEED_UNKNOWN		0x0800	/* Unknown */

#define FOURBYTES	4

@@ -1593,8 +1593,10 @@ lpfc_fdmi_cmd(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, int cmdcode)
			ae->ad.bits.AttrLen = be16_to_cpu(FOURBYTES + 4);

			ae->un.SupportSpeed = 0;
			if (phba->lmt & LMT_16Gb)
				ae->un.SupportSpeed |= HBA_PORTSPEED_16GBIT;
			if (phba->lmt & LMT_10Gb)
				ae->un.SupportSpeed = HBA_PORTSPEED_10GBIT;
				ae->un.SupportSpeed |= HBA_PORTSPEED_10GBIT;
			if (phba->lmt & LMT_8Gb)
				ae->un.SupportSpeed |= HBA_PORTSPEED_8GBIT;
			if (phba->lmt & LMT_4Gb)
@@ -1612,24 +1614,26 @@ lpfc_fdmi_cmd(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, int cmdcode)
			ae->ad.bits.AttrType = be16_to_cpu(PORT_SPEED);
			ae->ad.bits.AttrLen = be16_to_cpu(FOURBYTES + 4);
			switch(phba->fc_linkspeed) {
				case LA_1GHZ_LINK:
			case LPFC_LINK_SPEED_1GHZ:
				ae->un.PortSpeed = HBA_PORTSPEED_1GBIT;
				break;
				case LA_2GHZ_LINK:
			case LPFC_LINK_SPEED_2GHZ:
				ae->un.PortSpeed = HBA_PORTSPEED_2GBIT;
				break;
				case LA_4GHZ_LINK:
			case LPFC_LINK_SPEED_4GHZ:
				ae->un.PortSpeed = HBA_PORTSPEED_4GBIT;
				break;
				case LA_8GHZ_LINK:
			case LPFC_LINK_SPEED_8GHZ:
				ae->un.PortSpeed = HBA_PORTSPEED_8GBIT;
				break;
				case LA_10GHZ_LINK:
			case LPFC_LINK_SPEED_10GHZ:
				ae->un.PortSpeed = HBA_PORTSPEED_10GBIT;
				break;
			case LPFC_LINK_SPEED_16GHZ:
				ae->un.PortSpeed = HBA_PORTSPEED_16GBIT;
				break;
			default:
					ae->un.PortSpeed =
						HBA_PORTSPEED_UNKNOWN;
				ae->un.PortSpeed = HBA_PORTSPEED_UNKNOWN;
				break;
			}
			pab->ab.EntryCnt++;
Loading