diff options
-rw-r--r-- | drivers/scsi/lpfc/lpfc_attr.c | 47 | ||||
-rw-r--r-- | drivers/scsi/lpfc/lpfc_crtn.h | 1 | ||||
-rw-r--r-- | drivers/scsi/lpfc/lpfc_els.c | 6 | ||||
-rw-r--r-- | drivers/scsi/lpfc/lpfc_hbadisc.c | 22 | ||||
-rw-r--r-- | drivers/scsi/lpfc/lpfc_init.c | 22 | ||||
-rw-r--r-- | drivers/scsi/lpfc/lpfc_mbox.c | 632 | ||||
-rw-r--r-- | drivers/scsi/lpfc/lpfc_nportdisc.c | 13 | ||||
-rw-r--r-- | drivers/scsi/lpfc/lpfc_sli.c | 505 |
8 files changed, 1101 insertions, 147 deletions
diff --git a/drivers/scsi/lpfc/lpfc_attr.c b/drivers/scsi/lpfc/lpfc_attr.c index 82016fc672b1..463104d96867 100644 --- a/drivers/scsi/lpfc/lpfc_attr.c +++ b/drivers/scsi/lpfc/lpfc_attr.c | |||
@@ -507,12 +507,14 @@ lpfc_issue_lip(struct Scsi_Host *shost) | |||
507 | return -ENOMEM; | 507 | return -ENOMEM; |
508 | 508 | ||
509 | memset((void *)pmboxq, 0, sizeof (LPFC_MBOXQ_t)); | 509 | memset((void *)pmboxq, 0, sizeof (LPFC_MBOXQ_t)); |
510 | pmboxq->mb.mbxCommand = MBX_DOWN_LINK; | 510 | pmboxq->u.mb.mbxCommand = MBX_DOWN_LINK; |
511 | pmboxq->mb.mbxOwner = OWN_HOST; | 511 | pmboxq->u.mb.mbxOwner = OWN_HOST; |
512 | 512 | ||
513 | mbxstatus = lpfc_sli_issue_mbox_wait(phba, pmboxq, LPFC_MBOX_TMO * 2); | 513 | mbxstatus = lpfc_sli_issue_mbox_wait(phba, pmboxq, LPFC_MBOX_TMO * 2); |
514 | 514 | ||
515 | if ((mbxstatus == MBX_SUCCESS) && (pmboxq->mb.mbxStatus == 0)) { | 515 | if ((mbxstatus == MBX_SUCCESS) && |
516 | (pmboxq->u.mb.mbxStatus == 0 || | ||
517 | pmboxq->u.mb.mbxStatus == MBXERR_LINK_DOWN)) { | ||
516 | memset((void *)pmboxq, 0, sizeof (LPFC_MBOXQ_t)); | 518 | memset((void *)pmboxq, 0, sizeof (LPFC_MBOXQ_t)); |
517 | lpfc_init_link(phba, pmboxq, phba->cfg_topology, | 519 | lpfc_init_link(phba, pmboxq, phba->cfg_topology, |
518 | phba->cfg_link_speed); | 520 | phba->cfg_link_speed); |
@@ -791,7 +793,8 @@ lpfc_get_hba_info(struct lpfc_hba *phba, | |||
791 | uint32_t *mrpi, uint32_t *arpi, | 793 | uint32_t *mrpi, uint32_t *arpi, |
792 | uint32_t *mvpi, uint32_t *avpi) | 794 | uint32_t *mvpi, uint32_t *avpi) |
793 | { | 795 | { |
794 | struct lpfc_sli *psli = &phba->sli; | 796 | struct lpfc_sli *psli = &phba->sli; |
797 | struct lpfc_mbx_read_config *rd_config; | ||
795 | LPFC_MBOXQ_t *pmboxq; | 798 | LPFC_MBOXQ_t *pmboxq; |
796 | MAILBOX_t *pmb; | 799 | MAILBOX_t *pmb; |
797 | int rc = 0; | 800 | int rc = 0; |
@@ -813,7 +816,7 @@ lpfc_get_hba_info(struct lpfc_hba *phba, | |||
813 | return 0; | 816 | return 0; |
814 | memset(pmboxq, 0, sizeof (LPFC_MBOXQ_t)); | 817 | memset(pmboxq, 0, sizeof (LPFC_MBOXQ_t)); |
815 | 818 | ||
816 | pmb = &pmboxq->mb; | 819 | pmb = &pmboxq->u.mb; |
817 | pmb->mbxCommand = MBX_READ_CONFIG; | 820 | pmb->mbxCommand = MBX_READ_CONFIG; |
818 | pmb->mbxOwner = OWN_HOST; | 821 | pmb->mbxOwner = OWN_HOST; |
819 | pmboxq->context1 = NULL; | 822 | pmboxq->context1 = NULL; |
@@ -3247,7 +3250,7 @@ sysfs_mbox_write(struct kobject *kobj, struct bin_attribute *bin_attr, | |||
3247 | } | 3250 | } |
3248 | } | 3251 | } |
3249 | 3252 | ||
3250 | memcpy((uint8_t *) & phba->sysfs_mbox.mbox->mb + off, | 3253 | memcpy((uint8_t *) &phba->sysfs_mbox.mbox->u.mb + off, |
3251 | buf, count); | 3254 | buf, count); |
3252 | 3255 | ||
3253 | phba->sysfs_mbox.offset = off + count; | 3256 | phba->sysfs_mbox.offset = off + count; |
@@ -3289,6 +3292,7 @@ sysfs_mbox_read(struct kobject *kobj, struct bin_attribute *bin_attr, | |||
3289 | struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata; | 3292 | struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata; |
3290 | struct lpfc_hba *phba = vport->phba; | 3293 | struct lpfc_hba *phba = vport->phba; |
3291 | int rc; | 3294 | int rc; |
3295 | MAILBOX_t *pmb; | ||
3292 | 3296 | ||
3293 | if (off > MAILBOX_CMD_SIZE) | 3297 | if (off > MAILBOX_CMD_SIZE) |
3294 | return -ERANGE; | 3298 | return -ERANGE; |
@@ -3313,8 +3317,8 @@ sysfs_mbox_read(struct kobject *kobj, struct bin_attribute *bin_attr, | |||
3313 | if (off == 0 && | 3317 | if (off == 0 && |
3314 | phba->sysfs_mbox.state == SMBOX_WRITING && | 3318 | phba->sysfs_mbox.state == SMBOX_WRITING && |
3315 | phba->sysfs_mbox.offset >= 2 * sizeof(uint32_t)) { | 3319 | phba->sysfs_mbox.offset >= 2 * sizeof(uint32_t)) { |
3316 | 3320 | pmb = &phba->sysfs_mbox.mbox->u.mb; | |
3317 | switch (phba->sysfs_mbox.mbox->mb.mbxCommand) { | 3321 | switch (pmb->mbxCommand) { |
3318 | /* Offline only */ | 3322 | /* Offline only */ |
3319 | case MBX_INIT_LINK: | 3323 | case MBX_INIT_LINK: |
3320 | case MBX_DOWN_LINK: | 3324 | case MBX_DOWN_LINK: |
@@ -3331,7 +3335,7 @@ sysfs_mbox_read(struct kobject *kobj, struct bin_attribute *bin_attr, | |||
3331 | if (!(vport->fc_flag & FC_OFFLINE_MODE)) { | 3335 | if (!(vport->fc_flag & FC_OFFLINE_MODE)) { |
3332 | printk(KERN_WARNING "mbox_read:Command 0x%x " | 3336 | printk(KERN_WARNING "mbox_read:Command 0x%x " |
3333 | "is illegal in on-line state\n", | 3337 | "is illegal in on-line state\n", |
3334 | phba->sysfs_mbox.mbox->mb.mbxCommand); | 3338 | pmb->mbxCommand); |
3335 | sysfs_mbox_idle(phba); | 3339 | sysfs_mbox_idle(phba); |
3336 | spin_unlock_irq(&phba->hbalock); | 3340 | spin_unlock_irq(&phba->hbalock); |
3337 | return -EPERM; | 3341 | return -EPERM; |
@@ -3367,13 +3371,13 @@ sysfs_mbox_read(struct kobject *kobj, struct bin_attribute *bin_attr, | |||
3367 | case MBX_CONFIG_PORT: | 3371 | case MBX_CONFIG_PORT: |
3368 | case MBX_RUN_BIU_DIAG: | 3372 | case MBX_RUN_BIU_DIAG: |
3369 | printk(KERN_WARNING "mbox_read: Illegal Command 0x%x\n", | 3373 | printk(KERN_WARNING "mbox_read: Illegal Command 0x%x\n", |
3370 | phba->sysfs_mbox.mbox->mb.mbxCommand); | 3374 | pmb->mbxCommand); |
3371 | sysfs_mbox_idle(phba); | 3375 | sysfs_mbox_idle(phba); |
3372 | spin_unlock_irq(&phba->hbalock); | 3376 | spin_unlock_irq(&phba->hbalock); |
3373 | return -EPERM; | 3377 | return -EPERM; |
3374 | default: | 3378 | default: |
3375 | printk(KERN_WARNING "mbox_read: Unknown Command 0x%x\n", | 3379 | printk(KERN_WARNING "mbox_read: Unknown Command 0x%x\n", |
3376 | phba->sysfs_mbox.mbox->mb.mbxCommand); | 3380 | pmb->mbxCommand); |
3377 | sysfs_mbox_idle(phba); | 3381 | sysfs_mbox_idle(phba); |
3378 | spin_unlock_irq(&phba->hbalock); | 3382 | spin_unlock_irq(&phba->hbalock); |
3379 | return -EPERM; | 3383 | return -EPERM; |
@@ -3383,14 +3387,14 @@ sysfs_mbox_read(struct kobject *kobj, struct bin_attribute *bin_attr, | |||
3383 | * or RESTART mailbox commands until the HBA is restarted. | 3387 | * or RESTART mailbox commands until the HBA is restarted. |
3384 | */ | 3388 | */ |
3385 | if (phba->pport->stopped && | 3389 | if (phba->pport->stopped && |
3386 | phba->sysfs_mbox.mbox->mb.mbxCommand != MBX_DUMP_MEMORY && | 3390 | pmb->mbxCommand != MBX_DUMP_MEMORY && |
3387 | phba->sysfs_mbox.mbox->mb.mbxCommand != MBX_RESTART && | 3391 | pmb->mbxCommand != MBX_RESTART && |
3388 | phba->sysfs_mbox.mbox->mb.mbxCommand != MBX_WRITE_VPARMS && | 3392 | pmb->mbxCommand != MBX_WRITE_VPARMS && |
3389 | phba->sysfs_mbox.mbox->mb.mbxCommand != MBX_WRITE_WWN) | 3393 | pmb->mbxCommand != MBX_WRITE_WWN) |
3390 | lpfc_printf_log(phba, KERN_WARNING, LOG_MBOX, | 3394 | lpfc_printf_log(phba, KERN_WARNING, LOG_MBOX, |
3391 | "1259 mbox: Issued mailbox cmd " | 3395 | "1259 mbox: Issued mailbox cmd " |
3392 | "0x%x while in stopped state.\n", | 3396 | "0x%x while in stopped state.\n", |
3393 | phba->sysfs_mbox.mbox->mb.mbxCommand); | 3397 | pmb->mbxCommand); |
3394 | 3398 | ||
3395 | phba->sysfs_mbox.mbox->vport = vport; | 3399 | phba->sysfs_mbox.mbox->vport = vport; |
3396 | 3400 | ||
@@ -3416,8 +3420,7 @@ sysfs_mbox_read(struct kobject *kobj, struct bin_attribute *bin_attr, | |||
3416 | spin_unlock_irq(&phba->hbalock); | 3420 | spin_unlock_irq(&phba->hbalock); |
3417 | rc = lpfc_sli_issue_mbox_wait (phba, | 3421 | rc = lpfc_sli_issue_mbox_wait (phba, |
3418 | phba->sysfs_mbox.mbox, | 3422 | phba->sysfs_mbox.mbox, |
3419 | lpfc_mbox_tmo_val(phba, | 3423 | lpfc_mbox_tmo_val(phba, pmb->mbxCommand) * HZ); |
3420 | phba->sysfs_mbox.mbox->mb.mbxCommand) * HZ); | ||
3421 | spin_lock_irq(&phba->hbalock); | 3424 | spin_lock_irq(&phba->hbalock); |
3422 | } | 3425 | } |
3423 | 3426 | ||
@@ -3439,7 +3442,7 @@ sysfs_mbox_read(struct kobject *kobj, struct bin_attribute *bin_attr, | |||
3439 | return -EAGAIN; | 3442 | return -EAGAIN; |
3440 | } | 3443 | } |
3441 | 3444 | ||
3442 | memcpy(buf, (uint8_t *) & phba->sysfs_mbox.mbox->mb + off, count); | 3445 | memcpy(buf, (uint8_t *) &pmb + off, count); |
3443 | 3446 | ||
3444 | phba->sysfs_mbox.offset = off + count; | 3447 | phba->sysfs_mbox.offset = off + count; |
3445 | 3448 | ||
@@ -3711,14 +3714,14 @@ lpfc_get_stats(struct Scsi_Host *shost) | |||
3711 | return NULL; | 3714 | return NULL; |
3712 | memset(pmboxq, 0, sizeof (LPFC_MBOXQ_t)); | 3715 | memset(pmboxq, 0, sizeof (LPFC_MBOXQ_t)); |
3713 | 3716 | ||
3714 | pmb = &pmboxq->mb; | 3717 | pmb = &pmboxq->u.mb; |
3715 | pmb->mbxCommand = MBX_READ_STATUS; | 3718 | pmb->mbxCommand = MBX_READ_STATUS; |
3716 | pmb->mbxOwner = OWN_HOST; | 3719 | pmb->mbxOwner = OWN_HOST; |
3717 | pmboxq->context1 = NULL; | 3720 | pmboxq->context1 = NULL; |
3718 | pmboxq->vport = vport; | 3721 | pmboxq->vport = vport; |
3719 | 3722 | ||
3720 | if ((vport->fc_flag & FC_OFFLINE_MODE) || | 3723 | if ((vport->fc_flag & FC_OFFLINE_MODE) || |
3721 | (!(psli->sli_flag & LPFC_SLI2_ACTIVE))) | 3724 | (!(psli->sli_flag & LPFC_SLI_ACTIVE))) |
3722 | rc = lpfc_sli_issue_mbox(phba, pmboxq, MBX_POLL); | 3725 | rc = lpfc_sli_issue_mbox(phba, pmboxq, MBX_POLL); |
3723 | else | 3726 | else |
3724 | rc = lpfc_sli_issue_mbox_wait(phba, pmboxq, phba->fc_ratov * 2); | 3727 | rc = lpfc_sli_issue_mbox_wait(phba, pmboxq, phba->fc_ratov * 2); |
@@ -3817,7 +3820,7 @@ lpfc_reset_stats(struct Scsi_Host *shost) | |||
3817 | return; | 3820 | return; |
3818 | memset(pmboxq, 0, sizeof(LPFC_MBOXQ_t)); | 3821 | memset(pmboxq, 0, sizeof(LPFC_MBOXQ_t)); |
3819 | 3822 | ||
3820 | pmb = &pmboxq->mb; | 3823 | pmb = &pmboxq->u.mb; |
3821 | pmb->mbxCommand = MBX_READ_STATUS; | 3824 | pmb->mbxCommand = MBX_READ_STATUS; |
3822 | pmb->mbxOwner = OWN_HOST; | 3825 | pmb->mbxOwner = OWN_HOST; |
3823 | pmb->un.varWords[0] = 0x1; /* reset request */ | 3826 | pmb->un.varWords[0] = 0x1; /* reset request */ |
diff --git a/drivers/scsi/lpfc/lpfc_crtn.h b/drivers/scsi/lpfc/lpfc_crtn.h index 3802e455734f..e0f1cd4b3d3d 100644 --- a/drivers/scsi/lpfc/lpfc_crtn.h +++ b/drivers/scsi/lpfc/lpfc_crtn.h | |||
@@ -209,6 +209,7 @@ void lpfc_sli_release_iocbq(struct lpfc_hba *, struct lpfc_iocbq *); | |||
209 | uint16_t lpfc_sli_next_iotag(struct lpfc_hba *, struct lpfc_iocbq *); | 209 | uint16_t lpfc_sli_next_iotag(struct lpfc_hba *, struct lpfc_iocbq *); |
210 | void lpfc_sli_cancel_iocbs(struct lpfc_hba *, struct list_head *, uint32_t, | 210 | void lpfc_sli_cancel_iocbs(struct lpfc_hba *, struct list_head *, uint32_t, |
211 | uint32_t); | 211 | uint32_t); |
212 | void lpfc_sli_wake_mbox_wait(struct lpfc_hba *, LPFC_MBOXQ_t *); | ||
212 | 213 | ||
213 | void lpfc_reset_barrier(struct lpfc_hba * phba); | 214 | void lpfc_reset_barrier(struct lpfc_hba * phba); |
214 | int lpfc_sli_brdready(struct lpfc_hba *, uint32_t); | 215 | int lpfc_sli_brdready(struct lpfc_hba *, uint32_t); |
diff --git a/drivers/scsi/lpfc/lpfc_els.c b/drivers/scsi/lpfc/lpfc_els.c index 9fe36bf6fd14..2c034a554c88 100644 --- a/drivers/scsi/lpfc/lpfc_els.c +++ b/drivers/scsi/lpfc/lpfc_els.c | |||
@@ -4277,7 +4277,7 @@ lpfc_els_rcv_flogi(struct lpfc_vport *vport, struct lpfc_iocbq *cmdiocb, | |||
4277 | lpfc_init_link(phba, mbox, | 4277 | lpfc_init_link(phba, mbox, |
4278 | phba->cfg_topology, | 4278 | phba->cfg_topology, |
4279 | phba->cfg_link_speed); | 4279 | phba->cfg_link_speed); |
4280 | mbox->mb.un.varInitLnk.lipsr_AL_PA = 0; | 4280 | mbox->u.mb.un.varInitLnk.lipsr_AL_PA = 0; |
4281 | mbox->mbox_cmpl = lpfc_sli_def_mbox_cmpl; | 4281 | mbox->mbox_cmpl = lpfc_sli_def_mbox_cmpl; |
4282 | mbox->vport = vport; | 4282 | mbox->vport = vport; |
4283 | rc = lpfc_sli_issue_mbox(phba, mbox, MBX_NOWAIT); | 4283 | rc = lpfc_sli_issue_mbox(phba, mbox, MBX_NOWAIT); |
@@ -4426,7 +4426,7 @@ lpfc_els_rsp_rps_acc(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb) | |||
4426 | uint16_t xri, status; | 4426 | uint16_t xri, status; |
4427 | uint32_t cmdsize; | 4427 | uint32_t cmdsize; |
4428 | 4428 | ||
4429 | mb = &pmb->mb; | 4429 | mb = &pmb->u.mb; |
4430 | 4430 | ||
4431 | ndlp = (struct lpfc_nodelist *) pmb->context2; | 4431 | ndlp = (struct lpfc_nodelist *) pmb->context2; |
4432 | xri = (uint16_t) ((unsigned long)(pmb->context1)); | 4432 | xri = (uint16_t) ((unsigned long)(pmb->context1)); |
@@ -5755,7 +5755,7 @@ lpfc_cmpl_reg_new_vport(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb) | |||
5755 | struct lpfc_vport *vport = pmb->vport; | 5755 | struct lpfc_vport *vport = pmb->vport; |
5756 | struct Scsi_Host *shost = lpfc_shost_from_vport(vport); | 5756 | struct Scsi_Host *shost = lpfc_shost_from_vport(vport); |
5757 | struct lpfc_nodelist *ndlp = (struct lpfc_nodelist *) pmb->context2; | 5757 | struct lpfc_nodelist *ndlp = (struct lpfc_nodelist *) pmb->context2; |
5758 | MAILBOX_t *mb = &pmb->mb; | 5758 | MAILBOX_t *mb = &pmb->u.mb; |
5759 | 5759 | ||
5760 | spin_lock_irq(shost->host_lock); | 5760 | spin_lock_irq(shost->host_lock); |
5761 | vport->fc_flag &= ~FC_VPORT_NEEDS_REG_VPI; | 5761 | vport->fc_flag &= ~FC_VPORT_NEEDS_REG_VPI; |
diff --git a/drivers/scsi/lpfc/lpfc_hbadisc.c b/drivers/scsi/lpfc/lpfc_hbadisc.c index 0fc66005d545..2270d9a7c8e3 100644 --- a/drivers/scsi/lpfc/lpfc_hbadisc.c +++ b/drivers/scsi/lpfc/lpfc_hbadisc.c | |||
@@ -879,7 +879,7 @@ lpfc_mbx_cmpl_clear_la(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb) | |||
879 | struct lpfc_vport *vport = pmb->vport; | 879 | struct lpfc_vport *vport = pmb->vport; |
880 | struct Scsi_Host *shost = lpfc_shost_from_vport(vport); | 880 | struct Scsi_Host *shost = lpfc_shost_from_vport(vport); |
881 | struct lpfc_sli *psli = &phba->sli; | 881 | struct lpfc_sli *psli = &phba->sli; |
882 | MAILBOX_t *mb = &pmb->mb; | 882 | MAILBOX_t *mb = &pmb->u.mb; |
883 | uint32_t control; | 883 | uint32_t control; |
884 | 884 | ||
885 | /* Since we don't do discovery right now, turn these off here */ | 885 | /* Since we don't do discovery right now, turn these off here */ |
@@ -942,7 +942,7 @@ lpfc_mbx_cmpl_local_config_link(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb) | |||
942 | { | 942 | { |
943 | struct lpfc_vport *vport = pmb->vport; | 943 | struct lpfc_vport *vport = pmb->vport; |
944 | 944 | ||
945 | if (pmb->mb.mbxStatus) | 945 | if (pmb->u.mb.mbxStatus) |
946 | goto out; | 946 | goto out; |
947 | 947 | ||
948 | mempool_free(pmb, phba->mbox_mem_pool); | 948 | mempool_free(pmb, phba->mbox_mem_pool); |
@@ -970,7 +970,7 @@ out: | |||
970 | lpfc_printf_vlog(vport, KERN_ERR, LOG_MBOX, | 970 | lpfc_printf_vlog(vport, KERN_ERR, LOG_MBOX, |
971 | "0306 CONFIG_LINK mbxStatus error x%x " | 971 | "0306 CONFIG_LINK mbxStatus error x%x " |
972 | "HBA state x%x\n", | 972 | "HBA state x%x\n", |
973 | pmb->mb.mbxStatus, vport->port_state); | 973 | pmb->u.mb.mbxStatus, vport->port_state); |
974 | mempool_free(pmb, phba->mbox_mem_pool); | 974 | mempool_free(pmb, phba->mbox_mem_pool); |
975 | 975 | ||
976 | lpfc_linkdown(phba); | 976 | lpfc_linkdown(phba); |
@@ -1202,7 +1202,7 @@ lpfc_mbx_cmpl_read_la(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb) | |||
1202 | struct lpfc_vport *vport = pmb->vport; | 1202 | struct lpfc_vport *vport = pmb->vport; |
1203 | struct Scsi_Host *shost = lpfc_shost_from_vport(vport); | 1203 | struct Scsi_Host *shost = lpfc_shost_from_vport(vport); |
1204 | READ_LA_VAR *la; | 1204 | READ_LA_VAR *la; |
1205 | MAILBOX_t *mb = &pmb->mb; | 1205 | MAILBOX_t *mb = &pmb->u.mb; |
1206 | struct lpfc_dmabuf *mp = (struct lpfc_dmabuf *) (pmb->context1); | 1206 | struct lpfc_dmabuf *mp = (struct lpfc_dmabuf *) (pmb->context1); |
1207 | 1207 | ||
1208 | /* Unblock ELS traffic */ | 1208 | /* Unblock ELS traffic */ |
@@ -1217,7 +1217,7 @@ lpfc_mbx_cmpl_read_la(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb) | |||
1217 | goto lpfc_mbx_cmpl_read_la_free_mbuf; | 1217 | goto lpfc_mbx_cmpl_read_la_free_mbuf; |
1218 | } | 1218 | } |
1219 | 1219 | ||
1220 | la = (READ_LA_VAR *) & pmb->mb.un.varReadLA; | 1220 | la = (READ_LA_VAR *) &pmb->u.mb.un.varReadLA; |
1221 | 1221 | ||
1222 | memcpy(&phba->alpa_map[0], mp->virt, 128); | 1222 | memcpy(&phba->alpa_map[0], mp->virt, 128); |
1223 | 1223 | ||
@@ -1355,7 +1355,7 @@ lpfc_mbx_cmpl_reg_login(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb) | |||
1355 | static void | 1355 | static void |
1356 | lpfc_mbx_cmpl_unreg_vpi(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb) | 1356 | lpfc_mbx_cmpl_unreg_vpi(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb) |
1357 | { | 1357 | { |
1358 | MAILBOX_t *mb = &pmb->mb; | 1358 | MAILBOX_t *mb = &pmb->u.mb; |
1359 | struct lpfc_vport *vport = pmb->vport; | 1359 | struct lpfc_vport *vport = pmb->vport; |
1360 | struct Scsi_Host *shost = lpfc_shost_from_vport(vport); | 1360 | struct Scsi_Host *shost = lpfc_shost_from_vport(vport); |
1361 | 1361 | ||
@@ -1408,7 +1408,7 @@ lpfc_mbx_cmpl_reg_vpi(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb) | |||
1408 | { | 1408 | { |
1409 | struct lpfc_vport *vport = pmb->vport; | 1409 | struct lpfc_vport *vport = pmb->vport; |
1410 | struct Scsi_Host *shost = lpfc_shost_from_vport(vport); | 1410 | struct Scsi_Host *shost = lpfc_shost_from_vport(vport); |
1411 | MAILBOX_t *mb = &pmb->mb; | 1411 | MAILBOX_t *mb = &pmb->u.mb; |
1412 | 1412 | ||
1413 | switch (mb->mbxStatus) { | 1413 | switch (mb->mbxStatus) { |
1414 | case 0x0011: | 1414 | case 0x0011: |
@@ -2279,7 +2279,7 @@ lpfc_cleanup_node(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp) | |||
2279 | 2279 | ||
2280 | /* cleanup any ndlp on mbox q waiting for reglogin cmpl */ | 2280 | /* cleanup any ndlp on mbox q waiting for reglogin cmpl */ |
2281 | if ((mb = phba->sli.mbox_active)) { | 2281 | if ((mb = phba->sli.mbox_active)) { |
2282 | if ((mb->mb.mbxCommand == MBX_REG_LOGIN64) && | 2282 | if ((mb->u.mb.mbxCommand == MBX_REG_LOGIN64) && |
2283 | (ndlp == (struct lpfc_nodelist *) mb->context2)) { | 2283 | (ndlp == (struct lpfc_nodelist *) mb->context2)) { |
2284 | mb->context2 = NULL; | 2284 | mb->context2 = NULL; |
2285 | mb->mbox_cmpl = lpfc_sli_def_mbox_cmpl; | 2285 | mb->mbox_cmpl = lpfc_sli_def_mbox_cmpl; |
@@ -2288,7 +2288,7 @@ lpfc_cleanup_node(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp) | |||
2288 | 2288 | ||
2289 | spin_lock_irq(&phba->hbalock); | 2289 | spin_lock_irq(&phba->hbalock); |
2290 | list_for_each_entry_safe(mb, nextmb, &phba->sli.mboxq, list) { | 2290 | list_for_each_entry_safe(mb, nextmb, &phba->sli.mboxq, list) { |
2291 | if ((mb->mb.mbxCommand == MBX_REG_LOGIN64) && | 2291 | if ((mb->u.mb.mbxCommand == MBX_REG_LOGIN64) && |
2292 | (ndlp == (struct lpfc_nodelist *) mb->context2)) { | 2292 | (ndlp == (struct lpfc_nodelist *) mb->context2)) { |
2293 | mp = (struct lpfc_dmabuf *) (mb->context1); | 2293 | mp = (struct lpfc_dmabuf *) (mb->context1); |
2294 | if (mp) { | 2294 | if (mp) { |
@@ -2970,7 +2970,7 @@ restart_disc: | |||
2970 | lpfc_linkdown(phba); | 2970 | lpfc_linkdown(phba); |
2971 | lpfc_init_link(phba, initlinkmbox, phba->cfg_topology, | 2971 | lpfc_init_link(phba, initlinkmbox, phba->cfg_topology, |
2972 | phba->cfg_link_speed); | 2972 | phba->cfg_link_speed); |
2973 | initlinkmbox->mb.un.varInitLnk.lipsr_AL_PA = 0; | 2973 | initlinkmbox->u.mb.un.varInitLnk.lipsr_AL_PA = 0; |
2974 | initlinkmbox->vport = vport; | 2974 | initlinkmbox->vport = vport; |
2975 | initlinkmbox->mbox_cmpl = lpfc_sli_def_mbox_cmpl; | 2975 | initlinkmbox->mbox_cmpl = lpfc_sli_def_mbox_cmpl; |
2976 | rc = lpfc_sli_issue_mbox(phba, initlinkmbox, MBX_NOWAIT); | 2976 | rc = lpfc_sli_issue_mbox(phba, initlinkmbox, MBX_NOWAIT); |
@@ -3069,7 +3069,7 @@ restart_disc: | |||
3069 | void | 3069 | void |
3070 | lpfc_mbx_cmpl_fdmi_reg_login(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb) | 3070 | lpfc_mbx_cmpl_fdmi_reg_login(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb) |
3071 | { | 3071 | { |
3072 | MAILBOX_t *mb = &pmb->mb; | 3072 | MAILBOX_t *mb = &pmb->u.mb; |
3073 | struct lpfc_dmabuf *mp = (struct lpfc_dmabuf *) (pmb->context1); | 3073 | struct lpfc_dmabuf *mp = (struct lpfc_dmabuf *) (pmb->context1); |
3074 | struct lpfc_nodelist *ndlp = (struct lpfc_nodelist *) pmb->context2; | 3074 | struct lpfc_nodelist *ndlp = (struct lpfc_nodelist *) pmb->context2; |
3075 | struct lpfc_vport *vport = pmb->vport; | 3075 | struct lpfc_vport *vport = pmb->vport; |
diff --git a/drivers/scsi/lpfc/lpfc_init.c b/drivers/scsi/lpfc/lpfc_init.c index e9e4a1df8989..ff821bb77167 100644 --- a/drivers/scsi/lpfc/lpfc_init.c +++ b/drivers/scsi/lpfc/lpfc_init.c | |||
@@ -108,7 +108,7 @@ lpfc_config_port_prep(struct lpfc_hba *phba) | |||
108 | return -ENOMEM; | 108 | return -ENOMEM; |
109 | } | 109 | } |
110 | 110 | ||
111 | mb = &pmb->mb; | 111 | mb = &pmb->u.mb; |
112 | phba->link_state = LPFC_INIT_MBX_CMDS; | 112 | phba->link_state = LPFC_INIT_MBX_CMDS; |
113 | 113 | ||
114 | if (lpfc_is_LC_HBA(phba->pcidev->device)) { | 114 | if (lpfc_is_LC_HBA(phba->pcidev->device)) { |
@@ -221,6 +221,11 @@ lpfc_config_port_prep(struct lpfc_hba *phba) | |||
221 | mb->mbxCommand, mb->mbxStatus); | 221 | mb->mbxCommand, mb->mbxStatus); |
222 | mb->un.varDmp.word_cnt = 0; | 222 | mb->un.varDmp.word_cnt = 0; |
223 | } | 223 | } |
224 | /* dump mem may return a zero when finished or we got a | ||
225 | * mailbox error, either way we are done. | ||
226 | */ | ||
227 | if (mb->un.varDmp.word_cnt == 0) | ||
228 | break; | ||
224 | if (mb->un.varDmp.word_cnt > DMP_VPD_SIZE - offset) | 229 | if (mb->un.varDmp.word_cnt > DMP_VPD_SIZE - offset) |
225 | mb->un.varDmp.word_cnt = DMP_VPD_SIZE - offset; | 230 | mb->un.varDmp.word_cnt = DMP_VPD_SIZE - offset; |
226 | lpfc_sli_pcimem_bcopy(((uint8_t *)mb) + DMP_RSP_OFFSET, | 231 | lpfc_sli_pcimem_bcopy(((uint8_t *)mb) + DMP_RSP_OFFSET, |
@@ -249,7 +254,7 @@ out_free_mbox: | |||
249 | static void | 254 | static void |
250 | lpfc_config_async_cmpl(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmboxq) | 255 | lpfc_config_async_cmpl(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmboxq) |
251 | { | 256 | { |
252 | if (pmboxq->mb.mbxStatus == MBX_SUCCESS) | 257 | if (pmboxq->u.mb.mbxStatus == MBX_SUCCESS) |
253 | phba->temp_sensor_support = 1; | 258 | phba->temp_sensor_support = 1; |
254 | else | 259 | else |
255 | phba->temp_sensor_support = 0; | 260 | phba->temp_sensor_support = 0; |
@@ -276,7 +281,7 @@ lpfc_dump_wakeup_param_cmpl(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmboxq) | |||
276 | /* character array used for decoding dist type. */ | 281 | /* character array used for decoding dist type. */ |
277 | char dist_char[] = "nabx"; | 282 | char dist_char[] = "nabx"; |
278 | 283 | ||
279 | if (pmboxq->mb.mbxStatus != MBX_SUCCESS) { | 284 | if (pmboxq->u.mb.mbxStatus != MBX_SUCCESS) { |
280 | mempool_free(pmboxq, phba->mbox_mem_pool); | 285 | mempool_free(pmboxq, phba->mbox_mem_pool); |
281 | return; | 286 | return; |
282 | } | 287 | } |
@@ -284,7 +289,7 @@ lpfc_dump_wakeup_param_cmpl(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmboxq) | |||
284 | prg = (struct prog_id *) &prog_id_word; | 289 | prg = (struct prog_id *) &prog_id_word; |
285 | 290 | ||
286 | /* word 7 contain option rom version */ | 291 | /* word 7 contain option rom version */ |
287 | prog_id_word = pmboxq->mb.un.varWords[7]; | 292 | prog_id_word = pmboxq->u.mb.un.varWords[7]; |
288 | 293 | ||
289 | /* Decode the Option rom version word to a readable string */ | 294 | /* Decode the Option rom version word to a readable string */ |
290 | if (prg->dist < 4) | 295 | if (prg->dist < 4) |
@@ -341,7 +346,7 @@ lpfc_config_port_post(struct lpfc_hba *phba) | |||
341 | phba->link_state = LPFC_HBA_ERROR; | 346 | phba->link_state = LPFC_HBA_ERROR; |
342 | return -ENOMEM; | 347 | return -ENOMEM; |
343 | } | 348 | } |
344 | mb = &pmb->mb; | 349 | mb = &pmb->u.mb; |
345 | 350 | ||
346 | /* Get login parameters for NID. */ | 351 | /* Get login parameters for NID. */ |
347 | lpfc_read_sparam(phba, pmb, 0); | 352 | lpfc_read_sparam(phba, pmb, 0); |
@@ -476,17 +481,18 @@ lpfc_config_port_post(struct lpfc_hba *phba) | |||
476 | lpfc_printf_log(phba, KERN_ERR, LOG_MBOX, | 481 | lpfc_printf_log(phba, KERN_ERR, LOG_MBOX, |
477 | "0352 Config MSI mailbox command " | 482 | "0352 Config MSI mailbox command " |
478 | "failed, mbxCmd x%x, mbxStatus x%x\n", | 483 | "failed, mbxCmd x%x, mbxStatus x%x\n", |
479 | pmb->mb.mbxCommand, pmb->mb.mbxStatus); | 484 | pmb->u.mb.mbxCommand, |
485 | pmb->u.mb.mbxStatus); | ||
480 | mempool_free(pmb, phba->mbox_mem_pool); | 486 | mempool_free(pmb, phba->mbox_mem_pool); |
481 | return -EIO; | 487 | return -EIO; |
482 | } | 488 | } |
483 | } | 489 | } |
484 | 490 | ||
491 | spin_lock_irq(&phba->hbalock); | ||
485 | /* Initialize ERATT handling flag */ | 492 | /* Initialize ERATT handling flag */ |
486 | phba->hba_flag &= ~HBA_ERATT_HANDLED; | 493 | phba->hba_flag &= ~HBA_ERATT_HANDLED; |
487 | 494 | ||
488 | /* Enable appropriate host interrupts */ | 495 | /* Enable appropriate host interrupts */ |
489 | spin_lock_irq(&phba->hbalock); | ||
490 | status = readl(phba->HCregaddr); | 496 | status = readl(phba->HCregaddr); |
491 | status |= HC_MBINT_ENA | HC_ERINT_ENA | HC_LAINT_ENA; | 497 | status |= HC_MBINT_ENA | HC_ERINT_ENA | HC_LAINT_ENA; |
492 | if (psli->num_rings > 0) | 498 | if (psli->num_rings > 0) |
@@ -2201,7 +2207,7 @@ lpfc_offline_prep(struct lpfc_hba * phba) | |||
2201 | } | 2207 | } |
2202 | lpfc_destroy_vport_work_array(phba, vports); | 2208 | lpfc_destroy_vport_work_array(phba, vports); |
2203 | 2209 | ||
2204 | lpfc_sli_flush_mbox_queue(phba); | 2210 | lpfc_sli_mbox_sys_shutdown(phba); |
2205 | } | 2211 | } |
2206 | 2212 | ||
2207 | /** | 2213 | /** |
diff --git a/drivers/scsi/lpfc/lpfc_mbox.c b/drivers/scsi/lpfc/lpfc_mbox.c index 7f5899b70bd2..6aeb1c668e22 100644 --- a/drivers/scsi/lpfc/lpfc_mbox.c +++ b/drivers/scsi/lpfc/lpfc_mbox.c | |||
@@ -60,7 +60,7 @@ lpfc_dump_mem(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb, uint16_t offset) | |||
60 | MAILBOX_t *mb; | 60 | MAILBOX_t *mb; |
61 | void *ctx; | 61 | void *ctx; |
62 | 62 | ||
63 | mb = &pmb->mb; | 63 | mb = &pmb->u.mb; |
64 | ctx = pmb->context2; | 64 | ctx = pmb->context2; |
65 | 65 | ||
66 | /* Setup to dump VPD region */ | 66 | /* Setup to dump VPD region */ |
@@ -92,7 +92,7 @@ lpfc_dump_wakeup_param(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb) | |||
92 | MAILBOX_t *mb; | 92 | MAILBOX_t *mb; |
93 | void *ctx; | 93 | void *ctx; |
94 | 94 | ||
95 | mb = &pmb->mb; | 95 | mb = &pmb->u.mb; |
96 | /* Save context so that we can restore after memset */ | 96 | /* Save context so that we can restore after memset */ |
97 | ctx = pmb->context2; | 97 | ctx = pmb->context2; |
98 | 98 | ||
@@ -127,7 +127,7 @@ lpfc_read_nv(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb) | |||
127 | { | 127 | { |
128 | MAILBOX_t *mb; | 128 | MAILBOX_t *mb; |
129 | 129 | ||
130 | mb = &pmb->mb; | 130 | mb = &pmb->u.mb; |
131 | memset(pmb, 0, sizeof (LPFC_MBOXQ_t)); | 131 | memset(pmb, 0, sizeof (LPFC_MBOXQ_t)); |
132 | mb->mbxCommand = MBX_READ_NV; | 132 | mb->mbxCommand = MBX_READ_NV; |
133 | mb->mbxOwner = OWN_HOST; | 133 | mb->mbxOwner = OWN_HOST; |
@@ -153,7 +153,7 @@ lpfc_config_async(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb, | |||
153 | { | 153 | { |
154 | MAILBOX_t *mb; | 154 | MAILBOX_t *mb; |
155 | 155 | ||
156 | mb = &pmb->mb; | 156 | mb = &pmb->u.mb; |
157 | memset(pmb, 0, sizeof (LPFC_MBOXQ_t)); | 157 | memset(pmb, 0, sizeof (LPFC_MBOXQ_t)); |
158 | mb->mbxCommand = MBX_ASYNCEVT_ENABLE; | 158 | mb->mbxCommand = MBX_ASYNCEVT_ENABLE; |
159 | mb->un.varCfgAsyncEvent.ring = ring; | 159 | mb->un.varCfgAsyncEvent.ring = ring; |
@@ -179,7 +179,7 @@ lpfc_heart_beat(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb) | |||
179 | { | 179 | { |
180 | MAILBOX_t *mb; | 180 | MAILBOX_t *mb; |
181 | 181 | ||
182 | mb = &pmb->mb; | 182 | mb = &pmb->u.mb; |
183 | memset(pmb, 0, sizeof (LPFC_MBOXQ_t)); | 183 | memset(pmb, 0, sizeof (LPFC_MBOXQ_t)); |
184 | mb->mbxCommand = MBX_HEARTBEAT; | 184 | mb->mbxCommand = MBX_HEARTBEAT; |
185 | mb->mbxOwner = OWN_HOST; | 185 | mb->mbxOwner = OWN_HOST; |
@@ -213,7 +213,7 @@ lpfc_read_la(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb, struct lpfc_dmabuf *mp) | |||
213 | struct lpfc_sli *psli; | 213 | struct lpfc_sli *psli; |
214 | 214 | ||
215 | psli = &phba->sli; | 215 | psli = &phba->sli; |
216 | mb = &pmb->mb; | 216 | mb = &pmb->u.mb; |
217 | memset(pmb, 0, sizeof (LPFC_MBOXQ_t)); | 217 | memset(pmb, 0, sizeof (LPFC_MBOXQ_t)); |
218 | 218 | ||
219 | INIT_LIST_HEAD(&mp->list); | 219 | INIT_LIST_HEAD(&mp->list); |
@@ -250,7 +250,7 @@ lpfc_clear_la(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb) | |||
250 | { | 250 | { |
251 | MAILBOX_t *mb; | 251 | MAILBOX_t *mb; |
252 | 252 | ||
253 | mb = &pmb->mb; | 253 | mb = &pmb->u.mb; |
254 | memset(pmb, 0, sizeof (LPFC_MBOXQ_t)); | 254 | memset(pmb, 0, sizeof (LPFC_MBOXQ_t)); |
255 | 255 | ||
256 | mb->un.varClearLA.eventTag = phba->fc_eventTag; | 256 | mb->un.varClearLA.eventTag = phba->fc_eventTag; |
@@ -277,7 +277,7 @@ void | |||
277 | lpfc_config_link(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb) | 277 | lpfc_config_link(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb) |
278 | { | 278 | { |
279 | struct lpfc_vport *vport = phba->pport; | 279 | struct lpfc_vport *vport = phba->pport; |
280 | MAILBOX_t *mb = &pmb->mb; | 280 | MAILBOX_t *mb = &pmb->u.mb; |
281 | memset(pmb, 0, sizeof (LPFC_MBOXQ_t)); | 281 | memset(pmb, 0, sizeof (LPFC_MBOXQ_t)); |
282 | 282 | ||
283 | /* NEW_FEATURE | 283 | /* NEW_FEATURE |
@@ -323,7 +323,7 @@ lpfc_config_link(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb) | |||
323 | int | 323 | int |
324 | lpfc_config_msi(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb) | 324 | lpfc_config_msi(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb) |
325 | { | 325 | { |
326 | MAILBOX_t *mb = &pmb->mb; | 326 | MAILBOX_t *mb = &pmb->u.mb; |
327 | uint32_t attentionConditions[2]; | 327 | uint32_t attentionConditions[2]; |
328 | 328 | ||
329 | /* Sanity check */ | 329 | /* Sanity check */ |
@@ -407,7 +407,7 @@ lpfc_init_link(struct lpfc_hba * phba, | |||
407 | struct lpfc_sli *psli; | 407 | struct lpfc_sli *psli; |
408 | MAILBOX_t *mb; | 408 | MAILBOX_t *mb; |
409 | 409 | ||
410 | mb = &pmb->mb; | 410 | mb = &pmb->u.mb; |
411 | memset(pmb, 0, sizeof (LPFC_MBOXQ_t)); | 411 | memset(pmb, 0, sizeof (LPFC_MBOXQ_t)); |
412 | 412 | ||
413 | psli = &phba->sli; | 413 | psli = &phba->sli; |
@@ -494,7 +494,7 @@ lpfc_read_sparam(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb, int vpi) | |||
494 | struct lpfc_sli *psli; | 494 | struct lpfc_sli *psli; |
495 | 495 | ||
496 | psli = &phba->sli; | 496 | psli = &phba->sli; |
497 | mb = &pmb->mb; | 497 | mb = &pmb->u.mb; |
498 | memset(pmb, 0, sizeof (LPFC_MBOXQ_t)); | 498 | memset(pmb, 0, sizeof (LPFC_MBOXQ_t)); |
499 | 499 | ||
500 | mb->mbxOwner = OWN_HOST; | 500 | mb->mbxOwner = OWN_HOST; |
@@ -517,7 +517,7 @@ lpfc_read_sparam(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb, int vpi) | |||
517 | mb->un.varRdSparm.un.sp64.tus.f.bdeSize = sizeof (struct serv_parm); | 517 | mb->un.varRdSparm.un.sp64.tus.f.bdeSize = sizeof (struct serv_parm); |
518 | mb->un.varRdSparm.un.sp64.addrHigh = putPaddrHigh(mp->phys); | 518 | mb->un.varRdSparm.un.sp64.addrHigh = putPaddrHigh(mp->phys); |
519 | mb->un.varRdSparm.un.sp64.addrLow = putPaddrLow(mp->phys); | 519 | mb->un.varRdSparm.un.sp64.addrLow = putPaddrLow(mp->phys); |
520 | mb->un.varRdSparm.vpi = vpi; | 520 | mb->un.varRdSparm.vpi = vpi + phba->vpi_base; |
521 | 521 | ||
522 | /* save address for completion */ | 522 | /* save address for completion */ |
523 | pmb->context1 = mp; | 523 | pmb->context1 = mp; |
@@ -546,10 +546,12 @@ lpfc_unreg_did(struct lpfc_hba * phba, uint16_t vpi, uint32_t did, | |||
546 | { | 546 | { |
547 | MAILBOX_t *mb; | 547 | MAILBOX_t *mb; |
548 | 548 | ||
549 | mb = &pmb->mb; | 549 | mb = &pmb->u.mb; |
550 | memset(pmb, 0, sizeof (LPFC_MBOXQ_t)); | 550 | memset(pmb, 0, sizeof (LPFC_MBOXQ_t)); |
551 | 551 | ||
552 | mb->un.varUnregDID.did = did; | 552 | mb->un.varUnregDID.did = did; |
553 | if (vpi != 0xffff) | ||
554 | vpi += phba->vpi_base; | ||
553 | mb->un.varUnregDID.vpi = vpi; | 555 | mb->un.varUnregDID.vpi = vpi; |
554 | 556 | ||
555 | mb->mbxCommand = MBX_UNREG_D_ID; | 557 | mb->mbxCommand = MBX_UNREG_D_ID; |
@@ -575,7 +577,7 @@ lpfc_read_config(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb) | |||
575 | { | 577 | { |
576 | MAILBOX_t *mb; | 578 | MAILBOX_t *mb; |
577 | 579 | ||
578 | mb = &pmb->mb; | 580 | mb = &pmb->u.mb; |
579 | memset(pmb, 0, sizeof (LPFC_MBOXQ_t)); | 581 | memset(pmb, 0, sizeof (LPFC_MBOXQ_t)); |
580 | 582 | ||
581 | mb->mbxCommand = MBX_READ_CONFIG; | 583 | mb->mbxCommand = MBX_READ_CONFIG; |
@@ -600,7 +602,7 @@ lpfc_read_lnk_stat(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb) | |||
600 | { | 602 | { |
601 | MAILBOX_t *mb; | 603 | MAILBOX_t *mb; |
602 | 604 | ||
603 | mb = &pmb->mb; | 605 | mb = &pmb->u.mb; |
604 | memset(pmb, 0, sizeof (LPFC_MBOXQ_t)); | 606 | memset(pmb, 0, sizeof (LPFC_MBOXQ_t)); |
605 | 607 | ||
606 | mb->mbxCommand = MBX_READ_LNK_STAT; | 608 | mb->mbxCommand = MBX_READ_LNK_STAT; |
@@ -609,7 +611,7 @@ lpfc_read_lnk_stat(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb) | |||
609 | } | 611 | } |
610 | 612 | ||
611 | /** | 613 | /** |
612 | * lpfc_reg_login - Prepare a mailbox command for registering remote login | 614 | * lpfc_reg_rpi - Prepare a mailbox command for registering remote login |
613 | * @phba: pointer to lpfc hba data structure. | 615 | * @phba: pointer to lpfc hba data structure. |
614 | * @vpi: virtual N_Port identifier. | 616 | * @vpi: virtual N_Port identifier. |
615 | * @did: remote port identifier. | 617 | * @did: remote port identifier. |
@@ -633,17 +635,23 @@ lpfc_read_lnk_stat(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb) | |||
633 | * 1 - DMA memory allocation failed | 635 | * 1 - DMA memory allocation failed |
634 | **/ | 636 | **/ |
635 | int | 637 | int |
636 | lpfc_reg_login(struct lpfc_hba *phba, uint16_t vpi, uint32_t did, | 638 | lpfc_reg_rpi(struct lpfc_hba *phba, uint16_t vpi, uint32_t did, |
637 | uint8_t *param, LPFC_MBOXQ_t *pmb, uint32_t flag) | 639 | uint8_t *param, LPFC_MBOXQ_t *pmb, uint32_t flag) |
638 | { | 640 | { |
639 | MAILBOX_t *mb = &pmb->mb; | 641 | MAILBOX_t *mb = &pmb->u.mb; |
640 | uint8_t *sparam; | 642 | uint8_t *sparam; |
641 | struct lpfc_dmabuf *mp; | 643 | struct lpfc_dmabuf *mp; |
642 | 644 | ||
643 | memset(pmb, 0, sizeof (LPFC_MBOXQ_t)); | 645 | memset(pmb, 0, sizeof (LPFC_MBOXQ_t)); |
644 | 646 | ||
645 | mb->un.varRegLogin.rpi = 0; | 647 | mb->un.varRegLogin.rpi = 0; |
646 | mb->un.varRegLogin.vpi = vpi; | 648 | if (phba->sli_rev == LPFC_SLI_REV4) { |
649 | mb->un.varRegLogin.rpi = lpfc_sli4_alloc_rpi(phba); | ||
650 | if (mb->un.varRegLogin.rpi == LPFC_RPI_ALLOC_ERROR) | ||
651 | return 1; | ||
652 | } | ||
653 | |||
654 | mb->un.varRegLogin.vpi = vpi + phba->vpi_base; | ||
647 | mb->un.varRegLogin.did = did; | 655 | mb->un.varRegLogin.did = did; |
648 | mb->un.varWords[30] = flag; /* Set flag to issue action on cmpl */ | 656 | mb->un.varWords[30] = flag; /* Set flag to issue action on cmpl */ |
649 | 657 | ||
@@ -699,15 +707,16 @@ lpfc_unreg_login(struct lpfc_hba *phba, uint16_t vpi, uint32_t rpi, | |||
699 | { | 707 | { |
700 | MAILBOX_t *mb; | 708 | MAILBOX_t *mb; |
701 | 709 | ||
702 | mb = &pmb->mb; | 710 | mb = &pmb->u.mb; |
703 | memset(pmb, 0, sizeof (LPFC_MBOXQ_t)); | 711 | memset(pmb, 0, sizeof (LPFC_MBOXQ_t)); |
704 | 712 | ||
705 | mb->un.varUnregLogin.rpi = (uint16_t) rpi; | 713 | mb->un.varUnregLogin.rpi = (uint16_t) rpi; |
706 | mb->un.varUnregLogin.rsvd1 = 0; | 714 | mb->un.varUnregLogin.rsvd1 = 0; |
707 | mb->un.varUnregLogin.vpi = vpi; | 715 | mb->un.varUnregLogin.vpi = vpi + phba->vpi_base; |
708 | 716 | ||
709 | mb->mbxCommand = MBX_UNREG_LOGIN; | 717 | mb->mbxCommand = MBX_UNREG_LOGIN; |
710 | mb->mbxOwner = OWN_HOST; | 718 | mb->mbxOwner = OWN_HOST; |
719 | |||
711 | return; | 720 | return; |
712 | } | 721 | } |
713 | 722 | ||
@@ -727,15 +736,15 @@ lpfc_unreg_login(struct lpfc_hba *phba, uint16_t vpi, uint32_t rpi, | |||
727 | * This routine prepares the mailbox command for registering a virtual N_Port. | 736 | * This routine prepares the mailbox command for registering a virtual N_Port. |
728 | **/ | 737 | **/ |
729 | void | 738 | void |
730 | lpfc_reg_vpi(struct lpfc_hba *phba, uint16_t vpi, uint32_t sid, | 739 | lpfc_reg_vpi(struct lpfc_vport *vport, LPFC_MBOXQ_t *pmb) |
731 | LPFC_MBOXQ_t *pmb) | ||
732 | { | 740 | { |
733 | MAILBOX_t *mb = &pmb->mb; | 741 | MAILBOX_t *mb = &pmb->u.mb; |
734 | 742 | ||
735 | memset(pmb, 0, sizeof (LPFC_MBOXQ_t)); | 743 | memset(pmb, 0, sizeof (LPFC_MBOXQ_t)); |
736 | 744 | ||
737 | mb->un.varRegVpi.vpi = vpi; | 745 | mb->un.varRegVpi.vpi = vport->vpi + vport->phba->vpi_base; |
738 | mb->un.varRegVpi.sid = sid; | 746 | mb->un.varRegVpi.sid = vport->fc_myDID; |
747 | mb->un.varRegVpi.vfi = vport->vfi + vport->phba->vfi_base; | ||
739 | 748 | ||
740 | mb->mbxCommand = MBX_REG_VPI; | 749 | mb->mbxCommand = MBX_REG_VPI; |
741 | mb->mbxOwner = OWN_HOST; | 750 | mb->mbxOwner = OWN_HOST; |
@@ -762,10 +771,10 @@ lpfc_reg_vpi(struct lpfc_hba *phba, uint16_t vpi, uint32_t sid, | |||
762 | void | 771 | void |
763 | lpfc_unreg_vpi(struct lpfc_hba *phba, uint16_t vpi, LPFC_MBOXQ_t *pmb) | 772 | lpfc_unreg_vpi(struct lpfc_hba *phba, uint16_t vpi, LPFC_MBOXQ_t *pmb) |
764 | { | 773 | { |
765 | MAILBOX_t *mb = &pmb->mb; | 774 | MAILBOX_t *mb = &pmb->u.mb; |
766 | memset(pmb, 0, sizeof (LPFC_MBOXQ_t)); | 775 | memset(pmb, 0, sizeof (LPFC_MBOXQ_t)); |
767 | 776 | ||
768 | mb->un.varUnregVpi.vpi = vpi; | 777 | mb->un.varUnregVpi.vpi = vpi + phba->vpi_base; |
769 | 778 | ||
770 | mb->mbxCommand = MBX_UNREG_VPI; | 779 | mb->mbxCommand = MBX_UNREG_VPI; |
771 | mb->mbxOwner = OWN_HOST; | 780 | mb->mbxOwner = OWN_HOST; |
@@ -854,7 +863,7 @@ lpfc_config_pcb_setup(struct lpfc_hba * phba) | |||
854 | void | 863 | void |
855 | lpfc_read_rev(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb) | 864 | lpfc_read_rev(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb) |
856 | { | 865 | { |
857 | MAILBOX_t *mb = &pmb->mb; | 866 | MAILBOX_t *mb = &pmb->u.mb; |
858 | memset(pmb, 0, sizeof (LPFC_MBOXQ_t)); | 867 | memset(pmb, 0, sizeof (LPFC_MBOXQ_t)); |
859 | mb->un.varRdRev.cv = 1; | 868 | mb->un.varRdRev.cv = 1; |
860 | mb->un.varRdRev.v3req = 1; /* Request SLI3 info */ | 869 | mb->un.varRdRev.v3req = 1; /* Request SLI3 info */ |
@@ -947,7 +956,7 @@ lpfc_config_hbq(struct lpfc_hba *phba, uint32_t id, | |||
947 | uint32_t hbq_entry_index, LPFC_MBOXQ_t *pmb) | 956 | uint32_t hbq_entry_index, LPFC_MBOXQ_t *pmb) |
948 | { | 957 | { |
949 | int i; | 958 | int i; |
950 | MAILBOX_t *mb = &pmb->mb; | 959 | MAILBOX_t *mb = &pmb->u.mb; |
951 | struct config_hbq_var *hbqmb = &mb->un.varCfgHbq; | 960 | struct config_hbq_var *hbqmb = &mb->un.varCfgHbq; |
952 | 961 | ||
953 | memset(pmb, 0, sizeof (LPFC_MBOXQ_t)); | 962 | memset(pmb, 0, sizeof (LPFC_MBOXQ_t)); |
@@ -1022,7 +1031,7 @@ void | |||
1022 | lpfc_config_ring(struct lpfc_hba * phba, int ring, LPFC_MBOXQ_t * pmb) | 1031 | lpfc_config_ring(struct lpfc_hba * phba, int ring, LPFC_MBOXQ_t * pmb) |
1023 | { | 1032 | { |
1024 | int i; | 1033 | int i; |
1025 | MAILBOX_t *mb = &pmb->mb; | 1034 | MAILBOX_t *mb = &pmb->u.mb; |
1026 | struct lpfc_sli *psli; | 1035 | struct lpfc_sli *psli; |
1027 | struct lpfc_sli_ring *pring; | 1036 | struct lpfc_sli_ring *pring; |
1028 | 1037 | ||
@@ -1077,7 +1086,7 @@ void | |||
1077 | lpfc_config_port(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb) | 1086 | lpfc_config_port(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb) |
1078 | { | 1087 | { |
1079 | MAILBOX_t __iomem *mb_slim = (MAILBOX_t __iomem *) phba->MBslimaddr; | 1088 | MAILBOX_t __iomem *mb_slim = (MAILBOX_t __iomem *) phba->MBslimaddr; |
1080 | MAILBOX_t *mb = &pmb->mb; | 1089 | MAILBOX_t *mb = &pmb->u.mb; |
1081 | dma_addr_t pdma_addr; | 1090 | dma_addr_t pdma_addr; |
1082 | uint32_t bar_low, bar_high; | 1091 | uint32_t bar_low, bar_high; |
1083 | size_t offset; | 1092 | size_t offset; |
@@ -1101,21 +1110,22 @@ lpfc_config_port(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb) | |||
1101 | 1110 | ||
1102 | /* If HBA supports SLI=3 ask for it */ | 1111 | /* If HBA supports SLI=3 ask for it */ |
1103 | 1112 | ||
1104 | if (phba->sli_rev == 3 && phba->vpd.sli3Feat.cerbm) { | 1113 | if (phba->sli_rev == LPFC_SLI_REV3 && phba->vpd.sli3Feat.cerbm) { |
1105 | if (phba->cfg_enable_bg) | 1114 | if (phba->cfg_enable_bg) |
1106 | mb->un.varCfgPort.cbg = 1; /* configure BlockGuard */ | 1115 | mb->un.varCfgPort.cbg = 1; /* configure BlockGuard */ |
1116 | mb->un.varCfgPort.cdss = 1; /* Configure Security */ | ||
1107 | mb->un.varCfgPort.cerbm = 1; /* Request HBQs */ | 1117 | mb->un.varCfgPort.cerbm = 1; /* Request HBQs */ |
1108 | mb->un.varCfgPort.ccrp = 1; /* Command Ring Polling */ | 1118 | mb->un.varCfgPort.ccrp = 1; /* Command Ring Polling */ |
1109 | mb->un.varCfgPort.cinb = 1; /* Interrupt Notification Block */ | 1119 | mb->un.varCfgPort.cinb = 1; /* Interrupt Notification Block */ |
1110 | mb->un.varCfgPort.max_hbq = lpfc_sli_hbq_count(); | 1120 | mb->un.varCfgPort.max_hbq = lpfc_sli_hbq_count(); |
1111 | if (phba->max_vpi && phba->cfg_enable_npiv && | 1121 | if (phba->max_vpi && phba->cfg_enable_npiv && |
1112 | phba->vpd.sli3Feat.cmv) { | 1122 | phba->vpd.sli3Feat.cmv) { |
1113 | mb->un.varCfgPort.max_vpi = phba->max_vpi; | 1123 | mb->un.varCfgPort.max_vpi = LPFC_MAX_VPI; |
1114 | mb->un.varCfgPort.cmv = 1; | 1124 | mb->un.varCfgPort.cmv = 1; |
1115 | } else | 1125 | } else |
1116 | mb->un.varCfgPort.max_vpi = phba->max_vpi = 0; | 1126 | mb->un.varCfgPort.max_vpi = phba->max_vpi = 0; |
1117 | } else | 1127 | } else |
1118 | phba->sli_rev = 2; | 1128 | phba->sli_rev = LPFC_SLI_REV2; |
1119 | mb->un.varCfgPort.sli_mode = phba->sli_rev; | 1129 | mb->un.varCfgPort.sli_mode = phba->sli_rev; |
1120 | 1130 | ||
1121 | /* Now setup pcb */ | 1131 | /* Now setup pcb */ |
@@ -1247,7 +1257,7 @@ lpfc_config_port(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb) | |||
1247 | void | 1257 | void |
1248 | lpfc_kill_board(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb) | 1258 | lpfc_kill_board(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb) |
1249 | { | 1259 | { |
1250 | MAILBOX_t *mb = &pmb->mb; | 1260 | MAILBOX_t *mb = &pmb->u.mb; |
1251 | 1261 | ||
1252 | memset(pmb, 0, sizeof(LPFC_MBOXQ_t)); | 1262 | memset(pmb, 0, sizeof(LPFC_MBOXQ_t)); |
1253 | mb->mbxCommand = MBX_KILL_BOARD; | 1263 | mb->mbxCommand = MBX_KILL_BOARD; |
@@ -1307,29 +1317,98 @@ lpfc_mbox_get(struct lpfc_hba * phba) | |||
1307 | } | 1317 | } |
1308 | 1318 | ||
1309 | /** | 1319 | /** |
1320 | * __lpfc_mbox_cmpl_put - Put mailbox cmd into mailbox cmd complete list | ||
1321 | * @phba: pointer to lpfc hba data structure. | ||
1322 | * @mbq: pointer to the driver internal queue element for mailbox command. | ||
1323 | * | ||
1324 | * This routine put the completed mailbox command into the mailbox command | ||
1325 | * complete list. This is the unlocked version of the routine. The mailbox | ||
1326 | * complete list is used by the driver worker thread to process mailbox | ||
1327 | * complete callback functions outside the driver interrupt handler. | ||
1328 | **/ | ||
1329 | void | ||
1330 | __lpfc_mbox_cmpl_put(struct lpfc_hba *phba, LPFC_MBOXQ_t *mbq) | ||
1331 | { | ||
1332 | list_add_tail(&mbq->list, &phba->sli.mboxq_cmpl); | ||
1333 | } | ||
1334 | |||
1335 | /** | ||
1310 | * lpfc_mbox_cmpl_put - Put mailbox command into mailbox command complete list | 1336 | * lpfc_mbox_cmpl_put - Put mailbox command into mailbox command complete list |
1311 | * @phba: pointer to lpfc hba data structure. | 1337 | * @phba: pointer to lpfc hba data structure. |
1312 | * @mbq: pointer to the driver internal queue element for mailbox command. | 1338 | * @mbq: pointer to the driver internal queue element for mailbox command. |
1313 | * | 1339 | * |
1314 | * This routine put the completed mailbox command into the mailbox command | 1340 | * This routine put the completed mailbox command into the mailbox command |
1315 | * complete list. This routine is called from driver interrupt handler | 1341 | * complete list. This is the locked version of the routine. The mailbox |
1316 | * context.The mailbox complete list is used by the driver worker thread | 1342 | * complete list is used by the driver worker thread to process mailbox |
1317 | * to process mailbox complete callback functions outside the driver interrupt | 1343 | * complete callback functions outside the driver interrupt handler. |
1318 | * handler. | ||
1319 | **/ | 1344 | **/ |
1320 | void | 1345 | void |
1321 | lpfc_mbox_cmpl_put(struct lpfc_hba * phba, LPFC_MBOXQ_t * mbq) | 1346 | lpfc_mbox_cmpl_put(struct lpfc_hba *phba, LPFC_MBOXQ_t *mbq) |
1322 | { | 1347 | { |
1323 | unsigned long iflag; | 1348 | unsigned long iflag; |
1324 | 1349 | ||
1325 | /* This function expects to be called from interrupt context */ | 1350 | /* This function expects to be called from interrupt context */ |
1326 | spin_lock_irqsave(&phba->hbalock, iflag); | 1351 | spin_lock_irqsave(&phba->hbalock, iflag); |
1327 | list_add_tail(&mbq->list, &phba->sli.mboxq_cmpl); | 1352 | __lpfc_mbox_cmpl_put(phba, mbq); |
1328 | spin_unlock_irqrestore(&phba->hbalock, iflag); | 1353 | spin_unlock_irqrestore(&phba->hbalock, iflag); |
1329 | return; | 1354 | return; |
1330 | } | 1355 | } |
1331 | 1356 | ||
1332 | /** | 1357 | /** |
1358 | * lpfc_mbox_cmd_check - Check the validality of a mailbox command | ||
1359 | * @phba: pointer to lpfc hba data structure. | ||
1360 | * @mboxq: pointer to the driver internal queue element for mailbox command. | ||
1361 | * | ||
1362 | * This routine is to check whether a mailbox command is valid to be issued. | ||
1363 | * This check will be performed by both the mailbox issue API when a client | ||
1364 | * is to issue a mailbox command to the mailbox transport. | ||
1365 | * | ||
1366 | * Return 0 - pass the check, -ENODEV - fail the check | ||
1367 | **/ | ||
1368 | int | ||
1369 | lpfc_mbox_cmd_check(struct lpfc_hba *phba, LPFC_MBOXQ_t *mboxq) | ||
1370 | { | ||
1371 | /* Mailbox command that have a completion handler must also have a | ||
1372 | * vport specified. | ||
1373 | */ | ||
1374 | if (mboxq->mbox_cmpl && mboxq->mbox_cmpl != lpfc_sli_def_mbox_cmpl && | ||
1375 | mboxq->mbox_cmpl != lpfc_sli_wake_mbox_wait) { | ||
1376 | if (!mboxq->vport) { | ||
1377 | lpfc_printf_log(phba, KERN_ERR, LOG_MBOX | LOG_VPORT, | ||
1378 | "1814 Mbox x%x failed, no vport\n", | ||
1379 | mboxq->u.mb.mbxCommand); | ||
1380 | dump_stack(); | ||
1381 | return -ENODEV; | ||
1382 | } | ||
1383 | } | ||
1384 | return 0; | ||
1385 | } | ||
1386 | |||
1387 | /** | ||
1388 | * lpfc_mbox_dev_check - Check the device state for issuing a mailbox command | ||
1389 | * @phba: pointer to lpfc hba data structure. | ||
1390 | * | ||
1391 | * This routine is to check whether the HBA device is ready for posting a | ||
1392 | * mailbox command. It is used by the mailbox transport API at the time the | ||
1393 | * to post a mailbox command to the device. | ||
1394 | * | ||
1395 | * Return 0 - pass the check, -ENODEV - fail the check | ||
1396 | **/ | ||
1397 | int | ||
1398 | lpfc_mbox_dev_check(struct lpfc_hba *phba) | ||
1399 | { | ||
1400 | /* If the PCI channel is in offline state, do not issue mbox */ | ||
1401 | if (unlikely(pci_channel_offline(phba->pcidev))) | ||
1402 | return -ENODEV; | ||
1403 | |||
1404 | /* If the HBA is in error state, do not issue mbox */ | ||
1405 | if (phba->link_state == LPFC_HBA_ERROR) | ||
1406 | return -ENODEV; | ||
1407 | |||
1408 | return 0; | ||
1409 | } | ||
1410 | |||
1411 | /** | ||
1333 | * lpfc_mbox_tmo_val - Retrieve mailbox command timeout value | 1412 | * lpfc_mbox_tmo_val - Retrieve mailbox command timeout value |
1334 | * @phba: pointer to lpfc hba data structure. | 1413 | * @phba: pointer to lpfc hba data structure. |
1335 | * @cmd: mailbox command code. | 1414 | * @cmd: mailbox command code. |
@@ -1352,6 +1431,475 @@ lpfc_mbox_tmo_val(struct lpfc_hba *phba, int cmd) | |||
1352 | case MBX_WRITE_WWN: /* 0x98 */ | 1431 | case MBX_WRITE_WWN: /* 0x98 */ |
1353 | case MBX_LOAD_EXP_ROM: /* 0x9C */ | 1432 | case MBX_LOAD_EXP_ROM: /* 0x9C */ |
1354 | return LPFC_MBOX_TMO_FLASH_CMD; | 1433 | return LPFC_MBOX_TMO_FLASH_CMD; |
1434 | case MBX_SLI4_CONFIG: /* 0x9b */ | ||
1435 | return LPFC_MBOX_SLI4_CONFIG_TMO; | ||
1355 | } | 1436 | } |
1356 | return LPFC_MBOX_TMO; | 1437 | return LPFC_MBOX_TMO; |
1357 | } | 1438 | } |
1439 | |||
1440 | /** | ||
1441 | * lpfc_sli4_mbx_sge_set - Set a sge entry in non-embedded mailbox command | ||
1442 | * @mbox: pointer to lpfc mbox command. | ||
1443 | * @sgentry: sge entry index. | ||
1444 | * @phyaddr: physical address for the sge | ||
1445 | * @length: Length of the sge. | ||
1446 | * | ||
1447 | * This routine sets up an entry in the non-embedded mailbox command at the sge | ||
1448 | * index location. | ||
1449 | **/ | ||
1450 | void | ||
1451 | lpfc_sli4_mbx_sge_set(struct lpfcMboxq *mbox, uint32_t sgentry, | ||
1452 | dma_addr_t phyaddr, uint32_t length) | ||
1453 | { | ||
1454 | struct lpfc_mbx_nembed_cmd *nembed_sge; | ||
1455 | |||
1456 | nembed_sge = (struct lpfc_mbx_nembed_cmd *) | ||
1457 | &mbox->u.mqe.un.nembed_cmd; | ||
1458 | nembed_sge->sge[sgentry].pa_lo = putPaddrLow(phyaddr); | ||
1459 | nembed_sge->sge[sgentry].pa_hi = putPaddrHigh(phyaddr); | ||
1460 | nembed_sge->sge[sgentry].length = length; | ||
1461 | } | ||
1462 | |||
1463 | /** | ||
1464 | * lpfc_sli4_mbx_sge_get - Get a sge entry from non-embedded mailbox command | ||
1465 | * @mbox: pointer to lpfc mbox command. | ||
1466 | * @sgentry: sge entry index. | ||
1467 | * | ||
1468 | * This routine gets an entry from the non-embedded mailbox command at the sge | ||
1469 | * index location. | ||
1470 | **/ | ||
1471 | void | ||
1472 | lpfc_sli4_mbx_sge_get(struct lpfcMboxq *mbox, uint32_t sgentry, | ||
1473 | struct lpfc_mbx_sge *sge) | ||
1474 | { | ||
1475 | struct lpfc_mbx_nembed_cmd *nembed_sge; | ||
1476 | |||
1477 | nembed_sge = (struct lpfc_mbx_nembed_cmd *) | ||
1478 | &mbox->u.mqe.un.nembed_cmd; | ||
1479 | sge->pa_lo = nembed_sge->sge[sgentry].pa_lo; | ||
1480 | sge->pa_hi = nembed_sge->sge[sgentry].pa_hi; | ||
1481 | sge->length = nembed_sge->sge[sgentry].length; | ||
1482 | } | ||
1483 | |||
1484 | /** | ||
1485 | * lpfc_sli4_mbox_cmd_free - Free a sli4 mailbox command | ||
1486 | * @phba: pointer to lpfc hba data structure. | ||
1487 | * @mbox: pointer to lpfc mbox command. | ||
1488 | * | ||
1489 | * This routine frees SLI4 specific mailbox command for sending IOCTL command. | ||
1490 | **/ | ||
1491 | void | ||
1492 | lpfc_sli4_mbox_cmd_free(struct lpfc_hba *phba, struct lpfcMboxq *mbox) | ||
1493 | { | ||
1494 | struct lpfc_mbx_sli4_config *sli4_cfg; | ||
1495 | struct lpfc_mbx_sge sge; | ||
1496 | dma_addr_t phyaddr; | ||
1497 | uint32_t sgecount, sgentry; | ||
1498 | |||
1499 | sli4_cfg = &mbox->u.mqe.un.sli4_config; | ||
1500 | |||
1501 | /* For embedded mbox command, just free the mbox command */ | ||
1502 | if (bf_get(lpfc_mbox_hdr_emb, &sli4_cfg->header.cfg_mhdr)) { | ||
1503 | mempool_free(mbox, phba->mbox_mem_pool); | ||
1504 | return; | ||
1505 | } | ||
1506 | |||
1507 | /* For non-embedded mbox command, we need to free the pages first */ | ||
1508 | sgecount = bf_get(lpfc_mbox_hdr_sge_cnt, &sli4_cfg->header.cfg_mhdr); | ||
1509 | /* There is nothing we can do if there is no sge address array */ | ||
1510 | if (unlikely(!mbox->sge_array)) { | ||
1511 | mempool_free(mbox, phba->mbox_mem_pool); | ||
1512 | return; | ||
1513 | } | ||
1514 | /* Each non-embedded DMA memory was allocated in the length of a page */ | ||
1515 | for (sgentry = 0; sgentry < sgecount; sgentry++) { | ||
1516 | lpfc_sli4_mbx_sge_get(mbox, sgentry, &sge); | ||
1517 | phyaddr = getPaddr(sge.pa_hi, sge.pa_lo); | ||
1518 | dma_free_coherent(&phba->pcidev->dev, PAGE_SIZE, | ||
1519 | mbox->sge_array->addr[sgentry], phyaddr); | ||
1520 | } | ||
1521 | /* Free the sge address array memory */ | ||
1522 | kfree(mbox->sge_array); | ||
1523 | /* Finally, free the mailbox command itself */ | ||
1524 | mempool_free(mbox, phba->mbox_mem_pool); | ||
1525 | } | ||
1526 | |||
1527 | /** | ||
1528 | * lpfc_sli4_config - Initialize the SLI4 Config Mailbox command | ||
1529 | * @phba: pointer to lpfc hba data structure. | ||
1530 | * @mbox: pointer to lpfc mbox command. | ||
1531 | * @subsystem: The sli4 config sub mailbox subsystem. | ||
1532 | * @opcode: The sli4 config sub mailbox command opcode. | ||
1533 | * @length: Length of the sli4 config mailbox command. | ||
1534 | * | ||
1535 | * This routine sets up the header fields of SLI4 specific mailbox command | ||
1536 | * for sending IOCTL command. | ||
1537 | * | ||
1538 | * Return: the actual length of the mbox command allocated (mostly useful | ||
1539 | * for none embedded mailbox command). | ||
1540 | **/ | ||
1541 | int | ||
1542 | lpfc_sli4_config(struct lpfc_hba *phba, struct lpfcMboxq *mbox, | ||
1543 | uint8_t subsystem, uint8_t opcode, uint32_t length, bool emb) | ||
1544 | { | ||
1545 | struct lpfc_mbx_sli4_config *sli4_config; | ||
1546 | union lpfc_sli4_cfg_shdr *cfg_shdr = NULL; | ||
1547 | uint32_t alloc_len; | ||
1548 | uint32_t resid_len; | ||
1549 | uint32_t pagen, pcount; | ||
1550 | void *viraddr; | ||
1551 | dma_addr_t phyaddr; | ||
1552 | |||
1553 | /* Set up SLI4 mailbox command header fields */ | ||
1554 | memset(mbox, 0, sizeof(*mbox)); | ||
1555 | bf_set(lpfc_mqe_command, &mbox->u.mqe, MBX_SLI4_CONFIG); | ||
1556 | |||
1557 | /* Set up SLI4 ioctl command header fields */ | ||
1558 | sli4_config = &mbox->u.mqe.un.sli4_config; | ||
1559 | |||
1560 | /* Setup for the embedded mbox command */ | ||
1561 | if (emb) { | ||
1562 | /* Set up main header fields */ | ||
1563 | bf_set(lpfc_mbox_hdr_emb, &sli4_config->header.cfg_mhdr, 1); | ||
1564 | sli4_config->header.cfg_mhdr.payload_length = | ||
1565 | LPFC_MBX_CMD_HDR_LENGTH + length; | ||
1566 | /* Set up sub-header fields following main header */ | ||
1567 | bf_set(lpfc_mbox_hdr_opcode, | ||
1568 | &sli4_config->header.cfg_shdr.request, opcode); | ||
1569 | bf_set(lpfc_mbox_hdr_subsystem, | ||
1570 | &sli4_config->header.cfg_shdr.request, subsystem); | ||
1571 | sli4_config->header.cfg_shdr.request.request_length = length; | ||
1572 | return length; | ||
1573 | } | ||
1574 | |||
1575 | /* Setup for the none-embedded mbox command */ | ||
1576 | pcount = (PAGE_ALIGN(length))/PAGE_SIZE; | ||
1577 | pcount = (pcount > LPFC_SLI4_MBX_SGE_MAX_PAGES) ? | ||
1578 | LPFC_SLI4_MBX_SGE_MAX_PAGES : pcount; | ||
1579 | /* Allocate record for keeping SGE virtual addresses */ | ||
1580 | mbox->sge_array = kmalloc(sizeof(struct lpfc_mbx_nembed_sge_virt), | ||
1581 | GFP_KERNEL); | ||
1582 | if (!mbox->sge_array) | ||
1583 | return 0; | ||
1584 | |||
1585 | for (pagen = 0, alloc_len = 0; pagen < pcount; pagen++) { | ||
1586 | /* The DMA memory is always allocated in the length of a | ||
1587 | * page even though the last SGE might not fill up to a | ||
1588 | * page, this is used as a priori size of PAGE_SIZE for | ||
1589 | * the later DMA memory free. | ||
1590 | */ | ||
1591 | viraddr = dma_alloc_coherent(&phba->pcidev->dev, PAGE_SIZE, | ||
1592 | &phyaddr, GFP_KERNEL); | ||
1593 | /* In case of malloc fails, proceed with whatever we have */ | ||
1594 | if (!viraddr) | ||
1595 | break; | ||
1596 | mbox->sge_array->addr[pagen] = viraddr; | ||
1597 | /* Keep the first page for later sub-header construction */ | ||
1598 | if (pagen == 0) | ||
1599 | cfg_shdr = (union lpfc_sli4_cfg_shdr *)viraddr; | ||
1600 | resid_len = length - alloc_len; | ||
1601 | if (resid_len > PAGE_SIZE) { | ||
1602 | lpfc_sli4_mbx_sge_set(mbox, pagen, phyaddr, | ||
1603 | PAGE_SIZE); | ||
1604 | alloc_len += PAGE_SIZE; | ||
1605 | } else { | ||
1606 | lpfc_sli4_mbx_sge_set(mbox, pagen, phyaddr, | ||
1607 | resid_len); | ||
1608 | alloc_len = length; | ||
1609 | } | ||
1610 | } | ||
1611 | |||
1612 | /* Set up main header fields in mailbox command */ | ||
1613 | sli4_config->header.cfg_mhdr.payload_length = alloc_len; | ||
1614 | bf_set(lpfc_mbox_hdr_sge_cnt, &sli4_config->header.cfg_mhdr, pagen); | ||
1615 | |||
1616 | /* Set up sub-header fields into the first page */ | ||
1617 | if (pagen > 0) { | ||
1618 | bf_set(lpfc_mbox_hdr_opcode, &cfg_shdr->request, opcode); | ||
1619 | bf_set(lpfc_mbox_hdr_subsystem, &cfg_shdr->request, subsystem); | ||
1620 | cfg_shdr->request.request_length = | ||
1621 | alloc_len - sizeof(union lpfc_sli4_cfg_shdr); | ||
1622 | } | ||
1623 | /* The sub-header is in DMA memory, which needs endian converstion */ | ||
1624 | lpfc_sli_pcimem_bcopy(cfg_shdr, cfg_shdr, | ||
1625 | sizeof(union lpfc_sli4_cfg_shdr)); | ||
1626 | |||
1627 | return alloc_len; | ||
1628 | } | ||
1629 | |||
1630 | /** | ||
1631 | * lpfc_sli4_mbox_opcode_get - Get the opcode from a sli4 mailbox command | ||
1632 | * @phba: pointer to lpfc hba data structure. | ||
1633 | * @mbox: pointer to lpfc mbox command. | ||
1634 | * | ||
1635 | * This routine gets the opcode from a SLI4 specific mailbox command for | ||
1636 | * sending IOCTL command. If the mailbox command is not MBX_SLI4_CONFIG | ||
1637 | * (0x9B) or if the IOCTL sub-header is not present, opcode 0x0 shall be | ||
1638 | * returned. | ||
1639 | **/ | ||
1640 | uint8_t | ||
1641 | lpfc_sli4_mbox_opcode_get(struct lpfc_hba *phba, struct lpfcMboxq *mbox) | ||
1642 | { | ||
1643 | struct lpfc_mbx_sli4_config *sli4_cfg; | ||
1644 | union lpfc_sli4_cfg_shdr *cfg_shdr; | ||
1645 | |||
1646 | if (mbox->u.mb.mbxCommand != MBX_SLI4_CONFIG) | ||
1647 | return 0; | ||
1648 | sli4_cfg = &mbox->u.mqe.un.sli4_config; | ||
1649 | |||
1650 | /* For embedded mbox command, get opcode from embedded sub-header*/ | ||
1651 | if (bf_get(lpfc_mbox_hdr_emb, &sli4_cfg->header.cfg_mhdr)) { | ||
1652 | cfg_shdr = &mbox->u.mqe.un.sli4_config.header.cfg_shdr; | ||
1653 | return bf_get(lpfc_mbox_hdr_opcode, &cfg_shdr->request); | ||
1654 | } | ||
1655 | |||
1656 | /* For non-embedded mbox command, get opcode from first dma page */ | ||
1657 | if (unlikely(!mbox->sge_array)) | ||
1658 | return 0; | ||
1659 | cfg_shdr = (union lpfc_sli4_cfg_shdr *)mbox->sge_array->addr[0]; | ||
1660 | return bf_get(lpfc_mbox_hdr_opcode, &cfg_shdr->request); | ||
1661 | } | ||
1662 | |||
1663 | /** | ||
1664 | * lpfc_request_features: Configure SLI4 REQUEST_FEATURES mailbox | ||
1665 | * @mboxq: pointer to lpfc mbox command. | ||
1666 | * | ||
1667 | * This routine sets up the mailbox for an SLI4 REQUEST_FEATURES | ||
1668 | * mailbox command. | ||
1669 | **/ | ||
1670 | void | ||
1671 | lpfc_request_features(struct lpfc_hba *phba, struct lpfcMboxq *mboxq) | ||
1672 | { | ||
1673 | /* Set up SLI4 mailbox command header fields */ | ||
1674 | memset(mboxq, 0, sizeof(LPFC_MBOXQ_t)); | ||
1675 | bf_set(lpfc_mqe_command, &mboxq->u.mqe, MBX_SLI4_REQ_FTRS); | ||
1676 | |||
1677 | /* Set up host requested features. */ | ||
1678 | bf_set(lpfc_mbx_rq_ftr_rq_fcpi, &mboxq->u.mqe.un.req_ftrs, 1); | ||
1679 | |||
1680 | /* Virtual fabrics and FIPs are not supported yet. */ | ||
1681 | bf_set(lpfc_mbx_rq_ftr_rq_ifip, &mboxq->u.mqe.un.req_ftrs, 0); | ||
1682 | |||
1683 | /* Enable DIF (block guard) only if configured to do so. */ | ||
1684 | if (phba->cfg_enable_bg) | ||
1685 | bf_set(lpfc_mbx_rq_ftr_rq_dif, &mboxq->u.mqe.un.req_ftrs, 1); | ||
1686 | |||
1687 | /* Enable NPIV only if configured to do so. */ | ||
1688 | if (phba->max_vpi && phba->cfg_enable_npiv) | ||
1689 | bf_set(lpfc_mbx_rq_ftr_rq_npiv, &mboxq->u.mqe.un.req_ftrs, 1); | ||
1690 | |||
1691 | return; | ||
1692 | } | ||
1693 | |||
1694 | /** | ||
1695 | * lpfc_init_vfi - Initialize the INIT_VFI mailbox command | ||
1696 | * @mbox: pointer to lpfc mbox command to initialize. | ||
1697 | * @vport: Vport associated with the VF. | ||
1698 | * | ||
1699 | * This routine initializes @mbox to all zeros and then fills in the mailbox | ||
1700 | * fields from @vport. INIT_VFI configures virtual fabrics identified by VFI | ||
1701 | * in the context of an FCF. The driver issues this command to setup a VFI | ||
1702 | * before issuing a FLOGI to login to the VSAN. The driver should also issue a | ||
1703 | * REG_VFI after a successful VSAN login. | ||
1704 | **/ | ||
1705 | void | ||
1706 | lpfc_init_vfi(struct lpfcMboxq *mbox, struct lpfc_vport *vport) | ||
1707 | { | ||
1708 | struct lpfc_mbx_init_vfi *init_vfi; | ||
1709 | |||
1710 | memset(mbox, 0, sizeof(*mbox)); | ||
1711 | init_vfi = &mbox->u.mqe.un.init_vfi; | ||
1712 | bf_set(lpfc_mqe_command, &mbox->u.mqe, MBX_INIT_VFI); | ||
1713 | bf_set(lpfc_init_vfi_vr, init_vfi, 1); | ||
1714 | bf_set(lpfc_init_vfi_vt, init_vfi, 1); | ||
1715 | bf_set(lpfc_init_vfi_vfi, init_vfi, vport->vfi + vport->phba->vfi_base); | ||
1716 | bf_set(lpfc_init_vfi_fcfi, init_vfi, vport->phba->fcf.fcfi); | ||
1717 | } | ||
1718 | |||
1719 | /** | ||
1720 | * lpfc_reg_vfi - Initialize the REG_VFI mailbox command | ||
1721 | * @mbox: pointer to lpfc mbox command to initialize. | ||
1722 | * @vport: vport associated with the VF. | ||
1723 | * @phys: BDE DMA bus address used to send the service parameters to the HBA. | ||
1724 | * | ||
1725 | * This routine initializes @mbox to all zeros and then fills in the mailbox | ||
1726 | * fields from @vport, and uses @buf as a DMAable buffer to send the vport's | ||
1727 | * fc service parameters to the HBA for this VFI. REG_VFI configures virtual | ||
1728 | * fabrics identified by VFI in the context of an FCF. | ||
1729 | **/ | ||
1730 | void | ||
1731 | lpfc_reg_vfi(struct lpfcMboxq *mbox, struct lpfc_vport *vport, dma_addr_t phys) | ||
1732 | { | ||
1733 | struct lpfc_mbx_reg_vfi *reg_vfi; | ||
1734 | |||
1735 | memset(mbox, 0, sizeof(*mbox)); | ||
1736 | reg_vfi = &mbox->u.mqe.un.reg_vfi; | ||
1737 | bf_set(lpfc_mqe_command, &mbox->u.mqe, MBX_REG_VFI); | ||
1738 | bf_set(lpfc_reg_vfi_vp, reg_vfi, 1); | ||
1739 | bf_set(lpfc_reg_vfi_vfi, reg_vfi, vport->vfi + vport->phba->vfi_base); | ||
1740 | bf_set(lpfc_reg_vfi_fcfi, reg_vfi, vport->phba->fcf.fcfi); | ||
1741 | bf_set(lpfc_reg_vfi_vpi, reg_vfi, vport->vpi + vport->phba->vpi_base); | ||
1742 | reg_vfi->bde.addrHigh = putPaddrHigh(phys); | ||
1743 | reg_vfi->bde.addrLow = putPaddrLow(phys); | ||
1744 | reg_vfi->bde.tus.f.bdeSize = sizeof(vport->fc_sparam); | ||
1745 | reg_vfi->bde.tus.f.bdeFlags = BUFF_TYPE_BDE_64; | ||
1746 | bf_set(lpfc_reg_vfi_nport_id, reg_vfi, vport->fc_myDID); | ||
1747 | } | ||
1748 | |||
1749 | /** | ||
1750 | * lpfc_init_vpi - Initialize the INIT_VPI mailbox command | ||
1751 | * @mbox: pointer to lpfc mbox command to initialize. | ||
1752 | * @vpi: VPI to be initialized. | ||
1753 | * | ||
1754 | * The INIT_VPI mailbox command supports virtual N_Ports. The driver uses the | ||
1755 | * command to activate a virtual N_Port. The HBA assigns a MAC address to use | ||
1756 | * with the virtual N Port. The SLI Host issues this command before issuing a | ||
1757 | * FDISC to connect to the Fabric. The SLI Host should issue a REG_VPI after a | ||
1758 | * successful virtual NPort login. | ||
1759 | **/ | ||
1760 | void | ||
1761 | lpfc_init_vpi(struct lpfcMboxq *mbox, uint16_t vpi) | ||
1762 | { | ||
1763 | memset(mbox, 0, sizeof(*mbox)); | ||
1764 | bf_set(lpfc_mqe_command, &mbox->u.mqe, MBX_INIT_VPI); | ||
1765 | bf_set(lpfc_init_vpi_vpi, &mbox->u.mqe.un.init_vpi, vpi); | ||
1766 | } | ||
1767 | |||
1768 | /** | ||
1769 | * lpfc_unreg_vfi - Initialize the UNREG_VFI mailbox command | ||
1770 | * @mbox: pointer to lpfc mbox command to initialize. | ||
1771 | * @vfi: VFI to be unregistered. | ||
1772 | * | ||
1773 | * The UNREG_VFI mailbox command causes the SLI Host to put a virtual fabric | ||
1774 | * (logical NPort) into the inactive state. The SLI Host must have logged out | ||
1775 | * and unregistered all remote N_Ports to abort any activity on the virtual | ||
1776 | * fabric. The SLI Port posts the mailbox response after marking the virtual | ||
1777 | * fabric inactive. | ||
1778 | **/ | ||
1779 | void | ||
1780 | lpfc_unreg_vfi(struct lpfcMboxq *mbox, uint16_t vfi) | ||
1781 | { | ||
1782 | memset(mbox, 0, sizeof(*mbox)); | ||
1783 | bf_set(lpfc_mqe_command, &mbox->u.mqe, MBX_UNREG_VFI); | ||
1784 | bf_set(lpfc_unreg_vfi_vfi, &mbox->u.mqe.un.unreg_vfi, vfi); | ||
1785 | } | ||
1786 | |||
1787 | /** | ||
1788 | * lpfc_dump_fcoe_param - Dump config region 23 to get FCoe parameters. | ||
1789 | * @phba: pointer to the hba structure containing. | ||
1790 | * @mbox: pointer to lpfc mbox command to initialize. | ||
1791 | * | ||
1792 | * This function create a SLI4 dump mailbox command to dump FCoE | ||
1793 | * parameters stored in region 23. | ||
1794 | **/ | ||
1795 | int | ||
1796 | lpfc_dump_fcoe_param(struct lpfc_hba *phba, | ||
1797 | struct lpfcMboxq *mbox) | ||
1798 | { | ||
1799 | struct lpfc_dmabuf *mp = NULL; | ||
1800 | MAILBOX_t *mb; | ||
1801 | |||
1802 | memset(mbox, 0, sizeof(*mbox)); | ||
1803 | mb = &mbox->u.mb; | ||
1804 | |||
1805 | mp = kmalloc(sizeof(struct lpfc_dmabuf), GFP_KERNEL); | ||
1806 | if (mp) | ||
1807 | mp->virt = lpfc_mbuf_alloc(phba, 0, &mp->phys); | ||
1808 | |||
1809 | if (!mp || !mp->virt) { | ||
1810 | kfree(mp); | ||
1811 | /* dump_fcoe_param failed to allocate memory */ | ||
1812 | lpfc_printf_log(phba, KERN_WARNING, LOG_MBOX, | ||
1813 | "2569 lpfc_dump_fcoe_param: memory" | ||
1814 | " allocation failed \n"); | ||
1815 | return 1; | ||
1816 | } | ||
1817 | |||
1818 | memset(mp->virt, 0, LPFC_BPL_SIZE); | ||
1819 | INIT_LIST_HEAD(&mp->list); | ||
1820 | |||
1821 | /* save address for completion */ | ||
1822 | mbox->context1 = (uint8_t *) mp; | ||
1823 | |||
1824 | mb->mbxCommand = MBX_DUMP_MEMORY; | ||
1825 | mb->un.varDmp.type = DMP_NV_PARAMS; | ||
1826 | mb->un.varDmp.region_id = DMP_REGION_FCOEPARAM; | ||
1827 | mb->un.varDmp.sli4_length = DMP_FCOEPARAM_RGN_SIZE; | ||
1828 | mb->un.varWords[3] = putPaddrLow(mp->phys); | ||
1829 | mb->un.varWords[4] = putPaddrHigh(mp->phys); | ||
1830 | return 0; | ||
1831 | } | ||
1832 | |||
1833 | /** | ||
1834 | * lpfc_reg_fcfi - Initialize the REG_FCFI mailbox command | ||
1835 | * @phba: pointer to the hba structure containing the FCF index and RQ ID. | ||
1836 | * @mbox: pointer to lpfc mbox command to initialize. | ||
1837 | * | ||
1838 | * The REG_FCFI mailbox command supports Fibre Channel Forwarders (FCFs). The | ||
1839 | * SLI Host uses the command to activate an FCF after it has acquired FCF | ||
1840 | * information via a READ_FCF mailbox command. This mailbox command also is used | ||
1841 | * to indicate where received unsolicited frames from this FCF will be sent. By | ||
1842 | * default this routine will set up the FCF to forward all unsolicited frames | ||
1843 | * the the RQ ID passed in the @phba. This can be overridden by the caller for | ||
1844 | * more complicated setups. | ||
1845 | **/ | ||
1846 | void | ||
1847 | lpfc_reg_fcfi(struct lpfc_hba *phba, struct lpfcMboxq *mbox) | ||
1848 | { | ||
1849 | struct lpfc_mbx_reg_fcfi *reg_fcfi; | ||
1850 | |||
1851 | memset(mbox, 0, sizeof(*mbox)); | ||
1852 | reg_fcfi = &mbox->u.mqe.un.reg_fcfi; | ||
1853 | bf_set(lpfc_mqe_command, &mbox->u.mqe, MBX_REG_FCFI); | ||
1854 | bf_set(lpfc_reg_fcfi_rq_id0, reg_fcfi, phba->sli4_hba.hdr_rq->queue_id); | ||
1855 | bf_set(lpfc_reg_fcfi_rq_id1, reg_fcfi, REG_FCF_INVALID_QID); | ||
1856 | bf_set(lpfc_reg_fcfi_rq_id2, reg_fcfi, REG_FCF_INVALID_QID); | ||
1857 | bf_set(lpfc_reg_fcfi_rq_id3, reg_fcfi, REG_FCF_INVALID_QID); | ||
1858 | bf_set(lpfc_reg_fcfi_info_index, reg_fcfi, phba->fcf.fcf_indx); | ||
1859 | /* reg_fcf addr mode is bit wise inverted value of fcf addr_mode */ | ||
1860 | bf_set(lpfc_reg_fcfi_mam, reg_fcfi, | ||
1861 | (~phba->fcf.addr_mode) & 0x3); | ||
1862 | if (phba->fcf.fcf_flag & FCF_VALID_VLAN) { | ||
1863 | bf_set(lpfc_reg_fcfi_vv, reg_fcfi, 1); | ||
1864 | bf_set(lpfc_reg_fcfi_vlan_tag, reg_fcfi, phba->fcf.vlan_id); | ||
1865 | } | ||
1866 | } | ||
1867 | |||
1868 | /** | ||
1869 | * lpfc_unreg_fcfi - Initialize the UNREG_FCFI mailbox command | ||
1870 | * @mbox: pointer to lpfc mbox command to initialize. | ||
1871 | * @fcfi: FCFI to be unregistered. | ||
1872 | * | ||
1873 | * The UNREG_FCFI mailbox command supports Fibre Channel Forwarders (FCFs). | ||
1874 | * The SLI Host uses the command to inactivate an FCFI. | ||
1875 | **/ | ||
1876 | void | ||
1877 | lpfc_unreg_fcfi(struct lpfcMboxq *mbox, uint16_t fcfi) | ||
1878 | { | ||
1879 | memset(mbox, 0, sizeof(*mbox)); | ||
1880 | bf_set(lpfc_mqe_command, &mbox->u.mqe, MBX_UNREG_FCFI); | ||
1881 | bf_set(lpfc_unreg_fcfi, &mbox->u.mqe.un.unreg_fcfi, fcfi); | ||
1882 | } | ||
1883 | |||
1884 | /** | ||
1885 | * lpfc_resume_rpi - Initialize the RESUME_RPI mailbox command | ||
1886 | * @mbox: pointer to lpfc mbox command to initialize. | ||
1887 | * @ndlp: The nodelist structure that describes the RPI to resume. | ||
1888 | * | ||
1889 | * The RESUME_RPI mailbox command is used to restart I/O to an RPI after a | ||
1890 | * link event. | ||
1891 | **/ | ||
1892 | void | ||
1893 | lpfc_resume_rpi(struct lpfcMboxq *mbox, struct lpfc_nodelist *ndlp) | ||
1894 | { | ||
1895 | struct lpfc_mbx_resume_rpi *resume_rpi; | ||
1896 | |||
1897 | memset(mbox, 0, sizeof(*mbox)); | ||
1898 | resume_rpi = &mbox->u.mqe.un.resume_rpi; | ||
1899 | bf_set(lpfc_mqe_command, &mbox->u.mqe, MBX_RESUME_RPI); | ||
1900 | bf_set(lpfc_resume_rpi_rpi, resume_rpi, ndlp->nlp_rpi); | ||
1901 | bf_set(lpfc_resume_rpi_vpi, resume_rpi, | ||
1902 | ndlp->vport->vpi + ndlp->vport->phba->vpi_base); | ||
1903 | bf_set(lpfc_resume_rpi_vfi, resume_rpi, | ||
1904 | ndlp->vport->vfi + ndlp->vport->phba->vfi_base); | ||
1905 | } | ||
diff --git a/drivers/scsi/lpfc/lpfc_nportdisc.c b/drivers/scsi/lpfc/lpfc_nportdisc.c index 6ba5a72f6049..6efe459e8ddf 100644 --- a/drivers/scsi/lpfc/lpfc_nportdisc.c +++ b/drivers/scsi/lpfc/lpfc_nportdisc.c | |||
@@ -1192,7 +1192,7 @@ lpfc_rcv_logo_reglogin_issue(struct lpfc_vport *vport, | |||
1192 | 1192 | ||
1193 | /* cleanup any ndlp on mbox q waiting for reglogin cmpl */ | 1193 | /* cleanup any ndlp on mbox q waiting for reglogin cmpl */ |
1194 | if ((mb = phba->sli.mbox_active)) { | 1194 | if ((mb = phba->sli.mbox_active)) { |
1195 | if ((mb->mb.mbxCommand == MBX_REG_LOGIN64) && | 1195 | if ((mb->u.mb.mbxCommand == MBX_REG_LOGIN64) && |
1196 | (ndlp == (struct lpfc_nodelist *) mb->context2)) { | 1196 | (ndlp == (struct lpfc_nodelist *) mb->context2)) { |
1197 | lpfc_nlp_put(ndlp); | 1197 | lpfc_nlp_put(ndlp); |
1198 | mb->context2 = NULL; | 1198 | mb->context2 = NULL; |
@@ -1202,7 +1202,7 @@ lpfc_rcv_logo_reglogin_issue(struct lpfc_vport *vport, | |||
1202 | 1202 | ||
1203 | spin_lock_irq(&phba->hbalock); | 1203 | spin_lock_irq(&phba->hbalock); |
1204 | list_for_each_entry_safe(mb, nextmb, &phba->sli.mboxq, list) { | 1204 | list_for_each_entry_safe(mb, nextmb, &phba->sli.mboxq, list) { |
1205 | if ((mb->mb.mbxCommand == MBX_REG_LOGIN64) && | 1205 | if ((mb->u.mb.mbxCommand == MBX_REG_LOGIN64) && |
1206 | (ndlp == (struct lpfc_nodelist *) mb->context2)) { | 1206 | (ndlp == (struct lpfc_nodelist *) mb->context2)) { |
1207 | mp = (struct lpfc_dmabuf *) (mb->context1); | 1207 | mp = (struct lpfc_dmabuf *) (mb->context1); |
1208 | if (mp) { | 1208 | if (mp) { |
@@ -1253,7 +1253,7 @@ lpfc_cmpl_reglogin_reglogin_issue(struct lpfc_vport *vport, | |||
1253 | { | 1253 | { |
1254 | struct Scsi_Host *shost = lpfc_shost_from_vport(vport); | 1254 | struct Scsi_Host *shost = lpfc_shost_from_vport(vport); |
1255 | LPFC_MBOXQ_t *pmb = (LPFC_MBOXQ_t *) arg; | 1255 | LPFC_MBOXQ_t *pmb = (LPFC_MBOXQ_t *) arg; |
1256 | MAILBOX_t *mb = &pmb->mb; | 1256 | MAILBOX_t *mb = &pmb->u.mb; |
1257 | uint32_t did = mb->un.varWords[1]; | 1257 | uint32_t did = mb->un.varWords[1]; |
1258 | 1258 | ||
1259 | if (mb->mbxStatus) { | 1259 | if (mb->mbxStatus) { |
@@ -1880,11 +1880,12 @@ lpfc_cmpl_reglogin_npr_node(struct lpfc_vport *vport, | |||
1880 | void *arg, uint32_t evt) | 1880 | void *arg, uint32_t evt) |
1881 | { | 1881 | { |
1882 | LPFC_MBOXQ_t *pmb = (LPFC_MBOXQ_t *) arg; | 1882 | LPFC_MBOXQ_t *pmb = (LPFC_MBOXQ_t *) arg; |
1883 | MAILBOX_t *mb = &pmb->mb; | 1883 | MAILBOX_t *mb = &pmb->u.mb; |
1884 | 1884 | ||
1885 | if (!mb->mbxStatus) | 1885 | if (!mb->mbxStatus) { |
1886 | ndlp->nlp_rpi = mb->un.varWords[0]; | 1886 | ndlp->nlp_rpi = mb->un.varWords[0]; |
1887 | else { | 1887 | ndlp->nlp_flag |= NLP_RPI_VALID; |
1888 | } else { | ||
1888 | if (ndlp->nlp_flag & NLP_NODEV_REMOVE) { | 1889 | if (ndlp->nlp_flag & NLP_NODEV_REMOVE) { |
1889 | lpfc_drop_node(vport, ndlp); | 1890 | lpfc_drop_node(vport, ndlp); |
1890 | return NLP_STE_FREED_NODE; | 1891 | return NLP_STE_FREED_NODE; |
diff --git a/drivers/scsi/lpfc/lpfc_sli.c b/drivers/scsi/lpfc/lpfc_sli.c index cf42ada3ffcd..b53af9936282 100644 --- a/drivers/scsi/lpfc/lpfc_sli.c +++ b/drivers/scsi/lpfc/lpfc_sli.c | |||
@@ -43,24 +43,7 @@ | |||
43 | #include "lpfc_logmsg.h" | 43 | #include "lpfc_logmsg.h" |
44 | #include "lpfc_compat.h" | 44 | #include "lpfc_compat.h" |
45 | #include "lpfc_debugfs.h" | 45 | #include "lpfc_debugfs.h" |
46 | 46 | #include "lpfc_vport.h" | |
47 | /* | ||
48 | * Define macro to log: Mailbox command x%x cannot issue Data | ||
49 | * This allows multiple uses of lpfc_msgBlk0311 | ||
50 | * w/o perturbing log msg utility. | ||
51 | */ | ||
52 | #define LOG_MBOX_CANNOT_ISSUE_DATA(phba, pmbox, psli, flag) \ | ||
53 | lpfc_printf_log(phba, \ | ||
54 | KERN_INFO, \ | ||
55 | LOG_MBOX | LOG_SLI, \ | ||
56 | "(%d):0311 Mailbox command x%x cannot " \ | ||
57 | "issue Data: x%x x%x x%x\n", \ | ||
58 | pmbox->vport ? pmbox->vport->vpi : 0, \ | ||
59 | pmbox->mb.mbxCommand, \ | ||
60 | phba->pport->port_state, \ | ||
61 | psli->sli_flag, \ | ||
62 | flag) | ||
63 | |||
64 | 47 | ||
65 | /* There are only four IOCB completion types. */ | 48 | /* There are only four IOCB completion types. */ |
66 | typedef enum _lpfc_iocb_type { | 49 | typedef enum _lpfc_iocb_type { |
@@ -843,7 +826,7 @@ lpfc_sli_ring_map(struct lpfc_hba *phba) | |||
843 | pmb = (LPFC_MBOXQ_t *) mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL); | 826 | pmb = (LPFC_MBOXQ_t *) mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL); |
844 | if (!pmb) | 827 | if (!pmb) |
845 | return -ENOMEM; | 828 | return -ENOMEM; |
846 | pmbox = &pmb->mb; | 829 | pmbox = &pmb->u.mb; |
847 | phba->link_state = LPFC_INIT_MBX_CMDS; | 830 | phba->link_state = LPFC_INIT_MBX_CMDS; |
848 | for (i = 0; i < psli->num_rings; i++) { | 831 | for (i = 0; i < psli->num_rings; i++) { |
849 | lpfc_config_ring(phba, i, pmb); | 832 | lpfc_config_ring(phba, i, pmb); |
@@ -1652,6 +1635,15 @@ lpfc_sli_chk_mbx_command(uint8_t mbxCommand) | |||
1652 | case MBX_HEARTBEAT: | 1635 | case MBX_HEARTBEAT: |
1653 | case MBX_PORT_CAPABILITIES: | 1636 | case MBX_PORT_CAPABILITIES: |
1654 | case MBX_PORT_IOV_CONTROL: | 1637 | case MBX_PORT_IOV_CONTROL: |
1638 | case MBX_SLI4_CONFIG: | ||
1639 | case MBX_SLI4_REQ_FTRS: | ||
1640 | case MBX_REG_FCFI: | ||
1641 | case MBX_UNREG_FCFI: | ||
1642 | case MBX_REG_VFI: | ||
1643 | case MBX_UNREG_VFI: | ||
1644 | case MBX_INIT_VPI: | ||
1645 | case MBX_INIT_VFI: | ||
1646 | case MBX_RESUME_RPI: | ||
1655 | ret = mbxCommand; | 1647 | ret = mbxCommand; |
1656 | break; | 1648 | break; |
1657 | default: | 1649 | default: |
@@ -1672,7 +1664,7 @@ lpfc_sli_chk_mbx_command(uint8_t mbxCommand) | |||
1672 | * will wake up thread waiting on the wait queue pointed by context1 | 1664 | * will wake up thread waiting on the wait queue pointed by context1 |
1673 | * of the mailbox. | 1665 | * of the mailbox. |
1674 | **/ | 1666 | **/ |
1675 | static void | 1667 | void |
1676 | lpfc_sli_wake_mbox_wait(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmboxq) | 1668 | lpfc_sli_wake_mbox_wait(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmboxq) |
1677 | { | 1669 | { |
1678 | wait_queue_head_t *pdone_q; | 1670 | wait_queue_head_t *pdone_q; |
@@ -1706,7 +1698,7 @@ void | |||
1706 | lpfc_sli_def_mbox_cmpl(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb) | 1698 | lpfc_sli_def_mbox_cmpl(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb) |
1707 | { | 1699 | { |
1708 | struct lpfc_dmabuf *mp; | 1700 | struct lpfc_dmabuf *mp; |
1709 | uint16_t rpi; | 1701 | uint16_t rpi, vpi; |
1710 | int rc; | 1702 | int rc; |
1711 | 1703 | ||
1712 | mp = (struct lpfc_dmabuf *) (pmb->context1); | 1704 | mp = (struct lpfc_dmabuf *) (pmb->context1); |
@@ -1716,24 +1708,30 @@ lpfc_sli_def_mbox_cmpl(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb) | |||
1716 | kfree(mp); | 1708 | kfree(mp); |
1717 | } | 1709 | } |
1718 | 1710 | ||
1711 | if ((pmb->u.mb.mbxCommand == MBX_UNREG_LOGIN) && | ||
1712 | (phba->sli_rev == LPFC_SLI_REV4)) | ||
1713 | lpfc_sli4_free_rpi(phba, pmb->u.mb.un.varUnregLogin.rpi); | ||
1714 | |||
1719 | /* | 1715 | /* |
1720 | * If a REG_LOGIN succeeded after node is destroyed or node | 1716 | * If a REG_LOGIN succeeded after node is destroyed or node |
1721 | * is in re-discovery driver need to cleanup the RPI. | 1717 | * is in re-discovery driver need to cleanup the RPI. |
1722 | */ | 1718 | */ |
1723 | if (!(phba->pport->load_flag & FC_UNLOADING) && | 1719 | if (!(phba->pport->load_flag & FC_UNLOADING) && |
1724 | pmb->mb.mbxCommand == MBX_REG_LOGIN64 && | 1720 | pmb->u.mb.mbxCommand == MBX_REG_LOGIN64 && |
1725 | !pmb->mb.mbxStatus) { | 1721 | !pmb->u.mb.mbxStatus) { |
1726 | 1722 | rpi = pmb->u.mb.un.varWords[0]; | |
1727 | rpi = pmb->mb.un.varWords[0]; | 1723 | vpi = pmb->u.mb.un.varRegLogin.vpi - phba->vpi_base; |
1728 | lpfc_unreg_login(phba, pmb->mb.un.varRegLogin.vpi, rpi, pmb); | 1724 | lpfc_unreg_login(phba, vpi, rpi, pmb); |
1729 | pmb->mbox_cmpl = lpfc_sli_def_mbox_cmpl; | 1725 | pmb->mbox_cmpl = lpfc_sli_def_mbox_cmpl; |
1730 | rc = lpfc_sli_issue_mbox(phba, pmb, MBX_NOWAIT); | 1726 | rc = lpfc_sli_issue_mbox(phba, pmb, MBX_NOWAIT); |
1731 | if (rc != MBX_NOT_FINISHED) | 1727 | if (rc != MBX_NOT_FINISHED) |
1732 | return; | 1728 | return; |
1733 | } | 1729 | } |
1734 | 1730 | ||
1735 | mempool_free(pmb, phba->mbox_mem_pool); | 1731 | if (bf_get(lpfc_mqe_command, &pmb->u.mqe) == MBX_SLI4_CONFIG) |
1736 | return; | 1732 | lpfc_sli4_mbox_cmd_free(phba, pmb); |
1733 | else | ||
1734 | mempool_free(pmb, phba->mbox_mem_pool); | ||
1737 | } | 1735 | } |
1738 | 1736 | ||
1739 | /** | 1737 | /** |
@@ -1770,7 +1768,7 @@ lpfc_sli_handle_mb_event(struct lpfc_hba *phba) | |||
1770 | if (pmb == NULL) | 1768 | if (pmb == NULL) |
1771 | break; | 1769 | break; |
1772 | 1770 | ||
1773 | pmbox = &pmb->mb; | 1771 | pmbox = &pmb->u.mb; |
1774 | 1772 | ||
1775 | if (pmbox->mbxCommand != MBX_HEARTBEAT) { | 1773 | if (pmbox->mbxCommand != MBX_HEARTBEAT) { |
1776 | if (pmb->vport) { | 1774 | if (pmb->vport) { |
@@ -1799,9 +1797,10 @@ lpfc_sli_handle_mb_event(struct lpfc_hba *phba) | |||
1799 | /* Unknow mailbox command compl */ | 1797 | /* Unknow mailbox command compl */ |
1800 | lpfc_printf_log(phba, KERN_ERR, LOG_MBOX | LOG_SLI, | 1798 | lpfc_printf_log(phba, KERN_ERR, LOG_MBOX | LOG_SLI, |
1801 | "(%d):0323 Unknown Mailbox command " | 1799 | "(%d):0323 Unknown Mailbox command " |
1802 | "%x Cmpl\n", | 1800 | "x%x (x%x) Cmpl\n", |
1803 | pmb->vport ? pmb->vport->vpi : 0, | 1801 | pmb->vport ? pmb->vport->vpi : 0, |
1804 | pmbox->mbxCommand); | 1802 | pmbox->mbxCommand, |
1803 | lpfc_sli4_mbox_opcode_get(phba, pmb)); | ||
1805 | phba->link_state = LPFC_HBA_ERROR; | 1804 | phba->link_state = LPFC_HBA_ERROR; |
1806 | phba->work_hs = HS_FFER3; | 1805 | phba->work_hs = HS_FFER3; |
1807 | lpfc_handle_eratt(phba); | 1806 | lpfc_handle_eratt(phba); |
@@ -1816,29 +1815,29 @@ lpfc_sli_handle_mb_event(struct lpfc_hba *phba) | |||
1816 | LOG_MBOX | LOG_SLI, | 1815 | LOG_MBOX | LOG_SLI, |
1817 | "(%d):0305 Mbox cmd cmpl " | 1816 | "(%d):0305 Mbox cmd cmpl " |
1818 | "error - RETRYing Data: x%x " | 1817 | "error - RETRYing Data: x%x " |
1819 | "x%x x%x x%x\n", | 1818 | "(x%x) x%x x%x x%x\n", |
1820 | pmb->vport ? pmb->vport->vpi :0, | 1819 | pmb->vport ? pmb->vport->vpi :0, |
1821 | pmbox->mbxCommand, | 1820 | pmbox->mbxCommand, |
1821 | lpfc_sli4_mbox_opcode_get(phba, | ||
1822 | pmb), | ||
1822 | pmbox->mbxStatus, | 1823 | pmbox->mbxStatus, |
1823 | pmbox->un.varWords[0], | 1824 | pmbox->un.varWords[0], |
1824 | pmb->vport->port_state); | 1825 | pmb->vport->port_state); |
1825 | pmbox->mbxStatus = 0; | 1826 | pmbox->mbxStatus = 0; |
1826 | pmbox->mbxOwner = OWN_HOST; | 1827 | pmbox->mbxOwner = OWN_HOST; |
1827 | spin_lock_irq(&phba->hbalock); | ||
1828 | phba->sli.sli_flag &= ~LPFC_SLI_MBOX_ACTIVE; | ||
1829 | spin_unlock_irq(&phba->hbalock); | ||
1830 | rc = lpfc_sli_issue_mbox(phba, pmb, MBX_NOWAIT); | 1828 | rc = lpfc_sli_issue_mbox(phba, pmb, MBX_NOWAIT); |
1831 | if (rc == MBX_SUCCESS) | 1829 | if (rc != MBX_NOT_FINISHED) |
1832 | continue; | 1830 | continue; |
1833 | } | 1831 | } |
1834 | } | 1832 | } |
1835 | 1833 | ||
1836 | /* Mailbox cmd <cmd> Cmpl <cmpl> */ | 1834 | /* Mailbox cmd <cmd> Cmpl <cmpl> */ |
1837 | lpfc_printf_log(phba, KERN_INFO, LOG_MBOX | LOG_SLI, | 1835 | lpfc_printf_log(phba, KERN_INFO, LOG_MBOX | LOG_SLI, |
1838 | "(%d):0307 Mailbox cmd x%x Cmpl x%p " | 1836 | "(%d):0307 Mailbox cmd x%x (x%x) Cmpl x%p " |
1839 | "Data: x%x x%x x%x x%x x%x x%x x%x x%x x%x\n", | 1837 | "Data: x%x x%x x%x x%x x%x x%x x%x x%x x%x\n", |
1840 | pmb->vport ? pmb->vport->vpi : 0, | 1838 | pmb->vport ? pmb->vport->vpi : 0, |
1841 | pmbox->mbxCommand, | 1839 | pmbox->mbxCommand, |
1840 | lpfc_sli4_mbox_opcode_get(phba, pmb), | ||
1842 | pmb->mbox_cmpl, | 1841 | pmb->mbox_cmpl, |
1843 | *((uint32_t *) pmbox), | 1842 | *((uint32_t *) pmbox), |
1844 | pmbox->un.varWords[0], | 1843 | pmbox->un.varWords[0], |
@@ -3377,10 +3376,10 @@ lpfc_sli_brdkill(struct lpfc_hba *phba) | |||
3377 | } | 3376 | } |
3378 | spin_lock_irq(&phba->hbalock); | 3377 | spin_lock_irq(&phba->hbalock); |
3379 | psli->sli_flag &= ~LPFC_SLI_MBOX_ACTIVE; | 3378 | psli->sli_flag &= ~LPFC_SLI_MBOX_ACTIVE; |
3379 | psli->mbox_active = NULL; | ||
3380 | phba->link_flag &= ~LS_IGNORE_ERATT; | 3380 | phba->link_flag &= ~LS_IGNORE_ERATT; |
3381 | spin_unlock_irq(&phba->hbalock); | 3381 | spin_unlock_irq(&phba->hbalock); |
3382 | 3382 | ||
3383 | psli->mbox_active = NULL; | ||
3384 | lpfc_hba_down_post(phba); | 3383 | lpfc_hba_down_post(phba); |
3385 | phba->link_state = LPFC_HBA_ERROR; | 3384 | phba->link_state = LPFC_HBA_ERROR; |
3386 | 3385 | ||
@@ -3790,7 +3789,7 @@ lpfc_sli_hbq_setup(struct lpfc_hba *phba) | |||
3790 | if (!pmb) | 3789 | if (!pmb) |
3791 | return -ENOMEM; | 3790 | return -ENOMEM; |
3792 | 3791 | ||
3793 | pmbox = &pmb->mb; | 3792 | pmbox = &pmb->u.mb; |
3794 | 3793 | ||
3795 | /* Initialize the struct lpfc_sli_hbq structure for each hbq */ | 3794 | /* Initialize the struct lpfc_sli_hbq structure for each hbq */ |
3796 | phba->link_state = LPFC_INIT_MBX_CMDS; | 3795 | phba->link_state = LPFC_INIT_MBX_CMDS; |
@@ -3917,33 +3916,43 @@ lpfc_sli_config_port(struct lpfc_hba *phba, int sli_mode) | |||
3917 | lpfc_printf_log(phba, KERN_ERR, LOG_INIT, | 3916 | lpfc_printf_log(phba, KERN_ERR, LOG_INIT, |
3918 | "0442 Adapter failed to init, mbxCmd x%x " | 3917 | "0442 Adapter failed to init, mbxCmd x%x " |
3919 | "CONFIG_PORT, mbxStatus x%x Data: x%x\n", | 3918 | "CONFIG_PORT, mbxStatus x%x Data: x%x\n", |
3920 | pmb->mb.mbxCommand, pmb->mb.mbxStatus, 0); | 3919 | pmb->u.mb.mbxCommand, pmb->u.mb.mbxStatus, 0); |
3921 | spin_lock_irq(&phba->hbalock); | 3920 | spin_lock_irq(&phba->hbalock); |
3922 | phba->sli.sli_flag &= ~LPFC_SLI2_ACTIVE; | 3921 | phba->sli.sli_flag &= ~LPFC_SLI_ACTIVE; |
3923 | spin_unlock_irq(&phba->hbalock); | 3922 | spin_unlock_irq(&phba->hbalock); |
3924 | rc = -ENXIO; | 3923 | rc = -ENXIO; |
3925 | } else | 3924 | } else { |
3925 | /* Allow asynchronous mailbox command to go through */ | ||
3926 | spin_lock_irq(&phba->hbalock); | ||
3927 | phba->sli.sli_flag &= ~LPFC_SLI_ASYNC_MBX_BLK; | ||
3928 | spin_unlock_irq(&phba->hbalock); | ||
3926 | done = 1; | 3929 | done = 1; |
3930 | } | ||
3927 | } | 3931 | } |
3928 | if (!done) { | 3932 | if (!done) { |
3929 | rc = -EINVAL; | 3933 | rc = -EINVAL; |
3930 | goto do_prep_failed; | 3934 | goto do_prep_failed; |
3931 | } | 3935 | } |
3932 | if (pmb->mb.un.varCfgPort.sli_mode == 3) { | 3936 | if (pmb->u.mb.un.varCfgPort.sli_mode == 3) { |
3933 | if (!pmb->mb.un.varCfgPort.cMA) { | 3937 | if (!pmb->u.mb.un.varCfgPort.cMA) { |
3934 | rc = -ENXIO; | 3938 | rc = -ENXIO; |
3935 | goto do_prep_failed; | 3939 | goto do_prep_failed; |
3936 | } | 3940 | } |
3937 | if (phba->max_vpi && pmb->mb.un.varCfgPort.gmv) { | 3941 | if (phba->max_vpi && pmb->u.mb.un.varCfgPort.gmv) { |
3938 | phba->sli3_options |= LPFC_SLI3_NPIV_ENABLED; | 3942 | phba->sli3_options |= LPFC_SLI3_NPIV_ENABLED; |
3939 | phba->max_vpi = pmb->mb.un.varCfgPort.max_vpi; | 3943 | phba->max_vpi = pmb->u.mb.un.varCfgPort.max_vpi; |
3944 | phba->max_vports = (phba->max_vpi > phba->max_vports) ? | ||
3945 | phba->max_vpi : phba->max_vports; | ||
3946 | |||
3940 | } else | 3947 | } else |
3941 | phba->max_vpi = 0; | 3948 | phba->max_vpi = 0; |
3942 | if (pmb->mb.un.varCfgPort.gerbm) | 3949 | if (pmb->u.mb.un.varCfgPort.gdss) |
3950 | phba->sli3_options |= LPFC_SLI3_DSS_ENABLED; | ||
3951 | if (pmb->u.mb.un.varCfgPort.gerbm) | ||
3943 | phba->sli3_options |= LPFC_SLI3_HBQ_ENABLED; | 3952 | phba->sli3_options |= LPFC_SLI3_HBQ_ENABLED; |
3944 | if (pmb->mb.un.varCfgPort.gcrp) | 3953 | if (pmb->u.mb.un.varCfgPort.gcrp) |
3945 | phba->sli3_options |= LPFC_SLI3_CRP_ENABLED; | 3954 | phba->sli3_options |= LPFC_SLI3_CRP_ENABLED; |
3946 | if (pmb->mb.un.varCfgPort.ginb) { | 3955 | if (pmb->u.mb.un.varCfgPort.ginb) { |
3947 | phba->sli3_options |= LPFC_SLI3_INB_ENABLED; | 3956 | phba->sli3_options |= LPFC_SLI3_INB_ENABLED; |
3948 | phba->hbq_get = phba->mbox->us.s3_inb_pgp.hbq_get; | 3957 | phba->hbq_get = phba->mbox->us.s3_inb_pgp.hbq_get; |
3949 | phba->port_gp = phba->mbox->us.s3_inb_pgp.port; | 3958 | phba->port_gp = phba->mbox->us.s3_inb_pgp.port; |
@@ -3959,7 +3968,7 @@ lpfc_sli_config_port(struct lpfc_hba *phba, int sli_mode) | |||
3959 | } | 3968 | } |
3960 | 3969 | ||
3961 | if (phba->cfg_enable_bg) { | 3970 | if (phba->cfg_enable_bg) { |
3962 | if (pmb->mb.un.varCfgPort.gbg) | 3971 | if (pmb->u.mb.un.varCfgPort.gbg) |
3963 | phba->sli3_options |= LPFC_SLI3_BG_ENABLED; | 3972 | phba->sli3_options |= LPFC_SLI3_BG_ENABLED; |
3964 | else | 3973 | else |
3965 | lpfc_printf_log(phba, KERN_ERR, LOG_INIT, | 3974 | lpfc_printf_log(phba, KERN_ERR, LOG_INIT, |
@@ -4054,8 +4063,9 @@ lpfc_sli_hba_setup(struct lpfc_hba *phba) | |||
4054 | if (rc) | 4063 | if (rc) |
4055 | goto lpfc_sli_hba_setup_error; | 4064 | goto lpfc_sli_hba_setup_error; |
4056 | } | 4065 | } |
4057 | 4066 | spin_lock_irq(&phba->hbalock); | |
4058 | phba->sli.sli_flag |= LPFC_PROCESS_LA; | 4067 | phba->sli.sli_flag |= LPFC_PROCESS_LA; |
4068 | spin_unlock_irq(&phba->hbalock); | ||
4059 | 4069 | ||
4060 | rc = lpfc_config_port_post(phba); | 4070 | rc = lpfc_config_port_post(phba); |
4061 | if (rc) | 4071 | if (rc) |
@@ -4596,7 +4606,7 @@ void | |||
4596 | lpfc_mbox_timeout_handler(struct lpfc_hba *phba) | 4606 | lpfc_mbox_timeout_handler(struct lpfc_hba *phba) |
4597 | { | 4607 | { |
4598 | LPFC_MBOXQ_t *pmbox = phba->sli.mbox_active; | 4608 | LPFC_MBOXQ_t *pmbox = phba->sli.mbox_active; |
4599 | MAILBOX_t *mb = &pmbox->mb; | 4609 | MAILBOX_t *mb = &pmbox->u.mb; |
4600 | struct lpfc_sli *psli = &phba->sli; | 4610 | struct lpfc_sli *psli = &phba->sli; |
4601 | struct lpfc_sli_ring *pring; | 4611 | struct lpfc_sli_ring *pring; |
4602 | 4612 | ||
@@ -6414,6 +6424,52 @@ lpfc_sli_queue_setup(struct lpfc_hba *phba) | |||
6414 | } | 6424 | } |
6415 | 6425 | ||
6416 | /** | 6426 | /** |
6427 | * lpfc_sli_mbox_sys_flush - Flush mailbox command sub-system | ||
6428 | * @phba: Pointer to HBA context object. | ||
6429 | * | ||
6430 | * This routine flushes the mailbox command subsystem. It will unconditionally | ||
6431 | * flush all the mailbox commands in the three possible stages in the mailbox | ||
6432 | * command sub-system: pending mailbox command queue; the outstanding mailbox | ||
6433 | * command; and completed mailbox command queue. It is caller's responsibility | ||
6434 | * to make sure that the driver is in the proper state to flush the mailbox | ||
6435 | * command sub-system. Namely, the posting of mailbox commands into the | ||
6436 | * pending mailbox command queue from the various clients must be stopped; | ||
6437 | * either the HBA is in a state that it will never works on the outstanding | ||
6438 | * mailbox command (such as in EEH or ERATT conditions) or the outstanding | ||
6439 | * mailbox command has been completed. | ||
6440 | **/ | ||
6441 | static void | ||
6442 | lpfc_sli_mbox_sys_flush(struct lpfc_hba *phba) | ||
6443 | { | ||
6444 | LIST_HEAD(completions); | ||
6445 | struct lpfc_sli *psli = &phba->sli; | ||
6446 | LPFC_MBOXQ_t *pmb; | ||
6447 | unsigned long iflag; | ||
6448 | |||
6449 | /* Flush all the mailbox commands in the mbox system */ | ||
6450 | spin_lock_irqsave(&phba->hbalock, iflag); | ||
6451 | /* The pending mailbox command queue */ | ||
6452 | list_splice_init(&phba->sli.mboxq, &completions); | ||
6453 | /* The outstanding active mailbox command */ | ||
6454 | if (psli->mbox_active) { | ||
6455 | list_add_tail(&psli->mbox_active->list, &completions); | ||
6456 | psli->mbox_active = NULL; | ||
6457 | psli->sli_flag &= ~LPFC_SLI_MBOX_ACTIVE; | ||
6458 | } | ||
6459 | /* The completed mailbox command queue */ | ||
6460 | list_splice_init(&phba->sli.mboxq_cmpl, &completions); | ||
6461 | spin_unlock_irqrestore(&phba->hbalock, iflag); | ||
6462 | |||
6463 | /* Return all flushed mailbox commands with MBX_NOT_FINISHED status */ | ||
6464 | while (!list_empty(&completions)) { | ||
6465 | list_remove_head(&completions, pmb, LPFC_MBOXQ_t, list); | ||
6466 | pmb->u.mb.mbxStatus = MBX_NOT_FINISHED; | ||
6467 | if (pmb->mbox_cmpl) | ||
6468 | pmb->mbox_cmpl(phba, pmb); | ||
6469 | } | ||
6470 | } | ||
6471 | |||
6472 | /** | ||
6417 | * lpfc_sli_host_down - Vport cleanup function | 6473 | * lpfc_sli_host_down - Vport cleanup function |
6418 | * @vport: Pointer to virtual port object. | 6474 | * @vport: Pointer to virtual port object. |
6419 | * | 6475 | * |
@@ -6506,9 +6562,11 @@ lpfc_sli_hba_down(struct lpfc_hba *phba) | |||
6506 | struct lpfc_sli *psli = &phba->sli; | 6562 | struct lpfc_sli *psli = &phba->sli; |
6507 | struct lpfc_sli_ring *pring; | 6563 | struct lpfc_sli_ring *pring; |
6508 | struct lpfc_dmabuf *buf_ptr; | 6564 | struct lpfc_dmabuf *buf_ptr; |
6509 | LPFC_MBOXQ_t *pmb; | ||
6510 | int i; | ||
6511 | unsigned long flags = 0; | 6565 | unsigned long flags = 0; |
6566 | int i; | ||
6567 | |||
6568 | /* Shutdown the mailbox command sub-system */ | ||
6569 | lpfc_sli_mbox_sys_shutdown(phba); | ||
6512 | 6570 | ||
6513 | lpfc_hba_down_prep(phba); | 6571 | lpfc_hba_down_prep(phba); |
6514 | 6572 | ||
@@ -7773,7 +7831,7 @@ lpfc_sli_sp_intr_handler(int irq, void *dev_id) | |||
7773 | 7831 | ||
7774 | if ((work_ha_copy & HA_MBATT) && (phba->sli.mbox_active)) { | 7832 | if ((work_ha_copy & HA_MBATT) && (phba->sli.mbox_active)) { |
7775 | pmb = phba->sli.mbox_active; | 7833 | pmb = phba->sli.mbox_active; |
7776 | pmbox = &pmb->mb; | 7834 | pmbox = &pmb->u.mb; |
7777 | mbox = phba->mbox; | 7835 | mbox = phba->mbox; |
7778 | vport = pmb->vport; | 7836 | vport = pmb->vport; |
7779 | 7837 | ||
@@ -8170,6 +8228,183 @@ lpfc_sli4_iocb_param_transfer(struct lpfc_iocbq *pIocbIn, | |||
8170 | } | 8228 | } |
8171 | 8229 | ||
8172 | /** | 8230 | /** |
8231 | * lpfc_sli4_sp_handle_async_event - Handle an asynchroous event | ||
8232 | * @phba: Pointer to HBA context object. | ||
8233 | * @cqe: Pointer to mailbox completion queue entry. | ||
8234 | * | ||
8235 | * This routine process a mailbox completion queue entry with asynchrous | ||
8236 | * event. | ||
8237 | * | ||
8238 | * Return: true if work posted to worker thread, otherwise false. | ||
8239 | **/ | ||
8240 | static bool | ||
8241 | lpfc_sli4_sp_handle_async_event(struct lpfc_hba *phba, struct lpfc_mcqe *mcqe) | ||
8242 | { | ||
8243 | struct lpfc_cq_event *cq_event; | ||
8244 | unsigned long iflags; | ||
8245 | |||
8246 | lpfc_printf_log(phba, KERN_INFO, LOG_SLI, | ||
8247 | "0392 Async Event: word0:x%x, word1:x%x, " | ||
8248 | "word2:x%x, word3:x%x\n", mcqe->word0, | ||
8249 | mcqe->mcqe_tag0, mcqe->mcqe_tag1, mcqe->trailer); | ||
8250 | |||
8251 | /* Allocate a new internal CQ_EVENT entry */ | ||
8252 | cq_event = lpfc_sli4_cq_event_alloc(phba); | ||
8253 | if (!cq_event) { | ||
8254 | lpfc_printf_log(phba, KERN_ERR, LOG_SLI, | ||
8255 | "0394 Failed to allocate CQ_EVENT entry\n"); | ||
8256 | return false; | ||
8257 | } | ||
8258 | |||
8259 | /* Move the CQE into an asynchronous event entry */ | ||
8260 | memcpy(&cq_event->cqe, mcqe, sizeof(struct lpfc_mcqe)); | ||
8261 | spin_lock_irqsave(&phba->hbalock, iflags); | ||
8262 | list_add_tail(&cq_event->list, &phba->sli4_hba.sp_asynce_work_queue); | ||
8263 | /* Set the async event flag */ | ||
8264 | phba->hba_flag |= ASYNC_EVENT; | ||
8265 | spin_unlock_irqrestore(&phba->hbalock, iflags); | ||
8266 | |||
8267 | return true; | ||
8268 | } | ||
8269 | |||
8270 | /** | ||
8271 | * lpfc_sli4_sp_handle_mbox_event - Handle a mailbox completion event | ||
8272 | * @phba: Pointer to HBA context object. | ||
8273 | * @cqe: Pointer to mailbox completion queue entry. | ||
8274 | * | ||
8275 | * This routine process a mailbox completion queue entry with mailbox | ||
8276 | * completion event. | ||
8277 | * | ||
8278 | * Return: true if work posted to worker thread, otherwise false. | ||
8279 | **/ | ||
8280 | static bool | ||
8281 | lpfc_sli4_sp_handle_mbox_event(struct lpfc_hba *phba, struct lpfc_mcqe *mcqe) | ||
8282 | { | ||
8283 | uint32_t mcqe_status; | ||
8284 | MAILBOX_t *mbox, *pmbox; | ||
8285 | struct lpfc_mqe *mqe; | ||
8286 | struct lpfc_vport *vport; | ||
8287 | struct lpfc_nodelist *ndlp; | ||
8288 | struct lpfc_dmabuf *mp; | ||
8289 | unsigned long iflags; | ||
8290 | LPFC_MBOXQ_t *pmb; | ||
8291 | bool workposted = false; | ||
8292 | int rc; | ||
8293 | |||
8294 | /* If not a mailbox complete MCQE, out by checking mailbox consume */ | ||
8295 | if (!bf_get(lpfc_trailer_completed, mcqe)) | ||
8296 | goto out_no_mqe_complete; | ||
8297 | |||
8298 | /* Get the reference to the active mbox command */ | ||
8299 | spin_lock_irqsave(&phba->hbalock, iflags); | ||
8300 | pmb = phba->sli.mbox_active; | ||
8301 | if (unlikely(!pmb)) { | ||
8302 | lpfc_printf_log(phba, KERN_ERR, LOG_MBOX, | ||
8303 | "1832 No pending MBOX command to handle\n"); | ||
8304 | spin_unlock_irqrestore(&phba->hbalock, iflags); | ||
8305 | goto out_no_mqe_complete; | ||
8306 | } | ||
8307 | spin_unlock_irqrestore(&phba->hbalock, iflags); | ||
8308 | mqe = &pmb->u.mqe; | ||
8309 | pmbox = (MAILBOX_t *)&pmb->u.mqe; | ||
8310 | mbox = phba->mbox; | ||
8311 | vport = pmb->vport; | ||
8312 | |||
8313 | /* Reset heartbeat timer */ | ||
8314 | phba->last_completion_time = jiffies; | ||
8315 | del_timer(&phba->sli.mbox_tmo); | ||
8316 | |||
8317 | /* Move mbox data to caller's mailbox region, do endian swapping */ | ||
8318 | if (pmb->mbox_cmpl && mbox) | ||
8319 | lpfc_sli_pcimem_bcopy(mbox, mqe, sizeof(struct lpfc_mqe)); | ||
8320 | /* Set the mailbox status with SLI4 range 0x4000 */ | ||
8321 | mcqe_status = bf_get(lpfc_mcqe_status, mcqe); | ||
8322 | if (mcqe_status != MB_CQE_STATUS_SUCCESS) | ||
8323 | bf_set(lpfc_mqe_status, mqe, | ||
8324 | (LPFC_MBX_ERROR_RANGE | mcqe_status)); | ||
8325 | |||
8326 | if (pmb->mbox_flag & LPFC_MBX_IMED_UNREG) { | ||
8327 | pmb->mbox_flag &= ~LPFC_MBX_IMED_UNREG; | ||
8328 | lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_MBOX_VPORT, | ||
8329 | "MBOX dflt rpi: status:x%x rpi:x%x", | ||
8330 | mcqe_status, | ||
8331 | pmbox->un.varWords[0], 0); | ||
8332 | if (mcqe_status == MB_CQE_STATUS_SUCCESS) { | ||
8333 | mp = (struct lpfc_dmabuf *)(pmb->context1); | ||
8334 | ndlp = (struct lpfc_nodelist *)pmb->context2; | ||
8335 | /* Reg_LOGIN of dflt RPI was successful. Now lets get | ||
8336 | * RID of the PPI using the same mbox buffer. | ||
8337 | */ | ||
8338 | lpfc_unreg_login(phba, vport->vpi, | ||
8339 | pmbox->un.varWords[0], pmb); | ||
8340 | pmb->mbox_cmpl = lpfc_mbx_cmpl_dflt_rpi; | ||
8341 | pmb->context1 = mp; | ||
8342 | pmb->context2 = ndlp; | ||
8343 | pmb->vport = vport; | ||
8344 | rc = lpfc_sli_issue_mbox(phba, pmb, MBX_NOWAIT); | ||
8345 | if (rc != MBX_BUSY) | ||
8346 | lpfc_printf_log(phba, KERN_ERR, LOG_MBOX | | ||
8347 | LOG_SLI, "0385 rc should " | ||
8348 | "have been MBX_BUSY\n"); | ||
8349 | if (rc != MBX_NOT_FINISHED) | ||
8350 | goto send_current_mbox; | ||
8351 | } | ||
8352 | } | ||
8353 | spin_lock_irqsave(&phba->pport->work_port_lock, iflags); | ||
8354 | phba->pport->work_port_events &= ~WORKER_MBOX_TMO; | ||
8355 | spin_unlock_irqrestore(&phba->pport->work_port_lock, iflags); | ||
8356 | |||
8357 | /* There is mailbox completion work to do */ | ||
8358 | spin_lock_irqsave(&phba->hbalock, iflags); | ||
8359 | __lpfc_mbox_cmpl_put(phba, pmb); | ||
8360 | phba->work_ha |= HA_MBATT; | ||
8361 | spin_unlock_irqrestore(&phba->hbalock, iflags); | ||
8362 | workposted = true; | ||
8363 | |||
8364 | send_current_mbox: | ||
8365 | spin_lock_irqsave(&phba->hbalock, iflags); | ||
8366 | /* Release the mailbox command posting token */ | ||
8367 | phba->sli.sli_flag &= ~LPFC_SLI_MBOX_ACTIVE; | ||
8368 | /* Setting active mailbox pointer need to be in sync to flag clear */ | ||
8369 | phba->sli.mbox_active = NULL; | ||
8370 | spin_unlock_irqrestore(&phba->hbalock, iflags); | ||
8371 | /* Wake up worker thread to post the next pending mailbox command */ | ||
8372 | lpfc_worker_wake_up(phba); | ||
8373 | out_no_mqe_complete: | ||
8374 | if (bf_get(lpfc_trailer_consumed, mcqe)) | ||
8375 | lpfc_sli4_mq_release(phba->sli4_hba.mbx_wq); | ||
8376 | return workposted; | ||
8377 | } | ||
8378 | |||
8379 | /** | ||
8380 | * lpfc_sli4_sp_handle_mcqe - Process a mailbox completion queue entry | ||
8381 | * @phba: Pointer to HBA context object. | ||
8382 | * @cqe: Pointer to mailbox completion queue entry. | ||
8383 | * | ||
8384 | * This routine process a mailbox completion queue entry, it invokes the | ||
8385 | * proper mailbox complete handling or asynchrous event handling routine | ||
8386 | * according to the MCQE's async bit. | ||
8387 | * | ||
8388 | * Return: true if work posted to worker thread, otherwise false. | ||
8389 | **/ | ||
8390 | static bool | ||
8391 | lpfc_sli4_sp_handle_mcqe(struct lpfc_hba *phba, struct lpfc_cqe *cqe) | ||
8392 | { | ||
8393 | struct lpfc_mcqe mcqe; | ||
8394 | bool workposted; | ||
8395 | |||
8396 | /* Copy the mailbox MCQE and convert endian order as needed */ | ||
8397 | lpfc_sli_pcimem_bcopy(cqe, &mcqe, sizeof(struct lpfc_mcqe)); | ||
8398 | |||
8399 | /* Invoke the proper event handling routine */ | ||
8400 | if (!bf_get(lpfc_trailer_async, &mcqe)) | ||
8401 | workposted = lpfc_sli4_sp_handle_mbox_event(phba, &mcqe); | ||
8402 | else | ||
8403 | workposted = lpfc_sli4_sp_handle_async_event(phba, &mcqe); | ||
8404 | return workposted; | ||
8405 | } | ||
8406 | |||
8407 | /** | ||
8173 | * lpfc_sli4_sp_handle_els_wcqe - Handle els work-queue completion event | 8408 | * lpfc_sli4_sp_handle_els_wcqe - Handle els work-queue completion event |
8174 | * @phba: Pointer to HBA context object. | 8409 | * @phba: Pointer to HBA context object. |
8175 | * @wcqe: Pointer to work-queue completion queue entry. | 8410 | * @wcqe: Pointer to work-queue completion queue entry. |
@@ -9247,6 +9482,112 @@ out: | |||
9247 | } | 9482 | } |
9248 | 9483 | ||
9249 | /** | 9484 | /** |
9485 | * lpfc_mq_create - Create a mailbox Queue on the HBA | ||
9486 | * @phba: HBA structure that indicates port to create a queue on. | ||
9487 | * @mq: The queue structure to use to create the mailbox queue. | ||
9488 | * | ||
9489 | * This function creates a mailbox queue, as detailed in @mq, on a port, | ||
9490 | * described by @phba by sending a MQ_CREATE mailbox command to the HBA. | ||
9491 | * | ||
9492 | * The @phba struct is used to send mailbox command to HBA. The @cq struct | ||
9493 | * is used to get the entry count and entry size that are necessary to | ||
9494 | * determine the number of pages to allocate and use for this queue. This | ||
9495 | * function will send the MQ_CREATE mailbox command to the HBA to setup the | ||
9496 | * mailbox queue. This function is asynchronous and will wait for the mailbox | ||
9497 | * command to finish before continuing. | ||
9498 | * | ||
9499 | * On success this function will return a zero. If unable to allocate enough | ||
9500 | * memory this function will return ENOMEM. If the queue create mailbox command | ||
9501 | * fails this function will return ENXIO. | ||
9502 | **/ | ||
9503 | uint32_t | ||
9504 | lpfc_mq_create(struct lpfc_hba *phba, struct lpfc_queue *mq, | ||
9505 | struct lpfc_queue *cq, uint32_t subtype) | ||
9506 | { | ||
9507 | struct lpfc_mbx_mq_create *mq_create; | ||
9508 | struct lpfc_dmabuf *dmabuf; | ||
9509 | LPFC_MBOXQ_t *mbox; | ||
9510 | int rc, length, status = 0; | ||
9511 | uint32_t shdr_status, shdr_add_status; | ||
9512 | union lpfc_sli4_cfg_shdr *shdr; | ||
9513 | |||
9514 | mbox = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL); | ||
9515 | if (!mbox) | ||
9516 | return -ENOMEM; | ||
9517 | length = (sizeof(struct lpfc_mbx_mq_create) - | ||
9518 | sizeof(struct lpfc_sli4_cfg_mhdr)); | ||
9519 | lpfc_sli4_config(phba, mbox, LPFC_MBOX_SUBSYSTEM_COMMON, | ||
9520 | LPFC_MBOX_OPCODE_MQ_CREATE, | ||
9521 | length, LPFC_SLI4_MBX_EMBED); | ||
9522 | mq_create = &mbox->u.mqe.un.mq_create; | ||
9523 | bf_set(lpfc_mbx_mq_create_num_pages, &mq_create->u.request, | ||
9524 | mq->page_count); | ||
9525 | bf_set(lpfc_mq_context_cq_id, &mq_create->u.request.context, | ||
9526 | cq->queue_id); | ||
9527 | bf_set(lpfc_mq_context_valid, &mq_create->u.request.context, 1); | ||
9528 | switch (mq->entry_count) { | ||
9529 | default: | ||
9530 | lpfc_printf_log(phba, KERN_ERR, LOG_SLI, | ||
9531 | "0362 Unsupported MQ count. (%d)\n", | ||
9532 | mq->entry_count); | ||
9533 | if (mq->entry_count < 16) | ||
9534 | return -EINVAL; | ||
9535 | /* otherwise default to smallest count (drop through) */ | ||
9536 | case 16: | ||
9537 | bf_set(lpfc_mq_context_count, &mq_create->u.request.context, | ||
9538 | LPFC_MQ_CNT_16); | ||
9539 | break; | ||
9540 | case 32: | ||
9541 | bf_set(lpfc_mq_context_count, &mq_create->u.request.context, | ||
9542 | LPFC_MQ_CNT_32); | ||
9543 | break; | ||
9544 | case 64: | ||
9545 | bf_set(lpfc_mq_context_count, &mq_create->u.request.context, | ||
9546 | LPFC_MQ_CNT_64); | ||
9547 | break; | ||
9548 | case 128: | ||
9549 | bf_set(lpfc_mq_context_count, &mq_create->u.request.context, | ||
9550 | LPFC_MQ_CNT_128); | ||
9551 | break; | ||
9552 | } | ||
9553 | list_for_each_entry(dmabuf, &mq->page_list, list) { | ||
9554 | mq_create->u.request.page[dmabuf->buffer_tag].addr_lo = | ||
9555 | putPaddrLow(dmabuf->phys); | ||
9556 | mq_create->u.request.page[dmabuf->buffer_tag].addr_hi = | ||
9557 | putPaddrHigh(dmabuf->phys); | ||
9558 | } | ||
9559 | rc = lpfc_sli_issue_mbox(phba, mbox, MBX_POLL); | ||
9560 | /* The IOCTL status is embedded in the mailbox subheader. */ | ||
9561 | shdr = (union lpfc_sli4_cfg_shdr *) &mq_create->header.cfg_shdr; | ||
9562 | shdr_status = bf_get(lpfc_mbox_hdr_status, &shdr->response); | ||
9563 | shdr_add_status = bf_get(lpfc_mbox_hdr_add_status, &shdr->response); | ||
9564 | if (shdr_status || shdr_add_status || rc) { | ||
9565 | lpfc_printf_log(phba, KERN_ERR, LOG_INIT, | ||
9566 | "2502 MQ_CREATE mailbox failed with " | ||
9567 | "status x%x add_status x%x, mbx status x%x\n", | ||
9568 | shdr_status, shdr_add_status, rc); | ||
9569 | status = -ENXIO; | ||
9570 | goto out; | ||
9571 | } | ||
9572 | mq->queue_id = bf_get(lpfc_mbx_mq_create_q_id, &mq_create->u.response); | ||
9573 | if (mq->queue_id == 0xFFFF) { | ||
9574 | status = -ENXIO; | ||
9575 | goto out; | ||
9576 | } | ||
9577 | mq->type = LPFC_MQ; | ||
9578 | mq->subtype = subtype; | ||
9579 | mq->host_index = 0; | ||
9580 | mq->hba_index = 0; | ||
9581 | |||
9582 | /* link the mq onto the parent cq child list */ | ||
9583 | list_add_tail(&mq->list, &cq->child_list); | ||
9584 | out: | ||
9585 | if (rc != MBX_TIMEOUT) | ||
9586 | mempool_free(mbox, phba->mbox_mem_pool); | ||
9587 | return status; | ||
9588 | } | ||
9589 | |||
9590 | /** | ||
9250 | * lpfc_wq_create - Create a Work Queue on the HBA | 9591 | * lpfc_wq_create - Create a Work Queue on the HBA |
9251 | * @phba: HBA structure that indicates port to create a queue on. | 9592 | * @phba: HBA structure that indicates port to create a queue on. |
9252 | * @wq: The queue structure to use to create the work queue. | 9593 | * @wq: The queue structure to use to create the work queue. |
@@ -9615,6 +9956,60 @@ lpfc_cq_destroy(struct lpfc_hba *phba, struct lpfc_queue *cq) | |||
9615 | } | 9956 | } |
9616 | 9957 | ||
9617 | /** | 9958 | /** |
9959 | * lpfc_mq_destroy - Destroy a Mailbox Queue on the HBA | ||
9960 | * @qm: The queue structure associated with the queue to destroy. | ||
9961 | * | ||
9962 | * This function destroys a queue, as detailed in @mq by sending an mailbox | ||
9963 | * command, specific to the type of queue, to the HBA. | ||
9964 | * | ||
9965 | * The @mq struct is used to get the queue ID of the queue to destroy. | ||
9966 | * | ||
9967 | * On success this function will return a zero. If the queue destroy mailbox | ||
9968 | * command fails this function will return ENXIO. | ||
9969 | **/ | ||
9970 | uint32_t | ||
9971 | lpfc_mq_destroy(struct lpfc_hba *phba, struct lpfc_queue *mq) | ||
9972 | { | ||
9973 | LPFC_MBOXQ_t *mbox; | ||
9974 | int rc, length, status = 0; | ||
9975 | uint32_t shdr_status, shdr_add_status; | ||
9976 | union lpfc_sli4_cfg_shdr *shdr; | ||
9977 | |||
9978 | if (!mq) | ||
9979 | return -ENODEV; | ||
9980 | mbox = mempool_alloc(mq->phba->mbox_mem_pool, GFP_KERNEL); | ||
9981 | if (!mbox) | ||
9982 | return -ENOMEM; | ||
9983 | length = (sizeof(struct lpfc_mbx_mq_destroy) - | ||
9984 | sizeof(struct lpfc_sli4_cfg_mhdr)); | ||
9985 | lpfc_sli4_config(phba, mbox, LPFC_MBOX_SUBSYSTEM_COMMON, | ||
9986 | LPFC_MBOX_OPCODE_MQ_DESTROY, | ||
9987 | length, LPFC_SLI4_MBX_EMBED); | ||
9988 | bf_set(lpfc_mbx_mq_destroy_q_id, &mbox->u.mqe.un.mq_destroy.u.request, | ||
9989 | mq->queue_id); | ||
9990 | mbox->vport = mq->phba->pport; | ||
9991 | mbox->mbox_cmpl = lpfc_sli_def_mbox_cmpl; | ||
9992 | rc = lpfc_sli_issue_mbox(mq->phba, mbox, MBX_POLL); | ||
9993 | /* The IOCTL status is embedded in the mailbox subheader. */ | ||
9994 | shdr = (union lpfc_sli4_cfg_shdr *) | ||
9995 | &mbox->u.mqe.un.mq_destroy.header.cfg_shdr; | ||
9996 | shdr_status = bf_get(lpfc_mbox_hdr_status, &shdr->response); | ||
9997 | shdr_add_status = bf_get(lpfc_mbox_hdr_add_status, &shdr->response); | ||
9998 | if (shdr_status || shdr_add_status || rc) { | ||
9999 | lpfc_printf_log(phba, KERN_ERR, LOG_INIT, | ||
10000 | "2507 MQ_DESTROY mailbox failed with " | ||
10001 | "status x%x add_status x%x, mbx status x%x\n", | ||
10002 | shdr_status, shdr_add_status, rc); | ||
10003 | status = -ENXIO; | ||
10004 | } | ||
10005 | /* Remove mq from any list */ | ||
10006 | list_del_init(&mq->list); | ||
10007 | if (rc != MBX_TIMEOUT) | ||
10008 | mempool_free(mbox, mq->phba->mbox_mem_pool); | ||
10009 | return status; | ||
10010 | } | ||
10011 | |||
10012 | /** | ||
9618 | * lpfc_wq_destroy - Destroy a Work Queue on the HBA | 10013 | * lpfc_wq_destroy - Destroy a Work Queue on the HBA |
9619 | * @wq: The queue structure associated with the queue to destroy. | 10014 | * @wq: The queue structure associated with the queue to destroy. |
9620 | * | 10015 | * |