aboutsummaryrefslogtreecommitdiff
path: root/drivers/scsi/lpfc
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/scsi/lpfc')
-rw-r--r--drivers/scsi/lpfc/lpfc.h123
-rw-r--r--drivers/scsi/lpfc/lpfc_attr.c250
-rw-r--r--drivers/scsi/lpfc/lpfc_crtn.h63
-rw-r--r--drivers/scsi/lpfc/lpfc_ct.c15
-rw-r--r--drivers/scsi/lpfc/lpfc_debugfs.c21
-rw-r--r--drivers/scsi/lpfc/lpfc_disc.h1
-rw-r--r--drivers/scsi/lpfc/lpfc_els.c275
-rw-r--r--drivers/scsi/lpfc/lpfc_hbadisc.c1365
-rw-r--r--drivers/scsi/lpfc/lpfc_hw.h142
-rw-r--r--drivers/scsi/lpfc/lpfc_hw4.h2141
-rw-r--r--drivers/scsi/lpfc/lpfc_init.c5626
-rw-r--r--drivers/scsi/lpfc/lpfc_logmsg.h54
-rw-r--r--drivers/scsi/lpfc/lpfc_mbox.c674
-rw-r--r--drivers/scsi/lpfc/lpfc_mem.c206
-rw-r--r--drivers/scsi/lpfc/lpfc_nportdisc.c51
-rw-r--r--drivers/scsi/lpfc/lpfc_scsi.c930
-rw-r--r--drivers/scsi/lpfc/lpfc_scsi.h2
-rw-r--r--drivers/scsi/lpfc/lpfc_sli.c6683
-rw-r--r--drivers/scsi/lpfc/lpfc_sli.h29
-rw-r--r--drivers/scsi/lpfc/lpfc_sli4.h467
-rw-r--r--drivers/scsi/lpfc/lpfc_version.h2
-rw-r--r--drivers/scsi/lpfc/lpfc_vport.c62
22 files changed, 17512 insertions, 1670 deletions
diff --git a/drivers/scsi/lpfc/lpfc.h b/drivers/scsi/lpfc/lpfc.h
index 1105f9a111b..54056984909 100644
--- a/drivers/scsi/lpfc/lpfc.h
+++ b/drivers/scsi/lpfc/lpfc.h
@@ -1,7 +1,7 @@
/*******************************************************************
* This file is part of the Emulex Linux Device Driver for *
* Fibre Channel Host Bus Adapters. *
- * Copyright (C) 2004-2008 Emulex. All rights reserved. *
+ * Copyright (C) 2004-2009 Emulex. All rights reserved. *
* EMULEX and SLI are trademarks of Emulex. *
* www.emulex.com *
* Portions Copyright (C) 2004-2005 Christoph Hellwig *
@@ -23,6 +23,13 @@
struct lpfc_sli2_slim;
+#define LPFC_PCI_DEV_LP 0x1
+#define LPFC_PCI_DEV_OC 0x2
+
+#define LPFC_SLI_REV2 2
+#define LPFC_SLI_REV3 3
+#define LPFC_SLI_REV4 4
+
#define LPFC_MAX_TARGET 4096 /* max number of targets supported */
#define LPFC_MAX_DISC_THREADS 64 /* max outstanding discovery els
requests */
@@ -98,9 +105,11 @@ struct lpfc_dma_pool {
};
struct hbq_dmabuf {
+ struct lpfc_dmabuf hbuf;
struct lpfc_dmabuf dbuf;
uint32_t size;
uint32_t tag;
+ struct lpfc_rcqe rcqe;
};
/* Priority bit. Set value to exceed low water mark in lpfc_mem. */
@@ -134,7 +143,10 @@ typedef struct lpfc_vpd {
} rev;
struct {
#ifdef __BIG_ENDIAN_BITFIELD
- uint32_t rsvd2 :24; /* Reserved */
+ uint32_t rsvd3 :19; /* Reserved */
+ uint32_t cdss : 1; /* Configure Data Security SLI */
+ uint32_t rsvd2 : 3; /* Reserved */
+ uint32_t cbg : 1; /* Configure BlockGuard */
uint32_t cmv : 1; /* Configure Max VPIs */
uint32_t ccrp : 1; /* Config Command Ring Polling */
uint32_t csah : 1; /* Configure Synchronous Abort Handling */
@@ -152,7 +164,10 @@ typedef struct lpfc_vpd {
uint32_t csah : 1; /* Configure Synchronous Abort Handling */
uint32_t ccrp : 1; /* Config Command Ring Polling */
uint32_t cmv : 1; /* Configure Max VPIs */
- uint32_t rsvd2 :24; /* Reserved */
+ uint32_t cbg : 1; /* Configure BlockGuard */
+ uint32_t rsvd2 : 3; /* Reserved */
+ uint32_t cdss : 1; /* Configure Data Security SLI */
+ uint32_t rsvd3 :19; /* Reserved */
#endif
} sli3Feat;
} lpfc_vpd_t;
@@ -264,8 +279,8 @@ enum hba_state {
};
struct lpfc_vport {
- struct list_head listentry;
struct lpfc_hba *phba;
+ struct list_head listentry;
uint8_t port_type;
#define LPFC_PHYSICAL_PORT 1
#define LPFC_NPIV_PORT 2
@@ -273,6 +288,9 @@ struct lpfc_vport {
enum discovery_state port_state;
uint16_t vpi;
+ uint16_t vfi;
+ uint8_t vfi_state;
+#define LPFC_VFI_REGISTERED 0x1
uint32_t fc_flag; /* FC flags */
/* Several of these flags are HBA centric and should be moved to
@@ -385,6 +403,9 @@ struct lpfc_vport {
#endif
uint8_t stat_data_enabled;
uint8_t stat_data_blocked;
+ struct list_head rcv_buffer_list;
+ uint32_t vport_flag;
+#define STATIC_VPORT 1
};
struct hbq_s {
@@ -420,8 +441,66 @@ enum intr_type_t {
};
struct lpfc_hba {
+ /* SCSI interface function jump table entries */
+ int (*lpfc_new_scsi_buf)
+ (struct lpfc_vport *, int);
+ struct lpfc_scsi_buf * (*lpfc_get_scsi_buf)
+ (struct lpfc_hba *);
+ int (*lpfc_scsi_prep_dma_buf)
+ (struct lpfc_hba *, struct lpfc_scsi_buf *);
+ void (*lpfc_scsi_unprep_dma_buf)
+ (struct lpfc_hba *, struct lpfc_scsi_buf *);
+ void (*lpfc_release_scsi_buf)
+ (struct lpfc_hba *, struct lpfc_scsi_buf *);
+ void (*lpfc_rampdown_queue_depth)
+ (struct lpfc_hba *);
+ void (*lpfc_scsi_prep_cmnd)
+ (struct lpfc_vport *, struct lpfc_scsi_buf *,
+ struct lpfc_nodelist *);
+ int (*lpfc_scsi_prep_task_mgmt_cmd)
+ (struct lpfc_vport *, struct lpfc_scsi_buf *,
+ unsigned int, uint8_t);
+
+ /* IOCB interface function jump table entries */
+ int (*__lpfc_sli_issue_iocb)
+ (struct lpfc_hba *, uint32_t,
+ struct lpfc_iocbq *, uint32_t);
+ void (*__lpfc_sli_release_iocbq)(struct lpfc_hba *,
+ struct lpfc_iocbq *);
+ int (*lpfc_hba_down_post)(struct lpfc_hba *phba);
+
+
+ IOCB_t * (*lpfc_get_iocb_from_iocbq)
+ (struct lpfc_iocbq *);
+ void (*lpfc_scsi_cmd_iocb_cmpl)
+ (struct lpfc_hba *, struct lpfc_iocbq *, struct lpfc_iocbq *);
+
+ /* MBOX interface function jump table entries */
+ int (*lpfc_sli_issue_mbox)
+ (struct lpfc_hba *, LPFC_MBOXQ_t *, uint32_t);
+ /* Slow-path IOCB process function jump table entries */
+ void (*lpfc_sli_handle_slow_ring_event)
+ (struct lpfc_hba *phba, struct lpfc_sli_ring *pring,
+ uint32_t mask);
+ /* INIT device interface function jump table entries */
+ int (*lpfc_sli_hbq_to_firmware)
+ (struct lpfc_hba *, uint32_t, struct hbq_dmabuf *);
+ int (*lpfc_sli_brdrestart)
+ (struct lpfc_hba *);
+ int (*lpfc_sli_brdready)
+ (struct lpfc_hba *, uint32_t);
+ void (*lpfc_handle_eratt)
+ (struct lpfc_hba *);
+ void (*lpfc_stop_port)
+ (struct lpfc_hba *);
+
+
+ /* SLI4 specific HBA data structure */
+ struct lpfc_sli4_hba sli4_hba;
+
struct lpfc_sli sli;
- uint32_t sli_rev; /* SLI2 or SLI3 */
+ uint8_t pci_dev_grp; /* lpfc PCI dev group: 0x0, 0x1, 0x2,... */
+ uint32_t sli_rev; /* SLI2, SLI3, or SLI4 */
uint32_t sli3_options; /* Mask of enabled SLI3 options */
#define LPFC_SLI3_HBQ_ENABLED 0x01
#define LPFC_SLI3_NPIV_ENABLED 0x02
@@ -429,6 +508,7 @@ struct lpfc_hba {
#define LPFC_SLI3_CRP_ENABLED 0x08
#define LPFC_SLI3_INB_ENABLED 0x10
#define LPFC_SLI3_BG_ENABLED 0x20
+#define LPFC_SLI3_DSS_ENABLED 0x40
uint32_t iocb_cmd_size;
uint32_t iocb_rsp_size;
@@ -442,8 +522,13 @@ 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 0x4 /* Deferred error attention in progress */
+#define DEFER_ERATT 0x2 /* Deferred error attention in progress */
+#define HBA_FCOE_SUPPORT 0x4 /* HBA function supports FCOE */
+#define HBA_RECEIVE_BUFFER 0x8 /* Rcv buffer posted to worker thread */
+#define HBA_POST_RECEIVE_BUFFER 0x10 /* Rcv buffers need to be posted */
+#define FCP_XRI_ABORT_EVENT 0x20
+#define ELS_XRI_ABORT_EVENT 0x40
+#define ASYNC_EVENT 0x80
struct lpfc_dmabuf slim2p;
MAILBOX_t *mbox;
@@ -502,6 +587,9 @@ struct lpfc_hba {
uint32_t cfg_poll;
uint32_t cfg_poll_tmo;
uint32_t cfg_use_msi;
+ uint32_t cfg_fcp_imax;
+ uint32_t cfg_fcp_wq_count;
+ uint32_t cfg_fcp_eq_count;
uint32_t cfg_sg_seg_cnt;
uint32_t cfg_prot_sg_seg_cnt;
uint32_t cfg_sg_dma_buf_size;
@@ -511,6 +599,8 @@ struct lpfc_hba {
uint32_t cfg_enable_hba_reset;
uint32_t cfg_enable_hba_heartbeat;
uint32_t cfg_enable_bg;
+ uint32_t cfg_enable_fip;
+ uint32_t cfg_log_verbose;
lpfc_vpd_t vpd; /* vital product data */
@@ -526,11 +616,12 @@ struct lpfc_hba {
unsigned long data_flags;
uint32_t hbq_in_use; /* HBQs in use flag */
- struct list_head hbqbuf_in_list; /* in-fly hbq buffer list */
+ struct list_head rb_pend_list; /* Received buffers to be processed */
uint32_t hbq_count; /* Count of configured HBQs */
struct hbq_s hbqs[LPFC_MAX_HBQS]; /* local copy of hbq indicies */
unsigned long pci_bar0_map; /* Physical address for PCI BAR0 */
+ unsigned long pci_bar1_map; /* Physical address for PCI BAR1 */
unsigned long pci_bar2_map; /* Physical address for PCI BAR2 */
void __iomem *slim_memmap_p; /* Kernel memory mapped address for
PCI BAR0 */
@@ -593,7 +684,8 @@ struct lpfc_hba {
/* pci_mem_pools */
struct pci_pool *lpfc_scsi_dma_buf_pool;
struct pci_pool *lpfc_mbuf_pool;
- struct pci_pool *lpfc_hbq_pool;
+ struct pci_pool *lpfc_hrb_pool; /* header receive buffer pool */
+ struct pci_pool *lpfc_drb_pool; /* data receive buffer pool */
struct lpfc_dma_pool lpfc_mbuf_safety_pool;
mempool_t *mbox_mem_pool;
@@ -609,6 +701,14 @@ struct lpfc_hba {
struct lpfc_vport *pport; /* physical lpfc_vport pointer */
uint16_t max_vpi; /* Maximum virtual nports */
#define LPFC_MAX_VPI 0xFFFF /* Max number of VPI supported */
+ uint16_t max_vports; /*
+ * For IOV HBAs max_vpi can change
+ * after a reset. max_vports is max
+ * number of vports present. This can
+ * be greater than max_vpi.
+ */
+ uint16_t vpi_base;
+ uint16_t vfi_base;
unsigned long *vpi_bmask; /* vpi allocation table */
/* Data structure used by fabric iocb scheduler */
@@ -667,6 +767,11 @@ struct lpfc_hba {
/* Maximum number of events that can be outstanding at any time*/
#define LPFC_MAX_EVT_COUNT 512
atomic_t fast_event_count;
+ struct lpfc_fcf fcf;
+ uint8_t fc_map[3];
+ uint8_t valid_vlan;
+ uint16_t vlan_id;
+ struct list_head fcf_conn_rec_list;
};
static inline struct Scsi_Host *
diff --git a/drivers/scsi/lpfc/lpfc_attr.c b/drivers/scsi/lpfc/lpfc_attr.c
index c14f0cbdb12..d73e677201f 100644
--- a/drivers/scsi/lpfc/lpfc_attr.c
+++ b/drivers/scsi/lpfc/lpfc_attr.c
@@ -1,7 +1,7 @@
/*******************************************************************
* This file is part of the Emulex Linux Device Driver for *
* Fibre Channel Host Bus Adapters. *
- * Copyright (C) 2004-2008 Emulex. All rights reserved. *
+ * Copyright (C) 2004-2009 Emulex. All rights reserved. *
* EMULEX and SLI are trademarks of Emulex. *
* www.emulex.com *
* Portions Copyright (C) 2004-2005 Christoph Hellwig *
@@ -30,8 +30,10 @@
#include <scsi/scsi_tcq.h>
#include <scsi/scsi_transport_fc.h>
+#include "lpfc_hw4.h"
#include "lpfc_hw.h"
#include "lpfc_sli.h"
+#include "lpfc_sli4.h"
#include "lpfc_nl.h"
#include "lpfc_disc.h"
#include "lpfc_scsi.h"
@@ -505,12 +507,14 @@ lpfc_issue_lip(struct Scsi_Host *shost)
return -ENOMEM;
memset((void *)pmboxq, 0, sizeof (LPFC_MBOXQ_t));
- pmboxq->mb.mbxCommand = MBX_DOWN_LINK;
- pmboxq->mb.mbxOwner = OWN_HOST;
+ pmboxq->u.mb.mbxCommand = MBX_DOWN_LINK;
+ pmboxq->u.mb.mbxOwner = OWN_HOST;
mbxstatus = lpfc_sli_issue_mbox_wait(phba, pmboxq, LPFC_MBOX_TMO * 2);
- if ((mbxstatus == MBX_SUCCESS) && (pmboxq->mb.mbxStatus == 0)) {
+ if ((mbxstatus == MBX_SUCCESS) &&
+ (pmboxq->u.mb.mbxStatus == 0 ||
+ pmboxq->u.mb.mbxStatus == MBXERR_LINK_DOWN)) {
memset((void *)pmboxq, 0, sizeof (LPFC_MBOXQ_t));
lpfc_init_link(phba, pmboxq, phba->cfg_topology,
phba->cfg_link_speed);
@@ -789,7 +793,8 @@ lpfc_get_hba_info(struct lpfc_hba *phba,
uint32_t *mrpi, uint32_t *arpi,
uint32_t *mvpi, uint32_t *avpi)
{
- struct lpfc_sli *psli = &phba->sli;
+ struct lpfc_sli *psli = &phba->sli;
+ struct lpfc_mbx_read_config *rd_config;
LPFC_MBOXQ_t *pmboxq;
MAILBOX_t *pmb;
int rc = 0;
@@ -800,7 +805,7 @@ lpfc_get_hba_info(struct lpfc_hba *phba,
*/
if (phba->link_state < LPFC_LINK_DOWN ||
!phba->mbox_mem_pool ||
- (phba->sli.sli_flag & LPFC_SLI2_ACTIVE) == 0)
+ (phba->sli.sli_flag & LPFC_SLI_ACTIVE) == 0)
return 0;
if (phba->sli.sli_flag & LPFC_BLOCK_MGMT_IO)
@@ -811,13 +816,13 @@ lpfc_get_hba_info(struct lpfc_hba *phba,
return 0;
memset(pmboxq, 0, sizeof (LPFC_MBOXQ_t));
- pmb = &pmboxq->mb;
+ pmb = &pmboxq->u.mb;
pmb->mbxCommand = MBX_READ_CONFIG;
pmb->mbxOwner = OWN_HOST;
pmboxq->context1 = NULL;
if ((phba->pport->fc_flag & FC_OFFLINE_MODE) ||
- (!(psli->sli_flag & LPFC_SLI2_ACTIVE)))
+ (!(psli->sli_flag & LPFC_SLI_ACTIVE)))
rc = MBX_NOT_FINISHED;
else
rc = lpfc_sli_issue_mbox_wait(phba, pmboxq, phba->fc_ratov * 2);
@@ -828,18 +833,37 @@ lpfc_get_hba_info(struct lpfc_hba *phba,
return 0;
}
- if (mrpi)
- *mrpi = pmb->un.varRdConfig.max_rpi;
- if (arpi)
- *arpi = pmb->un.varRdConfig.avail_rpi;
- if (mxri)
- *mxri = pmb->un.varRdConfig.max_xri;
- if (axri)
- *axri = pmb->un.varRdConfig.avail_xri;
- if (mvpi)
- *mvpi = pmb->un.varRdConfig.max_vpi;
- if (avpi)
- *avpi = pmb->un.varRdConfig.avail_vpi;
+ if (phba->sli_rev == LPFC_SLI_REV4) {
+ rd_config = &pmboxq->u.mqe.un.rd_config;
+ if (mrpi)
+ *mrpi = bf_get(lpfc_mbx_rd_conf_rpi_count, rd_config);
+ if (arpi)
+ *arpi = bf_get(lpfc_mbx_rd_conf_rpi_count, rd_config) -
+ phba->sli4_hba.max_cfg_param.rpi_used;
+ if (mxri)
+ *mxri = bf_get(lpfc_mbx_rd_conf_xri_count, rd_config);
+ if (axri)
+ *axri = bf_get(lpfc_mbx_rd_conf_xri_count, rd_config) -
+ phba->sli4_hba.max_cfg_param.xri_used;
+ if (mvpi)
+ *mvpi = bf_get(lpfc_mbx_rd_conf_vpi_count, rd_config);
+ if (avpi)
+ *avpi = bf_get(lpfc_mbx_rd_conf_vpi_count, rd_config) -
+ phba->sli4_hba.max_cfg_param.vpi_used;
+ } else {
+ if (mrpi)
+ *mrpi = pmb->un.varRdConfig.max_rpi;
+ if (arpi)
+ *arpi = pmb->un.varRdConfig.avail_rpi;
+ if (mxri)
+ *mxri = pmb->un.varRdConfig.max_xri;
+ if (axri)
+ *axri = pmb->un.varRdConfig.avail_xri;
+ if (mvpi)
+ *mvpi = pmb->un.varRdConfig.max_vpi;
+ if (avpi)
+ *avpi = pmb->un.varRdConfig.avail_vpi;
+ }
mempool_free(pmboxq, phba->mbox_mem_pool);
return 1;
@@ -2021,22 +2045,9 @@ static DEVICE_ATTR(lpfc_devloss_tmo, S_IRUGO | S_IWUSR,
# lpfc_log_verbose: Only turn this flag on if you are willing to risk being
# deluged with LOTS of information.
# You can set a bit mask to record specific types of verbose messages:
-#
-# LOG_ELS 0x1 ELS events
-# LOG_DISCOVERY 0x2 Link discovery events
-# LOG_MBOX 0x4 Mailbox events
-# LOG_INIT 0x8 Initialization events
-# LOG_LINK_EVENT 0x10 Link events
-# LOG_FCP 0x40 FCP traffic history
-# LOG_NODE 0x80 Node table events
-# LOG_BG 0x200 BlockBuard events
-# LOG_MISC 0x400 Miscellaneous events
-# LOG_SLI 0x800 SLI events
-# LOG_FCP_ERROR 0x1000 Only log FCP errors
-# LOG_LIBDFC 0x2000 LIBDFC events
-# LOG_ALL_MSG 0xffff LOG all messages
+# See lpfc_logmsh.h for definitions.
*/
-LPFC_VPORT_ATTR_HEX_RW(log_verbose, 0x0, 0x0, 0xffff,
+LPFC_VPORT_ATTR_HEX_RW(log_verbose, 0x0, 0x0, 0xffffffff,
"Verbose logging bit-mask");
/*
@@ -2266,6 +2277,36 @@ lpfc_param_init(topology, 0, 0, 6)
static DEVICE_ATTR(lpfc_topology, S_IRUGO | S_IWUSR,
lpfc_topology_show, lpfc_topology_store);
+/**
+ * lpfc_static_vport_show: Read callback function for
+ * lpfc_static_vport sysfs file.
+ * @dev: Pointer to class device object.
+ * @attr: device attribute structure.
+ * @buf: Data buffer.
+ *
+ * This function is the read call back function for
+ * lpfc_static_vport sysfs file. The lpfc_static_vport
+ * sysfs file report the mageability of the vport.
+ **/
+static ssize_t
+lpfc_static_vport_show(struct device *dev, struct device_attribute *attr,
+ char *buf)
+{
+ struct Scsi_Host *shost = class_to_shost(dev);
+ struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;
+ if (vport->vport_flag & STATIC_VPORT)
+ sprintf(buf, "1\n");
+ else
+ sprintf(buf, "0\n");
+
+ return strlen(buf);
+}
+
+/*
+ * Sysfs attribute to control the statistical data collection.
+ */
+static DEVICE_ATTR(lpfc_static_vport, S_IRUGO,
+ lpfc_static_vport_show, NULL);
/**
* lpfc_stat_data_ctrl_store - write call back for lpfc_stat_data_ctrl sysfs file
@@ -2341,7 +2382,7 @@ lpfc_stat_data_ctrl_store(struct device *dev, struct device_attribute *attr,
if (vports == NULL)
return -ENOMEM;
- for (i = 0; i <= phba->max_vpi && vports[i] != NULL; i++) {
+ for (i = 0; i <= phba->max_vports && vports[i] != NULL; i++) {
v_shost = lpfc_shost_from_vport(vports[i]);
spin_lock_irq(v_shost->host_lock);
/* Block and reset data collection */
@@ -2356,7 +2397,7 @@ lpfc_stat_data_ctrl_store(struct device *dev, struct device_attribute *attr,
phba->bucket_base = base;
phba->bucket_step = step;
- for (i = 0; i <= phba->max_vpi && vports[i] != NULL; i++) {
+ for (i = 0; i <= phba->max_vports && vports[i] != NULL; i++) {
v_shost = lpfc_shost_from_vport(vports[i]);
/* Unblock data collection */
@@ -2373,7 +2414,7 @@ lpfc_stat_data_ctrl_store(struct device *dev, struct device_attribute *attr,
if (vports == NULL)
return -ENOMEM;
- for (i = 0; i <= phba->max_vpi && vports[i] != NULL; i++) {
+ for (i = 0; i <= phba->max_vports && vports[i] != NULL; i++) {
v_shost = lpfc_shost_from_vport(vports[i]);
spin_lock_irq(shost->host_lock);
vports[i]->stat_data_blocked = 1;
@@ -2844,15 +2885,39 @@ LPFC_ATTR_RW(poll_tmo, 10, 1, 255,
/*
# lpfc_use_msi: Use MSI (Message Signaled Interrupts) in systems that
# support this feature
-# 0 = MSI disabled
+# 0 = MSI disabled (default)
# 1 = MSI enabled
-# 2 = MSI-X enabled (default)
-# Value range is [0,2]. Default value is 2.
+# 2 = MSI-X enabled
+# Value range is [0,2]. Default value is 0.
*/
-LPFC_ATTR_R(use_msi, 2, 0, 2, "Use Message Signaled Interrupts (1) or "
+LPFC_ATTR_R(use_msi, 0, 0, 2, "Use Message Signaled Interrupts (1) or "
"MSI-X (2), if possible");
/*
+# lpfc_fcp_imax: Set the maximum number of fast-path FCP interrupts per second
+#
+# Value range is [636,651042]. Default value is 10000.
+*/
+LPFC_ATTR_R(fcp_imax, LPFC_FP_DEF_IMAX, LPFC_MIM_IMAX, LPFC_DMULT_CONST,
+ "Set the maximum number of fast-path FCP interrupts per second");
+
+/*
+# lpfc_fcp_wq_count: Set the number of fast-path FCP work queues
+#
+# Value range is [1,31]. Default value is 4.
+*/
+LPFC_ATTR_R(fcp_wq_count, LPFC_FP_WQN_DEF, LPFC_FP_WQN_MIN, LPFC_FP_WQN_MAX,
+ "Set the number of fast-path FCP work queues, if possible");
+
+/*
+# lpfc_fcp_eq_count: Set the number of fast-path FCP event queues
+#
+# Value range is [1,7]. Default value is 1.
+*/
+LPFC_ATTR_R(fcp_eq_count, LPFC_FP_EQN_DEF, LPFC_FP_EQN_MIN, LPFC_FP_EQN_MAX,
+ "Set the number of fast-path FCP event queues, if possible");
+
+/*
# lpfc_enable_hba_reset: Allow or prevent HBA resets to the hardware.
# 0 = HBA resets disabled
# 1 = HBA resets enabled (default)
@@ -2876,6 +2941,14 @@ LPFC_ATTR_R(enable_hba_heartbeat, 1, 0, 1, "Enable HBA Heartbeat.");
*/
LPFC_ATTR_R(enable_bg, 0, 0, 1, "Enable BlockGuard Support");
+/*
+# lpfc_enable_fip: When set, FIP is required to start discovery. If not
+# set, the driver will add an FCF record manually if the port has no
+# FCF records available and start discovery.
+# Value range is [0,1]. Default value is 1 (enabled)
+*/
+LPFC_ATTR_RW(enable_fip, 0, 0, 1, "Enable FIP Discovery");
+
/*
# lpfc_prot_mask: i
@@ -2942,6 +3015,7 @@ struct device_attribute *lpfc_hba_attrs[] = {
&dev_attr_lpfc_peer_port_login,
&dev_attr_lpfc_nodev_tmo,
&dev_attr_lpfc_devloss_tmo,
+ &dev_attr_lpfc_enable_fip,
&dev_attr_lpfc_fcp_class,
&dev_attr_lpfc_use_adisc,
&dev_attr_lpfc_ack0,
@@ -2969,6 +3043,9 @@ struct device_attribute *lpfc_hba_attrs[] = {
&dev_attr_lpfc_poll,
&dev_attr_lpfc_poll_tmo,
&dev_attr_lpfc_use_msi,
+ &dev_attr_lpfc_fcp_imax,
+ &dev_attr_lpfc_fcp_wq_count,
+ &dev_attr_lpfc_fcp_eq_count,
&dev_attr_lpfc_enable_bg,
&dev_attr_lpfc_soft_wwnn,
&dev_attr_lpfc_soft_wwpn,
@@ -2991,6 +3068,7 @@ struct device_attribute *lpfc_vport_attrs[] = {
&dev_attr_lpfc_lun_queue_depth,
&dev_attr_lpfc_nodev_tmo,
&dev_attr_lpfc_devloss_tmo,
+ &dev_attr_lpfc_enable_fip,
&dev_attr_lpfc_hba_queue_depth,
&dev_attr_lpfc_peer_port_login,
&dev_attr_lpfc_restrict_login,
@@ -3003,6 +3081,7 @@ struct device_attribute *lpfc_vport_attrs[] = {
&dev_attr_lpfc_enable_da_id,
&dev_attr_lpfc_max_scsicmpl_time,
&dev_attr_lpfc_stat_data_ctrl,
+ &dev_attr_lpfc_static_vport,
NULL,
};
@@ -3199,7 +3278,7 @@ sysfs_mbox_write(struct kobject *kobj, struct bin_attribute *bin_attr,
}
}
- memcpy((uint8_t *) & phba->sysfs_mbox.mbox->mb + off,
+ memcpy((uint8_t *) &phba->sysfs_mbox.mbox->u.mb + off,
buf, count);
phba->sysfs_mbox.offset = off + count;
@@ -3241,6 +3320,7 @@ sysfs_mbox_read(struct kobject *kobj, struct bin_attribute *bin_attr,
struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;
struct lpfc_hba *phba = vport->phba;
int rc;
+ MAILBOX_t *pmb;
if (off > MAILBOX_CMD_SIZE)
return -ERANGE;
@@ -3265,8 +3345,8 @@ sysfs_mbox_read(struct kobject *kobj, struct bin_attribute *bin_attr,
if (off == 0 &&
phba->sysfs_mbox.state == SMBOX_WRITING &&
phba->sysfs_mbox.offset >= 2 * sizeof(uint32_t)) {
-
- switch (phba->sysfs_mbox.mbox->mb.mbxCommand) {
+ pmb = &phba->sysfs_mbox.mbox->u.mb;
+ switch (pmb->mbxCommand) {
/* Offline only */
case MBX_INIT_LINK:
case MBX_DOWN_LINK:
@@ -3283,7 +3363,7 @@ sysfs_mbox_read(struct kobject *kobj, struct bin_attribute *bin_attr,
if (!(vport->fc_flag & FC_OFFLINE_MODE)) {
printk(KERN_WARNING "mbox_read:Command 0x%x "
"is illegal in on-line state\n",
- phba->sysfs_mbox.mbox->mb.mbxCommand);
+ pmb->mbxCommand);
sysfs_mbox_idle(phba);
spin_unlock_irq(&phba->hbalock);
return -EPERM;
@@ -3319,13 +3399,13 @@ sysfs_mbox_read(struct kobject *kobj, struct bin_attribute *bin_attr,
case MBX_CONFIG_PORT:
case MBX_RUN_BIU_DIAG:
printk(KERN_WARNING "mbox_read: Illegal Command 0x%x\n",
- phba->sysfs_mbox.mbox->mb.mbxCommand);
+ pmb->mbxCommand);
sysfs_mbox_idle(phba);
spin_unlock_irq(&phba->hbalock);
return -EPERM;
default:
printk(KERN_WARNING "mbox_read: Unknown Command 0x%x\n",
- phba->sysfs_mbox.mbox->mb.mbxCommand);
+ pmb->mbxCommand);
sysfs_mbox_idle(phba);
spin_unlock_irq(&phba->hbalock);
return -EPERM;
@@ -3335,14 +3415,14 @@ sysfs_mbox_read(struct kobject *kobj, struct bin_attribute *bin_attr,
* or RESTART mailbox commands until the HBA is restarted.
*/
if (phba->pport->stopped &&
- phba->sysfs_mbox.mbox->mb.mbxCommand != MBX_DUMP_MEMORY &&
- phba->sysfs_mbox.mbox->mb.mbxCommand != MBX_RESTART &&
- phba->sysfs_mbox.mbox->mb.mbxCommand != MBX_WRITE_VPARMS &&
- phba->sysfs_mbox.mbox->mb.mbxCommand != MBX_WRITE_WWN)
+ pmb->mbxCommand != MBX_DUMP_MEMORY &&
+ pmb->mbxCommand != MBX_RESTART &&
+ pmb->mbxCommand != MBX_WRITE_VPARMS &&
+ pmb->mbxCommand != MBX_WRITE_WWN)
lpfc_printf_log(phba, KERN_WARNING, LOG_MBOX,
"1259 mbox: Issued mailbox cmd "
"0x%x while in stopped state.\n",
- phba->sysfs_mbox.mbox->mb.mbxCommand);
+ pmb->mbxCommand);
phba->sysfs_mbox.mbox->vport = vport;
@@ -3356,7 +3436,7 @@ sysfs_mbox_read(struct kobject *kobj, struct bin_attribute *bin_attr,
}
if ((vport->fc_flag & FC_OFFLINE_MODE) ||
- (!(phba->sli.sli_flag & LPFC_SLI2_ACTIVE))){
+ (!(phba->sli.sli_flag & LPFC_SLI_ACTIVE))) {
spin_unlock_irq(&phba->hbalock);
rc = lpfc_sli_issue_mbox (phba,
@@ -3368,8 +3448,7 @@ sysfs_mbox_read(struct kobject *kobj, struct bin_attribute *bin_attr,
spin_unlock_irq(&phba->hbalock);
rc = lpfc_sli_issue_mbox_wait (phba,
phba->sysfs_mbox.mbox,
- lpfc_mbox_tmo_val(phba,
- phba->sysfs_mbox.mbox->mb.mbxCommand) * HZ);
+ lpfc_mbox_tmo_val(phba, pmb->mbxCommand) * HZ);
spin_lock_irq(&phba->hbalock);
}
@@ -3391,7 +3470,7 @@ sysfs_mbox_read(struct kobject *kobj, struct bin_attribute *bin_attr,
return -EAGAIN;
}
- memcpy(buf, (uint8_t *) & phba->sysfs_mbox.mbox->mb + off, count);
+ memcpy(buf, (uint8_t *) &pmb + off, count);
phba->sysfs_mbox.offset = off + count;
@@ -3585,6 +3664,9 @@ lpfc_get_host_speed(struct Scsi_Host *shost)
case LA_8GHZ_LINK:
fc_host_speed(shost) = FC_PORTSPEED_8GBIT;
break;
+ case LA_10GHZ_LINK:
+ fc_host_speed(shost) = FC_PORTSPEED_10GBIT;
+ break;
default:
fc_host_speed(shost) = FC_PORTSPEED_UNKNOWN;
break;
@@ -3652,7 +3734,7 @@ lpfc_get_stats(struct Scsi_Host *shost)
*/
if (phba->link_state < LPFC_LINK_DOWN ||
!phba->mbox_mem_pool ||
- (phba->sli.sli_flag & LPFC_SLI2_ACTIVE) == 0)
+ (phba->sli.sli_flag & LPFC_SLI_ACTIVE) == 0)
return NULL;
if (phba->sli.sli_flag & LPFC_BLOCK_MGMT_IO)
@@ -3663,14 +3745,14 @@ lpfc_get_stats(struct Scsi_Host *shost)
return NULL;
memset(pmboxq, 0, sizeof (LPFC_MBOXQ_t));
- pmb = &pmboxq->mb;
+ pmb = &pmboxq->u.mb;
pmb->mbxCommand = MBX_READ_STATUS;
pmb->mbxOwner = OWN_HOST;
pmboxq->context1 = NULL;
pmboxq->vport = vport;
if ((vport->fc_flag & FC_OFFLINE_MODE) ||
- (!(psli->sli_flag & LPFC_SLI2_ACTIVE)))
+ (!(psli->sli_flag & LPFC_SLI_ACTIVE)))
rc = lpfc_sli_issue_mbox(phba, pmboxq, MBX_POLL);
else
rc = lpfc_sli_issue_mbox_wait(phba, pmboxq, phba->fc_ratov * 2);
@@ -3695,7 +3777,7 @@ lpfc_get_stats(struct Scsi_Host *shost)
pmboxq->vport = vport;
if ((vport->fc_flag & FC_OFFLINE_MODE) ||
- (!(psli->sli_flag & LPFC_SLI2_ACTIVE)))
+ (!(psli->sli_flag & LPFC_SLI_ACTIVE)))
rc = lpfc_sli_issue_mbox(phba, pmboxq, MBX_POLL);
else
rc = lpfc_sli_issue_mbox_wait(phba, pmboxq, phba->fc_ratov * 2);
@@ -3769,7 +3851,7 @@ lpfc_reset_stats(struct Scsi_Host *shost)
return;
memset(pmboxq, 0, sizeof(LPFC_MBOXQ_t));
- pmb = &pmboxq->mb;
+ pmb = &pmboxq->u.mb;
pmb->mbxCommand = MBX_READ_STATUS;
pmb->mbxOwner = OWN_HOST;
pmb->un.varWords[0] = 0x1; /* reset request */
@@ -3777,7 +3859,7 @@ lpfc_reset_stats(struct Scsi_Host *shost)
pmboxq->vport = vport;
if ((vport->fc_flag & FC_OFFLINE_MODE) ||
- (!(psli->sli_flag & LPFC_SLI2_ACTIVE)))
+ (!(psli->sli_flag & LPFC_SLI_ACTIVE)))
rc = lpfc_sli_issue_mbox(phba, pmboxq, MBX_POLL);
else
rc = lpfc_sli_issue_mbox_wait(phba, pmboxq, phba->fc_ratov * 2);
@@ -3795,7 +3877,7 @@ lpfc_reset_stats(struct Scsi_Host *shost)
pmboxq->vport = vport;
if ((vport->fc_flag & FC_OFFLINE_MODE) ||
- (!(psli->sli_flag & LPFC_SLI2_ACTIVE)))
+ (!(psli->sli_flag & LPFC_SLI_ACTIVE)))
rc = lpfc_sli_issue_mbox(phba, pmboxq, MBX_POLL);
else
rc = lpfc_sli_issue_mbox_wait(phba, pmboxq, phba->fc_ratov * 2);
@@ -3962,6 +4044,21 @@ lpfc_set_vport_symbolic_name(struct fc_vport *fc_vport)
lpfc_ns_cmd(vport, SLI_CTNS_RSPN_ID, 0, 0);
}
+/**
+ * lpfc_hba_log_verbose_init - Set hba's log verbose level
+ * @phba: Pointer to lpfc_hba struct.
+ *
+ * This function is called by the lpfc_get_cfgparam() routine to set the
+ * module lpfc_log_verbose into the @phba cfg_log_verbose for use with
+ * log messsage according to the module's lpfc_log_verbose parameter setting
+ * before hba port or vport created.
+ **/
+static void
+lpfc_hba_log_verbose_init(struct lpfc_hba *phba, uint32_t verbose)
+{
+ phba->cfg_log_verbose = verbose;
+}
+
struct fc_function_template lpfc_transport_functions = {
/* fixed attributes the driver supports */
.show_host_node_name = 1,
@@ -4105,6 +4202,9 @@ lpfc_get_cfgparam(struct lpfc_hba *phba)
lpfc_poll_tmo_init(phba, lpfc_poll_tmo);
lpfc_enable_npiv_init(phba, lpfc_enable_npiv);
lpfc_use_msi_init(phba, lpfc_use_msi);
+ lpfc_fcp_imax_init(phba, lpfc_fcp_imax);
+ lpfc_fcp_wq_count_init(phba, lpfc_fcp_wq_count);
+ lpfc_fcp_eq_count_init(phba, lpfc_fcp_eq_count);
lpfc_enable_hba_reset_init(phba, lpfc_enable_hba_reset);
lpfc_enable_hba_heartbeat_init(phba, lpfc_enable_hba_heartbeat);
lpfc_enable_bg_init(phba, lpfc_enable_bg);
@@ -4113,26 +4213,10 @@ lpfc_get_cfgparam(struct lpfc_hba *phba)
phba->cfg_soft_wwpn = 0L;
lpfc_sg_seg_cnt_init(phba, lpfc_sg_seg_cnt);
lpfc_prot_sg_seg_cnt_init(phba, lpfc_prot_sg_seg_cnt);
- /*
- * Since the sg_tablesize is module parameter, the sg_dma_buf_size
- * used to create the sg_dma_buf_pool must be dynamically calculated.
- * 2 segments are added since the IOCB needs a command and response bde.
- */
- phba->cfg_sg_dma_buf_size = sizeof(struct fcp_cmnd) +
- sizeof(struct fcp_rsp) +
- ((phba->cfg_sg_seg_cnt + 2) * sizeof(struct ulp_bde64));
-
- if (phba->cfg_enable_bg) {
- phba->cfg_sg_seg_cnt = LPFC_MAX_SG_SEG_CNT;
- phba->cfg_sg_dma_buf_size +=
- phba->cfg_prot_sg_seg_cnt * sizeof(struct ulp_bde64);
- }
-
- /* Also reinitialize the host templates with new values. */
- lpfc_vport_template.sg_tablesize = phba->cfg_sg_seg_cnt;
- lpfc_template.sg_tablesize = phba->cfg_sg_seg_cnt;
-
lpfc_hba_queue_depth_init(phba, lpfc_hba_queue_depth);
+ lpfc_enable_fip_init(phba, lpfc_enable_fip);
+ lpfc_hba_log_verbose_init(phba, lpfc_log_verbose);
+
return;
}
diff --git a/drivers/scsi/lpfc/lpfc_crtn.h b/drivers/scsi/lpfc/lpfc_crtn.h
index f88ce3f2619..d2a922997c0 100644
--- a/drivers/scsi/lpfc/lpfc_crtn.h
+++ b/drivers/scsi/lpfc/lpfc_crtn.h
@@ -23,6 +23,8 @@ typedef int (*node_filter)(struct lpfc_nodelist *, void *);
struct fc_rport;
void lpfc_dump_mem(struct lpfc_hba *, LPFC_MBOXQ_t *, uint16_t);
void lpfc_dump_wakeup_param(struct lpfc_hba *, LPFC_MBOXQ_t *);
+void lpfc_dump_static_vport(struct lpfc_hba *, LPFC_MBOXQ_t *, uint16_t);
+int lpfc_dump_fcoe_param(struct lpfc_hba *, struct lpfcMboxq *);
void lpfc_read_nv(struct lpfc_hba *, LPFC_MBOXQ_t *);
void lpfc_config_async(struct lpfc_hba *, LPFC_MBOXQ_t *, uint32_t);
@@ -35,17 +37,19 @@ int lpfc_config_msi(struct lpfc_hba *, LPFC_MBOXQ_t *);
int lpfc_read_sparam(struct lpfc_hba *, LPFC_MBOXQ_t *, int);
void lpfc_read_config(struct lpfc_hba *, LPFC_MBOXQ_t *);
void lpfc_read_lnk_stat(struct lpfc_hba *, LPFC_MBOXQ_t *);
-int lpfc_reg_login(struct lpfc_hba *, uint16_t, uint32_t, uint8_t *,
- LPFC_MBOXQ_t *, uint32_t);
+int lpfc_reg_rpi(struct lpfc_hba *, uint16_t, uint32_t, uint8_t *,
+ LPFC_MBOXQ_t *, uint32_t);
void lpfc_unreg_login(struct lpfc_hba *, uint16_t, uint32_t, LPFC_MBOXQ_t *);
void lpfc_unreg_did(struct lpfc_hba *, uint16_t, uint32_t, LPFC_MBOXQ_t *);
-void lpfc_reg_vpi(struct lpfc_hba *, uint16_t, uint32_t, LPFC_MBOXQ_t *);
+void lpfc_reg_vpi(struct lpfc_vport *, LPFC_MBOXQ_t *);
void lpfc_unreg_vpi(struct lpfc_hba *, uint16_t, LPFC_MBOXQ_t *);
void lpfc_init_link(struct lpfc_hba *, LPFC_MBOXQ_t *, uint32_t, uint32_t);
+void lpfc_request_features(struct lpfc_hba *, struct lpfcMboxq *);
struct lpfc_vport *lpfc_find_vport_by_did(struct lpfc_hba *, uint32_t);
void lpfc_cleanup_rpis(struct lpfc_vport *, int);
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 *);
@@ -54,6 +58,7 @@ void lpfc_mbx_cmpl_dflt_rpi(struct lpfc_hba *, LPFC_MBOXQ_t *);
void lpfc_mbx_cmpl_fabric_reg_login(struct lpfc_hba *, LPFC_MBOXQ_t *);
void lpfc_mbx_cmpl_ns_reg_login(struct lpfc_hba *, LPFC_MBOXQ_t *);
void lpfc_mbx_cmpl_fdmi_reg_login(struct lpfc_hba *, LPFC_MBOXQ_t *);
+void lpfc_mbx_cmpl_reg_vfi(struct lpfc_hba *, LPFC_MBOXQ_t *);
void lpfc_enqueue_node(struct lpfc_vport *, struct lpfc_nodelist *);
void lpfc_dequeue_node(struct lpfc_vport *, struct lpfc_nodelist *);
struct lpfc_nodelist *lpfc_enable_node(struct lpfc_vport *,
@@ -105,6 +110,7 @@ int lpfc_issue_els_adisc(struct lpfc_vport *, stru