diff options
author | James Smart <james.smart@emulex.com> | 2010-04-06 14:48:51 -0400 |
---|---|---|
committer | James Bottomley <James.Bottomley@suse.de> | 2010-04-11 14:44:44 -0400 |
commit | b19a061a785db22401b62cc4ee2baf95d5c7e2e7 (patch) | |
tree | cc5219324cd5a59455f195f51afe9807d3b07595 /drivers/scsi/lpfc/lpfc_sli.c | |
parent | 40364a40b68a26cc882df05f7cc7f0ad87aac935 (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.c | 116 |
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 | **/ | ||
9850 | static void | ||
9851 | lpfc_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 | **/ |
9855 | uint32_t | 9916 | int32_t |
9856 | lpfc_mq_create(struct lpfc_hba *phba, struct lpfc_queue *mq, | 9917 | lpfc_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; |