Commit 92d7f7b0 authored by James Smart's avatar James Smart Committed by James Bottomley

[SCSI] lpfc: NPIV: add NPIV support on top of SLI-3

NPIV support is added to the driver.  It utilizes the interfaces of
the fc transport for the creation and deletion of vports. Within the
driver, a new Scsi_Host is created for each NPIV instance, and is
paired with a new instance of a FC port.  This allows N FC Port
elements to share a single Adapter.
Signed-off-by: default avatarJames Smart <James.Smart@emulex.com>
Signed-off-by: default avatarJames Bottomley <James.Bottomley@SteelEye.com>
parent ed957684
#/******************************************************************* #/*******************************************************************
# * This file is part of the Emulex Linux Device Driver for * # * This file is part of the Emulex Linux Device Driver for *
# * Fibre Channel Host Bus Adapters. * # * Fibre Channel Host Bus Adapters. *
# * Copyright (C) 2004-2005 Emulex. All rights reserved. * # * Copyright (C) 2004-2006 Emulex. All rights reserved. *
# * EMULEX and SLI are trademarks of Emulex. * # * EMULEX and SLI are trademarks of Emulex. *
# * www.emulex.com * # * www.emulex.com *
# * * # * *
...@@ -27,4 +27,5 @@ endif ...@@ -27,4 +27,5 @@ endif
obj-$(CONFIG_SCSI_LPFC) := lpfc.o obj-$(CONFIG_SCSI_LPFC) := lpfc.o
lpfc-objs := lpfc_mem.o lpfc_sli.o lpfc_ct.o lpfc_els.o lpfc_hbadisc.o \ lpfc-objs := lpfc_mem.o lpfc_sli.o lpfc_ct.o lpfc_els.o lpfc_hbadisc.o \
lpfc_init.o lpfc_mbox.o lpfc_nportdisc.o lpfc_scsi.o lpfc_attr.o lpfc_init.o lpfc_mbox.o lpfc_nportdisc.o lpfc_scsi.o lpfc_attr.o \
lpfc_vport.o
...@@ -34,6 +34,17 @@ struct lpfc_sli2_slim; ...@@ -34,6 +34,17 @@ struct lpfc_sli2_slim;
#define LPFC_IOCB_LIST_CNT 2250 /* list of IOCBs for fast-path usage. */ #define LPFC_IOCB_LIST_CNT 2250 /* list of IOCBs for fast-path usage. */
#define LPFC_Q_RAMP_UP_INTERVAL 120 /* lun q_depth ramp up interval */ #define LPFC_Q_RAMP_UP_INTERVAL 120 /* lun q_depth ramp up interval */
/*
* Following time intervals are used of adjusting SCSI device
* queue depths when there are driver resource error or Firmware
* resource error.
*/
#define QUEUE_RAMP_DOWN_INTERVAL (1 * HZ) /* 1 Second */
#define QUEUE_RAMP_UP_INTERVAL (300 * HZ) /* 5 minutes */
/* Number of exchanges reserved for discovery to complete */
#define LPFC_DISC_IOCB_BUFF_COUNT 20
/* Define macros for 64 bit support */ /* Define macros for 64 bit support */
#define putPaddrLow(addr) ((uint32_t) (0xffffffff & (u64)(addr))) #define putPaddrLow(addr) ((uint32_t) (0xffffffff & (u64)(addr)))
#define putPaddrHigh(addr) ((uint32_t) (0xffffffff & (((u64)(addr))>>32))) #define putPaddrHigh(addr) ((uint32_t) (0xffffffff & (((u64)(addr))>>32)))
...@@ -97,6 +108,29 @@ typedef struct lpfc_vpd { ...@@ -97,6 +108,29 @@ typedef struct lpfc_vpd {
uint32_t sli2FwRev; uint32_t sli2FwRev;
uint8_t sli2FwName[16]; uint8_t sli2FwName[16];
} rev; } rev;
struct {
#ifdef __BIG_ENDIAN_BITFIELD
uint32_t rsvd2 :24; /* Reserved */
uint32_t cmv : 1; /* Configure Max VPIs */
uint32_t ccrp : 1; /* Config Command Ring Polling */
uint32_t csah : 1; /* Configure Synchronous Abort Handling */
uint32_t chbs : 1; /* Cofigure Host Backing store */
uint32_t cinb : 1; /* Enable Interrupt Notification Block */
uint32_t cerbm : 1; /* Configure Enhanced Receive Buf Mgmt */
uint32_t cmx : 1; /* Configure Max XRIs */
uint32_t cmr : 1; /* Configure Max RPIs */
#else /* __LITTLE_ENDIAN */
uint32_t cmr : 1; /* Configure Max RPIs */
uint32_t cmx : 1; /* Configure Max XRIs */
uint32_t cerbm : 1; /* Configure Enhanced Receive Buf Mgmt */
uint32_t cinb : 1; /* Enable Interrupt Notification Block */
uint32_t chbs : 1; /* Cofigure Host Backing store */
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 */
#endif
} sli3Feat;
} lpfc_vpd_t; } lpfc_vpd_t;
struct lpfc_scsi_buf; struct lpfc_scsi_buf;
...@@ -129,6 +163,7 @@ struct lpfc_stats { ...@@ -129,6 +163,7 @@ struct lpfc_stats {
uint32_t elsRcvRPS; uint32_t elsRcvRPS;
uint32_t elsRcvRPL; uint32_t elsRcvRPL;
uint32_t elsXmitFLOGI; uint32_t elsXmitFLOGI;
uint32_t elsXmitFDISC;
uint32_t elsXmitPLOGI; uint32_t elsXmitPLOGI;
uint32_t elsXmitPRLI; uint32_t elsXmitPRLI;
uint32_t elsXmitADISC; uint32_t elsXmitADISC;
...@@ -174,17 +209,20 @@ struct lpfc_sysfs_mbox { ...@@ -174,17 +209,20 @@ struct lpfc_sysfs_mbox {
struct lpfc_hba; struct lpfc_hba;
enum discovery_state { enum discovery_state {
LPFC_STATE_UNKNOWN = 0, /* HBA state is unknown */ LPFC_VPORT_UNKNOWN = 0, /* vport state is unknown */
LPFC_VPORT_FAILED = 1, /* vport has failed */
LPFC_LOCAL_CFG_LINK = 6, /* local NPORT Id configured */ LPFC_LOCAL_CFG_LINK = 6, /* local NPORT Id configured */
LPFC_FLOGI = 7, /* FLOGI sent to Fabric */ LPFC_FLOGI = 7, /* FLOGI sent to Fabric */
LPFC_FABRIC_CFG_LINK = 8, /* Fabric assigned NPORT Id LPFC_FDISC = 8, /* FDISC sent for vport */
LPFC_FABRIC_CFG_LINK = 9, /* Fabric assigned NPORT Id
* configured */ * configured */
LPFC_NS_REG = 9, /* Register with NameServer */ LPFC_NS_REG = 10, /* Register with NameServer */
LPFC_NS_QRY = 10, /* Query NameServer for NPort ID list */ LPFC_NS_QRY = 11, /* Query NameServer for NPort ID list */
LPFC_BUILD_DISC_LIST = 11, /* Build ADISC and PLOGI lists for LPFC_BUILD_DISC_LIST = 12, /* Build ADISC and PLOGI lists for
* device authentication / discovery */ * device authentication / discovery */
LPFC_DISC_AUTH = 12, /* Processing ADISC list */ LPFC_DISC_AUTH = 13, /* Processing ADISC list */
LPFC_VPORT_READY = 32, LPFC_VPORT_READY = 32,
}; };
...@@ -195,8 +233,9 @@ enum hba_state { ...@@ -195,8 +233,9 @@ enum hba_state {
LPFC_INIT_MBX_CMDS = 3, /* Initialize HBA with mbox commands */ LPFC_INIT_MBX_CMDS = 3, /* Initialize HBA with mbox commands */
LPFC_LINK_DOWN = 4, /* HBA initialized, link is down */ LPFC_LINK_DOWN = 4, /* HBA initialized, link is down */
LPFC_LINK_UP = 5, /* Link is up - issue READ_LA */ LPFC_LINK_UP = 5, /* Link is up - issue READ_LA */
LPFC_CLEAR_LA = 13, /* authentication cmplt - issue LPFC_CLEAR_LA = 6, /* authentication cmplt - issue
* CLEAR_LA */ * CLEAR_LA */
LPFC_HBA_READY = 32,
LPFC_HBA_ERROR = -1 LPFC_HBA_ERROR = -1
}; };
...@@ -209,6 +248,7 @@ struct lpfc_vport { ...@@ -209,6 +248,7 @@ struct lpfc_vport {
#define LPFC_FABRIC_PORT 3 #define LPFC_FABRIC_PORT 3
enum discovery_state port_state; enum discovery_state port_state;
uint16_t vpi;
uint32_t fc_flag; /* FC flags */ uint32_t fc_flag; /* FC flags */
/* Several of these flags are HBA centric and should be moved to /* Several of these flags are HBA centric and should be moved to
...@@ -224,11 +264,14 @@ struct lpfc_vport { ...@@ -224,11 +264,14 @@ struct lpfc_vport {
#define FC_OFFLINE_MODE 0x80 /* Interface is offline for diag */ #define FC_OFFLINE_MODE 0x80 /* Interface is offline for diag */
#define FC_FABRIC 0x100 /* We are fabric attached */ #define FC_FABRIC 0x100 /* We are fabric attached */
#define FC_ESTABLISH_LINK 0x200 /* Reestablish Link */ #define FC_ESTABLISH_LINK 0x200 /* Reestablish Link */
#define FC_RSCN_DISCOVERY 0x400 /* Authenticate all devices after RSCN*/ #define FC_RSCN_DISCOVERY 0x400 /* Auth all devices after RSCN */
#define FC_SCSI_SCAN_TMO 0x4000 /* scsi scan timer running */ #define FC_SCSI_SCAN_TMO 0x4000 /* scsi scan timer running */
#define FC_ABORT_DISCOVERY 0x8000 /* we want to abort discovery */ #define FC_ABORT_DISCOVERY 0x8000 /* we want to abort discovery */
#define FC_NDISC_ACTIVE 0x10000 /* NPort discovery active */ #define FC_NDISC_ACTIVE 0x10000 /* NPort discovery active */
#define FC_BYPASSED_MODE 0x20000 /* NPort is in bypassed mode */ #define FC_BYPASSED_MODE 0x20000 /* NPort is in bypassed mode */
#define FC_RFF_NOT_SUPPORTED 0x40000 /* RFF_ID was rejected by switch */
#define FC_VPORT_NEEDS_REG_VPI 0x80000 /* Needs to have its vpi registered */
#define FC_RSCN_DEFERRED 0x100000 /* A deferred RSCN being processed */
struct list_head fc_nodes; struct list_head fc_nodes;
...@@ -269,6 +312,9 @@ struct lpfc_vport { ...@@ -269,6 +312,9 @@ struct lpfc_vport {
#define WORKER_ELS_TMO 0x2 /* ELS timeout */ #define WORKER_ELS_TMO 0x2 /* ELS timeout */
#define WORKER_MBOX_TMO 0x4 /* MBOX timeout */ #define WORKER_MBOX_TMO 0x4 /* MBOX timeout */
#define WORKER_FDMI_TMO 0x8 /* FDMI timeout */ #define WORKER_FDMI_TMO 0x8 /* FDMI timeout */
#define WORKER_FABRIC_BLOCK_TMO 0x10 /* fabric block timout */
#define WORKER_RAMP_DOWN_QUEUE 0x20 /* Decrease Q depth */
#define WORKER_RAMP_UP_QUEUE 0x40 /* Increase Q depth */
struct timer_list fc_fdmitmo; struct timer_list fc_fdmitmo;
struct timer_list els_tmofunc; struct timer_list els_tmofunc;
...@@ -278,10 +324,10 @@ struct lpfc_vport { ...@@ -278,10 +324,10 @@ struct lpfc_vport {
uint8_t load_flag; uint8_t load_flag;
#define FC_LOADING 0x1 /* HBA in process of loading drvr */ #define FC_LOADING 0x1 /* HBA in process of loading drvr */
#define FC_UNLOADING 0x2 /* HBA in process of unloading drvr */ #define FC_UNLOADING 0x2 /* HBA in process of unloading drvr */
char *vname; /* Application assigned name */
struct fc_vport *fc_vport;
}; };
struct hbq_s { struct hbq_s {
uint16_t entry_count; /* Current number of HBQ slots */ uint16_t entry_count; /* Current number of HBQ slots */
uint32_t next_hbqPutIdx; /* Index to next HBQ slot to use */ uint32_t next_hbqPutIdx; /* Index to next HBQ slot to use */
...@@ -289,7 +335,9 @@ struct hbq_s { ...@@ -289,7 +335,9 @@ struct hbq_s {
uint32_t local_hbqGetIdx; /* Local copy of Get index from Port */ uint32_t local_hbqGetIdx; /* Local copy of Get index from Port */
}; };
#define MAX_HBQS 16 #define LPFC_MAX_HBQS 16
/* this matches the possition in the lpfc_hbq_defs array */
#define LPFC_ELS_HBQ 0
struct lpfc_hba { struct lpfc_hba {
struct lpfc_sli sli; struct lpfc_sli sli;
...@@ -297,25 +345,28 @@ struct lpfc_hba { ...@@ -297,25 +345,28 @@ struct lpfc_hba {
uint32_t sli3_options; /* Mask of enabled SLI3 options */ uint32_t sli3_options; /* Mask of enabled SLI3 options */
#define LPFC_SLI3_ENABLED 0x01 #define LPFC_SLI3_ENABLED 0x01
#define LPFC_SLI3_HBQ_ENABLED 0x02 #define LPFC_SLI3_HBQ_ENABLED 0x02
#define LPFC_SLI3_INB_ENABLED 0x04 #define LPFC_SLI3_NPIV_ENABLED 0x04
#define LPFC_SLI3_VPORT_TEARDOWN 0x08
uint32_t iocb_cmd_size; uint32_t iocb_cmd_size;
uint32_t iocb_rsp_size; uint32_t iocb_rsp_size;
enum hba_state link_state; enum hba_state link_state;
uint32_t link_flag; /* link state flags */ uint32_t link_flag; /* link state flags */
#define LS_LOOPBACK_MODE 0x40000 /* NPort is in Loopback mode */ #define LS_LOOPBACK_MODE 0x1 /* NPort is in Loopback mode */
/* This flag is set while issuing */ /* This flag is set while issuing */
/* INIT_LINK mailbox command */ /* INIT_LINK mailbox command */
#define LS_IGNORE_ERATT 0x80000 /* intr handler should ignore ERATT */ #define LS_NPIV_FAB_SUPPORTED 0x2 /* Fabric supports NPIV */
#define LS_IGNORE_ERATT 0x3 /* intr handler should ignore ERATT */
struct lpfc_sli2_slim *slim2p; struct lpfc_sli2_slim *slim2p;
struct lpfc_dmabuf hbqslimp; struct lpfc_dmabuf hbqslimp;
dma_addr_t slim2p_mapping; dma_addr_t slim2p_mapping;
uint16_t pci_cfg_value; uint16_t pci_cfg_value;
uint8_t work_found;
#define LPFC_MAX_WORKER_ITERATION 4
uint8_t fc_linkspeed; /* Link speed after last READ_LA */ uint8_t fc_linkspeed; /* Link speed after last READ_LA */
...@@ -355,6 +406,8 @@ struct lpfc_hba { ...@@ -355,6 +406,8 @@ struct lpfc_hba {
uint32_t cfg_nodev_tmo; uint32_t cfg_nodev_tmo;
uint32_t cfg_devloss_tmo; uint32_t cfg_devloss_tmo;
uint32_t cfg_hba_queue_depth; uint32_t cfg_hba_queue_depth;
uint32_t cfg_peer_port_login;
uint32_t cfg_vport_restrict_login;
uint32_t cfg_fcp_class; uint32_t cfg_fcp_class;
uint32_t cfg_use_adisc; uint32_t cfg_use_adisc;
uint32_t cfg_ack0; uint32_t cfg_ack0;
...@@ -391,11 +444,9 @@ struct lpfc_hba { ...@@ -391,11 +444,9 @@ struct lpfc_hba {
wait_queue_head_t *work_wait; wait_queue_head_t *work_wait;
struct task_struct *worker_thread; struct task_struct *worker_thread;
struct hbq_dmabuf *hbq_buffer_pool; struct list_head hbq_buffer_list;
uint32_t hbq_buffer_count;
uint32_t hbq_buff_count; /* Current hbq buffers */
uint32_t hbq_count; /* Count of configured HBQs */ uint32_t hbq_count; /* Count of configured HBQs */
struct hbq_s hbqs[MAX_HBQS]; /* local copy of hbq indicies */ 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_bar0_map; /* Physical address for PCI BAR0 */
unsigned long pci_bar2_map; /* Physical address for PCI BAR2 */ unsigned long pci_bar2_map; /* Physical address for PCI BAR2 */
...@@ -413,7 +464,7 @@ struct lpfc_hba { ...@@ -413,7 +464,7 @@ struct lpfc_hba {
struct lpfc_hgp __iomem *host_gp; /* Host side get/put pointers */ struct lpfc_hgp __iomem *host_gp; /* Host side get/put pointers */
uint32_t __iomem *hbq_put; /* Address in SLIM to HBQ put ptrs */ uint32_t __iomem *hbq_put; /* Address in SLIM to HBQ put ptrs */
uint32_t __iomem *hbq_get; /* Address in SLIM to HBQ get ptrs */ uint32_t *hbq_get; /* Host mem address of HBQ get ptrs */
int brd_no; /* FC board number */ int brd_no; /* FC board number */
...@@ -464,6 +515,22 @@ struct lpfc_hba { ...@@ -464,6 +515,22 @@ struct lpfc_hba {
struct fc_host_statistics link_stats; struct fc_host_statistics link_stats;
struct list_head port_list; struct list_head port_list;
struct lpfc_vport *pport; /* physical lpfc_vport pointer */ struct lpfc_vport *pport; /* physical lpfc_vport pointer */
uint16_t max_vpi; /* Maximum virtual nports */
uint16_t vpi_cnt; /* Nport count */
#define LPFC_MAX_VPI 100 /* Max number of VPorts supported */
unsigned long *vpi_bmask; /* vpi allocation table */
/* Data structure used by fabric iocb scheduler */
struct list_head fabric_iocb_list;
atomic_t fabric_iocb_count;
struct timer_list fabric_block_timer;
unsigned long bit_flags;
#define FABRIC_COMANDS_BLOCKED 0
atomic_t num_rsrc_err;
atomic_t num_cmd_success;
unsigned long last_rsrc_error_time;
unsigned long last_ramp_down_time;
unsigned long last_ramp_up_time;
}; };
static inline struct Scsi_Host * static inline struct Scsi_Host *
...@@ -485,10 +552,9 @@ static inline int ...@@ -485,10 +552,9 @@ static inline int
lpfc_is_link_up(struct lpfc_hba *phba) lpfc_is_link_up(struct lpfc_hba *phba)
{ {
return phba->link_state == LPFC_LINK_UP || return phba->link_state == LPFC_LINK_UP ||
phba->link_state == LPFC_CLEAR_LA; phba->link_state == LPFC_CLEAR_LA ||
phba->link_state == LPFC_HBA_READY;
} }
#define FC_REG_DUMP_EVENT 0x10 /* Register for Dump events */ #define FC_REG_DUMP_EVENT 0x10 /* Register for Dump events */
This diff is collapsed.
...@@ -28,15 +28,18 @@ int lpfc_read_la(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb, ...@@ -28,15 +28,18 @@ int lpfc_read_la(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb,
void lpfc_clear_la(struct lpfc_hba *, LPFC_MBOXQ_t *); void lpfc_clear_la(struct lpfc_hba *, LPFC_MBOXQ_t *);
void lpfc_issue_clear_la(struct lpfc_hba *phba, struct lpfc_vport *vport); void lpfc_issue_clear_la(struct lpfc_hba *phba, struct lpfc_vport *vport);
void lpfc_config_link(struct lpfc_hba *, LPFC_MBOXQ_t *); void lpfc_config_link(struct lpfc_hba *, LPFC_MBOXQ_t *);
int lpfc_read_sparam(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_config(struct lpfc_hba *, LPFC_MBOXQ_t *);
void lpfc_read_lnk_stat(struct lpfc_hba *, LPFC_MBOXQ_t *); void lpfc_read_lnk_stat(struct lpfc_hba *, LPFC_MBOXQ_t *);
int lpfc_reg_login(struct lpfc_hba *, uint32_t, uint8_t *, LPFC_MBOXQ_t *, int lpfc_reg_login(struct lpfc_hba *, uint16_t, uint32_t, uint8_t *,
uint32_t); LPFC_MBOXQ_t *, uint32_t);
void lpfc_unreg_login(struct lpfc_hba *, uint32_t, LPFC_MBOXQ_t *); void lpfc_unreg_login(struct lpfc_hba *, uint16_t, uint32_t, LPFC_MBOXQ_t *);
void lpfc_unreg_did(struct lpfc_hba *, 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_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_init_link(struct lpfc_hba *, LPFC_MBOXQ_t *, uint32_t, uint32_t);
void lpfc_cleanup_rpis(struct lpfc_vport *vport, int remove);
int lpfc_linkdown(struct lpfc_hba *); int lpfc_linkdown(struct lpfc_hba *);
void lpfc_mbx_cmpl_read_la(struct lpfc_hba *, LPFC_MBOXQ_t *); void lpfc_mbx_cmpl_read_la(struct lpfc_hba *, LPFC_MBOXQ_t *);
...@@ -51,6 +54,10 @@ void lpfc_drop_node(struct lpfc_vport *, struct lpfc_nodelist *); ...@@ -51,6 +54,10 @@ void lpfc_drop_node(struct lpfc_vport *, struct lpfc_nodelist *);
void lpfc_set_disctmo(struct lpfc_vport *); void lpfc_set_disctmo(struct lpfc_vport *);
int lpfc_can_disctmo(struct lpfc_vport *); int lpfc_can_disctmo(struct lpfc_vport *);
int lpfc_unreg_rpi(struct lpfc_vport *, struct lpfc_nodelist *); int lpfc_unreg_rpi(struct lpfc_vport *, struct lpfc_nodelist *);
void lpfc_unreg_all_rpis(struct lpfc_vport *);
void lpfc_unreg_default_rpis(struct lpfc_vport *);
void lpfc_issue_reg_vpi(struct lpfc_hba *, struct lpfc_vport *);
int lpfc_check_sli_ndlp(struct lpfc_hba *, struct lpfc_sli_ring *, int lpfc_check_sli_ndlp(struct lpfc_hba *, struct lpfc_sli_ring *,
struct lpfc_iocbq *, struct lpfc_nodelist *); struct lpfc_iocbq *, struct lpfc_nodelist *);
void lpfc_nlp_init(struct lpfc_vport *, struct lpfc_nodelist *, uint32_t); void lpfc_nlp_init(struct lpfc_vport *, struct lpfc_nodelist *, uint32_t);
...@@ -60,25 +67,33 @@ struct lpfc_nodelist *lpfc_setup_disc_node(struct lpfc_vport *, uint32_t); ...@@ -60,25 +67,33 @@ struct lpfc_nodelist *lpfc_setup_disc_node(struct lpfc_vport *, uint32_t);
void lpfc_disc_list_loopmap(struct lpfc_vport *); void lpfc_disc_list_loopmap(struct lpfc_vport *);
void lpfc_disc_start(struct lpfc_vport *); void lpfc_disc_start(struct lpfc_vport *);
void lpfc_disc_flush_list(struct lpfc_vport *); void lpfc_disc_flush_list(struct lpfc_vport *);
void lpfc_cleanup_discovery_resources(struct lpfc_vport *);
void lpfc_disc_timeout(unsigned long); void lpfc_disc_timeout(unsigned long);
struct lpfc_nodelist *__lpfc_findnode_rpi(struct lpfc_vport *, uint16_t); struct lpfc_nodelist *__lpfc_findnode_rpi(struct lpfc_vport *, uint16_t);
struct lpfc_nodelist *lpfc_findnode_rpi(struct lpfc_vport *, uint16_t); struct lpfc_nodelist *lpfc_findnode_rpi(struct lpfc_vport *, uint16_t);
void lpfc_worker_wake_up(struct lpfc_hba *);
int lpfc_workq_post_event(struct lpfc_hba *, void *, void *, uint32_t); int lpfc_workq_post_event(struct lpfc_hba *, void *, void *, uint32_t);
int lpfc_do_work(void *); int lpfc_do_work(void *);
int lpfc_disc_state_machine(struct lpfc_vport *, struct lpfc_nodelist *, void *, int lpfc_disc_state_machine(struct lpfc_vport *, struct lpfc_nodelist *, void *,
uint32_t); uint32_t);
void lpfc_register_new_vport(struct lpfc_hba *, struct lpfc_vport *,
struct lpfc_nodelist *);
void lpfc_do_scr_ns_plogi(struct lpfc_hba *, struct lpfc_vport *);
int lpfc_check_sparm(struct lpfc_vport *, struct lpfc_nodelist *, int lpfc_check_sparm(struct lpfc_vport *, struct lpfc_nodelist *,
struct serv_parm *, uint32_t); struct serv_parm *, uint32_t);
int lpfc_els_abort(struct lpfc_hba *, struct lpfc_nodelist * ndlp); int lpfc_els_abort(struct lpfc_hba *, struct lpfc_nodelist *);
int lpfc_els_abort_flogi(struct lpfc_hba *); int lpfc_els_abort_flogi(struct lpfc_hba *);
int lpfc_initial_flogi(struct lpfc_vport *); int lpfc_initial_flogi(struct lpfc_vport *);
int lpfc_initial_fdisc(struct lpfc_vport *);
int lpfc_issue_els_fdisc(struct lpfc_vport *, struct lpfc_nodelist *, uint8_t);
int lpfc_issue_els_plogi(struct lpfc_vport *, uint32_t, uint8_t); 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); int lpfc_issue_els_prli(struct lpfc_vport *, struct lpfc_nodelist *, uint8_t);
int lpfc_issue_els_adisc(struct lpfc_vport *, struct lpfc_nodelist *, uint8_t); int lpfc_issue_els_adisc(struct lpfc_vport *, struct lpfc_nodelist *, uint8_t);
int lpfc_issue_els_logo(struct lpfc_vport *, struct lpfc_nodelist *, uint8_t); int lpfc_issue_els_logo(struct lpfc_vport *, struct lpfc_nodelist *, uint8_t);
int lpfc_issue_els_npiv_logo(struct lpfc_vport *, struct lpfc_nodelist *);
int lpfc_issue_els_scr(struct lpfc_vport *, uint32_t, uint8_t); int lpfc_issue_els_scr(struct lpfc_vport *, uint32_t, uint8_t);
int lpfc_els_free_iocb(struct lpfc_hba *, struct lpfc_iocbq *); int lpfc_els_free_iocb(struct lpfc_hba *, struct lpfc_iocbq *);
int lpfc_els_rsp_acc(struct lpfc_vport *, uint32_t, struct lpfc_iocbq *, int lpfc_els_rsp_acc(struct lpfc_vport *, uint32_t, struct lpfc_iocbq *,
...@@ -95,7 +110,7 @@ void lpfc_els_retry_delay_handler(struct lpfc_nodelist *); ...@@ -95,7 +110,7 @@ void lpfc_els_retry_delay_handler(struct lpfc_nodelist *);
void lpfc_els_unsol_event(struct lpfc_hba *, struct lpfc_sli_ring *, void lpfc_els_unsol_event(struct lpfc_hba *, struct lpfc_sli_ring *,
struct lpfc_iocbq *); struct lpfc_iocbq *);
int lpfc_els_handle_rscn(struct lpfc_vport *); int lpfc_els_handle_rscn(struct lpfc_vport *);
int lpfc_els_flush_rscn(struct lpfc_vport *); void lpfc_els_flush_rscn(struct lpfc_vport *);
int lpfc_rscn_payload_check(struct lpfc_vport *, uint32_t); int lpfc_rscn_payload_check(struct lpfc_vport *, uint32_t);
void lpfc_els_flush_cmd(struct lpfc_vport *); void lpfc_els_flush_cmd(struct lpfc_vport *);
int lpfc_els_disc_adisc(struct lpfc_vport *); int lpfc_els_disc_adisc(struct lpfc_vport *);
...@@ -105,7 +120,7 @@ void lpfc_els_timeout_handler(struct lpfc_vport *); ...@@ -105,7 +120,7 @@ void lpfc_els_timeout_handler(struct lpfc_vport *);
void lpfc_ct_unsol_event(struct lpfc_hba *, struct lpfc_sli_ring *, void lpfc_ct_unsol_event(struct lpfc_hba *, struct lpfc_sli_ring *,
struct lpfc_iocbq *); struct lpfc_iocbq *);
int lpfc_ns_cmd(struct lpfc_vport *, struct lpfc_nodelist *, int); int lpfc_ns_cmd(struct lpfc_vport *, int, uint8_t, uint32_t);
int lpfc_fdmi_cmd(struct lpfc_vport *, struct lpfc_nodelist *, int); int lpfc_fdmi_cmd(struct lpfc_vport *, struct lpfc_nodelist *, int);
void lpfc_fdmi_tmo(unsigned long); void lpfc_fdmi_tmo(unsigned long);
void lpfc_fdmi_timeout_handler(struct lpfc_vport *vport); void lpfc_fdmi_timeout_handler(struct lpfc_vport *vport);
...@@ -136,6 +151,7 @@ void lpfc_config_port(struct lpfc_hba *, LPFC_MBOXQ_t *); ...@@ -136,6 +151,7 @@ void lpfc_config_port(struct lpfc_hba *, LPFC_MBOXQ_t *);
void lpfc_kill_board(struct lpfc_hba *, LPFC_MBOXQ_t *); void lpfc_kill_board(struct lpfc_hba *, LPFC_MBOXQ_t *);
void lpfc_mbox_put(struct lpfc_hba *, LPFC_MBOXQ_t *); void lpfc_mbox_put(struct lpfc_hba *, LPFC_MBOXQ_t *);
LPFC_MBOXQ_t *lpfc_mbox_get(struct lpfc_hba *); LPFC_MBOXQ_t *lpfc_mbox_get(struct lpfc_hba *);
void lpfc_mbox_cmpl_put(struct lpfc_hba *, LPFC_MBOXQ_t *);
int lpfc_mbox_tmo_val(struct lpfc_hba *, int); int lpfc_mbox_tmo_val(struct lpfc_hba *, int);
void lpfc_config_hbq(struct lpfc_hba *, struct lpfc_hbq_init *, uint32_t , void lpfc_config_hbq(struct lpfc_hba *, struct lpfc_hbq_init *, uint32_t ,
...@@ -144,6 +160,7 @@ struct lpfc_hbq_entry * lpfc_sli_next_hbq_slot(struct lpfc_hba *, uint32_t); ...@@ -144,6 +160,7 @@ struct lpfc_hbq_entry * lpfc_sli_next_hbq_slot(struct lpfc_hba *, uint32_t);
int lpfc_mem_alloc(struct lpfc_hba *); int lpfc_mem_alloc(struct lpfc_hba *);
void lpfc_mem_free(struct lpfc_hba *); void lpfc_mem_free(struct lpfc_hba *);
void lpfc_stop_vport_timers(struct lpfc_vport *);
void lpfc_poll_timeout(unsigned long ptr); void lpfc_poll_timeout(unsigned long ptr);
void lpfc_poll_start_timer(struct lpfc_hba * phba); void lpfc_poll_start_timer(struct lpfc_hba * phba);
...@@ -176,11 +193,10 @@ int lpfc_sli_ringpostbuf_put(struct lpfc_hba *, struct lpfc_sli_ring *, ...@@ -176,11 +193,10 @@ int lpfc_sli_ringpostbuf_put(struct lpfc_hba *, struct lpfc_sli_ring *,
struct lpfc_dmabuf *lpfc_sli_ringpostbuf_get(struct lpfc_hba *, struct lpfc_dmabuf *lpfc_sli_ringpostbuf_get(struct lpfc_hba *,
struct lpfc_sli_ring *, struct lpfc_sli_ring *,
dma_addr_t); dma_addr_t);
int lpfc_sli_hbqbuf_fill_hbq(struct lpfc_hba *); int lpfc_sli_hbqbuf_init_hbqs(struct lpfc_hba *, uint32_t);
void lpfc_sli_hbqbuf_free(struct lpfc_hba *, void *, dma_addr_t); int lpfc_sli_hbqbuf_add_hbqs(struct lpfc_hba *, uint32_t);
void lpfc_sli_hbqbuf_free_all(struct lpfc_hba *); void lpfc_sli_hbqbuf_free_all(struct lpfc_hba *);
struct hbq_dmabuf *lpfc_sli_hbqbuf_find(struct lpfc_hba *, uint32_t); struct hbq_dmabuf *lpfc_sli_hbqbuf_find(struct lpfc_hba *, uint32_t);
void lpfc_sli_free_hbq(struct lpfc_hba *, struct hbq_dmabuf *);
int lpfc_sli_hbq_size(void); int lpfc_sli_hbq_size(void);
int lpfc_sli_issue_abort_iotag(struct lpfc_hba *, struct lpfc_sli_ring *, int lpfc_sli_issue_abort_iotag(struct lpfc_hba *, struct lpfc_sli_ring *,
struct lpfc_iocbq *); struct lpfc_iocbq *);
...@@ -192,6 +208,9 @@ int lpfc_sli_abort_iocb(struct lpfc_hba *, struct lpfc_sli_ring *, uint16_t, ...@@ -192,6 +208,9 @@ int lpfc_sli_abort_iocb(struct lpfc_hba *, struct lpfc_sli_ring *, uint16_t,
void lpfc_mbox_timeout(unsigned long); void lpfc_mbox_timeout(unsigned long);
void lpfc_mbox_timeout_handler(struct lpfc_hba *); void lpfc_mbox_timeout_handler(struct lpfc_hba *);
struct lpfc_nodelist *__lpfc_find_node(struct lpfc_vport *, node_filter,
void *);
struct lpfc_nodelist *lpfc_find_node(struct lpfc_vport *, node_filter, void *);
struct lpfc_nodelist *lpfc_findnode_did(struct lpfc_vport *, uint32_t); struct lpfc_nodelist *lpfc_findnode_did(struct lpfc_vport *, uint32_t);
struct lpfc_nodelist *lpfc_findnode_wwpn(struct lpfc_vport *, struct lpfc_nodelist *lpfc_findnode_wwpn(struct lpfc_vport *,
struct lpfc_name *); struct lpfc_name *);
...@@ -210,11 +229,13 @@ void lpfc_sli_abort_fcp_cmpl(struct lpfc_hba * phba, ...@@ -210,11 +229,13 @@ void lpfc_sli_abort_fcp_cmpl(struct lpfc_hba * phba,
void *lpfc_hbq_alloc(struct lpfc_hba *, int, dma_addr_t *); void *lpfc_hbq_alloc(struct lpfc_hba *, int, dma_addr_t *);
void lpfc_hbq_free(struct lpfc_hba *, void *, dma_addr_t); void lpfc_hbq_free(struct lpfc_hba *, void *, dma_addr_t);
void lpfc_sli_free_hbq(struct lpfc_hba *, struct hbq_dmabuf *);
void *lpfc_mbuf_alloc(struct lpfc_hba *, int, dma_addr_t *); void *lpfc_mbuf_alloc(struct lpfc_hba *, int, dma_addr_t *);
void __lpfc_mbuf_free(struct lpfc_hba *, void *, dma_addr_t); void __lpfc_mbuf_free(struct lpfc_hba *, void *, dma_addr_t);
void lpfc_mbuf_free(struct lpfc_hba *, void *, dma_addr_t); void lpfc_mbuf_free(struct lpfc_hba *, void *, dma_addr_t);
void lpfc_in_buf_free(struct lpfc_hba *, struct lpfc_dmabuf *);
/* Function prototypes. */ /* Function prototypes. */
const char* lpfc_info(struct Scsi_Host *); const char* lpfc_info(struct Scsi_Host *);
void lpfc_scan_start(struct Scsi_Host *); void lpfc_scan_start(struct Scsi_Host *);
...@@ -226,14 +247,34 @@ void lpfc_free_sysfs_attr(struct lpfc_vport *); ...@@ -226,14 +247,34 @@ void lpfc_free_sysfs_attr(struct lpfc_vport *);
extern struct class_device_attribute *lpfc_hba_attrs[]; extern struct class_device_attribute *lpfc_hba_attrs[];
extern struct scsi_host_template lpfc_template; extern struct scsi_host_template lpfc_template;
extern struct fc_function_template lpfc_transport_functions; extern struct fc_function_template lpfc_transport_functions;
extern struct fc_function_template lpfc_vport_transport_functions;
extern int lpfc_sli_mode; extern int lpfc_sli_mode;
extern int lpfc_npiv_enable;
void lpfc_get_hba_sym_node_name(struct lpfc_hba *phba, uint8_t *symbp); int lpfc_vport_symbolic_node_name(struct lpfc_vport *, char *, size_t);
void lpfc_terminate_rport_io(struct fc_rport *); void lpfc_terminate_rport_io(struct fc_rport *);
void lpfc_dev_loss_tmo_callbk(struct fc_rport *rport); void lpfc_dev_loss_tmo_callbk(struct fc_rport *rport);
struct lpfc_vport *lpfc_create_port(struct lpfc_hba *, int); struct lpfc_vport *lpfc_create_port(struct lpfc_hba *, int, struct fc_vport *);
void lpfc_post_hba_setup_vport_init(struct lpfc_vport *); int lpfc_vport_disable(struct fc_vport *fc_vport, bool disable);
void lpfc_mbx_unreg_vpi(struct lpfc_vport *);
void destroy_port(struct lpfc_vport *); void destroy_port(struct lpfc_vport *);
int lpfc_get_instance(void);
void lpfc_host_attrib_init(struct Scsi_Host *);
/* Interface exported by fabric iocb scheduler */
int lpfc_issue_fabric_iocb(struct lpfc_hba *, struct lpfc_iocbq *);
void lpfc_fabric_abort_vport(struct lpfc_vport *);
void lpfc_fabric_abort_nport(struct lpfc_nodelist *);
void lpfc_fabric_abort_hba(struct lpfc_hba *);
void lpfc_fabric_abort_flogi(struct lpfc_hba *);
void lpfc_fabric_block_timeout(unsigned long);
void lpfc_unblock_fabric_iocbs(struct lpfc_hba *);
void lpfc_adjust_queue_depth(struct lpfc_hba *);
void lpfc_ramp_down_queue_handler(struct lpfc_hba *);
void lpfc_ramp_up_queue_handler(struct lpfc_hba *);
#define ScsiResult(host_code, scsi_code) (((host_code) << 16) | scsi_code) #define ScsiResult(host_code, scsi_code) (((host_code) << 16) | scsi_code)
#define HBA_EVENT_RSCN 5
#define HBA_EVENT_LINK_UP 2
#define HBA_EVENT_LINK_DOWN 3
This diff is collapsed.
...@@ -36,13 +36,14 @@ enum lpfc_work_type { ...@@ -36,13 +36,14 @@ enum lpfc_work_type {
LPFC_EVT_WARM_START, LPFC_EVT_WARM_START,
LPFC_EVT_KILL, LPFC_EVT_KILL,
LPFC_EVT_ELS_RETRY, LPFC_EVT_ELS_RETRY,
LPFC_EVT_DEV_LOSS,
}; };
/* structure used to queue event to the discovery tasklet */ /* structure used to queue event to the discovery tasklet */
struct lpfc_work_evt { struct lpfc_work_evt {
struct list_head evt_listp; struct list_head evt_listp;
void * evt_arg1; void *evt_arg1;
void * evt_arg2; void *evt_arg2;
enum lpfc_work_type evt; enum lpfc_work_type evt;
}; };
...@@ -73,10 +74,12 @@ struct lpfc_nodelist { ...@@ -73,10 +74,12 @@ struct lpfc_nodelist {
#define NLP_FCP_2_DEVICE 0x10 /* FCP-2 device */ #define NLP_FCP_2_DEVICE 0x10 /* FCP-2 device */
struct timer_list nlp_delayfunc; /* Used for delayed ELS cmds */ struct timer_list nlp_delayfunc; /* Used for delayed ELS cmds */
struct timer_list nlp_initiator_tmr; /* Used with dev_loss */
struct fc_rport *rport; /* Corresponding FC transport struct fc_rport *rport; /* Corresponding FC transport
port structure */ port structure */
struct lpfc_vport *vport; struct lpfc_vport *vport;
struct lpfc_work_evt els_retry_evt; struct lpfc_work_evt els_retry_evt;
struct lpfc_work_evt dev_loss_evt;
unsigned long last_ramp_up_time; /* jiffy of last ramp up */ unsigned long last_ramp_up_time; /* jiffy of last ramp up */
unsigned long last_q_full_time; /* jiffy of last queue full */ unsigned long last_q_full_time; /* jiffy of last queue full */
struct kref kref; struct kref kref;
...@@ -99,6 +102,7 @@ struct lpfc_nodelist { ...@@ -99,6 +102,7 @@ struct lpfc_nodelist {
#define NLP_NPR_ADISC 0x2000000 /* Issue ADISC when dq'ed from #define NLP_NPR_ADISC 0x2000000 /* Issue ADISC when dq'ed from
NPR list */ NPR list */
#define NLP_NODEV_REMOVE 0x8000000 /* Defer removal till discovery ends */ #define NLP_NODEV_REMOVE 0x8000000 /* Defer removal till discovery ends */
#define NLP_TARGET_REMOVE 0x10000000 /* Target remove in process */
/* There are 4 different double linked lists nodelist entries can reside on. /* There are 4 different double linked lists nodelist entries can reside on.
* The Port Login (PLOGI) list and Address Discovery (ADISC) list are used * The Port Login (PLOGI) list and Address Discovery (ADISC) list are used
......
This diff is collapsed.
This diff is collapsed.
...@@ -64,6 +64,7 @@ ...@@ -64,6 +64,7 @@
#define SLI3_IOCB_CMD_SIZE 128 #define SLI3_IOCB_CMD_SIZE 128
#define SLI3_IOCB_RSP_SIZE 64 #define SLI3_IOCB_RSP_SIZE 64
/* Common Transport structures and definitions */ /* Common Transport structures and definitions */
union CtRevisionId { union CtRevisionId {
...@@ -84,6 +85,9 @@ union CtCommandResponse { ...@@ -84,6 +85,9 @@ union CtCommandResponse {
uint32_t word; uint32_t word;
}; };
#define FC4_FEATURE_INIT 0x2
#define FC4_FEATURE_TARGET 0x1
struct lpfc_sli_ct_request { struct lpfc_sli_ct_request {
/* Structure is in Big Endian format */ /* Structure is in Big Endian format */
union CtRevisionId RevisionId; union CtRevisionId RevisionId;
...@@ -126,20 +130,6 @@ struct lpfc_sli_ct_request { ...@@ -126,20 +130,6 @@ struct lpfc_sli_ct_request {
uint32_t rsvd[7]; uint32_t rsvd[7];
} rft; } rft;
struct rff {
uint32_t PortId;
uint8_t reserved[2];
#ifdef __BIG_ENDIAN_BITFIELD
uint8_t feature_res:6;
uint8_t feature_init:1;
uint8_t feature_tgt:1;
#else /* __LITTLE_ENDIAN_BITFIELD */
uint8_t feature_tgt:1;
uint8_t feature_init:1;
uint8_t feature_res:6;
#endif
uint8_t type_code; /* type=8 for FCP */
} rff;
struct rnn { struct rnn {
uint32_t PortId; /* For RNN_ID requests */ uint32_t PortId; /* For RNN_ID requests */
uint8_t wwnn[8]; uint8_t wwnn[8];
...@@ -149,15 +139,42 @@ struct lpfc_sli_ct_request { ...@@ -149,15 +139,42 @@ struct lpfc_sli_ct_request {
uint8_t len; uint8_t len;
uint8_t symbname[255]; uint8_t symbname[255];
} rsnn; } rsnn;
struct rspn { /* For RSPN_ID requests */
uint32_t PortId;
uint8_t len;
uint8_t symbname[255];
} rspn;
struct gff {
uint32_t PortId;
} gff;
struct gff_acc {
uint8_t fbits[128];
} gff_acc;
#define FCP_TYPE_FEATURE_OFFSET 4
struct rff {
uint32_t PortId;
uint8_t reserved[2];
uint8_t fbits;
uint8_t type_code; /* type=8 for FCP */
} rff;
} un; } un;
}; };
#define SLI_CT_REVISION 1 #define SLI_CT_REVISION 1
#define GID_REQUEST_SZ (sizeof(struct lpfc_sli_ct_request) - 260) #define GID_REQUEST_SZ (offsetof(struct lpfc_sli_ct_request, un) + \
#define RFT_REQUEST_SZ (sizeof(struct lpfc_sli_ct_request) - 228) sizeof(struct gid))
#define RFF_REQUEST_SZ (sizeof(struct lpfc_sli_ct_request) - 235) #define GFF_REQUEST_SZ (offsetof(struct lpfc_sli_ct_request, un) + \
#define RNN_REQUEST_SZ (sizeof(struct lpfc_sli_ct_request) - 252) sizeof(struct gff))
#define RSNN_REQUEST_SZ (sizeof(struct lpfc_sli_ct_request)) #define RFT_REQUEST_SZ (offsetof(struct lpfc_sli_ct_request, un) + \
sizeof(struct rft))
#define RFF_REQUEST_SZ (offsetof(struct lpfc_sli_ct_request, un) + \
sizeof(struct rff))
#define RNN_REQUEST_SZ (offsetof(struct lpfc_sli_ct_request, un) + \
sizeof(struct rnn))
#define RSNN_REQUEST_SZ (offsetof(struct lpfc_sli_ct_request, un) + \
sizeof(struct rsnn))
#define RSPN_REQUEST_SZ (offsetof(struct lpfc_sli_ct_request, un) + \
sizeof(struct rspn))
/* /*
* FsType Definitions * FsType Definitions
...@@ -232,6 +249,7 @@ struct lpfc_sli_ct_request { ...@@ -232,6 +249,7 @@ struct lpfc_sli_ct_request {
#define SLI_CTNS_GFT_ID 0x0117 #define SLI_CTNS_GFT_ID 0x0117
#define SLI_CTNS_GSPN_ID 0x0118 #define SLI_CTNS_GSPN_ID 0x0118
#define SLI_CTNS_GPT_ID 0x011A #define SLI_CTNS_GPT_ID 0x011A
#define SLI_CTNS_GFF_ID 0x011F
#define SLI_CTNS_GID_PN 0x0121 #define SLI_CTNS_GID_PN 0x0121
#define SLI_CTNS_GID_NN 0x0131 #define SLI_CTNS_GID_NN 0x0131
#define SLI_CTNS_GIP_NN 0x0135 #define SLI_CTNS_GIP_NN 0x0135
...@@ -245,9 +263,9 @@ struct lpfc_sli_ct_request { ...@@ -245,9 +263,9 @@ struct lpfc_sli_ct_request {
#define SLI_CTNS_RNN_ID 0x0213 #define SLI_CTNS_RNN_ID 0x0213
#define SLI_CTNS_RCS_ID 0x0214 #define SLI_CTNS_RCS_ID 0x0214
#define SLI_CTNS_RFT_ID 0x0217 #define SLI_CTNS_RFT_ID 0x0217
#define SLI_CTNS_RFF_ID 0x021F
#define SLI_CTNS_RSPN_ID 0x0218 #define SLI_CTNS_RSPN_ID 0x0218
#define SLI_CTNS_RPT_ID 0x021A #define SLI_CTNS_RPT_ID 0x021A
#define SLI_CTNS_RFF_ID 0x021F
#define SLI_CTNS_RIP_NN 0x0235 #define SLI_CTNS_RIP_NN 0x0235
#define SLI_CTNS_RIPA_NN 0x0236 #define SLI_CTNS_RIPA_NN 0x0236
#define SLI_CTNS_RSNN_NN 0x0239 #define SLI_CTNS_RSNN_NN 0x0239
...@@ -316,8 +334,9 @@ struct csp { ...@@ -316,8 +334,9 @@ struct csp {
uint8_t bbCreditlsb; /* FC Word 0, byte 3 */ uint8_t bbCreditlsb; /* FC Word 0, byte 3 */
#ifdef __BIG_ENDIAN_BITFIELD #ifdef __BIG_ENDIAN_BITFIELD
uint16_t increasingOffset:1; /* FC Word 1, bit 31 */ uint16_t request_multiple_Nport:1; /* FC Word 1, bit 31 */
uint16_t response_multiple_Nport:1; /* FC Word 1, bit 29 */ uint16_t randomOffset:1; /* FC Word 1, bit 30 */
uint16_t response_multiple_NPort:1; /* FC Word 1, bit 29 */
uint16_t fPort:1; /* FC Word 1, bit 28 */ uint16_t fPort:1; /* FC Word 1, bit 28 */
uint16_t altBbCredit:1; /* FC Word 1, bit 27 */ uint16_t altBbCredit:1; /* FC Word 1, bit 27 */
uint16_t edtovResolution:1; /* FC Word 1, bit 26 */ uint16_t edtovResolution:1; /* FC Word 1, bit 26 */
...@@ -336,9 +355,9 @@ struct csp { ...@@ -336,9 +355,9 @@ struct csp {
uint16_t edtovResolution:1; /* FC Word 1, bit 26 */ uint16_t edtovResolution:1; /* FC Word 1, bit 26 */
uint16_t altBbCredit:1; /* FC Word 1, bit 27 */ uint16_t altBbCredit:1; /* FC Word 1, bit 27 */
uint16_t fPort:1; /* FC Word 1, bit 28 */ uint16_t fPort:1; /* FC Word 1, bit 28 */
uint16_t word1Reserved2:1; /* FC Word 1, bit 29 */ uint16_t response_multiple_NPort:1; /* FC Word 1, bit 29 */
uint16_t randomOffset:1; /* FC Word 1, bit 30 */ uint16_t randomOffset:1; /* FC Word 1, bit 30 */
uint16_t increasingOffset:1; /* FC Word 1, bit 31 */ uint16_t request_multiple_Nport:1; /* FC Word 1, bit 31 */
uint16_t payloadlength:1; /* FC Word 1, bit 16 */ uint16_t payloadlength:1; /* FC Word 1, bit 16 */
uint16_t contIncSeqCnt:1; /* FC Word 1, bit 17 */ uint16_t contIncSeqCnt:1; /* FC Word 1, bit 17 */
...@@ -1268,6 +1287,10 @@ typedef struct { /* FireFly BIU registers */ ...@@ -1268,6 +1287,10 @@ typedef struct { /* FireFly BIU registers */
#define MBX_READ_RPI64 0x8F #define MBX_READ_RPI64 0x8F
#define MBX_REG_LOGIN64 0x93 #define MBX_REG_LOGIN64 0x93
#define MBX_READ_LA64 0x95 #define MBX_READ_LA64 0x95
#define MBX_REG_VPI 0x96
#define MBX_UNREG_VPI 0x97
#define MBX_REG_VNPID 0x96
#define MBX_UNREG_VNPID 0x97
#define MBX_FLASH_WR_ULA 0x98 #define MBX_FLASH_WR_ULA 0x98
#define MBX_SET_DEBUG 0x99 #define MBX_SET_DEBUG 0x99
...@@ -2086,6 +2109,45 @@ typedef struct { ...@@ -2086,6 +2109,45 @@ typedef struct {
#endif #endif
} UNREG_LOGIN_VAR; } UNREG_LOGIN_VAR;
/* Structure for MB Command REG_VPI (0x96) */
typedef struct {
#ifdef __BIG_ENDIAN_BITFIELD
uint32_t rsvd1;
uint32_t rsvd2:8;
uint32_t sid:24;
uint32_t rsvd3;
uint32_t rsvd4;
uint32_t rsvd5;
uint16_t rsvd6;
uint16_t vpi;
#else /* __LITTLE_ENDIAN */
uint32_t rsvd1;
uint32_t sid:24;
uint32_t rsvd2:8;
uint32_t rsvd3;
uint32_t rsvd4;
uint32_t rsvd5;
uint16_t vpi;
uint16_t rsvd6;
#endif
} REG_VPI_VAR;
/* Structure for MB Command UNREG_VPI (0x97) */
typedef struct {
uint32_t rsvd1;
uint32_t rsvd2;
uint32_t rsvd3;
uint32_t rsvd4;
uint32_t rsvd5;
#ifdef __BIG_ENDIAN_BITFIELD
uint16_t rsvd6;
uint16_t vpi;
#else /* __LITTLE_ENDIAN */
uint16_t vpi;
uint16_t rsvd6;
#endif
} UNREG_VPI_VAR;
/* Structure for MB Command UNREG_D_ID (0x23) */ /* Structure for MB Command UNREG_D_ID (0x23) */
typedef struct { typedef struct {
...@@ -2575,6 +2637,8 @@ typedef union { ...@@ -2575,6 +2637,8 @@ typedef union {
*/ */
struct config_hbq_var varCfgHbq;/* cmd = 0x7c (CONFIG_HBQ) */ struct config_hbq_var varCfgHbq;/* cmd = 0x7c (CONFIG_HBQ) */
CONFIG_PORT_VAR varCfgPort; /* cmd = 0x88 (CONFIG_PORT) */ CONFIG_PORT_VAR varCfgPort; /* cmd = 0x88 (CONFIG_PORT) */
REG_VPI_VAR varRegVpi; /* cmd = 0x96 (REG_VPI) */
UNREG_VPI_VAR varUnregVpi; /* cmd = 0x97 (UNREG_VPI) */
} MAILVARIANTS; } MAILVARIANTS;
/* /*
...@@ -2614,7 +2678,6 @@ typedef union { ...@@ -2614,7 +2678,6 @@ typedef union {
struct sli3_pgp s3_pgp; struct sli3_pgp s3_pgp;
} SLI_VAR; } SLI_VAR;
typedef struct { typedef struct {
#ifdef __BIG_ENDIAN_BITFIELD #ifdef __BIG_ENDIAN_BITFIELD
uint16_t mbxStatus; uint16_t mbxStatus;
...@@ -2935,6 +2998,8 @@ struct rcv_sli3 { ...@@ -2935,6 +2998,8 @@ struct rcv_sli3 {
struct ulp_bde64 bde2; struct ulp_bde64 bde2;
}; };
typedef struct _IOCB { /* IOCB structure */ typedef struct _IOCB { /* IOCB structure */
union { union {
GENERIC_RSP grsp; /* Generic response */ GENERIC_RSP grsp; /* Generic response */
...@@ -3011,6 +3076,7 @@ typedef struct _IOCB { /* IOCB structure */ ...@@ -3011,6 +3076,7 @@ typedef struct _IOCB { /* IOCB structure */
uint32_t ulpXS:1; uint32_t ulpXS:1;
uint32_t ulpTimeout:8; uint32_t ulpTimeout:8;
#endif #endif
union { union {
struct rcv_sli3 rcvsli3; /* words 8 - 15 */ struct rcv_sli3 rcvsli3; /* words 8 - 15 */
uint32_t sli3Words[24]; /* 96 extra bytes for SLI-3 */ uint32_t sli3Words[24]; /* 96 extra bytes for SLI-3 */
...@@ -3024,6 +3090,7 @@ typedef struct _IOCB { /* IOCB structure */ ...@@ -3024,6 +3090,7 @@ typedef struct _IOCB { /* IOCB structure */
#define PARM_UNUSED 0 /* PU field (Word 4) not used */ #define PARM_UNUSED 0 /* PU field (Word 4) not used */
#define PARM_REL_OFF 1 /* PU field (Word 4) = R. O. */ #define PARM_REL_OFF 1 /* PU field (Word 4) = R. O. */
#define PARM_READ_CHECK 2 /* PU field (Word 4) = Data Transfer Length */ #define PARM_READ_CHECK 2 /* PU field (Word 4) = Data Transfer Length */
#define PARM_NPIV_DID 3
#define CLASS1 0 /* Class 1 */ #define CLASS1 0 /* Class 1 */
#define CLASS2 1 /* Class 2 */ #define CLASS2 1 /* Class 2 */
#define CLASS3 2 /* Class 3 */ #define CLASS3 2 /* Class 3 */
...@@ -3044,7 +3111,7 @@ typedef struct _IOCB { /* IOCB structure */ ...@@ -3044,7 +3111,7 @@ typedef struct _IOCB { /* IOCB structure */
#define IOSTAT_RSVD2 0xC #define IOSTAT_RSVD2 0xC
#define IOSTAT_RSVD3 0xD #define IOSTAT_RSVD3 0xD
#define IOSTAT_RSVD4 0xE #define IOSTAT_RSVD4 0xE
#define IOSTAT_RSVD5 0xF #define IOSTAT_NEED_BUFFER 0xF
#define IOSTAT_DRIVER_REJECT 0x10 /* ulpStatus - Driver defined */ #define IOSTAT_DRIVER_REJECT 0x10 /* ulpStatus - Driver defined */
#define IOSTAT_DEFAULT 0xF /* Same as rsvd5 for now */ #define IOSTAT_DEFAULT 0xF /* Same as rsvd5 for now */
#define IOSTAT_CNT 0x11 #define IOSTAT_CNT 0x11
......
This diff is collapsed.
...@@ -30,6 +30,7 @@ ...@@ -30,6 +30,7 @@
#define LOG_SLI 0x800 /* SLI events */ #define LOG_SLI 0x800 /* SLI events */
#define LOG_FCP_ERROR 0x1000 /* log errors, not underruns */ #define LOG_FCP_ERROR 0x1000 /* log errors, not underruns */
#define LOG_LIBDFC 0x2000 /* Libdfc events */ #define LOG_LIBDFC 0x2000 /* Libdfc events */
#define LOG_VPORT 0x4000 /* NPIV events */
#define LOG_ALL_MSG 0xffff /* LOG all messages */ #define LOG_ALL_MSG 0xffff /* LOG all messages */
#define lpfc_printf_log(phba, level, mask, fmt, arg...) \ #define lpfc_printf_log(phba, level, mask, fmt, arg...) \
......
...@@ -106,7 +106,7 @@ lpfc_read_la(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb, struct lpfc_dmabuf *mp) ...@@ -106,7 +106,7 @@ lpfc_read_la(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb, struct lpfc_dmabuf *mp)
*/ */
pmb->context1 = (uint8_t *) mp; pmb->context1 = (uint8_t *) mp;
mb->mbxOwner = OWN_HOST; mb->mbxOwner = OWN_HOST;
return 0; return (0);
} }
/**********************************************/ /**********************************************/
...@@ -209,7 +209,7 @@ lpfc_init_link(struct lpfc_hba * phba, ...@@ -209,7 +209,7 @@ lpfc_init_link(struct lpfc_hba * phba,
*/ */
vpd = &phba->vpd; vpd = &phba->vpd;
if (vpd->rev.feaLevelHigh >= 0x02){ if (vpd->rev.feaLevelHigh >= 0x02){
switch (linkspeed){ switch(linkspeed){
case LINK_SPEED_1G: case LINK_SPEED_1G:
case LINK_SPEED_2G: case LINK_SPEED_2G:
case LINK_SPEED_4G: case LINK_SPEED_4G:
...@@ -232,7 +232,6 @@ lpfc_init_link(struct lpfc_hba * phba, ...@@ -232,7 +232,6 @@ lpfc_init_link(struct lpfc_hba * phba,
mb->mbxCommand = (volatile uint8_t)MBX_INIT_LINK; mb->mbxCommand = (volatile uint8_t)MBX_INIT_LINK;
mb->mbxOwner = OWN_HOST; mb->mbxOwner = OWN_HOST;
mb->un.varInitLnk.fabric_AL_PA = phba->fc_pref_ALPA; mb->un.varInitLnk.fabric_AL_PA = phba->fc_pref_ALPA;
mb->un.varInitLnk.link_flags |= FLAGS_UNREG_LOGIN_ALL;
return; return;
} }
...@@ -241,7 +240,7 @@ lpfc_init_link(struct lpfc_hba * phba, ...@@ -241,7 +240,7 @@ lpfc_init_link(struct lpfc_hba * phba,
/* mailbox command */ /* mailbox command */
/**********************************************/ /**********************************************/
int int
lpfc_read_sparam(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb) lpfc_read_sparam(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb, int vpi)
{ {
struct lpfc_dmabuf *mp; struct lpfc_dmabuf *mp;
MAILBOX_t *mb; MAILBOX_t *mb;
...@@ -265,18 +264,19 @@ lpfc_read_sparam(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb) ...@@ -265,18 +264,19 @@ lpfc_read_sparam(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb)
LOG_MBOX, LOG_MBOX,
"%d:0301 READ_SPARAM: no buffers\n", "%d:0301 READ_SPARAM: no buffers\n",
phba->brd_no); phba->brd_no);
return 1; return (1);
} }
INIT_LIST_HEAD(&mp->list); INIT_LIST_HEAD(&mp->list);
mb->mbxCommand = MBX_READ_SPARM64; mb->mbxCommand = MBX_READ_SPARM64;
mb->un.varRdSparm.un.sp64.tus.f.bdeSize = sizeof (struct serv_parm); mb->un.varRdSparm.un.sp64.tus.f.bdeSize = sizeof (struct serv_parm);
mb->un.varRdSparm.un.sp64.addrHigh = putPaddrHigh(mp->phys); mb->un.varRdSparm.un.sp64.addrHigh = putPaddrHigh(mp->phys);
mb->un.varRdSparm.un.sp64.addrLow = putPaddrLow(mp->phys); mb->un.varRdSparm.un.sp64.addrLow = putPaddrLow(mp->phys);
mb->un.varRdSparm.vpi = vpi;
/* save address for completion */ /* save address for completion */
pmb->context1 = mp; pmb->context1 = mp;
return 0; return (0);
} }
/********************************************/ /********************************************/
...@@ -284,7 +284,8 @@ lpfc_read_sparam(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb) ...@@ -284,7 +284,8 @@ lpfc_read_sparam(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb)
/* mailbox command */ /* mailbox command */
/********************************************/ /********************************************/
void void
lpfc_unreg_did(struct lpfc_hba *phba, uint32_t did, LPFC_MBOXQ_t *pmb) lpfc_unreg_did(struct lpfc_hba * phba, uint16_t vpi, uint32_t did,
LPFC_MBOXQ_t * pmb)
{ {
MAILBOX_t *mb; MAILBOX_t *mb;
...@@ -292,6 +293,7 @@ lpfc_unreg_did(struct lpfc_hba *phba, uint32_t did, LPFC_MBOXQ_t *pmb) ...@@ -292,6 +293,7 @@ lpfc_unreg_did(struct lpfc_hba *phba, uint32_t did, LPFC_MBOXQ_t *pmb)
memset(pmb, 0, sizeof (LPFC_MBOXQ_t)); memset(pmb, 0, sizeof (LPFC_MBOXQ_t));
mb->un.varUnregDID.did = did; mb->un.varUnregDID.did = did;
mb->un.varUnregDID.vpi = vpi;
mb->mbxCommand = MBX_UNREG_D_ID; mb->mbxCommand = MBX_UNREG_D_ID;
mb->mbxOwner = OWN_HOST; mb->mbxOwner = OWN_HOST;
...@@ -337,8 +339,8 @@ lpfc_read_lnk_stat(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb) ...@@ -337,8 +339,8 @@ lpfc_read_lnk_stat(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb)
/* mailbox command */ /* mailbox command */
/********************************************/ /********************************************/
int int
lpfc_reg_login(struct lpfc_hba *phba, uint32_t did, uint8_t *param, lpfc_reg_login(struct lpfc_hba *phba, uint16_t vpi, uint32_t did,
LPFC_MBOXQ_t *pmb, uint32_t flag) uint8_t *param, LPFC_MBOXQ_t *pmb, uint32_t flag)
{ {
MAILBOX_t *mb = &pmb->mb; MAILBOX_t *mb = &pmb->mb;
uint8_t *sparam; uint8_t *sparam;
...@@ -347,6 +349,7 @@ lpfc_reg_login(struct lpfc_hba *phba, uint32_t did, uint8_t *param, ...@@ -347,6 +349,7 @@ lpfc_reg_login(struct lpfc_hba *phba, uint32_t did, uint8_t *param,
memset(pmb, 0, sizeof (LPFC_MBOXQ_t)); memset(pmb, 0, sizeof (LPFC_MBOXQ_t));
mb->un.varRegLogin.rpi = 0; mb->un.varRegLogin.rpi = 0;
mb->un.varRegLogin.vpi = vpi;
mb->un.varRegLogin.did = did; mb->un.varRegLogin.did = did;
mb->un.varWords[30] = flag; /* Set flag to issue action on cmpl */ mb->un.varWords[30] = flag; /* Set flag to issue action on cmpl */
...@@ -358,13 +361,11 @@ lpfc_reg_login(struct lpfc_hba *phba, uint32_t did, uint8_t *param, ...@@ -358,13 +361,11 @@ lpfc_reg_login(struct lpfc_hba *phba, uint32_t did, uint8_t *param,
kfree(mp); kfree(mp);
mb->mbxCommand = MBX_REG_LOGIN64; mb->mbxCommand = MBX_REG_LOGIN64;
/* REG_LOGIN: no buffers */ /* REG_LOGIN: no buffers */
lpfc_printf_log(phba, lpfc_printf_log(phba, KERN_WARNING, LOG_MBOX,
KERN_WARNING, "%d (%d):0302 REG_LOGIN: no buffers, DID x%x, "
LOG_MBOX, "flag x%x\n",
"%d:0302 REG_LOGIN: no buffers Data x%x x%x\n", phba->brd_no, vpi, did, flag);
phba->brd_no, return (1);
(uint32_t) did, (uint32_t) flag);
return 1;
} }
INIT_LIST_HEAD(&mp->list); INIT_LIST_HEAD(&mp->list);
sparam = mp->virt; sparam = mp->virt;
...@@ -380,7 +381,7 @@ lpfc_reg_login(struct lpfc_hba *phba, uint32_t did, uint8_t *param, ...@@ -380,7 +381,7 @@ lpfc_reg_login(struct lpfc_hba *phba, uint32_t did, uint8_t *param,
mb->un.varRegLogin.un.sp64.addrHigh = putPaddrHigh(mp->phys); mb->un.varRegLogin.un.sp64.addrHigh = putPaddrHigh(mp->phys);
mb->un.varRegLogin.un.sp64.addrLow = putPaddrLow(mp->phys); mb->un.varRegLogin.un.sp64.addrLow = putPaddrLow(mp->phys);
return 0; return (0);
} }
/**********************************************/ /**********************************************/
...@@ -388,7 +389,8 @@ lpfc_reg_login(struct lpfc_hba *phba, uint32_t did, uint8_t *param, ...@@ -388,7 +389,8 @@ lpfc_reg_login(struct lpfc_hba *phba, uint32_t did, uint8_t *param,
/* mailbox command */ /* mailbox command */
/**********************************************/ /**********************************************/
void void
lpfc_unreg_login(struct lpfc_hba *phba, uint32_t rpi, LPFC_MBOXQ_t * pmb) lpfc_unreg_login(struct lpfc_hba *phba, uint16_t vpi, uint32_t rpi,
LPFC_MBOXQ_t * pmb)
{ {
MAILBOX_t *mb; MAILBOX_t *mb;
...@@ -397,12 +399,52 @@ lpfc_unreg_login(struct lpfc_hba *phba, uint32_t rpi, LPFC_MBOXQ_t * pmb) ...@@ -397,12 +399,52 @@ lpfc_unreg_login(struct lpfc_hba *phba, uint32_t rpi, LPFC_MBOXQ_t * pmb)
mb->un.varUnregLogin.rpi = (uint16_t) rpi; mb->un.varUnregLogin.rpi = (uint16_t) rpi;
mb->un.varUnregLogin.rsvd1 = 0; mb->un.varUnregLogin.rsvd1 = 0;
mb->un.varUnregLogin.vpi = vpi;
mb->mbxCommand = MBX_UNREG_LOGIN; mb->mbxCommand = MBX_UNREG_LOGIN;
mb->mbxOwner = OWN_HOST; mb->mbxOwner = OWN_HOST;
return; return;
} }
/**************************************************/
/* lpfc_reg_vpi Issue a REG_VPI */
/* mailbox command */
/**************************************************/
void
lpfc_reg_vpi(struct lpfc_hba *phba, uint16_t vpi, uint32_t sid,
LPFC_MBOXQ_t *pmb)
{
MAILBOX_t *mb = &pmb->mb;
memset(pmb, 0, sizeof (LPFC_MBOXQ_t));
mb->un.varRegVpi.vpi = vpi;
mb->un.varRegVpi.sid = sid;
mb->mbxCommand = MBX_REG_VPI;
mb->mbxOwner = OWN_HOST;
return;
}
/**************************************************/
/* lpfc_unreg_vpi Issue a UNREG_VNPI */
/* mailbox command */
/**************************************************/
void
lpfc_unreg_vpi(struct lpfc_hba *phba, uint16_t vpi, LPFC_MBOXQ_t *pmb)
{
MAILBOX_t *mb = &pmb->mb;
memset(pmb, 0, sizeof (LPFC_MBOXQ_t));
mb->un.varUnregVpi.vpi = vpi;
mb->mbxCommand = MBX_UNREG_VPI;
mb->mbxOwner = OWN_HOST;
return;
}
static void static void
lpfc_config_pcb_setup(struct lpfc_hba * phba) lpfc_config_pcb_setup(struct lpfc_hba * phba)
{ {
...@@ -437,18 +479,18 @@ lpfc_config_pcb_setup(struct lpfc_hba * phba) ...@@ -437,18 +479,18 @@ lpfc_config_pcb_setup(struct lpfc_hba * phba)
continue; continue;
} }
/* Command ring setup for ring */ /* Command ring setup for ring */
pring->cmdringaddr = (void *)&phba->slim2p->IOCBs[iocbCnt]; pring->cmdringaddr = (void *) &phba->slim2p->IOCBs[iocbCnt];
pcbp->rdsc[i].cmdEntries = pring->numCiocb; pcbp->rdsc[i].cmdEntries = pring->numCiocb;
offset = (uint8_t *)&phba->slim2p->IOCBs[iocbCnt] - offset = (uint8_t *) &phba->slim2p->IOCBs[iocbCnt] -
(uint8_t *)phba->slim2p; (uint8_t *) phba->slim2p;
pdma_addr = phba->slim2p_mapping + offset; pdma_addr = phba->slim2p_mapping + offset;
pcbp->rdsc[i].cmdAddrHigh = putPaddrHigh(pdma_addr); pcbp->rdsc[i].cmdAddrHigh = putPaddrHigh(pdma_addr);
pcbp->rdsc[i].cmdAddrLow = putPaddrLow(pdma_addr); pcbp->rdsc[i].cmdAddrLow = putPaddrLow(pdma_addr);
iocbCnt += pring->numCiocb; iocbCnt += pring->numCiocb;
/* Response ring setup for ring */ /* Response ring setup for ring */
pring->rspringaddr = (void *)&phba->slim2p->IOCBs[iocbCnt]; pring->rspringaddr = (void *) &phba->slim2p->IOCBs[iocbCnt];
pcbp->rdsc[i].rspEntries = pring->numRiocb; pcbp->rdsc[i].rspEntries = pring->numRiocb;
offset = (uint8_t *)&phba->slim2p->IOCBs[iocbCnt] - offset = (uint8_t *)&phba->slim2p->IOCBs[iocbCnt] -
...@@ -563,6 +605,8 @@ lpfc_config_hbq(struct lpfc_hba *phba, struct lpfc_hbq_init *hbq_desc, ...@@ -563,6 +605,8 @@ lpfc_config_hbq(struct lpfc_hba *phba, struct lpfc_hbq_init *hbq_desc,
return; return;
} }
void void
lpfc_config_ring(struct lpfc_hba * phba, int ring, LPFC_MBOXQ_t * pmb) lpfc_config_ring(struct lpfc_hba * phba, int ring, LPFC_MBOXQ_t * pmb)
{ {
...@@ -605,7 +649,7 @@ lpfc_config_ring(struct lpfc_hba * phba, int ring, LPFC_MBOXQ_t * pmb) ...@@ -605,7 +649,7 @@ lpfc_config_ring(struct lpfc_hba * phba, int ring, LPFC_MBOXQ_t * pmb)
} }
void void
lpfc_config_port(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb) lpfc_config_port(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb)
{ {
MAILBOX_t __iomem *mb_slim = (MAILBOX_t __iomem *) phba->MBslimaddr; MAILBOX_t __iomem *mb_slim = (MAILBOX_t __iomem *) phba->MBslimaddr;
MAILBOX_t *mb = &pmb->mb; MAILBOX_t *mb = &pmb->mb;
...@@ -629,11 +673,19 @@ lpfc_config_port(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb) ...@@ -629,11 +673,19 @@ lpfc_config_port(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb)
/* If HBA supports SLI=3 ask for it */ /* If HBA supports SLI=3 ask for it */
mb->un.varCfgPort.sli_mode = phba->sli_rev; if (phba->sli_rev == 3 && phba->vpd.sli3Feat.cerbm) {
if (phba->sli_rev == 3) {
mb->un.varCfgPort.cerbm = 1; /* Request HBQs */ mb->un.varCfgPort.cerbm = 1; /* Request HBQs */
mb->un.varCfgPort.max_hbq = 1; /* Requesting 2 HBQs */ mb->un.varCfgPort.max_hbq = 1; /* Requesting 2 HBQs */
} if (phba->max_vpi && lpfc_npiv_enable &&
phba->vpd.sli3Feat.cmv) {
mb->un.varCfgPort.max_vpi = phba->max_vpi;
mb->un.varCfgPort.cmv = 1;
phba->sli3_options |= LPFC_SLI3_NPIV_ENABLED;
} else
mb->un.varCfgPort.max_vpi = phba->max_vpi = 0;
} else
phba->sli_rev = 2;
mb->un.varCfgPort.sli_mode = phba->sli_rev;
/* Now setup pcb */ /* Now setup pcb */
phba->slim2p->pcb.type = TYPE_NATIVE_SLI2; phba->slim2p->pcb.type = TYPE_NATIVE_SLI2;
...@@ -748,7 +800,7 @@ lpfc_config_port(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb) ...@@ -748,7 +800,7 @@ lpfc_config_port(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb)
/* Swap PCB if needed */ /* Swap PCB if needed */
lpfc_sli_pcimem_bcopy(&phba->slim2p->pcb, &phba->slim2p->pcb, lpfc_sli_pcimem_bcopy(&phba->slim2p->pcb, &phba->slim2p->pcb,
sizeof (PCB_t)); sizeof(PCB_t));
} }
void void
...@@ -783,13 +835,22 @@ lpfc_mbox_get(struct lpfc_hba * phba) ...@@ -783,13 +835,22 @@ lpfc_mbox_get(struct lpfc_hba * phba)
struct lpfc_sli *psli = &phba->sli; struct lpfc_sli *psli = &phba->sli;
list_remove_head((&psli->mboxq), mbq, LPFC_MBOXQ_t, list); list_remove_head((&psli->mboxq), mbq, LPFC_MBOXQ_t, list);
if (mbq) { if (mbq)
psli->mboxq_cnt--; psli->mboxq_cnt--;
}
return mbq; return mbq;
} }
void
lpfc_mbox_cmpl_put(struct lpfc_hba * phba, LPFC_MBOXQ_t * mbq)
{
/* This function expects to be called from interupt context */
spin_lock(&phba->hbalock);
list_add_tail(&mbq->list, &phba->sli.mboxq_cmpl);
spin_unlock(&phba->hbalock);
return;
}
int int
lpfc_mbox_tmo_val(struct lpfc_hba *phba, int cmd) lpfc_mbox_tmo_val(struct lpfc_hba *phba, int cmd)
{ {
......
...@@ -44,6 +44,7 @@ int ...@@ -44,6 +44,7 @@ int
lpfc_mem_alloc(struct lpfc_hba * phba) lpfc_mem_alloc(struct lpfc_hba * phba)
{ {
struct lpfc_dma_pool *pool = &phba->lpfc_mbuf_safety_pool; struct lpfc_dma_pool *pool = &phba->lpfc_mbuf_safety_pool;
int longs;
int i; int i;
phba->lpfc_scsi_dma_buf_pool = pci_pool_create("lpfc_scsi_dma_buf_pool", phba->lpfc_scsi_dma_buf_pool = pci_pool_create("lpfc_scsi_dma_buf_pool",
...@@ -87,8 +88,15 @@ lpfc_mem_alloc(struct lpfc_hba * phba) ...@@ -87,8 +88,15 @@ lpfc_mem_alloc(struct lpfc_hba * phba)
if (!phba->lpfc_hbq_pool) if (!phba->lpfc_hbq_pool)
goto fail_free_nlp_mem_pool; goto fail_free_nlp_mem_pool;
longs = (phba->max_vpi + BITS_PER_LONG - 1) / BITS_PER_LONG;
phba->vpi_bmask = kzalloc(longs * sizeof(unsigned long), GFP_KERNEL);
if (!phba->vpi_bmask)
goto fail_free_hbq_pool;
return 0; return 0;
fail_free_hbq_pool:
lpfc_sli_hbqbuf_free_all(phba);
fail_free_nlp_mem_pool: fail_free_nlp_mem_pool:
mempool_destroy(phba->nlp_mem_pool); mempool_destroy(phba->nlp_mem_pool);
phba->nlp_mem_pool = NULL; phba->nlp_mem_pool = NULL;
...@@ -119,9 +127,9 @@ lpfc_mem_free(struct lpfc_hba * phba) ...@@ -119,9 +127,9 @@ lpfc_mem_free(struct lpfc_hba * phba)
struct lpfc_dmabuf *mp; struct lpfc_dmabuf *mp;
int i; int i;
kfree(phba->vpi_bmask);
lpfc_sli_hbqbuf_free_all(phba); lpfc_sli_hbqbuf_free_all(phba);
spin_lock_irq(&phba->hbalock);
list_for_each_entry_safe(mbox, next_mbox, &psli->mboxq, list) { list_for_each_entry_safe(mbox, next_mbox, &psli->mboxq, list) {
mp = (struct lpfc_dmabuf *) (mbox->context1); mp = (struct lpfc_dmabuf *) (mbox->context1);
if (mp) { if (mp) {
...@@ -131,9 +139,17 @@ lpfc_mem_free(struct lpfc_hba * phba) ...@@ -131,9 +139,17 @@ lpfc_mem_free(struct lpfc_hba * phba)
list_del(&mbox->list); list_del(&mbox->list);
mempool_free(mbox, phba->mbox_mem_pool); mempool_free(mbox, phba->mbox_mem_pool);
} }
list_for_each_entry_safe(mbox, next_mbox, &psli->mboxq_cmpl, list) {
mp = (struct lpfc_dmabuf *) (mbox->context1);
if (mp) {
lpfc_mbuf_free(phba, mp->virt, mp->phys);
kfree(mp);
}
list_del(&mbox->list);
mempool_free(mbox, phba->mbox_mem_pool);
}
psli->sli_flag &= ~LPFC_SLI_MBOX_ACTIVE; psli->sli_flag &= ~LPFC_SLI_MBOX_ACTIVE;
spin_unlock_irq(&phba->hbalock);
if (psli->mbox_active) { if (psli->mbox_active) {
mbox = psli->mbox_active; mbox = psli->mbox_active;
mp = (struct lpfc_dmabuf *) (mbox->context1); mp = (struct lpfc_dmabuf *) (mbox->context1);
...@@ -179,7 +195,7 @@ lpfc_mbuf_alloc(struct lpfc_hba *phba, int mem_flags, dma_addr_t *handle) ...@@ -179,7 +195,7 @@ lpfc_mbuf_alloc(struct lpfc_hba *phba, int mem_flags, dma_addr_t *handle)
ret = pci_pool_alloc(phba->lpfc_mbuf_pool, GFP_KERNEL, handle); ret = pci_pool_alloc(phba->lpfc_mbuf_pool, GFP_KERNEL, handle);
spin_lock_irqsave(&phba->hbalock, iflags); spin_lock_irqsave(&phba->hbalock, iflags);
if (!ret && ( mem_flags & MEM_PRI) && pool->current_count) { if (!ret && (mem_flags & MEM_PRI) && pool->current_count) {
pool->current_count--; pool->current_count--;
ret = pool->elements[pool->current_count].virt; ret = pool->elements[pool->current_count].virt;
*handle = pool->elements[pool->current_count].phys; *handle = pool->elements[pool->current_count].phys;
...@@ -214,7 +230,6 @@ lpfc_mbuf_free(struct lpfc_hba * phba, void *virt, dma_addr_t dma) ...@@ -214,7 +230,6 @@ lpfc_mbuf_free(struct lpfc_hba * phba, void *virt, dma_addr_t dma)
return; return;
} }
void * void *
lpfc_hbq_alloc(struct lpfc_hba *phba, int mem_flags, dma_addr_t *handle) lpfc_hbq_alloc(struct lpfc_hba *phba, int mem_flags, dma_addr_t *handle)
{ {
...@@ -230,3 +245,24 @@ lpfc_hbq_free(struct lpfc_hba *phba, void *virt, dma_addr_t dma) ...@@ -230,3 +245,24 @@ lpfc_hbq_free(struct lpfc_hba *phba, void *virt, dma_addr_t dma)
return; return;
} }
void
lpfc_in_buf_free(struct lpfc_hba *phba, struct lpfc_dmabuf *mp)
{
struct hbq_dmabuf *hbq_entry;
if (phba->sli3_options & LPFC_SLI3_HBQ_ENABLED) {
hbq_entry = container_of(mp, struct hbq_dmabuf, dbuf);
if (hbq_entry->tag == -1) {
lpfc_hbq_free(phba, hbq_entry->dbuf.virt,
hbq_entry->dbuf.phys);
kfree(hbq_entry);
} else {
lpfc_sli_free_hbq(phba, hbq_entry);
}
} else {
lpfc_mbuf_free(phba, mp->virt, mp->phys);
kfree(mp);
}
return;
}
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
...@@ -44,6 +44,7 @@ struct lpfc_iocbq { ...@@ -44,6 +44,7 @@ struct lpfc_iocbq {
#define LPFC_IO_WAKE 2 /* High Priority Queue signal flag */ #define LPFC_IO_WAKE 2 /* High Priority Queue signal flag */
#define LPFC_IO_FCP 4 /* FCP command -- iocbq in scsi_buf */ #define LPFC_IO_FCP 4 /* FCP command -- iocbq in scsi_buf */
#define LPFC_DRIVER_ABORTED 8 /* driver aborted this request */ #define LPFC_DRIVER_ABORTED 8 /* driver aborted this request */
#define LPFC_IO_FABRIC 0x10 /* Iocb send using fabric scheduler */
uint8_t abort_count; uint8_t abort_count;
uint8_t rsvd2; uint8_t rsvd2;
...@@ -58,6 +59,8 @@ struct lpfc_iocbq { ...@@ -58,6 +59,8 @@ struct lpfc_iocbq {
struct lpfcMboxq *mbox; struct lpfcMboxq *mbox;
} context_un; } context_un;
void (*fabric_iocb_cmpl) (struct lpfc_hba *, struct lpfc_iocbq *,
struct lpfc_iocbq *);
void (*iocb_cmpl) (struct lpfc_hba *, struct lpfc_iocbq *, void (*iocb_cmpl) (struct lpfc_hba *, struct lpfc_iocbq *,
struct lpfc_iocbq *); struct lpfc_iocbq *);
...@@ -173,7 +176,7 @@ struct lpfc_sli_ring { ...@@ -173,7 +176,7 @@ struct lpfc_sli_ring {
/* Structure used for configuring rings to a specific profile or rctl / type */ /* Structure used for configuring rings to a specific profile or rctl / type */
struct lpfc_hbq_init { struct lpfc_hbq_init {
uint32_t rn; /* Receive buffer notification */ uint32_t rn; /* Receive buffer notification */
uint32_t entry_count; /* # of entries in HBQ */ uint32_t entry_count; /* max # of entries in HBQ */
uint32_t headerLen; /* 0 if not profile 4 or 5 */ uint32_t headerLen; /* 0 if not profile 4 or 5 */
uint32_t logEntry; /* Set to 1 if this HBQ used for LogEntry */ uint32_t logEntry; /* Set to 1 if this HBQ used for LogEntry */
uint32_t profile; /* Selection profile 0=all, 7=logentry */ uint32_t profile; /* Selection profile 0=all, 7=logentry */
...@@ -188,6 +191,11 @@ struct lpfc_hbq_init { ...@@ -188,6 +191,11 @@ struct lpfc_hbq_init {
uint32_t cmdmatch[8]; uint32_t cmdmatch[8];
uint32_t mask_count; /* number of mask entries in prt array */ uint32_t mask_count; /* number of mask entries in prt array */
struct hbq_mask hbqMasks[6]; struct hbq_mask hbqMasks[6];
/* Non-config rings fields to keep track of buffer allocations */
uint32_t buffer_count; /* number of buffers allocated */
uint32_t init_count; /* number to allocate when initialized */
uint32_t add_count; /* number to allocate when starved */
} ; } ;
#define LPFC_MAX_HBQ 16 #define LPFC_MAX_HBQ 16
...@@ -238,6 +246,7 @@ struct lpfc_sli { ...@@ -238,6 +246,7 @@ struct lpfc_sli {
uint16_t mboxq_cnt; /* current length of queue */ uint16_t mboxq_cnt; /* current length of queue */
uint16_t mboxq_max; /* max length */ uint16_t mboxq_max; /* max length */
LPFC_MBOXQ_t *mbox_active; /* active mboxq information */ LPFC_MBOXQ_t *mbox_active; /* active mboxq information */
struct list_head mboxq_cmpl;
struct timer_list mbox_tmo; /* Hold clk to timeout active mbox struct timer_list mbox_tmo; /* Hold clk to timeout active mbox
cmd */ cmd */
...@@ -250,12 +259,6 @@ struct lpfc_sli { ...@@ -250,12 +259,6 @@ struct lpfc_sli {
struct lpfc_lnk_stat lnk_stat_offsets; struct lpfc_lnk_stat lnk_stat_offsets;
}; };
/* Given a pointer to the start of the ring, and the slot number of
* the desired iocb entry, calc a pointer to that entry.
* (assume iocb entry size is 32 bytes, or 8 words)
*/
#define IOCB_ENTRY(ring,slot) ((IOCB_t *)(((char *)(ring)) + ((slot) * 32)))
#define LPFC_MBOX_TMO 30 /* Sec tmo for outstanding mbox #define LPFC_MBOX_TMO 30 /* Sec tmo for outstanding mbox
command */ command */
#define LPFC_MBOX_TMO_FLASH_CMD 300 /* Sec tmo for outstanding FLASH write #define LPFC_MBOX_TMO_FLASH_CMD 300 /* Sec tmo for outstanding FLASH write
......
...@@ -18,7 +18,7 @@ ...@@ -18,7 +18,7 @@
* included with this package. * * included with this package. *
*******************************************************************/ *******************************************************************/
#define LPFC_DRIVER_VERSION "8.1.12_sli3" #define LPFC_DRIVER_VERSION "8.2.0"
#define LPFC_DRIVER_NAME "lpfc" #define LPFC_DRIVER_NAME "lpfc"
......
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment