mirror of https://gitee.com/openkylin/linux.git
[SCSI] lpfc: NPIV: add SLI-3 interface
NPIV support is only available via new adapter interface extensions, termed SLI-3. This interface changes some of the basic behaviors such as command and response ring element sizes and data structures, as well as a change in buffer posting. Note: the new firmware extensions are found only on our mid-range and enterprise 4Gig adapters - so NPIV support is available only on these newer adapters. The latest firmware can be downloaded from the Emulex support page. Signed-off-by: James Smart <James.Smart@emulex.com> Signed-off-by: James Bottomley <James.Bottomley@SteelEye.com>
This commit is contained in:
parent
2e0fef85e0
commit
ed95768429
|
@ -63,6 +63,11 @@ struct lpfc_dma_pool {
|
|||
uint32_t current_count;
|
||||
};
|
||||
|
||||
struct hbq_dmabuf {
|
||||
struct lpfc_dmabuf dbuf;
|
||||
uint32_t tag;
|
||||
};
|
||||
|
||||
/* Priority bit. Set value to exceed low water mark in lpfc_mem. */
|
||||
#define MEM_PRI 0x100
|
||||
|
||||
|
@ -276,8 +281,25 @@ struct lpfc_vport {
|
|||
|
||||
};
|
||||
|
||||
|
||||
struct hbq_s {
|
||||
uint16_t entry_count; /* Current number of HBQ slots */
|
||||
uint32_t next_hbqPutIdx; /* Index to next HBQ slot to use */
|
||||
uint32_t hbqPutIdx; /* HBQ slot to use */
|
||||
uint32_t local_hbqGetIdx; /* Local copy of Get index from Port */
|
||||
};
|
||||
|
||||
#define MAX_HBQS 16
|
||||
|
||||
struct lpfc_hba {
|
||||
struct lpfc_sli sli;
|
||||
uint32_t sli_rev; /* SLI2 or SLI3 */
|
||||
uint32_t sli3_options; /* Mask of enabled SLI3 options */
|
||||
#define LPFC_SLI3_ENABLED 0x01
|
||||
#define LPFC_SLI3_HBQ_ENABLED 0x02
|
||||
#define LPFC_SLI3_INB_ENABLED 0x04
|
||||
uint32_t iocb_cmd_size;
|
||||
uint32_t iocb_rsp_size;
|
||||
|
||||
enum hba_state link_state;
|
||||
uint32_t link_flag; /* link state flags */
|
||||
|
@ -286,8 +308,6 @@ struct lpfc_hba {
|
|||
/* INIT_LINK mailbox command */
|
||||
#define LS_IGNORE_ERATT 0x80000 /* intr handler should ignore ERATT */
|
||||
|
||||
uint32_t pgpOffset; /* PGP offset within host memory */
|
||||
|
||||
struct lpfc_sli2_slim *slim2p;
|
||||
struct lpfc_dmabuf hbqslimp;
|
||||
|
||||
|
@ -371,6 +391,12 @@ struct lpfc_hba {
|
|||
wait_queue_head_t *work_wait;
|
||||
struct task_struct *worker_thread;
|
||||
|
||||
struct hbq_dmabuf *hbq_buffer_pool;
|
||||
uint32_t hbq_buffer_count;
|
||||
uint32_t hbq_buff_count; /* Current hbq buffers */
|
||||
uint32_t hbq_count; /* Count of configured HBQs */
|
||||
struct hbq_s hbqs[MAX_HBQS]; /* local copy of hbq indicies */
|
||||
|
||||
unsigned long pci_bar0_map; /* Physical address for PCI BAR0 */
|
||||
unsigned long pci_bar2_map; /* Physical address for PCI BAR2 */
|
||||
void __iomem *slim_memmap_p; /* Kernel memory mapped address for
|
||||
|
@ -385,6 +411,10 @@ struct lpfc_hba {
|
|||
reg */
|
||||
void __iomem *HCregaddr; /* virtual address for host ctl reg */
|
||||
|
||||
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_get; /* Address in SLIM to HBQ get ptrs */
|
||||
|
||||
int brd_no; /* FC board number */
|
||||
|
||||
char SerialNumber[32]; /* adapter Serial Number */
|
||||
|
@ -425,6 +455,7 @@ 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 lpfc_dma_pool lpfc_mbuf_safety_pool;
|
||||
|
||||
mempool_t *mbox_mem_pool;
|
||||
|
|
|
@ -138,6 +138,10 @@ void lpfc_mbox_put(struct lpfc_hba *, LPFC_MBOXQ_t *);
|
|||
LPFC_MBOXQ_t *lpfc_mbox_get(struct lpfc_hba *);
|
||||
int lpfc_mbox_tmo_val(struct lpfc_hba *, int);
|
||||
|
||||
void lpfc_config_hbq(struct lpfc_hba *, struct lpfc_hbq_init *, uint32_t ,
|
||||
LPFC_MBOXQ_t *);
|
||||
struct lpfc_hbq_entry * lpfc_sli_next_hbq_slot(struct lpfc_hba *, uint32_t);
|
||||
|
||||
int lpfc_mem_alloc(struct lpfc_hba *);
|
||||
void lpfc_mem_free(struct lpfc_hba *);
|
||||
|
||||
|
@ -172,6 +176,12 @@ int lpfc_sli_ringpostbuf_put(struct lpfc_hba *, struct lpfc_sli_ring *,
|
|||
struct lpfc_dmabuf *lpfc_sli_ringpostbuf_get(struct lpfc_hba *,
|
||||
struct lpfc_sli_ring *,
|
||||
dma_addr_t);
|
||||
int lpfc_sli_hbqbuf_fill_hbq(struct lpfc_hba *);
|
||||
void lpfc_sli_hbqbuf_free(struct lpfc_hba *, void *, dma_addr_t);
|
||||
void lpfc_sli_hbqbuf_free_all(struct lpfc_hba *);
|
||||
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_issue_abort_iotag(struct lpfc_hba *, struct lpfc_sli_ring *,
|
||||
struct lpfc_iocbq *);
|
||||
int lpfc_sli_sum_iocb(struct lpfc_hba *, struct lpfc_sli_ring *, uint16_t,
|
||||
|
@ -198,6 +208,9 @@ void lpfc_sli_abort_fcp_cmpl(struct lpfc_hba * phba,
|
|||
struct lpfc_iocbq * cmdiocb,
|
||||
struct lpfc_iocbq * rspiocb);
|
||||
|
||||
void *lpfc_hbq_alloc(struct lpfc_hba *, int, dma_addr_t *);
|
||||
void lpfc_hbq_free(struct lpfc_hba *, void *, 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);
|
||||
|
@ -213,6 +226,7 @@ void lpfc_free_sysfs_attr(struct lpfc_vport *);
|
|||
extern struct class_device_attribute *lpfc_hba_attrs[];
|
||||
extern struct scsi_host_template lpfc_template;
|
||||
extern struct fc_function_template lpfc_transport_functions;
|
||||
extern int lpfc_sli_mode;
|
||||
|
||||
void lpfc_get_hba_sym_node_name(struct lpfc_hba *phba, uint8_t *symbp);
|
||||
void lpfc_terminate_rport_io(struct fc_rport *);
|
||||
|
|
|
@ -58,25 +58,66 @@ static char *lpfc_release_version = LPFC_DRIVER_VERSION;
|
|||
/*
|
||||
* lpfc_ct_unsol_event
|
||||
*/
|
||||
static void
|
||||
lpfc_ct_unsol_buffer(struct lpfc_hba *phba, struct lpfc_iocbq *piocbq,
|
||||
struct lpfc_dmabuf *mp, uint32_t size)
|
||||
{
|
||||
if (!mp) {
|
||||
printk(KERN_ERR "%s (%d): Unsolited CT, no buffer, "
|
||||
"piocbq = %p, status = x%x, mp = %p, size = %d\n",
|
||||
__FUNCTION__, __LINE__,
|
||||
piocbq, piocbq->iocb.ulpStatus, mp, size);
|
||||
}
|
||||
|
||||
printk(KERN_ERR "%s (%d): Ignoring unsolicted CT piocbq = %p, "
|
||||
"buffer = %p, size = %d, status = x%x\n",
|
||||
__FUNCTION__, __LINE__,
|
||||
piocbq, mp, size,
|
||||
piocbq->iocb.ulpStatus);
|
||||
}
|
||||
|
||||
static void
|
||||
lpfc_ct_ignore_hbq_buffer(struct lpfc_hba *phba, struct lpfc_iocbq *piocbq,
|
||||
struct hbq_dmabuf *sp, uint32_t size)
|
||||
{
|
||||
struct lpfc_dmabuf *mp = NULL;
|
||||
|
||||
mp = sp ? &sp->dbuf : NULL;
|
||||
if (!mp) {
|
||||
printk(KERN_ERR "%s (%d): Unsolited CT, no "
|
||||
"HBQ buffer, piocbq = %p, status = x%x\n",
|
||||
__FUNCTION__, __LINE__,
|
||||
piocbq, piocbq->iocb.ulpStatus);
|
||||
} else {
|
||||
lpfc_ct_unsol_buffer(phba, piocbq, mp, size);
|
||||
printk(KERN_ERR "%s (%d): Ignoring unsolicted CT "
|
||||
"piocbq = %p, buffer = %p, size = %d, "
|
||||
"status = x%x\n",
|
||||
__FUNCTION__, __LINE__,
|
||||
piocbq, mp, size, piocbq->iocb.ulpStatus);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
lpfc_ct_unsol_event(struct lpfc_hba *phba, struct lpfc_sli_ring *pring,
|
||||
struct lpfc_iocbq *piocbq)
|
||||
{
|
||||
|
||||
struct lpfc_iocbq *next_piocbq;
|
||||
struct lpfc_dmabuf *pmbuf = NULL;
|
||||
struct lpfc_dmabuf *matp = NULL, *next_matp;
|
||||
uint32_t ctx = 0, size = 0, cnt = 0;
|
||||
struct lpfc_dmabuf *mp = NULL;
|
||||
struct hbq_dmabuf *sp = NULL;
|
||||
IOCB_t *icmd = &piocbq->iocb;
|
||||
IOCB_t *save_icmd = icmd;
|
||||
int i, go_exit = 0;
|
||||
struct list_head head;
|
||||
int i;
|
||||
struct lpfc_iocbq *iocbq;
|
||||
dma_addr_t paddr;
|
||||
uint32_t size;
|
||||
|
||||
if ((icmd->ulpStatus == IOSTAT_LOCAL_REJECT) &&
|
||||
((icmd->un.ulpWord[4] & 0xff) == IOERR_RCV_BUFFER_WAITING)) {
|
||||
((icmd->un.ulpWord[4] & 0xff) == IOERR_RCV_BUFFER_WAITING)) {
|
||||
/* Not enough posted buffers; Try posting more buffers */
|
||||
phba->fc_stat.NoRcvBuf++;
|
||||
lpfc_post_buffer(phba, pring, 0, 1);
|
||||
if (phba->sli3_options & LPFC_SLI3_HBQ_ENABLED)
|
||||
lpfc_sli_hbqbuf_fill_hbq(phba);
|
||||
else
|
||||
lpfc_post_buffer(phba, pring, 0, 1);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -86,62 +127,62 @@ lpfc_ct_unsol_event(struct lpfc_hba *phba, struct lpfc_sli_ring *pring,
|
|||
if (icmd->ulpBdeCount == 0)
|
||||
return;
|
||||
|
||||
INIT_LIST_HEAD(&head);
|
||||
list_add_tail(&head, &piocbq->list);
|
||||
|
||||
list_for_each_entry_safe(piocbq, next_piocbq, &head, list) {
|
||||
icmd = &piocbq->iocb;
|
||||
if (ctx == 0)
|
||||
ctx = (uint32_t) (icmd->ulpContext);
|
||||
if (icmd->ulpBdeCount == 0)
|
||||
continue;
|
||||
|
||||
for (i = 0; i < icmd->ulpBdeCount; i++) {
|
||||
matp = lpfc_sli_ringpostbuf_get(phba, pring,
|
||||
getPaddr(icmd->un.
|
||||
cont64[i].
|
||||
addrHigh,
|
||||
icmd->un.
|
||||
cont64[i].
|
||||
addrLow));
|
||||
if (!matp) {
|
||||
/* Insert lpfc log message here */
|
||||
lpfc_post_buffer(phba, pring, cnt, 1);
|
||||
go_exit = 1;
|
||||
goto ct_unsol_event_exit_piocbq;
|
||||
if (phba->sli3_options & LPFC_SLI3_HBQ_ENABLED) {
|
||||
list_for_each_entry(iocbq, &piocbq->list, list) {
|
||||
icmd = &iocbq->iocb;
|
||||
if (icmd->ulpBdeCount == 0) {
|
||||
printk(KERN_ERR "%s (%d): Unsolited CT, no "
|
||||
"BDE, iocbq = %p, status = x%x\n",
|
||||
__FUNCTION__, __LINE__,
|
||||
iocbq, iocbq->iocb.ulpStatus);
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Typically for Unsolicited CT requests */
|
||||
if (!pmbuf) {
|
||||
pmbuf = matp;
|
||||
INIT_LIST_HEAD(&pmbuf->list);
|
||||
} else
|
||||
list_add_tail(&matp->list, &pmbuf->list);
|
||||
size = icmd->un.cont64[0].tus.f.bdeSize;
|
||||
sp = lpfc_sli_hbqbuf_find(phba, icmd->un.ulpWord[3]);
|
||||
if (sp)
|
||||
phba->hbq_buff_count--;
|
||||
lpfc_ct_ignore_hbq_buffer(phba, iocbq, sp, size);
|
||||
lpfc_sli_free_hbq(phba, sp);
|
||||
if (icmd->ulpBdeCount == 2) {
|
||||
sp = lpfc_sli_hbqbuf_find(phba,
|
||||
icmd->un.ulpWord[15]);
|
||||
if (sp)
|
||||
phba->hbq_buff_count--;
|
||||
lpfc_ct_ignore_hbq_buffer(phba, iocbq, sp,
|
||||
size);
|
||||
lpfc_sli_free_hbq(phba, sp);
|
||||
}
|
||||
|
||||
size += icmd->un.cont64[i].tus.f.bdeSize;
|
||||
cnt++;
|
||||
}
|
||||
lpfc_sli_hbqbuf_fill_hbq(phba);
|
||||
} else {
|
||||
struct lpfc_iocbq *next;
|
||||
|
||||
icmd->ulpBdeCount = 0;
|
||||
}
|
||||
list_for_each_entry_safe(iocbq, next, &piocbq->list, list) {
|
||||
icmd = &iocbq->iocb;
|
||||
if (icmd->ulpBdeCount == 0) {
|
||||
printk(KERN_ERR "%s (%d): Unsolited CT, no "
|
||||
"BDE, iocbq = %p, status = x%x\n",
|
||||
__FUNCTION__, __LINE__,
|
||||
iocbq, iocbq->iocb.ulpStatus);
|
||||
continue;
|
||||
}
|
||||
|
||||
lpfc_post_buffer(phba, pring, cnt, 1);
|
||||
if (save_icmd->ulpStatus) {
|
||||
go_exit = 1;
|
||||
}
|
||||
|
||||
ct_unsol_event_exit_piocbq:
|
||||
list_del(&head);
|
||||
if (pmbuf) {
|
||||
list_for_each_entry_safe(matp, next_matp, &pmbuf->list, list) {
|
||||
lpfc_mbuf_free(phba, matp->virt, matp->phys);
|
||||
list_del(&matp->list);
|
||||
kfree(matp);
|
||||
for (i = 0; i < icmd->ulpBdeCount; i++) {
|
||||
paddr = getPaddr(icmd->un.cont64[i].addrHigh,
|
||||
icmd->un.cont64[i].addrLow);
|
||||
mp = lpfc_sli_ringpostbuf_get(phba, pring,
|
||||
paddr);
|
||||
size = icmd->un.cont64[i].tus.f.bdeSize;
|
||||
lpfc_ct_unsol_buffer(phba, piocbq, mp, size);
|
||||
lpfc_mbuf_free(phba, mp->virt, mp->phys);
|
||||
kfree(mp);
|
||||
}
|
||||
list_del(&iocbq->list);
|
||||
lpfc_sli_release_iocbq(phba, iocbq);
|
||||
}
|
||||
lpfc_mbuf_free(phba, pmbuf->virt, pmbuf->phys);
|
||||
kfree(pmbuf);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -364,9 +405,7 @@ lpfc_ns_rsp(struct lpfc_vport *vport, struct lpfc_dmabuf *mp, uint32_t Size)
|
|||
vport->fc_flag,
|
||||
vport->fc_rscn_id_cnt);
|
||||
} else {
|
||||
lpfc_printf_log(phba,
|
||||
KERN_INFO,
|
||||
LOG_DISCOVERY,
|
||||
lpfc_printf_log(phba, KERN_INFO, LOG_DISCOVERY,
|
||||
"%d:0239 Skip x%x NameServer "
|
||||
"Rsp Data: x%x x%x x%x\n",
|
||||
phba->brd_no,
|
||||
|
@ -717,12 +756,9 @@ lpfc_cmpl_ct_cmd_fdmi(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
|
|||
ndlp = lpfc_findnode_did(vport, FDMI_DID);
|
||||
if (fdmi_rsp == be16_to_cpu(SLI_CT_RESPONSE_FS_RJT)) {
|
||||
/* FDMI rsp failed */
|
||||
lpfc_printf_log(phba,
|
||||
KERN_INFO,
|
||||
LOG_DISCOVERY,
|
||||
"%d:0220 FDMI rsp failed Data: x%x\n",
|
||||
phba->brd_no,
|
||||
be16_to_cpu(fdmi_cmd));
|
||||
lpfc_printf_log(phba, KERN_INFO, LOG_DISCOVERY,
|
||||
"%d:0220 FDMI rsp failed Data: x%x\n",
|
||||
phba->brd_no, be16_to_cpu(fdmi_cmd));
|
||||
}
|
||||
|
||||
switch (be16_to_cpu(fdmi_cmd)) {
|
||||
|
@ -791,9 +827,7 @@ lpfc_fdmi_cmd(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, int cmdcode)
|
|||
INIT_LIST_HEAD(&bmp->list);
|
||||
|
||||
/* FDMI request */
|
||||
lpfc_printf_log(phba,
|
||||
KERN_INFO,
|
||||
LOG_DISCOVERY,
|
||||
lpfc_printf_log(phba, KERN_INFO, LOG_DISCOVERY,
|
||||
"%d:0218 FDMI Request Data: x%x x%x x%x\n",
|
||||
phba->brd_no,
|
||||
vport->fc_flag, vport->port_state, cmdcode);
|
||||
|
@ -1120,12 +1154,9 @@ lpfc_fdmi_cmd(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, int cmdcode)
|
|||
kfree(mp);
|
||||
fdmi_cmd_exit:
|
||||
/* Issue FDMI request failed */
|
||||
lpfc_printf_log(phba,
|
||||
KERN_INFO,
|
||||
LOG_DISCOVERY,
|
||||
lpfc_printf_log(phba, KERN_INFO, LOG_DISCOVERY,
|
||||
"%d:0244 Issue FDMI request failed Data: x%x\n",
|
||||
phba->brd_no,
|
||||
cmdcode);
|
||||
phba->brd_no, cmdcode);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
|
|
@ -45,9 +45,7 @@ lpfc_els_chk_latt(struct lpfc_vport *vport)
|
|||
{
|
||||
struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
|
||||
struct lpfc_hba *phba = vport->phba;
|
||||
LPFC_MBOXQ_t *mbox;
|
||||
uint32_t ha_copy;
|
||||
int rc;
|
||||
|
||||
if (vport->port_state >= LPFC_VPORT_READY ||
|
||||
phba->link_state == LPFC_LINK_DOWN)
|
||||
|
@ -76,20 +74,7 @@ lpfc_els_chk_latt(struct lpfc_vport *vport)
|
|||
spin_unlock_irq(shost->host_lock);
|
||||
|
||||
if (phba->link_state != LPFC_CLEAR_LA) {
|
||||
if ((mbox = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL))) {
|
||||
phba->link_state = LPFC_CLEAR_LA;
|
||||
lpfc_clear_la(phba, mbox);
|
||||
mbox->mbox_cmpl = lpfc_mbx_cmpl_clear_la;
|
||||
mbox->vport = vport;
|
||||
printk(KERN_ERR "%s (%d): do clear_la\n",
|
||||
__FUNCTION__, __LINE__);
|
||||
rc = lpfc_sli_issue_mbox(phba, mbox,
|
||||
(MBX_NOWAIT | MBX_STOP_IOCB));
|
||||
if (rc == MBX_NOT_FINISHED) {
|
||||
mempool_free(mbox, phba->mbox_mem_pool);
|
||||
phba->link_state = LPFC_HBA_ERROR;
|
||||
}
|
||||
}
|
||||
lpfc_issue_clear_la(phba, vport);
|
||||
}
|
||||
|
||||
return 1;
|
||||
|
@ -153,8 +138,8 @@ lpfc_prep_els_iocb(struct lpfc_vport *vport, uint8_t expectRsp,
|
|||
/* Allocate buffer for Buffer ptr list */
|
||||
pbuflist = kmalloc(sizeof (struct lpfc_dmabuf), GFP_KERNEL);
|
||||
if (pbuflist)
|
||||
pbuflist->virt = lpfc_mbuf_alloc(phba, MEM_PRI,
|
||||
&pbuflist->phys);
|
||||
pbuflist->virt = lpfc_mbuf_alloc(phba, MEM_PRI,
|
||||
&pbuflist->phys);
|
||||
if (pbuflist == 0 || pbuflist->virt == 0) {
|
||||
lpfc_sli_release_iocbq(phba, elsiocb);
|
||||
lpfc_mbuf_free(phba, pcmd->virt, pcmd->phys);
|
||||
|
@ -289,6 +274,7 @@ lpfc_cmpl_els_flogi_fabric(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
|
|||
vport->port_state = LPFC_FABRIC_CFG_LINK;
|
||||
lpfc_config_link(phba, mbox);
|
||||
mbox->mbox_cmpl = lpfc_sli_def_mbox_cmpl;
|
||||
mbox->vport = vport;
|
||||
|
||||
rc = lpfc_sli_issue_mbox(phba, mbox, MBX_NOWAIT | MBX_STOP_IOCB);
|
||||
if (rc == MBX_NOT_FINISHED)
|
||||
|
@ -364,6 +350,7 @@ lpfc_cmpl_els_flogi_nport(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
|
|||
lpfc_config_link(phba, mbox);
|
||||
|
||||
mbox->mbox_cmpl = lpfc_sli_def_mbox_cmpl;
|
||||
mbox->vport = vport;
|
||||
rc = lpfc_sli_issue_mbox(phba, mbox,
|
||||
MBX_NOWAIT | MBX_STOP_IOCB);
|
||||
if (rc == MBX_NOT_FINISHED) {
|
||||
|
@ -714,8 +701,10 @@ lpfc_cmpl_els_plogi(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
|
|||
|
||||
irsp = &rspiocb->iocb;
|
||||
ndlp = lpfc_findnode_did(vport, irsp->un.elsreq64.remoteID);
|
||||
if (!ndlp)
|
||||
|
||||
if (!ndlp) {
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* Since ndlp can be freed in the disc state machine, note if this node
|
||||
* is being used during discovery.
|
||||
|
@ -1110,9 +1099,8 @@ lpfc_cmpl_els_adisc(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
|
|||
/* If we get here, there is nothing left to wait for */
|
||||
if (vport->port_state < LPFC_VPORT_READY &&
|
||||
phba->link_state != LPFC_CLEAR_LA) {
|
||||
if (vport->port_type == LPFC_PHYSICAL_PORT) {
|
||||
if (vport->port_type == LPFC_PHYSICAL_PORT)
|
||||
lpfc_issue_clear_la(phba, vport);
|
||||
}
|
||||
} else {
|
||||
lpfc_rscn_disc(vport);
|
||||
}
|
||||
|
@ -1420,6 +1408,27 @@ lpfc_issue_els_farpr(struct lpfc_vport *vport, uint32_t nportid, uint8_t retry)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
lpfc_end_rscn(struct lpfc_vport *vport)
|
||||
{
|
||||
struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
|
||||
|
||||
if (vport->fc_flag & FC_RSCN_MODE) {
|
||||
/*
|
||||
* Check to see if more RSCNs came in while we were
|
||||
* processing this one.
|
||||
*/
|
||||
if (vport->fc_rscn_id_cnt ||
|
||||
(vport->fc_flag & FC_RSCN_DISCOVERY) != 0)
|
||||
lpfc_els_handle_rscn(vport);
|
||||
else {
|
||||
spin_lock_irq(shost->host_lock);
|
||||
vport->fc_flag &= ~FC_RSCN_MODE;
|
||||
spin_unlock_irq(shost->host_lock);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
lpfc_cancel_retry_delay_tmo(struct lpfc_vport *vport, struct lpfc_nodelist *nlp)
|
||||
{
|
||||
|
@ -1449,24 +1458,7 @@ lpfc_cancel_retry_delay_tmo(struct lpfc_vport *vport, struct lpfc_nodelist *nlp)
|
|||
vport->fc_flag &= ~FC_NDISC_ACTIVE;
|
||||
spin_unlock_irq(shost->host_lock);
|
||||
lpfc_can_disctmo(vport);
|
||||
if (vport->fc_flag & FC_RSCN_MODE) {
|
||||
/*
|
||||
* Check to see if more RSCNs
|
||||
* came in while we were
|
||||
* processing this one.
|
||||
*/
|
||||
if (!vport->fc_rscn_id_cnt &&
|
||||
!(vport->fc_flag &
|
||||
FC_RSCN_DISCOVERY)) {
|
||||
spin_lock_irq(shost->host_lock);
|
||||
vport->fc_flag &= ~FC_RSCN_MODE;
|
||||
spin_unlock_irq(
|
||||
shost->host_lock);
|
||||
}
|
||||
else {
|
||||
lpfc_els_handle_rscn(vport);
|
||||
}
|
||||
}
|
||||
lpfc_end_rscn(vport);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1689,6 +1681,9 @@ lpfc_els_retry(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
|
|||
retry = 0;
|
||||
}
|
||||
|
||||
if ((vport->load_flag & FC_UNLOADING) != 0)
|
||||
retry = 0;
|
||||
|
||||
if (retry) {
|
||||
|
||||
/* Retry ELS command <elsCmd> to remote NPORT <did> */
|
||||
|
@ -2141,9 +2136,7 @@ lpfc_els_rsp_prli_acc(struct lpfc_vport *vport, struct lpfc_iocbq *oldiocb,
|
|||
|
||||
cmdsize = sizeof (uint32_t) + sizeof (PRLI);
|
||||
elsiocb = lpfc_prep_els_iocb(vport, 0, cmdsize, oldiocb->retry, ndlp,
|
||||
ndlp->nlp_DID,
|
||||
(ELS_CMD_ACC |
|
||||
(ELS_CMD_PRLI & ~ELS_RSP_MASK)));
|
||||
ndlp->nlp_DID, (ELS_CMD_ACC | (ELS_CMD_PRLI & ~ELS_RSP_MASK)));
|
||||
if (!elsiocb)
|
||||
return 1;
|
||||
|
||||
|
@ -2361,8 +2354,12 @@ lpfc_els_flush_rscn(struct lpfc_vport *vport)
|
|||
|
||||
for (i = 0; i < vport->fc_rscn_id_cnt; i++) {
|
||||
mp = vport->fc_rscn_id_list[i];
|
||||
lpfc_mbuf_free(phba, mp->virt, mp->phys);
|
||||
kfree(mp);
|
||||
if (phba->sli3_options & LPFC_SLI3_HBQ_ENABLED)
|
||||
lpfc_sli_hbqbuf_free(phba, mp->virt, mp->phys);
|
||||
else {
|
||||
lpfc_mbuf_free(phba, mp->virt, mp->phys);
|
||||
kfree(mp);
|
||||
}
|
||||
vport->fc_rscn_id_list[i] = NULL;
|
||||
}
|
||||
spin_lock_irq(shost->host_lock);
|
||||
|
@ -2486,9 +2483,7 @@ lpfc_els_rcv_rscn(struct lpfc_vport *vport, struct lpfc_iocbq *cmdiocb,
|
|||
cmd &= ELS_CMD_MASK;
|
||||
|
||||
/* RSCN received */
|
||||
lpfc_printf_log(phba,
|
||||
KERN_INFO,
|
||||
LOG_DISCOVERY,
|
||||
lpfc_printf_log(phba, KERN_INFO, LOG_DISCOVERY,
|
||||
"%d:0214 RSCN received Data: x%x x%x x%x x%x\n",
|
||||
phba->brd_no, vport->fc_flag, payload_len, *lp,
|
||||
vport->fc_rscn_id_cnt);
|
||||
|
@ -2581,9 +2576,7 @@ lpfc_els_handle_rscn(struct lpfc_vport *vport)
|
|||
lpfc_set_disctmo(vport);
|
||||
|
||||
/* RSCN processed */
|
||||
lpfc_printf_log(phba,
|
||||
KERN_INFO,
|
||||
LOG_DISCOVERY,
|
||||
lpfc_printf_log(phba, KERN_INFO, LOG_DISCOVERY,
|
||||
"%d:0215 RSCN processed Data: x%x x%x x%x x%x\n",
|
||||
phba->brd_no,
|
||||
vport->fc_flag, 0, vport->fc_rscn_id_cnt,
|
||||
|
@ -2683,6 +2676,7 @@ lpfc_els_rcv_flogi(struct lpfc_vport *vport, struct lpfc_iocbq *cmdiocb,
|
|||
phba->cfg_link_speed);
|
||||
mbox->mb.un.varInitLnk.lipsr_AL_PA = 0;
|
||||
mbox->mbox_cmpl = lpfc_sli_def_mbox_cmpl;
|
||||
mbox->vport = vport;
|
||||
rc = lpfc_sli_issue_mbox
|
||||
(phba, mbox, (MBX_NOWAIT | MBX_STOP_IOCB));
|
||||
lpfc_set_loopback_flag(phba);
|
||||
|
@ -2837,10 +2831,8 @@ lpfc_els_rsp_rps_acc(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb)
|
|||
|
||||
elsiocb->iocb_cmpl = lpfc_cmpl_els_acc;
|
||||
phba->fc_stat.elsXmitACC++;
|
||||
|
||||
if (lpfc_sli_issue_iocb(phba, pring, elsiocb, 0) == IOCB_ERROR) {
|
||||
if (lpfc_sli_issue_iocb(phba, pring, elsiocb, 0) == IOCB_ERROR)
|
||||
lpfc_els_free_iocb(phba, elsiocb);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -3015,9 +3007,7 @@ lpfc_els_rcv_farp(struct lpfc_vport *vport, struct lpfc_iocbq *cmdiocb,
|
|||
fp = (FARP *) lp;
|
||||
|
||||
/* FARP-REQ received from DID <did> */
|
||||
lpfc_printf_log(phba,
|
||||
KERN_INFO,
|
||||
LOG_ELS,
|
||||
lpfc_printf_log(phba, KERN_INFO, LOG_ELS,
|
||||
"%d:0601 FARP-REQ received from DID x%x\n",
|
||||
phba->brd_no, did);
|
||||
|
||||
|
@ -3077,12 +3067,9 @@ lpfc_els_rcv_farpr(struct lpfc_vport *vport, struct lpfc_iocbq *cmdiocb,
|
|||
|
||||
cmd = *lp++;
|
||||
/* FARP-RSP received from DID <did> */
|
||||
lpfc_printf_log(phba,
|
||||
KERN_INFO,
|
||||
LOG_ELS,
|
||||
lpfc_printf_log(phba, KERN_INFO, LOG_ELS,
|
||||
"%d:0600 FARP-RSP received from DID x%x\n",
|
||||
phba->brd_no, did);
|
||||
|
||||
/* ACCEPT the Farp resp request */
|
||||
lpfc_els_rsp_acc(vport, ELS_CMD_ACC, cmdiocb, ndlp, NULL, 0);
|
||||
|
||||
|
@ -3102,8 +3089,9 @@ lpfc_els_rcv_fan(struct lpfc_vport *vport, struct lpfc_iocbq *cmdiocb,
|
|||
struct lpfc_hba *phba = vport->phba;
|
||||
|
||||
/* FAN received */
|
||||
lpfc_printf_log(phba, KERN_INFO, LOG_ELS, "%d:0265 FAN received\n",
|
||||
phba->brd_no);
|
||||
lpfc_printf_log(phba, KERN_INFO, LOG_ELS,
|
||||
"%d:0265 FAN received\n",
|
||||
phba->brd_no);
|
||||
|
||||
icmd = &cmdiocb->iocb;
|
||||
did = icmd->un.elsreq64.remoteID;
|
||||
|
@ -3332,79 +3320,40 @@ lpfc_els_flush_cmd(struct lpfc_vport *vport)
|
|||
return;
|
||||
}
|
||||
|
||||
void
|
||||
lpfc_els_unsol_event(struct lpfc_hba *phba, struct lpfc_sli_ring *pring,
|
||||
struct lpfc_iocbq *elsiocb)
|
||||
static void
|
||||
lpfc_els_unsol_buffer(struct lpfc_hba *phba, struct lpfc_sli_ring *pring,
|
||||
struct lpfc_vport *vport, struct lpfc_dmabuf *mp,
|
||||
struct lpfc_iocbq *elsiocb)
|
||||
{
|
||||
struct lpfc_sli *psli;
|
||||
struct lpfc_nodelist *ndlp;
|
||||
struct lpfc_dmabuf *mp = NULL;
|
||||
uint32_t *lp;
|
||||
IOCB_t *icmd;
|
||||
struct ls_rjt stat;
|
||||
uint32_t *lp;
|
||||
uint32_t cmd, did, newnode, rjt_err = 0;
|
||||
uint32_t drop_cmd = 0; /* by default do NOT drop received cmd */
|
||||
struct lpfc_vport *vport = NULL;
|
||||
IOCB_t *icmd = &elsiocb->iocb;
|
||||
|
||||
psli = &phba->sli;
|
||||
icmd = &elsiocb->iocb;
|
||||
|
||||
if ((icmd->ulpStatus == IOSTAT_LOCAL_REJECT) &&
|
||||
((icmd->un.ulpWord[4] & 0xff) == IOERR_RCV_BUFFER_WAITING)) {
|
||||
phba->fc_stat.NoRcvBuf++;
|
||||
/* Not enough posted buffers; Try posting more buffers */
|
||||
lpfc_post_buffer(phba, pring, 0, 1);
|
||||
return;
|
||||
}
|
||||
|
||||
/* If there are no BDEs associated with this IOCB,
|
||||
* there is nothing to do.
|
||||
*/
|
||||
if (icmd->ulpBdeCount == 0)
|
||||
return;
|
||||
|
||||
/* type of ELS cmd is first 32bit word in packet */
|
||||
mp = lpfc_sli_ringpostbuf_get(phba, pring,
|
||||
getPaddr(icmd->un.cont64[0].addrHigh,
|
||||
icmd->un.cont64[0].addrLow));
|
||||
if (mp == 0) {
|
||||
drop_cmd = 1;
|
||||
if (!vport || !mp)
|
||||
goto dropit;
|
||||
}
|
||||
|
||||
vport = phba->pport;
|
||||
|
||||
newnode = 0;
|
||||
lp = (uint32_t *) mp->virt;
|
||||
cmd = *lp++;
|
||||
lpfc_post_buffer(phba, &psli->ring[LPFC_ELS_RING], 1, 1);
|
||||
if ((phba->sli3_options & LPFC_SLI3_HBQ_ENABLED) == 0)
|
||||
lpfc_post_buffer(phba, pring, 1, 1);
|
||||
|
||||
if (icmd->ulpStatus) {
|
||||
lpfc_mbuf_free(phba, mp->virt, mp->phys);
|
||||
kfree(mp);
|
||||
drop_cmd = 1;
|
||||
if (icmd->ulpStatus)
|
||||
goto dropit;
|
||||
}
|
||||
|
||||
/* Check to see if link went down during discovery */
|
||||
if (lpfc_els_chk_latt(vport)) {
|
||||
lpfc_mbuf_free(phba, mp->virt, mp->phys);
|
||||
kfree(mp);
|
||||
drop_cmd = 1;
|
||||
if (lpfc_els_chk_latt(vport))
|
||||
goto dropit;
|
||||
}
|
||||
|
||||
did = icmd->un.rcvels.remoteID;
|
||||
ndlp = lpfc_findnode_did(vport, did);
|
||||
if (!ndlp) {
|
||||
/* Cannot find existing Fabric ndlp, so allocate a new one */
|
||||
ndlp = mempool_alloc(phba->nlp_mem_pool, GFP_KERNEL);
|
||||
if (!ndlp) {
|
||||
lpfc_mbuf_free(phba, mp->virt, mp->phys);
|
||||
kfree(mp);
|
||||
drop_cmd = 1;
|
||||
if (!ndlp)
|
||||
goto dropit;
|
||||
}
|
||||
|
||||
lpfc_nlp_init(vport, ndlp, did);
|
||||
newnode = 1;
|
||||
|
@ -3428,7 +3377,7 @@ lpfc_els_unsol_event(struct lpfc_hba *phba, struct lpfc_sli_ring *pring,
|
|||
lpfc_printf_log(phba, KERN_INFO, LOG_ELS,
|
||||
"%d:0112 ELS command x%x received from NPORT x%x "
|
||||
"Data: x%x\n", phba->brd_no, cmd, did,
|
||||
vport->port_state);
|
||||
vport->port_state);
|
||||
|
||||
switch (cmd) {
|
||||
case ELS_CMD_PLOGI:
|
||||
|
@ -3537,8 +3486,9 @@ lpfc_els_unsol_event(struct lpfc_hba *phba, struct lpfc_sli_ring *pring,
|
|||
|
||||
/* Unknown ELS command <elsCmd> received from NPORT <did> */
|
||||
lpfc_printf_log(phba, KERN_ERR, LOG_ELS,
|
||||
"%d:0115 Unknown ELS command x%x received from "
|
||||
"NPORT x%x\n", phba->brd_no, cmd, did);
|
||||
"%d:0115 Unknown ELS command x%x "
|
||||
"received from NPORT x%x\n",
|
||||
phba->brd_no, cmd, did);
|
||||
if (newnode)
|
||||
lpfc_drop_node(vport, ndlp);
|
||||
break;
|
||||
|
@ -3553,20 +3503,89 @@ lpfc_els_unsol_event(struct lpfc_hba *phba, struct lpfc_sli_ring *pring,
|
|||
lpfc_els_rsp_reject(vport, stat.un.lsRjtError, elsiocb, ndlp);
|
||||
}
|
||||
|
||||
return;
|
||||
|
||||
dropit:
|
||||
lpfc_printf_log(phba, KERN_ERR, LOG_ELS,
|
||||
"%d:0111 Dropping received ELS cmd "
|
||||
"Data: x%x x%x x%x\n",
|
||||
phba->brd_no,
|
||||
icmd->ulpStatus, icmd->un.ulpWord[4],
|
||||
icmd->ulpTimeout);
|
||||
phba->fc_stat.elsRcvDrop++;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
lpfc_els_unsol_event(struct lpfc_hba *phba, struct lpfc_sli_ring *pring,
|
||||
struct lpfc_iocbq *elsiocb)
|
||||
{
|
||||
struct lpfc_vport *vport = phba->pport;
|
||||
struct lpfc_dmabuf *mp = NULL;
|
||||
IOCB_t *icmd = &elsiocb->iocb;
|
||||
struct hbq_dmabuf *sp = NULL;
|
||||
dma_addr_t paddr;
|
||||
|
||||
if ((icmd->ulpStatus == IOSTAT_LOCAL_REJECT) &&
|
||||
((icmd->un.ulpWord[4] & 0xff) == IOERR_RCV_BUFFER_WAITING)) {
|
||||
phba->fc_stat.NoRcvBuf++;
|
||||
/* Not enough posted buffers; Try posting more buffers */
|
||||
if (phba->sli3_options & LPFC_SLI3_HBQ_ENABLED)
|
||||
lpfc_sli_hbqbuf_fill_hbq(phba);
|
||||
else
|
||||
lpfc_post_buffer(phba, pring, 0, 1);
|
||||
return;
|
||||
}
|
||||
|
||||
/* If there are no BDEs associated with this IOCB,
|
||||
* there is nothing to do.
|
||||
*/
|
||||
if (icmd->ulpBdeCount == 0)
|
||||
return;
|
||||
|
||||
/* type of ELS cmd is first 32bit word in packet */
|
||||
if (phba->sli3_options & LPFC_SLI3_HBQ_ENABLED) {
|
||||
paddr = getPaddr(icmd->un.cont64[0].addrHigh,
|
||||
icmd->un.cont64[0].addrLow);
|
||||
sp = lpfc_sli_hbqbuf_find(phba, icmd->un.ulpWord[3]);
|
||||
if (sp)
|
||||
phba->hbq_buff_count--;
|
||||
mp = sp ? &sp->dbuf : NULL;
|
||||
} else {
|
||||
paddr = getPaddr(icmd->un.cont64[0].addrHigh,
|
||||
icmd->un.cont64[0].addrLow);
|
||||
mp = lpfc_sli_ringpostbuf_get(phba, pring, paddr);
|
||||
}
|
||||
|
||||
lpfc_els_unsol_buffer(phba, pring, vport, mp, elsiocb);
|
||||
|
||||
lpfc_nlp_put(elsiocb->context1);
|
||||
elsiocb->context1 = NULL;
|
||||
if (elsiocb->context2) {
|
||||
lpfc_mbuf_free(phba, mp->virt, mp->phys);
|
||||
kfree(mp);
|
||||
if (phba->sli3_options & LPFC_SLI3_HBQ_ENABLED)
|
||||
lpfc_sli_free_hbq(phba, sp);
|
||||
else {
|
||||
lpfc_mbuf_free(phba, mp->virt, mp->phys);
|
||||
kfree(mp);
|
||||
}
|
||||
}
|
||||
dropit:
|
||||
/* check if need to drop received ELS cmd */
|
||||
if (drop_cmd == 1) {
|
||||
lpfc_printf_log(phba, KERN_ERR, LOG_ELS,
|
||||
"%d:0111 Dropping received ELS cmd "
|
||||
"Data: x%x x%x x%x\n", phba->brd_no,
|
||||
icmd->ulpStatus, icmd->un.ulpWord[4],
|
||||
icmd->ulpTimeout);
|
||||
phba->fc_stat.elsRcvDrop++;
|
||||
|
||||
/* RCV_ELS64_CX provide for 2 BDEs - process 2nd if included */
|
||||
if ((phba->sli3_options & LPFC_SLI3_HBQ_ENABLED) != 0 &&
|
||||
icmd->ulpBdeCount == 2) {
|
||||
sp = lpfc_sli_hbqbuf_find(phba, icmd->un.ulpWord[15]);
|
||||
if (sp)
|
||||
phba->hbq_buff_count--;
|
||||
mp = sp ? &sp->dbuf : NULL;
|
||||
lpfc_els_unsol_buffer(phba, pring, vport, mp, elsiocb);
|
||||
/* free mp if we are done with it */
|
||||
if (elsiocb->context2) {
|
||||
if (phba->sli3_options & LPFC_SLI3_HBQ_ENABLED)
|
||||
lpfc_sli_free_hbq(phba, sp);
|
||||
else {
|
||||
lpfc_mbuf_free(phba, mp->virt, mp->phys);
|
||||
kfree(mp);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -232,9 +232,9 @@ static void
|
|||
lpfc_work_done(struct lpfc_hba *phba)
|
||||
{
|
||||
struct lpfc_sli_ring *pring;
|
||||
int i;
|
||||
uint32_t ha_copy, control, work_port_events;
|
||||
struct lpfc_vport *vport;
|
||||
int i;
|
||||
|
||||
spin_lock_irq(&phba->hbalock);
|
||||
ha_copy = phba->work_ha;
|
||||
|
@ -303,9 +303,9 @@ check_work_wait_done(struct lpfc_hba *phba)
|
|||
struct lpfc_vport *vport = phba->pport;
|
||||
int rc = 0;
|
||||
|
||||
|
||||
if (!vport)
|
||||
return 0;
|
||||
|
||||
spin_lock_irq(&phba->hbalock);
|
||||
|
||||
if (phba->work_ha ||
|
||||
|
@ -354,6 +354,7 @@ lpfc_workq_post_event(struct lpfc_hba *phba, void *arg1, void *arg2,
|
|||
uint32_t evt)
|
||||
{
|
||||
struct lpfc_work_evt *evtp;
|
||||
unsigned long flags;
|
||||
|
||||
/*
|
||||
* All Mailbox completions and LPFC_ELS_RING rcv ring IOCB events will
|
||||
|
@ -367,11 +368,11 @@ lpfc_workq_post_event(struct lpfc_hba *phba, void *arg1, void *arg2,
|
|||
evtp->evt_arg2 = arg2;
|
||||
evtp->evt = evt;
|
||||
|
||||
spin_lock_irq(&phba->hbalock);
|
||||
spin_lock_irqsave(&phba->hbalock, flags);
|
||||
list_add_tail(&evtp->evt_listp, &phba->work_list);
|
||||
if (phba->work_wait)
|
||||
wake_up(phba->work_wait);
|
||||
spin_unlock_irq(&phba->hbalock);
|
||||
spin_unlock_irqrestore(&phba->hbalock, flags);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
@ -401,6 +402,7 @@ lpfc_linkdown(struct lpfc_hba *phba)
|
|||
mb = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL);
|
||||
if (mb) {
|
||||
lpfc_unreg_did(phba, 0xffffffff, mb);
|
||||
mb->vport = vport;
|
||||
mb->mbox_cmpl = lpfc_sli_def_mbox_cmpl;
|
||||
if (lpfc_sli_issue_mbox(phba, mb, (MBX_NOWAIT | MBX_STOP_IOCB))
|
||||
== MBX_NOT_FINISHED) {
|
||||
|
@ -433,6 +435,7 @@ lpfc_linkdown(struct lpfc_hba *phba)
|
|||
if (mb) {
|
||||
lpfc_config_link(phba, mb);
|
||||
mb->mbox_cmpl=lpfc_sli_def_mbox_cmpl;
|
||||
mb->vport = vport;
|
||||
if (lpfc_sli_issue_mbox(phba, mb,
|
||||
(MBX_NOWAIT | MBX_STOP_IOCB))
|
||||
== MBX_NOT_FINISHED) {
|
||||
|
@ -550,15 +553,11 @@ lpfc_mbx_cmpl_clear_la(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb)
|
|||
spin_unlock_irq(shost->host_lock);
|
||||
}
|
||||
|
||||
printk(KERN_ERR "%s (%d): vport ready\n",
|
||||
__FUNCTION__, __LINE__);
|
||||
vport->port_state = LPFC_VPORT_READY;
|
||||
|
||||
out:
|
||||
/* Device Discovery completes */
|
||||
lpfc_printf_log(phba,
|
||||
KERN_INFO,
|
||||
LOG_DISCOVERY,
|
||||
lpfc_printf_log(phba, KERN_INFO, LOG_DISCOVERY,
|
||||
"%d:0225 Device Discovery completes\n",
|
||||
phba->brd_no);
|
||||
|
||||
|
@ -632,8 +631,6 @@ lpfc_mbx_cmpl_local_config_link(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb)
|
|||
phba->brd_no, vport->port_state);
|
||||
|
||||
lpfc_clear_la(phba, pmb);
|
||||
printk(KERN_ERR "%s (%d): do clear_la\n",
|
||||
__FUNCTION__, __LINE__);
|
||||
pmb->mbox_cmpl = lpfc_mbx_cmpl_clear_la;
|
||||
pmb->vport = vport;
|
||||
rc = lpfc_sli_issue_mbox(phba, pmb, (MBX_NOWAIT | MBX_STOP_IOCB));
|
||||
|
@ -643,8 +640,6 @@ lpfc_mbx_cmpl_local_config_link(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb)
|
|||
psli->ring[(psli->extra_ring)].flag &= ~LPFC_STOP_IOCB_EVENT;
|
||||
psli->ring[(psli->fcp_ring)].flag &= ~LPFC_STOP_IOCB_EVENT;
|
||||
psli->ring[(psli->next_ring)].flag &= ~LPFC_STOP_IOCB_EVENT;
|
||||
printk(KERN_ERR "%s (%d): vport ready\n",
|
||||
__FUNCTION__, __LINE__);
|
||||
vport->port_state = LPFC_VPORT_READY;
|
||||
}
|
||||
return;
|
||||
|
@ -702,8 +697,6 @@ lpfc_mbx_cmpl_read_sparam(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb)
|
|||
struct lpfc_sli_ring *next_ring = &psli->ring[psli->next_ring];
|
||||
|
||||
lpfc_clear_la(phba, pmb);
|
||||
printk(KERN_ERR "%s (%d): do clear_la\n",
|
||||
__FUNCTION__, __LINE__);
|
||||
pmb->mbox_cmpl = lpfc_mbx_cmpl_clear_la;
|
||||
pmb->vport = vport;
|
||||
if (lpfc_sli_issue_mbox(phba, pmb, (MBX_NOWAIT | MBX_STOP_IOCB))
|
||||
|
@ -713,8 +706,6 @@ lpfc_mbx_cmpl_read_sparam(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb)
|
|||
extra_ring->flag &= ~LPFC_STOP_IOCB_EVENT;
|
||||
fcp_ring->flag &= ~LPFC_STOP_IOCB_EVENT;
|
||||
next_ring->flag &= ~LPFC_STOP_IOCB_EVENT;
|
||||
printk(KERN_ERR "%s (%d): vport ready\n",
|
||||
__FUNCTION__, __LINE__);
|
||||
vport->port_state = LPFC_VPORT_READY;
|
||||
}
|
||||
} else {
|
||||
|
@ -875,12 +866,9 @@ lpfc_mbx_cmpl_read_la(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb)
|
|||
|
||||
/* Check for error */
|
||||
if (mb->mbxStatus) {
|
||||
lpfc_printf_log(phba,
|
||||
KERN_INFO,
|
||||
LOG_LINK_EVENT,
|
||||
lpfc_printf_log(phba, KERN_INFO, LOG_LINK_EVENT,
|
||||
"%d:1307 READ_LA mbox error x%x state x%x\n",
|
||||
phba->brd_no,
|
||||
mb->mbxStatus, vport->port_state);
|
||||
phba->brd_no, mb->mbxStatus, vport->port_state);
|
||||
lpfc_mbx_issue_link_down(phba);
|
||||
phba->link_state = LPFC_HBA_ERROR;
|
||||
goto lpfc_mbx_cmpl_read_la_free_mbuf;
|
||||
|
@ -955,7 +943,6 @@ lpfc_mbx_cmpl_reg_login(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb)
|
|||
struct lpfc_dmabuf *mp = (struct lpfc_dmabuf *) pmb->context1;
|
||||
struct lpfc_nodelist *ndlp = (struct lpfc_nodelist *) pmb->context2;
|
||||
|
||||
|
||||
pmb->context1 = NULL;
|
||||
|
||||
/* Good status, call state machine */
|
||||
|
@ -1553,6 +1540,7 @@ lpfc_unreg_rpi(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp)
|
|||
mbox = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL);
|
||||
if (mbox) {
|
||||
lpfc_unreg_login(phba, ndlp->nlp_rpi, mbox);
|
||||
mbox->vport = vport;
|
||||
mbox->mbox_cmpl=lpfc_sli_def_mbox_cmpl;
|
||||
rc = lpfc_sli_issue_mbox
|
||||
(phba, mbox, (MBX_NOWAIT | MBX_STOP_IOCB));
|
||||
|
@ -1925,8 +1913,6 @@ lpfc_disc_start(struct lpfc_vport *vport)
|
|||
if (vport->port_state < LPFC_VPORT_READY && !clear_la_pending) {
|
||||
if (vport->port_type == LPFC_PHYSICAL_PORT) {
|
||||
/* If we get here, there is nothing to ADISC */
|
||||
printk(KERN_ERR "%s (%d): do clear_la\n",
|
||||
__FUNCTION__, __LINE__);
|
||||
lpfc_issue_clear_la(phba, vport);
|
||||
} else if (!(vport->fc_flag & FC_ABORT_DISCOVERY)) {
|
||||
|
||||
|
@ -1940,8 +1926,6 @@ lpfc_disc_start(struct lpfc_vport *vport)
|
|||
vport->fc_flag &= ~FC_NDISC_ACTIVE;
|
||||
spin_unlock_irq(shost->host_lock);
|
||||
}
|
||||
printk(KERN_ERR "%s (%d): vport ready\n",
|
||||
__FUNCTION__, __LINE__);
|
||||
vport->port_state = LPFC_VPORT_READY;
|
||||
}
|
||||
} else {
|
||||
|
@ -2095,13 +2079,10 @@ lpfc_disc_timeout_handler(struct lpfc_vport *vport)
|
|||
if (!(vport->fc_flag & FC_DISC_TMO))
|
||||
return;
|
||||
|
||||
|
||||
spin_lock_irq(shost->host_lock);
|
||||
vport->fc_flag &= ~FC_DISC_TMO;
|
||||
spin_unlock_irq(shost->host_lock);
|
||||
|
||||
printk(KERN_ERR "%s (%d): link_state = %d, port_state = %d\n",
|
||||
__FUNCTION__, __LINE__, phba->link_state, vport->port_state);
|
||||
switch (vport->port_state) {
|
||||
|
||||
case LPFC_LOCAL_CFG_LINK:
|
||||
|
@ -2109,9 +2090,7 @@ lpfc_disc_timeout_handler(struct lpfc_vport *vport)
|
|||
* FAN
|
||||
*/
|
||||
/* FAN timeout */
|
||||
lpfc_printf_log(phba,
|
||||
KERN_WARNING,
|
||||
LOG_DISCOVERY,
|
||||
lpfc_printf_log(phba, KERN_WARNING, LOG_DISCOVERY,
|
||||
"%d:0221 FAN timeout\n",
|
||||
phba->brd_no);
|
||||
|
||||
|
@ -2138,9 +2117,7 @@ lpfc_disc_timeout_handler(struct lpfc_vport *vport)
|
|||
case LPFC_FLOGI:
|
||||
/* port_state is identically LPFC_FLOGI while waiting for FLOGI cmpl */
|
||||
/* Initial FLOGI timeout */
|
||||
lpfc_printf_log(phba,
|
||||
KERN_ERR,
|
||||
LOG_DISCOVERY,
|
||||
lpfc_printf_log(phba, KERN_ERR, LOG_DISCOVERY,
|
||||
"%d:0222 Initial FLOGI timeout\n",
|
||||
phba->brd_no);
|
||||
|
||||
|
@ -2203,8 +2180,6 @@ lpfc_disc_timeout_handler(struct lpfc_vport *vport)
|
|||
|
||||
phba->link_state = LPFC_CLEAR_LA;
|
||||
lpfc_clear_la(phba, clearlambox);
|
||||
printk(KERN_ERR "%s (%d): do clear_la\n",
|
||||
__FUNCTION__, __LINE__);
|
||||
clearlambox->mbox_cmpl = lpfc_mbx_cmpl_clear_la;
|
||||
clearlambox->vport = vport;
|
||||
rc = lpfc_sli_issue_mbox(phba, clearlambox,
|
||||
|
@ -2230,6 +2205,7 @@ lpfc_disc_timeout_handler(struct lpfc_vport *vport)
|
|||
lpfc_init_link(phba, initlinkmbox, phba->cfg_topology,
|
||||
phba->cfg_link_speed);
|
||||
initlinkmbox->mb.un.varInitLnk.lipsr_AL_PA = 0;
|
||||
initlinkmbox->vport = vport;
|
||||
rc = lpfc_sli_issue_mbox(phba, initlinkmbox,
|
||||
(MBX_NOWAIT | MBX_STOP_IOCB));
|
||||
lpfc_set_loopback_flag(phba);
|
||||
|
@ -2240,9 +2216,7 @@ lpfc_disc_timeout_handler(struct lpfc_vport *vport)
|
|||
|
||||
case LPFC_DISC_AUTH:
|
||||
/* Node Authentication timeout */
|
||||
lpfc_printf_log(phba,
|
||||
KERN_ERR,
|
||||
LOG_DISCOVERY,
|
||||
lpfc_printf_log(phba, KERN_ERR, LOG_DISCOVERY,
|
||||
"%d:0227 Node Authentication timeout\n",
|
||||
phba->brd_no);
|
||||
lpfc_disc_flush_list(vport);
|
||||
|
@ -2259,8 +2233,6 @@ lpfc_disc_timeout_handler(struct lpfc_vport *vport)
|
|||
}
|
||||
phba->link_state = LPFC_CLEAR_LA;
|
||||
lpfc_clear_la(phba, clearlambox);
|
||||
printk(KERN_ERR "%s (%d): do clear_la\n",
|
||||
__FUNCTION__, __LINE__);
|
||||
clearlambox->mbox_cmpl = lpfc_mbx_cmpl_clear_la;
|
||||
clearlambox->vport = vport;
|
||||
rc = lpfc_sli_issue_mbox(phba, clearlambox,
|
||||
|
@ -2273,9 +2245,7 @@ lpfc_disc_timeout_handler(struct lpfc_vport *vport)
|
|||
|
||||
case LPFC_VPORT_READY:
|
||||
if (vport->fc_flag & FC_RSCN_MODE) {
|
||||
lpfc_printf_log(phba,
|
||||
KERN_ERR,
|
||||
LOG_DISCOVERY,
|
||||
lpfc_printf_log(phba, KERN_ERR, LOG_DISCOVERY,
|
||||
"%d:0231 RSCN timeout Data: x%x x%x\n",
|
||||
phba->brd_no,
|
||||
vport->fc_ns_retry, LPFC_MAX_NS_RETRY);
|
||||
|
@ -2291,13 +2261,10 @@ lpfc_disc_timeout_handler(struct lpfc_vport *vport)
|
|||
case LPFC_STATE_UNKNOWN:
|
||||
case LPFC_NS_REG:
|
||||
case LPFC_BUILD_DISC_LIST:
|
||||
lpfc_printf_log(phba,
|
||||
KERN_ERR,
|
||||
LOG_DISCOVERY,
|
||||
lpfc_printf_log(phba, KERN_ERR, LOG_DISCOVERY,
|
||||
"%d:0229 Unexpected discovery timeout, vport "
|
||||
"State x%x\n",
|
||||
vport->port_state,
|
||||
phba->brd_no);
|
||||
vport->port_state, phba->brd_no);
|
||||
|
||||
break;
|
||||
}
|
||||
|
@ -2305,9 +2272,7 @@ lpfc_disc_timeout_handler(struct lpfc_vport *vport)
|
|||
switch (phba->link_state) {
|
||||
case LPFC_CLEAR_LA:
|
||||
/* CLEAR LA timeout */
|
||||
lpfc_printf_log(phba,
|
||||
KERN_ERR,
|
||||
LOG_DISCOVERY,
|
||||
lpfc_printf_log(phba, KERN_ERR, LOG_DISCOVERY,
|
||||
"%d:0228 CLEAR LA timeout\n",
|
||||
phba->brd_no);
|
||||
clrlaerr = 1;
|
||||
|
@ -2320,9 +2285,7 @@ lpfc_disc_timeout_handler(struct lpfc_vport *vport)
|
|||
case LPFC_LINK_DOWN:
|
||||
case LPFC_LINK_UP:
|
||||
case LPFC_HBA_ERROR:
|
||||
lpfc_printf_log(phba,
|
||||
KERN_ERR,
|
||||
LOG_DISCOVERY,
|
||||
lpfc_printf_log(phba, KERN_ERR, LOG_DISCOVERY,
|
||||
"%d:0230 Unexpected timeout, hba link "
|
||||
"state x%x\n",
|
||||
phba->brd_no, phba->link_state);
|
||||
|
@ -2335,8 +2298,6 @@ lpfc_disc_timeout_handler(struct lpfc_vport *vport)
|
|||
psli->ring[(psli->extra_ring)].flag &= ~LPFC_STOP_IOCB_EVENT;
|
||||
psli->ring[(psli->fcp_ring)].flag &= ~LPFC_STOP_IOCB_EVENT;
|
||||
psli->ring[(psli->next_ring)].flag &= ~LPFC_STOP_IOCB_EVENT;
|
||||
printk(KERN_ERR "%s (%d): vport ready\n",
|
||||
__FUNCTION__, __LINE__);
|
||||
vport->port_state = LPFC_VPORT_READY;
|
||||
}
|
||||
|
||||
|
|
|
@ -59,6 +59,11 @@
|
|||
#define SLI2_IOCB_CMD_R3XTRA_ENTRIES 24
|
||||
#define SLI2_IOCB_RSP_R3XTRA_ENTRIES 32
|
||||
|
||||
#define SLI2_IOCB_CMD_SIZE 32
|
||||
#define SLI2_IOCB_RSP_SIZE 32
|
||||
#define SLI3_IOCB_CMD_SIZE 128
|
||||
#define SLI3_IOCB_RSP_SIZE 64
|
||||
|
||||
/* Common Transport structures and definitions */
|
||||
|
||||
union CtRevisionId {
|
||||
|
@ -1255,6 +1260,7 @@ typedef struct { /* FireFly BIU registers */
|
|||
#define MBX_CONFIG_FARP 0x25
|
||||
#define MBX_BEACON 0x2A
|
||||
|
||||
#define MBX_CONFIG_HBQ 0x7C
|
||||
#define MBX_LOAD_AREA 0x81
|
||||
#define MBX_RUN_BIU_DIAG64 0x84
|
||||
#define MBX_CONFIG_PORT 0x88
|
||||
|
@ -1334,6 +1340,10 @@ typedef struct { /* FireFly BIU registers */
|
|||
#define CMD_FCP_TRECEIVE64_CX 0xA1
|
||||
#define CMD_FCP_TRSP64_CX 0xA3
|
||||
|
||||
#define CMD_IOCB_RCV_SEQ64_CX 0xB5
|
||||
#define CMD_IOCB_RCV_ELS64_CX 0xB7
|
||||
#define CMD_IOCB_RCV_CONT64_CX 0xBB
|
||||
|
||||
#define CMD_GEN_REQUEST64_CR 0xC2
|
||||
#define CMD_GEN_REQUEST64_CX 0xC3
|
||||
|
||||
|
@ -1560,6 +1570,7 @@ typedef struct {
|
|||
#define FLAGS_TOPOLOGY_MODE_PT_PT 0x02 /* Attempt pt-pt only */
|
||||
#define FLAGS_TOPOLOGY_MODE_LOOP 0x04 /* Attempt loop only */
|
||||
#define FLAGS_TOPOLOGY_MODE_PT_LOOP 0x06 /* Attempt pt-pt then loop */
|
||||
#define FLAGS_UNREG_LOGIN_ALL 0x08 /* UNREG_LOGIN all on link down */
|
||||
#define FLAGS_LIRP_LILP 0x80 /* LIRP / LILP is disabled */
|
||||
|
||||
#define FLAGS_TOPOLOGY_FAILOVER 0x0400 /* Bit 10 */
|
||||
|
@ -1817,6 +1828,13 @@ typedef struct {
|
|||
structure */
|
||||
struct ulp_bde64 sp64;
|
||||
} un;
|
||||
#ifdef __BIG_ENDIAN_BITFIELD
|
||||
uint16_t rsvd3;
|
||||
uint16_t vpi;
|
||||
#else /* __LITTLE_ENDIAN_BITFIELD */
|
||||
uint16_t vpi;
|
||||
uint16_t rsvd3;
|
||||
#endif
|
||||
} READ_SPARM_VAR;
|
||||
|
||||
/* Structure for MB Command READ_STATUS (14) */
|
||||
|
@ -1917,11 +1935,17 @@ typedef struct {
|
|||
#ifdef __BIG_ENDIAN_BITFIELD
|
||||
uint32_t cv:1;
|
||||
uint32_t rr:1;
|
||||
uint32_t rsvd1:29;
|
||||
uint32_t rsvd2:2;
|
||||
uint32_t v3req:1;
|
||||
uint32_t v3rsp:1;
|
||||
uint32_t rsvd1:25;
|
||||
uint32_t rv:1;
|
||||
#else /* __LITTLE_ENDIAN_BITFIELD */
|
||||
uint32_t rv:1;
|
||||
uint32_t rsvd1:29;
|
||||
uint32_t rsvd1:25;
|
||||
uint32_t v3rsp:1;
|
||||
uint32_t v3req:1;
|
||||
uint32_t rsvd2:2;
|
||||
uint32_t rr:1;
|
||||
uint32_t cv:1;
|
||||
#endif
|
||||
|
@ -1971,8 +1995,8 @@ typedef struct {
|
|||
uint8_t sli1FwName[16];
|
||||
uint32_t sli2FwRev;
|
||||
uint8_t sli2FwName[16];
|
||||
uint32_t rsvd2;
|
||||
uint32_t RandomData[7];
|
||||
uint32_t sli3Feat;
|
||||
uint32_t RandomData[6];
|
||||
} READ_REV_VAR;
|
||||
|
||||
/* Structure for MB Command READ_LINK_STAT (18) */
|
||||
|
@ -2012,6 +2036,14 @@ typedef struct {
|
|||
struct ulp_bde64 sp64;
|
||||
} un;
|
||||
|
||||
#ifdef __BIG_ENDIAN_BITFIELD
|
||||
uint16_t rsvd6;
|
||||
uint16_t vpi;
|
||||
#else /* __LITTLE_ENDIAN_BITFIELD */
|
||||
uint16_t vpi;
|
||||
uint16_t rsvd6;
|
||||
#endif
|
||||
|
||||
} REG_LOGIN_VAR;
|
||||
|
||||
/* Word 30 contents for REG_LOGIN */
|
||||
|
@ -2036,9 +2068,21 @@ typedef struct {
|
|||
#ifdef __BIG_ENDIAN_BITFIELD
|
||||
uint16_t rsvd1;
|
||||
uint16_t rpi;
|
||||
uint32_t rsvd2;
|
||||
uint32_t rsvd3;
|
||||
uint32_t rsvd4;
|
||||
uint32_t rsvd5;
|
||||
uint16_t rsvd6;
|
||||
uint16_t vpi;
|
||||
#else /* __LITTLE_ENDIAN_BITFIELD */
|
||||
uint16_t rpi;
|
||||
uint16_t rsvd1;
|
||||
uint32_t rsvd2;
|
||||
uint32_t rsvd3;
|
||||
uint32_t rsvd4;
|
||||
uint32_t rsvd5;
|
||||
uint16_t vpi;
|
||||
uint16_t rsvd6;
|
||||
#endif
|
||||
} UNREG_LOGIN_VAR;
|
||||
|
||||
|
@ -2046,6 +2090,17 @@ typedef struct {
|
|||
|
||||
typedef struct {
|
||||
uint32_t did;
|
||||
uint32_t rsvd2;
|
||||
uint32_t rsvd3;
|
||||
uint32_t rsvd4;
|
||||
uint32_t rsvd5;
|
||||
#ifdef __BIG_ENDIAN_BITFIELD
|
||||
uint16_t rsvd6;
|
||||
uint16_t vpi;
|
||||
#else
|
||||
uint16_t vpi;
|
||||
uint16_t rsvd6;
|
||||
#endif
|
||||
} UNREG_D_ID_VAR;
|
||||
|
||||
/* Structure for MB Command READ_LA (21) */
|
||||
|
@ -2177,13 +2232,240 @@ typedef struct {
|
|||
#define DMP_RSP_OFFSET 0x14 /* word 5 contains first word of rsp */
|
||||
#define DMP_RSP_SIZE 0x6C /* maximum of 27 words of rsp data */
|
||||
|
||||
struct hbq_mask {
|
||||
#ifdef __BIG_ENDIAN_BITFIELD
|
||||
uint8_t tmatch;
|
||||
uint8_t tmask;
|
||||
uint8_t rctlmatch;
|
||||
uint8_t rctlmask;
|
||||
#else /* __LITTLE_ENDIAN */
|
||||
uint8_t rctlmask;
|
||||
uint8_t rctlmatch;
|
||||
uint8_t tmask;
|
||||
uint8_t tmatch;
|
||||
#endif
|
||||
};
|
||||
|
||||
|
||||
/* Structure for MB Command CONFIG_HBQ (7c) */
|
||||
|
||||
struct config_hbq_var {
|
||||
#ifdef __BIG_ENDIAN_BITFIELD
|
||||
uint32_t rsvd1 :7;
|
||||
uint32_t recvNotify :1; /* Receive Notification */
|
||||
uint32_t numMask :8; /* # Mask Entries */
|
||||
uint32_t profile :8; /* Selection Profile */
|
||||
uint32_t rsvd2 :8;
|
||||
#else /* __LITTLE_ENDIAN */
|
||||
uint32_t rsvd2 :8;
|
||||
uint32_t profile :8; /* Selection Profile */
|
||||
uint32_t numMask :8; /* # Mask Entries */
|
||||
uint32_t recvNotify :1; /* Receive Notification */
|
||||
uint32_t rsvd1 :7;
|
||||
#endif
|
||||
|
||||
#ifdef __BIG_ENDIAN_BITFIELD
|
||||
uint32_t hbqId :16;
|
||||
uint32_t rsvd3 :12;
|
||||
uint32_t ringMask :4;
|
||||
#else /* __LITTLE_ENDIAN */
|
||||
uint32_t ringMask :4;
|
||||
uint32_t rsvd3 :12;
|
||||
uint32_t hbqId :16;
|
||||
#endif
|
||||
|
||||
#ifdef __BIG_ENDIAN_BITFIELD
|
||||
uint32_t entry_count :16;
|
||||
uint32_t rsvd4 :8;
|
||||
uint32_t headerLen :8;
|
||||
#else /* __LITTLE_ENDIAN */
|
||||
uint32_t headerLen :8;
|
||||
uint32_t rsvd4 :8;
|
||||
uint32_t entry_count :16;
|
||||
#endif
|
||||
|
||||
uint32_t hbqaddrLow;
|
||||
uint32_t hbqaddrHigh;
|
||||
|
||||
#ifdef __BIG_ENDIAN_BITFIELD
|
||||
uint32_t rsvd5 :31;
|
||||
uint32_t logEntry :1;
|
||||
#else /* __LITTLE_ENDIAN */
|
||||
uint32_t logEntry :1;
|
||||
uint32_t rsvd5 :31;
|
||||
#endif
|
||||
|
||||
uint32_t rsvd6; /* w7 */
|
||||
uint32_t rsvd7; /* w8 */
|
||||
uint32_t rsvd8; /* w9 */
|
||||
|
||||
struct hbq_mask hbqMasks[6];
|
||||
|
||||
|
||||
union {
|
||||
uint32_t allprofiles[12];
|
||||
|
||||
struct {
|
||||
#ifdef __BIG_ENDIAN_BITFIELD
|
||||
uint32_t seqlenoff :16;
|
||||
uint32_t maxlen :16;
|
||||
#else /* __LITTLE_ENDIAN */
|
||||
uint32_t maxlen :16;
|
||||
uint32_t seqlenoff :16;
|
||||
#endif
|
||||
#ifdef __BIG_ENDIAN_BITFIELD
|
||||
uint32_t rsvd1 :28;
|
||||
uint32_t seqlenbcnt :4;
|
||||
#else /* __LITTLE_ENDIAN */
|
||||
uint32_t seqlenbcnt :4;
|
||||
uint32_t rsvd1 :28;
|
||||
#endif
|
||||
uint32_t rsvd[10];
|
||||
} profile2;
|
||||
|
||||
struct {
|
||||
#ifdef __BIG_ENDIAN_BITFIELD
|
||||
uint32_t seqlenoff :16;
|
||||
uint32_t maxlen :16;
|
||||
#else /* __LITTLE_ENDIAN */
|
||||
uint32_t maxlen :16;
|
||||
uint32_t seqlenoff :16;
|
||||
#endif
|
||||
#ifdef __BIG_ENDIAN_BITFIELD
|
||||
uint32_t cmdcodeoff :28;
|
||||
uint32_t rsvd1 :12;
|
||||
uint32_t seqlenbcnt :4;
|
||||
#else /* __LITTLE_ENDIAN */
|
||||
uint32_t seqlenbcnt :4;
|
||||
uint32_t rsvd1 :12;
|
||||
uint32_t cmdcodeoff :28;
|
||||
#endif
|
||||
uint32_t cmdmatch[8];
|
||||
|
||||
uint32_t rsvd[2];
|
||||
} profile3;
|
||||
|
||||
struct {
|
||||
#ifdef __BIG_ENDIAN_BITFIELD
|
||||
uint32_t seqlenoff :16;
|
||||
uint32_t maxlen :16;
|
||||
#else /* __LITTLE_ENDIAN */
|
||||
uint32_t maxlen :16;
|
||||
uint32_t seqlenoff :16;
|
||||
#endif
|
||||
#ifdef __BIG_ENDIAN_BITFIELD
|
||||
uint32_t cmdcodeoff :28;
|
||||
uint32_t rsvd1 :12;
|
||||
uint32_t seqlenbcnt :4;
|
||||
#else /* __LITTLE_ENDIAN */
|
||||
uint32_t seqlenbcnt :4;
|
||||
uint32_t rsvd1 :12;
|
||||
uint32_t cmdcodeoff :28;
|
||||
#endif
|
||||
uint32_t cmdmatch[8];
|
||||
|
||||
uint32_t rsvd[2];
|
||||
} profile5;
|
||||
|
||||
} profiles;
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
/* Structure for MB Command CONFIG_PORT (0x88) */
|
||||
typedef struct {
|
||||
uint32_t pcbLen;
|
||||
#ifdef __BIG_ENDIAN_BITFIELD
|
||||
uint32_t cBE : 1;
|
||||
uint32_t cET : 1;
|
||||
uint32_t cHpcb : 1;
|
||||
uint32_t cMA : 1;
|
||||
uint32_t sli_mode : 4;
|
||||
uint32_t pcbLen : 24; /* bit 23:0 of memory based port
|
||||
* config block */
|
||||
#else /* __LITTLE_ENDIAN */
|
||||
uint32_t pcbLen : 24; /* bit 23:0 of memory based port
|
||||
* config block */
|
||||
uint32_t sli_mode : 4;
|
||||
uint32_t cMA : 1;
|
||||
uint32_t cHpcb : 1;
|
||||
uint32_t cET : 1;
|
||||
uint32_t cBE : 1;
|
||||
#endif
|
||||
|
||||
uint32_t pcbLow; /* bit 31:0 of memory based port config block */
|
||||
uint32_t pcbHigh; /* bit 63:32 of memory based port config block */
|
||||
uint32_t hbainit[5];
|
||||
uint32_t hbainit[6];
|
||||
|
||||
#ifdef __BIG_ENDIAN_BITFIELD
|
||||
uint32_t rsvd : 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 rsvd : 24; /* Reserved */
|
||||
#endif
|
||||
#ifdef __BIG_ENDIAN_BITFIELD
|
||||
uint32_t rsvd2 : 24; /* Reserved */
|
||||
uint32_t gmv : 1; /* Grant Max VPIs */
|
||||
uint32_t gcrp : 1; /* Grant Command Ring Polling */
|
||||
uint32_t gsah : 1; /* Grant Synchronous Abort Handling */
|
||||
uint32_t ghbs : 1; /* Grant Host Backing Store */
|
||||
uint32_t ginb : 1; /* Grant Interrupt Notification Block */
|
||||
uint32_t gerbm : 1; /* Grant ERBM Request */
|
||||
uint32_t gmx : 1; /* Grant Max XRIs */
|
||||
uint32_t gmr : 1; /* Grant Max RPIs */
|
||||
#else /* __LITTLE_ENDIAN */
|
||||
uint32_t gmr : 1; /* Grant Max RPIs */
|
||||
uint32_t gmx : 1; /* Grant Max XRIs */
|
||||
uint32_t gerbm : 1; /* Grant ERBM Request */
|
||||
uint32_t ginb : 1; /* Grant Interrupt Notification Block */
|
||||
uint32_t ghbs : 1; /* Grant Host Backing Store */
|
||||
uint32_t gsah : 1; /* Grant Synchronous Abort Handling */
|
||||
uint32_t gcrp : 1; /* Grant Command Ring Polling */
|
||||
uint32_t gmv : 1; /* Grant Max VPIs */
|
||||
uint32_t rsvd2 : 24; /* Reserved */
|
||||
#endif
|
||||
|
||||
#ifdef __BIG_ENDIAN_BITFIELD
|
||||
uint32_t max_rpi : 16; /* Max RPIs Port should configure */
|
||||
uint32_t max_xri : 16; /* Max XRIs Port should configure */
|
||||
#else /* __LITTLE_ENDIAN */
|
||||
uint32_t max_xri : 16; /* Max XRIs Port should configure */
|
||||
uint32_t max_rpi : 16; /* Max RPIs Port should configure */
|
||||
#endif
|
||||
|
||||
#ifdef __BIG_ENDIAN_BITFIELD
|
||||
uint32_t max_hbq : 16; /* Max HBQs Host expect to configure */
|
||||
uint32_t rsvd3 : 16; /* Max HBQs Host expect to configure */
|
||||
#else /* __LITTLE_ENDIAN */
|
||||
uint32_t rsvd3 : 16; /* Max HBQs Host expect to configure */
|
||||
uint32_t max_hbq : 16; /* Max HBQs Host expect to configure */
|
||||
#endif
|
||||
|
||||
uint32_t rsvd4; /* Reserved */
|
||||
|
||||
#ifdef __BIG_ENDIAN_BITFIELD
|
||||
uint32_t rsvd5 : 16; /* Reserved */
|
||||
uint32_t max_vpi : 16; /* Max number of virt N-Ports */
|
||||
#else /* __LITTLE_ENDIAN */
|
||||
uint32_t max_vpi : 16; /* Max number of virt N-Ports */
|
||||
uint32_t rsvd5 : 16; /* Reserved */
|
||||
#endif
|
||||
|
||||
} CONFIG_PORT_VAR;
|
||||
|
||||
/* SLI-2 Port Control Block */
|
||||
|
@ -2261,33 +2543,38 @@ typedef struct {
|
|||
#define MAILBOX_CMD_SIZE (MAILBOX_CMD_WSIZE * sizeof(uint32_t))
|
||||
|
||||
typedef union {
|
||||
uint32_t varWords[MAILBOX_CMD_WSIZE - 1];
|
||||
LOAD_SM_VAR varLdSM; /* cmd = 1 (LOAD_SM) */
|
||||
READ_NV_VAR varRDnvp; /* cmd = 2 (READ_NVPARMS) */
|
||||
WRITE_NV_VAR varWTnvp; /* cmd = 3 (WRITE_NVPARMS) */
|
||||
uint32_t varWords[MAILBOX_CMD_WSIZE - 1]; /* first word is type/
|
||||
* feature/max ring number
|
||||
*/
|
||||
LOAD_SM_VAR varLdSM; /* cmd = 1 (LOAD_SM) */
|
||||
READ_NV_VAR varRDnvp; /* cmd = 2 (READ_NVPARMS) */
|
||||
WRITE_NV_VAR varWTnvp; /* cmd = 3 (WRITE_NVPARMS) */
|
||||
BIU_DIAG_VAR varBIUdiag; /* cmd = 4 (RUN_BIU_DIAG) */
|
||||
INIT_LINK_VAR varInitLnk; /* cmd = 5 (INIT_LINK) */
|
||||
DOWN_LINK_VAR varDwnLnk; /* cmd = 6 (DOWN_LINK) */
|
||||
CONFIG_LINK varCfgLnk; /* cmd = 7 (CONFIG_LINK) */
|
||||
PART_SLIM_VAR varSlim; /* cmd = 8 (PART_SLIM) */
|
||||
CONFIG_LINK varCfgLnk; /* cmd = 7 (CONFIG_LINK) */
|
||||
PART_SLIM_VAR varSlim; /* cmd = 8 (PART_SLIM) */
|
||||
CONFIG_RING_VAR varCfgRing; /* cmd = 9 (CONFIG_RING) */
|
||||
RESET_RING_VAR varRstRing; /* cmd = 10 (RESET_RING) */
|
||||
READ_CONFIG_VAR varRdConfig; /* cmd = 11 (READ_CONFIG) */
|
||||
READ_RCONF_VAR varRdRConfig; /* cmd = 12 (READ_RCONFIG) */
|
||||
READ_SPARM_VAR varRdSparm; /* cmd = 13 (READ_SPARM(64)) */
|
||||
READ_STATUS_VAR varRdStatus; /* cmd = 14 (READ_STATUS) */
|
||||
READ_RPI_VAR varRdRPI; /* cmd = 15 (READ_RPI(64)) */
|
||||
READ_XRI_VAR varRdXRI; /* cmd = 16 (READ_XRI) */
|
||||
READ_REV_VAR varRdRev; /* cmd = 17 (READ_REV) */
|
||||
READ_LNK_VAR varRdLnk; /* cmd = 18 (READ_LNK_STAT) */
|
||||
READ_RPI_VAR varRdRPI; /* cmd = 15 (READ_RPI(64)) */
|
||||
READ_XRI_VAR varRdXRI; /* cmd = 16 (READ_XRI) */
|
||||
READ_REV_VAR varRdRev; /* cmd = 17 (READ_REV) */
|
||||
READ_LNK_VAR varRdLnk; /* cmd = 18 (READ_LNK_STAT) */
|
||||
REG_LOGIN_VAR varRegLogin; /* cmd = 19 (REG_LOGIN(64)) */
|
||||
UNREG_LOGIN_VAR varUnregLogin; /* cmd = 20 (UNREG_LOGIN) */
|
||||
READ_LA_VAR varReadLA; /* cmd = 21 (READ_LA(64)) */
|
||||
READ_LA_VAR varReadLA; /* cmd = 21 (READ_LA(64)) */
|
||||
CLEAR_LA_VAR varClearLA; /* cmd = 22 (CLEAR_LA) */
|
||||
DUMP_VAR varDmp; /* Warm Start DUMP mbx cmd */
|
||||
UNREG_D_ID_VAR varUnregDID; /* cmd = 0x23 (UNREG_D_ID) */
|
||||
CONFIG_FARP_VAR varCfgFarp; /* cmd = 0x25 (CONFIG_FARP) NEW_FEATURE */
|
||||
CONFIG_PORT_VAR varCfgPort; /* cmd = 0x88 (CONFIG_PORT) */
|
||||
DUMP_VAR varDmp; /* Warm Start DUMP mbx cmd */
|
||||
UNREG_D_ID_VAR varUnregDID; /* cmd = 0x23 (UNREG_D_ID) */
|
||||
CONFIG_FARP_VAR varCfgFarp; /* cmd = 0x25 (CONFIG_FARP)
|
||||
* NEW_FEATURE
|
||||
*/
|
||||
struct config_hbq_var varCfgHbq;/* cmd = 0x7c (CONFIG_HBQ) */
|
||||
CONFIG_PORT_VAR varCfgPort; /* cmd = 0x88 (CONFIG_PORT) */
|
||||
} MAILVARIANTS;
|
||||
|
||||
/*
|
||||
|
@ -2304,16 +2591,30 @@ struct lpfc_pgp {
|
|||
__le32 rspPutInx;
|
||||
};
|
||||
|
||||
typedef struct _SLI2_DESC {
|
||||
struct lpfc_hgp host[MAX_RINGS];
|
||||
struct sli2_desc {
|
||||
uint32_t unused1[16];
|
||||
struct lpfc_hgp host[MAX_RINGS];
|
||||
struct lpfc_pgp port[MAX_RINGS];
|
||||
} SLI2_DESC;
|
||||
};
|
||||
|
||||
struct sli3_desc {
|
||||
struct lpfc_hgp host[MAX_RINGS];
|
||||
uint32_t reserved[8];
|
||||
uint32_t hbq_put[16];
|
||||
};
|
||||
|
||||
struct sli3_pgp {
|
||||
struct lpfc_pgp port[MAX_RINGS];
|
||||
uint32_t hbq_get[16];
|
||||
};
|
||||
|
||||
typedef union {
|
||||
SLI2_DESC s2;
|
||||
struct sli2_desc s2;
|
||||
struct sli3_desc s3;
|
||||
struct sli3_pgp s3_pgp;
|
||||
} SLI_VAR;
|
||||
|
||||
|
||||
typedef struct {
|
||||
#ifdef __BIG_ENDIAN_BITFIELD
|
||||
uint16_t mbxStatus;
|
||||
|
@ -2617,6 +2918,23 @@ typedef struct {
|
|||
uint32_t fcpt_Length; /* transfer ready for IWRITE */
|
||||
} FCPT_FIELDS64;
|
||||
|
||||
/* IOCB Command template for CMD_IOCB_RCV_ELS64_CX (0xB7)
|
||||
or CMD_IOCB_RCV_SEQ64_CX (0xB5) */
|
||||
|
||||
struct rcv_sli3 {
|
||||
uint32_t word8Rsvd;
|
||||
#ifdef __BIG_ENDIAN_BITFIELD
|
||||
uint16_t vpi;
|
||||
uint16_t word9Rsvd;
|
||||
#else /* __LITTLE_ENDIAN */
|
||||
uint16_t word9Rsvd;
|
||||
uint16_t vpi;
|
||||
#endif
|
||||
uint32_t word10Rsvd;
|
||||
uint32_t acc_len; /* accumulated length */
|
||||
struct ulp_bde64 bde2;
|
||||
};
|
||||
|
||||
typedef struct _IOCB { /* IOCB structure */
|
||||
union {
|
||||
GENERIC_RSP grsp; /* Generic response */
|
||||
|
@ -2631,8 +2949,8 @@ typedef struct _IOCB { /* IOCB structure */
|
|||
|
||||
/* SLI-2 structures */
|
||||
|
||||
struct ulp_bde64 cont64[2]; /* up to 2 64 bit continuation
|
||||
bde_64s */
|
||||
struct ulp_bde64 cont64[2]; /* up to 2 64 bit continuation
|
||||
* bde_64s */
|
||||
ELS_REQUEST64 elsreq64; /* ELS_REQUEST template */
|
||||
GEN_REQUEST64 genreq64; /* GEN_REQUEST template */
|
||||
RCV_ELS_REQ64 rcvels64; /* RCV_ELS_REQ template */
|
||||
|
@ -2693,7 +3011,16 @@ typedef struct _IOCB { /* IOCB structure */
|
|||
uint32_t ulpXS:1;
|
||||
uint32_t ulpTimeout:8;
|
||||
#endif
|
||||
union {
|
||||
struct rcv_sli3 rcvsli3; /* words 8 - 15 */
|
||||
uint32_t sli3Words[24]; /* 96 extra bytes for SLI-3 */
|
||||
} unsli3;
|
||||
|
||||
#define ulpCt_h ulpXS
|
||||
#define ulpCt_l ulpFCP2Rcvy
|
||||
|
||||
#define IOCB_FCP 1 /* IOCB is used for FCP ELS cmds-ulpRsvByte */
|
||||
#define IOCB_IP 2 /* IOCB is used for IP ELS cmds */
|
||||
#define PARM_UNUSED 0 /* PU field (Word 4) not used */
|
||||
#define PARM_REL_OFF 1 /* PU field (Word 4) = R. O. */
|
||||
#define PARM_READ_CHECK 2 /* PU field (Word 4) = Data Transfer Length */
|
||||
|
@ -2724,21 +3051,33 @@ typedef struct _IOCB { /* IOCB structure */
|
|||
|
||||
} IOCB_t;
|
||||
|
||||
/* Structure used for a single HBQ entry */
|
||||
struct lpfc_hbq_entry {
|
||||
struct ulp_bde64 bde;
|
||||
uint32_t buffer_tag;
|
||||
};
|
||||
|
||||
|
||||
#define SLI1_SLIM_SIZE (4 * 1024)
|
||||
|
||||
/* Up to 498 IOCBs will fit into 16k
|
||||
* 256 (MAILBOX_t) + 140 (PCB_t) + ( 32 (IOCB_t) * 498 ) = < 16384
|
||||
*/
|
||||
#define SLI2_SLIM_SIZE (16 * 1024)
|
||||
#define SLI2_SLIM_SIZE (64 * 1024)
|
||||
|
||||
/* Maximum IOCBs that will fit in SLI2 slim */
|
||||
#define MAX_SLI2_IOCB 498
|
||||
#define MAX_SLIM_IOCB_SIZE (SLI2_SLIM_SIZE - \
|
||||
(sizeof(MAILBOX_t) + sizeof(PCB_t)))
|
||||
|
||||
/* HBQ entries are 4 words each = 4k */
|
||||
#define LPFC_TOTAL_HBQ_SIZE (sizeof(struct lpfc_hbq_entry) * \
|
||||
lpfc_sli_hbq_count())
|
||||
|
||||
struct lpfc_sli2_slim {
|
||||
MAILBOX_t mbx;
|
||||
PCB_t pcb;
|
||||
IOCB_t IOCBs[MAX_SLI2_IOCB];
|
||||
IOCB_t IOCBs[MAX_SLIM_IOCB_SIZE];
|
||||
};
|
||||
|
||||
/*
|
||||
|
|
|
@ -49,6 +49,12 @@ static int lpfc_post_rcv_buf(struct lpfc_hba *);
|
|||
static struct scsi_transport_template *lpfc_transport_template = NULL;
|
||||
static DEFINE_IDR(lpfc_hba_index);
|
||||
|
||||
int lpfc_sli_mode = 0;
|
||||
module_param(lpfc_sli_mode, int, 0);
|
||||
MODULE_PARM_DESC(lpfc_sli_mode, "SLI mode selector:"
|
||||
" 0 - auto (SLI-3 if supported),"
|
||||
" 2 - select SLI-2 even on SLI-3 capable HBAs,"
|
||||
" 3 - select SLI-3");
|
||||
|
||||
|
||||
/************************************************************************/
|
||||
|
@ -102,9 +108,7 @@ lpfc_config_port_prep(struct lpfc_hba *phba)
|
|||
rc = lpfc_sli_issue_mbox(phba, pmb, MBX_POLL);
|
||||
|
||||
if (rc != MBX_SUCCESS) {
|
||||
lpfc_printf_log(phba,
|
||||
KERN_ERR,
|
||||
LOG_MBOX,
|
||||
lpfc_printf_log(phba, KERN_ERR, LOG_MBOX,
|
||||
"%d:0324 Config Port initialization "
|
||||
"error, mbxCmd x%x READ_NVPARM, "
|
||||
"mbxStatus x%x\n",
|
||||
|
@ -123,9 +127,7 @@ lpfc_config_port_prep(struct lpfc_hba *phba)
|
|||
lpfc_read_rev(phba, pmb);
|
||||
rc = lpfc_sli_issue_mbox(phba, pmb, MBX_POLL);
|
||||
if (rc != MBX_SUCCESS) {
|
||||
lpfc_printf_log(phba,
|
||||
KERN_ERR,
|
||||
LOG_INIT,
|
||||
lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
|
||||
"%d:0439 Adapter failed to init, mbxCmd x%x "
|
||||
"READ_REV, mbxStatus x%x\n",
|
||||
phba->brd_no,
|
||||
|
@ -148,6 +150,9 @@ lpfc_config_port_prep(struct lpfc_hba *phba)
|
|||
return -ERESTART;
|
||||
}
|
||||
|
||||
if (phba->sli_rev == 3 && !mb->un.varRdRev.v3rsp)
|
||||
return -EINVAL;
|
||||
|
||||
/* Save information as VPD data */
|
||||
vp->rev.rBit = 1;
|
||||
vp->rev.sli1FwRev = mb->un.varRdRev.sli1FwRev;
|
||||
|
@ -236,10 +241,9 @@ lpfc_config_port_post(struct lpfc_hba *phba)
|
|||
|
||||
/* Get login parameters for NID. */
|
||||
lpfc_read_sparam(phba, pmb);
|
||||
pmb->vport = vport;
|
||||
if (lpfc_sli_issue_mbox(phba, pmb, MBX_POLL) != MBX_SUCCESS) {
|
||||
lpfc_printf_log(phba,
|
||||
KERN_ERR,
|
||||
LOG_INIT,
|
||||
lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
|
||||
"%d:0448 Adapter failed init, mbxCmd x%x "
|
||||
"READ_SPARM mbxStatus x%x\n",
|
||||
phba->brd_no,
|
||||
|
@ -296,10 +300,9 @@ lpfc_config_port_post(struct lpfc_hba *phba)
|
|||
}
|
||||
|
||||
lpfc_read_config(phba, pmb);
|
||||
pmb->vport = vport;
|
||||
if (lpfc_sli_issue_mbox(phba, pmb, MBX_POLL) != MBX_SUCCESS) {
|
||||
lpfc_printf_log(phba,
|
||||
KERN_ERR,
|
||||
LOG_INIT,
|
||||
lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
|
||||
"%d:0453 Adapter failed to init, mbxCmd x%x "
|
||||
"READ_CONFIG, mbxStatus x%x\n",
|
||||
phba->brd_no,
|
||||
|
@ -331,9 +334,7 @@ lpfc_config_port_post(struct lpfc_hba *phba)
|
|||
|| ((phba->cfg_link_speed == LINK_SPEED_10G)
|
||||
&& !(phba->lmt & LMT_10Gb))) {
|
||||
/* Reset link speed to auto */
|
||||
lpfc_printf_log(phba,
|
||||
KERN_WARNING,
|
||||
LOG_LINK_EVENT,
|
||||
lpfc_printf_log(phba, KERN_WARNING, LOG_LINK_EVENT,
|
||||
"%d:1302 Invalid speed for this board: "
|
||||
"Reset link speed to auto: x%x\n",
|
||||
phba->brd_no,
|
||||
|
@ -352,7 +353,8 @@ lpfc_config_port_post(struct lpfc_hba *phba)
|
|||
psli->ring[psli->next_ring].flag |= LPFC_STOP_IOCB_EVENT;
|
||||
|
||||
/* Post receive buffers for desired rings */
|
||||
lpfc_post_rcv_buf(phba);
|
||||
if (phba->sli_rev != 3)
|
||||
lpfc_post_rcv_buf(phba);
|
||||
|
||||
/* Enable appropriate host interrupts */
|
||||
spin_lock_irq(&phba->hbalock);
|
||||
|
@ -383,12 +385,11 @@ lpfc_config_port_post(struct lpfc_hba *phba)
|
|||
|
||||
lpfc_init_link(phba, pmb, phba->cfg_topology, phba->cfg_link_speed);
|
||||
pmb->mbox_cmpl = lpfc_sli_def_mbox_cmpl;
|
||||
pmb->vport = vport;
|
||||
rc = lpfc_sli_issue_mbox(phba, pmb, MBX_NOWAIT);
|
||||
lpfc_set_loopback_flag(phba);
|
||||
if (rc != MBX_SUCCESS) {
|
||||
lpfc_printf_log(phba,
|
||||
KERN_ERR,
|
||||
LOG_INIT,
|
||||
lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
|
||||
"%d:0454 Adapter failed to init, mbxCmd x%x "
|
||||
"INIT_LINK, mbxStatus x%x\n",
|
||||
phba->brd_no,
|
||||
|
@ -630,9 +631,7 @@ lpfc_handle_latt(struct lpfc_hba *phba)
|
|||
|
||||
/* The other case is an error from issue_mbox */
|
||||
if (rc == -ENOMEM)
|
||||
lpfc_printf_log(phba,
|
||||
KERN_WARNING,
|
||||
LOG_MBOX,
|
||||
lpfc_printf_log(phba, KERN_WARNING, LOG_MBOX,
|
||||
"%d:0300 READ_LA: no buffers\n",
|
||||
phba->brd_no);
|
||||
|
||||
|
@ -658,9 +657,7 @@ lpfc_parse_vpd(struct lpfc_hba *phba, uint8_t *vpd, int len)
|
|||
return 0;
|
||||
|
||||
/* Vital Product */
|
||||
lpfc_printf_log(phba,
|
||||
KERN_INFO,
|
||||
LOG_INIT,
|
||||
lpfc_printf_log(phba, KERN_INFO, LOG_INIT,
|
||||
"%d:0455 Vital Product Data: x%x x%x x%x x%x\n",
|
||||
phba->brd_no,
|
||||
(uint32_t) vpd[0], (uint32_t) vpd[1], (uint32_t) vpd[2],
|
||||
|
@ -1221,9 +1218,7 @@ lpfc_online(struct lpfc_hba *phba)
|
|||
if (!(vport->fc_flag & FC_OFFLINE_MODE))
|
||||
return 0;
|
||||
|
||||
lpfc_printf_log(phba,
|
||||
KERN_WARNING,
|
||||
LOG_INIT,
|
||||
lpfc_printf_log(phba, KERN_WARNING, LOG_INIT,
|
||||
"%d:0458 Bring Adapter online\n",
|
||||
phba->brd_no);
|
||||
|
||||
|
@ -1633,13 +1628,22 @@ lpfc_pci_probe_one(struct pci_dev *pdev, const struct pci_device_id *pid)
|
|||
|
||||
memset(phba->slim2p, 0, SLI2_SLIM_SIZE);
|
||||
|
||||
phba->hbqslimp.virt = dma_alloc_coherent(&phba->pcidev->dev,
|
||||
lpfc_sli_hbq_size(),
|
||||
&phba->hbqslimp.phys,
|
||||
GFP_KERNEL);
|
||||
if (!phba->hbqslimp.virt)
|
||||
goto out_free_slim;
|
||||
|
||||
memset(phba->hbqslimp.virt, 0, lpfc_sli_hbq_size());
|
||||
|
||||
/* Initialize the SLI Layer to run with lpfc HBAs. */
|
||||
lpfc_sli_setup(phba);
|
||||
lpfc_sli_queue_setup(phba);
|
||||
|
||||
error = lpfc_mem_alloc(phba);
|
||||
if (error)
|
||||
goto out_free_slim;
|
||||
goto out_free_hbqslimp;
|
||||
|
||||
/* Initialize and populate the iocb list per host. */
|
||||
INIT_LIST_HEAD(&phba->lpfc_iocb_list);
|
||||
|
@ -1753,6 +1757,9 @@ lpfc_pci_probe_one(struct pci_dev *pdev, const struct pci_device_id *pid)
|
|||
phba->total_iocbq_bufs--;
|
||||
}
|
||||
lpfc_mem_free(phba);
|
||||
out_free_hbqslimp:
|
||||
dma_free_coherent(&pdev->dev, lpfc_sli_hbq_size(), phba->hbqslimp.virt,
|
||||
phba->hbqslimp.phys);
|
||||
out_free_slim:
|
||||
dma_free_coherent(&pdev->dev, SLI2_SLIM_SIZE, phba->slim2p,
|
||||
phba->slim2p_mapping);
|
||||
|
@ -1811,6 +1818,9 @@ lpfc_pci_remove_one(struct pci_dev *pdev)
|
|||
lpfc_scsi_free(phba);
|
||||
lpfc_mem_free(phba);
|
||||
|
||||
dma_free_coherent(&pdev->dev, lpfc_sli_hbq_size(), phba->hbqslimp.virt,
|
||||
phba->hbqslimp.phys);
|
||||
|
||||
/* Free resources associated with SLI2 interface */
|
||||
dma_free_coherent(&pdev->dev, SLI2_SLIM_SIZE,
|
||||
phba->slim2p, phba->slim2p_mapping);
|
||||
|
|
|
@ -232,6 +232,7 @@ lpfc_init_link(struct lpfc_hba * phba,
|
|||
mb->mbxCommand = (volatile uint8_t)MBX_INIT_LINK;
|
||||
mb->mbxOwner = OWN_HOST;
|
||||
mb->un.varInitLnk.fabric_AL_PA = phba->fc_pref_ALPA;
|
||||
mb->un.varInitLnk.link_flags |= FLAGS_UNREG_LOGIN_ALL;
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -418,6 +419,10 @@ lpfc_config_pcb_setup(struct lpfc_hba * phba)
|
|||
for (i = 0; i < psli->num_rings; i++) {
|
||||
pring = &psli->ring[i];
|
||||
|
||||
pring->sizeCiocb = phba->sli_rev == 3 ? SLI3_IOCB_CMD_SIZE:
|
||||
SLI2_IOCB_CMD_SIZE;
|
||||
pring->sizeRiocb = phba->sli_rev == 3 ? SLI3_IOCB_RSP_SIZE:
|
||||
SLI2_IOCB_RSP_SIZE;
|
||||
/* A ring MUST have both cmd and rsp entries defined to be
|
||||
valid */
|
||||
if ((pring->numCiocb == 0) || (pring->numRiocb == 0)) {
|
||||
|
@ -432,8 +437,7 @@ lpfc_config_pcb_setup(struct lpfc_hba * phba)
|
|||
continue;
|
||||
}
|
||||
/* 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;
|
||||
|
||||
offset = (uint8_t *)&phba->slim2p->IOCBs[iocbCnt] -
|
||||
|
@ -444,8 +448,7 @@ lpfc_config_pcb_setup(struct lpfc_hba * phba)
|
|||
iocbCnt += pring->numCiocb;
|
||||
|
||||
/* 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;
|
||||
offset = (uint8_t *)&phba->slim2p->IOCBs[iocbCnt] -
|
||||
|
@ -463,11 +466,103 @@ lpfc_read_rev(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb)
|
|||
MAILBOX_t *mb = &pmb->mb;
|
||||
memset(pmb, 0, sizeof (LPFC_MBOXQ_t));
|
||||
mb->un.varRdRev.cv = 1;
|
||||
mb->un.varRdRev.v3req = 1; /* Request SLI3 info */
|
||||
mb->mbxCommand = MBX_READ_REV;
|
||||
mb->mbxOwner = OWN_HOST;
|
||||
return;
|
||||
}
|
||||
|
||||
static void
|
||||
lpfc_build_hbq_profile2(struct config_hbq_var *hbqmb,
|
||||
struct lpfc_hbq_init *hbq_desc)
|
||||
{
|
||||
hbqmb->profiles.profile2.seqlenbcnt = hbq_desc->seqlenbcnt;
|
||||
hbqmb->profiles.profile2.maxlen = hbq_desc->maxlen;
|
||||
hbqmb->profiles.profile2.seqlenoff = hbq_desc->seqlenoff;
|
||||
}
|
||||
|
||||
static void
|
||||
lpfc_build_hbq_profile3(struct config_hbq_var *hbqmb,
|
||||
struct lpfc_hbq_init *hbq_desc)
|
||||
{
|
||||
hbqmb->profiles.profile3.seqlenbcnt = hbq_desc->seqlenbcnt;
|
||||
hbqmb->profiles.profile3.maxlen = hbq_desc->maxlen;
|
||||
hbqmb->profiles.profile3.cmdcodeoff = hbq_desc->cmdcodeoff;
|
||||
hbqmb->profiles.profile3.seqlenoff = hbq_desc->seqlenoff;
|
||||
memcpy(&hbqmb->profiles.profile3.cmdmatch, hbq_desc->cmdmatch,
|
||||
sizeof(hbqmb->profiles.profile3.cmdmatch));
|
||||
}
|
||||
|
||||
static void
|
||||
lpfc_build_hbq_profile5(struct config_hbq_var *hbqmb,
|
||||
struct lpfc_hbq_init *hbq_desc)
|
||||
{
|
||||
hbqmb->profiles.profile5.seqlenbcnt = hbq_desc->seqlenbcnt;
|
||||
hbqmb->profiles.profile5.maxlen = hbq_desc->maxlen;
|
||||
hbqmb->profiles.profile5.cmdcodeoff = hbq_desc->cmdcodeoff;
|
||||
hbqmb->profiles.profile5.seqlenoff = hbq_desc->seqlenoff;
|
||||
memcpy(&hbqmb->profiles.profile5.cmdmatch, hbq_desc->cmdmatch,
|
||||
sizeof(hbqmb->profiles.profile5.cmdmatch));
|
||||
}
|
||||
|
||||
void
|
||||
lpfc_config_hbq(struct lpfc_hba *phba, struct lpfc_hbq_init *hbq_desc,
|
||||
uint32_t hbq_entry_index, LPFC_MBOXQ_t *pmb)
|
||||
{
|
||||
int i;
|
||||
MAILBOX_t *mb = &pmb->mb;
|
||||
struct config_hbq_var *hbqmb = &mb->un.varCfgHbq;
|
||||
|
||||
memset(pmb, 0, sizeof (LPFC_MBOXQ_t));
|
||||
hbqmb->entry_count = hbq_desc->entry_count; /* # entries in HBQ */
|
||||
hbqmb->recvNotify = hbq_desc->rn; /* Receive
|
||||
* Notification */
|
||||
hbqmb->numMask = hbq_desc->mask_count; /* # R_CTL/TYPE masks
|
||||
* # in words 0-19 */
|
||||
hbqmb->profile = hbq_desc->profile; /* Selection profile:
|
||||
* 0 = all,
|
||||
* 7 = logentry */
|
||||
hbqmb->ringMask = hbq_desc->ring_mask; /* Binds HBQ to a ring
|
||||
* e.g. Ring0=b0001,
|
||||
* ring2=b0100 */
|
||||
hbqmb->headerLen = hbq_desc->headerLen; /* 0 if not profile 4
|
||||
* or 5 */
|
||||
hbqmb->logEntry = hbq_desc->logEntry; /* Set to 1 if this
|
||||
* HBQ will be used
|
||||
* for LogEntry
|
||||
* buffers */
|
||||
hbqmb->hbqaddrLow = putPaddrLow(phba->hbqslimp.phys) +
|
||||
hbq_entry_index * sizeof(struct lpfc_hbq_entry);
|
||||
hbqmb->hbqaddrHigh = putPaddrHigh(phba->hbqslimp.phys);
|
||||
|
||||
mb->mbxCommand = MBX_CONFIG_HBQ;
|
||||
mb->mbxOwner = OWN_HOST;
|
||||
|
||||
/* Copy info for profiles 2,3,5. Other
|
||||
* profiles this area is reserved
|
||||
*/
|
||||
if (hbq_desc->profile == 2)
|
||||
lpfc_build_hbq_profile2(hbqmb, hbq_desc);
|
||||
else if (hbq_desc->profile == 3)
|
||||
lpfc_build_hbq_profile3(hbqmb, hbq_desc);
|
||||
else if (hbq_desc->profile == 5)
|
||||
lpfc_build_hbq_profile5(hbqmb, hbq_desc);
|
||||
|
||||
/* Return if no rctl / type masks for this HBQ */
|
||||
if (!hbq_desc->mask_count)
|
||||
return;
|
||||
|
||||
/* Otherwise we setup specific rctl / type masks for this HBQ */
|
||||
for (i = 0; i < hbq_desc->mask_count; i++) {
|
||||
hbqmb->hbqMasks[i].tmatch = hbq_desc->hbqMasks[i].tmatch;
|
||||
hbqmb->hbqMasks[i].tmask = hbq_desc->hbqMasks[i].tmask;
|
||||
hbqmb->hbqMasks[i].rctlmatch = hbq_desc->hbqMasks[i].rctlmatch;
|
||||
hbqmb->hbqMasks[i].rctlmask = hbq_desc->hbqMasks[i].rctlmask;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
void
|
||||
lpfc_config_ring(struct lpfc_hba * phba, int ring, LPFC_MBOXQ_t * pmb)
|
||||
{
|
||||
|
@ -512,13 +607,14 @@ lpfc_config_ring(struct lpfc_hba * phba, int ring, LPFC_MBOXQ_t * pmb)
|
|||
void
|
||||
lpfc_config_port(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb)
|
||||
{
|
||||
MAILBOX_t __iomem *mb_slim = (MAILBOX_t __iomem *) phba->MBslimaddr;
|
||||
MAILBOX_t *mb = &pmb->mb;
|
||||
dma_addr_t pdma_addr;
|
||||
uint32_t bar_low, bar_high;
|
||||
size_t offset;
|
||||
struct lpfc_hgp hgp;
|
||||
void __iomem *to_slim;
|
||||
int i;
|
||||
uint32_t pgp_offset;
|
||||
|
||||
memset(pmb, 0, sizeof(LPFC_MBOXQ_t));
|
||||
mb->mbxCommand = MBX_CONFIG_PORT;
|
||||
|
@ -531,12 +627,21 @@ lpfc_config_port(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb)
|
|||
mb->un.varCfgPort.pcbLow = putPaddrLow(pdma_addr);
|
||||
mb->un.varCfgPort.pcbHigh = putPaddrHigh(pdma_addr);
|
||||
|
||||
/* If HBA supports SLI=3 ask for it */
|
||||
|
||||
mb->un.varCfgPort.sli_mode = phba->sli_rev;
|
||||
if (phba->sli_rev == 3) {
|
||||
mb->un.varCfgPort.cerbm = 1; /* Request HBQs */
|
||||
mb->un.varCfgPort.max_hbq = 1; /* Requesting 2 HBQs */
|
||||
}
|
||||
|
||||
/* Now setup pcb */
|
||||
phba->slim2p->pcb.type = TYPE_NATIVE_SLI2;
|
||||
phba->slim2p->pcb.feature = FEATURE_INITIAL_SLI2;
|
||||
|
||||
/* Setup Mailbox pointers */
|
||||
phba->slim2p->pcb.mailBoxSize = sizeof(MAILBOX_t);
|
||||
phba->slim2p->pcb.mailBoxSize = offsetof(MAILBOX_t, us) +
|
||||
sizeof(struct sli2_desc);
|
||||
offset = (uint8_t *)&phba->slim2p->mbx - (uint8_t *)phba->slim2p;
|
||||
pdma_addr = phba->slim2p_mapping + offset;
|
||||
phba->slim2p->pcb.mbAddrHigh = putPaddrHigh(pdma_addr);
|
||||
|
@ -564,29 +669,70 @@ lpfc_config_port(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb)
|
|||
pci_read_config_dword(phba->pcidev, PCI_BASE_ADDRESS_0, &bar_low);
|
||||
pci_read_config_dword(phba->pcidev, PCI_BASE_ADDRESS_1, &bar_high);
|
||||
|
||||
/*
|
||||
* Set up HGP - Port Memory
|
||||
*
|
||||
* The port expects the host get/put pointers to reside in memory
|
||||
* following the "non-diagnostic" mode mailbox (32 words, 0x80 bytes)
|
||||
* area of SLIM. In SLI-2 mode, there's an additional 16 reserved
|
||||
* words (0x40 bytes). This area is not reserved if HBQs are
|
||||
* configured in SLI-3.
|
||||
*
|
||||
* CR0Put - SLI2(no HBQs) = 0xc0, With HBQs = 0x80
|
||||
* RR0Get 0xc4 0x84
|
||||
* CR1Put 0xc8 0x88
|
||||
* RR1Get 0xcc 0x8c
|
||||
* CR2Put 0xd0 0x90
|
||||
* RR2Get 0xd4 0x94
|
||||
* CR3Put 0xd8 0x98
|
||||
* RR3Get 0xdc 0x9c
|
||||
*
|
||||
* Reserved 0xa0-0xbf
|
||||
* If HBQs configured:
|
||||
* HBQ 0 Put ptr 0xc0
|
||||
* HBQ 1 Put ptr 0xc4
|
||||
* HBQ 2 Put ptr 0xc8
|
||||
* ......
|
||||
* HBQ(M-1)Put Pointer 0xc0+(M-1)*4
|
||||
*
|
||||
*/
|
||||
|
||||
if (phba->sli_rev == 3) {
|
||||
phba->host_gp = &mb_slim->us.s3.host[0];
|
||||
phba->hbq_put = &mb_slim->us.s3.hbq_put[0];
|
||||
} else {
|
||||
phba->host_gp = &mb_slim->us.s2.host[0];
|
||||
phba->hbq_put = NULL;
|
||||
}
|
||||
|
||||
/* mask off BAR0's flag bits 0 - 3 */
|
||||
phba->slim2p->pcb.hgpAddrLow = (bar_low & PCI_BASE_ADDRESS_MEM_MASK) +
|
||||
(SLIMOFF*sizeof(uint32_t));
|
||||
(void __iomem *) phba->host_gp -
|
||||
(void __iomem *)phba->MBslimaddr;
|
||||
if (bar_low & PCI_BASE_ADDRESS_MEM_TYPE_64)
|
||||
phba->slim2p->pcb.hgpAddrHigh = bar_high;
|
||||
else
|
||||
phba->slim2p->pcb.hgpAddrHigh = 0;
|
||||
/* write HGP data to SLIM at the required longword offset */
|
||||
memset(&hgp, 0, sizeof(struct lpfc_hgp));
|
||||
to_slim = phba->MBslimaddr + (SLIMOFF*sizeof (uint32_t));
|
||||
|
||||
for (i=0; i < phba->sli.num_rings; i++) {
|
||||
lpfc_memcpy_to_slim(to_slim, &hgp, sizeof(struct lpfc_hgp));
|
||||
to_slim += sizeof (struct lpfc_hgp);
|
||||
lpfc_memcpy_to_slim(phba->host_gp + i, &hgp,
|
||||
sizeof(*phba->host_gp));
|
||||
}
|
||||
|
||||
/* Setup Port Group ring pointer */
|
||||
offset = (uint8_t *)&phba->slim2p->mbx.us.s2.port -
|
||||
(uint8_t *)phba->slim2p;
|
||||
pdma_addr = phba->slim2p_mapping + offset;
|
||||
if (phba->sli_rev == 3)
|
||||
pgp_offset = (uint8_t *)&phba->slim2p->mbx.us.s3_pgp.port -
|
||||
(uint8_t *)phba->slim2p;
|
||||
else
|
||||
pgp_offset = (uint8_t *)&phba->slim2p->mbx.us.s2.port -
|
||||
(uint8_t *)phba->slim2p;
|
||||
|
||||
pdma_addr = phba->slim2p_mapping + pgp_offset;
|
||||
phba->slim2p->pcb.pgpAddrHigh = putPaddrHigh(pdma_addr);
|
||||
phba->slim2p->pcb.pgpAddrLow = putPaddrLow(pdma_addr);
|
||||
phba->hbq_get = &phba->slim2p->mbx.us.s3_pgp.hbq_get[0];
|
||||
|
||||
/* Use callback routine to setp rings in the pcb */
|
||||
lpfc_config_pcb_setup(phba);
|
||||
|
@ -603,10 +749,6 @@ lpfc_config_port(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb)
|
|||
/* Swap PCB if needed */
|
||||
lpfc_sli_pcimem_bcopy(&phba->slim2p->pcb, &phba->slim2p->pcb,
|
||||
sizeof (PCB_t));
|
||||
|
||||
lpfc_printf_log(phba, KERN_INFO, LOG_INIT,
|
||||
"%d:0405 Service Level Interface (SLI) 2 selected\n",
|
||||
phba->brd_no);
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
@ -82,8 +82,16 @@ lpfc_mem_alloc(struct lpfc_hba * phba)
|
|||
if (!phba->nlp_mem_pool)
|
||||
goto fail_free_mbox_pool;
|
||||
|
||||
phba->lpfc_hbq_pool = pci_pool_create("lpfc_hbq_pool",phba->pcidev,
|
||||
LPFC_BPL_SIZE, 8, 0);
|
||||
if (!phba->lpfc_hbq_pool)
|
||||
goto fail_free_nlp_mem_pool;
|
||||
|
||||
return 0;
|
||||
|
||||
fail_free_nlp_mem_pool:
|
||||
mempool_destroy(phba->nlp_mem_pool);
|
||||
phba->nlp_mem_pool = NULL;
|
||||
fail_free_mbox_pool:
|
||||
mempool_destroy(phba->mbox_mem_pool);
|
||||
phba->mbox_mem_pool = NULL;
|
||||
|
@ -111,6 +119,8 @@ lpfc_mem_free(struct lpfc_hba * phba)
|
|||
struct lpfc_dmabuf *mp;
|
||||
int i;
|
||||
|
||||
lpfc_sli_hbqbuf_free_all(phba);
|
||||
|
||||
spin_lock_irq(&phba->hbalock);
|
||||
list_for_each_entry_safe(mbox, next_mbox, &psli->mboxq, list) {
|
||||
mp = (struct lpfc_dmabuf *) (mbox->context1);
|
||||
|
@ -140,12 +150,14 @@ lpfc_mem_free(struct lpfc_hba * phba)
|
|||
pool->elements[i].phys);
|
||||
kfree(pool->elements);
|
||||
|
||||
pci_pool_destroy(phba->lpfc_hbq_pool);
|
||||
mempool_destroy(phba->nlp_mem_pool);
|
||||
mempool_destroy(phba->mbox_mem_pool);
|
||||
|
||||
pci_pool_destroy(phba->lpfc_scsi_dma_buf_pool);
|
||||
pci_pool_destroy(phba->lpfc_mbuf_pool);
|
||||
|
||||
phba->lpfc_hbq_pool = NULL;
|
||||
phba->nlp_mem_pool = NULL;
|
||||
phba->mbox_mem_pool = NULL;
|
||||
phba->lpfc_scsi_dma_buf_pool = NULL;
|
||||
|
@ -201,3 +213,20 @@ lpfc_mbuf_free(struct lpfc_hba * phba, void *virt, dma_addr_t dma)
|
|||
spin_unlock_irqrestore(&phba->hbalock, iflags);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
void *
|
||||
lpfc_hbq_alloc(struct lpfc_hba *phba, int mem_flags, dma_addr_t *handle)
|
||||
{
|
||||
void *ret;
|
||||
ret = pci_pool_alloc(phba->lpfc_hbq_pool, GFP_ATOMIC, handle);
|
||||
return ret;
|
||||
}
|
||||
|
||||
void
|
||||
lpfc_hbq_free(struct lpfc_hba *phba, void *virt, dma_addr_t dma)
|
||||
{
|
||||
pci_pool_free(phba->lpfc_hbq_pool, virt, dma);
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
@ -255,9 +255,8 @@ lpfc_rcv_plogi(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
|
|||
/* Start discovery - this should just do
|
||||
CLEAR_LA */
|
||||
lpfc_disc_start(vport);
|
||||
} else {
|
||||
} else
|
||||
lpfc_initial_flogi(vport);
|
||||
}
|
||||
} else {
|
||||
stat.un.b.lsRjtRsnCode = LSRJT_LOGICAL_BSY;
|
||||
stat.un.b.lsRjtRsnCodeExp = LSEXP_NOTHING_MORE;
|
||||
|
@ -279,19 +278,16 @@ lpfc_rcv_plogi(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
|
|||
icmd = &cmdiocb->iocb;
|
||||
|
||||
/* PLOGI chkparm OK */
|
||||
lpfc_printf_log(phba,
|
||||
KERN_INFO,
|
||||
LOG_ELS,
|
||||
lpfc_printf_log(phba, KERN_INFO, LOG_ELS,
|
||||
"%d:0114 PLOGI chkparm OK Data: x%x x%x x%x x%x\n",
|
||||
phba->brd_no,
|
||||
ndlp->nlp_DID, ndlp->nlp_state, ndlp->nlp_flag,
|
||||
ndlp->nlp_rpi);
|
||||
|
||||
if (phba->cfg_fcp_class == 2 && sp->cls2.classValid) {
|
||||
if (phba->cfg_fcp_class == 2 && sp->cls2.classValid)
|
||||
ndlp->nlp_fcp_info |= CLASS2;
|
||||
} else {
|
||||
else
|
||||
ndlp->nlp_fcp_info |= CLASS3;
|
||||
}
|
||||
|
||||
ndlp->nlp_class_sup = 0;
|
||||
if (sp->cls1.classValid)
|
||||
|
@ -327,6 +323,7 @@ lpfc_rcv_plogi(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
|
|||
goto out;
|
||||
lpfc_config_link(phba, mbox);
|
||||
mbox->mbox_cmpl = lpfc_sli_def_mbox_cmpl;
|
||||
mbox->vport = vport;
|
||||
rc = lpfc_sli_issue_mbox
|
||||
(phba, mbox, (MBX_NOWAIT | MBX_STOP_IOCB));
|
||||
if (rc == MBX_NOT_FINISHED) {
|
||||
|
@ -544,9 +541,7 @@ static uint32_t
|
|||
lpfc_disc_illegal(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
|
||||
void *arg, uint32_t evt)
|
||||
{
|
||||
lpfc_printf_log(vport->phba,
|
||||
KERN_ERR,
|
||||
LOG_DISCOVERY,
|
||||
lpfc_printf_log(vport->phba, KERN_ERR, LOG_DISCOVERY,
|
||||
"%d:0253 Illegal State Transition: node x%x event x%x, "
|
||||
"state x%x Data: x%x x%x\n",
|
||||
vport->phba->brd_no,
|
||||
|
@ -728,9 +723,7 @@ lpfc_cmpl_plogi_plogi_issue(struct lpfc_vport *vport,
|
|||
goto out;
|
||||
|
||||
/* PLOGI chkparm OK */
|
||||
lpfc_printf_log(phba,
|
||||
KERN_INFO,
|
||||
LOG_ELS,
|
||||
lpfc_printf_log(phba, KERN_INFO, LOG_ELS,
|
||||
"%d:0121 PLOGI chkparm OK "
|
||||
"Data: x%x x%x x%x x%x\n",
|
||||
phba->brd_no,
|
||||
|
@ -1105,9 +1098,7 @@ lpfc_cmpl_reglogin_reglogin_issue(struct lpfc_vport *vport,
|
|||
|
||||
if (mb->mbxStatus) {
|
||||
/* RegLogin failed */
|
||||
lpfc_printf_log(phba,
|
||||
KERN_ERR,
|
||||
LOG_DISCOVERY,
|
||||
lpfc_printf_log(phba, KERN_ERR, LOG_DISCOVERY,
|
||||
"%d:0246 RegLogin failed Data: x%x x%x x%x\n",
|
||||
phba->brd_no,
|
||||
did, mb->mbxStatus, vport->port_state);
|
||||
|
@ -1470,15 +1461,12 @@ static uint32_t
|
|||
lpfc_rcv_prlo_mapped_node(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
|
||||
void *arg, uint32_t evt)
|
||||
{
|
||||
struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
|
||||
struct lpfc_hba *phba = vport->phba;
|
||||
struct lpfc_iocbq *cmdiocb = (struct lpfc_iocbq *) arg;
|
||||
|
||||
/* flush the target */
|
||||
spin_lock_irq(shost->host_lock);
|
||||
lpfc_sli_abort_iocb(phba, &phba->sli.ring[phba->sli.fcp_ring],
|
||||
ndlp->nlp_sid, 0, 0, LPFC_CTX_TGT);
|
||||
spin_unlock_irq(shost->host_lock);
|
||||
|
||||
/* Treat like rcv logo */
|
||||
lpfc_rcv_logo(vport, ndlp, cmdiocb, ELS_CMD_PRLO);
|
||||
|
@ -1926,9 +1914,7 @@ lpfc_disc_state_machine(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
|
|||
cur_state = ndlp->nlp_state;
|
||||
|
||||
/* DSM in event <evt> on NPort <nlp_DID> in state <cur_state> */
|
||||
lpfc_printf_log(phba,
|
||||
KERN_INFO,
|
||||
LOG_DISCOVERY,
|
||||
lpfc_printf_log(phba, KERN_INFO, LOG_DISCOVERY,
|
||||
"%d:0211 DSM in event x%x on NPort x%x in state %d "
|
||||
"Data: x%x\n",
|
||||
phba->brd_no,
|
||||
|
@ -1938,9 +1924,7 @@ lpfc_disc_state_machine(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
|
|||
rc = (func) (vport, ndlp, arg, evt);
|
||||
|
||||
/* DSM out state <rc> on NPort <nlp_DID> */
|
||||
lpfc_printf_log(phba,
|
||||
KERN_INFO,
|
||||
LOG_DISCOVERY,
|
||||
lpfc_printf_log(phba, KERN_INFO, LOG_DISCOVERY,
|
||||
"%d:0212 DSM out state %d on NPort x%x Data: x%x\n",
|
||||
phba->brd_no,
|
||||
rc, ndlp->nlp_DID, ndlp->nlp_flag);
|
||||
|
|
|
@ -840,7 +840,7 @@ lpfc_queuecommand(struct scsi_cmnd *cmnd, void (*done) (struct scsi_cmnd *))
|
|||
cmnd->result = ScsiResult(DID_BUS_BUSY, 0);
|
||||
goto out_fail_command;
|
||||
}
|
||||
lpfc_cmd = lpfc_get_scsi_buf (phba);
|
||||
lpfc_cmd = lpfc_get_scsi_buf(phba);
|
||||
if (lpfc_cmd == NULL) {
|
||||
lpfc_printf_log(phba, KERN_INFO, LOG_FCP,
|
||||
"%d:0707 driver's buffer pool is empty, "
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -138,6 +138,8 @@ struct lpfc_sli_ring {
|
|||
uint8_t ringno; /* ring number */
|
||||
uint16_t numCiocb; /* number of command iocb's per ring */
|
||||
uint16_t numRiocb; /* number of rsp iocb's per ring */
|
||||
uint16_t sizeCiocb; /* Size of command iocb's in this ring */
|
||||
uint16_t sizeRiocb; /* Size of response iocb's in this ring */
|
||||
|
||||
uint32_t fast_iotag; /* max fastlookup based iotag */
|
||||
uint32_t iotag_ctr; /* keeps track of the next iotag to use */
|
||||
|
@ -168,6 +170,29 @@ struct lpfc_sli_ring {
|
|||
struct lpfc_sli_ring *);
|
||||
};
|
||||
|
||||
/* Structure used for configuring rings to a specific profile or rctl / type */
|
||||
struct lpfc_hbq_init {
|
||||
uint32_t rn; /* Receive buffer notification */
|
||||
uint32_t entry_count; /* # of entries in HBQ */
|
||||
uint32_t headerLen; /* 0 if not profile 4 or 5 */
|
||||
uint32_t logEntry; /* Set to 1 if this HBQ used for LogEntry */
|
||||
uint32_t profile; /* Selection profile 0=all, 7=logentry */
|
||||
uint32_t ring_mask; /* Binds HBQ to a ring e.g. Ring0=b0001,
|
||||
* ring2=b0100 */
|
||||
uint32_t hbq_index; /* index of this hbq in ring .HBQs[] */
|
||||
|
||||
uint32_t seqlenoff;
|
||||
uint32_t maxlen;
|
||||
uint32_t seqlenbcnt;
|
||||
uint32_t cmdcodeoff;
|
||||
uint32_t cmdmatch[8];
|
||||
uint32_t mask_count; /* number of mask entries in prt array */
|
||||
struct hbq_mask hbqMasks[6];
|
||||
} ;
|
||||
|
||||
#define LPFC_MAX_HBQ 16
|
||||
|
||||
|
||||
/* Structure used to hold SLI statistical counters and info */
|
||||
struct lpfc_sli_stat {
|
||||
uint64_t mbox_stat_err; /* Mbox cmds completed status error */
|
||||
|
|
|
@ -18,7 +18,7 @@
|
|||
* included with this package. *
|
||||
*******************************************************************/
|
||||
|
||||
#define LPFC_DRIVER_VERSION "8.1.12_psplit"
|
||||
#define LPFC_DRIVER_VERSION "8.1.12_sli3"
|
||||
|
||||
#define LPFC_DRIVER_NAME "lpfc"
|
||||
|
||||
|
|
Loading…
Reference in New Issue