aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/lpfc/lpfc_sli.c
diff options
context:
space:
mode:
authorJames Smart <james.smart@emulex.com>2010-04-06 14:48:51 -0400
committerJames Bottomley <James.Bottomley@suse.de>2010-04-11 14:44:44 -0400
commitb19a061a785db22401b62cc4ee2baf95d5c7e2e7 (patch)
treecc5219324cd5a59455f195f51afe9807d3b07595 /drivers/scsi/lpfc/lpfc_sli.c
parent40364a40b68a26cc882df05f7cc7f0ad87aac935 (diff)
[SCSI] lpfc 8.3.12: Emulex SLI enhancements
- Add the new Logical Link speed event support. - Add RATOV and EDTOV to the REG_VFI mailbox command. Signed-off-by: Alex Iannicelli <alex.iannicelli@emulex.com> Signed-off-by: James Smart <james.smart@emulex.com> Signed-off-by: James Bottomley <James.Bottomley@suse.de>
Diffstat (limited to 'drivers/scsi/lpfc/lpfc_sli.c')
-rw-r--r--drivers/scsi/lpfc/lpfc_sli.c116
1 files changed, 100 insertions, 16 deletions
diff --git a/drivers/scsi/lpfc/lpfc_sli.c b/drivers/scsi/lpfc/lpfc_sli.c
index 2f7018821531..2c88999b7095 100644
--- a/drivers/scsi/lpfc/lpfc_sli.c
+++ b/drivers/scsi/lpfc/lpfc_sli.c
@@ -9834,9 +9834,70 @@ out:
9834} 9834}
9835 9835
9836/** 9836/**
9837 * lpfc_mq_create_fb_init - Send MCC_CREATE without async events registration
9838 * @phba: HBA structure that indicates port to create a queue on.
9839 * @mq: The queue structure to use to create the mailbox queue.
9840 * @mbox: An allocated pointer to type LPFC_MBOXQ_t
9841 * @cq: The completion queue to associate with this cq.
9842 *
9843 * This function provides failback (fb) functionality when the
9844 * mq_create_ext fails on older FW generations. It's purpose is identical
9845 * to mq_create_ext otherwise.
9846 *
9847 * This routine cannot fail as all attributes were previously accessed and
9848 * initialized in mq_create_ext.
9849 **/
9850static void
9851lpfc_mq_create_fb_init(struct lpfc_hba *phba, struct lpfc_queue *mq,
9852 LPFC_MBOXQ_t *mbox, struct lpfc_queue *cq)
9853{
9854 struct lpfc_mbx_mq_create *mq_create;
9855 struct lpfc_dmabuf *dmabuf;
9856 int length;
9857
9858 length = (sizeof(struct lpfc_mbx_mq_create) -
9859 sizeof(struct lpfc_sli4_cfg_mhdr));
9860 lpfc_sli4_config(phba, mbox, LPFC_MBOX_SUBSYSTEM_COMMON,
9861 LPFC_MBOX_OPCODE_MQ_CREATE,
9862 length, LPFC_SLI4_MBX_EMBED);
9863 mq_create = &mbox->u.mqe.un.mq_create;
9864 bf_set(lpfc_mbx_mq_create_num_pages, &mq_create->u.request,
9865 mq->page_count);
9866 bf_set(lpfc_mq_context_cq_id, &mq_create->u.request.context,
9867 cq->queue_id);
9868 bf_set(lpfc_mq_context_valid, &mq_create->u.request.context, 1);
9869 switch (mq->entry_count) {
9870 case 16:
9871 bf_set(lpfc_mq_context_count, &mq_create->u.request.context,
9872 LPFC_MQ_CNT_16);
9873 break;
9874 case 32:
9875 bf_set(lpfc_mq_context_count, &mq_create->u.request.context,
9876 LPFC_MQ_CNT_32);
9877 break;
9878 case 64:
9879 bf_set(lpfc_mq_context_count, &mq_create->u.request.context,
9880 LPFC_MQ_CNT_64);
9881 break;
9882 case 128:
9883 bf_set(lpfc_mq_context_count, &mq_create->u.request.context,
9884 LPFC_MQ_CNT_128);
9885 break;
9886 }
9887 list_for_each_entry(dmabuf, &mq->page_list, list) {
9888 mq_create->u.request.page[dmabuf->buffer_tag].addr_lo =
9889 putPaddrLow(dmabuf->phys);
9890 mq_create->u.request.page[dmabuf->buffer_tag].addr_hi =
9891 putPaddrHigh(dmabuf->phys);
9892 }
9893}
9894
9895/**
9837 * lpfc_mq_create - Create a mailbox Queue on the HBA 9896 * lpfc_mq_create - Create a mailbox Queue on the HBA
9838 * @phba: HBA structure that indicates port to create a queue on. 9897 * @phba: HBA structure that indicates port to create a queue on.
9839 * @mq: The queue structure to use to create the mailbox queue. 9898 * @mq: The queue structure to use to create the mailbox queue.
9899 * @cq: The completion queue to associate with this cq.
9900 * @subtype: The queue's subtype.
9840 * 9901 *
9841 * This function creates a mailbox queue, as detailed in @mq, on a port, 9902 * This function creates a mailbox queue, as detailed in @mq, on a port,
9842 * described by @phba by sending a MQ_CREATE mailbox command to the HBA. 9903 * described by @phba by sending a MQ_CREATE mailbox command to the HBA.
@@ -9852,31 +9913,40 @@ out:
9852 * memory this function will return ENOMEM. If the queue create mailbox command 9913 * memory this function will return ENOMEM. If the queue create mailbox command
9853 * fails this function will return ENXIO. 9914 * fails this function will return ENXIO.
9854 **/ 9915 **/
9855uint32_t 9916int32_t
9856lpfc_mq_create(struct lpfc_hba *phba, struct lpfc_queue *mq, 9917lpfc_mq_create(struct lpfc_hba *phba, struct lpfc_queue *mq,
9857 struct lpfc_queue *cq, uint32_t subtype) 9918 struct lpfc_queue *cq, uint32_t subtype)
9858{ 9919{
9859 struct lpfc_mbx_mq_create *mq_create; 9920 struct lpfc_mbx_mq_create *mq_create;
9921 struct lpfc_mbx_mq_create_ext *mq_create_ext;
9860 struct lpfc_dmabuf *dmabuf; 9922 struct lpfc_dmabuf *dmabuf;
9861 LPFC_MBOXQ_t *mbox; 9923 LPFC_MBOXQ_t *mbox;
9862 int rc, length, status = 0; 9924 int rc, length, status = 0;
9863 uint32_t shdr_status, shdr_add_status; 9925 uint32_t shdr_status, shdr_add_status;
9864 union lpfc_sli4_cfg_shdr *shdr; 9926 union lpfc_sli4_cfg_shdr *shdr;
9865 9927
9928
9866 mbox = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL); 9929 mbox = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL);
9867 if (!mbox) 9930 if (!mbox)
9868 return -ENOMEM; 9931 return -ENOMEM;
9869 length = (sizeof(struct lpfc_mbx_mq_create) - 9932 length = (sizeof(struct lpfc_mbx_mq_create_ext) -
9870 sizeof(struct lpfc_sli4_cfg_mhdr)); 9933 sizeof(struct lpfc_sli4_cfg_mhdr));
9871 lpfc_sli4_config(phba, mbox, LPFC_MBOX_SUBSYSTEM_COMMON, 9934 lpfc_sli4_config(phba, mbox, LPFC_MBOX_SUBSYSTEM_COMMON,
9872 LPFC_MBOX_OPCODE_MQ_CREATE, 9935 LPFC_MBOX_OPCODE_MQ_CREATE_EXT,
9873 length, LPFC_SLI4_MBX_EMBED); 9936 length, LPFC_SLI4_MBX_EMBED);
9874 mq_create = &mbox->u.mqe.un.mq_create; 9937
9875 bf_set(lpfc_mbx_mq_create_num_pages, &mq_create->u.request, 9938 mq_create_ext = &mbox->u.mqe.un.mq_create_ext;
9939 bf_set(lpfc_mbx_mq_create_ext_num_pages, &mq_create_ext->u.request,
9876 mq->page_count); 9940 mq->page_count);
9877 bf_set(lpfc_mq_context_cq_id, &mq_create->u.request.context, 9941 bf_set(lpfc_mbx_mq_create_ext_async_evt_link, &mq_create_ext->u.request,
9878 cq->queue_id); 9942 1);
9879 bf_set(lpfc_mq_context_valid, &mq_create->u.request.context, 1); 9943 bf_set(lpfc_mbx_mq_create_ext_async_evt_fcfste,
9944 &mq_create_ext->u.request, 1);
9945 bf_set(lpfc_mbx_mq_create_ext_async_evt_group5,
9946 &mq_create_ext->u.request, 1);
9947 bf_set(lpfc_mq_context_cq_id, &mq_create_ext->u.request.context,
9948 cq->queue_id);
9949 bf_set(lpfc_mq_context_valid, &mq_create_ext->u.request.context, 1);
9880 switch (mq->entry_count) { 9950 switch (mq->entry_count) {
9881 default: 9951 default:
9882 lpfc_printf_log(phba, KERN_ERR, LOG_SLI, 9952 lpfc_printf_log(phba, KERN_ERR, LOG_SLI,
@@ -9886,31 +9956,46 @@ lpfc_mq_create(struct lpfc_hba *phba, struct lpfc_queue *mq,
9886 return -EINVAL; 9956 return -EINVAL;
9887 /* otherwise default to smallest count (drop through) */ 9957 /* otherwise default to smallest count (drop through) */
9888 case 16: 9958 case 16:
9889 bf_set(lpfc_mq_context_count, &mq_create->u.request.context, 9959 bf_set(lpfc_mq_context_count, &mq_create_ext->u.request.context,
9890 LPFC_MQ_CNT_16); 9960 LPFC_MQ_CNT_16);
9891 break; 9961 break;
9892 case 32: 9962 case 32:
9893 bf_set(lpfc_mq_context_count, &mq_create->u.request.context, 9963 bf_set(lpfc_mq_context_count, &mq_create_ext->u.request.context,
9894 LPFC_MQ_CNT_32); 9964 LPFC_MQ_CNT_32);
9895 break; 9965 break;
9896 case 64: 9966 case 64:
9897 bf_set(lpfc_mq_context_count, &mq_create->u.request.context, 9967 bf_set(lpfc_mq_context_count, &mq_create_ext->u.request.context,
9898 LPFC_MQ_CNT_64); 9968 LPFC_MQ_CNT_64);
9899 break; 9969 break;
9900 case 128: 9970 case 128:
9901 bf_set(lpfc_mq_context_count, &mq_create->u.request.context, 9971 bf_set(lpfc_mq_context_count, &mq_create_ext->u.request.context,
9902 LPFC_MQ_CNT_128); 9972 LPFC_MQ_CNT_128);
9903 break; 9973 break;
9904 } 9974 }
9905 list_for_each_entry(dmabuf, &mq->page_list, list) { 9975 list_for_each_entry(dmabuf, &mq->page_list, list) {
9906 mq_create->u.request.page[dmabuf->buffer_tag].addr_lo = 9976 mq_create_ext->u.request.page[dmabuf->buffer_tag].addr_lo =
9907 putPaddrLow(dmabuf->phys); 9977 putPaddrLow(dmabuf->phys);
9908 mq_create->u.request.page[dmabuf->buffer_tag].addr_hi = 9978 mq_create_ext->u.request.page[dmabuf->buffer_tag].addr_hi =
9909 putPaddrHigh(dmabuf->phys); 9979 putPaddrHigh(dmabuf->phys);
9910 } 9980 }
9911 rc = lpfc_sli_issue_mbox(phba, mbox, MBX_POLL); 9981 rc = lpfc_sli_issue_mbox(phba, mbox, MBX_POLL);
9982 shdr = (union lpfc_sli4_cfg_shdr *) &mq_create_ext->header.cfg_shdr;
9983 mq->queue_id = bf_get(lpfc_mbx_mq_create_q_id,
9984 &mq_create_ext->u.response);
9985 if (rc != MBX_SUCCESS) {
9986 lpfc_printf_log(phba, KERN_INFO, LOG_INIT,
9987 "2795 MQ_CREATE_EXT failed with "
9988 "status x%x. Failback to MQ_CREATE.\n",
9989 rc);
9990 lpfc_mq_create_fb_init(phba, mq, mbox, cq);
9991 mq_create = &mbox->u.mqe.un.mq_create;
9992 rc = lpfc_sli_issue_mbox(phba, mbox, MBX_POLL);
9993 shdr = (union lpfc_sli4_cfg_shdr *) &mq_create->header.cfg_shdr;
9994 mq->queue_id = bf_get(lpfc_mbx_mq_create_q_id,
9995 &mq_create->u.response);
9996 }
9997
9912 /* The IOCTL status is embedded in the mailbox subheader. */ 9998 /* The IOCTL status is embedded in the mailbox subheader. */
9913 shdr = (union lpfc_sli4_cfg_shdr *) &mq_create->header.cfg_shdr;
9914 shdr_status = bf_get(lpfc_mbox_hdr_status, &shdr->response); 9999 shdr_status = bf_get(lpfc_mbox_hdr_status, &shdr->response);
9915 shdr_add_status = bf_get(lpfc_mbox_hdr_add_status, &shdr->response); 10000 shdr_add_status = bf_get(lpfc_mbox_hdr_add_status, &shdr->response);
9916 if (shdr_status || shdr_add_status || rc) { 10001 if (shdr_status || shdr_add_status || rc) {
@@ -9921,7 +10006,6 @@ lpfc_mq_create(struct lpfc_hba *phba, struct lpfc_queue *mq,
9921 status = -ENXIO; 10006 status = -ENXIO;
9922 goto out; 10007 goto out;
9923 } 10008 }
9924 mq->queue_id = bf_get(lpfc_mbx_mq_create_q_id, &mq_create->u.response);
9925 if (mq->queue_id == 0xFFFF) { 10009 if (mq->queue_id == 0xFFFF) {
9926 status = -ENXIO; 10010 status = -ENXIO;
9927 goto out; 10011 goto out;