Skip to content

Commit

Permalink
[SCSI] lpfc 8.3.19: Add SLI4 FC Discovery support
Browse files Browse the repository at this point in the history
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: Alex Iannicelli <alex.iannicelli@emulex.com>
Signed-off-by: James Smart <james.smart@emulex.com>
Signed-off-by: James Bottomley <James.Bottomley@suse.de>
  • Loading branch information
James Smart authored and James Bottomley committed Dec 21, 2010
1 parent 085c647 commit 76a95d7
Show file tree
Hide file tree
Showing 14 changed files with 516 additions and 382 deletions.
19 changes: 18 additions & 1 deletion drivers/scsi/lpfc/lpfc.h
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down Expand Up @@ -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
Expand Down
91 changes: 43 additions & 48 deletions drivers/scsi/lpfc/lpfc_attr.c
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down Expand Up @@ -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");
Expand Down Expand Up @@ -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.
Expand All @@ -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;
Expand All @@ -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)
Expand All @@ -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;
}

Expand Down Expand Up @@ -2938,21 +2931,21 @@ 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;
}
lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
"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;
}

static DEVICE_ATTR(lpfc_link_speed, S_IRUGO | S_IWUSR,
lpfc_link_speed_show, lpfc_link_speed_store);
lpfc_link_speed_show, lpfc_link_speed_store);

/*
# lpfc_aer_support: Support PCIe device Advanced Error Reporting (AER)
Expand Down Expand Up @@ -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:
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -4058,23 +4050,26 @@ lpfc_get_host_speed(struct Scsi_Host *shost)

if (lpfc_is_link_up(phba)) {
switch(phba->fc_linkspeed) {
case LA_1GHZ_LINK:
fc_host_speed(shost) = FC_PORTSPEED_1GBIT;
case LPFC_LINK_SPEED_1GHZ:
fc_host_speed(shost) = FC_PORTSPEED_1GBIT;
break;
case LA_2GHZ_LINK:
fc_host_speed(shost) = FC_PORTSPEED_2GBIT;
case LPFC_LINK_SPEED_2GHZ:
fc_host_speed(shost) = FC_PORTSPEED_2GBIT;
break;
case LA_4GHZ_LINK:
fc_host_speed(shost) = FC_PORTSPEED_4GBIT;
case LPFC_LINK_SPEED_4GHZ:
fc_host_speed(shost) = FC_PORTSPEED_4GBIT;
break;
case LA_8GHZ_LINK:
fc_host_speed(shost) = FC_PORTSPEED_8GBIT;
case LPFC_LINK_SPEED_8GHZ:
fc_host_speed(shost) = FC_PORTSPEED_8GBIT;
break;
case LA_10GHZ_LINK:
fc_host_speed(shost) = FC_PORTSPEED_10GBIT;
case LPFC_LINK_SPEED_10GHZ:
fc_host_speed(shost) = FC_PORTSPEED_10GBIT;
break;
default:
fc_host_speed(shost) = FC_PORTSPEED_UNKNOWN;
case LPFC_LINK_SPEED_16GHZ:
fc_host_speed(shost) = FC_PORTSPEED_16GBIT;
break;
default:
fc_host_speed(shost) = FC_PORTSPEED_UNKNOWN;
break;
}
} else
Expand All @@ -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
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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);
Expand Down
5 changes: 2 additions & 3 deletions drivers/scsi/lpfc/lpfc_bsg.c
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down
5 changes: 3 additions & 2 deletions drivers/scsi/lpfc/lpfc_crtn.h
Original file line number Diff line number Diff line change
Expand Up @@ -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 *);
Expand Down Expand Up @@ -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 *);
Expand Down Expand Up @@ -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);
Expand Down
48 changes: 26 additions & 22 deletions drivers/scsi/lpfc/lpfc_ct.c
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down Expand Up @@ -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)
Expand All @@ -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:
ae->un.PortSpeed = HBA_PORTSPEED_1GBIT;
case LPFC_LINK_SPEED_1GHZ:
ae->un.PortSpeed = HBA_PORTSPEED_1GBIT;
break;
case LA_2GHZ_LINK:
ae->un.PortSpeed = HBA_PORTSPEED_2GBIT;
case LPFC_LINK_SPEED_2GHZ:
ae->un.PortSpeed = HBA_PORTSPEED_2GBIT;
break;
case LA_4GHZ_LINK:
ae->un.PortSpeed = HBA_PORTSPEED_4GBIT;
case LPFC_LINK_SPEED_4GHZ:
ae->un.PortSpeed = HBA_PORTSPEED_4GBIT;
break;
case LA_8GHZ_LINK:
ae->un.PortSpeed = HBA_PORTSPEED_8GBIT;
case LPFC_LINK_SPEED_8GHZ:
ae->un.PortSpeed = HBA_PORTSPEED_8GBIT;
break;
case LA_10GHZ_LINK:
ae->un.PortSpeed = HBA_PORTSPEED_10GBIT;
case LPFC_LINK_SPEED_10GHZ:
ae->un.PortSpeed = HBA_PORTSPEED_10GBIT;
break;
default:
ae->un.PortSpeed =
HBA_PORTSPEED_UNKNOWN;
case LPFC_LINK_SPEED_16GHZ:
ae->un.PortSpeed = HBA_PORTSPEED_16GBIT;
break;
default:
ae->un.PortSpeed = HBA_PORTSPEED_UNKNOWN;
break;
}
pab->ab.EntryCnt++;
Expand Down
Loading

0 comments on commit 76a95d7

Please sign in to comment.